β‘οΈ Run your CI workflows with multiple triggers. Stop writing custom bash variable resolvers, and end your if/then expression nightmares.
This action simplifies resolving variables, evaluating expressions, and defining fallback behaviors. The action supports three types of resolution:
This action is designed to make your workflows more maintainable by:
- Coalescing the first non-empty value from a list of inputs
- Evaluating Jinja2 expressions
- Emitting both flat outputs and structured results
- Optionally logging results and writing a step summary
Learn more about each resolution type:
- Direct Assignment
- E.g.
var1=my value
- E.g.
- Jinja Expression Assignment
- E.g.
var1=true ? 'great' : 'not great'
- E.g.
- Standard CI Vars
- Standard CI Vars. Automatic resolution of canned variables and defined inputs. We handle a number of common use cases for you, saving you time, code lines, and troubleshooting time.
Direct variable assignment is provided with the static_inputs
input arg.
The static_inputs
parameter takes variable assignments in key=value
format:
with:
static_inputs:
answer=42
question=What is the meaning of life?
More likely, you will use GitHub expressions to resolve these variables:
with:
static_inputs:
answer=${{ github.inputs.something || github.inputs.else }}
The benefit of this approach is that subsequent action steps can simply pull the resolved variable, rather than repeating the expression everywhere it is needed.
Jinja expressions provide a powerful balance between expressiveness and simplicity.
You can leave off the normal {{
and }}
wrappers and provide any valid jinja2 expression.
with:
jinja_inputs: |
answer=40 + 2
question='What is the meaning' + 'of life?'
Just as with static inputs, you can use GitHub expressions to inject variables into the jinja expression:
with:
jinja_inputs: |
token='${{ inputs.custom_token }}' or '${{ secrets.GITHUB_TOKEN }}'
environment='${{ inputs.environment }}' or ('main' if '${{ github.ref }}' == 'refs/heads/main' else 'dev')
api_url='${{ vars.CUSTOM_API_URL }}' or 'https://api.example.com'
For help with Jinja2 expressions, check out these resources:
- Official Jinja2 Documentation - Complete reference
- Jinja2 Cheat Sheet - Quick syntax reference
The action automatically resolves common CI variables from GitHub context, eliminating the need for complex expressions like ${{ github.event.pull_request.head.repo.full_name || github.repository }}
throughout your workflows.
Variable | Description | Example Value |
---|---|---|
Resolved Variables (always the effective context) | ||
resolved-git-ref |
Full Git ref (refs/heads/... or refs/tags/... ) |
refs/heads/feature/new-connector |
resolved-git-branch |
Short branch name (e.g. main , feature/foo ) |
feature/new-connector |
resolved-git-sha |
Commit SHA | abc123... |
resolved-git-tag |
Tag name (if applicable) | v1.0.0 |
resolved-repo-name |
Repository name (e.g. my-repo ) |
airbyte |
resolved-repo-owner |
Repository owner (user or org) | airbytehq |
resolved-repo-name-full |
Owner + name (e.g. myorg/my-repo ) |
airbytehq/airbyte |
PR Source Variables (for PR workflows) | ||
pr-source-git-ref |
Git ref of the source (PR head) | refs/heads/feature/new-connector |
pr-source-git-branch |
Branch name of the source | feature/new-connector |
pr-source-git-sha |
SHA of the source commit | abc123... |
pr-source-repo-name |
Source repo name | airbyte |
pr-source-repo-owner |
Source repo owner | contributor |
pr-source-repo-name-full |
Full source repo name (owner/name) | contributor/airbyte |
pr-source-repo-is-fork |
Whether the source repo is a fork of the target repo | true |
PR Target Variables (for PR workflows) | ||
pr-target-git-ref |
Git ref of the target (PR base) | refs/heads/main |
pr-target-git-branch |
Branch name of the target | main |
pr-target-git-sha |
SHA of the target commit | def456... |
pr-target-git-tag |
Tag name, if PR targets a tag | `` |
pr-target-repo-name |
Target repo name | airbyte |
pr-target-repo-owner |
Target repo owner | airbytehq |
pr-target-repo-name-full |
Full target repo name (owner/name) | airbytehq/airbyte |
Additional Resolved Metadata | ||
pr-number |
Pull request number (if applicable) | 12345 |
pr-url |
URL to the pull request | https://github.com/airbytehq/airbyte/pull/12345 |
pr-title |
Title of the pull request | feat: Add new connector |
comment-id |
ID of the triggering comment (if applicable) | 987654321 |
comment-url |
URL to the triggering comment (if applicable) | https://github.com/airbytehq/airbyte/issues/12345#issuecomment-987654321 |
run-id |
GitHub Actions run ID | 123456789 |
run-url |
URL to the GitHub Actions run | https://github.com/airbytehq/airbyte/actions/runs/123456789 |
is-pr |
Boolean: whether the current context is a PR | true |
- name: Resolve CI variables
id: vars
uses: aaronsteers/resolve-ci-vars-action@v1
with:
static_inputs: |
custom_var=my_value
- name: Use resolved variables
run: |
echo "PR Number: ${{ steps.vars.outputs.pr-number }}"
echo "Resolved Branch: ${{ steps.vars.outputs.resolved-git-branch }}"
echo "Repository: ${{ steps.vars.outputs.resolved-repo-name-full }}"
echo "All variables: ${{ steps.vars.outputs.custom }}"
The action automatically detects and resolves common workflow_dispatch inputs:
- PR inputs:
pr
orpr-number
- Automatically resolves PR context and updates resolved variables to point to PR head - Comment inputs:
comment-id
- Resolves comment metadata for slash command workflows - Issue inputs:
issue-id
orissue-number
- Resolves issue context and constructs URLs
# Example workflow_dispatch with auto-detected inputs
on:
workflow_dispatch:
inputs:
pr-number:
description: 'PR number to operate on'
required: false
comment-id:
description: 'Comment ID that triggered this'
required: false
issue-number:
description: 'Issue number'
required: false
jobs:
example:
runs-on: ubuntu-latest
steps:
- uses: aaronsteers/resolve-ci-vars-action@v1
id: vars
# All workflow_dispatch inputs are now available as resolved variables
- run: echo "Operating on PR: ${{ steps.vars.outputs.pr-number }}"
Key Features:
- Smart resolved context:
resolved-*
variables always point to the effective working context (PR head for PRs, current branch otherwise) - Explicit PR source/target: Separate
pr-source-*
andpr-target-*
variables for fine-grained PR workflows - URL generation: Automatic GitHub URLs for branches, commits, PRs, and comments
- Fork-aware: Properly distinguishes between source and target repositories in fork scenarios
- Context detection:
is-pr
boolean and other metadata for workflow logic - Workflow dispatch auto-detection: Automatically detects and resolves
pr
/pr-number
,comment-id
, andissue-id
/issue-number
inputs
- β Auto-coalesce static inputs
- π§ Evaluate Jinja2 expressions
- π¦ Expose custom results in reusable outputs:
var1
,var2
,var3
- π§Ύ Structured JSON output:
custom
- π Optional GitHub Step Summary output
jobs:
example:
runs-on: ubuntu-latest
steps:
- name: Resolve variables
id: vars
uses: your-org/resolve-ci-vars-action@v1
with:
static_inputs: |
username=${{ inputs.username }}
default_username=guest
jinja_inputs: |
team='${{ inputs.team }}' or 'default_team'
var1: "priority or 'low'"
log_outputs: true
- name: Use resolved values
run: |
echo "Username: ${{ steps.vars.outputs.result }}"
echo "Team: ${{ steps.vars.outputs.result }}"
echo "Priority: ${{ steps.vars.outputs.var1 }}"
echo "Custom object: ${{ steps.vars.outputs.custom }}"
Name | Description | Required | Default |
---|---|---|---|
static_inputs |
Variable assignments in key=value format (multiline string) | β | |
jinja_inputs |
Jinja2 expressions to evaluate (e.g. user or default_user ) |
β | |
log_outputs |
Whether to log resolved values to the console and step summary | β | false |
non_sensitive |
Alias for log_outputs |
β | false |
Output Name | Description |
---|---|
custom |
JSON-encoded object with all resolved values |
var1 |
Custom user-defined output variable 1 |
var2 |
Custom user-defined output variable 2 |
var3 |
Custom user-defined output variable 3 |
{variable-name} |
Individual outputs for each resolved variable (e.g., pr-number , resolved-git-branch ) |
with:
static_inputs: |
username=${{ inputs.username }}
default_username=fallback
with:
jinja_inputs: |
team='${{ inputs.team }}' or 'unknown'
Sensitive values should not be logged unless you are confident they are masked.
Use log_outputs: true
or non_sensitive: true
only for safe-to-print variables.
MIT License β feel free to fork, extend, and share!
Your Name or Org β github.com/your-org