The publish workflow only fired on push to main and on v* tags, which meant the Dockerfile got no CI coverage at all until after it landed — and the workflow could not be observed working before merging it. PRs now run the same build with push disabled, amd64 only (the emulated arm64 leg is the slow part and is not needed to prove the build works). Login, SBOM, provenance and attestation are skipped when not publishing. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
96 lines
3.3 KiB
YAML
96 lines
3.3 KiB
YAML
name: Publish Docker image
|
|
|
|
on:
|
|
push:
|
|
branches: [main]
|
|
tags: ["v*.*.*"]
|
|
# Build (but do not publish) on PRs, so a broken Dockerfile is caught before
|
|
# it reaches main rather than after. Without this the image build gets no
|
|
# coverage at all until merge.
|
|
pull_request:
|
|
workflow_dispatch:
|
|
|
|
env:
|
|
REGISTRY: ghcr.io
|
|
IMAGE_NAME: ${{ github.repository }}
|
|
|
|
jobs:
|
|
publish:
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
contents: read
|
|
packages: write
|
|
# Needed to attach a build provenance attestation to the pushed image.
|
|
id-token: write
|
|
attestations: write
|
|
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
# QEMU lets the amd64 runner emulate arm64 so one job produces both
|
|
# architectures (Apple Silicon + typical cloud hosts). The emulated arm64
|
|
# leg is the slow part of this workflow; if it starts to hurt, split into
|
|
# a matrix over ubuntu-latest + ubuntu-24.04-arm and merge the digests.
|
|
- name: Set up QEMU
|
|
uses: docker/setup-qemu-action@v3
|
|
|
|
- name: Set up Buildx
|
|
uses: docker/setup-buildx-action@v3
|
|
|
|
- name: Log in to GHCR
|
|
if: github.event_name != 'pull_request'
|
|
uses: docker/login-action@v3
|
|
with:
|
|
registry: ${{ env.REGISTRY }}
|
|
username: ${{ github.actor }}
|
|
password: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
# ghcr.io requires a lowercase image path; github.repository keeps the
|
|
# owner's original casing (geneticglitch1/XRayPDF), so normalize it.
|
|
- name: Compute lowercase image name
|
|
id: image
|
|
run: echo "name=${IMAGE_NAME,,}" >> "$GITHUB_OUTPUT"
|
|
|
|
- name: Extract metadata
|
|
id: meta
|
|
uses: docker/metadata-action@v5
|
|
with:
|
|
images: ${{ env.REGISTRY }}/${{ steps.image.outputs.name }}
|
|
tags: |
|
|
type=raw,value=latest,enable={{is_default_branch}}
|
|
type=ref,event=branch
|
|
type=semver,pattern={{version}}
|
|
type=semver,pattern={{major}}.{{minor}}
|
|
type=sha,format=long
|
|
labels: |
|
|
org.opencontainers.image.title=XRayPDF
|
|
org.opencontainers.image.description=Strip hidden text and invisible layers out of PDFs
|
|
org.opencontainers.image.licenses=Apache-2.0
|
|
|
|
- name: Build and push
|
|
id: build
|
|
uses: docker/build-push-action@v6
|
|
with:
|
|
context: ./client
|
|
# PRs only need to prove the image builds; the emulated arm64 leg is
|
|
# the slow part, so save it for builds that actually publish.
|
|
platforms: >-
|
|
${{ github.event_name == 'pull_request'
|
|
&& 'linux/amd64'
|
|
|| 'linux/amd64,linux/arm64' }}
|
|
push: ${{ github.event_name != 'pull_request' }}
|
|
tags: ${{ steps.meta.outputs.tags }}
|
|
labels: ${{ steps.meta.outputs.labels }}
|
|
cache-from: type=gha
|
|
cache-to: type=gha,mode=max
|
|
provenance: ${{ github.event_name != 'pull_request' && 'mode=max' || 'false' }}
|
|
sbom: ${{ github.event_name != 'pull_request' }}
|
|
|
|
- name: Attest build provenance
|
|
if: github.event_name != 'pull_request'
|
|
uses: actions/attest-build-provenance@v2
|
|
with:
|
|
subject-name: ${{ env.REGISTRY }}/${{ steps.image.outputs.name }}
|
|
subject-digest: ${{ steps.build.outputs.digest }}
|
|
push-to-registry: true
|