Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 1 addition & 9 deletions .github/workflows/accessTests.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
name: Access Tests
on:
workflow_call:
workflow_dispatch:
inputs:
jfrog_url:
Expand All @@ -12,14 +13,6 @@ on:
type: string
required: false
default: ""
push:
branches:
- "master"
# Triggers the workflow on PRs to master branch only.
pull_request_target:
types: [labeled]
branches:
- "master"

# Ensures that only the latest commit is running for each PR at a time.
concurrency:
Expand All @@ -31,7 +24,6 @@ permissions:
jobs:
Access-Tests:
name: Access tests (${{ matrix.os.name }})
if: github.event_name == 'workflow_dispatch' || github.event_name == 'push' || contains(github.event.pull_request.labels.*.name, 'safe to test')
strategy:
fail-fast: false
matrix:
Expand Down
10 changes: 1 addition & 9 deletions .github/workflows/artifactoryTests.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
name: Artifactory Tests
on:
workflow_call:
workflow_dispatch:
inputs:
jfrog_url:
Expand All @@ -12,14 +13,6 @@ on:
type: string
required: false
default: ""
push:
branches:
- "master"
# Triggers the workflow on PRs to master branch only.
pull_request_target:
types: [labeled]
branches:
- "master"

# Ensures that only the latest commit is running for each PR at a time.
concurrency:
Expand All @@ -28,7 +21,6 @@ concurrency:
jobs:
Artifactory-Tests:
name: ${{ matrix.suite }} ${{ matrix.os.name }}
if: github.event_name == 'workflow_dispatch' || github.event_name == 'push' || contains(github.event.pull_request.labels.*.name, 'safe to test')
strategy:
fail-fast: false
matrix:
Expand Down
200 changes: 200 additions & 0 deletions .github/workflows/build-gate.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
name: Build Gate
# Single approval gate for fork/PR runs: a maintainer approves the `build-gate`
# environment deployment once, releasing frogbot and every integration-test suite.
# Replaces the per-workflow 'safe to test' label mechanism.
on:
pull_request_target:
types: [opened, synchronize, reopened]
branches:
- "master"
push:
branches:
- "master"
workflow_dispatch:

# Ensures that only the latest commit is running for each PR at a time.
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}-${{ github.ref }}
cancel-in-progress: true

permissions:
pull-requests: write

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like there is a bug here (not security)
I remember that the caller workflow cannot assign permissions it doesn't have
In that case, the caller does not have id-token: write, and it assigns it to a different workflow like .github/workflows/helmTests.yml by triggrering it

https://github.com/jfrog/jfrog-cli/pull/3535/changes#diff-b4f30d948e9602b6e03aa68700eb3589067e5fabe411faa596842e3bcf0de387R22 row 22

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct. Fixed in 27645d29 by granting id-token: write per-job on the four OIDC suites (access, helm, huggingface, oidc).

contents: read

jobs:
# The single approval point. `build-gate` carries the Required-reviewers rule.
# Trusted push & manual dispatch skip approval (empty environment name = no gate).
gate:
name: Approval gate
runs-on: ubuntu-latest
environment: ${{ github.event_name == 'pull_request_target' && 'build-gate' || '' }}
steps:
- run: echo "Approved — releasing frogbot and integration suites."

# ---- Suites (each fans out behind the single gate) ----------------------
frogbot:
needs: gate
uses: ./.github/workflows/frogbot-scan-pull-request.yml
secrets: inherit

