From 1e6b554f3270c3946e9ca1fe10f6eee4828c9cdf Mon Sep 17 00:00:00 2001 From: Ben Date: Mon, 7 Sep 2026 15:01:07 -0600 Subject: [PATCH 1/6] Pin SimpleAPI snapshot build --- AdvancedCore/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AdvancedCore/pom.xml b/AdvancedCore/pom.xml index 0b4ec710e2..383ffe5bbe 100644 --- a/AdvancedCore/pom.xml +++ b/AdvancedCore/pom.xml @@ -208,7 +208,7 @@ com.bencodez simpleapi - 1.0.2-SNAPSHOT + 1.0.2-20260905.234759-10 compile From b239de041681664d2d2856ccdb8339081f37870f Mon Sep 17 00:00:00 2001 From: Ben Date: Mon, 7 Sep 2026 15:01:11 -0600 Subject: [PATCH 2/6] Test immutable build inputs --- .../build/BuildInputPinningTest.java | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 AdvancedCore/src/test/java/com/bencodez/advancedcore/build/BuildInputPinningTest.java diff --git a/AdvancedCore/src/test/java/com/bencodez/advancedcore/build/BuildInputPinningTest.java b/AdvancedCore/src/test/java/com/bencodez/advancedcore/build/BuildInputPinningTest.java new file mode 100644 index 0000000000..d412c67acb --- /dev/null +++ b/AdvancedCore/src/test/java/com/bencodez/advancedcore/build/BuildInputPinningTest.java @@ -0,0 +1,33 @@ +package com.bencodez.advancedcore.build; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; + +import org.junit.jupiter.api.Test; + +class BuildInputPinningTest { + + @Test + void javadocPublisherUsesImmutableRevisionAndExplicitPermissions() throws IOException { + String workflow = Files.readString(Path.of("..", ".github", "workflows", "publish-javadoc.yml")); + + assertTrue(workflow.matches("(?s).*MathieuSoysal/Javadoc-publisher\\.yml@[0-9a-f]{40}.*")); + assertTrue(workflow.contains("permissions:\n contents: write")); + assertFalse(workflow.contains("Javadoc-publisher.yml@main")); + } + + @Test + void simpleApiDependencyUsesImmutableSnapshotBuild() throws IOException { + String pom = Files.readString(Path.of("pom.xml")); + int dependency = pom.indexOf("simpleapi"); + + assertTrue(dependency >= 0); + String declaration = pom.substring(dependency, Math.min(pom.length(), dependency + 200)); + assertFalse(declaration.contains("SNAPSHOT")); + assertTrue(declaration.contains("1.0.2-20260905.234759-10")); + } +} From bcb5a03ac83c43b54a3c83b909cb2e7322ae0c00 Mon Sep 17 00:00:00 2001 From: Ben Date: Mon, 7 Sep 2026 15:03:31 -0600 Subject: [PATCH 3/6] Use least-privilege GitHub Pages deployment --- .github/workflows/publish-javadoc.yml | 36 +++++++++++++++++++-------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/.github/workflows/publish-javadoc.yml b/.github/workflows/publish-javadoc.yml index 644dfa5849..70997f1e78 100644 --- a/.github/workflows/publish-javadoc.yml +++ b/.github/workflows/publish-javadoc.yml @@ -7,18 +7,34 @@ on: - master - main +permissions: + contents: read + pages: write + id-token: write + jobs: publish: runs-on: ubuntu-latest + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} steps: - - name: Deploy JavaDoc 🚀 - uses: MathieuSoysal/Javadoc-publisher.yml@main + - name: Checkout + uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 + - name: Set up Java + uses: actions/setup-java@cf277c60eb25467037889841efdb72551f06f6c3 + with: + distribution: temurin + java-version: '21' + cache: maven + - name: Build Javadoc + run: mvn -B -f AdvancedCore/pom.xml javadoc:javadoc + - name: Configure Pages + uses: actions/configure-pages@983d7736d9b0ae728b81ab479565c72886d7745b + - name: Upload Pages artifact + uses: actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa with: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - javadoc-branch: gh-pages - java-version: 21 - target-folder: '' - project: maven # or gradle - # subdirectories: moduleA moduleB #for subdirectories support, needs to be run with custom command - custom-command: mvn -f AdvancedCore/pom.xml deploy -P javadoc javadoc:aggregate - javadoc-source-folder: 'AdvancedCore/target/reports/apidocs' + path: AdvancedCore/target/reports/apidocs + - name: Deploy Pages + id: deployment + uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e From 72e8b19545be5dda3643e935b5c906a268ac9171 Mon Sep 17 00:00:00 2001 From: Ben Date: Mon, 7 Sep 2026 15:03:37 -0600 Subject: [PATCH 4/6] Test least-privilege pinned workflow --- .../bencodez/advancedcore/build/BuildInputPinningTest.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/AdvancedCore/src/test/java/com/bencodez/advancedcore/build/BuildInputPinningTest.java b/AdvancedCore/src/test/java/com/bencodez/advancedcore/build/BuildInputPinningTest.java index d412c67acb..4db0da1208 100644 --- a/AdvancedCore/src/test/java/com/bencodez/advancedcore/build/BuildInputPinningTest.java +++ b/AdvancedCore/src/test/java/com/bencodez/advancedcore/build/BuildInputPinningTest.java @@ -15,8 +15,11 @@ class BuildInputPinningTest { void javadocPublisherUsesImmutableRevisionAndExplicitPermissions() throws IOException { String workflow = Files.readString(Path.of("..", ".github", "workflows", "publish-javadoc.yml")); - assertTrue(workflow.matches("(?s).*MathieuSoysal/Javadoc-publisher\\.yml@[0-9a-f]{40}.*")); - assertTrue(workflow.contains("permissions:\n contents: write")); + assertFalse(workflow.contains("MathieuSoysal/Javadoc-publisher")); + assertTrue(workflow.matches("(?s).*actions/checkout@[0-9a-f]{40}.*")); + assertTrue(workflow.matches("(?s).*actions/setup-java@[0-9a-f]{40}.*")); + assertTrue(workflow.matches("(?s).*actions/deploy-pages@[0-9a-f]{40}.*")); + assertTrue(workflow.contains("permissions:\n contents: read\n pages: write\n id-token: write")); assertFalse(workflow.contains("Javadoc-publisher.yml@main")); } From 284b322de07884a5cf8be813d90ee2ab3cc7c9e3 Mon Sep 17 00:00:00 2001 From: Ben Date: Mon, 7 Sep 2026 16:33:44 -0600 Subject: [PATCH 5/6] Address build hardening review feedback --- .github/workflows/publish-javadoc.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish-javadoc.yml b/.github/workflows/publish-javadoc.yml index 70997f1e78..03275bbc32 100644 --- a/.github/workflows/publish-javadoc.yml +++ b/.github/workflows/publish-javadoc.yml @@ -28,7 +28,7 @@ jobs: java-version: '21' cache: maven - name: Build Javadoc - run: mvn -B -f AdvancedCore/pom.xml javadoc:javadoc + run: mvn -B -f AdvancedCore/pom.xml org.apache.maven.plugins:maven-javadoc-plugin:3.12.0:javadoc - name: Configure Pages uses: actions/configure-pages@983d7736d9b0ae728b81ab479565c72886d7745b - name: Upload Pages artifact From 5efdbe8cd0a583cc06cf989c06e8ad6cd3d4f402 Mon Sep 17 00:00:00 2001 From: Ben Date: Mon, 7 Sep 2026 16:33:59 -0600 Subject: [PATCH 6/6] Address build hardening review feedback --- .../bencodez/advancedcore/build/BuildInputPinningTest.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/AdvancedCore/src/test/java/com/bencodez/advancedcore/build/BuildInputPinningTest.java b/AdvancedCore/src/test/java/com/bencodez/advancedcore/build/BuildInputPinningTest.java index 4db0da1208..c2fc3069f1 100644 --- a/AdvancedCore/src/test/java/com/bencodez/advancedcore/build/BuildInputPinningTest.java +++ b/AdvancedCore/src/test/java/com/bencodez/advancedcore/build/BuildInputPinningTest.java @@ -14,12 +14,14 @@ class BuildInputPinningTest { @Test void javadocPublisherUsesImmutableRevisionAndExplicitPermissions() throws IOException { String workflow = Files.readString(Path.of("..", ".github", "workflows", "publish-javadoc.yml")); + String normalizedWorkflow = workflow.replace("\r\n", "\n"); assertFalse(workflow.contains("MathieuSoysal/Javadoc-publisher")); assertTrue(workflow.matches("(?s).*actions/checkout@[0-9a-f]{40}.*")); assertTrue(workflow.matches("(?s).*actions/setup-java@[0-9a-f]{40}.*")); assertTrue(workflow.matches("(?s).*actions/deploy-pages@[0-9a-f]{40}.*")); - assertTrue(workflow.contains("permissions:\n contents: read\n pages: write\n id-token: write")); + assertTrue(normalizedWorkflow.contains("permissions:\n contents: read\n pages: write\n id-token: write")); + assertTrue(workflow.contains("maven-javadoc-plugin:3.12.0:javadoc")); assertFalse(workflow.contains("Javadoc-publisher.yml@main")); }