Skip to content

Commit 4a4cb78

Browse files
authored
JGC-499 - Replace 'safe to test' label with single build-gate environment approval (#3535)
* JGC-499 - Replace 'safe to test' label with single build-gate environment approval Introduce build-gate.yml orchestrator: a single `build-gate` environment deployment approval (skipped on push/dispatch) releases frogbot and all integration-test suites for fork/PR runs. Convert frogbot and the 25 test workflows to reusable (workflow_call) workflows invoked behind the gate, drop the per-workflow 'safe to test' label conditions, and delete removeLabel.yml. Add a build-gate-success aggregator job that needs all suites, so branch protection can require a single stable check instead of matrix-expanded suite contexts. * JGC-499 - Fix build-gate aggregator gate dependency and OIDC permissions Address PR review: - Add `gate` to build-gate-success needs so a rejected/unapproved deployment fails (or blocks) the required check instead of passing on skipped suites. - Grant id-token: write on the access, helm, huggingface and oidc caller jobs, since a reusable workflow cannot escalate beyond the caller's token scopes.
1 parent 77c81c1 commit 4a4cb78

28 files changed

Lines changed: 235 additions & 245 deletions

.github/workflows/accessTests.yml

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
name: Access Tests
22
on:
3+
workflow_call:
34
workflow_dispatch:
45
inputs:
56
jfrog_url:
@@ -12,14 +13,6 @@ on:
1213
type: string
1314
required: false
1415
default: ""
15-
push:
16-
branches:
17-
- "master"
18-
# Triggers the workflow on PRs to master branch only.
19-
pull_request_target:
20-
types: [labeled]
21-
branches:
22-
- "master"
2316

2417
# Ensures that only the latest commit is running for each PR at a time.
2518
concurrency:
@@ -31,7 +24,6 @@ permissions:
3124
jobs:
3225
Access-Tests:
3326
name: Access tests (${{ matrix.os.name }})
34-
if: github.event_name == 'workflow_dispatch' || github.event_name == 'push' || contains(github.event.pull_request.labels.*.name, 'safe to test')
3527
strategy:
3628
fail-fast: false
3729
matrix:

.github/workflows/artifactoryTests.yml

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
name: Artifactory Tests
22
on:
3+
workflow_call:
34
workflow_dispatch:
45
inputs:
56
jfrog_url:
@@ -12,14 +13,6 @@ on:
1213
type: string
1314
required: false
1415
default: ""
15-
push:
16-
branches:
17-
- "master"
18-
# Triggers the workflow on PRs to master branch only.
19-
pull_request_target:
20-
types: [labeled]
21-
branches:
22-
- "master"
2316

2417
# Ensures that only the latest commit is running for each PR at a time.
2518
concurrency:
@@ -28,7 +21,6 @@ concurrency:
2821
jobs:
2922
Artifactory-Tests:
3023
name: ${{ matrix.suite }} ${{ matrix.os.name }}
31-
if: github.event_name == 'workflow_dispatch' || github.event_name == 'push' || contains(github.event.pull_request.labels.*.name, 'safe to test')
3224
strategy:
3325
fail-fast: false
3426
matrix:

.github/workflows/build-gate.yml

Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
name: Build Gate
2+
# Single approval gate for fork/PR runs: a maintainer approves the `build-gate`
3+
# environment deployment once, releasing frogbot and every integration-test suite.
4+
# Replaces the per-workflow 'safe to test' label mechanism.
5+
on:
6+
pull_request_target:
7+
types: [opened, synchronize, reopened]
8+
branches:
9+
- "master"
10+
push:
11+
branches:
12+
- "master"
13+
workflow_dispatch:
14+
15+
# Ensures that only the latest commit is running for each PR at a time.
16+
concurrency:
17+
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}-${{ github.ref }}
18+
cancel-in-progress: true
19+
20+
permissions:
21+
pull-requests: write
22+
contents: read
23+
24+
jobs:
25+
# The single approval point. `build-gate` carries the Required-reviewers rule.
26+
# Trusted push & manual dispatch skip approval (empty environment name = no gate).
27+
gate:
28+
name: Approval gate
29+
runs-on: ubuntu-latest
30+
environment: ${{ github.event_name == 'pull_request_target' && 'build-gate' || '' }}
31+
steps:
32+
- run: echo "Approved — releasing frogbot and integration suites."
33+
34+
# ---- Suites (each fans out behind the single gate) ----------------------
35+
frogbot:
36+
needs: gate
37+
uses: ./.github/workflows/frogbot-scan-pull-request.yml
38+
secrets: inherit
39+
40+
access:
41+
needs: gate
42+
# OIDC suite: caller must grant id-token so the reusable workflow can request it.
43+
permissions:
44+
id-token: write
45+
contents: read
46+
uses: ./.github/workflows/accessTests.yml
47+
secrets: inherit
48+
artifactory:
49+
needs: gate
50+
uses: ./.github/workflows/artifactoryTests.yml
51+
secrets: inherit
52+
conan:
53+
needs: gate
54+
uses: ./.github/workflows/conanTests.yml
55+
secrets: inherit
56+
distribution:
57+
needs: gate
58+
uses: ./.github/workflows/distributionTests.yml
59+
secrets: inherit
60+
docker:
61+
needs: gate
62+
uses: ./.github/workflows/dockerTests.yml
63+
secrets: inherit
64+
evidence:
65+
needs: gate
66+
uses: ./.github/workflows/evidenceTests.yml
67+
secrets: inherit
68+
ghost-frog:
69+
needs: gate
70+
uses: ./.github/workflows/ghostFrogTests.yml
71+
secrets: inherit
72+
go:
73+
needs: gate
74+
uses: ./.github/workflows/goTests.yml
75+
secrets: inherit
76+
gradle:
77+
needs: gate
78+
uses: ./.github/workflows/gradleTests.yml
79+
secrets: inherit
80+
helm:
81+
needs: gate
82+
# OIDC suite: caller must grant id-token so the reusable workflow can request it.
83+
permissions:
84+
id-token: write
85+
contents: read
86+
uses: ./.github/workflows/helmTests.yml
87+
secrets: inherit
88+
huggingface:
89+
needs: gate
90+
# OIDC suite: caller must grant id-token so the reusable workflow can request it.
91+
permissions:
92+
id-token: write
93+
contents: read
94+
uses: ./.github/workflows/huggingfaceTests.yml
95+
secrets: inherit
96+
lifecycle:
97+
needs: gate
98+
uses: ./.github/workflows/lifecycleTests.yml
99+
secrets: inherit
100+
maven:
101+
needs: gate
102+
uses: ./.github/workflows/mavenTests.yml
103+
secrets: inherit
104+
nix:
105+
needs: gate
106+
uses: ./.github/workflows/nixTests.yml
107+
secrets: inherit
108+
npm:
109+
needs: gate
110+
uses: ./.github/workflows/npmTests.yml
111+
secrets: inherit
112+
nuget:
113+
needs: gate
114+
uses: ./.github/workflows/nugetTests.yml
115+
secrets: inherit
116+
oidc:
117+
needs: gate
118+
# OIDC suite: caller must grant id-token so the reusable workflow can request it.
119+
permissions:
120+
id-token: write
121+
contents: read
122+
uses: ./.github/workflows/oidcTests.yml
123+
secrets: inherit
124+
plugins:
125+
needs: gate
126+
uses: ./.github/workflows/pluginsTests.yml
127+
secrets: inherit
128+
pnpm:
129+
needs: gate
130+
uses: ./.github/workflows/pnpmTests.yml
131+
secrets: inherit
132+
podman:
133+
needs: gate
134+
uses: ./.github/workflows/podmanTests.yml
135+
secrets: inherit
136+
poetry:
137+
needs: gate
138+
uses: ./.github/workflows/poetryTests.yml
139+
secrets: inherit
140+
python:
141+
needs: gate
142+
uses: ./.github/workflows/pythonTests.yml
143+
secrets: inherit
144+
script:
145+
needs: gate
146+
uses: ./.github/workflows/scriptTests.yml
147+
secrets: inherit
148+
transfer:
149+
needs: gate
150+
uses: ./.github/workflows/transferTests.yml
151+
secrets: inherit
152+
uv:
153+
needs: gate
154+
uses: ./.github/workflows/uvTests.yml
155+
secrets: inherit
156+
157+
# Single, stable required status check. Point branch protection at
158+
# "Build Gate / build-gate-success" instead of the matrix-expanded suite checks.
159+
# Recover a failed suite with "Re-run failed jobs" (re-runs the suite + this job,
160+
# not the approval gate) — no re-approval and no new commit needed.
161+
build-gate-success:
162+
name: build-gate-success
163+
if: always()
164+
needs:
165+
- gate
166+
- frogbot
167+
- access
168+
- artifactory
169+
- conan
170+
- distribution
171+
- docker
172+
- evidence
173+
- ghost-frog
174+
- go
175+
- gradle
176+
- helm
177+
- huggingface
178+
- lifecycle
179+
- maven
180+
- nix
181+
- npm
182+
- nuget
183+
- oidc
184+
- plugins
185+
- pnpm
186+
- podman
187+
- poetry
188+
- python
189+
- script
190+
- transfer
191+
- uv
192+
runs-on: ubuntu-latest
193+
steps:
194+
- name: Verify no suite failed or was cancelled
195+
run: |
196+
if ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') }}; then
197+
echo "::error::One or more suites failed or were cancelled."
198+
exit 1
199+
fi
200+
echo "All suites succeeded (skipped suites are allowed)."

