Skip to content

Commit 7e023fa

Browse files
authored
Merge pull request #15 from datum-cloud/ci/harden-pipeline
ci: harden pipeline for secure, validated releases
2 parents 0c812b9 + 1f5c755 commit 7e023fa

8 files changed

Lines changed: 166 additions & 6 deletions

File tree

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
name: Setup Node and Yarn
2+
description: Set up Node.js with Corepack-managed Yarn and an immutable install
3+
4+
runs:
5+
using: composite
6+
steps:
7+
- name: Set up Node.js
8+
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
9+
with:
10+
node-version: 22
11+
cache: yarn
12+
13+
- name: Enable Corepack
14+
run: corepack enable
15+
shell: bash
16+
17+
- name: Install dependencies
18+
run: yarn install --immutable
19+
shell: bash

.github/workflows/ci.yaml

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
name: CI
2+
3+
on:
4+
pull_request:
5+
workflow_call:
6+
7+
permissions:
8+
contents: read
9+
10+
jobs:
11+
typecheck:
12+
runs-on: ubuntu-latest
13+
steps:
14+
- name: Checkout
15+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
16+
- name: Setup Node and Yarn
17+
uses: ./.github/actions/setup-node-yarn
18+
- name: Typecheck
19+
run: yarn tsc:full
20+
21+
lint:
22+
runs-on: ubuntu-latest
23+
steps:
24+
- name: Checkout
25+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
26+
- name: Setup Node and Yarn
27+
uses: ./.github/actions/setup-node-yarn
28+
- name: Lint
29+
run: yarn lint:all
30+
31+
test:
32+
runs-on: ubuntu-latest
33+
env:
34+
CI: 'true'
35+
steps:
36+
- name: Checkout
37+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
38+
- name: Setup Node and Yarn
39+
uses: ./.github/actions/setup-node-yarn
40+
- name: Unit tests
41+
run: yarn test:all

.github/workflows/e2e.yaml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@ name: E2E
22

33
on:
44
pull_request:
5-
push:
6-
branches:
7-
- main
5+
workflow_call:
86

97
permissions:
108
contents: read

.github/workflows/publish.yaml

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,27 +8,91 @@ on:
88
types: ['published']
99

1010
jobs:
11+
validate:
12+
permissions:
13+
contents: read
14+
uses: ./.github/workflows/ci.yaml
15+
16+
e2e:
17+
permissions:
18+
contents: read
19+
uses: ./.github/workflows/e2e.yaml
20+
1121
publish-container-image:
22+
needs: [validate, e2e]
1223
permissions:
1324
id-token: write
1425
contents: read
1526
packages: write
1627
attestations: write
17-
uses: datum-cloud/actions/.github/workflows/publish-docker.yaml@v1.16.0
28+
uses: datum-cloud/actions/.github/workflows/publish-docker.yaml@605da9a9cc20ab7266d1635ec4ba9cd4f223f68c # v1.16.0
1829
with:
1930
image-name: backstage
2031
context: .
2132
dockerfile-path: packages/backend/Dockerfile
2233
platforms: linux/amd64
2334
secrets: inherit
2435

