Skip to content

Commit 4535063

Browse files
authored
OIDC Logic Isolation and Backward Compatibility Improvements (#265)
1 parent 611876c commit 4535063

20 files changed

+1877
-1781
lines changed

.github/workflows/auto-build-publish-test.yml renamed to .github/workflows/auto-build-publish-and-job-summary-test.yml

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
name: Auto Build Publish Test
1+
name: Auto Build Publish Test And Job Summary
2+
# This test ensures that the auto build and publish process works correctly and that the job summary is generated.
3+
# These two are interconnected, as the summary must be generated.
4+
# This test only verifies its existence, not its content,
5+
# which is covered in the unit tests.
26
on:
37
push:
48
branches:
@@ -80,4 +84,13 @@ jobs:
8084
- name: Add npm modules to local build-info
8185
run: |
8286
jf npm-config --repo-resolve npm-remote
83-
jf npm install
87+
jf npm install
88+
89+
- name: Validate job summary was written (sanity check)
90+
shell: bash
91+
run: |
92+
if [ ! -s "$GITHUB_STEP_SUMMARY" ]; then
93+
echo "❌ Job summary file is empty!"
94+
exit 1
95+
fi
96+
echo "✅ Job summary written!"

.github/workflows/cli-oidc-test.yml

Lines changed: 0 additions & 44 deletions
This file was deleted.

.github/workflows/manual-oidc-test.yml

Lines changed: 0 additions & 95 deletions
This file was deleted.
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
name: OIDC Integration Test
2+
# This workflow tests the setup-jfrog-cli GitHub Action's OpenID Connect integration across OSes and CLI versions.
3+
# It ensures backward compatibility with older CLI versions and validates step outputs and connectivity.
4+
# CLI versions used:
5+
# - 2.74.1: Does not support `jf eot` command, validates manual fallback logic.
6+
# - 2.75.0: Introduced native OIDC token exchange.
7+
# - Latest: Ensures ongoing compatibility with the most recent CLI build.
8+
9+
on:
10+
push:
11+
branches:
12+
- master
13+
# Triggers the workflow on labeled PRs only.
14+
pull_request_target:
15+
types: [ labeled ]
16+
# Ensures that only the latest commit is running for each PR at a time.
17+
concurrency:
18+
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}-${{ github.ref }}
19+
cancel-in-progress: true
20+
21+
permissions:
22+
id-token: write
23+
contents: read
24+
25+
jobs:
26+
oidc-test:
27+
strategy:
28+
fail-fast: false
29+
matrix:
30+
os: [ ubuntu, macos, windows ]
31+
cli-version: [ '2.74.1', '2.75.0','latest' ]
32+
runs-on: ${{ matrix.os }}-latest
33+
name: OIDC Test - ${{ matrix.cli-version }} on ${{ matrix.os }}
34+
env:
35+
JFROG_CLI_LOG_LEVEL: DEBUG
36+
37+
steps:
38+
- name: Checkout Repository
39+
uses: actions/checkout@v4
40+
with:
41+
ref: ${{ github.event.pull_request.head.sha }}
42+
43+
# Setup OIDC platform integration
44+
- name: Generate unique OIDC provider name
45+
id: gen-oidc
46+
shell: bash
47+
run: |
48+
cli_version="${{ matrix.cli-version }}" && cli_version="${cli_version//./-}"
49+
echo "oidc_provider_name=oidc-integration-${cli_version}-${{ matrix.os }}-$(date +%s)" >> "$GITHUB_OUTPUT"
50+
51+
- name: Create OpenID Connect integration
52+
shell: bash
53+
run: |
54+
curl -X POST "${{ secrets.JFROG_PLATFORM_URL }}/access/api/v1/oidc" \
55+
-H "Content-Type: application/json" \
56+
-H "Authorization: Bearer ${{ secrets.JFROG_PLATFORM_RT_TOKEN }}" \
57+
-d '{
58+
"name": "${{ steps.gen-oidc.outputs.oidc_provider_name }}",
59+
"issuer_url": "https://token.actions.githubusercontent.com",
60+
"provider_type": "GitHub",
61+
"enable_permissive_configuration": "true",
62+
"description": "Test configuration for CLI version ${{ matrix.cli-version }}"
63+
}'
64+
65+
- name: Create OIDC Identity Mapping
66+
shell: bash
67+
run: |
68+
curl -X POST "${{ secrets.JFROG_PLATFORM_URL }}/access/api/v1/oidc/${{ steps.gen-oidc.outputs.oidc_provider_name }}/identity_mappings" \
69+
-H 'Content-Type: application/json' \
70+
-H "Authorization: Bearer ${{ secrets.JFROG_PLATFORM_RT_TOKEN }}" \
71+
-d '{
72+
"name": "oidc-test-mapping",
73+
"priority": "1",
74+
"claims": {
75+
"repository": "${{ github.repository_owner }}/setup-jfrog-cli"
76+
},
77+
"token_spec": {
78+
"scope": "applied-permissions/groups:readers",
79+
"expires_in": 30
80+
}
81+
}'
82+
83+
# Setup
84+
- name: Setup JFrog CLI
85+
id: setup-jfrog-cli
86+
uses: ./
87+
env:
88+
JF_URL: ${{ secrets.JFROG_PLATFORM_URL }}
89+
with:
90+
version: ${{ matrix.cli-version }}
91+
oidc-provider-name: ${{ steps.gen-oidc.outputs.oidc_provider_name }}
92+
93+
# validate successful OIDC configuration
94+
- name: Test JFrog CLI connectivity
95+
run: jf rt ping
96+
97+
# Validate step outputs
98+
- name: Validate user output
99+
shell: bash
100+
run: test -n "${{ steps.setup-jfrog-cli.outputs.oidc-user }}"
101+
102+
- name: Validate token output
103+
shell: bash
104+
run: test -n "${{ steps.setup-jfrog-cli.outputs.oidc-token }}"
105+
106+
# Cleanup
107+
- name: Delete OIDC integration
108+
shell: bash
109+
if: always()
110+
run: |
111+
curl -X DELETE "${{ secrets.JFROG_PLATFORM_URL }}/access/api/v1/oidc/${{ steps.gen-oidc.outputs.oidc_provider_name }}" \
112+
-H "Authorization: Bearer ${{ secrets.JFROG_PLATFORM_RT_TOKEN }}"

