2121 IMAGE_PREFIX : ghcr.io/databuddy-analytics/databuddy
2222
2323jobs :
24+ detect :
25+ name : Detect affected services
26+ runs-on : blacksmith-2vcpu-ubuntu-2404
27+ timeout-minutes : 5
28+ outputs :
29+ services : ${{ steps.detect.outputs.services }}
30+ steps :
31+ - uses : actions/checkout@v6
32+ with :
33+ fetch-depth : 0
34+ - uses : oven-sh/setup-bun@v2
35+ with :
36+ bun-version : " 1.3.11"
37+ - uses : actions/cache@v5
38+ with :
39+ path : ~/.bun/install/cache
40+ key : ${{ runner.os }}-bun-${{ hashFiles('bun.lock') }}
41+ restore-keys : ${{ runner.os }}-bun-
42+ - run : bun install --frozen-lockfile
43+ - id : detect
44+ env :
45+ EVENT_NAME : ${{ github.event_name }}
46+ BEFORE_SHA : ${{ github.event.before }}
47+ run : |
48+ ALL='["api","basket","links","uptime"]'
49+ if [[ "$EVENT_NAME" != "push" ]]; then
50+ echo "services=$ALL" >> "$GITHUB_OUTPUT"
51+ exit 0
52+ fi
53+ if [[ -z "$BEFORE_SHA" || "$BEFORE_SHA" == "0000000000000000000000000000000000000000" ]]; then
54+ echo "services=$ALL" >> "$GITHUB_OUTPUT"
55+ exit 0
56+ fi
57+ export TURBO_SCM_BASE="$BEFORE_SHA"
58+ export TURBO_SCM_HEAD="HEAD"
59+ affected=()
60+ for svc in api basket links uptime; do
61+ count=$(bunx turbo ls --affected --filter="@databuddy/$svc" --output=json | jq -r '.packages.count')
62+ if [[ "$count" != "0" ]]; then
63+ affected+=("\"$svc\"")
64+ fi
65+ done
66+ if [[ ${#affected[@]} -eq 0 ]]; then
67+ echo "services=[]" >> "$GITHUB_OUTPUT"
68+ else
69+ IFS=,
70+ echo "services=[${affected[*]}]" >> "$GITHUB_OUTPUT"
71+ fi
72+
2473 build :
2574 name : Build ${{ matrix.service }} (${{ matrix.platform.arch }})
75+ needs : detect
76+ if : needs.detect.outputs.services != '[]'
2677 runs-on : ${{ matrix.platform.runner }}
78+ timeout-minutes : 30
2779 permissions :
2880 contents : read
2981 packages : write
82+ id-token : write
83+ security-events : write
3084 strategy :
3185 fail-fast : false
3286 matrix :
33- service : [api, basket, links, uptime]
87+ service : ${{ fromJson(needs.detect.outputs.services) }}
3488 platform :
3589 - arch : amd64
3690 os : linux/amd64
49103 description : " Databuddy Uptime service - availability monitoring"
50104
51105 steps :
52- - uses : actions/checkout@v4
106+ - uses : actions/checkout@v6
53107
54108 - name : Mount Docker build cache
55109 uses : useblacksmith/stickydisk@v1
60114 - name : Set up Docker Builder
61115 uses : useblacksmith/setup-docker-builder@v1
62116
63- - uses : docker/login-action@v3
117+ - uses : docker/login-action@v4
64118 with :
65119 registry : ${{ env.REGISTRY }}
66120 username : ${{ github.actor }}
84138
85139 - name : Extract metadata (labels)
86140 id : meta
87- uses : docker/metadata-action@v5
141+ uses : docker/metadata-action@v6
88142 with :
89143 images : ${{ env.IMAGE_PREFIX }}-${{ matrix.service }}
90144 labels : |
@@ -93,13 +147,16 @@ jobs:
93147 org.opencontainers.image.vendor=Databuddy Analytics
94148 org.opencontainers.image.licenses=AGPL-3.0
95149
96- - uses : useblacksmith/build-push-action@v2
150+ - name : Build and push
151+ id : build
152+ uses : useblacksmith/build-push-action@v2
97153 with :
98154 context : .
99155 file : ${{ matrix.service }}.Dockerfile
100156 push : true
101157 platforms : ${{ matrix.platform.os }}
102- provenance : false
158+ provenance : mode=max
159+ sbom : true
103160 labels : ${{ steps.meta.outputs.labels }}
104161 tags : ${{ env.IMAGE_PREFIX }}-${{ matrix.service }}:${{ steps.version.outputs.tag }}-${{ matrix.platform.arch }}
105162 build-args : |
@@ -109,18 +166,43 @@ jobs:
109166 cache-from : type=gha,scope=${{ matrix.service }}-${{ matrix.platform.arch }}
110167 cache-to : type=gha,mode=max,scope=${{ matrix.service }}-${{ matrix.platform.arch }}
111168
169+ - name : Scan image for vulnerabilities
170+ uses : aquasecurity/trivy-action@0.35.0
171+ with :
172+ image-ref : ${{ env.IMAGE_PREFIX }}-${{ matrix.service }}:${{ steps.version.outputs.tag }}-${{ matrix.platform.arch }}
173+ format : sarif
174+ output : trivy-results.sarif
175+ severity : CRITICAL,HIGH
176+ ignore-unfixed : true
177+
178+ - name : Upload scan results to GitHub Security
179+ uses : github/codeql-action/upload-sarif@v4
180+ if : always()
181+ with :
182+ sarif_file : trivy-results.sarif
183+
184+ - name : Install cosign
185+ uses : sigstore/cosign-installer@v4
186+
187+ - name : Sign image
188+ run : cosign sign --yes ${{ env.IMAGE_PREFIX }}-${{ matrix.service }}:${{ steps.version.outputs.tag }}-${{ matrix.platform.arch }}
189+
112190 manifest :
113191 name : Publish ${{ matrix.service }} manifest
114- needs : build
192+ needs : [detect, build]
193+ if : needs.detect.outputs.services != '[]'
115194 runs-on : blacksmith-2vcpu-ubuntu-2404
195+ timeout-minutes : 10
116196 permissions :
197+ contents : read
117198 packages : write
199+ id-token : write
118200 strategy :
119201 matrix :
120- service : [api, basket, links, uptime]
202+ service : ${{ fromJson(needs.detect.outputs.services) }}
121203
122204 steps :
123- - uses : docker/login-action@v3
205+ - uses : docker/login-action@v4
124206 with :
125207 registry : ${{ env.REGISTRY }}
126208 username : ${{ github.actor }}
@@ -166,3 +248,12 @@ jobs:
166248 TAG="${{ steps.version.outputs.tag }}"
167249 echo "Inspecting $IMAGE:$TAG"
168250 docker buildx imagetools inspect "$IMAGE:$TAG"
251+
252+ - name : Install cosign
253+ uses : sigstore/cosign-installer@v4
254+
255+ - name : Sign manifest
256+ run : |
257+ IMAGE="${{ env.IMAGE_PREFIX }}-${{ matrix.service }}"
258+ TAG="${{ steps.version.outputs.tag }}"
259+ cosign sign --yes "$IMAGE:$TAG"
0 commit comments