Skip to content

CI/CD

Engineering Runtime is designed for pipelines: install a release binary, bootstrap a throwaway Runtime Home per job, authenticate with secrets, execute provider operations or capabilities, then read the audit trail.

Working examples live in engineering-runtime-samples. Prefer copying those workflows over inventing a new install path.

Job contract (minimum)

Every CI job should set:

env:
  ENGINEERING_RUNTIME_HOME: ${{ github.workspace }}/runtime-home
  RUNTIME_CONFIG_FILE:      ${{ github.workspace }}/runtime-home/config.yaml
  RUNTIME_POLICY_FILE:      ${{ github.workspace }}/runtime-home/policy-config.yaml
  ENGINEERING_RUNTIME_CONSUMER: ci
  RUNTIME_GITHUB_TOKEN: ${{ secrets.RUNTIME_GITHUB_TOKEN }}
Variable Why
ENGINEERING_RUNTIME_HOME Per-job Home — never reuse a developer's ~/.engineering-runtime
RUNTIME_CONFIG_FILE / RUNTIME_POLICY_FILE Pin config/policy to that Home (not a checked-in copy)
ENGINEERING_RUNTIME_CONSUMER=ci Labels audit records as pipeline-driven
RUNTIME_GITHUB_TOKEN Auth Engine + GitHub provider ops; also downloads private releases

Do not point RUNTIME_CAPABILITIES_DIR at a folder you will also bootstrap into — Bootstrap seeds capabilities into that directory and can pollute the working tree. Execute sample capabilities by full path, or clone a dedicated store and set RUNTIME_CAPABILITIES_DIR to that clone only (see capabilities-from-registry).

setup-runtime composite action

From engineering-runtime-samples:

- uses: kishore-gutta/engineering-runtime-samples/.github/actions/setup-runtime@main
  with:
    runtime_github_token: ${{ secrets.RUNTIME_GITHUB_TOKEN }}
    github_organization: ${{ vars.GITHUB_ORG || github.repository_owner }}
    version: v0.5.2   # optional — empty installs latest

What it does:

  1. gh release download from kishore-gutta/engineering-runtime-releases (linux-amd64), checksum-verify, put runtime on PATH
  2. runtime bootstrap into the job's Home
  3. Optionally seed context.yaml with the GitHub organization

Never use github.token for the release download

While engineering-runtime-releases is private, secrets.RUNTIME_GITHUB_TOKEN must have contents:read on that repo. The action always uses the token you pass as runtime_github_token (as GH_TOKEN), not the workflow's default GITHUB_TOKEN.

Secrets and variables

Kind Name Purpose
Secret RUNTIME_GITHUB_TOKEN Release download + Auth Engine / github provider
Variable (optional) GITHUB_ORG Org written into Runtime Context; defaults to github.repository_owner

Token scopes depend on the capabilities you run (org listing, secrets inventory, etc.). Start with a classic PAT that can read releases and the orgs/repos your jobs touch.

Minimal workflow

name: Runtime smoke

on:
  workflow_dispatch: {}

permissions:
  contents: read

env:
  ENGINEERING_RUNTIME_HOME: ${{ github.workspace }}/runtime-home
  RUNTIME_CONFIG_FILE:      ${{ github.workspace }}/runtime-home/config.yaml
  RUNTIME_POLICY_FILE:      ${{ github.workspace }}/runtime-home/policy-config.yaml
  ENGINEERING_RUNTIME_CONSUMER: ci
  RUNTIME_GITHUB_TOKEN: ${{ secrets.RUNTIME_GITHUB_TOKEN }}

jobs:
  smoke:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: kishore-gutta/engineering-runtime-samples/.github/actions/setup-runtime@main
        with:
          runtime_github_token: ${{ secrets.RUNTIME_GITHUB_TOKEN }}
          github_organization: ${{ vars.GITHUB_ORG || github.repository_owner }}

      - run: runtime config validate

      - run: |
          runtime capability execute examples/capabilities/files/notes-roundtrip.md \
            --input path=./notes.txt \
            --input message="hello from CI"

      - env:
          RUNTIME_GITHUB_TOKEN: ${{ secrets.RUNTIME_GITHUB_TOKEN }}
        run: |
          runtime auth status
          runtime github user get

      - if: always()
        run: runtime audit tail -n 50

Use the company Capability Registry

Clone engineering-runtime-capabilities and resolve capabilities by name:

- name: Clone capability registry
  run: |
    git clone --depth 1 \
      https://github.com/kishore-gutta/engineering-runtime-capabilities.git \
      capability-registry

- name: Validate / execute from registry
  env:
    RUNTIME_CAPABILITIES_DIR: ${{ github.workspace }}/capability-registry
  run: |
    runtime capability validate github/github-repo-health
    runtime capability execute github/github-repo-health \
      --input repository=cli/cli

Reference workflow: capabilities-from-registry.yaml.

Patterns from samples

Workflow Pattern
runtime-ci.yaml Install → validate sample caps → auth-free + GitHub smoke → audit
capabilities-from-registry.yaml Clone full registry → validate all → optional execute
java-service-scaffold-and-ship.yaml Dispatch-only end-to-end demo (creates a fresh repo)
github-*.yaml Scheduled / dispatch packs for org health, reviews, audits

Destructive packs are dispatch-only or local — do not schedule them blindly.

Other CI systems

The composite action is GitHub Actions-specific. Elsewhere, mirror its steps:

  1. Download the matching linux-* / runner archive + SHA256SUMS.txt
  2. Verify checksum, extract, put runtime on PATH
  3. Export the env vars in Job contract
  4. runtime bootstrap
  5. Seed context if needed (runtime context / edit context.yaml)
  6. runtime config validate then your capability or provider commands

Local dry-run of a CI-shaped Home

export ENGINEERING_RUNTIME_HOME="$PWD/runtime-home"
export RUNTIME_CONFIG_FILE="$ENGINEERING_RUNTIME_HOME/config.yaml"
export RUNTIME_POLICY_FILE="$ENGINEERING_RUNTIME_HOME/policy-config.yaml"
export ENGINEERING_RUNTIME_CONSUMER=ci
export RUNTIME_GITHUB_TOKEN=ghp_…

rm -rf "$ENGINEERING_RUNTIME_HOME"
runtime bootstrap
runtime config validate

runtime-home/ should stay gitignored.

Next