From 5d338a1497151abf877e1d46c11f5d76590b59e2 Mon Sep 17 00:00:00 2001 From: Joel Rudsberg Date: Fri, 29 Nov 2024 14:17:48 +0100 Subject: [PATCH] Integrate Native Image SBOM with GitHub's Dependency Submission API --- .github/workflows/test.yml | 47 ++ .gitignore | 5 +- README.md | 1 + __tests__/sbom.test.ts | 285 ++++++++ __tests__/sbom/main-test-app/pom.xml | 55 ++ .../com/oracle/sbom/SBOMTestApplication.java | 12 + action.yml | 4 + dist/cleanup/index.js | 389 ++++++++-- dist/main/index.js | 662 ++++++++++++++---- package-lock.json | 38 +- package.json | 3 +- src/cleanup.ts | 2 + src/constants.ts | 2 + src/features/reports.ts | 5 +- src/features/sbom.ts | 282 ++++++++ src/main.ts | 4 +- 16 files changed, 1583 insertions(+), 213 deletions(-) create mode 100644 __tests__/sbom.test.ts create mode 100644 __tests__/sbom/main-test-app/pom.xml create mode 100644 __tests__/sbom/main-test-app/src/main/java/com/oracle/sbom/SBOMTestApplication.java create mode 100644 src/features/sbom.ts diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2642a1f..8888349 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -417,3 +417,50 @@ jobs: # popd > /dev/null - name: Remove components run: gu remove espresso llvm-toolchain nodejs python ruby wasm + test-sbom: + name: test 'native-image-enable-sbom' option + runs-on: ${{ matrix.os }} + permissions: + contents: write + strategy: + matrix: + os: [macos-latest, ubuntu-latest, windows-latest] + steps: + - uses: actions/checkout@v4 + - uses: ./ + with: + java-version: 'latest-ea' + distribution: 'graalvm' + native-image-enable-sbom: 'true' + - name: Build Maven project and verify SBOM was generated + run: | + cd __tests__/sbom/main-test-app + mvn -Pnative package + cd target + echo "Checking for 'pkg:maven/org.json/json@20211205'" + grep -q 'pkg:maven/org.json/json@20211205' sbom.sbom.json || exit 1 + echo "Checking for 'main-test-app'" + grep -q '"main-test-app"' sbom.sbom.json || exit 1 + echo "Checking for 'svm'" + grep -q '"svm"' sbom.sbom.json || exit 1 + echo "Checking for 'nativeimage'" + grep -q '"nativeimage"' sbom.sbom.json || exit 1 + echo "SBOM was successfully generated and contained the expected contents" + shell: bash + if: runner.os != 'Windows' + - name: Build Maven project and verify SBOM was generated (Windows) + run: | + cd __tests__\sbom\main-test-app + mvn -Pnative package + cd target + echo "Checking for 'pkg:maven/org.json/json@20211205'" + findstr /c:"pkg:maven/org.json/json@20211205" sbom.sbom.json || exit /b 1 + echo "Checking for 'main-test-app'" + findstr /c:"\"main-test-app\"" sbom.sbom.json || exit /b 1 + echo "Checking for 'svm'" + findstr /c:"\"svm\"" sbom.sbom.json || exit /b 1 + echo "Checking for 'nativeimage'" + findstr /c:"\"nativeimage\"" sbom.sbom.json || exit /b 1 + echo "SBOM was successfully generated and contained the expected contents" + shell: cmd + if: runner.os == 'Windows' \ No newline at end of file diff --git a/.gitignore b/.gitignore index 18e337d..6afa38e 100644 --- a/.gitignore +++ b/.gitignore @@ -96,4 +96,7 @@ Thumbs.db # Ignore built ts files __tests__/runner/* -lib/**/* \ No newline at end of file +lib/**/* + +# Ignore target directory in test +__tests__/**/target diff --git a/README.md b/README.md index 58a589a..bbf3f61 100644 --- a/README.md +++ b/README.md @@ -205,6 +205,7 @@ This actions can be configured with the following options: | `native-image-job-reports` *) | `'false'` | If set to `'true'`, post a job summary containing a Native Image build report. | | `native-image-pr-reports` *) | `'false'` | If set to `'true'`, post a comment containing a Native Image build report on pull requests. Requires `write` permissions for the [`pull-requests` scope][gha-permissions]. | | `native-image-pr-reports-update-existing` *) | `'false'` | Instead of posting another comment, update an existing PR comment with the latest Native Image build report. Requires `native-image-pr-reports` to be `true`. | +| `native-image-enable-sbom` | `'false'` | If set to `'true'`, generate a minimal SBOM based on the Native Image static analysis and submit it to GitHub's dependency submission API. This enables the [dependency graph feature](https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-the-dependency-graph) for dependency tracking and vulnerability analysis. Requires `write` permissions for the [`contents` scope][gha-permissions] and the dependency graph to be actived (on my default for public repositories - see [how to activate](https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/configuring-the-dependency-graph#enabling-and-disabling-the-dependency-graph-for-a-private-repository)). | | `components` | `''` | Comma-separated list of GraalVM components (e.g., `native-image` or `ruby,nodejs`) that will be installed by the [GraalVM Updater][gu]. | | `version` | `''` | `X.Y.Z` (e.g., `22.3.0`) for a specific [GraalVM release][releases] up to `22.3.2`
`mandrel-X.Y.Z.W` or `X.Y.Z.W-Final` (e.g., `mandrel-21.3.0.0-Final` or `21.3.0.0-Final`) for a specific [Mandrel release][mandrel-releases],
`mandrel-latest` or `latest` for the latest Mandrel stable release. | | `gds-token` | `''` Download token for the GraalVM Download Service. If a non-empty token is provided, the action will set up Oracle GraalVM (see [Oracle GraalVM via GDS template](#template-for-oracle-graalvm-via-graalvm-download-service)) or GraalVM Enterprise Edition (see [GraalVM EE template](#template-for-graalvm-enterprise-edition)) via GDS. | diff --git a/__tests__/sbom.test.ts b/__tests__/sbom.test.ts new file mode 100644 index 0000000..0629883 --- /dev/null +++ b/__tests__/sbom.test.ts @@ -0,0 +1,285 @@ +import * as c from '../src/constants' +import { + setUpSBOMSupport, + processSBOM, + mapToComponentsWithDependencies, + INPUT_NI_SBOM +} from '../src/features/sbom' +import * as core from '@actions/core' +import * as github from '@actions/github' +import * as glob from '@actions/glob' +import {join} from 'path' +import {tmpdir} from 'os' +import {mkdtempSync, writeFileSync, rmSync} from 'fs' + +jest.mock('@actions/glob') +jest.mock('@actions/github', () => ({ + getOctokit: jest.fn(() => ({ + request: jest.fn().mockResolvedValue(undefined) + })), + context: { + repo: { + owner: 'test-owner', + repo: 'test-repo' + }, + sha: 'test-sha', + ref: 'test-ref', + workflow: 'test-workflow', + job: 'test-job', + runId: '12345' + } +})) + +// sbom.ts uses glob to find the SBOM file +// This helper function mocks the glob module to return 'files' +function mockGlobResult(files: string[]) { + const mockCreate = jest.fn().mockResolvedValue({ + glob: jest.fn().mockResolvedValue(files) + }) + ;(glob.create as jest.Mock).mockImplementation(mockCreate) +} + +describe('sbom feature', () => { + let spyInfo: jest.SpyInstance> + let spyWarning: jest.SpyInstance> + let spyExportVariable: jest.SpyInstance< + void, + Parameters + > + let workspace: string + let originalEnv: NodeJS.ProcessEnv + + beforeEach(() => { + originalEnv = process.env + + process.env = { + ...process.env, + GITHUB_REPOSITORY: 'test-owner/test-repo', + GITHUB_TOKEN: 'fake-token' + } + + workspace = mkdtempSync(join(tmpdir(), 'setup-graalvm-sbom-')) + ;(github.getOctokit as jest.Mock).mockReturnValue({ + request: jest.fn().mockResolvedValue(undefined) + }) + + spyInfo = jest.spyOn(core, 'info').mockImplementation(() => null) + spyWarning = jest.spyOn(core, 'warning').mockImplementation(() => null) + spyExportVariable = jest + .spyOn(core, 'exportVariable') + .mockImplementation(() => null) + jest.spyOn(core, 'getInput').mockImplementation((name: string) => { + if (name === INPUT_NI_SBOM) { + return 'true' + } + if (name === 'github-token') { + return 'fake-token' + } + return '' + }) + }) + + afterEach(() => { + // Restore original env + process.env = originalEnv + + jest.clearAllMocks() + rmSync(workspace, {recursive: true, force: true}) + }) + + describe('setup', () => { + it('should set the SBOM option flag when activated', () => { + setUpSBOMSupport() + expect(spyExportVariable).toHaveBeenCalledWith( + c.NATIVE_IMAGE_OPTIONS_ENV, + expect.stringContaining('--enable-sbom=export') + ) + expect(spyInfo).toHaveBeenCalledWith( + 'Enabled SBOM generation for Native Image builds' + ) + }) + + it('should not set the SBOM option flag when not activated', () => { + jest.spyOn(core, 'getInput').mockReturnValue('false') + setUpSBOMSupport() + expect(spyExportVariable).not.toHaveBeenCalled() + expect(spyInfo).not.toHaveBeenCalled() + }) + }) + + describe('process', () => { + const sampleSBOM = { + bomFormat: 'CycloneDX', + specVersion: '1.5', + version: 1, + serialNumber: 'urn:uuid:52c977f8-6d04-3c07-8826-597a036d61a6', + components: [ + { + type: 'library', + group: 'org.json', + name: 'json', + version: '20211205', + purl: 'pkg:maven/org.json/json@20211205', + 'bom-ref': 'pkg:maven/org.json/json@20211205', + properties: [ + { + name: 'syft:cpe23', + value: 'cpe:2.3:a:json:json:20211205:*:*:*:*:*:*:*' + } + ] + }, + { + type: 'library', + group: 'com.oracle', + name: 'main-test-app', + version: '1.0-SNAPSHOT', + purl: 'pkg:maven/com.oracle/main-test-app@1.0-SNAPSHOT', + 'bom-ref': 'pkg:maven/com.oracle/main-test-app@1.0-SNAPSHOT' + } + ], + dependencies: [ + { + ref: 'pkg:maven/com.oracle/main-test-app@1.0-SNAPSHOT', + dependsOn: ['pkg:maven/org.json/json@20211205'] + }, + { + ref: 'pkg:maven/org.json/json@20211205', + dependsOn: [] + } + ] + } + + it('should process SBOM file and display components', async () => { + setUpSBOMSupport() + spyInfo.mockClear() + + // Mock 'native-image' invocation by creating the SBOM file + const sbomPath = join(workspace, 'test.sbom.json') + writeFileSync(sbomPath, JSON.stringify(sampleSBOM, null, 2)) + + mockGlobResult([sbomPath]) + + await processSBOM() + + expect(spyInfo).toHaveBeenCalledWith('Found SBOM file: ' + sbomPath) + expect(spyInfo).toHaveBeenCalledWith('=== SBOM Content ===') + expect(spyInfo).toHaveBeenCalledWith('- pkg:maven/org.json/json@20211205') + expect(spyInfo).toHaveBeenCalledWith( + '- pkg:maven/com.oracle/main-test-app@1.0-SNAPSHOT' + ) + expect(spyInfo).toHaveBeenCalledWith( + ' depends on: pkg:maven/org.json/json@20211205' + ) + expect(spyWarning).not.toHaveBeenCalled() + }) + + it('should handle components without purl', async () => { + setUpSBOMSupport() + spyInfo.mockClear() + + const sbomWithoutPurl = { + ...sampleSBOM, + components: [ + { + type: 'library', + name: 'no-purl-package', + version: '1.0.0', + 'bom-ref': 'no-purl-package@1.0.0' + } + ] + } + + const sbomPath = join(workspace, 'test.sbom.json') + writeFileSync(sbomPath, JSON.stringify(sbomWithoutPurl, null, 2)) + + mockGlobResult([sbomPath]) + + await processSBOM() + + expect(spyInfo).toHaveBeenCalledWith('=== SBOM Content ===') + expect(spyInfo).toHaveBeenCalledWith('- no-purl-package@1.0.0') + expect(spyWarning).not.toHaveBeenCalled() + }) + + it('should handle missing SBOM file', async () => { + setUpSBOMSupport() + spyInfo.mockClear() + + mockGlobResult([]) + + await processSBOM() + expect(spyWarning).toHaveBeenCalledWith( + 'No SBOM file found. Make sure native-image build completed successfully. Skipping submission to GitHub Dependency API.' + ) + }) + + it('should submit dependency snapshot when processing valid SBOM', async () => { + setUpSBOMSupport() + spyInfo.mockClear() + + const mockOctokit = { + request: jest.fn().mockResolvedValue(undefined) + } + ;(github.getOctokit as jest.Mock).mockReturnValue(mockOctokit) + + const sbomPath = join(workspace, 'test.sbom.json') + writeFileSync(sbomPath, JSON.stringify(sampleSBOM, null, 2)) + + mockGlobResult([sbomPath]) + + await processSBOM() + + expect(mockOctokit.request).toHaveBeenCalledWith( + 'POST /repos/{owner}/{repo}/dependency-graph/snapshots', + expect.objectContaining({ + owner: 'test-owner', + repo: 'test-repo', + version: expect.any(Number), + sha: 'test-sha', + ref: 'test-ref', + job: expect.objectContaining({ + correlator: 'test-workflow_test-job', + id: '12345' + }), + manifests: expect.objectContaining({ + 'test.sbom.json': expect.objectContaining({ + name: 'test.sbom.json', + resolved: expect.objectContaining({ + json: expect.objectContaining({ + package_url: 'pkg:maven/org.json/json@20211205', + dependencies: [] + }), + 'main-test-app': expect.objectContaining({ + package_url: + 'pkg:maven/com.oracle/main-test-app@1.0-SNAPSHOT', + dependencies: ['pkg:maven/org.json/json@20211205'] + }) + }) + }) + }) + }) + ) + }) + + it('should handle GitHub API submission errors gracefully', async () => { + setUpSBOMSupport() + spyInfo.mockClear() + + const mockOctokit = { + request: jest.fn().mockRejectedValue(new Error('API submission failed')) + } + ;(github.getOctokit as jest.Mock).mockReturnValue(mockOctokit) + + const sbomPath = join(workspace, 'test.sbom.json') + writeFileSync(sbomPath, JSON.stringify(sampleSBOM, null, 2)) + + mockGlobResult([sbomPath]) + + await processSBOM() + + expect(spyWarning).toHaveBeenCalledWith( + expect.stringContaining('Failed to submit dependency snapshot') + ) + }) + }) +}) diff --git a/__tests__/sbom/main-test-app/pom.xml b/__tests__/sbom/main-test-app/pom.xml new file mode 100644 index 0000000..09390b1 --- /dev/null +++ b/__tests__/sbom/main-test-app/pom.xml @@ -0,0 +1,55 @@ + + + 4.0.0 + + com.oracle + main-test-app + 1.0.0 + + + 11 + 11 + + + + + org.json + json + 20211205 + + + + + + native + + + + org.graalvm.buildtools + native-maven-plugin + 0.10.3 + + + + compile-no-fork + + package + + + + sbom + com.oracle.sbom.SBOMTestApplication + + -Ob + --no-fallback + -H:+ReportExceptionStackTraces + + + + + + + + \ No newline at end of file diff --git a/__tests__/sbom/main-test-app/src/main/java/com/oracle/sbom/SBOMTestApplication.java b/__tests__/sbom/main-test-app/src/main/java/com/oracle/sbom/SBOMTestApplication.java new file mode 100644 index 0000000..5164f7b --- /dev/null +++ b/__tests__/sbom/main-test-app/src/main/java/com/oracle/sbom/SBOMTestApplication.java @@ -0,0 +1,12 @@ +package com.oracle.sbom; + +import org.json.JSONObject; + +public class SBOMTestApplication { + public static void main(String argv[]) { + JSONObject jo = new JSONObject(); + jo.put("lorem", "ipsum"); + jo.put("dolor", "sit amet"); + System.out.println(jo); + } +} diff --git a/action.yml b/action.yml index ea52128..39e7c1b 100644 --- a/action.yml +++ b/action.yml @@ -51,6 +51,10 @@ inputs: required: false description: 'Instead of posting another comment, update an existing PR comment with the latest Native Image build report.' default: 'false' + native-image-enable-sbom: + required: false + description: "Automatically generate an SBOM and submit it to GitHub's dependency submission API for vulnerability and dependency tracking." + default: 'false' version: required: false description: 'GraalVM version (release, latest, dev).' diff --git a/dist/cleanup/index.js b/dist/cleanup/index.js index 588caec..928cbba 100644 --- a/dist/cleanup/index.js +++ b/dist/cleanup/index.js @@ -90339,13 +90339,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? ( }) : function(o, v) { o["default"] = v; }); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { @@ -90356,11 +90366,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }); }; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.run = void 0; +exports.run = run; const core = __importStar(__nccwpck_require__(2186)); const constants = __importStar(__nccwpck_require__(9042)); const cache_1 = __nccwpck_require__(9179); const reports_1 = __nccwpck_require__(2046); +const sbom_1 = __nccwpck_require__(9181); /** * Check given input and run a save process for the specified package manager * @returns Promise that will be resolved when the save process finishes @@ -90393,10 +90404,10 @@ function ignoreErrors(promise) { function run() { return __awaiter(this, void 0, void 0, function* () { yield ignoreErrors((0, reports_1.generateReports)()); + yield ignoreErrors((0, sbom_1.processSBOM)()); yield ignoreErrors(saveCache()); }); } -exports.run = run; if (require.main === require.cache[eval('__filename')]) { run(); } @@ -90414,7 +90425,7 @@ else { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.ERROR_HINT = exports.ERROR_REQUEST = exports.EVENT_NAME_PULL_REQUEST = exports.ENV_GITHUB_EVENT_NAME = exports.GDS_GRAALVM_PRODUCT_ID = exports.GDS_BASE = exports.MANDREL_NAMESPACE = exports.GRAALVM_RELEASES_REPO = exports.GRAALVM_PLATFORM = exports.GRAALVM_GH_USER = exports.GRAALVM_FILE_EXTENSION = exports.GRAALVM_ARCH = exports.JDK_HOME_SUFFIX = exports.JDK_PLATFORM = exports.JDK_ARCH = exports.VERSION_LATEST = exports.VERSION_DEV = exports.DISTRIBUTION_LIBERICA = exports.DISTRIBUTION_MANDREL = exports.DISTRIBUTION_GRAALVM_COMMUNITY = exports.DISTRIBUTION_GRAALVM = exports.EXECUTABLE_SUFFIX = exports.IS_WINDOWS = exports.IS_MACOS = exports.IS_LINUX = exports.INPUT_NI_MUSL = exports.INPUT_CHECK_FOR_UPDATES = exports.INPUT_CACHE = exports.INPUT_SET_JAVA_HOME = exports.INPUT_GITHUB_TOKEN = exports.INPUT_COMPONENTS = exports.INPUT_DISTRIBUTION = exports.INPUT_JAVA_PACKAGE = exports.INPUT_JAVA_VERSION = exports.INPUT_GDS_TOKEN = exports.INPUT_VERSION = exports.ACTION_VERSION = void 0; +exports.ERROR_HINT = exports.ERROR_REQUEST = exports.EVENT_NAME_PULL_REQUEST = exports.ENV_GITHUB_EVENT_NAME = exports.GDS_GRAALVM_PRODUCT_ID = exports.GDS_BASE = exports.MANDREL_NAMESPACE = exports.GRAALVM_RELEASES_REPO = exports.GRAALVM_PLATFORM = exports.GRAALVM_GH_USER = exports.GRAALVM_FILE_EXTENSION = exports.GRAALVM_ARCH = exports.JDK_HOME_SUFFIX = exports.JDK_PLATFORM = exports.JDK_ARCH = exports.VERSION_LATEST = exports.VERSION_DEV = exports.DISTRIBUTION_LIBERICA = exports.DISTRIBUTION_MANDREL = exports.DISTRIBUTION_GRAALVM_COMMUNITY = exports.DISTRIBUTION_GRAALVM = exports.EXECUTABLE_SUFFIX = exports.IS_WINDOWS = exports.IS_MACOS = exports.IS_LINUX = exports.NATIVE_IMAGE_OPTIONS_ENV = exports.INPUT_NI_MUSL = exports.INPUT_CHECK_FOR_UPDATES = exports.INPUT_CACHE = exports.INPUT_SET_JAVA_HOME = exports.INPUT_GITHUB_TOKEN = exports.INPUT_COMPONENTS = exports.INPUT_DISTRIBUTION = exports.INPUT_JAVA_PACKAGE = exports.INPUT_JAVA_VERSION = exports.INPUT_GDS_TOKEN = exports.INPUT_VERSION = exports.ACTION_VERSION = void 0; exports.ACTION_VERSION = '1.2.6'; exports.INPUT_VERSION = 'version'; exports.INPUT_GDS_TOKEN = 'gds-token'; @@ -90427,6 +90438,7 @@ exports.INPUT_SET_JAVA_HOME = 'set-java-home'; exports.INPUT_CACHE = 'cache'; exports.INPUT_CHECK_FOR_UPDATES = 'check-for-updates'; exports.INPUT_NI_MUSL = 'native-image-musl'; +exports.NATIVE_IMAGE_OPTIONS_ENV = 'NATIVE_IMAGE_OPTIONS'; exports.IS_LINUX = process.platform === 'linux'; exports.IS_MACOS = process.platform === 'darwin'; exports.IS_WINDOWS = process.platform === 'win32'; @@ -90546,13 +90558,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? ( }) : function(o, v) { o["default"] = v; }); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { @@ -90566,7 +90588,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.save = exports.restore = void 0; +exports.restore = restore; +exports.save = save; const path_1 = __nccwpck_require__(1017); const os_1 = __importDefault(__nccwpck_require__(2037)); const cache = __importStar(__nccwpck_require__(7799)); @@ -90666,7 +90689,6 @@ function restore(id) { } }); } -exports.restore = restore; /** * Save the dependency cache * @param id ID of the package manager, should be "maven" or "gradle" @@ -90707,7 +90729,6 @@ function save(id) { } }); } -exports.save = save; /** * @param packageManager the specified package manager by user * @param error the error thrown by the saveCache @@ -90747,13 +90768,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? ( }) : function(o, v) { o["default"] = v; }); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { @@ -90764,7 +90795,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }); }; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.generateReports = exports.setUpNativeImageBuildReports = void 0; +exports.setUpNativeImageBuildReports = setUpNativeImageBuildReports; +exports.generateReports = generateReports; const c = __importStar(__nccwpck_require__(9042)); const core = __importStar(__nccwpck_require__(2186)); const fs = __importStar(__nccwpck_require__(7147)); @@ -90782,7 +90814,6 @@ const INPUT_NI_JOB_REPORTS = 'native-image-job-reports'; const INPUT_NI_PR_REPORTS = 'native-image-pr-reports'; const INPUT_NI_PR_REPORTS_UPDATE = 'native-image-pr-reports-update-existing'; const NATIVE_IMAGE_CONFIG_FILE = (0, path_1.join)((0, os_1.tmpdir)(), 'native-image-options.properties'); -const NATIVE_IMAGE_OPTIONS_ENV = 'NATIVE_IMAGE_OPTIONS'; const NATIVE_IMAGE_CONFIG_FILE_ENV = 'NATIVE_IMAGE_CONFIG_FILE'; const PR_COMMENT_TITLE = '## GraalVM Native Image Build Report'; function setUpNativeImageBuildReports(isGraalVMforJDK17OrLater, javaVersionOrDev, graalVMVersion) { @@ -90803,7 +90834,6 @@ function setUpNativeImageBuildReports(isGraalVMforJDK17OrLater, javaVersionOrDev setNativeImageOption(javaVersionOrDev, `-H:BuildOutputJSONFile=${BUILD_OUTPUT_JSON_PATH.replace(/\\/g, '\\\\')}`); // Escape backslashes for Windows }); } -exports.setUpNativeImageBuildReports = setUpNativeImageBuildReports; function generateReports() { return __awaiter(this, void 0, void 0, function* () { if (areJobReportsEnabled() || arePRReportsEnabled()) { @@ -90832,7 +90862,6 @@ function generateReports() { } }); } -exports.generateReports = generateReports; function areJobReportsEnabled() { return core.getInput(INPUT_NI_JOB_REPORTS) === 'true'; } @@ -90850,11 +90879,11 @@ function setNativeImageOption(javaVersionOrDev, optionValue) { javaVersionOrDev.endsWith('-ea')) { /* NATIVE_IMAGE_OPTIONS was introduced in GraalVM for JDK 22 (so were EA builds). */ let newOptionValue = optionValue; - const existingOptions = process.env[NATIVE_IMAGE_OPTIONS_ENV]; + const existingOptions = process.env[c.NATIVE_IMAGE_OPTIONS_ENV]; if (existingOptions) { newOptionValue = `${existingOptions} ${newOptionValue}`; } - core.exportVariable(NATIVE_IMAGE_OPTIONS_ENV, newOptionValue); + core.exportVariable(c.NATIVE_IMAGE_OPTIONS_ENV, newOptionValue); } else { const optionsFile = getNativeImageOptionsFile(); @@ -91103,7 +91132,7 @@ function secondsToHuman(seconds) { /***/ }), -/***/ 1314: +/***/ 9181: /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { "use strict"; @@ -91124,13 +91153,266 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? ( }) : function(o, v) { o["default"] = v; }); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); }; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.SBOM_FILE_SUFFIX = exports.INPUT_NI_SBOM = void 0; +exports.setUpSBOMSupport = setUpSBOMSupport; +exports.processSBOM = processSBOM; +exports.mapToComponentsWithDependencies = mapToComponentsWithDependencies; +const c = __importStar(__nccwpck_require__(9042)); +const core = __importStar(__nccwpck_require__(2186)); +const fs = __importStar(__nccwpck_require__(7147)); +const github = __importStar(__nccwpck_require__(5438)); +const glob = __importStar(__nccwpck_require__(8090)); +const path_1 = __nccwpck_require__(1017); +exports.INPUT_NI_SBOM = 'native-image-enable-sbom'; +exports.SBOM_FILE_SUFFIX = '.sbom.json'; +function setUpSBOMSupport() { + const isSbomEnabled = core.getInput(exports.INPUT_NI_SBOM) === 'true'; + if (!isSbomEnabled) { + return; + } + let options = process.env[c.NATIVE_IMAGE_OPTIONS_ENV] || ''; + if (options.length > 0) { + options += ' '; + } + options += '--enable-sbom=export'; + core.exportVariable(c.NATIVE_IMAGE_OPTIONS_ENV, options); + core.info('Enabled SBOM generation for Native Image builds'); +} +function processSBOM() { + return __awaiter(this, void 0, void 0, function* () { + const isSbomEnabled = core.getInput(exports.INPUT_NI_SBOM) === 'true'; + if (!isSbomEnabled) { + return; + } + const sbomPath = yield findSBOMFilePath(); + if (!sbomPath) { + return; + } + try { + const sbomContent = fs.readFileSync(sbomPath, 'utf8'); + const sbomData = parseSBOM(sbomContent); + if (!sbomData) { + return; + } + const components = mapToComponentsWithDependencies(sbomData); + if (components.length === 0) { + return; + } + printSBOMContent(components); + const snapshot = convertSBOMToSnapshot(sbomPath, components); + if (snapshot) { + yield submitDependencySnapshot(snapshot); + } + } + catch (error) { + core.warning(`Failed to process SBOM file: ${error instanceof Error ? error.message : String(error)}`); + } + }); +} +function findSBOMFilePath() { + return __awaiter(this, void 0, void 0, function* () { + const globber = yield glob.create(`**/*${exports.SBOM_FILE_SUFFIX}`); + const sbomFiles = yield globber.glob(); + if (sbomFiles.length === 0) { + logSkippingSubmission('No SBOM file found. Make sure native-image build completed successfully.'); + return null; + } + if (sbomFiles.length > 1) { + logSkippingSubmission(`Found multiple SBOM files: ${sbomFiles.join(', ')}.`); + return null; + } + core.info(`Found SBOM file: ${sbomFiles[0]}`); + return sbomFiles[0]; + }); +} +function parseSBOM(jsonString) { + try { + const sbomData = JSON.parse(jsonString); + return sbomData; + } + catch (error) { + core.warning(`Failed to parse SBOM JSON: ${error instanceof Error ? error.message : String(error)}`); + return null; + } +} +// Maps the SBOM data to a list of components with their dependencies +function mapToComponentsWithDependencies(sbom) { + if (!sbom || sbom.components.length === 0) { + logSkippingSubmission('Invalid SBOM data or no components found.'); + return []; + } + return sbom.components.map((component) => { + var _a, _b; + const dependencies = ((_b = (_a = sbom.dependencies) === null || _a === void 0 ? void 0 : _a.find((dep) => dep.ref === component['bom-ref'])) === null || _b === void 0 ? void 0 : _b.dependsOn) || []; + return { + name: component.name, + version: component.version, + purl: component.purl, + dependencies, + 'bom-ref': component['bom-ref'] + }; + }); +} +function printSBOMContent(components) { + core.info('=== SBOM Content ==='); + for (const component of components) { + core.info(`- ${component['bom-ref']}`); + if (component.dependencies && component.dependencies.length > 0) { + core.info(` depends on: ${component.dependencies.join(', ')}`); + } + } + core.info('=================='); +} +function mapToSnapshotResolved(components) { + return Object.fromEntries(components + .filter(component => { + if (!component.purl) { + core.info(`Component ${component.name} does not have a valid package URL (purl). Skipping.`); + } + return component.purl; + }) + .map(component => [ + component.name, + { + package_url: component.purl, + dependencies: component.dependencies || [] + } + ])); +} +function convertSBOMToSnapshot(sbomPath, components) { + const context = github.context; + const sbomFileName = (0, path_1.basename)(sbomPath); + if (!sbomFileName.endsWith(exports.SBOM_FILE_SUFFIX)) { + logSkippingSubmission(`Invalid SBOM file name: ${sbomFileName}. Expected a file ending with ${exports.SBOM_FILE_SUFFIX}.`); + return null; + } + return { + version: 0, + sha: context.sha, + ref: context.ref, + job: { + correlator: `${context.workflow}_${context.job}`, + id: context.runId.toString(), + html_url: `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}` + }, + detector: { + name: 'graalvm-native-image', + version: c.ACTION_VERSION, + url: 'https://github.com/graalvm/setup-graalvm' + }, + scanned: new Date().toISOString(), + manifests: { + [sbomFileName]: { + name: sbomFileName, + resolved: mapToSnapshotResolved(components), + metadata: { + generated_by: 'SBOM generated by GraalVM Native Image', + action_version: c.ACTION_VERSION + } + } + } + }; +} +function submitDependencySnapshot(snapshotData) { + return __awaiter(this, void 0, void 0, function* () { + const token = core.getInput(c.INPUT_GITHUB_TOKEN, { required: true }); + const octokit = github.getOctokit(token); + const context = github.context; + try { + yield octokit.request('POST /repos/{owner}/{repo}/dependency-graph/snapshots', { + owner: context.repo.owner, + repo: context.repo.repo, + version: snapshotData.version, + sha: snapshotData.sha, + ref: snapshotData.ref, + job: snapshotData.job, + detector: snapshotData.detector, + metadata: {}, + scanned: snapshotData.scanned, + manifests: snapshotData.manifests, + headers: { + 'X-GitHub-Api-Version': '2022-11-28' + } + }); + core.info('Dependency snapshot submitted successfully.'); + } + catch (error) { + core.warning(`Failed to submit dependency snapshot for SBOM: ${error instanceof Error ? error.message : String(error)}`); + } + }); +} +function logSkippingSubmission(prefix) { + core.warning(`${prefix} Skipping submission to GitHub Dependency API.`); +} + + +/***/ }), + +/***/ 1314: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + +"use strict"; + +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { @@ -91141,7 +91423,19 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }); }; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.createPRComment = exports.updatePRComment = exports.findExistingPRCommentId = exports.isPREvent = exports.toSemVer = exports.calculateSHA256 = exports.downloadExtractAndCacheJDK = exports.downloadAndExtractJDK = exports.getMatchingTags = exports.getTaggedRelease = exports.getContents = exports.getLatestRelease = exports.exec = void 0; +exports.exec = exec; +exports.getLatestRelease = getLatestRelease; +exports.getContents = getContents; +exports.getTaggedRelease = getTaggedRelease; +exports.getMatchingTags = getMatchingTags; +exports.downloadAndExtractJDK = downloadAndExtractJDK; +exports.downloadExtractAndCacheJDK = downloadExtractAndCacheJDK; +exports.calculateSHA256 = calculateSHA256; +exports.toSemVer = toSemVer; +exports.isPREvent = isPREvent; +exports.findExistingPRCommentId = findExistingPRCommentId; +exports.updatePRComment = updatePRComment; +exports.createPRComment = createPRComment; const c = __importStar(__nccwpck_require__(9042)); const core = __importStar(__nccwpck_require__(2186)); const github = __importStar(__nccwpck_require__(5438)); @@ -91171,7 +91465,6 @@ function exec(commandLine, args, options) { } }); } -exports.exec = exec; function getLatestRelease(repo) { return __awaiter(this, void 0, void 0, function* () { const githubToken = getGitHubToken(); @@ -91183,7 +91476,6 @@ function getLatestRelease(repo) { })).data; }); } -exports.getLatestRelease = getLatestRelease; function getContents(repo, path) { return __awaiter(this, void 0, void 0, function* () { const githubToken = getGitHubToken(); @@ -91196,7 +91488,6 @@ function getContents(repo, path) { })).data; }); } -exports.getContents = getContents; function getTaggedRelease(owner, repo, tag) { return __awaiter(this, void 0, void 0, function* () { const githubToken = getGitHubToken(); @@ -91209,7 +91500,6 @@ function getTaggedRelease(owner, repo, tag) { })).data; }); } -exports.getTaggedRelease = getTaggedRelease; function getMatchingTags(owner, repo, tagPrefix) { return __awaiter(this, void 0, void 0, function* () { const githubToken = getGitHubToken(); @@ -91222,13 +91512,11 @@ function getMatchingTags(owner, repo, tagPrefix) { })).data; }); } -exports.getMatchingTags = getMatchingTags; function downloadAndExtractJDK(downloadUrl) { return __awaiter(this, void 0, void 0, function* () { return findJavaHomeInSubfolder(yield extract(yield tc.downloadTool(downloadUrl))); }); } -exports.downloadAndExtractJDK = downloadAndExtractJDK; function downloadExtractAndCacheJDK(downloader, toolName, version) { return __awaiter(this, void 0, void 0, function* () { const semVersion = toSemVer(version); @@ -91244,13 +91532,11 @@ function downloadExtractAndCacheJDK(downloader, toolName, version) { return findJavaHomeInSubfolder(toolPath); }); } -exports.downloadExtractAndCacheJDK = downloadExtractAndCacheJDK; function calculateSHA256(filePath) { const hashSum = (0, crypto_1.createHash)('sha256'); hashSum.update((0, fs_1.readFileSync)(filePath)); return hashSum.digest('hex'); } -exports.calculateSHA256 = calculateSHA256; function extract(downloadPath) { return __awaiter(this, void 0, void 0, function* () { if (c.GRAALVM_FILE_EXTENSION === '.tar.gz') { @@ -91290,11 +91576,9 @@ function toSemVer(version) { } return validVersion; } -exports.toSemVer = toSemVer; function isPREvent() { return process.env[c.ENV_GITHUB_EVENT_NAME] === c.EVENT_NAME_PULL_REQUEST; } -exports.isPREvent = isPREvent; function getGitHubToken() { return core.getInput(c.INPUT_GITHUB_TOKEN); } @@ -91318,7 +91602,6 @@ function findExistingPRCommentId(bodyStartsWith) { } }); } -exports.findExistingPRCommentId = findExistingPRCommentId; function updatePRComment(content, commentId) { return __awaiter(this, void 0, void 0, function* () { if (!isPREvent()) { @@ -91332,7 +91615,6 @@ function updatePRComment(content, commentId) { } }); } -exports.updatePRComment = updatePRComment; function createPRComment(content) { return __awaiter(this, void 0, void 0, function* () { var _a; @@ -91348,7 +91630,6 @@ function createPRComment(content) { } }); } -exports.createPRComment = createPRComment; /***/ }), diff --git a/dist/main/index.js b/dist/main/index.js index 8c7b2d6..df8dcbb 100644 --- a/dist/main/index.js +++ b/dist/main/index.js @@ -90980,7 +90980,7 @@ function wrappy (fn, cb) { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.ERROR_HINT = exports.ERROR_REQUEST = exports.EVENT_NAME_PULL_REQUEST = exports.ENV_GITHUB_EVENT_NAME = exports.GDS_GRAALVM_PRODUCT_ID = exports.GDS_BASE = exports.MANDREL_NAMESPACE = exports.GRAALVM_RELEASES_REPO = exports.GRAALVM_PLATFORM = exports.GRAALVM_GH_USER = exports.GRAALVM_FILE_EXTENSION = exports.GRAALVM_ARCH = exports.JDK_HOME_SUFFIX = exports.JDK_PLATFORM = exports.JDK_ARCH = exports.VERSION_LATEST = exports.VERSION_DEV = exports.DISTRIBUTION_LIBERICA = exports.DISTRIBUTION_MANDREL = exports.DISTRIBUTION_GRAALVM_COMMUNITY = exports.DISTRIBUTION_GRAALVM = exports.EXECUTABLE_SUFFIX = exports.IS_WINDOWS = exports.IS_MACOS = exports.IS_LINUX = exports.INPUT_NI_MUSL = exports.INPUT_CHECK_FOR_UPDATES = exports.INPUT_CACHE = exports.INPUT_SET_JAVA_HOME = exports.INPUT_GITHUB_TOKEN = exports.INPUT_COMPONENTS = exports.INPUT_DISTRIBUTION = exports.INPUT_JAVA_PACKAGE = exports.INPUT_JAVA_VERSION = exports.INPUT_GDS_TOKEN = exports.INPUT_VERSION = exports.ACTION_VERSION = void 0; +exports.ERROR_HINT = exports.ERROR_REQUEST = exports.EVENT_NAME_PULL_REQUEST = exports.ENV_GITHUB_EVENT_NAME = exports.GDS_GRAALVM_PRODUCT_ID = exports.GDS_BASE = exports.MANDREL_NAMESPACE = exports.GRAALVM_RELEASES_REPO = exports.GRAALVM_PLATFORM = exports.GRAALVM_GH_USER = exports.GRAALVM_FILE_EXTENSION = exports.GRAALVM_ARCH = exports.JDK_HOME_SUFFIX = exports.JDK_PLATFORM = exports.JDK_ARCH = exports.VERSION_LATEST = exports.VERSION_DEV = exports.DISTRIBUTION_LIBERICA = exports.DISTRIBUTION_MANDREL = exports.DISTRIBUTION_GRAALVM_COMMUNITY = exports.DISTRIBUTION_GRAALVM = exports.EXECUTABLE_SUFFIX = exports.IS_WINDOWS = exports.IS_MACOS = exports.IS_LINUX = exports.NATIVE_IMAGE_OPTIONS_ENV = exports.INPUT_NI_MUSL = exports.INPUT_CHECK_FOR_UPDATES = exports.INPUT_CACHE = exports.INPUT_SET_JAVA_HOME = exports.INPUT_GITHUB_TOKEN = exports.INPUT_COMPONENTS = exports.INPUT_DISTRIBUTION = exports.INPUT_JAVA_PACKAGE = exports.INPUT_JAVA_VERSION = exports.INPUT_GDS_TOKEN = exports.INPUT_VERSION = exports.ACTION_VERSION = void 0; exports.ACTION_VERSION = '1.2.6'; exports.INPUT_VERSION = 'version'; exports.INPUT_GDS_TOKEN = 'gds-token'; @@ -90993,6 +90993,7 @@ exports.INPUT_SET_JAVA_HOME = 'set-java-home'; exports.INPUT_CACHE = 'cache'; exports.INPUT_CHECK_FOR_UPDATES = 'check-for-updates'; exports.INPUT_NI_MUSL = 'native-image-musl'; +exports.NATIVE_IMAGE_OPTIONS_ENV = 'NATIVE_IMAGE_OPTIONS'; exports.IS_LINUX = process.platform === 'linux'; exports.IS_MACOS = process.platform === 'darwin'; exports.IS_WINDOWS = process.platform === 'win32'; @@ -91085,13 +91086,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? ( }) : function(o, v) { o["default"] = v; }); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { @@ -91102,7 +91113,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }); }; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.setUpDependencies = void 0; +exports.setUpDependencies = setUpDependencies; const core = __importStar(__nccwpck_require__(2186)); const constants_1 = __nccwpck_require__(9042); const utils_1 = __nccwpck_require__(1314); @@ -91136,7 +91147,6 @@ function setUpDependencies(components) { } }); } -exports.setUpDependencies = setUpDependencies; /***/ }), @@ -91189,13 +91199,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? ( }) : function(o, v) { o["default"] = v; }); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { @@ -91209,7 +91229,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.save = exports.restore = void 0; +exports.restore = restore; +exports.save = save; const path_1 = __nccwpck_require__(1017); const os_1 = __importDefault(__nccwpck_require__(2037)); const cache = __importStar(__nccwpck_require__(7799)); @@ -91309,7 +91330,6 @@ function restore(id) { } }); } -exports.restore = restore; /** * Save the dependency cache * @param id ID of the package manager, should be "maven" or "gradle" @@ -91350,7 +91370,6 @@ function save(id) { } }); } -exports.save = save; /** * @param packageManager the specified package manager by user * @param error the error thrown by the saveCache @@ -91390,15 +91409,25 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? ( }) : function(o, v) { o["default"] = v; }); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.checkForUpdates = void 0; +exports.checkForUpdates = checkForUpdates; const core = __importStar(__nccwpck_require__(2186)); function checkForUpdates(graalVMVersion, javaVersion) { if (javaVersion === '20') { @@ -91417,7 +91446,6 @@ function checkForUpdates(graalVMVersion, javaVersion) { } // TODO: add support for JDK-specific update checks (e.g., 17.0.X) } -exports.checkForUpdates = checkForUpdates; /***/ }), @@ -91443,13 +91471,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? ( }) : function(o, v) { o["default"] = v; }); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { @@ -91460,7 +91498,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }); }; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.setUpNativeImageMusl = void 0; +exports.setUpNativeImageMusl = setUpNativeImageMusl; const c = __importStar(__nccwpck_require__(9042)); const core = __importStar(__nccwpck_require__(2186)); const tc = __importStar(__nccwpck_require__(7784)); @@ -91501,7 +91539,6 @@ function setUpNativeImageMusl() { core.addPath((0, path_1.join)(toolPath, 'bin')); }); } -exports.setUpNativeImageMusl = setUpNativeImageMusl; /***/ }), @@ -91527,13 +91564,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? ( }) : function(o, v) { o["default"] = v; }); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { @@ -91544,7 +91591,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }); }; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.generateReports = exports.setUpNativeImageBuildReports = void 0; +exports.setUpNativeImageBuildReports = setUpNativeImageBuildReports; +exports.generateReports = generateReports; const c = __importStar(__nccwpck_require__(9042)); const core = __importStar(__nccwpck_require__(2186)); const fs = __importStar(__nccwpck_require__(7147)); @@ -91562,7 +91610,6 @@ const INPUT_NI_JOB_REPORTS = 'native-image-job-reports'; const INPUT_NI_PR_REPORTS = 'native-image-pr-reports'; const INPUT_NI_PR_REPORTS_UPDATE = 'native-image-pr-reports-update-existing'; const NATIVE_IMAGE_CONFIG_FILE = (0, path_1.join)((0, os_1.tmpdir)(), 'native-image-options.properties'); -const NATIVE_IMAGE_OPTIONS_ENV = 'NATIVE_IMAGE_OPTIONS'; const NATIVE_IMAGE_CONFIG_FILE_ENV = 'NATIVE_IMAGE_CONFIG_FILE'; const PR_COMMENT_TITLE = '## GraalVM Native Image Build Report'; function setUpNativeImageBuildReports(isGraalVMforJDK17OrLater, javaVersionOrDev, graalVMVersion) { @@ -91583,7 +91630,6 @@ function setUpNativeImageBuildReports(isGraalVMforJDK17OrLater, javaVersionOrDev setNativeImageOption(javaVersionOrDev, `-H:BuildOutputJSONFile=${BUILD_OUTPUT_JSON_PATH.replace(/\\/g, '\\\\')}`); // Escape backslashes for Windows }); } -exports.setUpNativeImageBuildReports = setUpNativeImageBuildReports; function generateReports() { return __awaiter(this, void 0, void 0, function* () { if (areJobReportsEnabled() || arePRReportsEnabled()) { @@ -91612,7 +91658,6 @@ function generateReports() { } }); } -exports.generateReports = generateReports; function areJobReportsEnabled() { return core.getInput(INPUT_NI_JOB_REPORTS) === 'true'; } @@ -91630,11 +91675,11 @@ function setNativeImageOption(javaVersionOrDev, optionValue) { javaVersionOrDev.endsWith('-ea')) { /* NATIVE_IMAGE_OPTIONS was introduced in GraalVM for JDK 22 (so were EA builds). */ let newOptionValue = optionValue; - const existingOptions = process.env[NATIVE_IMAGE_OPTIONS_ENV]; + const existingOptions = process.env[c.NATIVE_IMAGE_OPTIONS_ENV]; if (existingOptions) { newOptionValue = `${existingOptions} ${newOptionValue}`; } - core.exportVariable(NATIVE_IMAGE_OPTIONS_ENV, newOptionValue); + core.exportVariable(c.NATIVE_IMAGE_OPTIONS_ENV, newOptionValue); } else { const optionsFile = getNativeImageOptionsFile(); @@ -91883,7 +91928,7 @@ function secondsToHuman(seconds) { /***/ }), -/***/ 9543: +/***/ 9181: /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { "use strict"; @@ -91904,13 +91949,266 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? ( }) : function(o, v) { o["default"] = v; }); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); }; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.SBOM_FILE_SUFFIX = exports.INPUT_NI_SBOM = void 0; +exports.setUpSBOMSupport = setUpSBOMSupport; +exports.processSBOM = processSBOM; +exports.mapToComponentsWithDependencies = mapToComponentsWithDependencies; +const c = __importStar(__nccwpck_require__(9042)); +const core = __importStar(__nccwpck_require__(2186)); +const fs = __importStar(__nccwpck_require__(7147)); +const github = __importStar(__nccwpck_require__(5438)); +const glob = __importStar(__nccwpck_require__(8090)); +const path_1 = __nccwpck_require__(1017); +exports.INPUT_NI_SBOM = 'native-image-enable-sbom'; +exports.SBOM_FILE_SUFFIX = '.sbom.json'; +function setUpSBOMSupport() { + const isSbomEnabled = core.getInput(exports.INPUT_NI_SBOM) === 'true'; + if (!isSbomEnabled) { + return; + } + let options = process.env[c.NATIVE_IMAGE_OPTIONS_ENV] || ''; + if (options.length > 0) { + options += ' '; + } + options += '--enable-sbom=export'; + core.exportVariable(c.NATIVE_IMAGE_OPTIONS_ENV, options); + core.info('Enabled SBOM generation for Native Image builds'); +} +function processSBOM() { + return __awaiter(this, void 0, void 0, function* () { + const isSbomEnabled = core.getInput(exports.INPUT_NI_SBOM) === 'true'; + if (!isSbomEnabled) { + return; + } + const sbomPath = yield findSBOMFilePath(); + if (!sbomPath) { + return; + } + try { + const sbomContent = fs.readFileSync(sbomPath, 'utf8'); + const sbomData = parseSBOM(sbomContent); + if (!sbomData) { + return; + } + const components = mapToComponentsWithDependencies(sbomData); + if (components.length === 0) { + return; + } + printSBOMContent(components); + const snapshot = convertSBOMToSnapshot(sbomPath, components); + if (snapshot) { + yield submitDependencySnapshot(snapshot); + } + } + catch (error) { + core.warning(`Failed to process SBOM file: ${error instanceof Error ? error.message : String(error)}`); + } + }); +} +function findSBOMFilePath() { + return __awaiter(this, void 0, void 0, function* () { + const globber = yield glob.create(`**/*${exports.SBOM_FILE_SUFFIX}`); + const sbomFiles = yield globber.glob(); + if (sbomFiles.length === 0) { + logSkippingSubmission('No SBOM file found. Make sure native-image build completed successfully.'); + return null; + } + if (sbomFiles.length > 1) { + logSkippingSubmission(`Found multiple SBOM files: ${sbomFiles.join(', ')}.`); + return null; + } + core.info(`Found SBOM file: ${sbomFiles[0]}`); + return sbomFiles[0]; + }); +} +function parseSBOM(jsonString) { + try { + const sbomData = JSON.parse(jsonString); + return sbomData; + } + catch (error) { + core.warning(`Failed to parse SBOM JSON: ${error instanceof Error ? error.message : String(error)}`); + return null; + } +} +// Maps the SBOM data to a list of components with their dependencies +function mapToComponentsWithDependencies(sbom) { + if (!sbom || sbom.components.length === 0) { + logSkippingSubmission('Invalid SBOM data or no components found.'); + return []; + } + return sbom.components.map((component) => { + var _a, _b; + const dependencies = ((_b = (_a = sbom.dependencies) === null || _a === void 0 ? void 0 : _a.find((dep) => dep.ref === component['bom-ref'])) === null || _b === void 0 ? void 0 : _b.dependsOn) || []; + return { + name: component.name, + version: component.version, + purl: component.purl, + dependencies, + 'bom-ref': component['bom-ref'] + }; + }); +} +function printSBOMContent(components) { + core.info('=== SBOM Content ==='); + for (const component of components) { + core.info(`- ${component['bom-ref']}`); + if (component.dependencies && component.dependencies.length > 0) { + core.info(` depends on: ${component.dependencies.join(', ')}`); + } + } + core.info('=================='); +} +function mapToSnapshotResolved(components) { + return Object.fromEntries(components + .filter(component => { + if (!component.purl) { + core.info(`Component ${component.name} does not have a valid package URL (purl). Skipping.`); + } + return component.purl; + }) + .map(component => [ + component.name, + { + package_url: component.purl, + dependencies: component.dependencies || [] + } + ])); +} +function convertSBOMToSnapshot(sbomPath, components) { + const context = github.context; + const sbomFileName = (0, path_1.basename)(sbomPath); + if (!sbomFileName.endsWith(exports.SBOM_FILE_SUFFIX)) { + logSkippingSubmission(`Invalid SBOM file name: ${sbomFileName}. Expected a file ending with ${exports.SBOM_FILE_SUFFIX}.`); + return null; + } + return { + version: 0, + sha: context.sha, + ref: context.ref, + job: { + correlator: `${context.workflow}_${context.job}`, + id: context.runId.toString(), + html_url: `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}` + }, + detector: { + name: 'graalvm-native-image', + version: c.ACTION_VERSION, + url: 'https://github.com/graalvm/setup-graalvm' + }, + scanned: new Date().toISOString(), + manifests: { + [sbomFileName]: { + name: sbomFileName, + resolved: mapToSnapshotResolved(components), + metadata: { + generated_by: 'SBOM generated by GraalVM Native Image', + action_version: c.ACTION_VERSION + } + } + } + }; +} +function submitDependencySnapshot(snapshotData) { + return __awaiter(this, void 0, void 0, function* () { + const token = core.getInput(c.INPUT_GITHUB_TOKEN, { required: true }); + const octokit = github.getOctokit(token); + const context = github.context; + try { + yield octokit.request('POST /repos/{owner}/{repo}/dependency-graph/snapshots', { + owner: context.repo.owner, + repo: context.repo.repo, + version: snapshotData.version, + sha: snapshotData.sha, + ref: snapshotData.ref, + job: snapshotData.job, + detector: snapshotData.detector, + metadata: {}, + scanned: snapshotData.scanned, + manifests: snapshotData.manifests, + headers: { + 'X-GitHub-Api-Version': '2022-11-28' + } + }); + core.info('Dependency snapshot submitted successfully.'); + } + catch (error) { + core.warning(`Failed to submit dependency snapshot for SBOM: ${error instanceof Error ? error.message : String(error)}`); + } + }); +} +function logSkippingSubmission(prefix) { + core.warning(`${prefix} Skipping submission to GitHub Dependency API.`); +} + + +/***/ }), + +/***/ 9543: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + +"use strict"; + +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { @@ -91921,7 +92219,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }); }; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.fetchArtifactEE = exports.fetchArtifact = exports.downloadGraalVMEELegacy = exports.downloadGraalVM = void 0; +exports.downloadGraalVM = downloadGraalVM; +exports.downloadGraalVMEELegacy = downloadGraalVMEELegacy; +exports.fetchArtifact = fetchArtifact; +exports.fetchArtifactEE = fetchArtifactEE; const c = __importStar(__nccwpck_require__(9042)); const core = __importStar(__nccwpck_require__(2186)); const fs = __importStar(__nccwpck_require__(7147)); @@ -91942,7 +92243,6 @@ function downloadGraalVM(gdsToken, javaVersion) { return downloadArtifact(gdsToken, userAgent, baseArtifact); }); } -exports.downloadGraalVM = downloadGraalVM; function downloadGraalVMEELegacy(gdsToken, version, javaVersion) { return __awaiter(this, void 0, void 0, function* () { const userAgent = `GraalVMGitHubAction/${c.ACTION_VERSION} (arch:${c.GRAALVM_ARCH}; os:${c.GRAALVM_PLATFORM}; java:${javaVersion})`; @@ -91950,7 +92250,6 @@ function downloadGraalVMEELegacy(gdsToken, version, javaVersion) { return downloadArtifact(gdsToken, userAgent, baseArtifact); }); } -exports.downloadGraalVMEELegacy = downloadGraalVMEELegacy; function fetchArtifact(userAgent, metadata, javaVersion) { return __awaiter(this, void 0, void 0, function* () { const http = new httpClient.HttpClient(userAgent); @@ -91984,7 +92283,6 @@ function fetchArtifact(userAgent, metadata, javaVersion) { return artifactResponse.items[0]; }); } -exports.fetchArtifact = fetchArtifact; function fetchArtifactEE(userAgent, metadata, version, javaVersion) { return __awaiter(this, void 0, void 0, function* () { const http = new httpClient.HttpClient(userAgent); @@ -92011,7 +92309,6 @@ function fetchArtifactEE(userAgent, metadata, version, javaVersion) { return artifactResponse.items[0]; }); } -exports.fetchArtifactEE = fetchArtifactEE; function downloadArtifact(gdsToken, userAgent, artifact) { return __awaiter(this, void 0, void 0, function* () { let downloadPath; @@ -92144,13 +92441,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? ( }) : function(o, v) { o["default"] = v; }); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { @@ -92161,7 +92468,15 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }); }; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.setUpGraalVMRelease = exports.findGraalVMVersion = exports.setUpGraalVMLatest_22_X = exports.findHighestJavaVersion = exports.setUpGraalVMJDKDevBuild = exports.findLatestGraalVMJDKCEJavaVersion = exports.setUpGraalVMJDKCE = exports.findLatestEABuildDownloadUrl = exports.setUpGraalVMJDK = void 0; +exports.setUpGraalVMJDK = setUpGraalVMJDK; +exports.findLatestEABuildDownloadUrl = findLatestEABuildDownloadUrl; +exports.setUpGraalVMJDKCE = setUpGraalVMJDKCE; +exports.findLatestGraalVMJDKCEJavaVersion = findLatestGraalVMJDKCEJavaVersion; +exports.setUpGraalVMJDKDevBuild = setUpGraalVMJDKDevBuild; +exports.findHighestJavaVersion = findHighestJavaVersion; +exports.setUpGraalVMLatest_22_X = setUpGraalVMLatest_22_X; +exports.findGraalVMVersion = findGraalVMVersion; +exports.setUpGraalVMRelease = setUpGraalVMRelease; const c = __importStar(__nccwpck_require__(9042)); const core = __importStar(__nccwpck_require__(2186)); const semver = __importStar(__nccwpck_require__(1383)); @@ -92229,7 +92544,6 @@ function setUpGraalVMJDK(javaVersionOrDev, gdsToken) { return (0, utils_1.downloadExtractAndCacheJDK)(downloader, toolName, javaVersion); }); } -exports.setUpGraalVMJDK = setUpGraalVMJDK; function findLatestEABuildDownloadUrl(javaEaVersion) { return __awaiter(this, void 0, void 0, function* () { const filePath = `versions/${javaEaVersion}.json`; @@ -92263,7 +92577,6 @@ function findLatestEABuildDownloadUrl(javaEaVersion) { return `${latestVersion.download_base_url}${file.filename}`; }); } -exports.findLatestEABuildDownloadUrl = findLatestEABuildDownloadUrl; function setUpGraalVMJDKCE(javaVersionOrDev) { return __awaiter(this, void 0, void 0, function* () { if (javaVersionOrDev === c.VERSION_DEV) { @@ -92282,7 +92595,6 @@ function setUpGraalVMJDKCE(javaVersionOrDev) { return (0, utils_1.downloadExtractAndCacheJDK)(downloader, toolName, javaVersion); }); } -exports.setUpGraalVMJDKCE = setUpGraalVMJDKCE; function findLatestGraalVMJDKCEJavaVersion(majorJavaVersion) { return __awaiter(this, void 0, void 0, function* () { const matchingRefs = yield (0, utils_1.getMatchingTags)(c.GRAALVM_GH_USER, c.GRAALVM_RELEASES_REPO, `${GRAALVM_JDK_TAG_PREFIX}${majorJavaVersion}`); @@ -92302,7 +92614,6 @@ function findLatestGraalVMJDKCEJavaVersion(majorJavaVersion) { return highestVersion; }); } -exports.findLatestGraalVMJDKCEJavaVersion = findLatestGraalVMJDKCEJavaVersion; function determineToolName(javaVersion, isCommunity) { return `graalvm${isCommunity ? '-community' : ''}-jdk-${javaVersion}_${c.JDK_PLATFORM}-${c.JDK_ARCH}_bin`; } @@ -92329,7 +92640,6 @@ function setUpGraalVMJDKDevBuild() { return (0, utils_1.downloadAndExtractJDK)(downloadUrl); }); } -exports.setUpGraalVMJDKDevBuild = setUpGraalVMJDKDevBuild; function findHighestJavaVersion(release, version) { const graalVMIdentifierPattern = determineGraalVMLegacyIdentifier(false, version, '(\\d+)'); const expectedFileNameRegExp = new RegExp(`^${graalVMIdentifierPattern}${c.GRAALVM_FILE_EXTENSION.replace(/\./g, '\\.')}$`); @@ -92350,7 +92660,6 @@ function findHighestJavaVersion(release, version) { throw new Error('Could not find highest Java version. Please file an issue at: https://github.com/graalvm/setup-graalvm/issues.'); } } -exports.findHighestJavaVersion = findHighestJavaVersion; // Support for GraalVM 22.X releases and earlier function setUpGraalVMLatest_22_X(gdsToken, javaVersion) { return __awaiter(this, void 0, void 0, function* () { @@ -92363,7 +92672,6 @@ function setUpGraalVMLatest_22_X(gdsToken, javaVersion) { return setUpGraalVMRelease(gdsToken, version, javaVersion); }); } -exports.setUpGraalVMLatest_22_X = setUpGraalVMLatest_22_X; function findGraalVMVersion(release) { const tag_name = release.tag_name; if (!tag_name.startsWith(GRAALVM_TAG_PREFIX)) { @@ -92371,7 +92679,6 @@ function findGraalVMVersion(release) { } return tag_name.substring(GRAALVM_TAG_PREFIX.length, tag_name.length); } -exports.findGraalVMVersion = findGraalVMVersion; function setUpGraalVMRelease(gdsToken, version, javaVersion) { return __awaiter(this, void 0, void 0, function* () { const isEE = gdsToken.length > 0; @@ -92386,7 +92693,6 @@ function setUpGraalVMRelease(gdsToken, version, javaVersion) { return (0, utils_1.downloadExtractAndCacheJDK)(downloader, toolName, version); }); } -exports.setUpGraalVMRelease = setUpGraalVMRelease; function findDownloadUrl(release, javaVersion) { const graalVMIdentifier = determineGraalVMLegacyIdentifier(false, c.VERSION_DEV, javaVersion); const expectedFileName = `${graalVMIdentifier}${c.GRAALVM_FILE_EXTENSION}`; @@ -92445,13 +92751,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? ( }) : function(o, v) { o["default"] = v; }); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { @@ -92462,7 +92778,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }); }; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.setUpGUComponents = void 0; +exports.setUpGUComponents = setUpGUComponents; const c = __importStar(__nccwpck_require__(9042)); const core = __importStar(__nccwpck_require__(2186)); const semver = __importStar(__nccwpck_require__(1383)); @@ -92511,7 +92827,6 @@ function setUpGUComponents(javaVersion, graalVMVersion, graalVMHome, components, } }); } -exports.setUpGUComponents = setUpGUComponents; function installGUComponents(gdsToken, graalVMHome, components) { return __awaiter(this, void 0, void 0, function* () { yield (0, utils_1.exec)('gu', BASE_FLAGS.concat(components), { @@ -92553,13 +92868,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? ( }) : function(o, v) { o["default"] = v; }); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { @@ -92570,7 +92895,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }); }; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.findLibericaURL = exports.findLatestLibericaJavaVersion = exports.setUpLiberica = void 0; +exports.setUpLiberica = setUpLiberica; +exports.findLatestLibericaJavaVersion = findLatestLibericaJavaVersion; +exports.findLibericaURL = findLibericaURL; const c = __importStar(__nccwpck_require__(9042)); const semver = __importStar(__nccwpck_require__(1383)); const utils_1 = __nccwpck_require__(1314); @@ -92588,7 +92915,6 @@ function setUpLiberica(javaVersion, javaPackage) { return (0, utils_1.downloadExtractAndCacheJDK)(() => __awaiter(this, void 0, void 0, function* () { return (0, tool_cache_1.downloadTool)(downloadUrl); }), toolName, javaVersion); }); } -exports.setUpLiberica = setUpLiberica; function findLatestLibericaJavaVersion(javaVersion) { return __awaiter(this, void 0, void 0, function* () { const matchingRefs = yield (0, utils_1.getMatchingTags)(LIBERICA_GH_USER, LIBERICA_RELEASES_REPO, `${LIBERICA_JDK_TAG_PREFIX}${javaVersion}`); @@ -92612,7 +92938,6 @@ function findLatestLibericaJavaVersion(javaVersion) { return bestMatch; }); } -exports.findLatestLibericaJavaVersion = findLatestLibericaJavaVersion; function findLibericaURL(javaVersion, javaPackage) { return __awaiter(this, void 0, void 0, function* () { const release = yield (0, utils_1.getTaggedRelease)(LIBERICA_GH_USER, LIBERICA_RELEASES_REPO, LIBERICA_JDK_TAG_PREFIX + javaVersion); @@ -92628,7 +92953,6 @@ function findLibericaURL(javaVersion, javaPackage) { throw new Error(`Unable to find asset for java-version: ${javaVersion}, java-package: ${javaPackage}, platform: ${platform}. ${c.ERROR_REQUEST}`); }); } -exports.findLibericaURL = findLibericaURL; function determineToolName(javaVersion, javaPackage) { const variant = determineVariantPart(javaPackage); const platform = determinePlatformPart(); @@ -92682,13 +93006,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? ( }) : function(o, v) { o["default"] = v; }); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { @@ -92715,6 +93049,7 @@ const musl_1 = __nccwpck_require__(316); const msvc_1 = __nccwpck_require__(1165); const reports_1 = __nccwpck_require__(2046); const exec_1 = __nccwpck_require__(1514); +const sbom_1 = __nccwpck_require__(9181); function run() { return __awaiter(this, void 0, void 0, function* () { try { @@ -92826,6 +93161,7 @@ function run() { yield (0, cache_2.restore)(cache); } (0, reports_1.setUpNativeImageBuildReports)(isGraalVMforJDK17OrLater, javaVersion, graalVMVersion); + (0, sbom_1.setUpSBOMSupport)(); core.startGroup(`Successfully set up '${(0, path_1.basename)(graalVMHome)}'`); yield (0, exec_1.exec)((0, path_1.join)(graalVMHome, 'bin', `java${c.EXECUTABLE_SUFFIX}`), [ javaVersion.startsWith('8') ? '-version' : '--version' @@ -92864,13 +93200,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? ( }) : function(o, v) { o["default"] = v; }); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { @@ -92881,7 +93227,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }); }; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.stripMandrelNamespace = exports.getLatestMandrelReleaseUrl = exports.setUpMandrel = exports.MANDREL_TAG_PREFIX = exports.MANDREL_REPO = void 0; +exports.MANDREL_TAG_PREFIX = exports.MANDREL_REPO = void 0; +exports.setUpMandrel = setUpMandrel; +exports.getLatestMandrelReleaseUrl = getLatestMandrelReleaseUrl; +exports.stripMandrelNamespace = stripMandrelNamespace; const c = __importStar(__nccwpck_require__(9042)); const httpClient = __importStar(__nccwpck_require__(6255)); const utils_1 = __nccwpck_require__(1314); @@ -92908,7 +93257,6 @@ function setUpMandrel(mandrelVersion, javaVersion) { return mandrelHome; }); } -exports.setUpMandrel = setUpMandrel; function setUpMandrelLatest(javaVersion) { return __awaiter(this, void 0, void 0, function* () { const latest_release_url = yield getLatestMandrelReleaseUrl(javaVersion); @@ -92947,7 +93295,6 @@ function getLatestMandrelReleaseUrl(javaVersion) { } }); } -exports.getLatestMandrelReleaseUrl = getLatestMandrelReleaseUrl; function getLatestMandrelReleaseUrlHelper(_http, java_version, pkg_info_uri) { return __awaiter(this, void 0, void 0, function* () { var _a; @@ -93000,7 +93347,6 @@ function stripMandrelNamespace(graalVMVersion) { return graalVMVersion; } } -exports.stripMandrelNamespace = stripMandrelNamespace; /***/ }), @@ -93026,15 +93372,26 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? ( }) : function(o, v) { o["default"] = v; }); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.setUpWindowsEnvironment = exports.needsWindowsEnvironmentSetup = void 0; +exports.needsWindowsEnvironmentSetup = needsWindowsEnvironmentSetup; +exports.setUpWindowsEnvironment = setUpWindowsEnvironment; const core = __importStar(__nccwpck_require__(2186)); const child_process_1 = __nccwpck_require__(2081); const fs_1 = __nccwpck_require__(7147); @@ -93068,7 +93425,6 @@ function needsWindowsEnvironmentSetup(javaVersion, graalVMVersion, isGraalVMforJ } return true; } -exports.needsWindowsEnvironmentSetup = needsWindowsEnvironmentSetup; function setUpWindowsEnvironment(javaVersion, graalVMVersion, isGraalVMforJDK17OrLater) { if (!needsWindowsEnvironmentSetup(javaVersion, graalVMVersion, isGraalVMforJDK17OrLater)) { return; @@ -93105,7 +93461,6 @@ function setUpWindowsEnvironment(javaVersion, graalVMVersion, isGraalVMforJDK17O } core.endGroup(); } -exports.setUpWindowsEnvironment = setUpWindowsEnvironment; /***/ }), @@ -93131,13 +93486,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? ( }) : function(o, v) { o["default"] = v; }); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { @@ -93148,7 +93513,19 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }); }; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.createPRComment = exports.updatePRComment = exports.findExistingPRCommentId = exports.isPREvent = exports.toSemVer = exports.calculateSHA256 = exports.downloadExtractAndCacheJDK = exports.downloadAndExtractJDK = exports.getMatchingTags = exports.getTaggedRelease = exports.getContents = exports.getLatestRelease = exports.exec = void 0; +exports.exec = exec; +exports.getLatestRelease = getLatestRelease; +exports.getContents = getContents; +exports.getTaggedRelease = getTaggedRelease; +exports.getMatchingTags = getMatchingTags; +exports.downloadAndExtractJDK = downloadAndExtractJDK; +exports.downloadExtractAndCacheJDK = downloadExtractAndCacheJDK; +exports.calculateSHA256 = calculateSHA256; +exports.toSemVer = toSemVer; +exports.isPREvent = isPREvent; +exports.findExistingPRCommentId = findExistingPRCommentId; +exports.updatePRComment = updatePRComment; +exports.createPRComment = createPRComment; const c = __importStar(__nccwpck_require__(9042)); const core = __importStar(__nccwpck_require__(2186)); const github = __importStar(__nccwpck_require__(5438)); @@ -93178,7 +93555,6 @@ function exec(commandLine, args, options) { } }); } -exports.exec = exec; function getLatestRelease(repo) { return __awaiter(this, void 0, void 0, function* () { const githubToken = getGitHubToken(); @@ -93190,7 +93566,6 @@ function getLatestRelease(repo) { })).data; }); } -exports.getLatestRelease = getLatestRelease; function getContents(repo, path) { return __awaiter(this, void 0, void 0, function* () { const githubToken = getGitHubToken(); @@ -93203,7 +93578,6 @@ function getContents(repo, path) { })).data; }); } -exports.getContents = getContents; function getTaggedRelease(owner, repo, tag) { return __awaiter(this, void 0, void 0, function* () { const githubToken = getGitHubToken(); @@ -93216,7 +93590,6 @@ function getTaggedRelease(owner, repo, tag) { })).data; }); } -exports.getTaggedRelease = getTaggedRelease; function getMatchingTags(owner, repo, tagPrefix) { return __awaiter(this, void 0, void 0, function* () { const githubToken = getGitHubToken(); @@ -93229,13 +93602,11 @@ function getMatchingTags(owner, repo, tagPrefix) { })).data; }); } -exports.getMatchingTags = getMatchingTags; function downloadAndExtractJDK(downloadUrl) { return __awaiter(this, void 0, void 0, function* () { return findJavaHomeInSubfolder(yield extract(yield tc.downloadTool(downloadUrl))); }); } -exports.downloadAndExtractJDK = downloadAndExtractJDK; function downloadExtractAndCacheJDK(downloader, toolName, version) { return __awaiter(this, void 0, void 0, function* () { const semVersion = toSemVer(version); @@ -93251,13 +93622,11 @@ function downloadExtractAndCacheJDK(downloader, toolName, version) { return findJavaHomeInSubfolder(toolPath); }); } -exports.downloadExtractAndCacheJDK = downloadExtractAndCacheJDK; function calculateSHA256(filePath) { const hashSum = (0, crypto_1.createHash)('sha256'); hashSum.update((0, fs_1.readFileSync)(filePath)); return hashSum.digest('hex'); } -exports.calculateSHA256 = calculateSHA256; function extract(downloadPath) { return __awaiter(this, void 0, void 0, function* () { if (c.GRAALVM_FILE_EXTENSION === '.tar.gz') { @@ -93297,11 +93666,9 @@ function toSemVer(version) { } return validVersion; } -exports.toSemVer = toSemVer; function isPREvent() { return process.env[c.ENV_GITHUB_EVENT_NAME] === c.EVENT_NAME_PULL_REQUEST; } -exports.isPREvent = isPREvent; function getGitHubToken() { return core.getInput(c.INPUT_GITHUB_TOKEN); } @@ -93325,7 +93692,6 @@ function findExistingPRCommentId(bodyStartsWith) { } }); } -exports.findExistingPRCommentId = findExistingPRCommentId; function updatePRComment(content, commentId) { return __awaiter(this, void 0, void 0, function* () { if (!isPREvent()) { @@ -93339,7 +93705,6 @@ function updatePRComment(content, commentId) { } }); } -exports.updatePRComment = updatePRComment; function createPRComment(content) { return __awaiter(this, void 0, void 0, function* () { var _a; @@ -93355,7 +93720,6 @@ function createPRComment(content) { } }); } -exports.createPRComment = createPRComment; /***/ }), diff --git a/package-lock.json b/package-lock.json index 985ed71..e3e2022 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,6 +17,7 @@ "@actions/http-client": "^2.2.1", "@actions/io": "^1.1.3", "@actions/tool-cache": "^2.0.1", + "@github/dependency-submission-toolkit": "^2.0.4", "@octokit/core": "^5.1.0", "@octokit/types": "^12.6.0", "semver": "^7.6.0", @@ -40,7 +41,7 @@ "prettier": "^3.2.5", "prettier-eslint": "^16.3.0", "ts-jest": "^29.1.2", - "typescript": "^5.3.3" + "typescript": "^5.7.2" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -1136,6 +1137,22 @@ "integrity": "sha512-gIhjdJp/c2beaIWWIlsXdqXVRUz3r2BxBCpfz/F3JXHvSAQ1paMYjLH+maEATtENg+k5eLV7gA+9yPp762ieuw==", "dev": true }, + "node_modules/@github/dependency-submission-toolkit": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@github/dependency-submission-toolkit/-/dependency-submission-toolkit-2.0.4.tgz", + "integrity": "sha512-uQia1YSLTrVmy+f6XpAzy/MEFDvjMg/VOm9pdROxVKQA5SvLXDvXeGgxLwy9fH+sXHqtDWRnVOI1+UAcQ4pi/w==", + "license": "MIT", + "workspaces": [ + "example" + ], + "dependencies": { + "@actions/core": "^1.10.1", + "@actions/github": "^6.0.0", + "@octokit/request-error": "^5.0.1", + "@octokit/webhooks-types": "^7.3.1", + "packageurl-js": "^1.2.1" + } + }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.14", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", @@ -1756,6 +1773,12 @@ "@octokit/openapi-types": "^20.0.0" } }, + "node_modules/@octokit/webhooks-types": { + "version": "7.6.1", + "resolved": "https://registry.npmjs.org/@octokit/webhooks-types/-/webhooks-types-7.6.1.tgz", + "integrity": "sha512-S8u2cJzklBC0FgTwWVLaM8tMrDuDMVE4xiTK4EYXM9GntyvrdbSoxqDQa+Fh57CCNApyIpyeqPhhFEmHPfrXgw==", + "license": "MIT" + }, "node_modules/@opentelemetry/api": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.8.0.tgz", @@ -6356,6 +6379,12 @@ "node": ">=6" } }, + "node_modules/packageurl-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/packageurl-js/-/packageurl-js-1.2.1.tgz", + "integrity": "sha512-cZ6/MzuXaoFd16/k0WnwtI298UCaDHe/XlSh85SeOKbGZ1hq0xvNbx3ILyCMyk7uFQxl6scF3Aucj6/EO9NwcA==", + "license": "MIT" + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -7644,10 +7673,11 @@ } }, "node_modules/typescript": { - "version": "5.4.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz", - "integrity": "sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", + "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", "dev": true, + "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" diff --git a/package.json b/package.json index 72547e0..53c4364 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,7 @@ "@actions/http-client": "^2.2.1", "@actions/io": "^1.1.3", "@actions/tool-cache": "^2.0.1", + "@github/dependency-submission-toolkit": "^2.0.4", "@octokit/core": "^5.1.0", "@octokit/types": "^12.6.0", "semver": "^7.6.0", @@ -58,6 +59,6 @@ "prettier": "^3.2.5", "prettier-eslint": "^16.3.0", "ts-jest": "^29.1.2", - "typescript": "^5.3.3" + "typescript": "^5.7.2" } } diff --git a/src/cleanup.ts b/src/cleanup.ts index 3ed1b0c..4ebd75a 100644 --- a/src/cleanup.ts +++ b/src/cleanup.ts @@ -28,6 +28,7 @@ import * as core from '@actions/core' import * as constants from './constants' import {save} from './features/cache' import {generateReports} from './features/reports' +import {processSBOM} from './features/sbom' /** * Check given input and run a save process for the specified package manager @@ -58,6 +59,7 @@ async function ignoreErrors(promise: Promise): Promise { export async function run(): Promise { await ignoreErrors(generateReports()) + await ignoreErrors(processSBOM()) await ignoreErrors(saveCache()) } diff --git a/src/constants.ts b/src/constants.ts index b3356a0..7b30729 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -14,6 +14,8 @@ export const INPUT_CACHE = 'cache' export const INPUT_CHECK_FOR_UPDATES = 'check-for-updates' export const INPUT_NI_MUSL = 'native-image-musl' +export const NATIVE_IMAGE_OPTIONS_ENV = 'NATIVE_IMAGE_OPTIONS' + export const IS_LINUX = process.platform === 'linux' export const IS_MACOS = process.platform === 'darwin' export const IS_WINDOWS = process.platform === 'win32' diff --git a/src/features/reports.ts b/src/features/reports.ts index fd21fd3..eca3898 100644 --- a/src/features/reports.ts +++ b/src/features/reports.ts @@ -26,7 +26,6 @@ const NATIVE_IMAGE_CONFIG_FILE = join( tmpdir(), 'native-image-options.properties' ) -const NATIVE_IMAGE_OPTIONS_ENV = 'NATIVE_IMAGE_OPTIONS' const NATIVE_IMAGE_CONFIG_FILE_ENV = 'NATIVE_IMAGE_CONFIG_FILE' const PR_COMMENT_TITLE = '## GraalVM Native Image Build Report' @@ -182,11 +181,11 @@ function setNativeImageOption( ) { /* NATIVE_IMAGE_OPTIONS was introduced in GraalVM for JDK 22 (so were EA builds). */ let newOptionValue = optionValue - const existingOptions = process.env[NATIVE_IMAGE_OPTIONS_ENV] + const existingOptions = process.env[c.NATIVE_IMAGE_OPTIONS_ENV] if (existingOptions) { newOptionValue = `${existingOptions} ${newOptionValue}` } - core.exportVariable(NATIVE_IMAGE_OPTIONS_ENV, newOptionValue) + core.exportVariable(c.NATIVE_IMAGE_OPTIONS_ENV, newOptionValue) } else { const optionsFile = getNativeImageOptionsFile() if (fs.existsSync(optionsFile)) { diff --git a/src/features/sbom.ts b/src/features/sbom.ts new file mode 100644 index 0000000..74d785d --- /dev/null +++ b/src/features/sbom.ts @@ -0,0 +1,282 @@ +import * as c from '../constants' +import * as core from '@actions/core' +import * as fs from 'fs' +import * as github from '@actions/github' +import * as glob from '@actions/glob' +import {basename} from 'path' + +export const INPUT_NI_SBOM = 'native-image-enable-sbom' +export const SBOM_FILE_SUFFIX = '.sbom.json' + +export function setUpSBOMSupport(): void { + const isSbomEnabled = core.getInput(INPUT_NI_SBOM) === 'true' + if (!isSbomEnabled) { + return + } + + let options = process.env[c.NATIVE_IMAGE_OPTIONS_ENV] || '' + if (options.length > 0) { + options += ' ' + } + options += '--enable-sbom=export' + core.exportVariable(c.NATIVE_IMAGE_OPTIONS_ENV, options) + core.info('Enabled SBOM generation for Native Image builds') +} + +export async function processSBOM(): Promise { + const isSbomEnabled = core.getInput(INPUT_NI_SBOM) === 'true' + if (!isSbomEnabled) { + return + } + + const sbomPath = await findSBOMFilePath() + if (!sbomPath) { + return + } + + try { + const sbomContent = fs.readFileSync(sbomPath, 'utf8') + const sbomData = parseSBOM(sbomContent) + if (!sbomData) { + return + } + + const components = mapToComponentsWithDependencies(sbomData) + if (components.length === 0) { + return + } + + printSBOMContent(components) + const snapshot = convertSBOMToSnapshot(sbomPath, components) + if (snapshot) { + await submitDependencySnapshot(snapshot) + } + } catch (error) { + core.warning( + `Failed to process SBOM file: ${error instanceof Error ? error.message : String(error)}` + ) + } +} + +async function findSBOMFilePath(): Promise { + const globber = await glob.create(`**/*${SBOM_FILE_SUFFIX}`) + const sbomFiles = await globber.glob() + + if (sbomFiles.length === 0) { + logSkippingSubmission( + 'No SBOM file found. Make sure native-image build completed successfully.' + ) + return null + } + + if (sbomFiles.length > 1) { + logSkippingSubmission(`Found multiple SBOM files: ${sbomFiles.join(', ')}.`) + return null + } + + core.info(`Found SBOM file: ${sbomFiles[0]}`) + return sbomFiles[0] +} + +function parseSBOM(jsonString: string): SBOM | null { + try { + const sbomData: SBOM = JSON.parse(jsonString) + return sbomData + } catch (error) { + core.warning( + `Failed to parse SBOM JSON: ${error instanceof Error ? error.message : String(error)}` + ) + return null + } +} + +// Maps the SBOM data to a list of components with their dependencies +export function mapToComponentsWithDependencies(sbom: SBOM): Component[] { + if (!sbom || sbom.components.length === 0) { + logSkippingSubmission('Invalid SBOM data or no components found.') + return [] + } + + return sbom.components.map((component: Component) => { + const dependencies = + sbom.dependencies?.find( + (dep: Dependency) => dep.ref === component['bom-ref'] + )?.dependsOn || [] + + return { + name: component.name, + version: component.version, + purl: component.purl, + dependencies, + 'bom-ref': component['bom-ref'] + } + }) +} + +function printSBOMContent(components: Component[]): void { + core.info('=== SBOM Content ===') + + for (const component of components) { + core.info(`- ${component['bom-ref']}`) + if (component.dependencies && component.dependencies.length > 0) { + core.info(` depends on: ${component.dependencies.join(', ')}`) + } + } + + core.info('==================') +} + +function mapToSnapshotResolved( + components: Component[] +): Record { + return Object.fromEntries( + components + .filter(component => { + if (!component.purl) { + core.info( + `Component ${component.name} does not have a valid package URL (purl). Skipping.` + ) + } + return component.purl + }) + .map(component => [ + component.name, + { + package_url: component.purl as string, + dependencies: component.dependencies || [] + } + ]) + ) +} + +function convertSBOMToSnapshot( + sbomPath: string, + components: Component[] +): DependencySnapshot | null { + const context = github.context + const sbomFileName = basename(sbomPath) + + if (!sbomFileName.endsWith(SBOM_FILE_SUFFIX)) { + logSkippingSubmission( + `Invalid SBOM file name: ${sbomFileName}. Expected a file ending with ${SBOM_FILE_SUFFIX}.` + ) + return null + } + + return { + version: 0, + sha: context.sha, + ref: context.ref, + job: { + correlator: `${context.workflow}_${context.job}`, + id: context.runId.toString(), + html_url: `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}` + }, + detector: { + name: 'graalvm-native-image', + version: c.ACTION_VERSION, + url: 'https://github.com/graalvm/setup-graalvm' + }, + scanned: new Date().toISOString(), + manifests: { + [sbomFileName]: { + name: sbomFileName, + resolved: mapToSnapshotResolved(components), + metadata: { + generated_by: 'SBOM generated by GraalVM Native Image', + action_version: c.ACTION_VERSION + } + } + } + } +} + +async function submitDependencySnapshot( + snapshotData: DependencySnapshot +): Promise { + const token = core.getInput(c.INPUT_GITHUB_TOKEN, {required: true}) + const octokit = github.getOctokit(token) + const context = github.context + + try { + await octokit.request( + 'POST /repos/{owner}/{repo}/dependency-graph/snapshots', + { + owner: context.repo.owner, + repo: context.repo.repo, + version: snapshotData.version, + sha: snapshotData.sha, + ref: snapshotData.ref, + job: snapshotData.job, + detector: snapshotData.detector, + metadata: {}, + scanned: snapshotData.scanned, + manifests: snapshotData.manifests, + headers: { + 'X-GitHub-Api-Version': '2022-11-28' + } + } + ) + core.info('Dependency snapshot submitted successfully.') + } catch (error) { + core.warning( + `Failed to submit dependency snapshot for SBOM: ${error instanceof Error ? error.message : String(error)}` + ) + } +} + +interface SBOM { + components: Component[] + dependencies: Dependency[] +} + +interface Component { + name: string + version?: string + purl?: string + dependencies?: string[] + 'bom-ref': string +} + +interface Dependency { + ref: string + dependsOn: string[] +} + +interface DependencySnapshot { + version: number + sha: string + ref: string + job: { + correlator: string + id: string + html_url?: string + } + detector: { + name: string + version: string + url: string + } + scanned: string + manifests: Record< + string, + { + name: string + metadata?: Record + // Not including the file property since we cannot use any reasonable value for "source_location" + resolved: Record< + string, + { + package_url: string + relationship?: 'direct' | 'indirect' + scope?: 'runtime' | 'development' + dependencies?: string[] + } + > + } + > +} + +function logSkippingSubmission(prefix: string): void { + core.warning(`${prefix} Skipping submission to GitHub Dependency API.`) +} diff --git a/src/main.ts b/src/main.ts index 7f32b82..7ec1f00 100644 --- a/src/main.ts +++ b/src/main.ts @@ -14,6 +14,7 @@ import {setUpNativeImageMusl} from './features/musl' import {setUpWindowsEnvironment} from './msvc' import {setUpNativeImageBuildReports} from './features/reports' import {exec} from '@actions/exec' +import {setUpSBOMSupport} from './features/sbom' async function run(): Promise { try { @@ -148,7 +149,6 @@ async function run(): Promise { if (setJavaHome) { core.exportVariable('JAVA_HOME', graalVMHome) } - await setUpGUComponents( javaVersion, graalVMVersion, @@ -166,6 +166,8 @@ async function run(): Promise { graalVMVersion ) + setUpSBOMSupport() + core.startGroup(`Successfully set up '${basename(graalVMHome)}'`) await exec(join(graalVMHome, 'bin', `java${c.EXECUTABLE_SUFFIX}`), [ javaVersion.startsWith('8') ? '-version' : '--version'