Files
actions/README.md
T
peetandClaude Fable 5 54cdfad823 android-signing and trivy-fs-scan actions (android repo cleanup)
- android-signing: the keystore-restore step previously copy-pasted in
  habitude and ablage-android; no-op without the secret (unsigned build).
- trivy-fs-scan: lockfile-based dependency scan for artifact-building
  repos (APKs); non-blocking by default via enforce input.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P5NjXQ3jmyVjimHQxnyKhg
2026-08-30 10:01:15 +02:00

5.9 KiB

Gitea Actions

Reusable Gitea Actions composite workflows for noctrl infrastructure automation.

The standard pipeline (since v11)

Build once, scan explicitly, promote — the registry is the hand-off between workflows. A push to the default branch builds each architecture exactly once and pushes immutable, never-deployed candidate tags (sha-<commit>[-<arch>]); an explicit Trivy job scans the candidate. A release rebuilds nothing: it re-scans the candidate and retags it server-side.

build.yml (push to default branch):

validate (pre-commit)  →  build-amd64 ─┐
                          build-arm64 ─┤→  manifest (multi-arch only)  →  scan

release.yml (tag v*):

scan (candidate of the tagged commit)  →  promote (sha-<commit> → vX)

The scan in release.yml is the enforcing gate: a release tag can only come into existence behind a scan that passed at promotion time. Candidates carrying CVEs may exist in the registry — nothing consumes sha-* tags, so they are inert. Scan and promote jobs always run on linux,build,amd64 (never on the slow arm runners; vulnerability results are package-based and arch-independent).

Before v11, podman-build-publish@v10 briefly embedded the Trivy gate itself; v11 moved it into the explicit trivy-scan action.

Available Actions

Podman Build And Publish

Builds and optionally pushes OCI container images to registry.noctrl.eu using Podman with isolated storage context. Build and candidate-push are deliberately one action: each invocation initializes its own podman storage, so a split build/push pair would have to re-pull what was just built.

Location: ./podman-build-publish

- uses: https://gitea.noctrl.eu/public/actions/podman-build-publish@v11
  with:
    image-name: noctrl/myapp
    tags: |
      sha-${{ github.sha }}-amd64
    registry-username: ${{ secrets.REGISTRY_USERNAME }}
    registry-password: ${{ secrets.REGISTRY_PASSWORD }}

Podman Manifest Publish

Creates and pushes OCI multi-arch manifest tags to registry.noctrl.eu — used to assemble the per-arch candidates into the multi-arch candidate.

Location: ./podman-manifest-publish

- uses: https://gitea.noctrl.eu/public/actions/podman-manifest-publish@v11
  with:
    image-name: noctrl/myapp
    manifest-tag: sha-${{ github.sha }}
    source-tags: |
      sha-${{ github.sha }}-amd64
      sha-${{ github.sha }}-arm64

Trivy Scan

Scans an image ref in registry.noctrl.eu and fails on fixable HIGH/CRITICAL vulnerabilities (severities configurable). Requires trivy on the runner (noctrl/gitea-runner >= v9). Pin the job to linux,build,amd64.

Location: ./trivy-scan

- uses: https://gitea.noctrl.eu/public/actions/trivy-scan@v11
  with:
    image-name: noctrl/myapp
    tag: sha-${{ github.sha }}
    registry-username: ${{ secrets.REGISTRY_USERNAME }}
    registry-password: ${{ secrets.REGISTRY_PASSWORD }}

Podman Promote

Retags an existing image (or multi-arch manifest list) server-side via skopeo copy --all — no rebuild, no transfer, fails if the source tag does not exist. Requires skopeo on the runner (noctrl/gitea-runner >= v10).

Location: ./podman-promote

- uses: https://gitea.noctrl.eu/public/actions/podman-promote@v11
  with:
    image-name: noctrl/myapp
    source-tag: sha-${{ github.sha }}
    target-tag: ${{ github.ref_name }}
    registry-username: ${{ secrets.REGISTRY_USERNAME }}
    registry-password: ${{ secrets.REGISTRY_PASSWORD }}

Android Signing

Restores the Android release keystore (<alias>-release.jks + keystore.properties) from repo secrets; no-op when the secret is unset (build stays unsigned).

Location: ./android-signing

- uses: https://gitea.noctrl.eu/public/actions/android-signing@v12
  with:
    keystore-b64: ${{ secrets.ANDROID_KEYSTORE_B64 }}
    keystore-password: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
    key-alias: habitude

Trivy Filesystem Scan

Scans the checked-out workspace for vulnerable dependencies (lockfile-based) — for repos that build artifacts (APKs) rather than images. Non-blocking by default (enforce: "false"); requires committed Gradle lockfiles and the trivy binary on the runner. Pin the job to linux,build,amd64.

Location: ./trivy-fs-scan

- uses: https://gitea.noctrl.eu/public/actions/trivy-fs-scan@v12

Deploy Prod

Shared deploy body for the *.podman infrastructure repos: installs the SSH deploy key, validates the mounted deploy-target env file, and pipes the deploy runner's deploy-prod.sh to the production host over SSH. Runs on that host's dedicated deploy runner (gitea-runner-deploy image).

Location: ./deploy-prod

- uses: https://gitea.noctrl.eu/public/actions/deploy-prod@v11
  with:
    deploy-target-file: /run/noctrl/prod-deploy-target.env
    ssh-key-b64: ${{ secrets.PROD_DEPLOY_SSH_KEY }}
    target-sha: ${{ github.sha }}

Usage

Reference actions by absolute URL in your workflow:

- uses: https://gitea.noctrl.eu/public/actions/<action-name>@<ref>

Ref Options:

  • @v1 — points to tag v1
  • @main — points to default branch
  • @commit-sha — points to specific commit

Repository Secrets

Actions reference caller repository secrets. Ensure your repository has required secrets defined:

  • REGISTRY_USERNAME — registry.noctrl.eu authentication username
  • REGISTRY_PASSWORD — registry.noctrl.eu authentication password
  • PROD_DEPLOY_SSH_KEY — base64-encoded SSH deploy key (*.podman repos only)

Set these in repository Settings → Secrets.

Contributing

When adding new actions:

  1. Create action directory: ./action-name/
  2. Include action.yaml (composite action definition)
  3. Tag stable versions: git tag v1, git tag v2, etc.
  4. Update this root README