.github/workflows/conanTests.yml

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
name: Conan Tests
22
on:
3+
workflow_call:
34
workflow_dispatch:
45
inputs:
56
jfrog_url:
@@ -12,21 +13,13 @@ on:
1213
type: string
1314
required: false
1415
default: ""
15-
push:
16-
branches:
17-
- "master"
18-
pull_request_target:
19-
types: [labeled]
20-
branches:
21-
- "master"
2216

2317
concurrency:
2418
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}-${{ github.ref }}
2519
cancel-in-progress: true
2620
jobs:
2721
Conan-Tests:
2822
name: Conan tests (${{ matrix.os.name }})
29-
if: github.event_name == 'workflow_dispatch' || github.event_name == 'push' || contains(github.event.pull_request.labels.*.name, 'safe to test')
3023
strategy:
3124
fail-fast: false
3225
matrix:

.github/workflows/distributionTests.yml

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,7 @@
11
name: Distribution Tests
22
on:
3+
workflow_call:
34
workflow_dispatch:
4-
push:
5-
branches:
6-
- "master"
7-
# Triggers the workflow on PRs to master branch only.
8-
pull_request_target:
9-
types: [labeled]
10-
branches:
11-
- "master"
125

136
# Ensures that only the latest commit is running for each PR at a time.
147
concurrency:
@@ -17,7 +10,6 @@ concurrency:
1710
jobs:
1811
Distribution-Tests:
1912
name: Distribution tests (${{ matrix.os }})
20-
if: github.event_name == 'workflow_dispatch' || github.event_name == 'push' || contains(github.event.pull_request.labels.*.name, 'safe to test')
2113
strategy:
2214
fail-fast: false
2315
matrix:

