From baeebefede25317304df7770562459e2229ad312 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 16 Nov 2024 13:16:57 +1300 Subject: [PATCH 01/10] Bump github/codeql-action from 3.27.3 to 3.27.4 (#4042) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.27.3 to 3.27.4. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/396bb3e45325a47dd9ef434068033c6d5bb0d11a...ea9e4e37992a54ee68a9622e985e60c8e8f12d9f) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql.yml | 6 +++--- .github/workflows/ossf-scorecard.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 3522f6533..a89e74289 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -58,7 +58,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@396bb3e45325a47dd9ef434068033c6d5bb0d11a # v3.27.3 + uses: github/codeql-action/init@ea9e4e37992a54ee68a9622e985e60c8e8f12d9f # v3.27.4 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -68,7 +68,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@396bb3e45325a47dd9ef434068033c6d5bb0d11a # v3.27.3 + uses: github/codeql-action/autobuild@ea9e4e37992a54ee68a9622e985e60c8e8f12d9f # v3.27.4 # ℹī¸ Command-line programs to run using the OS shell. # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun @@ -81,6 +81,6 @@ jobs: # ./location_of_script_within_repo/buildscript.sh - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@396bb3e45325a47dd9ef434068033c6d5bb0d11a # v3.27.3 + uses: github/codeql-action/analyze@ea9e4e37992a54ee68a9622e985e60c8e8f12d9f # v3.27.4 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/ossf-scorecard.yml b/.github/workflows/ossf-scorecard.yml index 64e2de24c..226a9e008 100644 --- a/.github/workflows/ossf-scorecard.yml +++ b/.github/workflows/ossf-scorecard.yml @@ -46,6 +46,6 @@ jobs: name: SARIF file path: results.sarif retention-days: 5 - - uses: github/codeql-action/upload-sarif@396bb3e45325a47dd9ef434068033c6d5bb0d11a # v2.13.4 + - uses: github/codeql-action/upload-sarif@ea9e4e37992a54ee68a9622e985e60c8e8f12d9f # v2.13.4 with: sarif_file: results.sarif From 78e698069bddcb702cdfb85e5380e160393b727d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 16 Nov 2024 13:17:16 +1300 Subject: [PATCH 02/10] Bump gr2m/create-or-update-pull-request-action from 1.10.0 to 1.10.1 (#4041) Bumps [gr2m/create-or-update-pull-request-action](https://github.com/gr2m/create-or-update-pull-request-action) from 1.10.0 to 1.10.1. - [Release notes](https://github.com/gr2m/create-or-update-pull-request-action/releases) - [Commits](https://github.com/gr2m/create-or-update-pull-request-action/compare/488876a65a2ca38b7eb05e9086166337087f5323...b65137ca591da0b9f43bad7b24df13050ea45d1b) --- updated-dependencies: - dependency-name: gr2m/create-or-update-pull-request-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ca-cert-updater.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ca-cert-updater.yml b/.github/workflows/ca-cert-updater.yml index 71419dc9f..cfc616c39 100644 --- a/.github/workflows/ca-cert-updater.yml +++ b/.github/workflows/ca-cert-updater.yml @@ -35,7 +35,7 @@ jobs: working-directory: ./security run: "./mk-ca-bundle.pl" - - uses: gr2m/create-or-update-pull-request-action@488876a65a2ca38b7eb05e9086166337087f5323 # v1.10.0 + - uses: gr2m/create-or-update-pull-request-action@b65137ca591da0b9f43bad7b24df13050ea45d1b # v1.10.1 env: GITHUB_TOKEN: ${{ secrets.ADOPTIUM_TEMURIN_BOT_TOKEN }} with: From 78a484c88e01045073e8a81326bc664c63787471 Mon Sep 17 00:00:00 2001 From: Severin Gehwolf Date: Sat, 16 Nov 2024 01:19:36 +0100 Subject: [PATCH 03/10] Add smoke test for enabled JEP 493 for Eclipse Temurin builds (#4040) * Add smoke test for linkable runtime * Fix linting errors * More linter fixes --- .../src/net/adoptium/test/FeatureTests.java | 83 ++++++++++++++++--- 1 file changed, 70 insertions(+), 13 deletions(-) diff --git a/test/functional/buildAndPackage/src/net/adoptium/test/FeatureTests.java b/test/functional/buildAndPackage/src/net/adoptium/test/FeatureTests.java index 6c22f83e6..976e92b74 100644 --- a/test/functional/buildAndPackage/src/net/adoptium/test/FeatureTests.java +++ b/test/functional/buildAndPackage/src/net/adoptium/test/FeatureTests.java @@ -15,12 +15,15 @@ package net.adoptium.test; +import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.Locale; import java.util.logging.Logger; +import java.util.regex.Pattern; import static net.adoptium.test.JdkPlatform.Architecture; import static net.adoptium.test.JdkPlatform.OperatingSystem; @@ -40,6 +43,71 @@ public class FeatureTests { private final JdkPlatform jdkPlatform = new JdkPlatform(); + private String testJdkHome = null; + + /** + * Ensure TEST_JDK_HOME environment variable is set for every test in this class. + */ + @BeforeTest + public final void ensureTestJDKSet() { + String tmpJdkHome = System.getenv("TEST_JDK_HOME"); + if (tmpJdkHome == null) { + throw new AssertionError("TEST_JDK_HOME is not set"); + } + this.testJdkHome = tmpJdkHome; + } + + /** + * Tests whether JEP 493 is enabled for Eclipse Temurin builds. + * + * @see JEP 493: Linking Run-Time Images without JMODs + */ + @Test + public void testLinkableRuntimeJDK24Plus() { + // Only JDK 24 and better and temurin builds have this enabled + if (jdkVersion.isNewerOrEqual(24) && isVendorAdoptium()) { + List command = new ArrayList<>(); + command.add(String.format("%s/bin/jlink", testJdkHome)); + command.add("-J-Duser.lang=en"); + command.add("--help"); + + try { + ProcessBuilder processBuilder = new ProcessBuilder(command); + Process process = processBuilder.start(); + + String stdout = StreamUtils.consumeStream(process.getInputStream()); + if (process.waitFor() != 0) { + throw new AssertionError("Could not run jlink --help"); + } + String[] lines = stdout.split(Pattern.quote(System.lineSeparator())); + boolean seenCapabilities = false; + String capLine = ""; + for (int i = 0; i < lines.length; i++) { + if (lines[i].trim().startsWith("Capabilities:")) { + seenCapabilities = true; + continue; // skip Capabilities line + } + if (!seenCapabilities) { + continue; + } + if (seenCapabilities) { + capLine = lines[i].trim(); + break; + } + } + LOGGER.info(String.format("Matched 'Capabilities:' line: %s", capLine)); + assertEquals(capLine, "Linking from run-time image enabled", + "jlink should have enabled run-time image link capability"); + } catch (InterruptedException | IOException e) { + throw new RuntimeException("Failed to launch JVM", e); + } + } + } + + private boolean isVendorAdoptium() { + return System.getProperty("java.vendor", "").toLowerCase(Locale.US).contains("adoptium"); + } + /** * Tests whether Shenandoah GC is available. *

@@ -53,10 +121,6 @@ public class FeatureTests { */ @Test public void testShenandoahAvailable() { - String testJdkHome = System.getenv("TEST_JDK_HOME"); - if (testJdkHome == null) { - throw new AssertionError("TEST_JDK_HOME is not set"); - } boolean shouldBePresent = false; if ((jdkVersion.isNewerOrEqual(15) || jdkVersion.isNewerOrEqualSameFeature(11, 0, 9))) { @@ -73,7 +137,7 @@ public void testShenandoahAvailable() { } } if (jdkVersion.isNewerOrEqual(17) && jdkPlatform.runsOn(OperatingSystem.LINUX, Architecture.PPC64LE)) { - shouldBePresent = true; + shouldBePresent = true; } if (jdkVersion.isNewerOrEqual(19) || jdkVersion.isNewerOrEqualSameFeature(17, 0, 9) @@ -116,10 +180,6 @@ public void testShenandoahAvailable() { */ @Test public void testZGCAvailable() { - String testJdkHome = System.getenv("TEST_JDK_HOME"); - if (testJdkHome == null) { - throw new AssertionError("TEST_JDK_HOME is not set"); - } boolean shouldBePresent = false; if (jdkVersion.isNewerOrEqual(15)) { @@ -184,10 +244,6 @@ public void testZGCAvailable() { */ @Test public void testJFRAvailable() { - String testJdkHome = System.getenv("TEST_JDK_HOME"); - if (testJdkHome == null) { - throw new AssertionError("TEST_JDK_HOME is not set"); - } boolean shouldBePresent = false; if (jdkVersion.isNewerOrEqual(11) || jdkVersion.isNewerOrEqualSameFeature(8, 0, 262)) { if (!jdkPlatform.runsOn(OperatingSystem.AIX) || jdkVersion.isNewerOrEqual(20)) { @@ -213,4 +269,5 @@ public void testJFRAvailable() { throw new RuntimeException("Failed to launch JVM", e); } } + } From aa3791ff2edc82fcca9a8f747f6a2578d675c684 Mon Sep 17 00:00:00 2001 From: Severin Gehwolf Date: Mon, 18 Nov 2024 15:15:04 +0100 Subject: [PATCH 04/10] Add --enable-linkable-runtime for JDK 24+ (#4039) For JDK's including JEP 493, enable the build option for producing a jlink that is capable of linking from the run-time image. Closes #4035 --- sbin/build.sh | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/sbin/build.sh b/sbin/build.sh index 27a314f9f..14c8ffbac 100755 --- a/sbin/build.sh +++ b/sbin/build.sh @@ -174,6 +174,17 @@ configureMacOSCodesignParameter() { fi } +# JDK 24+ includes JEP 493 which allows for the JDK to enable +# linking from the run-time image (instead of only from JMODs). Enable +# this option. This has the effect, that no 'jmods' directory will be +# produced in the resulting build. Thus, the tarball and, especially the +# extracted tarball will be smaller in terms of disk space size. +configureLinkableRuntimeParameter() { + if [[ "${BUILD_CONFIG[OPENJDK_FEATURE_NUMBER]}" -ge 24 ]]; then + addConfigureArg "--enable-linkable-runtime" "" + fi +} + # Get the OpenJDK update version and build version getOpenJDKUpdateAndBuildVersion() { cd "${BUILD_CONFIG[WORKSPACE_DIR]}/${BUILD_CONFIG[WORKING_DIR]}" @@ -574,6 +585,7 @@ configureCommandParameters() { configureVersionStringParameter configureBootJDKConfigureParameter configureDevKitConfigureParameter + configureLinkableRuntimeParameter configureShenandoahBuildParameter configureMacOSCodesignParameter configureDebugParameters From 8b302cf968636070e4adeb6efa131d66f20631a7 Mon Sep 17 00:00:00 2001 From: Andrew Leonard <31470007+andrew-m-leonard@users.noreply.github.com> Date: Tue, 19 Nov 2024 14:43:47 +0000 Subject: [PATCH 05/10] Update RELEASING doc with comment about auto-disabling of testing (#4048) Signed-off-by: Andrew Leonard --- RELEASING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RELEASING.md b/RELEASING.md index 5c6ec42db..c17e36ea6 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -149,7 +149,7 @@ flowchart TD -Disable nightly testing so the release builds aren't delayed by any nightly test runs (set `enableTests : false` in [defaults.json](https://github.com/adoptium/ci-jenkins-pipelines/blob/master/pipelines/defaults.json)). Ensure the build pipeline generator job runs successfully (), and the flag is disabled by bringing up the Build pipeline job and check the `enableTests` checkbox is unticked. +Scheduled pipeline Testing is automatically disabled from the Saturday prior to "release Tuesday", to the Sunday after, see: https://github.com/adoptium/ci-jenkins-pipelines/blob/5bd79eb1d95a033c4ee364a8f9fcc270ad653178/pipelines/build/common/trigger_beta_build.groovy#L51 Add a banner to the website to indicate that the releases are coming in the near future ([Example Changes](https://github.com/adoptium/adoptium.net/blob/main/src/components/Banner.tsx)). From 2144411c18db3d057b5b159cade179f70164e56b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 Nov 2024 21:00:03 +1300 Subject: [PATCH 06/10] Bump github/codeql-action from 3.27.4 to 3.27.5 (#4049) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.27.4 to 3.27.5. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/ea9e4e37992a54ee68a9622e985e60c8e8f12d9f...f09c1c0a94de965c15400f5634aa42fac8fb8f88) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql.yml | 6 +++--- .github/workflows/ossf-scorecard.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index a89e74289..a23b92de7 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -58,7 +58,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@ea9e4e37992a54ee68a9622e985e60c8e8f12d9f # v3.27.4 + uses: github/codeql-action/init@f09c1c0a94de965c15400f5634aa42fac8fb8f88 # v3.27.5 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -68,7 +68,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@ea9e4e37992a54ee68a9622e985e60c8e8f12d9f # v3.27.4 + uses: github/codeql-action/autobuild@f09c1c0a94de965c15400f5634aa42fac8fb8f88 # v3.27.5 # ℹī¸ Command-line programs to run using the OS shell. # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun @@ -81,6 +81,6 @@ jobs: # ./location_of_script_within_repo/buildscript.sh - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@ea9e4e37992a54ee68a9622e985e60c8e8f12d9f # v3.27.4 + uses: github/codeql-action/analyze@f09c1c0a94de965c15400f5634aa42fac8fb8f88 # v3.27.5 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/ossf-scorecard.yml b/.github/workflows/ossf-scorecard.yml index 226a9e008..bcb2d44cb 100644 --- a/.github/workflows/ossf-scorecard.yml +++ b/.github/workflows/ossf-scorecard.yml @@ -46,6 +46,6 @@ jobs: name: SARIF file path: results.sarif retention-days: 5 - - uses: github/codeql-action/upload-sarif@ea9e4e37992a54ee68a9622e985e60c8e8f12d9f # v2.13.4 + - uses: github/codeql-action/upload-sarif@f09c1c0a94de965c15400f5634aa42fac8fb8f88 # v2.13.4 with: sarif_file: results.sarif From 4a141b1fad22bfcf2d6eb075ac9b01d394e544e7 Mon Sep 17 00:00:00 2001 From: Scott Fryer <60462088+steelhead31@users.noreply.github.com> Date: Wed, 27 Nov 2024 22:25:31 +0000 Subject: [PATCH 07/10] Doc: Update Executing Smoke Tests Document (#4060) * Doc: Update Executing Smoke Tests Document * Fix typo --- SmokeTesting.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/SmokeTesting.md b/SmokeTesting.md index f3179a09e..a57b0f26a 100644 --- a/SmokeTesting.md +++ b/SmokeTesting.md @@ -7,8 +7,9 @@ These are the general steps to execute the Smoke Tests found in[/test/functional 1. export TEST_JDK_HOME=/someLocation // set test JDK home. On windows, the windows path format is expected. (i.e., TEST_JDK_HOME=C:\someLocation ) 1. git clone [https://github.com/adoptium/aqa-tests.git](https://github.com/adoptium/aqa-tests) to /testLocation 1. cd aqa-tests -1. ./get.sh +1. ./get.sh --vendor_repos https://github.com/adoptium/temurin-build --vendor_branches master --vendor_dirs /test/functional +1. ( When running get.sh ensure the vendor parameters are passed correctly, the above example shows how to run the smoke tests contained within the temurin-build repository ) 1. cd TKG -1. Export environment variables suitable for the SDK under test and for the test materials being used (i.e., export BUILD_LIST=functional/buildAndPackage, VENDOR_TEST_REPOS=https://github.com/adoptium/temurin-build, VENDOR_TEST_BRANCHES=master, VENDOR_TEST_DIRS=/test/functional ) +1. Export environment variables suitable for the SDK under test and for the test materials being used (i.e., export BUILD_LIST=functional/buildAndPackage, this value details which test material that should be compiled. 1. make compile // fetches test material and compiles it, based on build.xml files in the test directories 1. make _extended.functional // executes the test target (can be test group, level, level.group or specific test). i.e., openjdk (all tests in openjdk group), sanity.functional (all functional tests labelled at sanity level), or in the case of smoke tests which are all tagged to belong to level=extended and group=functional, we use `_extended.functional` and because we have limited BUILD_LIST to the directory where the smoke test material lives, we will only run tests from that directory tagged as extended.functional. From ed07fcfa4f847897a39758c116fe7279b55eacfa Mon Sep 17 00:00:00 2001 From: Andrew Leonard <31470007+andrew-m-leonard@users.noreply.github.com> Date: Mon, 2 Dec 2024 13:32:31 +0000 Subject: [PATCH 08/10] github build actions on Linux failing due to Node16 runner removal (#4064) * PR TEST Signed-off-by: Andrew Leonard * PR TEST Signed-off-by: Andrew Leonard * PR TEST Signed-off-by: Andrew Leonard * PR TEST Signed-off-by: Andrew Leonard * PR TEST Signed-off-by: Andrew Leonard * PR TEST Signed-off-by: Andrew Leonard * PR TEST Signed-off-by: Andrew Leonard * PR TEST Signed-off-by: Andrew Leonard * Fix Node20 error starting docker container Signed-off-by: Andrew Leonard * Fix Node20 error starting docker container Signed-off-by: Andrew Leonard * Fix Node20 error starting docker container Signed-off-by: Andrew Leonard * Fix Node20 error starting docker container Signed-off-by: Andrew Leonard * Fix Node20 error starting docker container Signed-off-by: Andrew Leonard * Fix Node20 error starting docker container Signed-off-by: Andrew Leonard * Fix Node20 error starting docker container Signed-off-by: Andrew Leonard * Fix Node20 error starting docker container Signed-off-by: Andrew Leonard * Fix Node20 error starting docker container Signed-off-by: Andrew Leonard * Fix Node20 error starting docker container Signed-off-by: Andrew Leonard * Fix Node20 error starting docker container Signed-off-by: Andrew Leonard * Fix Node20 error starting docker container Signed-off-by: Andrew Leonard * Fix Node20 error starting docker container Signed-off-by: Andrew Leonard * Fix Node20 error starting docker container Signed-off-by: Andrew Leonard * Fix Node20 error starting docker container Signed-off-by: Andrew Leonard * Fix Node20 error starting docker container Signed-off-by: Andrew Leonard * Fix Node20 error starting docker container Signed-off-by: Andrew Leonard * Fix Node20 error starting docker container Signed-off-by: Andrew Leonard * Fix Node20 error starting docker container Signed-off-by: Andrew Leonard * Fix Node20 error starting docker container Signed-off-by: Andrew Leonard * Fix Node20 error starting docker container Signed-off-by: Andrew Leonard * Fix Node20 error starting docker container Signed-off-by: Andrew Leonard * Fix Node20 error starting docker container Signed-off-by: Andrew Leonard * Fix Node20 error starting docker container Signed-off-by: Andrew Leonard * Fix Node20 error starting docker container Signed-off-by: Andrew Leonard * Fix Node20 error starting docker container Signed-off-by: Andrew Leonard --------- Signed-off-by: Andrew Leonard --- .github/workflows/build.yml | 73 +++++++++++++++++++++---------------- 1 file changed, 42 insertions(+), 31 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 11a7ffd93..b5fb32a3f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -35,10 +35,6 @@ jobs: build_linux: name: Linux runs-on: ubuntu-latest - env: - ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: 'true' - container: - image: ${{ matrix.image }} strategy: fail-fast: false matrix: @@ -80,24 +76,23 @@ jobs: variant: bisheng image: adoptopenjdk/centos7_build_image steps: - # pinned at v3 to as Node.js 20.x is not supported on Centos 7 - - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 + - uses: actions/checkout@v4 - - name: Build Linux - run: ./build-farm/make-adopt-build-farm.sh - env: - JAVA_TO_BUILD: ${{ matrix.version }} - ARCHITECTURE: x64 - VARIANT: ${{ matrix.variant }} - TARGET_OS: ${{ matrix.os }} - FILENAME: OpenJDK.tar.gz - # Don't set the OS as we use both linux and alpine-linux - PLATFORM_CONFIG_LOCATION: adoptium/temurin-build/master/build-farm/platform-specific-configurations - BUILD_ARGS: --create-sbom - CONFIGURE_ARGS: --with-native-debug-symbols=none - - # pinned at v3 to as Node.js 20.x is not supported on Centos 7 - - uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 + - name: Build Linux within container image "${{ matrix.image }}" + run: | + docker run --rm -w /home/jenkins -v "$PWD":"/home/jenkins" \ + -e "JAVA_TO_BUILD=${{ matrix.version }}" \ + -e "ARCHITECTURE=x64" \ + -e "VARIANT=${{ matrix.variant }}" \ + -e "TARGET_OS=${{ matrix.os }}" \ + -e "FILENAME=OpenJDK.tar.gz" \ + -e "PLATFORM_CONFIG_LOCATION=adoptium/temurin-build/master/build-farm/platform-specific-configurations" \ + -e "BUILD_ARGS=--create-sbom" \ + -e "CONFIGURE_ARGS=--with-native-debug-symbols=none" \ + "${{ matrix.image }}" \ + ./build-farm/make-adopt-build-farm.sh + + - uses: actions/upload-artifact@v4 name: Collect and Archive Artifacts with: name: ${{matrix.version}}-${{matrix.os}}-${{matrix.variant}} @@ -110,17 +105,33 @@ jobs: - name: Set root of jdk image dir run: | imageroot=$(find "${HOME}/JDK" -name release -type f) - echo "TEST_JDK_HOME=$(dirname "${imageroot}")" >> "$GITHUB_ENV" - - name: Smoke test - uses: adoptium/run-aqa@6bacb4e732ad546eda1b09665b9067cdc87651f4 # v2 + # TEST_JDK_HOME needs to be mapped to the docker container /home/jenkins mapping + echo "TEST_JDK_HOME=$(dirname "${imageroot}")" | sed "s,${HOME},/home/jenkins," >> "$GITHUB_ENV" + + - name: Checkout aqa-tests repo + uses: actions/checkout@v4 with: - build_list: 'functional/buildAndPackage' - target: '_extended.functional' - vendor_testRepos: "${{ github.event.pull_request.head.repo.html_url }}.git" - vendor_testBranches: "${{ github.head_ref }}" - vendor_testDirs: "/test/functional" - # pinned at v3 to as Node.js 20.x is not supported on Centos 7 - - uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 + repository: adoptium/aqa-tests + path: aqa-tests + - name: Run Smoke test within container image "${{ matrix.image }}" + env: + VENDOR_REPOS: ${{ github.event.pull_request.head.repo.html_url }}.git + VENDOR_BRANCH: ${{ github.head_ref }} + run: | + WORK_DIR="${PWD//${HOME}//home/jenkins}" + docker run --rm -w /home/jenkins -v "$HOME":"/home/jenkins" \ + -e "TEST_JDK_HOME=${TEST_JDK_HOME}" \ + -e "BUILD_LIST=functional/buildAndPackage" \ + "${{ matrix.image }}" \ + sh -c "cd ${WORK_DIR}/aqa-tests && \ + ./get.sh --vendor_repos ${VENDOR_REPOS} \ + --vendor_branches ${VENDOR_BRANCH} \ + --vendor_dirs /test/functional && \ + cd TKG && \ + make compile && \ + make _extended.functional" + + - uses: actions/upload-artifact@v4 name: Collect and Archive SmokeTest Results if: failure() with: From 71d1cd5bf4f31614818a2d411222223c09dc1527 Mon Sep 17 00:00:00 2001 From: Adam Farley Date: Tue, 3 Dec 2024 06:50:21 +0000 Subject: [PATCH 09/10] Adding windows aarch64 to the list of platforms to be triaged (#4070) Signed-off-by: Adam Farley --- tooling/build_autotriage/build_autotriage.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/tooling/build_autotriage/build_autotriage.sh b/tooling/build_autotriage/build_autotriage.sh index 27bd40772..5445f050f 100644 --- a/tooling/build_autotriage/build_autotriage.sh +++ b/tooling/build_autotriage/build_autotriage.sh @@ -59,6 +59,7 @@ temurinPlatforms+=("mac-aarch64"); platformStart+=(11); platformEnd+=(9 temurinPlatforms+=("mac-x64"); platformStart+=(8); platformEnd+=(99) temurinPlatforms+=("solaris-sparcv9"); platformStart+=(8); platformEnd+=(8) temurinPlatforms+=("solaris-x64"); platformStart+=(8); platformEnd+=(8) +temurinPlatforms+=("windows-aarch64"); platformStart+=(21); platformEnd+=(99) temurinPlatforms+=("windows-x64"); platformStart+=(8); platformEnd+=(99) temurinPlatforms+=("windows-x86-32"); platformStart+=(8); platformEnd+=(17) From ededebcd82709a4f58c74642c99571bff2a9b8ae Mon Sep 17 00:00:00 2001 From: Andrew Leonard <31470007+andrew-m-leonard@users.noreply.github.com> Date: Tue, 3 Dec 2024 07:02:23 +0000 Subject: [PATCH 10/10] CDXA XML and JSON support for temurin-build cyclonedx Java client (#4063) * Initial CDXA support Signed-off-by: Andrew Leonard * Initial CDXA support Signed-off-by: Andrew Leonard * Initial CDXA support Signed-off-by: Andrew Leonard * Initial CDXA support Signed-off-by: Andrew Leonard * Initial CDXA support Signed-off-by: Andrew Leonard * Initial CDXA support Signed-off-by: Andrew Leonard * Initial CDXA support Signed-off-by: Andrew Leonard * Initial CDXA support Signed-off-by: Andrew Leonard * Initial CDXA support Signed-off-by: Andrew Leonard * Initial CDXA support Signed-off-by: Andrew Leonard * Initial CDXA support Signed-off-by: Andrew Leonard * Initial CDXA support Signed-off-by: Andrew Leonard * Initial CDXA support Signed-off-by: Andrew Leonard * Initial CDXA support Signed-off-by: Andrew Leonard --------- Signed-off-by: Andrew Leonard --- .github/linters/.gitleaks.toml | 5 + .github/linters/suppressed-java.xml | 3 +- .../{testsbom.yml => testcyclonedx.yml} | 33 +- cyclonedx-lib/build.xml | 381 +++++++++++++++++- .../dependency_data.properties | 16 +- cyclonedx-lib/sign_src/TemurinSignSBOM.java | 4 +- .../src/temurin/sbom/TemurinGenCDXA.java | 336 +++++++++++++++ .../src/temurin/sbom/TemurinGenSBOM.java | 149 ++++--- sbin/common/sbom.sh | 15 - 9 files changed, 847 insertions(+), 95 deletions(-) create mode 100644 .github/linters/.gitleaks.toml rename .github/workflows/{testsbom.yml => testcyclonedx.yml} (52%) create mode 100644 cyclonedx-lib/src/temurin/sbom/TemurinGenCDXA.java diff --git a/.github/linters/.gitleaks.toml b/.github/linters/.gitleaks.toml new file mode 100644 index 000000000..6012aaeb6 --- /dev/null +++ b/.github/linters/.gitleaks.toml @@ -0,0 +1,5 @@ +title = "gitleaks config" +[allowlist] +files = [ + "cyclonedx-lib/dependency_data/dependency_data.properties" +] diff --git a/.github/linters/suppressed-java.xml b/.github/linters/suppressed-java.xml index b9c1a256e..0acb11e80 100644 --- a/.github/linters/suppressed-java.xml +++ b/.github/linters/suppressed-java.xml @@ -28,4 +28,5 @@ - \ No newline at end of file + + diff --git a/.github/workflows/testsbom.yml b/.github/workflows/testcyclonedx.yml similarity index 52% rename from .github/workflows/testsbom.yml rename to .github/workflows/testcyclonedx.yml index 073411098..f4f5703d9 100644 --- a/.github/workflows/testsbom.yml +++ b/.github/workflows/testcyclonedx.yml @@ -1,5 +1,5 @@ # ******************************************************************************** -# Copyright (c) 2023 Contributors to the Eclipse Foundation +# Copyright (c) 2023, 2024 Contributors to the Eclipse Foundation # # See the NOTICE file(s) with this work for additional # information regarding copyright ownership. @@ -12,7 +12,7 @@ # ******************************************************************************** --- -name: TestSBOM +name: TestCycloneDX on: pull_request: @@ -30,21 +30,21 @@ permissions: contents: read jobs: - test_sbom_gen: - name: gen_sbom + test_cyclonedx_gen: + name: gen_cyclonedx runs-on: ubuntu-latest steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - # Build with jdk8 to ensure TemurinGenSBOM meets min compatibility + # Build with jdk8 to ensure TemurinGen* meets min compatibility - uses: actions/setup-java@8df1039502a15bceb9433410b1a100fbe190c53b # v4.5.0 id: setup-java with: java-version: 8 distribution: 'temurin' - - name: Build TemurinGenSBOM.java + - name: Build TemurinGenSBOM.java and TemurinGenCDXA.java run: | ant -noinput -buildfile cyclonedx-lib/build.xml clean ant -noinput -buildfile cyclonedx-lib/build.xml build @@ -52,8 +52,27 @@ jobs: - name: Run TemurinGenSBOM Unit test run: ant -noinput -buildfile cyclonedx-lib/build.xml run + - name: Run TemurinGenCDXA Unit test + run: ant -noinput -buildfile cyclonedx-lib/build.xml runCDXA + + - name: Validate generated SBOM and CDXA documents using cyclonedx-cli validate + run: | + curl -L -O https://github.com/CycloneDX/cyclonedx-cli/releases/latest/download/cyclonedx-linux-x64 + chmod +x cyclonedx-linux-x64 + ./cyclonedx-linux-x64 validate --input-file cyclonedx-lib/build/testSBOM.json --fail-on-errors --input-version v1_6 + ./cyclonedx-linux-x64 validate --input-file cyclonedx-lib/build/testSBOM.xml --fail-on-errors --input-version v1_6 + ./cyclonedx-linux-x64 validate --input-file cyclonedx-lib/build/testCDXA.json --fail-on-errors --input-version v1_6 + ./cyclonedx-linux-x64 validate --input-file cyclonedx-lib/build/testCDXA.xml --fail-on-errors --input-version v1_6 + - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 name: Collect and Archive TemurinGenSBOM Artifacts with: name: testSBOM - path: cyclonedx-lib/build/testSBOM.json + path: cyclonedx-lib/build/testSBOM.* + + - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 + name: Collect and Archive TemurinGenCDXA Artifacts + with: + name: testCDXA + path: cyclonedx-lib/build/testCDXA.* + diff --git a/cyclonedx-lib/build.xml b/cyclonedx-lib/build.xml index f026a2611..f4e11f65c 100644 --- a/cyclonedx-lib/build.xml +++ b/cyclonedx-lib/build.xml @@ -30,7 +30,7 @@ - + @@ -42,8 +42,11 @@ + + + @@ -67,7 +70,7 @@ - + @@ -114,11 +117,23 @@ + + + + - + + + + + + + + + @@ -134,11 +149,16 @@ - + + + + + + @@ -179,9 +199,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -193,6 +274,7 @@ + @@ -333,7 +415,7 @@ - + @@ -353,7 +435,7 @@ - + @@ -417,7 +499,7 @@ - + @@ -429,7 +511,7 @@ - + @@ -476,6 +558,289 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cyclonedx-lib/dependency_data/dependency_data.properties b/cyclonedx-lib/dependency_data/dependency_data.properties index 4b5607d50..cb2d15487 100644 --- a/cyclonedx-lib/dependency_data/dependency_data.properties +++ b/cyclonedx-lib/dependency_data/dependency_data.properties @@ -21,11 +21,14 @@ commons-codec.jar=commons-codec-${commons-codec.version}.jar commons-collections4.version=4.4 commons-collections4.sha256=1df8b9430b5c8ed143d7815e403e33ef5371b2400aadbe9bda0883762e0846d1 commons-collections4.jar=commons-collections4-${commons-collections4.version}.jar +commons-lang3.version=3.17.0 +commons-lang3.sha256=6ee731df5c8e5a2976a1ca023b6bb320ea8d3539fbe64c8a1d5cb765127c33b4 +commons-lang3.jar=commons-lang3-${commons-lang3.version}.jar commons-io.version=2.16.1 commons-io.sha256=f41f7baacd716896447ace9758621f62c1c6b0a91d89acee488da26fc477c84f commons-io.jar=commons-io-${commons-io.version}.jar -cyclonedx-core-java.version=9.0.5 -cyclonedx-core-java.sha256=9474c73a81d9be6206367d357a3449e03e70c69bc672d82be04f15806ef170fa +cyclonedx-core-java.version=9.1.0 +cyclonedx-core-java.sha256=a911ee5e5ebdabc2b2c08d08f9c92c673c21965ee1b982f40fc166d80f1eb088 cyclonedx-core-java.jar=cyclonedx-core-java-${cyclonedx-core-java.version}.jar github-package-url.version=1.5.0 github-package-url.sha256=e45551727707acc0c56ac62d56964332ea0f138d6cc3656d988b9369150f5247 @@ -45,10 +48,17 @@ jackson-dataformat-xml.jar=jackson-dataformat-xml-${jackson-dataformat-xml.versi json-schema-validator.version=1.5.1 json-schema-validator.sha256=de015f79d4a63d22c002bad76bb30c039cafa205465eef8770e2c6b85880ded7 json-schema-validator.jar=json-schema-validator-${json-schema-validator.version}.jar +stax2-api.version=4.2.2 +stax2-api.sha256=a61c48d553efad78bc01fffc4ac528bebbae64cbaec170b2a5e39cf61eb51abe +stax2-api.jar=stax2-api-${stax2-api.version}.jar +woodstox-core.version=7.1.0 +woodstox-core.sha256=81266920a1cdc47306a8a2b4726c99ec89b3fbf31c2470e4f5e477d9d857ca9f +woodstox-core.jar=woodstox-core-${woodstox-core.version}.jar # Download URLs commons-codec.url=${maven.central.repo}/commons-codec/commons-codec/${commons-codec.version}/${commons-codec.jar} commons-collections4.url=${maven.central.repo}/org/apache/commons/commons-collections4/${commons-collections4.version}/${commons-collections4.jar} +commons-lang3.url=${maven.central.repo}/org/apache/commons/commons-lang3/${commons-lang3.version}/${commons-lang3.jar} commons-io.url=${maven.central.repo}/commons-io/commons-io/${commons-io.version}/${commons-io.jar} cyclonedx-core-java.url=${maven.central.repo}/org/cyclonedx/cyclonedx-core-java/${cyclonedx-core-java.version}/${cyclonedx-core-java.jar} github-package-url.url=${maven.central.repo}/com/github/package-url/packageurl-java/${github-package-url.version}/${github-package-url.jar} @@ -57,4 +67,6 @@ jackson-core.url=${maven.central.repo}/com/fasterxml/jackson/core/jackson-core/$ jackson-databind.url=${maven.central.repo}/com/fasterxml/jackson/core/jackson-databind/${jackson-databind.version}/${jackson-databind.jar} jackson-dataformat-xml.url=${maven.central.repo}/com/fasterxml/jackson/dataformat/jackson-dataformat-xml/${jackson-dataformat-xml.version}/${jackson-dataformat-xml.jar} json-schema-validator.url=${maven.central.repo}/com/networknt/json-schema-validator/${json-schema-validator.version}/${json-schema-validator.jar} +stax2-api.url=${maven.central.repo}/org/codehaus/woodstox/stax2-api/${stax2-api.version}/${stax2-api.jar} +woodstox-core.url=${maven.central.repo}/com/fasterxml/woodstox/woodstox-core/${woodstox-core.version}/${woodstox-core.jar} diff --git a/cyclonedx-lib/sign_src/TemurinSignSBOM.java b/cyclonedx-lib/sign_src/TemurinSignSBOM.java index 14784fc76..d9d35f105 100644 --- a/cyclonedx-lib/sign_src/TemurinSignSBOM.java +++ b/cyclonedx-lib/sign_src/TemurinSignSBOM.java @@ -60,7 +60,7 @@ private TemurinSignSBOM() { * @param args Arguments for sbom operation. */ public static void main(final String[] args) { - String cmd = null; + String cmd = ""; String privateKeyFile = null; String publicKeyFile = null; String fileName = null; @@ -95,6 +95,8 @@ public static void main(final String[] args) { } else if (cmd.equals("verifySignature")) { success = verifySignature(fileName, publicKeyFile); // set success to the result of verifySignature System.out.println("Signature verification result: " + (success ? "Valid" : "Invalid")); + } else { + System.out.println("Please enter a command."); } // Set success to true only when the operation is completed successfully. diff --git a/cyclonedx-lib/src/temurin/sbom/TemurinGenCDXA.java b/cyclonedx-lib/src/temurin/sbom/TemurinGenCDXA.java new file mode 100644 index 000000000..a1f02c0f1 --- /dev/null +++ b/cyclonedx-lib/src/temurin/sbom/TemurinGenCDXA.java @@ -0,0 +1,336 @@ +/* + * ******************************************************************************** + * Copyright (c) 2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made + * available under the terms of the Apache Software License 2.0 + * which is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + * ******************************************************************************** + */ + +package temurin.sbom; + +import org.cyclonedx.exception.GeneratorException; +import org.cyclonedx.generators.json.BomJsonGenerator; +import org.cyclonedx.generators.xml.BomXmlGenerator; +import org.cyclonedx.model.Bom; +import org.cyclonedx.model.Component; +import org.cyclonedx.model.ExternalReference; +import org.cyclonedx.model.Hash; +import org.cyclonedx.model.OrganizationalEntity; +import org.cyclonedx.model.attestation.Declarations; +import org.cyclonedx.model.attestation.Assessor; +import org.cyclonedx.model.attestation.Attestation; +import org.cyclonedx.model.attestation.AttestationMap; +import org.cyclonedx.model.attestation.Claim; +import org.cyclonedx.model.attestation.affirmation.Affirmation; +import org.cyclonedx.model.attestation.affirmation.Signatory; +import org.cyclonedx.model.attestation.Targets; +import org.cyclonedx.parsers.JsonParser; +import org.cyclonedx.parsers.XmlParser; +import org.cyclonedx.Version; +import java.io.FileReader; +import java.io.FileWriter; +import java.util.List; +import java.util.LinkedList; +import java.util.UUID; + +/** + * Command line tool to construct a CycloneDX CDXA. + */ +public final class TemurinGenCDXA { + + private static boolean verbose = false; + private static boolean useJson = false; + + // Valid predicates + enum CDXAPredicate { + VERIFIED_REPRODUCIBLE_BUILD + }; + + private TemurinGenCDXA() { + } + + /** + * Main entry. + * @param args Arguments for operation. + */ + public static void main(final String[] args) { + String cmd = ""; + String fileName = null; + String attestingOrgName = null; + String predicate = null; + String targetName = null; + String targetUrl = null; + String targetHash = null; + String affirmationStmt = null; + String affirmationWebsite = null; + boolean thirdParty = true; + + for (int i = 0; i < args.length; i++) { + if (args[i].equals("--jsonFile")) { + fileName = args[++i]; + useJson = true; + } else if (args[i].equals("--xmlFile")) { + fileName = args[++i]; + useJson = false; + } else if (args[i].equals("--attesting-org-name")) { + attestingOrgName = args[++i]; + } else if (args[i].equals("--predicate")) { + predicate = args[++i]; + } else if (args[i].equals("--target-name")) { + targetName = args[++i]; + } else if (args[i].equals("--target-url")) { + targetUrl = args[++i]; + } else if (args[i].equals("--target-sha256-hash")) { + targetHash = args[++i]; + } else if (args[i].equals("--affirmation-stmt")) { + affirmationStmt = args[++i]; + } else if (args[i].equals("--affirmation-website")) { + affirmationWebsite = args[++i]; + } else if (args[i].equals("--not-third-party")) { + thirdParty = false; + } else if (args[i].equals("--createNewCDXA")) { + cmd = "createCDXA"; + } else if (args[i].equals("--verbose")) { + verbose = true; + } + } + + switch (cmd) { + case "createCDXA": // Create a new CDXA json file + Bom bom = createCdxa(fileName, attestingOrgName, predicate, targetName, targetUrl, targetHash, affirmationStmt, affirmationWebsite, thirdParty); + if (bom != null) { + writeFile(bom, fileName); + } else { + System.exit(1); + } + break; + + default: + System.out.println("Please enter a command."); + System.exit(1); + } + } + + static Bom createCdxa(final String fileName, final String attestingOrgName, final String predicate, + final String targetName, final String targetUrl, final String targetHash, + final String affirmationStmt, final String affirmationWebsite, final boolean thirdParty) { + // Validate inputs + boolean validInput = true; + if (fileName == null) { + System.out.println("--xmlFile|--jsonFile not specified"); + validInput = false; + } + if (attestingOrgName == null) { + System.out.println("--attesting-org-name not specified"); + validInput = false; + } + if (predicate == null) { + System.out.println("--predicate not specified"); validInput = false; + } else { + boolean validPred = false; + for (CDXAPredicate validPredicate : CDXAPredicate.values()) { + if (validPredicate.name().equals(predicate)) { + validPred = true; + break; + } + } + if (!validPred) { + System.out.println("--predicate " + predicate + " not a valid value"); + validInput = false; + } + } + if (targetName == null) { + System.out.println("--target-name not specified"); + validInput = false; + } + if (targetUrl == null) { + System.out.println("--target-url not specified"); + validInput = false; + } + if (targetHash == null) { + System.out.println("--target-sha256-hash not specified"); + validInput = false; + } + if (affirmationStmt == null) { + System.out.println("--affirmation-stmt not specified"); + validInput = false; + } + if (affirmationWebsite == null) { + System.out.println("--affirmation-website not specified"); + validInput = false; + } + if (!validInput) { + return null; + } + + Declarations declarations = new Declarations(); + Assessor assessor = new Assessor(); + Claim claim = new Claim(); + Targets targets = new Targets(); + Affirmation affirmation = new Affirmation(); + Signatory signatory = new Signatory(); + Attestation attestation = new Attestation(); + AttestationMap attestationMap = new AttestationMap(); + + final String targetJdkBomRef = "target-jdk-1"; + final String assessorBomRef = "assessor-1"; + final String claimBomRef = "claim-1"; + + // External reference to the target JDK + ExternalReference extRef = new ExternalReference(); + Hash hash1 = new Hash(Hash.Algorithm.SHA_256, targetHash); + extRef.addHash(hash1); + extRef.setUrl(targetUrl); + extRef.setType(ExternalReference.Type.DISTRIBUTION); + + // Target JDK Component + Component targetJDK = new Component(); + targetJDK.setType(Component.Type.APPLICATION); + targetJDK.setName(targetName); + targetJDK.addExternalReference(extRef); + targetJDK.setBomRef(targetJdkBomRef); + List components = new LinkedList(); + components.add(targetJDK); + targets.setComponents(components); + declarations.setTargets(targets); + + // Assessor + assessor.setThirdParty(thirdParty); + OrganizationalEntity org = new OrganizationalEntity(); + org.setName(attestingOrgName); + assessor.setOrganization(org); + assessor.setBomRef(assessorBomRef); + List assessors = new LinkedList(); + assessors.add(assessor); + declarations.setAssessors(assessors); + + // Claim + claim.setPredicate(predicate); + claim.setTarget(targetJDK.getBomRef()); + claim.setBomRef(claimBomRef); + List claims = new LinkedList(); + claims.add(claim); + declarations.setClaims(claims); + + // Affirmation + affirmation.setStatement(affirmationStmt); + signatory.setOrganization(org); + ExternalReference orgExtRef = new ExternalReference(); + orgExtRef.setUrl(affirmationWebsite); + orgExtRef.setType(ExternalReference.Type.WEBSITE); + signatory.setExternalReference(orgExtRef); + List signatories = new LinkedList(); + signatories.add(signatory); + affirmation.setSignatories(signatories); + declarations.setAffirmation(affirmation); + + // Construct the Attestation + attestation.setSummary("Eclipse Temurin Attestation"); + attestation.setAssessor(assessor.getBomRef()); + List claimsList = new LinkedList(); + claimsList.add(claim.getBomRef()); + attestationMap.setClaims(claimsList); + List attestationMaps = new LinkedList(); + attestationMaps.add(attestationMap); + attestation.setMap(attestationMaps); + List attestations = new LinkedList(); + attestations.add(attestation); + declarations.setAttestations(attestations); + + // Create CDXA Bom + Bom cdxa = new Bom(); + cdxa.setSerialNumber("urn:uuid:" + UUID.randomUUID()); + cdxa.setDeclarations(declarations); + + return cdxa; + } + + static String generateBomJson(final Bom bom) throws GeneratorException { + // Use schema v16: https://cyclonedx.org/schema/bom-1.6.schema.json + BomJsonGenerator bomGen = new BomJsonGenerator(bom, Version.VERSION_16); + String json = bomGen.toJsonString(); + return json; + } + + static String generateBomXml(final Bom bom) throws GeneratorException { + BomXmlGenerator bomGen = new BomXmlGenerator(bom, Version.VERSION_16); + String xml = bomGen.toXmlString(); + return xml; + } + + // Writes the BOM object to the specified type of file + static void writeFile(final Bom bom, final String fileName) { + if (useJson) { + writeJSONfile(bom, fileName); + } else { + writeXMLfile(bom, fileName); + } + } + + // Writes the BOM object to the specified JSON file. + static void writeJSONfile(final Bom bom, final String fileName) { + FileWriter file; + try { + String json = generateBomJson(bom); + + file = new FileWriter(fileName); + file.write(json); + file.close(); + } catch (Exception e) { + e.printStackTrace(); + System.exit(1); + } + } + + // Writes the BOM object to the specified XML file. + static void writeXMLfile(final Bom bom, final String fileName) { + FileWriter file; + try { + String xml = generateBomXml(bom); + + file = new FileWriter(fileName); + file.write(xml); + file.close(); + } catch (Exception e) { + e.printStackTrace(); + System.exit(1); + } + } + + // Returns a parsed BOM object from the specified file. + static Bom readJSONfile(final String fileName) { + Bom bom = null; + try { + FileReader reader = new FileReader(fileName); + JsonParser parser = new JsonParser(); + bom = parser.parse(reader); + } catch (Exception e) { + e.printStackTrace(); + System.exit(1); + } finally { + return bom; + } + } + + // Returns a parsed BOM object from the specified file. + static Bom readXMLfile(final String fileName) { + Bom bom = null; + try { + FileReader reader = new FileReader(fileName); + XmlParser parser = new XmlParser(); + bom = parser.parse(reader); + } catch (Exception e) { + e.printStackTrace(); + System.exit(1); + } finally { + return bom; + } + } +} diff --git a/cyclonedx-lib/src/temurin/sbom/TemurinGenSBOM.java b/cyclonedx-lib/src/temurin/sbom/TemurinGenSBOM.java index 639ed6737..4533a9c37 100644 --- a/cyclonedx-lib/src/temurin/sbom/TemurinGenSBOM.java +++ b/cyclonedx-lib/src/temurin/sbom/TemurinGenSBOM.java @@ -17,9 +17,9 @@ import org.cyclonedx.exception.GeneratorException; import org.cyclonedx.generators.json.BomJsonGenerator; +import org.cyclonedx.generators.xml.BomXmlGenerator; import org.cyclonedx.model.Bom; import org.cyclonedx.model.Component; -import org.cyclonedx.model.ExternalReference; import org.cyclonedx.model.formulation.Formula; import org.cyclonedx.model.Hash; import org.cyclonedx.model.Metadata; @@ -28,12 +28,14 @@ import org.cyclonedx.model.Property; import org.cyclonedx.model.Tool; import org.cyclonedx.parsers.JsonParser; +import org.cyclonedx.parsers.XmlParser; import org.cyclonedx.Version; import java.io.FileReader; import java.io.FileWriter; import java.util.Collections; import java.util.List; import java.util.LinkedList; +import java.util.UUID; /** * Command line tool to construct a CycloneDX SBOM. @@ -41,6 +43,7 @@ public final class TemurinGenSBOM { private static boolean verbose = false; + private static boolean useJson = false; private TemurinGenSBOM() { } @@ -50,7 +53,7 @@ private TemurinGenSBOM() { * @param args Arguments for sbom operation. */ public static void main(final String[] args) { - String cmd = null; + String cmd = ""; String comment = null; String compName = null; String formulaName = null; @@ -67,6 +70,10 @@ public static void main(final String[] args) { for (int i = 0; i < args.length; i++) { if (args[i].equals("--jsonFile")) { fileName = args[++i]; + useJson = true; + } else if (args[i].equals("--xmlFile")) { + fileName = args[++i]; + useJson = false; } else if (args[i].equals("--version")) { version = args[++i]; } else if (args[i].equals("--name")) { @@ -120,69 +127,60 @@ public static void main(final String[] args) { } } switch (cmd) { - case "createNewSBOM": // Creates JSON file + case "createNewSBOM": // Creates new SBOM Bom bom = createBom(); - writeJSONfile(bom, fileName); + writeFile(bom, fileName); break; case "addMetadata": // Adds Metadata --> name bom = addMetadata(fileName); - writeJSONfile(bom, fileName); + writeFile(bom, fileName); break; case "addMetadataComponent": // Adds Metadata --> Component --> name bom = addMetadataComponent(fileName, name, type, version, description); - writeJSONfile(bom, fileName); + writeFile(bom, fileName); break; case "addMetadataProperty": // Adds MetaData --> Property --> name-value: bom = addMetadataProperty(fileName, name, value); - writeJSONfile(bom, fileName); + writeFile(bom, fileName); break; case "addFormulation": // Adds Formulation --> name bom = addFormulation(fileName, formulaName); - writeJSONfile(bom, fileName); + writeFile(bom, fileName); break; case "addFormulationComp": // Adds Formulation --> Component--> name bom = addFormulationComp(fileName, formulaName, name, type); - writeJSONfile(bom, fileName); + writeFile(bom, fileName); break; case "addFormulationCompProp": // Adds Formulation --> Component -> name-value: bom = addFormulationCompProp(fileName, formulaName, compName, name, value); - writeJSONfile(bom, fileName); + writeFile(bom, fileName); break; case "addMetadataTools": bom = addMetadataTools(fileName, tool, version); - writeJSONfile(bom, fileName); + writeFile(bom, fileName); break; case "addComponent": // Adds Components --> Component --> name bom = addComponent(fileName, compName, version, description); - writeJSONfile(bom, fileName); + writeFile(bom, fileName); break; case "addComponentHash": // Adds Components --> Component --> hash bom = addComponentHash(fileName, compName, hash); - writeJSONfile(bom, fileName); + writeFile(bom, fileName); break; case "addComponentProp": // Adds Components --> Component --> name-value pairs bom = addComponentProperty(fileName, compName, name, value); - writeJSONfile(bom, fileName); - break; - - case "addExternalReference": // Adds external Reference - bom = addExternalReference(fileName, hash, url, comment); - writeJSONfile(bom, fileName); + writeFile(bom, fileName); break; - case "addComponentExternalReference": // Adds external Reference to component - bom = addComponentExternalReference(fileName, hash, url, comment); - writeJSONfile(bom, fileName); - break; default: System.out.println("Please enter a command."); } @@ -194,12 +192,13 @@ public static void main(final String[] args) { */ static Bom createBom() { Bom bom = new Bom(); + bom.setSerialNumber("urn:uuid:" + UUID.randomUUID()); return bom; } // Method to store Metadata --> name. static Bom addMetadata(final String fileName) { - Bom bom = readJSONfile(fileName); + Bom bom = readFile(fileName); Metadata meta = new Metadata(); OrganizationalEntity org = new OrganizationalEntity(); org.setName("Eclipse Foundation"); @@ -213,7 +212,7 @@ static Bom addMetadata(final String fileName) { } static Bom addMetadataComponent(final String fileName, final String name, final String type, final String version, final String description) { - Bom bom = readJSONfile(fileName); + Bom bom = readFile(fileName); Metadata meta = new Metadata(); Component comp = new Component(); Component.Type compType = Component.Type.FRAMEWORK; @@ -235,7 +234,7 @@ static Bom addMetadataComponent(final String fileName, final String name, final // Method to store Metadata --> Properties List --> name-values. static Bom addMetadataProperty(final String fileName, final String name, final String value) { - Bom bom = readJSONfile(fileName); + Bom bom = readFile(fileName); Metadata meta = new Metadata(); Property prop1 = new Property(); meta = bom.getMetadata(); @@ -247,7 +246,7 @@ static Bom addMetadataProperty(final String fileName, final String name, final S } static Bom addMetadataTools(final String fileName, final String toolName, final String version) { - Bom bom = readJSONfile(fileName); + Bom bom = readFile(fileName); Metadata meta = new Metadata(); Tool tool = new Tool(); meta = bom.getMetadata(); @@ -260,7 +259,7 @@ static Bom addMetadataTools(final String fileName, final String toolName, final // Method to store Component --> name & single name-value pair. static Bom addComponent(final String fileName, final String compName, final String version, final String description) { - Bom bom = readJSONfile(fileName); + Bom bom = readFile(fileName); Component comp = new Component(); comp.setName(compName); comp.setVersion(version); @@ -274,7 +273,7 @@ static Bom addComponent(final String fileName, final String compName, final Stri } static Bom addComponentHash(final String fileName, final String compName, final String hash) { - Bom bom = readJSONfile(fileName); + Bom bom = readFile(fileName); List componentArrayList = bom.getComponents(); for (Component item : componentArrayList) { if (item.getName().equals(compName)) { @@ -287,7 +286,7 @@ static Bom addComponentHash(final String fileName, final String compName, final // Method to add Component --> Property --> name-value pairs. static Bom addComponentProperty(final String fileName, final String compName, final String name, final String value) { - Bom bom = readJSONfile(fileName); + Bom bom = readFile(fileName); List componentArrayList = bom.getComponents(); for (Component item : componentArrayList) { if (item.getName().equals(compName)) { @@ -300,36 +299,8 @@ static Bom addComponentProperty(final String fileName, final String compName, fi return bom; } - // Method to store externalReferences: dependency_version_alsa. - static Bom addExternalReference(final String fileName, final String hash, final String url, final String comment) { - Bom bom = readJSONfile(fileName); - ExternalReference extRef = new ExternalReference(); - Hash hash1 = new Hash(Hash.Algorithm.SHA3_256, hash); - extRef.setType(ExternalReference.Type.BUILD_SYSTEM); //required - extRef.setUrl(url); // required must be a valid URL with protocol - extRef.setComment(comment); - extRef.addHash(hash1); - bom.addExternalReference(extRef); - return bom; - } - - // Method to store externalReferences to store: openjdk_source. - static Bom addComponentExternalReference(final String fileName, final String hash, final String url, final String comment) { - Bom bom = readJSONfile(fileName); - ExternalReference extRef = new ExternalReference(); - Hash hash1 = new Hash(Hash.Algorithm.SHA3_256, hash); - Component comp = new Component(); - extRef.addHash(hash1); - extRef.setUrl(url); - extRef.setComment(comment); //"openjdk_source" - extRef.setType(ExternalReference.Type.BUILD_SYSTEM); - comp.addExternalReference(extRef); - bom.addComponent(comp); - return bom; - } - static Bom addFormulation(final String fileName, final String name) { - Bom bom = readJSONfile(fileName); + Bom bom = readFile(fileName); List formulation = bom.getFormulation(); if (formulation == null) { formulation = new LinkedList(); @@ -343,7 +314,7 @@ static Bom addFormulation(final String fileName, final String name) { } static Bom addFormulationComp(final String fileName, final String formulaName, final String name, final String type) { - Bom bom = readJSONfile(fileName); + Bom bom = readFile(fileName); if (formulaName == null) { System.out.println("addFormulationComp: formulaName is null"); return bom; @@ -376,7 +347,7 @@ static Bom addFormulationComp(final String fileName, final String formulaName, f } static Bom addFormulationCompProp(final String fileName, final String formulaName, final String componentName, final String name, final String value) { - Bom bom = readJSONfile(fileName); + Bom bom = readFile(fileName); boolean foundFormula = false; boolean foundComponent = false; List formulation = bom.getFormulation(); @@ -417,6 +388,32 @@ static String generateBomJson(final Bom bom) throws GeneratorException { return json; } + static String generateBomXml(final Bom bom) throws GeneratorException { + BomXmlGenerator bomGen = new BomXmlGenerator(bom, Version.VERSION_16); + String xml = bomGen.toXmlString(); + return xml; + } + + // Writes the BOM object to the specified type of file + static void writeFile(final Bom bom, final String fileName) { + if (useJson) { + writeJSONfile(bom, fileName); + } else { + writeXMLfile(bom, fileName); + } + } + + // Read the BOM object from the specified type of file + static Bom readFile(final String fileName) { + Bom bom; + if (useJson) { + bom = readJSONfile(fileName); + } else { + bom = readXMLfile(fileName); + } + return bom; + } + // Writes the BOM object to the specified file. static void writeJSONfile(final Bom bom, final String fileName) { FileWriter file; @@ -432,6 +429,21 @@ static void writeJSONfile(final Bom bom, final String fileName) { } } + // Writes the BOM object to the specified XML file. + static void writeXMLfile(final Bom bom, final String fileName) { + FileWriter file; + try { + String xml = generateBomXml(bom); + + file = new FileWriter(fileName); + file.write(xml); + file.close(); + } catch (Exception e) { + e.printStackTrace(); + System.exit(1); + } + } + // Returns a parsed BOM object from the specified file. static Bom readJSONfile(final String fileName) { Bom bom = null; @@ -446,4 +458,19 @@ static Bom readJSONfile(final String fileName) { return bom; } } + + // Returns a parsed BOM object from the specified file. + static Bom readXMLfile(final String fileName) { + Bom bom = null; + try { + FileReader reader = new FileReader(fileName); + XmlParser parser = new XmlParser(); + bom = parser.parse(reader); + } catch (Exception e) { + e.printStackTrace(); + System.exit(1); + } finally { + return bom; + } + } } diff --git a/sbin/common/sbom.sh b/sbin/common/sbom.sh index 945389b68..7fd7869aa 100755 --- a/sbin/common/sbom.sh +++ b/sbin/common/sbom.sh @@ -205,18 +205,3 @@ addSBOMComponentPropertyFromFile() { fi } -# Function not in use -# Ref: https://cyclonedx.org/docs/1.4/json/#externalReferences -addExternalReference() { - local javaHome="${1}" - local classpath="${2}" - local jsonFile="${3}" - local url="${4}" # required - local comment="${5}" - local hash="${6}" - if [ -z "${hash}" ]; then - "${javaHome}"/bin/java -cp "${classpath}" temurin.sbom.TemurinGenSBOM --addExternalReference --jsonFile "${jsonFile}" --url "${url}" --comment "${comment}" --hash "${hash}" - else - "${javaHome}"/bin/java -cp "${classpath}" temurin.sbom.TemurinGenSBOM --addExternalReference --jsonFile "${jsonFile}" --url "${url}" --comment "${comment}" - fi -}