# GitHub Actions

## Summary


In any software project, there are repetitive tasks that can benefit from automation. Code reviews, branch management, pull request labelling, regression testing, issue triaging, release management, npm package publication, and cloud deployment are examples of such tasks. These are hard to do manually or consistently. GitHub Actions is feature of GitHub to automate these tasks. 

Before 2018, third-party tools and services such as CircleCI, Jenkins and Travis CI were used to automate some of these tasks. Bots automated repetitive tasks. With GitHub Actions, it's now possible to do these more easily within the GitHub platform for code hosted at GitHub.

The GitHub Marketplace has thousands of free GitHub Actions shared by developers. This improves productivity for developers and teams. Actions can be executed for private/public repositories under free/paid plans, though limits differ.

## Discussion

### What are the use cases for GitHub Actions?

While there are thousands of tasks that could be automated with GitHub Actions, we mention a few. The notable use case is CI/CD in which every commit triggers a build-and-test cycle so that code merges become simpler and errors are caught proactively. 

When making a software release, with Actions we can build the software for multiple architectures in parallel.  Likewise, for software testing or code coverage, we can exercise the software across all variations of platform versions, browsers, operating systems, etc. 

Before publishing container images to a registry, it's a good idea to scan them for security vulnerabilities. After scanning, the resulting metadata is checked against security policies for compliance. These tasks can be part of a GitHub Actions workflow. 

GitHub itself uses Actions to track vulnerabilities in open source components they use. When an issue is raised, a workflow updates an internal database and reports it as per security policies. 


### What are the components of GitHub Actions?

We describe the following components:  

    + **Workflow**: Encapsulates a specific automation. Defined in a configurable YAML file at `.github/workflows` within the repository. A repository can have multiple workflows.
    + **Event**: Triggers a workflow. Pull request, new commit and new issue are examples of events. A REST API call, a manual trigger or a defined schedule can also trigger workflows. See the full list of events.
    + **Job**: A sequence of steps that define the actual execution of a workflow. A shell script or an action is executed. A workflow can have one or more jobs. Jobs can be defined to run in parallel or in sequence. Steps within a job are sequential and can share data.
    + **Action**: A custom application for the GitHub Actions platform. Encapsulates repetitive tasks and enables code reuse across workflows. Actions are steps in a job. Configured in a YAML file at `.github/actions`.
    + **Runner**: A server that runs a workflow. A runner runs a single job. GitHub provides Ubuntu Linux, Microsoft Windows, and macOS runners. Projects can also use self-hosted runners. Each workflow run creates a new virtual machine.

### Could you describe some important features of GitHub Actions?

**Reusability** is an essential feature. A workflow can reuse actions defined in the same repository, a public repository or a published image on Docker Hub. A workflow itself can be reused if defined in the same repository or a public repository. 

Actions can use **variables**. These are name-value pairs under `env`, which can be scoped to the entire workflow, a job or a step. In addition, workflows can use default environment variables. Examples include `GITHUB_ACTION_PATH`, `GITHUB_EVENT_NAME`, `GITHUB_RUN_ID`, `RUNNER_ARCH`, `RUNNER_OS`, and many more. 

**Expressions** are those within `${{…}}`. In conjunction with `if`, they can be used to execute jobs or steps conditionally. Expressions include literals (`null`, `true`, `false`, numbers, strings), operators (index, compare, logical, etc.) and functions (`contains`, `startsWith`, `join`, `toJSON`, etc.). 

**Contexts** are objects that contain useful information. Available contexts include `github`, `env`, `job`, `steps`, `runner`, `secrets`, `strategy`, `matrix`, `needs`, and `inputs`. Default environment variables exist only on the runner. In other parts of the workflow, use contexts. For example, `if: ${{ github.ref == 'refs/heads/main' }}` executes the job only if the current branch is `main`. 


### What's the mechanism to pass data among jobs and workflows?

To set an environment variable, here's an example showing two ways to do it: `echo "action_state=yellow" >> $GITHUB_ENV` within a `run` or `action_state: yellow` within `env` context. Subsequent steps of the job can access it via `env.action_state`. In shells, it can be accessed as `$action_state` (Linux) or `$env::action_state` (PowerShell). 

Suppose *job2* depends on *job1*. Via `outputs` property, *job1* can pass data to *job2*, which can access it via the `needs` context. **Workflow artifacts** allow for persistent data across jobs of the same workflow. Common artifacts include log files, core dumps, test results, code coverage results, screenshots, and binary files. 

To pass inputs to a workflow, the property `inputs` can be used. Each input has a name and sub-properties `description`, `type`, `default` and `required`. Within the workflow, inputs can be accessed via `github.event.inputs`. 


### What's the platform and language support for GitHub Actions?