action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ author: "JFrog"
44
inputs:
55
version:
66
description: "JFrog CLI Version"
7-
default: "2.74.1"
7+
default: "2.75.0"
88
required: false
99
download-repository:
1010
description: "Remote repository in Artifactory pointing to 'https://releases.jfrog.io/artifactory/jfrog-cli'. Use this parameter in case you don't have an Internet access."

lib/cleanup.js

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
3434
Object.defineProperty(exports, "__esModule", { value: true });
3535
const core = __importStar(require("@actions/core"));
3636
const utils_1 = require("./utils");
37+
const job_summary_1 = require("./job-summary");
3738
function cleanup() {
3839
return __awaiter(this, void 0, void 0, function* () {
3940
if (yield shouldSkipCleanup()) {
@@ -66,7 +67,7 @@ function cleanup() {
6667
function buildInfoPostTasks() {
6768
return __awaiter(this, void 0, void 0, function* () {
6869
const disableAutoBuildPublish = core.getBooleanInput(utils_1.Utils.AUTO_BUILD_PUBLISH_DISABLE);
69-
const disableJobSummary = core.getBooleanInput(utils_1.Utils.JOB_SUMMARY_DISABLE) || !utils_1.Utils.isJobSummarySupported();
70+
const disableJobSummary = core.getBooleanInput(utils_1.Utils.JOB_SUMMARY_DISABLE) || !job_summary_1.JobSummary.isJobSummarySupported();
7071
if (disableAutoBuildPublish && disableJobSummary) {
7172
core.info(`Both auto-build-publish and job-summary are disabled. Skipping Build Info post tasks.`);
7273
return;
@@ -94,11 +95,11 @@ function buildInfoPostTasks() {
9495
function hasUnpublishedModules(workingDirectory) {
9596
return __awaiter(this, void 0, void 0, function* () {
9697
// Save the old value of the environment variable to revert it later
97-
const origValue = process.env[utils_1.Utils.JFROG_CLI_COMMAND_SUMMARY_OUTPUT_DIR_ENV];
98+
const origValue = process.env[job_summary_1.JobSummary.JFROG_CLI_COMMAND_SUMMARY_OUTPUT_DIR_ENV];
9899
try {
99100
core.startGroup('Check for unpublished modules');
100101
// Avoid saving a command summary for this dry-run command
101-
core.exportVariable(utils_1.Utils.JFROG_CLI_COMMAND_SUMMARY_OUTPUT_DIR_ENV, '');
102+
core.exportVariable(job_summary_1.JobSummary.JFROG_CLI_COMMAND_SUMMARY_OUTPUT_DIR_ENV, '');
102103
// Running build-publish command with a dry-run flag to check if there are any unpublished modules, 'silent' to avoid polluting the logs
103104
const responseStr = yield utils_1.Utils.runCliAndGetOutput(['rt', 'build-publish', '--dry-run'], { cwd: workingDirectory });
104105
// Parse the JSON string to an object
@@ -111,7 +112,7 @@ function hasUnpublishedModules(workingDirectory) {
111112
return false;
112113
}
113114
finally {
114-
core.exportVariable(utils_1.Utils.JFROG_CLI_COMMAND_SUMMARY_OUTPUT_DIR_ENV, origValue);
115+
core.exportVariable(job_summary_1.JobSummary.JFROG_CLI_COMMAND_SUMMARY_OUTPUT_DIR_ENV, origValue);
115116
core.endGroup();
116117
}
117118
});
@@ -184,10 +185,10 @@ function generateJobSummary() {
184185
try {
185186
core.startGroup('Generating Job Summary');
186187
yield utils_1.Utils.runCli(['generate-summary-markdown']);
187-
yield utils_1.Utils.setMarkdownAsJobSummary();
188-
yield utils_1.Utils.populateCodeScanningTab();
188+
yield job_summary_1.JobSummary.setMarkdownAsJobSummary();
189+
yield job_summary_1.JobSummary.populateCodeScanningTab();
189190
// Clear files
190-
yield utils_1.Utils.clearCommandSummaryDir();
191+
yield job_summary_1.JobSummary.clearCommandSummaryDir();
191192
}
192193
catch (error) {
193194
core.warning('Failed while attempting to generate job summary: ' + error);

0 commit comments

Comments
 (0)