GitHub Actions Demystified

By September 29, 2020DevOps

GitHub Actions header

GitHub Actions helps you create your software development workflows i.e CI/CD process from the same code space you store code and collaborate on pull requests and issues. These workflows have different tasks which are called actions that can be run automatically on certain events. In the blogpost below, I have shared the workflows for creating pipelines for deploying Fission on a GKE Kubernetes cluster which is created by GitHub Actions, some code validation actions, and lastly some monitoring actions. Let’s get deep dive into the world of GitHub Actions.

What are GitHub Actions?

GitHub Actions is an API for events and triggers on GitHub which orchestrates a workflow, supported by various events, and all the execution is managed by GitHub in a secure way. With GitHub Actions, workflows and steps are just code in the repository so you can create, share, reuse, and fork making possible to do code reviews, branch management, and issue triaging the way you would like. With GitHub Actions, you can build end-to-end continuous integration (CI) and continuous deployment (CD) capabilities directly in your repository.


To get started using GitHub Actions, you’ll need to add a folder to the root of your GitHub repository.

mkdir -p .github/workflows

In this directory, we will add all the workflows which are YAML files. Let’s get started.

 

Core Concepts

Workflows

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

Events

An event is a specific activity that triggers aa workflow. Example: Someone pushes a commit to a repository that can trigger a workflow, or a PR creation can be an event.  These events can be external as well, which can use a repository dispatch webhook to trigger a workflow.

Jobs

A job is a set of steps that execute on the same runner. By default, they are executed in parallel but you can also configure to run them sequentially. 

Steps

A step is an individual task that can run commands (or Actions)., Each step in a job executes on the same running, allowing the actions in that job to share data with each other.

Actions

Actions are standalone commands, it is the smallest unit in the workflow. You can create your own actions, or use actions created by the Github community. 

Runners

A runner is an agent or server that has the Github Actions runner application installed. A runner listens for the available jobs, runs one job at a time, and reports the progress, logs, and the result back to Github. The Github hosted runners are based on Ubuntu Linux, Microsoft Windows, and macOS. They are virtualized environments and we can also create our own runners.

How do GitHub Actions work?

Github Actions is fully integrated into the Github. As described in the above concepts, it mainly consists of workflows that are stored in the git repository (.github/workflows/). Workflows are typically triggered by events such as PR, Issues, Commits in the repository or it can also be triggered from the external events using repository webhooks. When the workflow is triggered, the runner picks up the job and executes one by one. The job consists of steps (with an action) that perform a unit of work in the workflow. 

Workflow Syntax

A workflow is a configurable automated process made up of one or more jobs.

  • name: The name of your workflow. The workflow name is displayed by GitHub on your repository’s actions page.
  • on: GitHub event that triggers all the workflow. A workflow is triggered when somebody pushes to the repository or when a pull request is made. Events also can be configured to concentrate on external events using Webhooks.
  • job: A workflow run is formed from one or more jobs. Each job runs in an environment such as OS or containers which is specified by runs-on. A job consists of a sequence of tasks called steps. Steps can run commands, run setup tasks, or run action in your repository, a public repository, or action published during a Docker registry. 
  • actions: Actions are the littlest portable building block of a workflow and may be combined as steps to make a job. Github Marketplace has publicly shared actions or you can create your own actions.
  • env: Environment variables that are available to all the jobs and steps in the workflow. 

I also want to introduce a few important features here. 

  1. Matrix Strategy: Github Actions allows you to automate the tasks to run on multiple versions of OS (e.g. ubuntu 18.04, 20.04) and runtimes (e.g. let’s say node 6, 8, 10).
  2. Caching: You can use caching when you are dealing with a lot of data related to libraries, dependencies to improve the performance of subsequent builds. 
  3. Built-in secrets store: This can help you in embracing automation in the git-flow. 
  4. Artifacts storage: you can store project artifacts such as log files, binaries, test results, code coverage results. Using uploads and downloads artifact actions, it is possible to share between jobs.

Creating a GKE cluster

The below workflow is triggered whenever there is a code change in GitHub and a Pull Request is created for the master branch. This workflow will create a new GKE cluster.

name: gke-cluster
on:
  pull_request:
    branches:
      - master
    types: [labeled]
