--- title: Github Actions date: 2023-11-28 icon: background: bg-[#808080] tags: - Github - CICD categories: - Toolkit intro: A quick reference to Github Actions for the automation of software workflows, allowing developers to build, test, and deploy code right from their GitHub repositories. plugins: - copyCode --- ## Getting Started ### Introduction [GitHub Actions](https://docs.github.com/en/actions) is a CI/CD platform that enables automation of software workflows, allowing developers to build, test, and deploy code right from their GitHub repositories. --- ### Workflow Files Github Action Workflows are defined in special YAML files, typically stored in a `.github/workflows` directory in the github repository. ```yaml name: hello-world on: push jobs: hello-world-job: runs-on: ubuntu-latest steps: - name: Hello World run: echo "Hello World!" ``` **Viewing your workflow runs** - On GitHub.com, navigate to the main page of the repository. - Under your repository name, click `Actions`. - In the left sidebar, click the workflow you want to display, in this example "hello-world" --- ### Workflow Syntax ```yaml name: learn-github-actions run-name: ${{ github.actor }} is learning GitHub Actions on: [push] jobs: check-bats-version: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v3 with: node-version: '14' - run: npm install -g bats - run: bats -v ``` ### Workflow Syntax Descriptions | Line | Description | | :-------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `name:` | Sets the name of the GitHub Actions workflow. It's a label used for identifying the workflow in the repository. | | `run-name:` | Sets a custom name for the run, using a GitHub context `${{ github.actor }}` to include the name of the user who initiated the run. | | `on:` | Specifies the event that triggers the workflow. In this case, the workflow is triggered on any `push` event to the repository. | | `jobs:` | Defines a group of jobs that will be executed as part of the workflow. Each job runs independently in the workflow. | | `check-bats-version:` | Identifier for a specific job within the workflow. This job is named `check-bats-version`. | | `runs-on:` | Specifies the type of machine to run the job on. Here, it's set to run on the latest version of Ubuntu. | | `steps:` | Contains a sequence of tasks (steps) that will be executed as part of the job. | | `uses:` | Used to specify an action to include as part of a step. For example, `actions/checkout@v4` checks out the repository, and `actions/setup-node@v3` sets up a Node environment. | | `with:` | Specifies additional parameters for the action. It's used in conjunction with `uses` to configure the action. | | `node-version:` | Contains parameter under `with`, specifying the version of Node.js to be set up by the `setup-node` action. In this case, it's set to version '14'. | ### Events ```yaml name: Event-trigger-on-push-example on: [push] # event is defined here jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Run a script run: echo "This workflow runs on every push to the repository." ``` **Event Triggers** | Event Name | Description | | :---------------------------- | :---------------------------------------------- | | `push` | Triggers on a push to the repository. | | `pull_request` | Triggers on pull request events. | | `pull_request_review` | Triggers on pull request review events. | | `pull_request_review_comment` | Triggers on comments on pull request reviews. | | `pull_request_target` | For workflows in forked repositories. | | `fork` | Triggers when a repository is forked. | | `issue_comment` | Triggers on issue and PR comments. | | `issues` | Triggers on issue events. | | `label` | Triggers on label events. | | `milestone` | Triggers on milestone events. | | `deployment` | Triggers on deployment. | | `deployment_status` | Triggers on deployment status updates. | | `public` | Triggers when repo goes from private to public. | | `repository_dispatch` | Triggers on a custom repository event. | | `schedule` | Triggers on a defined schedule. | | `workflow_dispatch` | Allows manual triggering of the workflow. | | `workflow_run` | Triggers on the completion of another workflow. | | `create` | Triggers when a branch or tag is created. | | `delete` | Triggers when a branch or tag is deleted. | | `page_build` | Triggers on GitHub Pages build events. | | `release` | Triggers on release events. | | `watch` | Triggers when someone stars the repo. | | `registry_package` | Triggers on registry package events. | | `status` | Triggers on status updates to a Git commit. | | `project` | Triggers on project board events. | | `project_card` | Triggers on project card events. | | `project_column` | Triggers on project column events. | | `member` | Triggers on collaborator events. | | `gollum` | Triggers on wiki page updates. | ### Jobs Single Job: ```yaml name: Single Job on: [push] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Run a build script run: script/build ``` Multiple Jobs: ```yaml name: CI Workflow on: [push] jobs: job-1: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Runs job 1 run: echo "Running Job 1" job-2: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Runs job 2 run: echo "Running Job 2" job-3: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Runs job 3 run: echo "Running Job 3" ``` ### Steps ```yaml jobs: build: runs-on: ubuntu-latest steps: # step 1 - name: Check out repository uses: actions/checkout@v2 # step 2 - name: Set up Node.js uses: actions/setup-node@v2 with: node-version: '14' # step 3 - name: Install dependencies run: npm install # step 4 - name: Run tests run: npm test ``` ### Github Runners & Self Hosted Runners [Github Hosted Runner](https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners/about-github-hosted-runners): ```yaml name: Workflow on: [push] jobs: build: runs-on: ubuntu-latest # default runner steps: - uses: actions/checkout@v2 - name: Run a script run: echo "Hello, world!" ``` [Self Hosted Runner](https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/about-self-hosted-runners) ```yaml name: Workflow with Self-Hosted Runner on: [push] jobs: build: runs-on: self-hosted steps: - uses: actions/checkout@v2 - name: Run a script run: echo "Hello from self-hosted runner!" ``` ### Environment Variables Custom variable defined using environments. ```yaml jobs: build: runs-on: ubuntu-latest env: CUSTOM_VARIABLE: 'Hello, World!' # Custom variable defined using env: steps: - name: Check environment variable run: echo "Value of CUSTOM_VAR is $CUSTOM_VAR" ``` ### Secrets To add a new secret in your github repository nagivate to `Repository` > `Settings` > `Security` > `Secrets and Variables` > `Actions` > `New Repository Secret` Example Secrets workflow: ```yaml name: Workflow with Secrets on: [push] jobs: example_job: runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v2 - name: Use a secret run: echo "The secret is ${{ secrets.MY_SECRET }}" ``` ### Artifacts To access your artifact navigate to `Repository` > `Actions` > `Workflow Run` > `Artifacts` ```yaml jobs: build: runs-on: ubuntu-latest steps: - name: Build project run: make build - name: Upload build artifact uses: actions/upload-artifact@v3 # upload Artifacts prebuilt action with: name: my-artifact path: path/to/artifact ``` ### Caching Dependencies Dependency caches stores downloaded packages or compiled binaries of your workflows. ```yaml jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Cache dependencies uses: actions/cache@v2 # stores downloaded packages or compiled binaries with: path: | path/to/dependencies another/path key: ${{ runner.os }}-deps-${{ hashFiles('**/lockfile') }} # hash of the dependency lock file is generated in the OS - name: Install dependencies run: install-command ``` ### Matrix Strategies ```yaml jobs: build: runs-on: ubuntu-latest strategy: matrix: node-version: [12.x, 14.x, 16.x] # matrix strategy runs enables you to run jobs across multiple combinations of environments and OS's os: [ubuntu-latest, windows-latest, macOS-latest] steps: - uses: actions/checkout@v2 - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v1 with: node-version: ${{ matrix.node-version }} - run: npm install - run: npm test env: CI: true ``` ### Conditions and Expressions Branch Conditions: ```yaml jobs: build: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v2 - name: Run build if: github.ref == 'refs/heads/main' # "Run build" step will only execute if the current branch is main. run: make build ``` Event Trigger Conditions: ```yaml jobs: test: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v2 - name: Run tests if: github.event_name == 'pull_request' # "Run tests" step is executed only when the workflow is triggered by a pull request event run: npm test ``` ### Workflow Commands Depending on your OS, if you are running ubuntu-latest, bash commands should work ```yaml steps: - name: Set environment variable run: echo "NAME=value" >> $GITHUB_ENV ``` ### Concurrency The concurrency field creates a group based on the `github.head_ref`. If a new run starts within the same concurrency group, it cancels any in-progress runs. ```yaml jobs: my_job: runs-on: ubuntu-latest concurrency: group: ${{ github.head_ref }} cancel-in-progress: true steps: - name: Run a script run: echo "Running script..." ``` ## Also see - [YAML](/yaml) _(cheatsheets.zip)_ - [Github](/github) _(cheatsheets.zip)_ - [Github Actions Documentation](https://docs.github.com/en/actions)_(docs.github.com/en/actions)_