GitHub Actions is an end-to-end GitHub-centric SDLC process. It provides an automation platform and framework previously missing from GitHub and had to be added with other solutions, such as Jenkins or Travis CI.

|600
Relationship of GitHub Actions components

Components

Triggering Workflows

An event can be defined in several different ways:

This can be described with the on command. Here are a set of examples:

on: push
on: [push, pull_request]
on:
  push:
    branches:
      - main 
      - 'rel/v*'
    tags:
      - v1.*
      - beta  
    paths:
      - '**.py'
on:
  scheduled:
    - cron: '30 5,15 * * *'
on: [workflow-dispatch, repository-dispatch]
on: workflow_call
on: issue_comment

The workflow file should be in the default branch.

Steps

steps:
- uses: actions/checkout@v3
- name: setup Go version
  uses: actions/setup-go@v2
  with:
    go-version: '1.14.0'
- run: go run helloworld.go

Runners

Runners are the physical or virtual computers or containers where the code for a workflow is executed. They can be systems provided and hosted by GitHub (and run within their control) or instances you set up, host, and control.
In either case, the systems are configured to understand how to interact with the GitHub Actions framework. They can interact with GitHub to access workflows and predefined actions, execute steps, and report outcomes.

runs-on: ubuntu-latest

GitHub hosted vs Self-Hosted runners

Category GitHub-hosted Self-hosted
Provisioning/hosting Managed by GitHub Managed by you
Prereqs Running GitHub actions runner application (handled by GitHub) GitHub Actions self-hosted runner application deployed and configured
Platforms Windows, Ubuntu Linux, MacOS Any from the supported architectures and platforms that you choose
Configurability Constrained mostly to predefined configurations Highly configurable
Ownership GitHub As defined
Lifetime Clean instance for the life of a job As defined
Cost Free minutes based on your GitHub plan with cost for overages Free to use with actions, but owner is responsible for any other cost
Automatic updates GitHub provides for the OS, installed packages, tools, and hosted runner application GitHub provides only for self-hosted runner application
Implementation Virtual Virtual or physical

Limits for Self-Hosted Runners

There are limits imposed on Actions usage when you use self-hosted runners. As of the time of this writing, the limits are those shown in Table 5-4.

Table 5-4. Self-hosted runner limits:

Category Limit Action if limit is reached/exceeded
Workflow run time 35 days Workflow canceled
Job queue time 24 hours Job terminated if not started
API requests 1,000 per hour across all actions in a repository Additional API calls will fail
Job matrix 256 jobs per workflow run Not allowed
Workflow run queue 500 workflow runs per 10-second interval per repository Workflow run terminated and fails to complete
Queuing by GitHub Actions Within 30 minutes of being triggered Workflow not processed (this would most likely only occur if GitHub Actions services are unavailable for an extended time)
Runners provide the required infrastructure to execute your workflows and thus, GitHub Actions. Runners can be automatically provided by GitHub through their hosting, or you can download the Runner app and use your own systems as runners. Each has advantages and disadvantages, including key factors such as cost, maintenance, control, configurability, and simplicity. Hosted runners are available for Ubuntu Linux, Windows, and macOS for preselected operating system versions and on standardized virtual systems. GitHub periodically updates and maintains these standardized environments.

Your workflows can choose a particular runner through the runs-on clause for each job in your workflow. You can also utilize standard OS commands (like calls to apt or brew) to install additional software on the systems if needed.

Self-hosted runners can be made ephemeral so that they execute only one job. This is desirable for autoscaling solutions such as the ARC.

Jobs

Jobs aggregate steps and define which runner to execute them on. An individual job is usually targeted toward accomplishing one particular goal of the overall workflow. An example could be a workflow that implements a CI/CD pipeline with separate building, testing, and packaging jobs.

Aside from the definition of the runner, a job in a workflow is like a function or procedure in a programming language. It comprises a series of individual commands to run and/or predefined actions to call, similar to how a function or procedure in a programming language is made up of individual lines of code and/or calls to other functions or procedures.
Building on the steps and runners previously shown, the next listing shows a simple job that does the checkout and setup and performs a build:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: setup Go version'
        uses: actions/setup-go@v2
        with:
          go-version: '1.14.0'
      - run: go run helloworld.go

Workflow

workflow is like a pipeline. At a high level, it first defines the types of inputs (events) it will respond to and under what conditions it will react to them. This is what we talked about in the earlier section on events. If the events and conditions match, the response is to execute the series of jobs in the workflow, which, in turn, executes the steps for each job.

