GitHub Actions samples (Stella Ops)

Copy-me GitHub Actions workflows for your repository. Nothing here is executed by this repository — Stella Ops runs its own CI on Gitea Actions (.gitea/workflows/).

Why these live under docs/samples/ and not in .github/. They are customer-facing integration examples, not this repo’s pipeline. Gitea Actions discovers workflows in both .gitea/workflows/ and .github/workflows/, so a .github/workflows/*.yml file carrying on: push triggers is a live workflow in this repo’s own CI, not an inert sample — and a GitHub mirror would run it too. Keeping the samples here means they can never be auto-discovered by any forge, while staying next to the rest of docs/samples/ci/. Moved 2026-08-20 from .github/.

The supported path: generate them with the CLI

Prefer stella ci init over copying these files. The CLI is the maintained generator and emits the current templates for GitHub, GitLab, and Gitea:

stella ci init --platform github --template gate     # → .github/workflows/stellaops-gate.yml
stella ci init --platform github --template scan     # → .github/workflows/stellaops-scan.yml
stella ci init --platform github --template verify   # → .github/workflows/stellaops-verify.yml
stella ci init --platform github --template full     # all three
stella ci init --platform all                        # github + gitlab + gitea
stella ci list                                       # what is available

--platform accepts github | gitlab | gitea | all (required). --template accepts gate | scan | verify | full (default gate). --mode accepts scan-only | scan-attest | scan-vex (default scan-attest). Add --offline for an offline-friendly bundle with pinned digests, --output <dir> to write elsewhere, and --force to overwrite.

Command: src/Cli/StellaOps.Cli/Commands/CiCommandGroup.cs; templates: src/Cli/StellaOps.Cli/Commands/CiTemplates.cs. Covered by src/__Tests/e2e/Integrations/CiTemplateTests.cs and src/Cli/__Tests/StellaOps.Cli.Tests/Commands/CiTemplatesProvenanceTests.cs.

stella ci validate <path> exists but is currently a path-existence check only — it reports “validation passed” for any file or directory that exists. Do not read a pass from it as schema or semantic validation of your workflow.

What is in this directory

FilePurposeCopy into your repo as
stellaops-gate-example.ymlRelease gate: stella gate evaluate blocks releases that add reachable vulnerabilities. Exit codes 0 pass / 1 warn / 2 fail..github/workflows/stellaops-gate.yml
stellaops-sign.ymlReusable (workflow_call) keyless signing via Sigstore Fulcio, using the Actions OIDC token..github/workflows/stellaops-sign.yml
stellaops-verify.ymlReusable (workflow_call) verification gate — verifies attestations before deploy..github/workflows/stellaops-verify.yml
example-container-sign.ymlEnd-to-end: build → push → keyless-sign a container image, attach attestation..github/workflows/ (adapt)
example-sbom-sign.ymlGenerate an SBOM (Syft), sign it, attach the SBOM attestation..github/workflows/ (adapt)
example-verdict-sign.ymlRun policy evaluation, sign the verdict, use it as a deployment gate..github/workflows/ (adapt)
example-verification-gate.ymlPre-deployment gate: require attestations, validate identity constraints, block on failure..github/workflows/ (adapt)

The two stellaops-*.yml reusable workflows are called by the example-*.yml ones. If you copy an example, copy the reusable workflows it references too, and update the uses: reference to point at your own repository.

Before you copy