forked from ChelseaKR/tods-validate
-
Notifications
You must be signed in to change notification settings - Fork 0
134 lines (125 loc) · 5.19 KB
/
Copy pathdocker.yml
File metadata and controls
134 lines (125 loc) · 5.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
name: Docker image
on:
release:
types: [published]
# A release event runs the workflow file at the tagged commit, so a fix to
# this file cannot re-run for an already-published release. The `tag` input
# lets a dispatch (which runs the file from main) rebuild an existing
# release tag with the same verify-at-tag/scan-before-push/sign chain.
workflow_dispatch:
inputs:
tag:
description: "Existing release tag to build (e.g. v0.8.0). Empty builds main as latest-only."
required: false
type: string
default: ""
# Least-privilege default; the build-push job escalates only what it needs
# (CICD-04: write scopes job-level only).
permissions:
contents: read
# Never run two image builds/pushes of the same ref at once (CICD-23).
concurrency:
group: docker-${{ github.ref }}
cancel-in-progress: false
jobs:
# Re-run the full gate set at the tagged commit before anything is pushed
# (REL-14/15, added after the 2026-07-05 conformance audit).
verify:
uses: ./.github/workflows/verify.yml
with:
tag: ${{ github.event_name == 'release' && github.event.release.tag_name || inputs.tag || '' }}
build-push:
needs: [verify]
runs-on: ubuntu-latest
permissions:
packages: write
id-token: write # for keyless cosign signing
outputs:
digest: ${{ steps.build.outputs.digest }}
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
with:
persist-credentials: false
# On a release event inputs.tag is empty, so this stays github.ref
# (the tag); a dispatch with a tag builds that tag's tree.
ref: ${{ inputs.tag || github.ref }}
- uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3
- uses: docker/metadata-action@80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9 # v6.1.0
id: meta
with:
images: ghcr.io/${{ github.repository }}
# semver value: on a release event ref_name is the tag, matching the
# old ref-derived behavior; a dispatch supplies the tag explicitly.
tags: |
type=semver,pattern={{version}},value=${{ inputs.tag || github.ref_name }}
type=raw,value=latest
# Build once, locally (push: false), so Trivy can scan the image before
# it ever reaches the registry (SEC-28 / REL-18). Only pushed below if
# the scan is clean.
- uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7.2.0
id: build-local
with:
context: .
push: false
load: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
# OCI references reject uppercase; github.repository is mixed-case
# (ChelseaKR/...), which made this scan fail to parse the ref on the
# v0.7.0 release. metadata-action lowercases the tags it builds, so the
# locally-loaded image only exists under the lowercased name.
- name: Lowercase the image name for the scan
id: image
env:
REPO: ${{ github.repository }}
run: echo "name=ghcr.io/${REPO,,}" >> "$GITHUB_OUTPUT"
- name: Scan the image for CRITICAL/HIGH CVEs (blocking)
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
with:
image-ref: ${{ steps.image.outputs.name }}:${{ steps.meta.outputs.version }}
severity: "CRITICAL,HIGH"
exit-code: "1"
ignore-unfixed: true
- uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7.2.0
id: build
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
sbom: true
provenance: mode=max
- name: Install cosign
uses: sigstore/cosign-installer@398d4b0eeef1380460a10c8013a76f728fb906ac # v3
- name: Sign the image by digest
env:
DIGEST: ${{ steps.build.outputs.digest }}
REPO: ${{ github.repository }}
run: |
IMAGE="ghcr.io/${REPO,,}"
cosign sign --yes "${IMAGE}@${DIGEST}"
verify-published:
# Re-verify the signature on the pushed digest rather than trusting that
# `cosign sign` exiting 0 means a verifier will accept it later (REL-16).
needs: [build-push]
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Install cosign
uses: sigstore/cosign-installer@398d4b0eeef1380460a10c8013a76f728fb906ac # v3
- name: Verify the keyless signature by digest
env:
DIGEST: ${{ needs.build-push.outputs.digest }}
REPO: ${{ github.repository }}
run: |
set -eu
IMAGE="ghcr.io/${REPO,,}"
cosign verify "${IMAGE}@${DIGEST}" \
--certificate-identity-regexp "^https://github.com/${REPO}/.github/workflows/docker.yml@.*$" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com"