36+
sign-and-attest:
37+
needs: publish-container-image
38+
runs-on: ubuntu-latest
39+
permissions:
40+
id-token: write
41+
contents: read
42+
packages: write
43+
attestations: write
44+
env:
45+
IMAGE: ghcr.io/datum-cloud/backstage
46+
TAG: ${{ needs.publish-container-image.outputs.tag }}
47+
steps:
48+
- name: Log in to GitHub Container Registry
49+
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
50+
with:
51+
registry: ghcr.io
52+
username: ${{ github.actor }}
53+
password: ${{ secrets.GITHUB_TOKEN }}
54+
55+
- name: Install Cosign
56+
uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6 # v4.1.2
57+
58+
- name: Resolve image digest
59+
id: digest
60+
run: |
61+
digest=$(docker buildx imagetools inspect "${IMAGE}:${TAG}" --format '{{json .Manifest.Digest}}' | tr -d '"')
62+
echo "digest=${digest}" >> "$GITHUB_OUTPUT"
63+
64+
- name: Sign image (keyless)
65+
run: cosign sign --yes "${IMAGE}@${{ steps.digest.outputs.digest }}"
66+
67+
- name: Generate SBOM
68+
uses: anchore/sbom-action@e22c389904149dbc22b58101806040fa8d37a610 # v0.24.0
69+
with:
70+
image: ${{ env.IMAGE }}@${{ steps.digest.outputs.digest }}
71+
format: spdx-json
72+
output-file: sbom.spdx.json
73+
74+
- name: Attest build provenance
75+
uses: actions/attest-build-provenance@0f67c3f4856b2e3261c31976d6725780e5e4c373 # v4.1.1
76+
with:
77+
subject-name: ${{ env.IMAGE }}
78+
subject-digest: ${{ steps.digest.outputs.digest }}
79+
push-to-registry: true
80+
81+
- name: Attest SBOM
82+
uses: actions/attest-sbom@c604332985a26aa8cf1bdc465b92731239ec6b9e # v4.1.0
83+
with:
84+
subject-name: ${{ env.IMAGE }}
85+
subject-digest: ${{ steps.digest.outputs.digest }}
86+
sbom-path: sbom.spdx.json
87+
push-to-registry: true
88+
2589
publish-kustomize-bundle:
2690
needs: publish-container-image
2791
permissions:
2892
id-token: write
2993
contents: read
3094
packages: write
31-
uses: datum-cloud/actions/.github/workflows/publish-kustomize-bundle.yaml@v1.16.0
95+
uses: datum-cloud/actions/.github/workflows/publish-kustomize-bundle.yaml@605da9a9cc20ab7266d1635ec4ba9cd4f223f68c # v1.16.0
3296
with:
3397
bundle-name: ghcr.io/datum-cloud/backstage-kustomize
3498
bundle-path: config

.github/workflows/snyk-scan.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818
contents: read
1919
security-events: write
2020
actions: read
21-
uses: datum-cloud/actions/.github/workflows/snyk-scan.yaml@v1.16.0
21+
uses: datum-cloud/actions/.github/workflows/snyk-scan.yaml@605da9a9cc20ab7266d1635ec4ba9cd4f223f68c # v1.16.0
2222
with:
2323
severity-threshold: high
2424
upload-sarif: true

.github/workflows/trivy.yaml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
name: Trivy Security Scan
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
schedule:
8+
- cron: '0 6 * * 1'
9+
10+
permissions:
11+
contents: read
12+
security-events: write
13+
14+
jobs:
15+
trivy-fs:
16+
runs-on: ubuntu-latest
17+
steps:
18+
- name: Checkout
19+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
20+
21+
- name: Run Trivy filesystem scan
22+
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
23+
with:
24+
scan-type: fs
25+
scan-ref: .
26+
format: sarif
27+
output: trivy-results.sarif
28+
severity: CRITICAL,HIGH
29+
exit-code: '0'
30+
31+
- name: Upload Trivy SARIF to GitHub Security
32+
if: always()
33+
uses: github/codeql-action/upload-sarif@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4
34+
with:
35+
sarif_file: trivy-results.sarif
36+
category: trivy-fs

packages/app/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
"@backstage/plugin-techdocs": "^1.17.7",
5353
"@backstage/plugin-techdocs-module-addons-contrib": "^1.1.37",
5454
"@backstage/plugin-user-settings": "^0.9.4",
55+
"@backstage/theme": "^0.7.3",
5556
"@backstage/ui": "^0.16.0",
5657
"@material-ui/core": "^4.12.2",
5758
"@material-ui/icons": "^4.9.1",

yarn.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12467,6 +12467,7 @@ __metadata:
1246712467
"@backstage/plugin-techdocs": "npm:^1.17.7"
1246812468
"@backstage/plugin-techdocs-module-addons-contrib": "npm:^1.1.37"
1246912469
"@backstage/plugin-user-settings": "npm:^0.9.4"
12470+
"@backstage/theme": "npm:^0.7.3"
1247012471
"@backstage/ui": "npm:^0.16.0"
1247112472
"@material-ui/core": "npm:^4.12.2"
1247212473
"@material-ui/icons": "npm:^4.9.1"

0 commit comments

Comments
 (0)