Added copa to the images build#247
Conversation
Changed publishing process to publish only patched images
There was a problem hiding this comment.
Pull request overview
Updates the Docker image release workflow to introduce an automated “scan + patch” stage (Trivy + Copa) before pushing images to registries, aiming to publish images after OS-level vulnerability remediation.
Changes:
- Defaults manual (
workflow_dispatch) runs to not publish images unless explicitly enabled. - Installs Trivy and Copa in the workflow, and starts a BuildKit daemon to support Copa patching.
- Changes the build/publish flow to build locally, scan + patch the image, then tag and push all tags manually.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…efined') The 5.x merge (c3586e2) reintroduced the full production matrix without the per-entry 'hardened' field, but 5 steps still gate on matrix.build.hardened -> actionlint failed (property not defined). Re-add hardened: true on the stable v* legs (v2.3, v3.8 x8.2/8.3, v4.2, v5.2) and hardened: false on the *.x dev legs, matching the README contract (-hardened is for stable release tags; -dev tags are plain-only). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 11 out of 11 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (1)
.github/workflows/release.yml:406
always()is also true after an operator cancels the workflow, soprocess-tagscan still publish logical manifests from whichever per-architecture artifacts completed before cancellation. Use!cancelled()here; it still allows this job to run after failed matrix legs (preserving plain-tag aggregation after gate failures) while honoring cancellation.
uses: docker/setup-buildx-action@v4
| if compgen -G '.docker-state/*/gate_failed.txt' > /dev/null; then | ||
| echo "The following variants failed the severity gate; their -hardened tags were NOT published:" | ||
| grep -H . .docker-state/*/gate_failed.txt | ||
| echo "::error::One or more variants failed the severity gate (plain images were published as-is)" |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 11 out of 11 changed files in this pull request and generated 2 comments.
Comments suppressed due to low confidence (1)
.github/workflows/release.yml:129
- These Oras downloads run under
set -ebefore any image is built or pushed, so a transient Oras release/checksum outage aborts the entire matrix leg. That makes OCI referrer attachment mandatory in practice even though the PR defines it as best-effort. Guard the Oras installation and continue with an explicit warning when it is unavailable;attach-sbom.shcan then skip attachment while SBOM artifact generation and image publishing continue.
curl -fsSL -o oras.tar.gz "https://github.com/oras-project/oras/releases/download/v${ORAS_VERSION}/oras_${ORAS_VERSION}_linux_${ORAS_ARCH}.tar.gz"
curl -fsSL -o oras_checksums.txt "https://github.com/oras-project/oras/releases/download/v${ORAS_VERSION}/oras_${ORAS_VERSION}_checksums.txt"
| sparse-checkout-cone-mode: false | ||
|
|
||
| - name: Enable containerd image store | ||
| if: ${{ matrix.build.hardened }} |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 11 out of 11 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (1)
.github/workflows/release.yml:12
- The new publishing controls leave the existing
publishinput defaulted totrueon line 9. This contradicts the PR's stated opt-in/default-false contract and means a routine manual dispatch pushes all plain tags unless the operator explicitly disables publishing. Change that default tofalsesoworkflow_dispatchis a dry run by default.
publish_hardened:
description: 'Also publish the Copa-hardened (-hardened) tags. Requires publish=true. Off by default so hardened stays unpublished (built + scanned + gated but not pushed) on scheduled/tag runs and during testing, until explicitly enabled on a manual dispatch.'
…-run) The severity-gate failure error claimed '(plain images were published as-is)', which is false on a publish:false dry-run where nothing is pushed. Reword to state only that the -hardened tags were skipped and plain handling is unaffected -- accurate in both publish and dry-run modes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 11 out of 11 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (1)
.github/workflows/release.yml:12
- The new publishing contract says manual publishing is opt-in, but the
publishinput above still defaults totrue. A manual dispatch that accepts the defaults will therefore push every plain tag, contrary to the PR description and the documentedpublish: falsedefault. Change that default tofalse.
description: 'Also publish the Copa-hardened (-hardened) tags. Requires publish=true. Off by default so hardened stays unpublished (built + scanned + gated but not pushed) on scheduled/tag runs and during testing, until explicitly enabled on a manual dispatch.'
| if ! docker buildx imagetools create \ | ||
| --tag "$lt" \ | ||
| "${lt}-amd64" \ | ||
| "${lt}-arm64"; then |
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…empty) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…s (no behavior change)
…ver now works on the tags users pull)
…ertion gap)
Final-review (Fable) found the S assertion was vacuous: 'pimcore/pimcore:php8.5-v5.2'
is a substring of the imagetools-create line already in the log, so it passed even if
attach targeted the child (…-amd64) ref. Replace with exact subject-binding assertions
per arch, and fix the garbled 'got 0\n0' count message. Mutation-verified: attaching to
${lt}-amd64 instead of $lt now fails both assertions.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 15 out of 15 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (1)
.github/workflows/release.yml:12
- The PR description makes manual publishing opt-in (
publishdefaults tofalse), but the existingpublishinput still defaults totrueat line 9. A manual dispatch that accepts the defaults will therefore push all plain images, contrary to the advertised safe dry-run default. Change that default tofalse.
description: 'Also publish the Copa-hardened (-hardened) tags. Requires publish=true. Off by default so hardened stays unpublished (built + scanned + gated but not pushed) on scheduled/tag runs and during testing, until explicitly enabled on a manual dispatch.'
Adds an opt-in, security-hardened image flavour to the release pipeline. Plain
images are always published as-is (even if they contain CVEs); Copacetic (Copa) then
produces a patched
-hardenedvariant with fixable OS-level vulnerabilitiesresolved. Every published image gets a Trivy-generated SPDX SBOM.
Users pick per image: plain (e.g.
php8.5-debug-v5) or hardened(
php8.5-debug-v5-hardened).Vulnerability scanning & patching
--ignore-unfixed).-hardenedimage.fail_on_severity, defaultCRITICAL,HIGH, threshold semantics —naming a severity also gates everything above it;
NONEdisables) decides whether thehardened image passes. If the gate fails, the plain image still ships and only the
hardened tag is skipped.
Local patching via the containerd image store
On the hardened (stable) legs the workflow enables Docker's containerd image store
(
containerd-snapshotter) so Copa patches the locally built image through dockerd'sembedded BuildKit — no standalone BuildKit daemon and no registry round-trip. This replaces
the earlier standalone-
buildkitdapproach and means apublish: falsedispatch runs thefull hardened path (build → patch → gate → SBOM) entirely on the runner, pushing nothing.
SBOM (compliance)
Trivy generates an SPDX SBOM for each published image (legal requirement). SBOMs are
attached as OCI referrers via
oras(best-effort) and uploaded as workflow artifacts.Publishing controls
publish— defaultfalse: publishing is opt-in for manualworkflow_dispatchruns.publish_hardened— defaultfalse: the hardened image is always built, scanned andgated, but only pushed when explicitly enabled (requires
publish: true). Scheduled/tagruns and dry-runs never push hardened tags.
arches were pushed in the same run.
Housekeeping
scan-patch-gate.sh,attach-sbom.sh,normalize-severity.sh) ship withbash unit tests, and
actionlintlints the workflows in CI.Testing the hardened path without publishing
Trigger the workflow via
workflow_dispatchwithpublish: false— the stable images arebuilt, Copa-patched, scanned and gated on the runner with nothing pushed. Use
publish: true+publish_hardened: falseto publish plain tags while still building andgating hardened locally.