GitHub Actions Workflows

Posted on
Contents

GitHub Actions provide a great way to automate all parts of your development workflow. I often use the same workflows between open-source projects I work on. I’ve added the workflow configs below so feel free to copy and paste them to your projects.

CodeQL

CodeQL is GitHub’s code security checking engine and this action runs a repository’s source code to find security vulnerabilities. It then displays the results in the repository’s security tab.

Note: This is only available for public repositories (or private repositories that have GitHub Advanced Security licensed)

Code snippet
name: "CodeQL"

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  analyze:
    name: Analyze
    runs-on: ubuntu-latest
    permissions:
      actions: read
      contents: read
      security-events: write

    strategy:
      fail-fast: false
      matrix:
        language: [ 'javascript' ]

    steps:
    - name: Checkout repository
      uses: actions/checkout@v3

    - name: Initialize CodeQL
      uses: github/codeql-action/init@v2
      with:
        languages: ${{ matrix.language }}

    - name: Perform CodeQL Analysis
      uses: github/codeql-action/analyze@v2

More info

Dependency Review

This one scans your pull requests for dependency changes and will raise an error if any newly added dependencies have existing vulnerabilities.

Note: This is only available for public repositories (or private repositories that have GitHub Advanced Security licensed)

Code snippet
name: 'Dependency Review'
on: [pull_request]

permissions:
  contents: read

jobs:
  dependency-review:
    runs-on: ubuntu-latest
    steps:
      - name: 'Checkout Repository'
        uses: actions/checkout@v3
      - name: 'Dependency Review'
        uses: actions/dependency-review-action@v1

More info

cSpell (Spellcheck)

I’ve been happily using the VS Code extension of this for many years. The GitHub Action workflow is good for helping catch typos from contributors at the pull request stage. I recommend adding a cspell.json config to your projects root, adding any false-positives to the dictionary and checking it in to git.

Code snippet
name: 'Check spelling'
on: # rebuild any PRs and main branch changes
  pull_request:
    branches-ignore:
      - "dependabot/**"

permissions:
  contents: read

jobs:
  spellcheck: # run the action
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: streetsidesoftware/cspell-action@v1
        with:
          inline: warning
          strict: false
          incremental_files_only: true

More info

Test

If you have a test script defined in your package.json then you can set this to run on every PR.

Code snippet
name: Lint

on:
  push:
    branches-ignore:
      - "dependabot/**"
  pull_request:

env:
  FORCE_COLOR: 2
  NODE: 16

permissions:
  contents: read

jobs:
  lint:
    runs-on: ubuntu-latest

    steps:
      - name: Clone repository
        uses: actions/checkout@v3

      - name: Set up Node.js
        uses: actions/setup-node@v3
        with:
          node-version: "${{ env.NODE }}"
          cache: npm

      - name: Install npm dependencies
        run: npm ci

      - name: Lint
        run: npm run lint

Super Linter

This project from the folks at GitHub bundles a huge number of linters. You can tweak the linting configs or disable linting for a particular type. I recommend including this even if you have a test GitHub Action as above as Super Linter can test for additional files such as GitHub Actions.

Code snippet
name: Lint Code Base

on:
  push:
    branches-ignore:
      - "dependabot/**"

permissions:
  contents: read

jobs:
  build:
    name: Lint Code Base
    runs-on: ubuntu-latest

    steps:
      - name: Checkout Code
        uses: actions/checkout@v3

      - name: Lint Code Base
        uses: github/super-linter/slim@v4
        env:
          VALIDATE_ALL_CODEBASE: false
          DEFAULT_BRANCH: main
          JAVASCRIPT_DEFAULT_STYLE: prettier
          VALIDATE_MARKDOWN: false
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

More info

Wrap up

I recommend to always keep a dependabot.yml config file in your repo’s .github directory with something like the below to ensure you get PRs to update to any new versions of GitHub Actions as they become available.

version: 2
updates:
  - package-ecosystem: github-actions
    directory: "/"
    schedule:
      interval: monthly

I personally like to have them set on a monthly schedule to cut down on noise but you can change that to daily or weekly.

You can do so much more with GitHub Actions - check the Advanced workflow features docs on GitHub for more ideas.

You might also like