access:
needs: gate
# OIDC suite: caller must grant id-token so the reusable workflow can request it.
permissions:
id-token: write
contents: read
uses: ./.github/workflows/accessTests.yml
secrets: inherit
artifactory:
needs: gate
uses: ./.github/workflows/artifactoryTests.yml
secrets: inherit
conan:
needs: gate
uses: ./.github/workflows/conanTests.yml
secrets: inherit
distribution:
needs: gate
uses: ./.github/workflows/distributionTests.yml
secrets: inherit
docker:
needs: gate
uses: ./.github/workflows/dockerTests.yml
secrets: inherit
evidence:
needs: gate
uses: ./.github/workflows/evidenceTests.yml
secrets: inherit
ghost-frog:
needs: gate
uses: ./.github/workflows/ghostFrogTests.yml
secrets: inherit
go:
needs: gate
uses: ./.github/workflows/goTests.yml
secrets: inherit
gradle:
needs: gate
uses: ./.github/workflows/gradleTests.yml
secrets: inherit
helm:
needs: gate
# OIDC suite: caller must grant id-token so the reusable workflow can request it.
permissions:
id-token: write
contents: read
uses: ./.github/workflows/helmTests.yml
secrets: inherit
huggingface:
needs: gate
# OIDC suite: caller must grant id-token so the reusable workflow can request it.
permissions:
id-token: write
contents: read
uses: ./.github/workflows/huggingfaceTests.yml
secrets: inherit
lifecycle:
needs: gate
uses: ./.github/workflows/lifecycleTests.yml
secrets: inherit
maven:
needs: gate
uses: ./.github/workflows/mavenTests.yml
secrets: inherit
nix:
needs: gate
uses: ./.github/workflows/nixTests.yml
secrets: inherit
npm:
needs: gate
uses: ./.github/workflows/npmTests.yml
secrets: inherit
nuget:
needs: gate
uses: ./.github/workflows/nugetTests.yml
secrets: inherit
oidc:
needs: gate
# OIDC suite: caller must grant id-token so the reusable workflow can request it.
permissions:
id-token: write
contents: read
uses: ./.github/workflows/oidcTests.yml
secrets: inherit
plugins:
needs: gate
uses: ./.github/workflows/pluginsTests.yml
secrets: inherit
pnpm:
needs: gate
uses: ./.github/workflows/pnpmTests.yml
secrets: inherit
podman:
needs: gate
uses: ./.github/workflows/podmanTests.yml
secrets: inherit
poetry:
needs: gate
uses: ./.github/workflows/poetryTests.yml
secrets: inherit
python:
needs: gate
uses: ./.github/workflows/pythonTests.yml
secrets: inherit
script:
needs: gate
uses: ./.github/workflows/scriptTests.yml
secrets: inherit
transfer:
needs: gate
uses: ./.github/workflows/transferTests.yml
secrets: inherit
uv:
needs: gate
uses: ./.github/workflows/uvTests.yml
secrets: inherit

# Single, stable required status check. Point branch protection at
# "Build Gate / build-gate-success" instead of the matrix-expanded suite checks.
# Recover a failed suite with "Re-run failed jobs" (re-runs the suite + this job,
# not the approval gate) — no re-approval and no new commit needed.
build-gate-success:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add gate also here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 27645d29. This also fixes the if: always() issue below.

name: build-gate-success
if: always()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The if: always () cusing an issue here
build-gate-success doesn’t directly depend on gate, only on jobs after it. If gate is rejected, those jobs may be skipped, and the final check can still pass because it allows skipped jobs.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. Fixed in 27645d29 by adding gate to needs: a rejected gate now fails the check, and an unapproved one keeps it pending. Kept if: always() so it still reports a definitive result when a suite fails.

