Skip to content

Commit 371a8c2

Browse files
committed
feat(workflows): enhance Docker metadata extraction for validation and push
- Split metadata extraction into two distinct steps: one for validation (using manifest-only annotations) and another for push (utilizing both manifest and index annotations). - Updated the workflow to ensure proper handling of OCI labels and annotations for Docker images, improving traceability and compliance. - Adjusted the tags and annotations references in subsequent steps to align with the new metadata extraction structure.
1 parent 1e1aae6 commit 371a8c2

File tree

1 file changed

+53
-9
lines changed

1 file changed

+53
-9
lines changed

.github/workflows/docker.yml

Lines changed: 53 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -285,8 +285,49 @@ jobs:
285285
# - Full registry path (ghcr.io/owner/repo) for production images
286286
# - Multiple tags for flexibility (full version, minor version, latest)
287287
# - Comprehensive OCI labels for traceability and compliance
288-
- name: Extract metadata
289-
id: meta
288+
#
289+
# Note: We extract metadata twice - once for validation (manifest-only annotations
290+
# since index annotations aren't supported when loading to Docker daemon) and once
291+
# for push (manifest+index annotations for full registry support).
292+
- name: Extract metadata for validation
293+
id: meta_validate
294+
uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5
295+
with:
296+
# Full registry path for production images (ghcr.io/owner/repo)
297+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
298+
tags: |
299+
type=semver,pattern={{version}}
300+
type=semver,pattern={{major}}.{{minor}}
301+
type=raw,value=latest
302+
labels: |
303+
org.opencontainers.image.title=${{ env.DOCKER_IMAGE_TITLE }}
304+
org.opencontainers.image.description=${{ env.DOCKER_IMAGE_DESCRIPTION }}
305+
org.opencontainers.image.source=${{ env.DOCKER_IMAGE_SOURCE }}
306+
org.opencontainers.image.licenses=${{ env.DOCKER_IMAGE_LICENSE }}
307+
org.opencontainers.image.authors=${{ env.DOCKER_IMAGE_AUTHORS }}
308+
org.opencontainers.image.vendor=${{ env.DOCKER_IMAGE_VENDOR }}
309+
org.opencontainers.image.revision=${{ github.sha }}
310+
org.opencontainers.image.documentation=${{ env.DOCKER_IMAGE_DOCS }}
311+
# GHCR often reads description from OCI annotations (manifest/index)
312+
# rather than only image config labels, especially when Buildx produces
313+
# an OCI index (e.g. when provenance/attestations are attached).
314+
# For validation builds (load: true), we only use manifest annotations
315+
# since index annotations aren't supported for single-platform Docker exports.
316+
annotations: |
317+
org.opencontainers.image.title=${{ env.DOCKER_IMAGE_TITLE }}
318+
org.opencontainers.image.description=${{ env.DOCKER_IMAGE_DESCRIPTION }}
319+
org.opencontainers.image.source=${{ env.DOCKER_IMAGE_SOURCE }}
320+
org.opencontainers.image.licenses=${{ env.DOCKER_IMAGE_LICENSE }}
321+
org.opencontainers.image.authors=${{ env.DOCKER_IMAGE_AUTHORS }}
322+
org.opencontainers.image.vendor=${{ env.DOCKER_IMAGE_VENDOR }}
323+
org.opencontainers.image.revision=${{ github.sha }}
324+
org.opencontainers.image.documentation=${{ env.DOCKER_IMAGE_DOCS }}
325+
env:
326+
# Only manifest annotations for validation builds (load: true)
327+
# Index annotations aren't supported when loading to Docker daemon
328+
DOCKER_METADATA_ANNOTATIONS_LEVELS: manifest
329+
- name: Extract metadata for push
330+
id: meta_push
290331
uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5
291332
with:
292333
# Full registry path for production images (ghcr.io/owner/repo)
@@ -318,6 +359,7 @@ jobs:
318359
org.opencontainers.image.documentation=${{ env.DOCKER_IMAGE_DOCS }}
319360
env:
320361
# Place annotations on both the manifest and (when present) the index.
362+
# Index annotations are supported when pushing to registry.
321363
DOCKER_METADATA_ANNOTATIONS_LEVELS: manifest,index
322364
- name: Generate Release Version
323365
id: release_version
@@ -370,11 +412,12 @@ jobs:
370412
type=gha,mode=max
371413
# Image tags for identification (semver versions + latest from metadata extraction)
372414
# Multiple tags created: v1.2.3, 1.2, 1, latest (for default branch)
373-
tags: ${{ steps.meta.outputs.tags }}
415+
tags: ${{ steps.meta_validate.outputs.tags }}
374416
# OCI labels for image metadata (title, description, source, license, etc.)
375-
labels: ${{ steps.meta.outputs.labels }}
417+
labels: ${{ steps.meta_validate.outputs.labels }}
376418
# OCI annotations for registry UIs (e.g. GHCR package description)
377-
annotations: ${{ steps.meta.outputs.annotations }}
419+
# Using manifest-only annotations since index annotations aren't supported when loading
420+
annotations: ${{ steps.meta_validate.outputs.annotations }}
378421
# Disable attestations for validation build (faster validation, attestations added in push step)
379422
# Note: Attestations (SBOM/provenance) are only generated when pushing, not when loading to daemon
380423
provenance: false
@@ -393,7 +436,7 @@ jobs:
393436
uses: docker/scout-action@f8c776824083494ab0d56b8105ba2ca85c86e4de # v1
394437
with:
395438
command: cves
396-
image: ${{ steps.meta.outputs.tags }}
439+
image: ${{ steps.meta_validate.outputs.tags }}
397440
only-severities: critical,high
398441
exit-code: 1
399442
github-token: ${{ secrets.GITHUB_TOKEN }}
@@ -430,11 +473,12 @@ jobs:
430473
type=gha,mode=max
431474
# Image tags for identification (semver versions + latest from metadata extraction)
432475
# Multiple tags created: v1.2.3, 1.2, 1, latest (for default branch)
433-
tags: ${{ steps.meta.outputs.tags }}
476+
tags: ${{ steps.meta_push.outputs.tags }}
434477
# OCI labels for image metadata (title, description, source, license, etc.)
435-
labels: ${{ steps.meta.outputs.labels }}
478+
labels: ${{ steps.meta_push.outputs.labels }}
436479
# OCI annotations for registry UIs (e.g. GHCR package description)
437-
annotations: ${{ steps.meta.outputs.annotations }}
480+
# Using manifest+index annotations for full registry support
481+
annotations: ${{ steps.meta_push.outputs.annotations }}
438482
# Enable SBOM and provenance for supply chain security
439483
# SBOM: Software Bill of Materials for dependency tracking
440484
# Provenance: Build attestations for supply chain security (mode=max includes all metadata)

0 commit comments

Comments
 (0)