jobs:
  Fission-on-gke:
    runs-on: ubuntu-latest
    if: github.event.label.name == 'gke'
    env:
      APPLICATION_CREDENTIALS: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }}
      CLUSTER_NAME: ${{ secrets.GKE_CLUSTER_NAME }}
      ZONE_NAME: us-central1-c
      GKE_PROJECT_NAME: ${{ secrets.PROJECT_ID }}
    steps:
      - name: Checkout fisson from master
        uses: actions/checkout@v2
      - uses: GoogleCloudPlatform/github-actions/setup-gcloud@master
        with:
          version: '270.0.0'
          project_id: ${{ env.GKE_PROJECT_NAME }}
          service_account_key: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }}
          export_default_credentials: true

      - name: Create cluster and verify
        run: |
          gcloud container clusters create "$CLUSTER_NAME" --zone "$ZONE_NAME"
          gcloud container clusters get-credentials "$CLUSTER_NAME" --zone "$ZONE_NAME" --project "$GKE_PROJECT_NAME"
          kubectl config view
          kubectl config current-context
          kubectl get ns
          kubectl create namespace Fission
          gcloud auth configure-docker
  • The workflow is triggered when a pull request is created for the master branch AND when the pull request has attached a label. This is handled in the on block of the workflow.
  • The name of the job is Fission-on-gke.The job is executed only if the label attached is gke.
  • Env defines a map of environment variables that are available to all jobs and steps in the workflow.
  • Secrets are encrypted environment variables that you create in a repository or organization.
  • Step checkout action : This action checks-out your repository under $GITHUB_WORKSPACE, so your workflow can access it.
  • Shell commands can be executed in the steps using the run attribute. Multiple shell commands can be executed using a pipe | on the run attribute.
  • Steps setup-gcloud: This action configures the Google Cloud SDK in the environment for use in actions. The Google Cloud SDK includes both the gcloud and gsutil binaries.

Just add more actions with the steps to deploy your Fission code and workflow is ready.

Setting up Environment as per the Fission requirements

Mostly all the required tools are already installed on GitHub runner. Here is the list of tools installed. Fission build and deployment happens using Skaffold and installation is done using Helm charts. But sometimes we might need different versions as per the deployment and hence some actions for getting the required version.

  • Getting the required version of Go. Fission requires go1.12 and action setup-go can configure the required version with the input go-version
    - name: Set up Go 1.12
      uses: actions/setup-go@v1
      with:
        go-version: 1.12
    
  • Fission is built and deployed through Skaffold. Downloading Skaffold, changing its permission and moving it inside a location from PATH.
    - name: Skaffold installation
      run: |
        curl -Lo skaffold https://storage.googleapis.com/skaffold/releases/latest/skaffold-linux-amd64
        chmod +x skaffold
        sudo mv skaffold /usr/local/bin
        skaffold version 
    
  • Fission installation is done using Helm charts and it requires Helm v2.
    - name: Install the required helm version
      run: |
        helm version
        curl -LO https://git.io/get_helm.sh
        chmod 700 get_helm.sh
        ./get_helm.sh -v v2.16.6

Validation Actions

Validation step for pods.

- name: Verify the pods
  run: |
    kubectl get pods -n Fission

Validation step is executed to check if the pods of Fission are running fine.

Monitoring Actions

Finding Actions is a fairly simple job. Just go to the GitHub marketplace and check for actions. They are readily available for almost all the task(s). Few examples below

Create or Update Comment

- name: Post a comment on the PR
  uses: peter-evans/create-or-update-comment@v1
  with:
    token: ${{ secrets.GITHUB_ACCESS_TOKEN }}
    repository: infracloudio/${{ env.REPO }}
    issue-number: ${{ env.PR_NUMBER }}
    body: |
      GKE Cluster is ready with Fission deployed onto it.

Github Action for sending message to Slack

- name: Sends a message to Slack when a push, a pull request or an issue is made
  steps:
    - name: Send message to Slack API
      uses: archive/github-actions-slack@master
      with:
        slack-bot-user-oauth-access-token: ${{ secrets.SLACK_BOT_USER_OAUTH_ACCESS_TOKEN }}
        slack-channel: test
        slack-text: Hello! Event "${{ github.event_name }}" in "${{ github.repository }}" 🤓

- name: Result from "Send Message"
  run: echo "The result was ${{ steps.notify.outputs.slack-result }}"

Fission-workflow

The entire workflow of Fission deployed on gke-cluster can be found in the Fission repository

Conclusion

GitHub Actions are a significant improvement to the GitHub ecosystem. Actions provides simple constructs, great integration with Github with a large community-driven market for actions. Particularly, it is well-positioned for the public open-source projects for which it provides unlimited free usage. You should also check this link if you want to see a comparison between Jenkins and Github Actions and how you can import your Jenkins pipeline to Github Actions.

I hope you have got a taste of Github Actions, please let us know your thoughts in the comments below. 

– Pooja Dhoot and Anjul Sahu

 

Pooja Dhoot

Author Pooja Dhoot

More posts by Pooja Dhoot

Leave a Reply