For directories whose bundled dependencies cannot be upgraded in place — first user: the Android SDK cmdline-tools jars (old protobuf/guava et al. inside sdkmanager) in the gitea-runner-android image. Callers must leave a comment in the workflow explaining each exclusion. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01P5NjXQ3jmyVjimHQxnyKhg Reviewed-on: #4 Co-authored-by: peet <peet@noctrl.eu>
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 tagv1@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 (
*.podmanrepos only)
Set these in repository Settings → Secrets.
Contributing
When adding new actions:
- Create action directory:
./action-name/ - Include
action.yaml(composite action definition) - Tag stable versions:
git tag v1,git tag v2, etc. - Update this root README