Skip to main content

Working with Expressions and Contexts

1. Evaluating Expressions

GitHub Actions expressions are used to evaluate values, make decisions, and construct dynamic values within workflows. Expressions use the ${{...}} syntax.

Expression Type Description Example
Literal Values Static values like strings, numbers, booleans ${{ 'hello' }}
Variables Access environment variables or context properties ${{ github.actor }}
Functions Functions that return computed values ${{ contains(github.event.pull_request.labels.*.name, 'bug') }}
Operators Logical and comparison operators ${{ github.event_name == 'pull_request' }}

Example: Using Expressions in Conditions

on:
  pull_request:
    types: [opened, synchronize]

jobs:
  build:
    if: 
on:
  pull_request:
    types: [opened, synchronize]

jobs:
  build:
    if: ${{ github.event.pull_request.draft == false }}
    runs-on: ubuntu-latest
    steps:
      - name: Check PR status
        run: echo "Processing non-draft PR"
#x26;#123;{ github.event.pull_request.draft == false }}
runs-on: ubuntu-latest steps: - name: Check PR status run: echo "Processing non-draft PR"

Example: Combining Expressions

on:
  push:
    branches: [main]

jobs:
  deploy:
    if: 
on:
  push:
    branches: [main]

jobs:
  deploy:
    if: ${{ github.ref == 'refs/heads/main' && github.event_name == 'push' }}
    runs-on: ubuntu-latest
    steps:
      - name: Deploy to production
        run: echo "Deploying to prod"
#x26;#123;{ github.ref == 'refs/heads/main' && github.event_name == 'push' }}
runs-on: ubuntu-latest steps: - name: Deploy to production run: echo "Deploying to prod"
Note: Expressions are evaluated at runtime, not at parse time. Make sure to use proper syntax and avoid runtime errors.

2. Using GitHub Context

Property Description Example Value
github.event Full event payload {"action": "created", "issue": {...}}
github.event_name Name of the event that triggered the workflow issues
github.sha Commit SHA that triggered the workflow abc123def456...
github.ref Git ref that triggered the workflow refs/heads/main
github.workflow Name of the workflow Build and Test
github.run_id Unique identifier for the current workflow run 123456789
github.run_number Unique number for each run of the workflow 1
github.actor User who triggered the workflow octocat

Example: Accessing GitHub Context in a Job

jobs:
  example-job:
    runs-on: ubuntu-latest
    steps:
      - name: Print event name
        run: echo "Event name is ${{ github.event_name }}"
      - name: Print commit SHA
        run: echo "Commit SHA is ${{ github.sha }}"
Note: The github context is read-only and cannot be modified.

3. Using Env Context

Property Description Example
env.<var>name</var> Environment variable value set in the workflow env.MY_VAR
env.GITHUB_* GitHub Actions environment variables env.GITHUB_SHA

Example: Setting and Using Environment Variables

jobs:
  build:
    steps:
      - name: Set environment variable
        run: echo "MY_VAR=hello" >> $GITHUB_ENV
      - name: Use environment variable
        run: echo ${{ env.MY_VAR }}
Note: Environment variables set in a job are only available to subsequent steps in that job.

4. Using Job Context

Property Description Example
job.status Current status of the job. Possible values: success, failure, canceled. success
job.name Name of the current job. build-and-test
job.steps List of steps in the job with their status and duration.
[
  {
    "name": "Checkout code",
    "status": "success",
    "duration": "10s"
  }
]

Example: Using job context in a condition

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Check job status
        if: ${{ job.status == 'success' }}
        run: echo "Job completed successfully"

5. Using Steps Context

Property Description Example
steps.<step_id>.outputs Outputs from a previous step in the workflow
{
  "message": "Hello World"
}
steps.<step_id>.outcome Result of a step execution: success or failure "success"
steps.<step_id>.conclusion Final conclusion of a step: success, failure, cancelled, or skipped "success"

Example: Accessing Step Outputs

name: Example Workflow
on: [push]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Set output
        id: set_output
        run: echo "::set-output name=message::Hello World"
      - name: Use output
        run: echo "The message is ${{ steps.set_output.outputs.message }}"
Note: The steps context is only available within the scope of a job and cannot be used outside of it.

6. Using Runner Context