.github/workflows/dockerTests.yml

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,7 @@
11
name: Docker Tests
22
on:
3+
workflow_call:
34
workflow_dispatch:
4-
push:
5-
branches:
6-
- "master"
7-
# Triggers the workflow on PRs to master branch only.
8-
pull_request_target:
9-
types: [labeled]
10-
branches:
11-
- "master"
125

136
# Ensures that only the latest commit is running for each PR at a time.
147
concurrency:
@@ -17,7 +10,6 @@ concurrency:
1710
jobs:
1811
Docker-tests:
1912
name: Docker tests (${{ matrix.os.name }}, containerd-snapshotter=${{ !matrix.disable-containerd-snapshotter }})
20-
if: github.event_name == 'workflow_dispatch' || github.event_name == 'push' || contains(github.event.pull_request.labels.*.name, 'safe to test')
2113
strategy:
2214
fail-fast: false
2315
matrix:

.github/workflows/evidenceTests.yml

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,7 @@
11
name: Evidence Tests
22
on:
3+
workflow_call:
34
workflow_dispatch:
4-
push:
5-
branches:
6-
- "master"
7-
# Triggers the workflow on PRs to master branch only.
8-
pull_request_target:
9-
types: [labeled]
10-
branches:
11-
- "master"
125

136
# Ensures that only the latest commit is running for each PR at a time.
147
concurrency:

.github/workflows/frogbot-scan-pull-request.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
name: "Frogbot Scan Pull Request"
2+
# Reusable: invoked by build-gate.yml behind the `build-gate` approval.
3+
# Also runnable standalone via workflow_dispatch. The approval gate now lives in the
4+
# orchestrator, so this workflow no longer declares its own environment.
25
on:
3-
pull_request_target:
4-
types: [opened, synchronize]
5-
branches:
6-
- "master"
6+
workflow_call:
7+
workflow_dispatch:
78
permissions:
89
pull-requests: write
910
contents: read
1011
jobs:
1112
scan-pull-request:
1213
if: ${{ github.actor != 'dependabot[bot]' }}
1314
runs-on: ubuntu-latest
14-
environment: frogbot
1515
steps:
1616
- name: Checkout the repository
1717
uses: actions/checkout@v6

.github/workflows/ghostFrogTests.yml

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,7 @@
11
name: Ghost Frog Tests
22
on:
3+
workflow_call:
34
workflow_dispatch:
4-
push:
5-
branches:
6-
- "master"
7-
- "ghost-frog"
8-
# Triggers the workflow on PRs to master branch only.
9-
pull_request_target:
10-
types: [labeled]
11-
branches:
12-
- "master"
135

146
# Ensures that only the latest commit is running for each PR at a time.
157
concurrency:

0 commit comments

Comments
 (0)