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. | |
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 | |
| 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:/ |