needs:
- gate
- frogbot
- access
- artifactory
- conan
- distribution
- docker
- evidence
- ghost-frog
- go
- gradle
- helm
- huggingface
- lifecycle
- maven
- nix
- npm
- nuget
- oidc
- plugins
- pnpm
- podman
- poetry
- python
- script
- transfer
- uv
runs-on: ubuntu-latest
steps:
- name: Verify no suite failed or was cancelled
run: |
if ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') }}; then
echo "::error::One or more suites failed or were cancelled."
exit 1
fi
echo "All suites succeeded (skipped suites are allowed)."
9 changes: 1 addition & 8 deletions .github/workflows/conanTests.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
name: Conan Tests
on:
workflow_call:
workflow_dispatch:
inputs:
jfrog_url:
Expand All @@ -12,21 +13,13 @@ on:
type: string
required: false
default: ""
push:
branches:
- "master"
pull_request_target:
types: [labeled]
branches:
- "master"

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}-${{ github.ref }}
cancel-in-progress: true
jobs:
Conan-Tests:
name: Conan tests (${{ matrix.os.name }})
if: github.event_name == 'workflow_dispatch' || github.event_name == 'push' || contains(github.event.pull_request.labels.*.name, 'safe to test')
strategy:
fail-fast: false
matrix:
Expand Down
10 changes: 1 addition & 9 deletions .github/workflows/distributionTests.yml
Original file line number Diff line number Diff line change
@@ -1,14 +1,7 @@
name: Distribution Tests
on:
workflow_call:
workflow_dispatch:
push:
branches:
- "master"
# Triggers the workflow on PRs to master branch only.
pull_request_target:
types: [labeled]
branches:
- "master"

# Ensures that only the latest commit is running for each PR at a time.
concurrency:
Expand All @@ -17,7 +10,6 @@ concurrency:
jobs:
Distribution-Tests:
name: Distribution tests (${{ matrix.os }})
if: github.event_name == 'workflow_dispatch' || github.event_name == 'push' || contains(github.event.pull_request.labels.*.name, 'safe to test')
strategy:
fail-fast: false
matrix:
Expand Down
10 changes: 1 addition & 9 deletions .github/workflows/dockerTests.yml
Original file line number Diff line number Diff line change
@@ -1,14 +1,7 @@
name: Docker Tests
on:
workflow_call:
workflow_dispatch:
push:
branches:
- "master"
# Triggers the workflow on PRs to master branch only.
pull_request_target:
types: [labeled]
branches:
- "master"

# Ensures that only the latest commit is running for each PR at a time.
concurrency:
Expand All @@ -17,7 +10,6 @@ concurrency:
jobs:
Docker-tests:
name: Docker tests (${{ matrix.os.name }}, containerd-snapshotter=${{ !matrix.disable-containerd-snapshotter }})
if: github.event_name == 'workflow_dispatch' || github.event_name == 'push' || contains(github.event.pull_request.labels.*.name, 'safe to test')
strategy:
fail-fast: false
matrix:
Expand Down
9 changes: 1 addition & 8 deletions .github/workflows/evidenceTests.yml
Original file line number Diff line number Diff line change
@@ -1,14 +1,7 @@
name: Evidence Tests
on:
workflow_call:
workflow_dispatch:
push:
branches:
- "master"
# Triggers the workflow on PRs to master branch only.
pull_request_target:
types: [labeled]
branches:
- "master"

# Ensures that only the latest commit is running for each PR at a time.
concurrency:
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/frogbot-scan-pull-request.yml
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
name: "Frogbot Scan Pull Request"
# Reusable: invoked by build-gate.yml behind the `build-gate` approval.
# Also runnable standalone via workflow_dispatch. The approval gate now lives in the
# orchestrator, so this workflow no longer declares its own environment.
on:
pull_request_target:
types: [opened, synchronize]
branches:
- "master"
workflow_call:
workflow_dispatch:
permissions:
pull-requests: write
contents: read
jobs:
scan-pull-request:
if: ${{ github.actor != 'dependabot[bot]' }}
runs-on: ubuntu-latest
environment: frogbot
steps:
- name: Checkout the repository
uses: actions/checkout@v6
Expand Down
10 changes: 1 addition & 9 deletions .github/workflows/ghostFrogTests.yml
Original file line number Diff line number Diff line change
@@ -1,15 +1,7 @@
name: Ghost Frog Tests
on:
workflow_call:
workflow_dispatch:
push:
branches:
- "master"
- "ghost-frog"
# Triggers the workflow on PRs to master branch only.
pull_request_target:
types: [labeled]
branches:
- "master"

# Ensures that only the latest commit is running for each PR at a time.
concurrency:
Expand Down
Loading
Loading