Skip to main content
  1. 🔰Posts/
  2. 🗂️My Trainings/
  3. VCS Trainings and Certifications/
  4. GitHub Actions - The Complete Guide/

GitHub Actions: Fundamentals 🔥

📚 Part 1 of 5: "GitHub Actions The Complete Guide" series.

In GitHub Actions, workflows are automated processes that consist of Jobs and Steps. Jobs are collections of steps that run in a specific environment, while steps are individual tasks executed sequentially within a job, allowing for organized automation of tasks like building, testing, and deploying code.
External Resources »
GitHub Actions official DocumentationGitHub Actions MarketplaceGitHub.com

Workflows, Jobs & Steps #

flowchart TD subgraph Repo[Git Repository] %% Workflow 1 A[Workflow 1] --> B[Job 1] B --> C[Step 1] B --> D[Step 2] %% Workflow 2 E[Workflow 2] --> F[Job 1] E --> I[Job 2] %% Steps for Job 1 F --> G[Step 1] F --> H[Step 2] %% Steps for Job 2 I --> J[Step 1] end

⚙️ Workflows #

  • Attached to GitHub repository
  • Contain one or more Jobs
  • Triggered upon Events

🔧 Jobs #

  • Define a Runner (execution environment / operating system to execute the steps)
  • Contain one or more Steps
  • Run in parallel (default) or sequential
  • Can be conditional

👣 Steps #

  • Execute a shell script, command or an Action
  • Can use custom or third-party actions
  • Steps are executed in order
  • Can be conditional

GitHub Actions: Availability & Pricing

In public repositories, you can use GitHub Actions for free. For private repositoriesonly a certain amount of monthly usage is available for free - extra usage on top must be paid.

The exact quotas and payment details depend on your GitHub plan, a detailed summary can be found here: GitHub Actions billing

If you can’t find an “Actions” tab in your GitHub repository, you can should enable them as described here: Managing GitHub Actions settings for a repository

📄 File: .github/workflows/01-first-action.yml

name: First Workflow
on: workflow_dispatch
jobs:
  first-job:
    runs-on: ubuntu-latest
    steps:
      - name: Print greeting
        run: echo "Hello World!"
      - name: Print goodbye
        run: echo "Done - bye!"

ℹ️ If you need to run multiple shell commands, you can easily do so by adding the pipe symbol (|) as a value after the run: key:

    steps:
      - name: Print greeting
        run: | 
	        echo "Hello World!"
	        echo "Hello Solar System!"

This will run both commands in one step.

Events (Workflow Triggers) #

You can configure your workflows to run when specific activity on GitHub happens, at a scheduled time, or when an event outside of GitHub occurs.
Repository relatedComment
on: pushPushing a commit
on: pull_requestPull request action (opened, closed, …)
on: createA branch or tag was created
on: forkRepository was forked
on: issuesAn issues was opened, deleted, …
on: issue_commentIssue or pull request comment action
on: watchRepository was starred
Other
on: workflow_dispatchManually trigger workflow
on: repository_dispatchREST API request triggers workflow
on: scheduleWorkflow is scheduled

Example:

📄 File: .github/workflows/04-01-exercise.yml

name: 04-01 - Exercise - Events
on:
  pull_request:
    types:
      - opened
    branches:
      - main # main
      - 'dev-*' # dev-new dev-this-is-new
      - 'feat/**' # feat/new feat/new/button
  workflow_dispatch:
  push:
    branches:
      - main # main
      - 'dev-*' # dev-new dev-this-is-new
      - 'feat/**' # feat/new feat/new/button
      # developer-1
    paths-ignore:
      - '.github/workflows/*' # If files in .github/workflows change, workflow will not run
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Output event data
        run: echo "${{ toJSON(github.event) }}"
      - name: Get code
        uses: actions/checkout@v3
      - name: Install dependencies
        run: |
          cd 04-react-exercise
          npm ci
      - name: Test code
        run: |
          cd 04-react-exercise
          npm run test
      - name: Build code
        run: |
          cd 04-react-exercise
          npm run build
      - name: Deploy project
        run: echo "Deploying..."

By default, Pull Requests based on Forks do NOT trigger a workflow.

Reason: Everyone can fork & open pull requests. Malicious workflow runs & excess cost could be caused.

First-time contributors must be approved manually.

More info:

Job Runners #

Runners are the machines that execute jobs in a GitHub Actions workflow. For example, a runner can clone your repository locally, install testing software, and then run commands that evaluate your code.

ℹ️ GitHub provides runners that you can use to run your jobs, or you can host your own runners.