Property Description Value
runner.name Name of the runner executing the job GitHub Actions
runner.os Operating system of the runner Linux, macOS, or Windows
runner.arch Architecture of the runner AMD64, ARM64
runner.temp Temporary directory on the runner /tmp (Linux), %TEMP% (Windows)
runner.workspace Workspace directory for the job /home/runner/work (Linux), C:\Users\runneradmin\AppData\Local\Temp (Windows)

Example: Using runner context in a job

name: Example using runner context
on: [push]

jobs:
  example-job:
    runs-on: ${{ runner.os }}
    steps:
      - name: Print runner OS
        run: echo "Running on ${{ runner.os }}"

7. Using Secrets Context

Property Description Example
secrets Access to secrets configured in the repository or organization ${{ secrets.SECRET_NAME }}

Example: Using a Secret in a Workflow

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Deploy to server
        env:
          API_KEY: ${{ secrets.API_KEY }}
        run: |
          echo "Deploying with key: $API_KEY"
Note: Secrets are encrypted and only available to workflows that have access to them.
Warning: Never log or output secrets in plain text.

8. Using Strategy Context

Property Description Values
strategy.fail-fast Whether to fail the job if any step in the matrix fails true or false
strategy.max-parallel Maximum number of jobs to run in parallel number
strategy.matrix Configuration for matrix strategy object

Example: Using strategy.fail-fast

jobs:
  build:
    strategy:
      fail-fast: false
    steps:
      - run: echo "Running all jobs even if one fails"

Example: Using strategy.max-parallel

jobs:
  build:
    strategy:
      max-parallel: 4
    steps:
      - run: echo "Running up to 4 jobs in parallel"

Example: Using strategy.matrix

jobs:
  build:
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest]
        node-version: [12, 14, 16]
    steps:
      - run: echo "Running on ${{ matrix.os }} with Node.js ${{ matrix.node-version }}"

9. Using Needs Context

Example: Accessing outputs from a previous job

jobs:
  job1:
    runs-on: ubuntu-latest
    outputs:
      output1: ${{ steps.step1.outputs.output1 }}
  job2:
    runs-on: ubuntu-latest
    needs: job1
    steps:
      - name: Use output from job1
        run: echo ${{ needs.job1.outputs.output1 }}
Property Description Usage
needs Reference to other jobs in the workflow needs.job1.outputs.output1
outputs Values that can be passed to downstream jobs outputs.output1
Note: The needs context is only available in jobs that depend on other jobs.

10. Using Inputs Context

Property Description Example
inputs.<input_name> Value of an input defined in the workflow file inputs.debug_mode

Example: Accessing input value

jobs:
  build:
    steps:
      - name: Check debug mode
        run: |
          if [ "${{ inputs.debug_mode }}" = "true" ]; then
            echo "Debug mode enabled"
          fi
Note: Inputs are available in the inputs context and can be accessed using the ${{ inputs.<input_name> }} syntax.

11. Using Boolean Expressions

Expression Description Example
true Boolean true value true
false Boolean false value false
! (NOT) Negates a boolean value ! false evaluates to true
&& (AND) Logical AND operator true && false evaluates to false
|| (OR) Logical OR operator true || false evaluates to true

Example: Using Boolean Expressions in Conditions

on: push
jobs:
  build:
    if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
    steps:
      - run: echo "Running on main branch"

12. Using Comparison Operators

Operator Description Examples
== Equal to if github.event_name == 'push'
!= Not equal to if github.event_name != 'pull_request'
< Less than if github.run_number < 100
> Greater than if github.run_number > 50
<= Less than or equal to if github.run_number <= 100
>= Greater than or equal to if github.run_number >= 50
contains Checks if a string contains another string if contains(github.event.pull_request.title, 'bug')
startsWith Checks if a string starts with another string if startsWith(github.event.pull_request.title, 'fix')
endsWith Checks if a string ends with another string if endsWith(github.event.pull_request.title, 'fix')
regex Matches a string using regular expression if github.event.pull_request.title matches /^fix:/

Example: Using == operator

on:
  push:
    branches:
      - main

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Check branch
        if: github.ref == 'refs/heads/main'
        run: echo "Running on main branch"

Example: Using contains operator

on:
  pull_request:
    types: [opened, synchronize]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Check PR title for bug fix
        if: contains(github.event.pull_request.title, 'bug')
        run: echo "This PR fixes a bug"

Was this article helpful?