Skip to content

Commit 8a6e98a

Browse files
ncalteenam-stead
andauthored
Remove references to committing node_modules for JS actions (#56043)
Co-authored-by: Anne-Marie <102995847+am-stead@users.noreply.github.com>
1 parent 14b18dd commit 8a6e98a

File tree

1 file changed

+85
-54
lines changed

1 file changed

+85
-54
lines changed

content/actions/sharing-automations/creating-actions/creating-a-javascript-action.md

Lines changed: 85 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ Before you begin, you'll need to download Node.js and create a public {% data va
3939
1. Download and install Node.js 20.x, which includes npm.
4040

4141
https://nodejs.org/en/download/
42+
4243
1. Create a new public repository on {% data variables.product.github %} and call it "hello-world-javascript-action". For more information, see [AUTOTITLE](/repositories/creating-and-managing-repositories/creating-a-new-repository).
4344

4445
1. Clone your repository to your computer. For more information, see [AUTOTITLE](/repositories/creating-and-managing-repositories/cloning-a-repository).
@@ -60,19 +61,22 @@ Before you begin, you'll need to download Node.js and create a public {% data va
6061
Create a new file named `action.yml` in the `hello-world-javascript-action` directory with the following example code. For more information, see [AUTOTITLE](/actions/creating-actions/metadata-syntax-for-github-actions).
6162

6263
```yaml copy
63-
name: 'Hello World'
64-
description: 'Greet someone and record the time'
64+
name: Hello World
65+
description: Greet someone and record the time
66+
6567
inputs:
66-
who-to-greet: # id of input
67-
description: 'Who to greet'
68+
who-to-greet: # id of input
69+
description: Who to greet
6870
required: true
69-
default: 'World'
71+
default: World
72+
7073
outputs:
7174
time: # id of output
72-
description: 'The time we greeted you'
75+
description: The time we greeted you
76+
7377
runs:
74-
using: 'node20'
75-
main: 'index.js'
78+
using: node20
79+
main: dist/index.js
7680
```
7781
7882
This file defines the `who-to-greet` input and `time` output. It also tells the action runner how to start running this JavaScript action.
@@ -90,35 +94,37 @@ The toolkit offers more than the `core` and `github` packages. For more informat
9094
At your terminal, install the actions toolkit `core` and `github` packages.
9195

9296
```shell copy
93-
npm install @actions/core
94-
npm install @actions/github
97+
npm install @actions/core @actions/github
9598
```
9699

97-
Now you should see a `node_modules` directory with the modules you just installed and a `package-lock.json` file with the installed module dependencies and the versions of each installed module.
100+
You should now see a `node_modules` directory and a `package-lock.json` file which track any installed dependencies and their versions. You should not commit the `node_modules` directory to your repository.
98101

99102
## Writing the action code
100103

101104
This action uses the toolkit to get the `who-to-greet` input variable required in the action's metadata file and prints "Hello [who-to-greet]" in a debug message in the log. Next, the script gets the current time and sets it as an output variable that actions running later in a job can use.
102105

103106
GitHub Actions provide context information about the webhook event, Git refs, workflow, action, and the person who triggered the workflow. To access the context information, you can use the `github` package. The action you'll write will print the webhook event payload to the log.
104107

105-
Add a new file called `index.js`, with the following code.
108+
Add a new file called `src/index.js`, with the following code.
106109

107110
{% raw %}
108111

109112
```javascript copy
110-
const core = require('@actions/core');
111-
const github = require('@actions/github');
113+
import * as core from "@actions/core";
114+
import * as github from "@actions/github";
112115
113116
try {
114117
// `who-to-greet` input defined in action metadata file
115-
const nameToGreet = core.getInput('who-to-greet');
116-
console.log(`Hello ${nameToGreet}!`);
117-
const time = (new Date()).toTimeString();
118+
const nameToGreet = core.getInput("who-to-greet");
119+
core.info(`Hello ${nameToGreet}!`);
120+
121+
// Get the current time and set it as an output variable
122+
const time = new Date().toTimeString();
118123
core.setOutput("time", time);
124+
119125
// Get the JSON webhook payload for the event that triggered the workflow
120-
const payload = JSON.stringify(github.context.payload, undefined, 2)
121-
console.log(`The event payload: ${payload}`);
126+
const payload = JSON.stringify(github.context.payload, undefined, 2);
127+
core.info(`The event payload: ${payload}`);
122128
} catch (error) {
123129
core.setFailed(error.message);
124130
}
@@ -142,7 +148,7 @@ In your `hello-world-javascript-action` directory, create a `README.md` file tha
142148
* An example of how to use your action in a workflow.
143149

144150
````markdown copy
145-
# Hello world javascript action
151+
# Hello world JavaScript action
146152

147153
This action prints "Hello World" or "Hello" + the name of a person to greet to the log.
148154

@@ -163,54 +169,70 @@ The time we greeted you.
163169
```yaml
164170
uses: actions/hello-world-javascript-action@e76147da8e5c81eaf017dede5645551d4b94427b
165171
with:
166-
who-to-greet: 'Mona the Octocat'
172+
who-to-greet: Mona the Octocat
167173
```
168174
````
169175

170176
## Commit, tag, and push your action
171177

172-
{% data variables.product.github %} downloads each action run in a workflow during runtime and executes it as a complete package of code before you can use workflow commands like `run` to interact with the runner machine. This means you must include any package dependencies required to run the JavaScript code. You'll need to check in the toolkit `core` and `github` packages to your action's repository.
178+
{% data variables.product.github %} downloads each action run in a workflow during runtime and executes it as a complete package of code before you can use workflow commands like `run` to interact with the runner machine. This means you must include any package dependencies required to run the JavaScript code. For example, this action uses `@actions/core` and `@actions/github` packages.
173179

174-
From your terminal, commit your `action.yml`, `index.js`, `node_modules`, `package.json`, `package-lock.json`, and `README.md` files. If you added a `.gitignore` file that lists `node_modules`, you'll need to remove that line to commit the `node_modules` directory.
180+
Checking in your `node_modules` directory can cause problems. As an alternative, you can use tools such as [`rollup.js`](https://github.com/rollup/rollup) or [`@vercel/ncc`](https://github.com/vercel/ncc) to combine your code and dependencies into one file for distribution.
175181

176-
It's best practice to also add a version tag for releases of your action. For more information on versioning your action, see [AUTOTITLE](/actions/creating-actions/about-custom-actions#using-release-management-for-actions).
182+
1. Install `rollup` and its plugins by running this command in your terminal.
177183

178-
```shell copy
179-
git add action.yml index.js node_modules/* package.json package-lock.json README.md
180-
git commit -m "My first action is ready"
181-
git tag -a -m "My first action release" v1.1
182-
git push --follow-tags
183-
```
184-
185-
Checking in your `node_modules` directory can cause problems. As an alternative, you can use a tool called [`@vercel/ncc`](https://github.com/vercel/ncc) to compile your code and modules into one file used for distribution.
184+
`npm install --save-dev rollup @rollup/plugin-commonjs @rollup/plugin-node-resolve`
186185

187-
1. Install `vercel/ncc` by running this command in your terminal.
186+
1. Create a new file called `rollup.config.js` in the root of your repository with the following code.
188187

189-
`npm i -g @vercel/ncc`
188+
```javascript copy
189+
import commonjs from "@rollup/plugin-commonjs";
190+
import { nodeResolve } from "@rollup/plugin-node-resolve";
190191

191-
1. Compile your `index.js` file.
192+
const config = {
193+
input: "src/index.js",
194+
output: {
195+
esModule: true,
196+
file: "dist/index.js",
197+
format: "es",
198+
sourcemap: true,
199+
},
200+
plugins: [commonjs(), nodeResolve({ preferBuiltins: true })],
201+
};
192202

193-
`ncc build index.js --license licenses.txt`
194-
195-
You'll see a new `dist/index.js` file with your code and the compiled modules. You will also see an accompanying `dist/licenses.txt` file containing all the licenses of the `node_modules` you are using.
196-
197-
1. Change the `main` keyword in your `action.yml` file to use the new `dist/index.js` file.
203+
export default config;
204+
```
198205

199-
`main: 'dist/index.js'`
206+
1. Compile your `dist/index.js` file.
200207

201-
1. If you already checked in your `node_modules` directory, remove it.
208+
`rollup --config rollup.config.js`
202209

203-
`rm -rf node_modules/*`
210+
You'll see a new `dist/index.js` file with your code and any dependencies.
204211

205-
1. From your terminal, commit the updates to your `action.yml`, `dist/index.js`, and `node_modules` files.
212+
1. From your terminal, commit the updates.
206213

207214
```shell copy
208-
git add action.yml dist/index.js node_modules/*
209-
git commit -m "Use vercel/ncc"
215+
git add src/index.js dist/index.js rollup.config.js package.json package-lock.json README.md action.yml
216+
git commit -m "Initial commit of my first action"
210217
git tag -a -m "My first action release" v1.1
211218
git push --follow-tags
212219
```
213220

221+
When you commit and push your code, your updated repository should look like this:
222+
223+
```text
224+
hello-world-javascript-action/
225+
├── action.yml
226+
├── dist/
227+
│ └── index.js
228+
├── package.json
229+
├── package-lock.json
230+
├── README.md
231+
├── rollup.config.js
232+
└── src/
233+
└── index.js
234+
```
235+
214236
## Testing out your action in a workflow
215237

216238
Now you're ready to test your action out in a workflow.
@@ -228,18 +250,23 @@ Copy the following YAML into a new file at `.github/workflows/main.yml`, and upd
228250
{% raw %}
229251

230252
```yaml copy
231-
on: [push]
253+
on:
254+
push:
255+
branches:
256+
- main
232257

233258
jobs:
234259
hello_world_job:
235-
runs-on: ubuntu-latest
236260
name: A job to say hello
261+
runs-on: ubuntu-latest
262+
237263
steps:
238264
- name: Hello world action step
239265
id: hello
240266
uses: octocat/hello-world-javascript-action@1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b
241267
with:
242-
who-to-greet: 'Mona the Octocat'
268+
who-to-greet: Mona the Octocat
269+
243270
# Use the output from the `hello` step
244271
- name: Get the output time
245272
run: echo "The time was ${{ steps.hello.outputs.time }}"
@@ -253,25 +280,29 @@ When this workflow is triggered, the runner will download the `hello-world-javas
253280

254281
Copy the workflow code into a `.github/workflows/main.yml` file in your action's repository. You can also replace the `who-to-greet` input with your name.
255282

256-
**.github/workflows/main.yml**
257-
258283
```yaml copy
259-
on: [push]
284+
on:
285+
push:
286+
branches:
287+
- main
260288
261289
jobs:
262290
hello_world_job:
263-
runs-on: ubuntu-latest
264291
name: A job to say hello
292+
runs-on: ubuntu-latest
293+
265294
steps:
266295
# To use this repository's private action,
267296
# you must check out the repository
268297
- name: Checkout
269298
uses: {% data reusables.actions.action-checkout %}
299+
270300
- name: Hello world action step
271301
uses: ./ # Uses an action in the root directory
272302
id: hello
273303
with:
274-
who-to-greet: 'Mona the Octocat'
304+
who-to-greet: Mona the Octocat
305+
275306
# Use the output from the `hello` step
276307
- name: Get the output time
277308
run: echo "The time was {% raw %}${{ steps.hello.outputs.time }}{% endraw %}"

0 commit comments

Comments
 (0)