The overall flow is like a continuous integration process in that it responds to a particular kind of change and kicks off an automated sequence of work. The next listing shows an example of a simple workflow for processing Go programs built on the previous definitions:

1. name: Simple Go Build
2.
3. on:
4.   push:
5.     branches:
6.       - main
7.
8. jobs:
9.   build:
10.    runs-on: ubuntu-latest 
11.    steps:
12.      - uses: actions/checkout@v3
13.      - name: Setup Go version
14.        uses: actions/setup-go@v2
15.        with:
16.          go-version: '1.15.1'
17.      - run: go run hello-world.go
Workflows versus Actions

Think of actions as plug-ins or modules in other applications.
The workflows are more like the pipelines or scripts that use those modules or plug-ins.

Context Purpose Example properties
github Data attributes about the workflow run and the event that triggered the run. github.ref

github.event_name

github.repository
env Variables that have been set in a workflow, job, or step. env.<env_name> (to retrieve value)
vars Configuration variables set for a repository, environment, or organization (see also Chapter 12). vars.<var_name> (to retrieve value)
job Information about the currently running job. job.container

job.services

job.status
jobs Only available for reusable workflows. Used to set outputs from reusable workflows. jobs.<job_id>.results

jobs.<job_id>.outputs
steps If a step has an id property associated with it and has already run, this contains information from the run. steps.<step_id>.outcome

steps.<step_id>.outputs
runner Information about the runner executing the current job. runner.name

runner.os

runner.arch
secrets Contains names and values associated with a secret; not available in composite workflows but can be passed in. secrets.GITHUB_TOKEN

secrets.<secret_name> (to retrieve value)
strategy If a matrix is used to define a set of items to execute across, this context contains information about the matrix for the current job. strategy.job-index

strategy.max-parallel
matrix For workflows that use a matrix, contains the matrix properties that apply to the current job. matrix.<property_name>
needs Used to collect output from other jobs; contains output from all jobs that are defined as a direct dependent of the current job. needs.<job_id>

needs.<job_id>.outputs

needs.<job_id>.outputs.<output name>
inputs Contains input properties that are passed in to an action, a reusable workflow, or a manually triggered workflow. inputs.<name> (to retrieve value)

|800
Review-based workflow deployment is also possible.

GitHub Actions provides several ways to get and set properties of the environment for use in your workflows. Contexts provide data properties associated with key categories such as GitHub, runners, and secrets.

Environment variables can be used to set values in a single workflow and referenced via the env context. Configuration variables can be set at the repository or organizational level, providing mappings for use across workflows. Secrets serve a similar purpose but encapsulate data that needs to be handled securely.

When your workflow needs to access key information or interact more directly with the repository, you may need to adjust its permissions. This can be done by assigning more permissions to the built-in GITHUB_TOKEN. Permissions should be the minimum needed for the workflow or job to accomplish what is needed.

Deployment environments give you a way to provide destinations to deploy items from your workflow into separate areas. You can configure protection rules, tokens, and variables unique to the environment and associate an environment to a job. This setup allows you to exercise more control over what conditions can be used to run your jobs, provide exclusive data values, and provide a way to differentiate your workflow runs for different levels, such as dev, test, prod.

GitHub Actions provides a number of built-in features to help you understand the execution of your workflow runs at multiple levels. This includes clear, easy-to-find status information in the browser interface through the list of workflow runs, job graphs, and selectable filters.

At a lower level, you can dig into logs and turn on debugging information for the steps in your workflow that will be visible in your logs.

At the deepest level, you can enable runner diagnostic logs to see exactly what is being executed on the runner system throughout a workflow run. These logs are generated separately and must be downloaded to access and view.

When you want to provide more diagnostic or information messages in your logging, Actions makes that easy to do with simple workflow commands that can be used to echo out different messages.

Finally, when your jobs are completed, you can provide customized job summaries with as much detail as needed/desired.

name: Verify existence of CONTRIBUTING.md file

on:
  push:
  pull_request:
   
jobs:
  verify:
    runs-on: ubuntu-latest
    
    steps:
      - uses: actions/checkout@v3
      - run: |
          [[ -f CONTRIBUTING.md ]] || 
( echo "CONTRIBUTING.md file needs to be added to 
${{ github.repository }} !" && exit 1 )
    strategy:
      matrix:
        prod: [prod1, prod2]
        level: [dev, stage, rel]
        include:
          - prod: prod3
            level: dev
            tag: alpha
        exclude:
          - prod: prod1
            level: stage
          - level: dev 

Source

Thoughts 🤔 by Soumendra Kumar Sahoo is licensed under CC BY 4.0