Skip to main content

Workflow Syntax

run: steps

Shell scripts executed via bash (or configured shell)

uses: actions

GitHub actions, local actions, composite actions, Node.js actions

Job dependencies

needs: with DAG resolution and concurrent execution

Matrix strategy

Cartesian product expansion with include/exclude

Expression engine

Full expression evaluation with contexts, operators, and functions

Environment variables

env: at workflow, job, and step levels + $GITHUB_ENV

Step outputs

$GITHUB_OUTPUT with multiline delimiter support

Job outputs

jobs.*.outputs evaluated from step outputs

Conditions

Full expression evaluation in if: with status functions

Timeouts

timeout-minutes at job and step level

continue-on-error

Step failures don’t fail the job

GitHub context

github.sha, github.ref, github.repository, github.actor, etc.

Secrets

secrets.* context populated from server environment variables

Concurrency

concurrency: groups with cancel-in-progress support

Permissions

permissions: field parsed at workflow and job level

Container

container: runs job steps inside a Docker container

Services

services: starts sidecar containers alongside the job

Artifacts

actions/upload-artifact and actions/download-artifact built-in shims

Reusable workflows

workflow_call with inputs and secret inheritance

Branch filters

on: push: branches: and branches-ignore: filters

$GITHUB_PATH

PATH modifications persist across steps (including in VMs)

Expression Functions

FunctionDescription
contains(search, item)Case-insensitive string/array search
startsWith(string, prefix)Case-insensitive prefix check
endsWith(string, suffix)Case-insensitive suffix check
format(string, args...)String formatting with {0}, {1} placeholders
join(array, separator)Join array elements
toJSON(value)Convert to JSON string
fromJSON(string)Parse JSON string
success()True if job has not failed
failure()True if any previous step failed
always()Always true
cancelled()True if workflow was cancelled

Expression Contexts

ContextDescription
github.*Repository, commit, ref, actor, event info
env.*Environment variables
steps.*Step outputs and outcomes
needs.*Dependent job outputs and results
matrix.*Current matrix combination values
runner.*Runner OS, architecture, temp directory
job.*Current job status
inputs.*Workflow/action inputs
secrets.*Secret values from server configuration

Action Support

TypeExampleStatus
GitHub actionsactions/checkout@v4Supported (built-in shim)
Setup actionsactions/setup-node@v4, actions/setup-go@v5Supported (built-in shim, tools pre-installed)
Artifact actionsactions/upload-artifact@v4, actions/download-artifact@v4Supported (built-in shim, local storage)
Local actions./my-actionSupported
Composite actionsruns.using: compositeSupported
Node.js actionsruns.using: node20Supported (requires Node on PATH)
Docker actionsdocker://imageNot supported

CI Server Features

FeatureDescription
GitHub webhooksReceives push and pull_request events with branch filtering
Commit statusesReports pass/fail via the Statuses API
Checks APIFull log output per workflow (requires GitHub App)
MicroVM isolationEach job runs in an ephemeral CloudHypervisor VM
Parallel VMsIndependent jobs run concurrently, configurable via VM_MAX_PARALLEL
virtiofs sharingWorkspace shared between host and VM
Web dashboardReal-time build status with per-step log viewing
SSE updatesLive streaming of build progress to the browser
Concurrency groupsPrevents concurrent runs of the same workflow/branch
Secrets managementSECRET_* env vars exposed as secrets.* context
ArtifactsLocal artifact storage shared between jobs
Container jobsRun steps inside Docker containers
Service containersSidecar containers for databases, caches, etc.
Reusable workflowsCall other workflow files with inputs and secrets

Secrets

Secrets are loaded from environment variables on the server. Any env var prefixed with SECRET_ is exposed in the secrets.* context with the prefix stripped. For example:
# In /etc/athanor/env
SECRET_SSH_PRIVATE_KEY=...
SECRET_STRIPE_KEY=sk_test_...
These become available in workflows as ${{ secrets.SSH_PRIVATE_KEY }} and ${{ secrets.STRIPE_KEY }}.

Container Support

Jobs can specify a Docker container image. All run: steps execute inside the container with the workspace mounted:
jobs:
  test:
    container: node:20-alpine
    steps:
      - uses: actions/checkout@v4
      - run: npm test
Service containers run alongside the job and are accessible via localhost:
jobs:
  test:
    services:
      postgres:
        image: postgres:16
        env:
          POSTGRES_PASSWORD: test
        ports:
          - 5432:5432
    steps:
      - run: pg_isready -h localhost
Container and service support requires Docker to be installed in the VM rootfs.

Concurrency

Prevent concurrent runs of the same workflow:
concurrency:
  group: deploy
  cancel-in-progress: true
When a new run starts for the same group, the previous run is cancelled.