2222permissions :
2323 contents : write
2424 packages : write
25+ security-events : write
2526
2627jobs :
28+ scan-dependencies :
29+ runs-on : ubuntu-latest
30+ steps :
31+ - name : Check out code
32+ uses : actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
33+
34+ - uses : actions/dependency-review-action@56339e523c0409420f6c2c9a2f4292bbb3c07dd3 # v4.8.0
35+ # this action requires a base and head
36+ # ensure that trunk changes require pull request checks to pass
37+ if : ${{ github.event_name == 'pull_request' }}
38+
39+ scan-codeql :
40+ runs-on : ubuntu-latest
41+ steps :
42+ - name : Check out code
43+ uses : actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
44+
45+ - uses : github/codeql-action/init@e296a935590eb16afc0c0108289f68c87e2a89a5 # v4.30.7
46+ with :
47+ languages : actions,go
48+ - uses : github/codeql-action/analyze@e296a935590eb16afc0c0108289f68c87e2a89a5 # v4.30.7
49+ with :
50+ output : codeql-sarif
51+ - name : Check success or failure
52+ # github/codeql-action/analyze doesn't fail the pipeline when it finds vulnerabilities
53+ run : |
54+ set -euo pipefail
55+ shopt -s nullglob
56+ files=(codeql-sarif/*.sarif)
57+ if [ ${#files[@]} -eq 0 ]; then
58+ echo "No SARIF files produced by CodeQL analyze."
59+ exit 1
60+ fi
61+ # Count non-note results across all SARIF files
62+ count="$(jq -s 'map(.runs[].results // []) | flatten | map(select(.level != "note")) | length' "${files[@]}")"
63+ echo "Non-note CodeQL results: ${count}"
64+ if [ "${count}" -gt 0 ]; then
65+ echo "::error::CodeQL produced ${count} alerts (warning/error)."
66+ exit 1
67+ fi
68+
69+ scan-nix :
70+ runs-on : ubuntu-latest
71+ steps :
72+ - name : Check out code
73+ uses : actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
74+
75+ - name : Check Nix flake inputs
76+ uses : DeterminateSystems/flake-checker-action@3164002371bc90729c68af0e24d5aacf20d7c9f6 # v12
77+ with :
78+ send-statistics : false
79+
2780 build-go :
81+ needs : [ scan-dependencies, scan-codeql, scan-nix ]
2882 runs-on : ubuntu-latest
2983 strategy :
3084 matrix :
3185 arch : ${{ fromJson(inputs.architectures) }}
3286 steps :
3387 - name : Check out code
34- uses : actions/checkout@v5
88+ uses : actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
3589
3690 - name : Install Go
37- uses : actions/setup-go@v5
91+ uses : actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
3892 with :
3993 go-version-file : go.mod
4094
4195 - name : Run linter
42- uses : golangci/golangci-lint-action@v8
96+ uses : golangci/golangci-lint-action@4afd733a84b1f43292c63897423277bb7f4313a9 # v8.0.0
4397
4498 - name : Run tests
4599 run : |-
@@ -64,73 +118,110 @@ jobs:
64118 ./cmd/multigres-operator
65119
66120 - name : Upload artifacts
67- uses : actions/upload-artifact@v4
121+ uses : actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
68122 with :
69123 name : multigres-operator-${{matrix.arch}}
70124 path : dist/*
125+ if-no-files-found : error
126+ retention-days : 7
71127
72- build-push-container :
128+ build-scan- push-container :
73129 needs : [ build-go ]
74130 runs-on : ubuntu-latest
75131 steps :
76132 - name : Check out code
77- uses : actions/checkout@v5
133+ uses : actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
78134
79135 - name : Set up QEMU
80- uses : docker/setup-qemu-action@v3
136+ uses : docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
137+
138+ - name : Set up Docker for multi-platform
139+ uses : docker/setup-docker-action@b60f85385d03ac8acfca6d9996982511d8620a19 # v4.3.0
140+ with :
141+ daemon-config : |
142+ {
143+ "features": {
144+ "containerd-snapshotter": true
145+ }
146+ }
81147
82148 - name : Setup Docker buildx
83- uses : docker/setup-buildx-action@v3
149+ uses : docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
150+
151+ - uses : actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
152+ with :
153+ pattern : multigres-operator-*
154+ path : dist/
84155
85156 - name : Log into registry
86- uses : docker/login-action@v3
157+ uses : docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
87158 with :
88159 registry : ghcr.io
89160 username : ${{ github.actor }}
90161 password : ${{ secrets.GITHUB_TOKEN }}
91162
92- - name : Extract container metadata
93- id : meta
94- uses : docker/metadata-action@v5
95- with :
96- github-token : ${{ secrets.GITHUB_TOKEN }}
97- images : ghcr.io/${{ github.repository }}
98- tags : |
99- type=ref,event=branch,prefix=
100- type=ref,event=tag,prefix=
101- type=sha,format=short,prefix=
102- type=sha,format=long,prefix=
103-
104- - uses : actions/download-artifact@v5
105- with :
106- pattern : multigres-operator-*
107- path : dist/
108-
109- - name : Build and push container image
110- id : build-and-push
111- uses : docker/build-push-action@v5
163+ - name : Build container image
164+ uses : docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
112165 with :
113166 context : .
114167 file : Containerfile
115168 platforms : linux/${{ join(fromJson(inputs.architectures), ',linux/') }}
116- push : ${{ inputs.push-container-image }}
117- tags : ${{ steps.meta.outputs.tags }}
118- labels : ${{ steps.meta.outputs.labels }}
169+ load : true
170+ push : false
171+ tags : " ghcr.io/ ${{ github.repository }}:${{ github.sha }}"
119172 provenance : false
120173 cache-from : type=gha
121174 cache-to : type=gha,mode=max
175+ outputs : type=oci,dest=container-image.tar
176+
177+ - name : Push to registry (sha)
178+ run : |
179+ IMAGE="ghcr.io/${{ github.repository }}"
180+ docker push "$IMAGE:${{ github.sha }}"
181+
182+ # grype requires that the container image be pushed already because
183+ # the scanner runs in a container with a different local registry
184+ - name : Scan image with grype
185+ id : scan
186+ uses : anchore/scan-action@f6601287cdb1efc985d6b765bbf99cb4c0ac29d8 # v7.0.0
187+ continue-on-error : true
188+ with :
189+ cache-db : true
190+ image : " ghcr.io/${{ github.repository }}:${{ github.sha }}"
191+ output-file : grype.sarif
192+ severity-cutoff : critical # TODO: lower this once vulns are fixed
193+ - name : Upload SARIF file
194+ uses : github/codeql-action/upload-sarif@e296a935590eb16afc0c0108289f68c87e2a89a5 # v4.30.7
195+ with :
196+ sarif_file : grype.sarif
197+ - name : Check success or failure
198+ if : ${{ steps.scan.outcome == 'failure' }}
199+ run : exit 1
200+
201+ - name : Push to registry (proper)
202+ if : ${{ inputs.push-container-image }}
203+ run : |
204+ IMAGE="ghcr.io/${{ github.repository }}"
205+ if [ "${{ github.ref }}" = "refs/heads/main" ]; then
206+ docker tag "$IMAGE:${{ github.sha }}" "$IMAGE:latest"
207+ docker push "$IMAGE:latest"
208+ fi
209+ if [ "${{ github.ref_type }}" = "tag" ]; then
210+ docker tag "$IMAGE:${{ github.sha }}" "$IMAGE:${{ github.ref_name }}"
211+ docker push "$IMAGE:${{ github.ref_name }}"
212+ fi
122213
123214 create-release :
124- needs : [ build-go ]
215+ needs : [ build-scan-push-container ]
125216 runs-on : ubuntu-latest
126217 if : ${{ inputs.create-release }}
127218 steps :
128- - uses : actions/download-artifact@v5
219+ - uses : actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
129220 with :
130221 pattern : " *"
131222 path : dist/
132223
133224 - name : Release
134- uses : softprops/action-gh-release@v2
225+ uses : softprops/action-gh-release@aec2ec56f94eb8180ceec724245f64ef008b89f5 # 2.4.0
135226 with :
136227 files : dist/**
0 commit comments