Skip to content

Repository files navigation

actions

Blessed GitHub Actions.

CI Test Podman Actions License Nix flake Last commit Hercules CI

Composite actions and reusable workflows shared across my repos. The podman actions mirror the docker/* action interfaces so a workflow can swap between them with minimal changes.

Actions

Action Purpose Docker counterpart
podman-build-push Build and optionally push an image with podman, with multi-arch, cache, and SBOM support docker/build-push-action
podman-login Log into a container registry with podman, with ECR auto-detection docker/login-action
setup-qemu Register QEMU binfmt emulators via tonistiigi/binfmt for cross-platform builds docker/setup-qemu-action
setup-nix Install Nix and configure Cachix none

Reusable workflows

Workflow Purpose
docker-build-push.yml Build and push with buildx, tagged by docker/metadata-action
podman-build-push.yml Same interface as above, built with podman
release-please.yml Open release PRs and tag releases with release-please

Usage

Releases are tagged vX.Y.Z and a floating vX tag tracks the latest release of each major version. The examples use @main for brevity; pin to @v1 for the floating major tag, or to @v1.2.3 or a full commit SHA for an exact version. setup-qemu registers binfmt_misc handlers with sudo podman run --privileged, so it needs sudo and a rootful podman. GitHub-hosted Ubuntu runners meet both requirements.

Composite actions

permissions:
  contents: read
  packages: write

steps:
  - uses: actions/checkout@v4

  - uses: unmango/actions/setup-qemu@main

  - uses: unmango/actions/podman-login@main
    with:
      registry: ghcr.io
      username: ${{ github.actor }}
      password: ${{ github.token }}

  - uses: unmango/actions/podman-build-push@main
    with:
      platforms: linux/amd64,linux/arm64
      push: 'true'
      tags: ghcr.io/${{ github.repository }}:latest

Reusable workflow

permissions:
  contents: read
  packages: write

jobs:
  image:
    uses: unmango/actions/.github/workflows/podman-build-push.yml@main
    with:
      image: ghcr.io/${{ github.repository }}
      platforms: linux/amd64,linux/arm64
      push: ${{ github.event_name != 'pull_request' }}
      sbom: ${{ github.event_name != 'pull_request' }}
    secrets:
      dockerhub_token: ${{ secrets.DOCKERHUB_TOKEN }}

Versioning a container repo

release-please.yml runs release-please in simple mode. It opens a release PR from Conventional Commits, maintains version.txt and CHANGELOG.md, and on merge creates a vX.Y.Z tag and GitHub release. The tag push runs the build-push workflow, and docker/metadata-action derives the image tags 1.2.3, 1.2, 1, and latest from it.

The workflow needs credentials with contents, pull-requests, and issues write. issues write covers the autorelease labels release-please puts on its PRs. Tags created with the default GITHUB_TOKEN do not trigger other workflows, so the image build would never run.

Pass a GitHub App through the app-client-id input and the app-private-key secret, and the workflow mints a token from them. Commits pushed with an app token are signed. A personal access token in the token secret is the alternative when app-client-id is empty.

# .github/workflows/release-please.yml
on:
  push:
    branches: [main]

permissions:
  contents: write
  pull-requests: write

jobs:
  release:
    uses: unmango/actions/.github/workflows/release-please.yml@main
    with:
      app-client-id: ${{ vars.RELEASE_APP_CLIENT_ID }}
    secrets:
      app-private-key: ${{ secrets.RELEASE_APP_PRIVATE_KEY }}
# .github/workflows/image.yml
on:
  pull_request:
  push:
    branches: [main]
    tags: ['v*']

permissions:
  contents: read
  packages: write

jobs:
  image:
    uses: unmango/actions/.github/workflows/podman-build-push.yml@main
    with:
      image: ghcr.io/${{ github.repository }}
      push: ${{ github.event_name != 'pull_request' }}
Event Image tags
Pull request pr-N
Push to main main, sha-<short>
Tag v1.2.3 1.2.3, 1.2, 1, latest, sha-<short>

Pass config-file and manifest-file to use a release-please-config.json instead of the simple defaults. The workflow exposes release_created, tag_name, version, major, minor, patch, and sha as outputs for jobs that need to run only after a release.

Feature support matrix

✅ supported · ⚠️ accepted for interface parity but ignored · ❌ not available

podman-build-push vs docker/build-push-action

Input Podman Docker Notes
context ✅ ✅
file ✅ ✅
platforms ✅ ✅ Multiple platforms build a manifest list; run setup-qemu first
tags ✅ ✅
labels ✅ ✅
annotations ✅ ✅
build-args ✅ ✅
build-contexts ✅ ✅
secrets ✅ ✅ Podman takes the id=id,src=path form only
no-cache ✅ ✅
cache-from ✅ ✅ Podman takes a single registry ref or local directory, not buildx type=... syntax, and forces --layers
cache-to ✅ ✅ Same as cache-from
pull ✅ ✅
network ✅ ✅
add-hosts ✅ ✅
cgroup-parent ✅ ✅
shm-size ✅ ✅
ulimit ✅ ✅
push ✅ ✅
sbom ✅ ✅ Podman requires push and needs syft and cosign on the runner
provenance ⚠️ ✅ No native SLSA provenance generation in buildah or podman
ssh ⚠️ ✅ No buildkit SSH agent forwarding equivalent
no-cache-filters ⚠️ ✅ buildah cache invalidation is all-or-nothing
allow ⚠️ ✅ No buildkit entitlement model
attests ❌ ✅
builder ❌ ✅
call ❌ ✅
load ❌ ✅ Podman images are already in the local store after a build
outputs ❌ ✅
secret-envs ❌ ✅
secret-files ❌ ✅ Use secrets
target ❌ ✅
github-token ❌ ✅
Output Podman Docker Notes
imageid ✅ ✅
digest ✅ ✅ Podman only sets it when push is true
metadata ✅ ✅ Podman emits containerimage.imageid, containerimage.digest, and image.tags, a subset of the buildx shape

Podman boolean inputs are strings ('true' and 'false') because composite actions have no typed inputs.

podman-login vs docker/login-action

Input Podman Docker Notes
registry ✅ ✅
username ✅ ✅
password ✅ ✅
ecr ✅ ✅ auto, true, or false; needs aws-actions/configure-aws-credentials first
logout ⚠️ ✅ Composite actions have no post-job hook; no warning is logged

setup-qemu vs docker/setup-qemu-action

Input Podman Docker Notes
platforms ✅ ✅
image ✅ ✅
cache-image ❌ ✅
cache-binary ❌ ✅

podman-build-push.yml vs docker-build-push.yml

Input Podman Docker Notes
image ✅ ✅
platforms ✅ ✅ Podman runs setup-qemu when more than one platform is listed
push ✅ ✅
build-args ✅ ✅
file ✅ ✅
context ✅ ✅
dockerhub_token (secret) ✅ ✅
secrets-list ✅ ❌ Build secrets in id=id,src=path form
cache ✅ ❌ none, registry, or local; docker always uses the GHA cache backend
cache-image ✅ ❌ Registry ref used when cache is registry
cache-dir ✅ ❌ Directory used when cache is local, persisted with actions/cache
sbom ✅ ❌ Docker always attaches an SBOM when pushing; podman installs syft and cosign and attaches an SPDX SBOM on request
provenance ⚠️ ❌ Docker always generates provenance when pushing; podman accepts the input and ignores it

Development

Enter the dev shell with nix develop, or let direnv load it from .envrc.

make check   # nix flake check, includes actionlint
make fmt     # nix fmt

About

Blessed GitHub Actions

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages