Running A Javascript Github Action
4 min readFeb 13, 2021
The aim of this tutorial🔍 is to offer both a hello-world and a real-world example of a successfully set up and executed JavaScript Github Action.
1. Prerequisites
1.1. Setup a Project (github repo, npm init)
- create a new repo
- clone locally
- run
npm init -y
to initialize a node project by creating apackage.json
Wrote to C:\Users\Admin\Documents\workspace\SNOW\hello-world-javascript-action\package.json:{
"name": "hello-world-javascript-action",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/pkutaj/hello-world-javascript-action.git"
},
"keywords": [],
"author": "",
"license": "ISC",
"bugs": {
"url": "https://github.com/pkutaj/hello-world-javascript-action/issues"
},
"homepage": "https://github.com/pkutaj/hello-world-javascript-action#readme"
}
1.2. Add NPM Github Actions Toolkit Packages
- use
npm
to install 2 required packages from the toolkit @actions/core
→ interface to the workflow commands, input, output variables, exit statuses, debug messages@actions/github
→ returns an authenticated Octokit REST client; provides access to Github Actions contexts- to install, run
- run
npm install @actions/core
- run
npm install @actions/github
â–¶ npm install @actions/core
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN hello-world-javascript-action@1.0.0 No description+ @actions/core@1.2.6
added 1 package and audited 1 package in 0.742s
found 0 vulnerabilities~\Documents\workspace\SNOW\hello-world-javascript-action î‚ master ≢ +4 ~0 -0 ! ⚡ ⨯
â–¶ npm install @actions/github
npm WARN hello-world-javascript-action@1.0.0 No description+ @actions/github@4.0.0
added 21 packages from 56 contributors and audited 22 packages in 4.408s
found 0 vulnerabilities
2. Action Metadata
Docker and JavaScript actions require a metadata file. The metadata filename must be either action.yml or action.yaml. The data in the metadata file defines the inputs, outputs, and main entry point for your action.
- Action Metadata File == AMF
- location: root of the repo (
./
) - name:
action.yaml
- it has a specific metadata syntax for GitHub Actions — GitHub Docs
- in essence you have 4 required keys
Name:
Action NameDescription:
Action’s descriptionRuns: using:
What application are you using to execute the codeRuns: main:
The actual file containing the action code (what is being executed)
- There are other optional fields as well, as illustrated in the Hello World AMF
2.1. Hello-World AMF
- this is from the exemplary GitHub’s action metadata file that
- defines input:
who-to-greet
- defines output:
time
- tells the action runner hot to start running this actions
name: 'Hello World'
description: 'Greet someone and record the time'
inputs:
who-to-greet: # id of input
description: 'Who to greet'
required: true
default: 'World'
outputs:
time: # id of output
description: 'The time we greeted you'
runs:
using: 'node12'
main: 'index.js'
2.2. Real-World AMF
- This is the bare bones essential with the 4 required fields
name: 'Publish to Zendesk'
description: 'Publish Markdown to Zendesk'
runs:
using: 'node12'
main: 'publish.js'
3. Action
- Action == Code to be executed by a SQL runner that is in a separate file or a repo
3.1. Hello-World Action
- create
index.js
as defined in the metadata and populate with your code, for example with
const core = require('@actions/core');
const github = require('@actions/github');try {
// `who-to-greet` input defined in action metadata file
const nameToGreet = core.getInput('who-to-greet');
console.log(`Hello ${nameToGreet}!`);
const time = (new Date()).toTimeString();
core.setOutput("time", time);
// Get the JSON webhook payload for the event that triggered the workflow
const payload = JSON.stringify(github.context.payload, undefined, 2)
console.log(`The event payload: ${payload}`);
} catch (error) {
core.setFailed(error.message);
}
3.2. Real-World Action
- Running a fork of docs/publish.js at master · JupiterOne/docs
- It is in a private repo, but a variation of publishing markdown files within the repo into zendesk
4. Workflow
- required
- it has to be in a location
repo\.github\workflows\main.yaml
- if you are not running a shared public action it must include a public action called Checkout
- the
uses
key points to a repository whereaction.yml
is located
4.1. Hello-World Workflow
on: [push]jobs:
hello_world_job:
runs-on: ubuntu-latest
name: A job to say hello
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Hello world action step
id: hello
uses: ./
with:
who-to-greet: 'Mr Paul'
# Use the output from the `hello` step
- name: Get the output time
run: echo "The time was $"
4.2. Real-World Workflow
on: [push]jobs:
publish_to_zendesk:
runs-on: ubuntu-latest
name: Publish to Zendesk
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Publish
id: publish
uses: ./
- name: Commit
run: |
date > generated.txt
git config user.name github-actions
git config user.email github-actions@github.com
git add .
git commit -m "generated"
git push
5. Commit && Push
- During the runtime of a workflow, github downloads each action used there
- Actions are executed as s complete packages of code before commands like
run
can be used - It follows, that any package dependencies must be included
- Shared prerequisites are core and github npm packages checked in the action repo
6. Summary: required items to be commited
action.yml
index.js
any code to be executednode_modules
package.json
package-lock.json
README.md
being optional