Mastering GitHub Actions: Using Contexts and Expressions
In our previous lesson on GitHub Actions Environment Variables, we learned how to store and retrieve data. However, to build truly dynamic and intelligent CI/CD pipelines, you need to go beyond static variables. This is where Contexts and Expressions come into play. They allow your workflows to make decisions, access metadata about the repository, and handle sensitive information securely.
What are Expressions in GitHub Actions?
Expressions are used to programmatically set variables in workflow files and access contexts. An expression can be any combination of literal values, context references, or functions. They are evaluated before the workflow step is executed.
The syntax for an expression is: ${{ <expression> }}.
Common Operators in Expressions
- Logical:
&&(And),||(Or),!(Not) - Comparison:
==,!=,<,>,<=,>= - Functions:
contains(),startsWith(),endsWith(),format(), andjoin().
Understanding Contexts
Contexts are a way to access information about workflow runs, runner environments, jobs, and steps. Each context is an object that contains various properties.
Essential GitHub Contexts
- github: Contains information about the workflow run, such as the repository name, the actor who triggered the event, and the event type.
- env: Contains variables set in a workflow, job, or step.
- vars: Contains custom configuration variables defined at the repository, environment, or organization level.
- secrets: Contains sensitive information like API tokens or passwords.
- steps: Contains information about the steps that have already run in the current job.
- runner: Contains information about the machine executing the current job.
Flow Chart: How Expressions are Evaluated
[Workflow Triggered]
|
v
[Gather Context Data] (GitHub, Secrets, Env, Runner)
|
v
[Evaluate Expressions] (Check 'if' conditions, resolve ${{ }})
|
v
[Execute Job/Step]
|
v
[Update 'steps' Context] (Status, Outputs)
Practical Examples
1. Conditional Execution Based on Branch
You might want to run a deployment step only when code is pushed to the main branch. We use the github context and an if expression for this.
jobs:
deploy:
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- name: Deploy to Production
run: echo "Deploying to production server..."
2. Using Functions to Check for Strings
The contains() function is extremely useful for checking if a commit message or a branch name contains a specific keyword.
jobs:
notify:
runs-on: ubuntu-latest
if: contains(github.event.head_commit.message, 'FIX')
steps:
- name: Alert Team
run: echo "A critical fix was pushed!"
Common Mistakes to Avoid
- Missing Curly Braces: Forgetting the
${{ }}wrapper is the most common error. Without them, GitHub treats the expression as a plain string. - Case Sensitivity: Context keys and function names are generally case-sensitive. Always use
github.ref, notGitHub.Ref. - Printing Secrets: Never use expressions to
echosecrets in your logs. GitHub attempts to mask them, but it is not a foolproof security measure. - Using Contexts in the Wrong Place: Some contexts, like
steps, are only available after a step has actually run.
Real-World Use Cases
- Dynamic Environment Selection: Use
${{ github.event_name == 'push' ? 'production' : 'staging' }}to decide where to deploy. - Matrix Filtering: Use expressions to include or exclude specific operating systems or versions in a build matrix.
- Step Dependencies: Use
${{ success() }}or${{ failure() }}in anifcondition to trigger cleanup tasks or notifications based on previous step results.
Interview Notes: Contexts and Expressions
- Question: What is the difference between
envandvarscontexts? - Answer: The
envcontext is used for variables defined within the YAML file itself (workflow, job, or step level). Thevarscontext is used for non-sensitive configuration variables defined in the GitHub Repository Settings. - Question: How do you access the output of a previous step?
- Answer: You must first give the step an
id, then access it using${{ steps.<step_id>.outputs.<output_name> }}. - Question: Can you use expressions inside a
runscript? - Answer: Yes, but be careful with shell escaping. It is often safer to map the expression to an environment variable first.
Summary
Contexts and Expressions are the "brain" of your GitHub Actions. They allow your workflows to be dynamic, secure, and context-aware. By mastering the github, secrets, and steps contexts, along with logical functions, you can automate complex CI/CD patterns with ease. In the next topic, we will dive deeper into GitHub Actions Secrets Management to ensure your data remains protected.
Continue your journey by exploring the next lesson: Managing Secrets and Security.