Automate All the Things with GitHub Actions

Michael Born

  • My eyebrows are different colors
  • My yodeling stinks
  • I once biked 72 miles in 6 hours
  • Favorite hobbies:
  • Falling off my bike
  • Hitting my thumb with a hammer
  • Bad puns

GA: What and Why

  • What is it
  • Why does it exist
  • What can I do with it?

What Is It?

Github Actions is an event-driven automation tool for github repositories, and utilizes open-source "Actions" for condensed, reusable configuration

Why Does it Exist?

  • Test your code
  • Improve code quality
  • notify Slack of a test failure
  • etc, etc
  • without leaving GitHub

GA makes it simple to:

Example

  • User creates GitHub issue
  • GitHub Actions run on "issues" event
  • Action assigns "Needs Triage" tag

Example

  • User pushes up bugfix PR
  • Github Actions run
  • CFFormat formats the bugfix
  • Cleaner PR
  • Easier to merge
  • Everyone is happier

GA: Terms and Tools

  • What is a workflow?
  • What is an action?
  • What is the Github Marketplace?

What is a Workflow?

The workflow is an automated procedure that you add to your repository. Workflows are made up of one or more jobs and can be scheduled or triggered by an event. The workflow can be used to build, test, package, release, or deploy a project on GitHub.

"Understanding Github Actions"

What is an Action?

Actions are standalone commands that are combined into steps to create a job. Actions are the smallest portable building block of a workflow. You can create your own actions, or use actions created by the GitHub community.

"Understanding Github Actions"

What is Github Marketplace?

Github Marketplace is a public search directory for shared actions.

GA: First Workflow

GA: First Workflow

What would a CFFormat workflow look like?

  1. When a pull request is opened:
  2. Install Java
  3. Install CommandBox
  4. Install commandbox-cfformat
  5. Run CFFormat
  6. Commit the changes

GA: First Workflow

on: pull_request

jobs:
  format:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Repository
        uses: actions/checkout@v2

      - name: Setup Java
        uses: actions/setup-java@v2
        with:
          distribution: "adopt"
          java-version: "11"

      - name: Set Up CommandBox
        uses: elpete/setup-commandbox@v1.0.0

      - name: Install CFFormat
        run: box install commandbox-cfformat

      - name: Run CFFormat
        run: box cfformat run path=models,tests/specs --overwrite

      - name: Commit Format Changes
        uses: stefanzweifel/git-auto-commit-action@v4
        with:
          commit_message: "👌 IMPROVE: Auto-format cfcs via cfformat"

Problems

So Slow!

So Much Config!

So Complex!

Solution

  1. Reusable actions
  2. Single-purpose workflows

Solution

Instead of this:

  • pr.yml
    • Formatting
    • Fixinator
    • Testing

Solution

Do this:

  • cfformat.yml
  • fixinator.yml
  • testbox.yml

Introducing

steps:
  - uses: Ortus-Solutions/commandbox-action@v1
    with:
      cmd: cfformat run models,handlers,tests/specs --overwrite
  • Great for one-off commands
  • CFFormat
  • DocBox
  • Box Install

CommandBox Action

steps:
  - uses: Ortus-Solutions/semantic-release-action@v1
    with:
      githubToken: ${{ secrets.GH_TOKEN }}
      excludeCommit: ${{ github.event.head_commit.message }}
      forgeboxToken: ${{ secrets.FORGEBOX_TOKEN }}
      branch: main
  • Uses commandbox-semantic-release
  • Read commits
  • Bump package version
  • Update changelog
  • Push GitHub release
  • Push ForgeBox version

Semantic Release Action

steps:
  - name: Run Fixinator Security Scan
    uses: Ortus-Solutions/fixinator-action@v1
    with:
      api_key: ${{ secrets.FIXINATOR_KEY }}
      path: ModuleConfig.cfc,models
      confidence: medium
      severity: low

Fixinator Action

  • GitHub Action for Fixinator
  • Scan your CFML for vulns
  • Specify path to scan
  • Confidence level
  • Severity level
steps:
  - name: Run tests
    uses: Ortus-Solutions/testbox-action
    with:
      cfengine: lucee@5.3.8

Coming Soon: TestBox Action

  • Start Server
  • Run Tests
  • Specify CF Engine
  • Specify server config file
  • Specify JUNIT result file path

Practical Github Actions for CFML

  1. Formatting CFML
  2. Generating model docs
  3. Running Fixinator audits
  4. Publishing on ForgeBox

Formatting CFML

  1. Checkout repository
  2. Run cfformat
  3. Commit file changes
name: CFFormat

on: [push, pull_request]

jobs:
  format:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repo
        uses: actions/checkout@v2
      
      - name: Run CFFormat
        uses: Ortus-Solutions/commandbox-action@v1
        with:
          cmd: cfformat run path=models,tests/specs --overwrite
      
      - name: Commit Format Changes
        uses: stefanzweifel/git-auto-commit-action@v4
        with:
          commit_message: "👌 IMPROVE: Auto-format cfcs via cfformat"

Generating Model Docs

  1. Checkout repository
  2. Run docbox
  3. Commit file changes
  4. Github will auto-deploy the new docs to Github Pages
name: DocBox

on: [push, pull_request]

jobs:
  format:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Repo
        uses: actions/checkout@v2
      
      - name: Generate Docs
        uses: Ortus-Solutions/commandbox-action@v1
        with:
          cmd: docbox generate mapping=cfPlaid excludes=test|ModuleConfig strategy-outputDir=docs strategy-projectTitle=cfPlaid
      
      - name: Commit Docs to Repo
        uses: stefanzweifel/git-auto-commit-action@v4
        with:
          commit_message: "📖 DOC: Auto-generate DocBox API docs"

Running Fixinator Scans

  1. Create FIXINATOR_KEY repo secret
  2. Checkout repository
  3. Run fixinator with secrets.FIXINATOR_KEY
  4. Fixinator will fail the build if it identifies any security issues
  5. Publish Junit report
name: Fixinator

on: [push, pull_request]

jobs:
  audit:
    name: Fixinator
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Repo
        uses: actions/checkout@v2
      
      - name: Run Fixinator Security Scan
        uses: Ortus-Solutions/fixinator-action@v1
        with:
          api_key: ${{ secrets.FIXINATOR_KEY }}
          path: ModuleConfig.cfc,models
          confidence: medium
          severity: low

Publishing on ForgeBox

  1. Create GH_TOKEN repo secret
  2. Create FORGEBOX_TOKEN repo secret
  3. Checkout repository
  4. Run semantic-release-action
name: Fixinator

on: [push, pull_request]

jobs:
  release:
    name: Semantic Release
    if: "!contains(github.event.head_commit.message, '__SEMANTIC RELEASE VERSION UPDATE__')"
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repo
        uses: actions/checkout@v2

      - name: Push new Release
        uses: Ortus-Solutions/semantic-release-action@v1
        with:
          githubToken: ${{ secrets.GH_TOKEN }}
          excludeCommit: ${{ github.event.head_commit.message }}
          forgeboxToken: ${{ secrets.FORGEBOX_TOKEN }}
          branch: main

Giveaway Time!

Giveaway!

@michaelborn_me

DM me your GitHub repo on Twitter.

I'll PR a GitHub Actions workflow

Michael Born

Software Engineer

Ortus Solutions, Corp

 

@michaelborn_me

ITB 2021: Automate All the Things with GitHub Actions

By Michael Born

ITB 2021: Automate All the Things with GitHub Actions

  • 464