From 582ae53f7ac67ba39c9773166ef89d026ebbe4a6 Mon Sep 17 00:00:00 2001 From: Asaf Gabai Date: Thu, 7 Aug 2025 11:16:28 +0300 Subject: [PATCH] Promote version to `v4.5.12` --- lib/cleanup.js | 14 ++++---- lib/evidence-collection.js | 65 +++++++++++++++++++++++++++----------- package-lock.json | 4 +-- package.json | 2 +- 4 files changed, 55 insertions(+), 30 deletions(-) diff --git a/lib/cleanup.js b/lib/cleanup.js index f795a98b3..52fa3fbc9 100644 --- a/lib/cleanup.js +++ b/lib/cleanup.js @@ -77,17 +77,15 @@ function buildInfoPostTasks() { return; } // Check connection to Artifactory before proceeding with build info post tasks - if (!(yield checkConnectionToArtifactory())) { - return; - } + const pingWorked = yield checkConnectionToArtifactory(); // Auto-publish build info if needed - if (!disableAutoBuildPublish) { + if (pingWorked && !disableAutoBuildPublish) { yield collectAndPublishBuildInfoIfNeeded(); } else { - core.info('Auto build info publish is disabled. Skipping auto build info collection and publishing'); + core.info('Auto build info publish is disabled or jf rt ping failed. Skipping auto build info collection and publishing'); } - // Collect evidences if not disabled + // Collect evidences if not disabled. Evidence use Access token that may not work with jf rt ping. if (!disableAutoEvidenceCollection) { yield (0, evidence_collection_1.collectEvidences)(); } @@ -95,11 +93,11 @@ function buildInfoPostTasks() { core.info('Auto evidence collection is disabled. Skipping evidence collection'); } // Generate job summary if not disabled and the JFrog CLI version supports it - if (!disableJobSummary) { + if (pingWorked && !disableJobSummary) { yield generateJobSummary(); } else { - core.info('Job summary is disabled. Skipping job summary generation'); + core.info('Job summary is disabled or jf rt ping failed. Skipping job summary generation'); } }); } diff --git a/lib/evidence-collection.js b/lib/evidence-collection.js index b8109f590..0b909de7d 100644 --- a/lib/evidence-collection.js +++ b/lib/evidence-collection.js @@ -33,6 +33,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }; Object.defineProperty(exports, "__esModule", { value: true }); exports.collectEvidences = collectEvidences; +exports.getSigstoreBundlePaths = getSigstoreBundlePaths; const core = __importStar(require("@actions/core")); const utils_1 = require("./utils"); const http_client_1 = require("@actions/http-client"); @@ -40,21 +41,35 @@ const fs_1 = require("fs"); const path = __importStar(require("path")); /** * Collects evidences from the current workflow. - * This function first checks if evidence collection is supported by the Artifactory server. + * This function first checks if attestation files exist, then checks if evidence collection is supported by the Artifactory server. */ function collectEvidences() { return __awaiter(this, void 0, void 0, function* () { + var _a; try { core.startGroup('Collecting evidences'); + // Check authentication method first - evidence collection requires access token or OIDC + const credentials = utils_1.Utils.collectJfrogCredentialsFromEnvVars(); + if (!credentials.accessToken && !credentials.oidcProviderName && (credentials.username || credentials.password)) { + core.info('Evidence collection does not support authentication with username and password. Skipping evidence collection.'); + return; + } + // Check if attestation files exist first to fail fast + const filePaths = yield getSigstoreBundlePaths(); + if (filePaths.length === 0) { + return; + } // Check if evidence collection is supported by the server const evidenceConfig = yield getEvidenceConfiguration(); if (!evidenceConfig.external_evidence_collection_supported) { - core.info('Evidence collection is not supported by this Artifactory server. Skipping evidence collection.'); + core.info("Evidence collection is not supported by Artifactory's license type. Skipping evidence collection."); return; } - core.info(`Evidence collection is supported. Maximum file size: ${evidenceConfig.max_evidence_file_size_mb} MB`); - // Read sigstore bundle file paths and create evidence for each - yield createEvidenceFromSigstoreBundles(evidenceConfig.max_evidence_file_size_mb); + // Use a default limit if the server doesn't provide one + const maxFileSizeMB = (_a = evidenceConfig.evidence_file_size_limit_mb) !== null && _a !== void 0 ? _a : 16; + core.info(`Evidence collection is supported. Maximum file size: ${maxFileSizeMB} MB`); + // Create evidence for each sigstore bundle file + yield createEvidenceFromSigstoreBundles(maxFileSizeMB, filePaths); } catch (error) { core.warning('Failed while attempting to collect evidences: ' + error); @@ -76,19 +91,21 @@ function getEvidenceConfiguration() { } // Get access token for authentication let accessToken = credentials.accessToken; + // Try to get access token if not available if (!accessToken && credentials.oidcProviderName) { // Import OidcUtils dynamically to avoid circular dependency const { OidcUtils } = yield Promise.resolve().then(() => __importStar(require('./oidc-utils'))); accessToken = yield OidcUtils.exchangeOidcToken(credentials); } + // Check if we have access token available if (!accessToken) { - throw new Error('No access token available for authentication'); + throw new Error('No access token available for authentication. Evidence collection requires access token authentication.'); } // Remove trailing slash from jfrogUrl to avoid double slashes when appending the API path const url = `${credentials.jfrogUrl.replace(/\/$/, '')}/evidence/api/v1/config/`; const httpClient = new http_client_1.HttpClient(); const headers = { - 'Authorization': `Bearer ${accessToken}`, + Authorization: `Bearer ${accessToken}`, }; core.debug(`Getting evidence configuration at: ${url}`); let response; @@ -99,11 +116,11 @@ function getEvidenceConfiguration() { } catch (error) { core.warning(`Failed to get evidence configuration (network error or server unavailable): ${error}`); - return { external_evidence_collection_supported: false, max_evidence_file_size_mb: 0 }; + return {external_evidence_collection_supported: false, evidence_file_size_limit_mb: 0}; } if (response.message.statusCode !== 200) { core.warning(`Failed to get evidence configuration. Status: ${response.message.statusCode}, Response: ${body}`); - return { external_evidence_collection_supported: false, max_evidence_file_size_mb: 0 }; + return {external_evidence_collection_supported: false, evidence_file_size_limit_mb: 0}; } try { const config = JSON.parse(body); @@ -111,21 +128,20 @@ function getEvidenceConfiguration() { } catch (error) { core.warning(`Failed to parse evidence config response: ${error}`); - return { external_evidence_collection_supported: false, max_evidence_file_size_mb: 0 }; + return {external_evidence_collection_supported: false, evidence_file_size_limit_mb: 0}; } }); } /** - * Reads sigstore bundle file paths and creates evidence for each file. - * Reads from ${RUNNER_TEMP}/created_attestation_paths.txt - * @param maxFileSizeMB Maximum allowed file size in MB + * Read and parse sigstore bundle file paths from the attestation paths file + * @returns Array of file paths, or empty array if file doesn't exist or is empty */ -function createEvidenceFromSigstoreBundles(maxFileSizeMB) { +function getSigstoreBundlePaths() { return __awaiter(this, void 0, void 0, function* () { const runnerTemp = process.env.RUNNER_TEMP; if (!runnerTemp) { core.warning('RUNNER_TEMP environment variable is not set. Skipping evidence creation.'); - return; + return []; } const attestationPathsFile = path.join(runnerTemp, 'created_attestation_paths.txt'); try { @@ -134,17 +150,28 @@ function createEvidenceFromSigstoreBundles(maxFileSizeMB) { } catch (error) { core.info(`No attestation paths file found. Skipping evidence creation. Searched for: ${attestationPathsFile}. Error: ${error}`); - return; + return []; } // Read the file content core.info(`Reading attestation paths file: ${attestationPathsFile}`); const fileContent = yield fs_1.promises.readFile(attestationPathsFile, 'utf8'); - const filePaths = fileContent.split('\n').filter(line => line.trim() !== ''); + const filePaths = fileContent.split('\n').filter((line) => line.trim() !== ''); if (filePaths.length === 0) { core.info('No sigstore bundle files found in attestation paths file.'); - return; + return []; } core.info(`Found ${filePaths.length} sigstore bundle file(s) to process.`); + return filePaths; + }); +} + +/** + * Creates evidence for sigstore bundle files. + * @param maxFileSizeMB Maximum allowed file size in MB + * @param filePaths Array of file paths to process + */ +function createEvidenceFromSigstoreBundles(maxFileSizeMB, filePaths) { + return __awaiter(this, void 0, void 0, function* () { for (const filePath of filePaths) { try { const fileStats = yield fs_1.promises.stat(filePath); @@ -154,7 +181,7 @@ function createEvidenceFromSigstoreBundles(maxFileSizeMB) { continue; } core.info(`Creating evidence for: ${filePath}`); - const output = yield utils_1.Utils.runCliAndGetOutput(['evd', 'create', '--sigstore-bundle', filePath]); + const output = yield utils_1.Utils.runCliAndGetOutput(['evd', 'create', '--sigstore-bundle', filePath, '--provider-id', 'github']); core.info(`Evidence created successfully for ${filePath}: ${output}`); } catch (error) { diff --git a/package-lock.json b/package-lock.json index 4e0541668..4e03acfba 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@jfrog/setup-jfrog-cli", - "version": "4.5.11", + "version": "4.5.12", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@jfrog/setup-jfrog-cli", - "version": "4.5.11", + "version": "4.5.12", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { diff --git a/package.json b/package.json index 388c4258b..ab155a5f0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@jfrog/setup-jfrog-cli", - "version": "4.5.11", + "version": "4.5.12", "private": true, "description": "Setup JFrog CLI in GitHub Actions", "main": "lib/main.js",