Data report"State of code review 2024" is now liveRead the full report

GitHub Actions and code automation

Kenny DuMez
Kenny DuMez
Graphite software engineer

GitHub Actions is a powerful platform built into GitHub that lets you create and run various code automations. These automations can help streamline repetitive or complex tasks, such as testing new changes, deploying releases, and running static code analyzers to detect bugs in code.

GitHub Actions consist of five core components:

Diagram illustrating the five core components of GitHub Actions

  1. Workflows define a sequence of jobs to execute when an event occurs. These jobs can be run in sequence or in parallel. You develop workflows in YAML files in your repository's .github/workflows/ folder.
  2. Events, when raised, are used to trigger workflows. Different activities, both in GitHub and in external systems, can raise events. Scheduled events can also run workflows at certain times. Following are some common events:
    • push: This event runs whenever a new commit or tag is pushed to the repository.
    • pull_request: This event runs whenever activity occurs on a pull request, such as opening or merging a pull request.
    • schedule: This event lets you schedule a task to run using a cron schedule.
  3. Jobs are the building blocks of a workflow. Each job contains sequential steps that execute on the same runner.
  4. Actions are reusable blocks of logic that run tasks in your jobs. Actions can be a simple shell script or a complex, prebuilt application packaged into an action. You can search for prebuilt actions in the GitHub Marketplace or create your own.
  5. Runners are virtual machines or containers that execute a job. GitHub provides runners for all major operating systems. You can also host a runner on your server for more flexibility and control.

Many companies and individuals have developed prebuilt actions in the GitHub Marketplace, letting you build almost any automation for your repository. Following are some examples of use cases you might implement for your repository.

Creating a pull request can be daunting for first-time contributors. GitHub Actions lets you post a welcome message on the contributor's pull request, welcoming them and explaining the contribution process:

Terminal
name: First Pull Request Greeting
on: [pull_request_target]
jobs:
greeting:
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- uses: actions/first-interaction@v1
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
pr-message: |
Hey there 👋
Congrats on creating your first pull request in the Example repository. We're grateful to you for taking the time and contributing to this fantastic project.
This project conforms to [Airbnb's JavaScript Style Guide](https://airbnb.io/javascript/react/). ESLint will find any code that doesn't conform and highlight it for you. Once you've fixed the issues, the linter will ensure everything looks and then one of the maintainers will glance through the pull request and approve it.
Please get in touch with any of the maintainers in the Discussions tab if you have any questions.

The name property contains the display name for the workflow. The workflow triggers are then configured using the on property. In this case, this workflow will execute whenever the pull_request_target event occurs in the repository. You can specify one or more jobs as part of the workflow in the jobs property. This workflow contains a single greeting job which runs on an Ubuntu runner and uses the actions/first-interaction action to respond to a pull request if it’s the contributor’s first change in the repository.

GitHub Actions lets you run continuous integration (CI) in your repository. These processes include building code every time it changes, executing integration and unit tests, and running static code analyzers to find bugs and optimizations.

The following workflow demonstrates how to run unit tests for a TypeScript project when a new pull request is opened or merged into the main branch:

Terminal
name: Build and Test Node.js
on:
push:
branches: ['main']
pull_request:
branches: ['main']
jobs:
# Define a build job
build:
runs-on: ubuntu-latest
# Define steps in the job
steps:
- uses: actions/checkout@v3
# Installs Node.js v20 to build and test the app
- name: Use Node.js
uses: actions/setup-node@v3
with:
node-version: 20.x
# Install the NPM dependencies
- name: NPM Install
run: npm install
# Build the TypeScript application
- name: NPM Build
run: npm run build
# Run the tests
- name: NPM Test
run: npm test

Similar to the first workflow, the display name and triggers are defined using the name and on properties. In this case, the workflow is triggered by a push or pull_request event on the main branch of the repository. The workflow also contains a single job called build to be run on an Ubuntu runner. The job downloads Node.js, checks out the repository and runs tests in the code base. Each action is either a package from GitHub Marketplace, like actions/checkout@v3 and actions/setup-node@v3, or a bash command that gets executed on the runner, like npm install.

While powerful, GitHub Actions do have some limitations:

Graphite
Git stacked on GitHub

Stacked pull requests are easier to read, easier to write, and easier to manage.
Teams that stack ship better software, faster.

Or install our CLI.
Product Screenshot 1
Product Screenshot 2