Skip to content

Commit 25e2874

Browse files
Update to 4 in STEP and README.md
1 parent 7db804f commit 25e2874

File tree

2 files changed

+138
-39
lines changed

2 files changed

+138
-39
lines changed

.github/steps/-step.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
3
1+
4

README.md

Lines changed: 137 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -15,69 +15,168 @@ _Write your own GitHub JavaScript Action and automate customized tasks unique to
1515
</header>
1616

1717
<!--
18-
<<< Author notes: Step 3 >>>
18+
<<< Author notes: Step 4 >>>
1919
Start this step by acknowledging the previous step.
2020
Define terms and link to docs.github.com.
2121
-->
2222

23-
## Step 3: Create the metadata file
23+
## Step 4: Create the JavaScript files for your action
2424

25-
_Nice work configuring your action :smile:_
25+
_Good job adding the metadata file! :dancer:_
2626

27-
## Action metadata
27+
## Files
2828

29-
Every GitHub Action that we write needs to be accompanied by a metadata file. This file has a few rules to it, as are indicated below:
29+
As you probably know, in JavaScript and other programming languages it is common to break your code into modules so that it is easier to read and maintain going forward. Since JavaScript actions are just programs written in JavaScript that run based on a specific trigger we are able to make our action code modular as well.
3030

31-
- Filename **must** be `action.yml`.
32-
- Required for both Docker container and JavaScript actions.
33-
- Written in YAML syntax.
31+
To do so we will create two files. One of them will contain the logic to reach out to an external API and retrieve a joke for us, the other will call that module and print the joke to the actions console for us. We will be extending this functionality in our third and final action.
3432

35-
This file defines the following information about your action:
33+
### Fetching a joke
3634

37-
| Parameter | Description | Required |
38-
| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | :----------------: |
39-
| Name | The name of your action. Helps visually identify the actions in a job. | :white_check_mark: |
40-
| Description | A summary of what your action does. | :white_check_mark: |
41-
| Inputs | Input parameters allow you to specify data that the action expects to use during runtime. These parameters become environment variables in the runner. | :x: |
42-
| Outputs | Specifies the data that subsequent actions can use later in the workflow after the action that defines these outputs has run. | :x: |
43-
| Runs | The command to run when the action executes. | :white_check_mark: |
44-
| Branding | You can use a color and Feather icon to create a badge to personalize and distinguish your action in GitHub Marketplace. | :x: |
35+
**Joke API**
4536

