Reusable workflows
Find a file
2026-04-29 21:39:36 +00:00
.forgejo/workflows Add .forgejo/workflows/orbital-cosign.yml 2026-04-29 21:16:58 +00:00
README.md Update README.md 2026-04-29 21:39:36 +00:00

.forgejo-workflows

Reusable Forgejo Actions workflows for the Calltheory organization.

Workflows

Our primary workflow is to sign and build containers for Orbital customers to get updates.

orbital-cosign.yml

Builds a Docker image, pushes to the orbital project on Harbor, and signs it with Cosign using the org's signing key.

Pushes the image with these tags:

  • <git-sha> — immutable, traceable
  • latest
  • Any extra tags passed via extra-tags

Signs by digest (not tag), so the signature is bound to the exact image content regardless of tag mutations.

Inputs

Name Required Default Description
image-name yes Image name within the orbital project (e.g. api)
context no . Build context path within the calling repo
dockerfile no Dockerfile Dockerfile path relative to context
extra-tags no "" Newline-separated extra tags to apply (in addition to defaults)
cosign-version no v2.4.1 Cosign version to install

Required secrets

These must be available to the calling workflow (typically set at the org level and passed via secrets: inherit):

  • HARBOR_REGISTRY — registry hostname (e.g. cr.calltheory.com)
  • HARBOR_USERNAME — Harbor robot account username
  • HARBOR_PASSWORD — Harbor robot account secret
  • COSIGN_KEY — Cosign private key (PEM, encrypted)
  • COSIGN_PASSWORD — password for the Cosign private key

Versioning

Production callers should pin to a tag like @v1 for stability. Use @main only while iterating on the reusable workflow itself. Tags move forward as versions are validated.

Example callers

Minimal

Build a single image from the repo root

name: build api
 
on:
  push:
    branches: [main]
  workflow_dispatch:
 
jobs:
  build:
    uses: calltheory/.forgejo-workflows/.forgejo/workflows/orbital-cosign.yml@v1
    with:
      image-name: api
    secrets: inherit

Subdirectory

Build image from a service folder in a monorepo

name: build asterisk
 
on:
  push:
    branches: [main]
    paths:
      - 'services/asterisk/**'
  workflow_dispatch:
 
jobs:
  build:
    uses: calltheory/.forgejo-workflows/.forgejo/workflows/orbital-cosign.yml@v1
    with:
      image-name: asterisk
      context: services/asterisk
    secrets: inherit

Release tag

Build and push a versioned tag in addition to sha and latest

name: release
 
on:
  push:
    tags: ['v*']
 
jobs:
  build:
    uses: calltheory/.forgejo-workflows/.forgejo/workflows/orbital-cosign.yml@v1
    with:
      image-name: api
      extra-tags: ${{ github.ref_name }}
    secrets: inherit

This pushes api:v1.2.3 along with the usual api:<sha> and api:latest.

Multiple tags

A "stable" channel and a sha

jobs:
  build:
    uses: calltheory/.forgejo-workflows/.forgejo/workflows/orbital-cosign.yml@v1
    with:
      image-name: api
      extra-tags: |
        stable
        ${{ github.ref_name }}
    secrets: inherit

extra-tags accepts a newline-separated list. The pipe character is YAML for "multi-line literal string."

Custom Dockerfile name

jobs:
  build:
    uses: calltheory/.forgejo-workflows/.forgejo/workflows/orbital-cosign.yml@v1
    with:
      image-name: api
      dockerfile: Dockerfile.production
    secrets: inherit

Verifying signed images

After a successful run, customers can verify an image:

# First, login with your robot account credentials
docker login cr.calltheory.com

Once logged in, you can verify different images:

cosign verify --key cosign.pub cr.calltheory.com/orbital/<image-name>:<tag>

Full example using our smoketest:latest:

cosign verify --key cosign.pub cr.calltheory.com/orbital/smoketest:latest

Verification for cr.calltheory.com/orbital/smoketest:latest --
The following checks were performed on each of these signatures:
  - The cosign claims were validated
  - Existence of the claims in the transparency log was verified offline
  - The signatures were verified against the specified public key

[{"critical":{"identity":{"docker-reference":"cr.calltheory.com/orbital/smoketest:latest"},"image":{"docker-manifest-digest":"sha256:a6cb10f595b7f5ef196499a6962bb4c1b50f6f4340e1bd8aa260cbe191f080f5"},"type":"https://sigstore.dev/cosign/sign/v1"},"optional":{}}]

Finding our public key

The public key is published at:

https://git.calltheory.com/calltheory/public-keys/raw/branch/main/cosign.pub

For details on verification including Kubernetes admission control, see:

https://git.calltheory.com/calltheory/public-keys/raw/branch/main/README.md

Releasing changes to this repo

  1. Edit and test against @main from a non-production repo.

  2. Once happy, tag a release:

    git tag v1
    git push origin v1
    
  3. To roll out a breaking change, cut a new major: git tag v2, etc.

  4. To update an existing major in place (additive changes only):

    git tag -d v1
    git push origin :refs/tags/v1
    git tag v1
    git push origin v1
    

    This is destructive — only do it for non-breaking changes that production callers should pick up automatically.