forked from NVIDIA/aicr
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathevidence-dashboard-publish.yaml
More file actions
178 lines (161 loc) · 7.76 KB
/
Copy pathevidence-dashboard-publish.yaml
File metadata and controls
178 lines (161 loc) · 7.76 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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# GP5 — Evidence dashboard publish to GitHub Pages (#1405).
#
# The repo's FIRST GitHub Pages pipeline. On merge to main (and on demand),
# it syncs the source-keyed corroboration evidence tree from GCS read-only,
# runs the GP4 generator (tools/corroborate) to emit the deterministic static
# site, verifies the build is reproducible, then publishes via the canonical
# configure-pages -> upload-pages-artifact -> deploy-pages chain.
#
# (Fern publishes the product docs to docs.nvidia.com via publish-fern-docs.yml,
# a separate surface; this is the only workflow that deploys to GitHub Pages.)
#
# Identity & fork safety, per hippo:reviewer-cicd norms:
# - The build job authenticates to GCS with a READ-ONLY identity (objectViewer
# only) impersonated through the existing github-actions-pool federation. It
# is NOT the GP2 write/publish SA and NOT the shared project-wide SA. GP3
# provisions the dedicated read SA; the name is overridable via the
# EVIDENCE_READ_SERVICE_ACCOUNT repo var so it can be retargeted without a
# code change.
# - Every job is gated to the canonical repo, so a fork PR never obtains GCS
# credentials or Pages write.
# - The credentialed build job (id-token for GCS WIF) is separate from the
# deploy job (pages: write); neither grants the other's scope.
name: "Evidence: Dashboard Publish"
on:
push:
branches: [main]
workflow_dispatch: {}
# Least privilege at the top level; jobs widen only what they need.
permissions:
contents: read
# Serialize deploys to the single Pages environment and let an in-flight
# publish finish (do not cancel — a half-deployed site is worse than a stale
# one for the few extra seconds a queued run waits).
concurrency:
group: "pages"
cancel-in-progress: false
jobs:
# ---------------------------------------------------------------------
# Build: holds the GCS READ-ONLY credentials. Syncs the evidence tree,
# runs the deterministic generator twice and diffs the output (the
# determinism gate), then uploads the site as a Pages artifact. Holds NO
# pages: write.
# ---------------------------------------------------------------------
build:
name: Build site
if: github.repository == 'nvidia/aicr'
runs-on: ubuntu-latest
timeout-minutes: 20
permissions:
contents: read
id-token: write # GCS Workload Identity Federation only
env:
GCP_WIF_PROVIDER: "projects/116689922666/locations/global/workloadIdentityPools/github-actions-pool/providers/github-actions-provider"
# Read-only (objectViewer) SA, scoped to the evidence bucket by
# infra/uat-gcp-account/evidence-dashboard.tf. Deliberately NOT the shared
# github-actions@eidosx SA and NOT the GP2 evidence-publish writer.
GCS_READ_SERVICE_ACCOUNT: "evidence-read@eidosx.iam.gserviceaccount.com"
BUCKET: "aicr-testgrid-staging"
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Load versions
id: versions
uses: ./.github/actions/load-versions
- name: Set up Go
uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version: ${{ steps.versions.outputs.go }}
cache: false
- name: Build corroborate generator
env:
GOFLAGS: -mod=vendor
run: go build -o ./bin/corroborate ./tools/corroborate
- name: Authenticate to GCP (read-only)
uses: google-github-actions/auth@7c6bc770dae815cd3e89ee6cdf493a5fab2cc093 # v3.0.0
with:
workload_identity_provider: ${{ env.GCP_WIF_PROVIDER }}
service_account: ${{ env.GCS_READ_SERVICE_ACCOUNT }}
- name: Set up gcloud
uses: google-github-actions/setup-gcloud@aa5489c8933f4cc7a4f7d45035b3b1440c9c10db # v3.0.1
- name: Sync evidence tree from GCS
run: |
set -euo pipefail
mkdir -p evidence/results
# Mirror the source-keyed tree to disk; the generator has no embedded
# cloud client and reads from a local directory. Read-only: rsync here
# only pulls (the SA cannot write back).
gcloud storage rsync -r "gs://${BUCKET}/results" evidence/results
- name: Generate site (with determinism gate)
run: |
set -euo pipefail
# Two independent builds from the same inputs must be byte-identical
# (the generator carries no clock/random). A drift here means a
# non-reproducible build — fail loudly rather than publish it.
#
# -allowlist re-derives each source's class from its VERIFIED signer
# against the in-tree GP1 allowlist — defense in depth on top of the
# class GP2 baked into meta.json at ingest time. The generator's
# loader (pkg/corroborate) delegates to the shared
# pkg/evidence/allowlist parser, so it reads the canonical
# identityPattern/source schema directly (#1505).
./bin/corroborate -in evidence -out _site \
-allowlist recipes/evidence/allowlist.yaml
./bin/corroborate -in evidence -out _site_check \
-allowlist recipes/evidence/allowlist.yaml
if ! diff -r _site _site_check; then
echo "::error::corroborate output is not reproducible (determinism gate failed)"
exit 1
fi
rm -rf _site_check
# Reassert the custom domain on every publish. With the GitHub Actions
# source the domain set in repo settings is authoritative, but a deploy
# whose artifact omits CNAME can silently clear it; writing the file makes
# the domain self-healing. Placed AFTER the determinism diff so the extra
# file never trips the byte-identical gate above.
- name: Assert custom domain
run: echo 'validation.aicr.run' > _site/CNAME
- name: Configure Pages
uses: actions/configure-pages@45bfe0192ca1faeb007ade9deae92b16b8254a0d # v6.0.0
- name: Upload Pages artifact
uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0
with:
path: _site
# ---------------------------------------------------------------------
# Deploy: holds pages: write and deploys the artifact to the github-pages
# environment. Holds NO GCS credentials.
# ---------------------------------------------------------------------
deploy:
name: Deploy to Pages
needs: build
# Publish only from main. A workflow_dispatch run on a non-main branch still
# builds (a credential-free preview of the generator output), but must never
# overwrite the single live Pages site with a branch build.
if: github.repository == 'nvidia/aicr' && github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
pages: write # deploy to the Pages environment
id-token: write # OIDC verification for deploy-pages
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5.0.0