46-
---
37+
The first file will be `joke.js` and it will fetch our joke for us. We will be using the [icanhazdadjoke API](https://icanhazdadjoke.com/api) for our action. This API does not require any authentication, but it does however that we set a few parameters in the [HTTP headers](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers). We need to point out what those are when we get to the code, however it is outside of the scope of this course to cover HTTP in any depth.
38+
39+
When we make our request to this API we will get back a JSON Object in the response. That Object looks like this:
40+
41+
```
42+
{
43+
id: '0LuXvkq4Muc',
44+
joke: "I knew I shouldn't steal a mixer from work, but it was a whisk I was willing to take.",
45+
status: 200
46+
}
47+
```
48+
49+
It contains 3 key/value pairs of data that we can use in our own program or service. In our case, we are only interested in the `joke` field.
50+
51+
**Joke Module**
52+
53+
We will create a file named `joke.js` and it will reside in the `.github/actions/joke-action` directory.
54+
55+
The joke module will look like this:
56+
57+
```javascript
58+
const request = require("request-promise");
59+
60+
const options = {
61+
method: "GET",
62+
uri: "https://icanhazdadjoke.com/",
63+
headers: {
64+
Accept: "application/json",
65+
"User-Agent": "Writing JavaScript action GitHub Skills course.",
66+
},
67+
json: true,
68+
};
69+
70+
async function getJoke() {
71+
const res = await request(options);
72+
return res.joke;
73+
}
74+
75+
module.exports = getJoke;
76+
```
77+
78+
Need an advanced description of the <code>joke.js</code> source code?
79+
80+
We first bring in the `request-promise` library that we installed earlier using `npm`.
81+
82+
Next we define a set of `options` that the `request-promise` library will use when it makes the request.
83+
84+
Read more about [request-promise](https://github.com/request/request-promise/)
85+
86+
Inside of the `options` block we add a key named `headers`. This defines the HTTP headers that the **icanhazdadjoke** API expects in each request that comes it's way.
87+
88+
**icanhazdadjoke** cares the most about the keys, **Accept** and **User-Agent**, so we need to make sure we fill them in.
89+
90+
Next we define an **asynchronous JavaScript function** to make the request for us, storing the JSON Object that is returned in a variable named `res`.
4791

48-
Read more about [Action metadata](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/metadata-syntax-for-github-actions)
92+
Lastly, we `return` the `res.joke` which is only the value associated with the `joke` key of the JSON Object. This value will be random every time our action runs because of how we are interacting with the **icanhazdadjoke** API.
4993

50-
### :keyboard: Activity 1: Create the metadata file
94+
This file finishes up by exporting the newly created function so that we can use it in our `main.js` file.
5195

52-
All of the following steps take place inside of the `.github/actions/joke-action` directory.
96+
### Creating the main entry point for your action
5397

54-
Our action does not require much metadata for it to run correctly. We will not be accepting any inputs, we will however be setting a single output this time.
98+
**Main Module**
5599

56-
1. Update the action metadata file `.github/actions/joke-action/action.yml` with the following content:
100+
We will also create a file named `main.js` that resides inside of the `.github/actions/joke-action` directory.
101+
102+
That file will look like this:
103+
104+
```javascript
105+
const getJoke = require("./joke");
106+
const core = require("@actions/core");
107+
108+
async function run() {
109+
const joke = await getJoke();
110+
console.log(joke);
111+
core.setOutput("joke-output", joke);
112+
}
113+
114+
run();
115+
```
116+
117+
Need an advanced description of the <code>main.js</code> source code?
118+
119+
Like we did in the `joke.js` file, we are first going to bring in our dependencies. Only this time, our dependencies include something we wrote! To do that we simply use `require()` to point to the location of the file we wish to bring in.
120+
121+
We also bring in `@actions/core` so that we can set the output of our action.
122+
123+
Next we write another **asynchronous JavaScript function** that stores the return value of `getJoke()` in a variable called **joke**.
124+
125+
Then we log the joke to the console.
126+
127+
Finally we finish the function with by setting the contents of the joke as the value of the `joke-output` output parameter. We will use this output later in the course.
128+
_Don't forget to call the `run()` function._
129+
130+
### :keyboard: Activity 1: Creating the JavaScript files for your new action.
131+
132+
1. Create and add the following contents to the `.github/actions/joke-action/joke.js` file:
133+
134+
```javascript
135+
const request = require("request-promise");
136+
137+
const options = {
138+
method: "GET",
139+
uri: "https://icanhazdadjoke.com/",
140+
headers: {
141+
Accept: "application/json",
142+
"User-Agent": "Writing JavaScript action GitHub Skills course.",
143+
},
144+
json: true,
145+
};
146+
147+
async function getJoke() {
148+
const res = await request(options);
149+
return res.joke;
150+
}
151+
152+
module.exports = getJoke;
153+
```
57154

58-
```yaml
59-
name: "my joke action"
155+
2. Save the `joke.js` file.
156+
3. Create and add the following contents to the `.github/actions/joke-action/main.js` file:
60157

61-
description: "use an external API to retrieve and display a joke"
158+
```javascript
159+
const getJoke = require("./joke");
160+
const core = require("@actions/core");
62161

63-
outputs:
64-
joke-output:
65-
description: The resulting joke from the icanhazdadjokes API
162+
async function run() {
163+
const joke = await getJoke();
164+
console.log(joke);
165+
core.setOutput("joke-output", joke);
166+
}
66167

67-
runs:
68-
using: "node16"
69-
main: "main.js"
168+
run();
70169
```
71170

72-
2. Save the `action.yml` file
73-
3. Commit the changes and push them to GitHub:
171+
4. Save the `main.js` file.
172+
5. Commit the changes to this branch and push them to GitHub:
74173
```shell
75-
git add action.yml
76-
git pull
77-
git commit -m 'add metadata for the joke action'
174+
git add joke.js main.js
175+
git commit -m 'creating joke.js and main.js'
176+
git pull
78177
git push
79178
```
80-
4. Wait about 20 seconds then refresh this page (the one you're following instructions from). [GitHub Actions](https://docs.github.com/en/actions) will automatically update to the next step.
179+
6. Wait about 20 seconds then refresh this page (the one you're following instructions from). [GitHub Actions](https://docs.github.com/en/actions) will automatically update to the next step.
81180

82181
<footer>
83182

0 commit comments

Comments
 (0)