FabricFabricHarness
Deployment

GitHub Actions

Build, sign, and deploy from GitHub Actions.

A reference workflow that builds the workspace, emits a signed Docker image, and pushes to a registry.

name: build-agents
on:
  push:
    branches: [main]

jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      id-token: write
      packages: write
    steps:
      - uses: actions/checkout@v7
      - uses: pnpm/action-setup@v6
        with:
          version: 10.10.0
      - uses: actions/setup-node@v7
        with:
          node-version: 22
          cache: pnpm
      - run: pnpm install --frozen-lockfile
      - run: pnpm build

      - name: Login to GHCR
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Build, sign, push agents image
        env:
          COSIGN_PRIVATE_KEY: ${{ secrets.COSIGN_PRIVATE_KEY }}
        run: |
          ./packages/cli/dist/bin/fabric-harness.js build \
            --target docker \
            --docker-build --docker-push \
            --docker-tag ghcr.io/${{ github.repository }}/agents:${{ github.sha }} \
            --image-sbom --image-sbom-required \
            --provenance --sign-provenance --signing-key env://COSIGN_PRIVATE_KEY \
            --attestation

      - uses: actions/upload-artifact@v7
        with:
          name: build-manifest
          path: |
            .fabricharness/build/docker/manifest.json
            .fabricharness/build/docker/provenance.json
            .fabricharness/build/docker/attestation.intoto.jsonl

CI smoke tests

Add a job that runs the agent against the mock model in CI:

  smoke:
    needs: build
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
      - uses: pnpm/action-setup@v6
        with:
          version: 10.10.0
      - uses: actions/setup-node@v7
        with:
          node-version: 22
          cache: pnpm
      - run: pnpm install --frozen-lockfile
      - run: pnpm build
      - run: |
          cd examples/issue-triage-ci
          ../../packages/cli/dist/bin/fabric-harness.js doctor --tools
          ../../packages/cli/dist/bin/fabric-harness.js run triage \
            --model openai/gpt-5.5 \
            --mock \
            --payload-file fixtures/issue.json

--mock is mandatory in this credential-free smoke job. It prevents provider calls, cost, and nondeterministic model output even though the definition contains a real model identifier. See examples/issue-triage-ci for repository access to the complete read-only triage fixture.

Keep Actions on supported runtimes

GitHub-hosted JavaScript actions must use a supported action runtime independently of the Node.js version your job installs. For example, actions/setup-node itself runs on Node 24 while it can still install Node 20.19 or Node 22 for compatibility testing.

Fabric's reviewed baseline is:

ActionSupported baseline
actions/checkoutv7
actions/setup-nodev7
actions/upload-artifactv7
actions/attestv4
pnpm/action-setupv6

Run pnpm check:github-actions before landing workflow or documentation changes. The check rejects older Node-runtime majors, deprecated attestation wrappers, an outdated reviewed Databricks CLI pin, the checksum-pinned Gitleaks CLI release used by the supply-chain workflow, and attempts to restore obsolete runtimes with ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION.

Fabric runs the open-source Gitleaks v8.30.1 CLI directly from its checksum-verified release archive. The current gitleaks/gitleaks-action requires a commercial license for organization-owned repositories, so it is not used as a portable default.

The repository also enables weekly Dependabot checks for the github-actions ecosystem. Treat those PRs as runtime and supply-chain updates: read the action's official release notes, update the policy baseline and examples in the same change, run CI, and verify self-hosted runners meet the action's minimum runner version. The current Node 24 actions require runner 2.327.1 or newer.

Major tags keep official actions on security and patch updates within the reviewed compatibility line. Pin third-party actions to a full commit SHA in secret-bearing or deployment workflows, and keep the human-readable release tag in the comment beside the pin.

Use ${{ github.sha }} or ${{ github.run_id }} in artifact names rather than ${{ github.ref_name }}. Branch ref names can contain /, which current upload-artifact releases reject in portable artifact names.

Protected live evidence

Keep destructive or credentialed certification in a GitHub Environment with required reviewers and protected deployment branches. Fabric's hosted-sandbox jobs use sandbox-live; direct DeepSeek, Moonshot, and xAI smoke tests use model-providers-live. A missing secret may skip an optional smoke, but it cannot create retained certification evidence.

For hosted sandboxes, run scripts/validate-sandbox-certification.mjs before upload. The validator requires credentials, all nine checks, the declared package and SDK target, and the actually installed package version. It emits a digest manifest and immutable Actions run URL. Retain both the report and manifest for review.

The ordinary CI workflow also runs pnpm test:coverage:authoring and uploads its LCOV/JSON summary. Do not publish Databricks authoring packages if that gate, docs:impact, docs:check, or docs:build fails.