flowchart TB %% Class Definitions classDef redclass fill:#EB4925 classDef redclasss stroke:#EB4925 classDef yellowclass stroke:#EBAC25 classDef greenclass stroke:#C7EB25 %% Workflows W@{ shape: doc, label: "**Workflow**" } %% Jobs Job1@{ shape: processes, label: "**Job1**" } Job2@{ shape: processes, label: "**Job2**" } %% Job1 Steps Step1Job1@{ shape: process, label: "**Step1**" } Step2Job1@{ shape: process, label: "**Step2**" } %% Job2 Steps Step1Job2@{ shape: process, label: "**Step1**" } Step2Job2@{ shape: process, label: "**Step2**" } %% Runners Runner1@{ shape: db, label: "**Runner1**" } Runner2@{ shape: db, label: "**Runner2**" } %% Comments Comment1@{ shape: braces, label: "Runner: - Server that runs the job - GitHub provides Ubuntu Linux, Windows & macOS Runners - You can also host and use your own runner" } Comment2@{ shape: braces, label: "By default jobs are being executed in paralel (see **Job 2**).
Dependencies can be specified explicitly (see **Job 1**)." } %% Job1 W:::redclasss --> Job1:::yellowclass %% Step1 Job1 Job1_Step1_Route@--> Step1Job1:::greenclass Step1Job1 Job1_Step1_Step2_Route@-->|Explicit dependency:
Step2 'needs: Step1'| Step2Job1:::greenclass Job1_Step1_Route@{ animate: true } Job1_Step1_Step2_Route@{ animate: true } %% Step2 Step2Job1 Job1_Step2_Runner_Route@-->|Steps execute on the Runner| Runner1:::redclass Job1_Step2_Runner_Route@{ animate: true } Runner1 -.-|Every job has a Runner| Job1 %% Job2 W --> Job2:::yellowclass %% Step1 Job2 Job2_Step1_Route@--> Step1Job2:::greenclass Job2_Step1_Route@{ animate: true } Step1Job2 Job2_Step1_Runner_Route@-->|Steps execute on the Runner| Runner2:::redclass Job2_Step1_Runner_Route@{ animate: true } Runner2 -.- |Every job has a Runner| Job2 %% Step2 Job2 Job2_Step2_Route@--> Step2Job2:::greenclass Job2_Step2_Route@{ animate: true } Step2Job2 Job2_Step2_Runner_Route@-->|Steps execute on the Runner| Runner2 Job2_Step2_Runner_Route@{ animate: true } %% Comments Runner2 ~~~ Comment1 Runner2 ~~~ Comment2

IMPORTANT: Every job gets its own runner - it’s own Virtual Machine that’s totally isolated from other machines and jobs! For that reason, runs-on: must be defined for each job.

More: GitHub Actions Runners

Contexts reference #

Find information about contexts (metadata) available in GitHub Actions workflows, including available properties, access methods, and usage examples.

Available contexts #

Context nameTypeDescription
githubobjectInformation about the workflow run. For more information, see github context.
envobjectContains variables set in a workflow, job, or step. For more information, see env context.
varsobjectContains variables set at the repository, organization, or environment levels. For more information, see vars context.
jobobjectInformation about the currently running job. For more information, see job context.
jobsobjectFor reusable workflows only, contains outputs of jobs from the reusable workflow. For more information, see jobs context.
stepsobjectInformation about the steps that have been run in the current job. For more information, see steps context.
runnerobjectInformation about the runner that is running the current job. For more information, see runner context.
secretsobjectContains the names and values of secrets that are available to a workflow run. For more information, see secrets context.
strategyobjectInformation about the matrix execution strategy for the current job. For more information, see strategy context.
matrixobjectContains the matrix properties defined in the workflow that apply to the current job. For more information, see matrix context.
needsobjectContains the outputs of all jobs that are defined as a dependency of the current job. For more information, see needs context.
inputsobjectContains the inputs of a reusable or manually triggered workflow. For more information, see inputs context.

The following example demonstrates how these different types of variables can be used together in a job:

name: CI
on: push
jobs:
  prod-check:
    if: ${{ github.ref == 'refs/heads/main' }}
    runs-on: ubuntu-latest
    steps:
      - run: echo "Deploying to production server on branch $GITHUB_REF"

Another example demonstrates how to output a GitHub context in JSON format:

📄 File: .github/workflows/03-output.yml

name: 03 - Output information
on: workflow_dispatch
jobs:
  info:
    runs-on: ubuntu-latest
    steps:
      - name: Output GitHub context
        run: echo "${{ toJSON(github) }}"

GitHub Actions contexts are useful for accessing information about the workflow run, such as the event that triggered it, repository details, and environment variables.

Common use cases include conditionally executing steps based on event types, managing secrets securely, and customizing workflows based on the context of the job or steps.

More: GitHub Actions Contexts

Skipping workflow runs #

You can skip workflow runs triggered by the push and pull_request events by including a command in your commit message.

Workflows that would otherwise be triggered using on: push or on: pull_request won’t be triggered if you add any of the following strings to the commit message in a push, or the HEAD commit of a pull request:

  • [skip ci]
  • [ci skip]
  • [no ci]
  • [skip actions]
  • [actions skip]

Alternatively, you can add a skip-checks trailer to your commit message. The trailers section should be included at the end of your commit message and be preceded by two empty lines. If you already have other trailers in your commit message, skip-checks should be last. You can use either of the following:

  • skip-checks:true
  • skip-checks: true
This can be useful for minor code changes (updating comments, etc.). When making minor changes, Workflows may be skipped if necessary.

More: Skipping workflow runs


» Sources « #

» Disclaimer « #

This series draws heavily from Maximilian Schwarzmüller’s GitHub Actions - The Complete Guide course on Udemy.

About the instructor:
🌐 Website📺 YouTube
💼 LinkedIn🗃️ GitHub
My Repos for this section:
cicd-gh-actions-courseLearnings from "GitHub Actions - The Complete Guide" on Udemy.

ℹ️Shared for educational purposes only, no rights reserved.


RobK
Author
RobK
DevOps | Agile | AWS | Ansible | Terraform | GitHub Actions | Linux | Windows