GitHub Actions is supported on Linux, Windows and macOS platforms. Workflows can be configured to use specific versions of these platforms or the latest version. This is specified via the job property `runs-on`. Another useful feature **build matrix**. With a single job definition, developers can execute variations of the job in parallel, such as for different OS or Node versions. This is specified with the job property `strategy.matrix`. 

For programming actions, GitHub Actions supports C, C++, C#, Go, Java, JavaScript, PHP, Python, Ruby, Scala, and TypeScript. 

Within a Docker environment any platform and any language can be used. The job property `container` includes container configuration including image, environment, ports and volumes to use. A developer can releases Docker images for various architectures.To facilitate this, Docker has published actions for QEMU setup (`docker/setup-qemu`), enhanced build capability (`docker/setup-buildx`), Docker Hub authentication (`docker/login-action`), and build and push images to Docker Hub (`docker/build-push-action`). 


### What are some best practices for GitHub Actions?

Keep actions minimal to reduce wait times and favour reuse. Install only necessary dependencies. In fact, leverage GitHub's feature that can cache dependencies. In case of Node.js, publish the entire `node_modules` folder. Don't pollute the global environment with lots of variables. Variables can be scoped to narrower levels such as a job or a step. Don't overwrite default environment variables. To attribute action to authors, use the `author` metadata in YAML file. Version actions properly. Test actions before releasing them. 

From a security standpoint, avoid self-hosted runner in a public repository. Someone could take a fork and submit a pull request with malicious code. Use GitHub web interface to manage secrets. Never hardcode these actions in a YAML file. Don't dump context data into logs since this could expose sensitive information. 

Many Marketplace actions are not certified by GitHub. Have a security policy to either fully block them or allow them via forking. When reusing actions, pick a stable version rather than the latest on the master branch. 


### What tools can help developers create GitHub Actions?

For many common use cases, developers need not create actions from scratch. The GitHub Marketplace has 12,000+ actions shared by developers and organizations. Of these, nearly 300 are from verified creators. Marketplace actions are grouped into many categories: API management, code quality, continuous integration, dependency management, IDEs, mobile, monitoring, security, testing, and more. 

Beginners can start with the official documentation. The GitHub Actions guides has tutorials and overviews on specific use cases. Take a look at the course material of GitHub Actions: Hello World. For a summary, consult the Actions Cheat Sheet.

Details of VMs used by GitHub-hosted runners are available.

Those using other CI/CD tools can read the migration guides. These are available for Azure Pipelines, CircleCI, GitLab CI/CD, Jenkins and Travis CI.

To help developers build actions easily, toolkits are available. The official toolkit supports JavaScript, TypeScript and Docker. An alternative is Etcovitch's toolkit. A curated list of GitHub Actions is also available online.

## Milestones

Apr  
2008

**GitHub** is launched as an online software repository that uses Git, a decentralized version control system. By July, GitHub hosts 10,000 repositories. It's particularly popular among open source and Rails communities. 

Oct  
2018

Microsoft is in the process of acquiring GitHub. About the same time, **GitHub Actions is announced**. This makes GitHub more than just a code repository. Workflows can be automated. Sam Lambert, GitHub's platform head, describes this as "the biggest shift we've had in the history of GitHub." 

Nov  
2018

A study of 351 sampled open source projects on GitHub finds that 93 (26%) use bots. This excludes the newly launched GitHub Actions. Bots are used for ensuring license agreement signing, reporting integration failures, reviewing code, reviewing/merging pull requests, assigning reviewers, welcoming newcomers, running automated tests, building, creating issues, and more. 

Nov  
2019

Due to popular demand from developers, support for **CI/CD** becomes generally available. An example CI/CD pipeline would be to trigger a build and deploy to Heroku whenever a new commit happens on the master branch. Based on the project, GitHub can suggest suitable Actions workflows. It's now easy to publish/consume packages from GitHub Package Registry and other registries. Beta version of this feature was announced in August.  

Sep  
2020

With the release of GitHub Enterprise Server 2.22, GitHub Actions is for the first time **supported in GitHub Enterprise Server**. This includes support for enterprise features such as centralized self-hosted runners, runner groups to manage access controls, and custom workflow templates. By now, GitHub Actions is the most popular CI solution on GitHub.com. 

Mar  
2021

Kinsman et al. publish results of a study on how developers are using GitHub Actions on open source projects. The study considers the period Nov 2019 to Aug 2020. Of the 416k+ active repositories, only 0.7% are using actions. Python, Java and Ruby repositories are the top adopters. Common actions include repository checkout or environment setup. Most actions are in the categories of continuous integration, utilities and deployment. They also find that Actions doesn't result in faster merges of pull requests. 

Oct  
2021

Beta version of **reusable workflows** is introduced. Repetitive tasks can be encapsulated into actions or workflows. This reduces duplication and brings consistency. Like actions, workflows support inputs and outputs to pass data. In November, this feature becomes generally available. 

Feb  
2022

At the GitHub Marketplace, there are now 12,000+ Actions that developers can readily use.