Github Actions

JaxNode September 2020

Github Actions

  • Introduced 2018 
  • Added instances last year
  • Can tie github events to workflows
  • No configuration of spot instances required
  • Runs off of Docker

Use Cases

  • Continuous Integration
  • Continuous Deployment
  • Bot integration
  • Static Website Builds
  • Image Resizing

CI/CD

  • Devops
  • Setup server
  • Run build
  • Run tests
  • Deploy app

Jenkins

3rd Party

  • Travis CI
  • Circle CI
  • CodeShip
  • MS App Center

Key Terms

  • Workflows
  • Events
  • hosted runner (GitHub/Self)
  • Jobs
  • Actions
  • Steps

Matrix platforms

  • Linux
  • Windows
  • macOS

Cost

  • Free: 2000 mpm
  • Pro: 3000 mpm
  • Team: 3000 mpm
  • Enterprise: 50000 mpm
  • Additional Linux $0.008 minute
  • Additional macOS $0.08 minute
  • Additional Windows $0.016 minute

Workflows

  • Define a workflow
  • Configure using YAML
  • Select from a template
  • .github/worklows/hello.yml

Runners

  • Github provides runners
  • Ubuntu
  • Windows
  • macOS
  • local runners

Actions

  • Github provides standard actions
  • Marketplace for actions
  • Custom actions
  • Create custom actions with either shell or Javascript

Jobs

  • Multiple Jobs per workflow
  • Jobs can be run on different OSes
  • Each job can have multiple steps

Events

  • on:
  • push
  • pull_request
  • issues
  • check_run
  • scheduled
  • gollum
  • fork
on:
  # Trigger the workflow on push or pull request,
  # but only for the master branch
  push:
    branches:
      - master
  pull_request:
    branches:
      - master

Job Steps

  • -name
  • uses: action
  • with: parameter
  • id
  • run: shell command
name: Greet Everyone
# This workflow is triggered on pushes to the repository.
on: [push]

jobs:
  build:
    # Job name is Greeting
    name: Greeting
    # This job runs on Linux
    runs-on: ubuntu-latest
    steps:
      # This step uses GitHub's hello-world-javascript-action: 
      # https://github.com/actions/hello-world-javascript-action
      - name: Hello world
        uses: actions/hello-world-javascript-action@v1.1
        with:
          who-to-greet: 'Mona the Octocat'
        id: hello
      # This step prints an output (time) from the previous step's action.
      - name: Echo the greeting's time
        run: echo 'The time was ${{ steps.hello.outputs.time }}.'

Environment Variables

  • env
  • Referenced in shell or node actions
  • Public
steps:
  - name: Hello world
    run: echo Hello world $FIRST_NAME $middle_name $Last_Name!
    env:
      FIRST_NAME: Mona
      middle_name: The
      Last_Name: Octocat

Secrets

  • reference secrets in workflows
  • Secrets stored in github 'Secrets' in Repo Settings
  • Use GPG to encrypt and decrypt
  • .github/secrets/encryptedfile.gpg

Custom Action

  • Written as shell or Node.js
  • Define action.yml
  • Contains inputs and outputs
  • index.js main entry point
  • keep node_modules in source
  • include @actions/core and @actions/github
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'

action.yml

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);
}

index.js

Included Applications

  • Android
  • ImageMagick
  • Ruby
  • Node.js
  • Azure CLI
  • Docker
  • Clang
  • Chrome
  • TypeScript
  • Webpack

Demo

Questions?