Files
accounted/.github/workflows/docker-publish.yml
T
dependabot[bot] be9bec6b0d build(deps): bump actions/checkout from 6 to 7 (#764)
Bumps [actions/checkout](https://github.com/actions/checkout) from 6 to 7.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-25 12:39:32 +02:00

121 lines
4.5 KiB
YAML

name: Build and Push Docker Image
on:
push:
branches: [main]
tags: ['v*.*.*']
env:
REGISTRY: ghcr.io
IMAGE_NAME: erp-mafia/gnubok
jobs:
build-and-push:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
# OIDC token used by cosign keyless signing.
id-token: write
# SARIF upload to the repo's "Security" tab from the Trivy scan.
security-events: write
steps:
- uses: actions/checkout@v7
- name: Log in to GHCR
uses: docker/login-action@v4
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
# On main: push `latest` + commit-sha tags.
# On v*.*.* tags: push semver tags (1.2.3, 1.2, 1) for production pinning.
tags: |
type=raw,value=latest,enable={{is_default_branch}}
type=sha,prefix=
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
- name: Set up QEMU
uses: docker/setup-qemu-action@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
- name: Build and push
id: build
uses: docker/build-push-action@v7
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
build-args: |
EXTENSIONS_PRESET=self-hosted
# SBOM (software bill of materials) + SLSA provenance are attached as
# OCI attestations, queryable via `docker buildx imagetools inspect`.
provenance: mode=max
sbom: true
# Per-branch cache scope so a PR branch can't poison main's cache
# layers. Fall back to main's cache on first build of a new branch.
cache-from: |
type=gha,scope=${{ github.ref_name }}
type=gha,scope=main
cache-to: type=gha,scope=${{ github.ref_name }},mode=max
- name: Install cosign
uses: sigstore/cosign-installer@v3.7.0
- name: Sign the image (keyless OIDC)
env:
DIGEST: ${{ steps.build.outputs.digest }}
run: |
cosign sign --yes "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${DIGEST}"
- name: Scan image with Trivy (report-only)
id: trivy
# Decoupled from the publish gate on purpose: this pipeline must stay
# green so builds are deterministic. The image is already pushed and
# signed above, so failing here would only redden the run — it would not
# unship a vulnerable image. exit-code:0 + continue-on-error keep CVEs
# (and even a Trivy/DB outage) from failing the build; findings still
# flow to the Security tab below. The real blocking gate is
# docker-image-scan.yml, which re-scans the published image and fails
# (notifying admins) on a fixable CRITICAL/HIGH CVE. It runs on a
# workflow_run trigger the moment THIS workflow completes — so the gap
# between publish and the blocking scan is the scan's own duration
# (minutes), not a 24h cron window — plus a daily cron as a safety net.
# Accepted residual risk: an image is live for that short scan window
# before the gate fires; see SELF-HOSTING.md / the risk register.
continue-on-error: true
uses: aquasecurity/trivy-action@v0.36.0
with:
image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ steps.build.outputs.digest }}
severity: CRITICAL,HIGH
exit-code: '0'
ignore-unfixed: true
format: sarif
output: trivy-results.sarif
- name: Upload Trivy results to GitHub Security tab
# if: always() — evidence must reach the Security tab regardless of the
# scan step's exit status. With the previous `outcome == 'success'` guard,
# a Trivy/DB outage that errored the scan would silently drop findings.
# Kept non-fatal (continue-on-error) so a missing SARIF or a Security-tab
# hiccup can't redden an otherwise-good publish.
if: always()
continue-on-error: true
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: trivy-results.sarif
category: trivy