From ee5b42afff32e5b176ee07731898bc6e953be01c Mon Sep 17 00:00:00 2001 From: StepSecurity Bot Date: Thu, 7 Mar 2024 19:18:20 -0800 Subject: [PATCH 01/15] chore(ci): apply hardening to ci jobs - chore: apply 'Harden Runner' auditing to all ci tasks - chore: apply `persist-credentials: false` to checkout tasks - chore: publish dependency graph and add dependency review check - chore: add codeql scan job (temp) Bumps [actions/checkout](https://github.com/actions/checkout) from 3.6.0 to 4.1.1. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3.6.0...b4ffde65f46336ab88eb53be808477a3936bae11) Bumps [actions/dependency-review-action](https://github.com/actions/dependency-review-action) from 2.5.1 to 4.1.3. - [Release notes](https://github.com/actions/dependency-review-action/releases) - [Commits](https://github.com/actions/dependency-review-action/compare/0efb1d1d84fc9633afcdaad14c485cbbc90ef46c...9129d7d40b8c12c1ed0f60400d00c92d437adcce) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major - dependency-name: actions/dependency-review-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: StepSecurity Bot Signed-off-by: Sam Gammon Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 17 +++- .github/workflows/codeql.yml | 79 +++++++++++++++++++ .github/workflows/dependency-review.yml | 33 ++++++++ .../workflows/gradle-wrapper-validation.yml | 14 +++- .github/workflows/scorecard.yml | 4 + 5 files changed, 143 insertions(+), 4 deletions(-) create mode 100644 .github/workflows/codeql.yml create mode 100644 .github/workflows/dependency-review.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c0cac9d8e013..11300f727446 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,15 +31,20 @@ jobs: ROOT_POM: ${{ matrix.root-pom }} steps: # Cancel any previous runs for the same branch that are still running. + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit - name: 'Cancel previous runs' uses: styfle/cancel-workflow-action@85880fa0301c86cca9da44039ee3bb12d3bedbfa # 0.12.1 with: access_token: ${{ github.token }} - name: 'Check out repository' uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + with: + persist-credentials: false - name: 'Set up JDK ${{ matrix.java }}' uses: actions/setup-java@9704b39bf258b59bc04b50fa2dd55e9ed76b47a8 # v4.1.0 - with: java-version: ${{ matrix.java }} distribution: 'zulu' @@ -66,11 +71,14 @@ jobs: if: github.event_name == 'push' && github.repository == 'google/guava' runs-on: ubuntu-latest steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit - name: 'Check out repository' uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: 'Set up JDK 11' uses: actions/setup-java@9704b39bf258b59bc04b50fa2dd55e9ed76b47a8 # v4.1.0 - with: java-version: 11 distribution: 'zulu' @@ -92,11 +100,14 @@ jobs: if: github.event_name == 'push' && github.repository == 'google/guava' runs-on: ubuntu-latest steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit - name: 'Check out repository' uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: 'Set up JDK 11' uses: actions/setup-java@9704b39bf258b59bc04b50fa2dd55e9ed76b47a8 # v4.1.0 - with: java-version: 11 distribution: 'zulu' diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 000000000000..6be21cbc81cf --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,79 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: "CodeQL" + +on: + push: + branches: ["master"] + pull_request: + # The branches below must be a subset of the branches above + branches: ["master"] + schedule: + - cron: "0 0 * * 1" + +permissions: + contents: read + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: ["java"] + # CodeQL supports [ $supported-codeql-languages ] + # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support + + steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: Checkout repository + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + with: + persist-credentials: false + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@928ff8c822d966a999092a6a35e32177899afb7c # v2.24.6 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + + # 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@928ff8c822d966a999092a6a35e32177899afb7c # v2.24.6 + + # ℹī¸ 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 + + # If the Autobuild fails above, remove it and uncomment the following three lines. + # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. + + # - run: | + # echo "Run, Build Application using script" + # ./location_of_script_within_repo/buildscript.sh + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@928ff8c822d966a999092a6a35e32177899afb7c # v2.24.6 + with: + category: "/language:${{matrix.language}}" diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml new file mode 100644 index 000000000000..8b419a6a39ad --- /dev/null +++ b/.github/workflows/dependency-review.yml @@ -0,0 +1,33 @@ +name: 'Dependency Graph' +on: + pull_request: {} + push: + branches: + - master + +permissions: + contents: read + +jobs: + dependency-review: + name: 'Dependency Graph' + runs-on: ubuntu-latest + permissions: + contents: read # needed to check out the repository + id-token: write # needed to exchange the graph publish token for an access token + steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: 'Checkout Repository' + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - name: Maven Dependency Tree Dependency Submission + uses: advanced-security/maven-dependency-submission-action@bfd2106013da0957cdede0b6c39fb5ca25ae375e # v4.0.2 + with: + token: ${{ secrets.GH_GRAPH_PUBLISH_TOKEN }} + - name: 'Dependency Review' + uses: actions/dependency-review-action@9129d7d40b8c12c1ed0f60400d00c92d437adcce # v4.1.3 + continue-on-error: true + with: + retry-on-snapshot-warnings: true diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml index 317c184351f5..ab739790b00d 100644 --- a/.github/workflows/gradle-wrapper-validation.yml +++ b/.github/workflows/gradle-wrapper-validation.yml @@ -1,5 +1,11 @@ name: "Validate Gradle Wrapper" -on: [push, pull_request] +on: + push: + branches: + - master + pull_request: + branches: + - master permissions: contents: read @@ -9,5 +15,11 @@ jobs: name: "Validation" runs-on: ubuntu-latest steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + with: + persist-credentials: false - uses: gradle/wrapper-validation-action@699bb18358f12c5b78b37bb0111d3a0e2276e0e2 # v2.1.1 diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index b42a78370343..c48175975b36 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -31,6 +31,10 @@ jobs: # actions: read steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit - name: "Checkout code" uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 with: From dbce167e66b3c4945f1a1c8b975938c492ebc9ff Mon Sep 17 00:00:00 2001 From: Sam Gammon Date: Thu, 7 Mar 2024 20:29:57 -0800 Subject: [PATCH 02/15] chore(ci): refactor into reusable workflows This change refactors the main CI workflow into two new workflows, `on.pr.yml` and `on.push.yml`, which each call into the exiting CI job as a reusable workflow. This has the nice benefit of putting all tests, checks, builds, etc., on one screen during development on GitHub, allows customization of the PR vs. push flow, and yet keeps behavior fully consistent between the two. - chore: move ci jobs to `workflow_call` trigger - chore: add entrypoint jobs for PR and Push events - chore: cleanup permissions and dispatch checks/tests Signed-off-by: Sam Gammon --- .github/workflows/ci.yml | 13 +++--- .github/workflows/codeql.yml | 15 +++---- .github/workflows/dependency-review.yml | 23 ++++++---- .../workflows/gradle-wrapper-validation.yml | 10 ++--- .github/workflows/on.pr.yml | 42 +++++++++++++++++++ .github/workflows/on.push.yml | 31 ++++++++++++++ 6 files changed, 104 insertions(+), 30 deletions(-) create mode 100644 .github/workflows/on.pr.yml create mode 100644 .github/workflows/on.push.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 11300f727446..20181531a1e9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,12 +1,8 @@ name: CI on: - push: - branches: - - master - pull_request: - branches: - - master + workflow_call: {} + workflow_dispatch: {} permissions: contents: read @@ -25,6 +21,11 @@ jobs: include: - os: windows-latest java: 17 + mode: JRE + root-pom: pom.xml + - os: windows-latest + java: 17 + mode: Android root-pom: pom.xml runs-on: ${{ matrix.os }} env: diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 6be21cbc81cf..5835c9c94667 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -12,11 +12,10 @@ name: "CodeQL" on: + workflow_call: {} + workflow_dispatch: {} push: branches: ["master"] - pull_request: - # The branches below must be a subset of the branches above - branches: ["master"] schedule: - cron: "0 0 * * 1" @@ -25,7 +24,7 @@ permissions: jobs: analyze: - name: Analyze + name: CodeQL Analysis runs-on: ubuntu-latest permissions: actions: read @@ -48,10 +47,8 @@ jobs: uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 with: persist-credentials: false - - # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@928ff8c822d966a999092a6a35e32177899afb7c # v2.24.6 + uses: github/codeql-action/init@8a470fddafa5cbb6266ee11b37ef4d8aae19c571 # v3.24.6 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -61,7 +58,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@928ff8c822d966a999092a6a35e32177899afb7c # v2.24.6 + uses: github/codeql-action/autobuild@8a470fddafa5cbb6266ee11b37ef4d8aae19c571 # v3.24.6 # ℹī¸ 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 @@ -74,6 +71,6 @@ jobs: # ./location_of_script_within_repo/buildscript.sh - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@928ff8c822d966a999092a6a35e32177899afb7c # v2.24.6 + uses: github/codeql-action/analyze@8a470fddafa5cbb6266ee11b37ef4d8aae19c571 # v3.24.6 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index 8b419a6a39ad..ea5d4df36afa 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -1,9 +1,17 @@ name: 'Dependency Graph' on: - pull_request: {} - push: - branches: - - master + workflow_call: + inputs: + review: + type: boolean + description: "Dependency Review" + default: false + workflow_dispatch: + inputs: + review: + type: boolean + description: "Dependency Review" + default: false permissions: contents: read @@ -13,8 +21,8 @@ jobs: name: 'Dependency Graph' runs-on: ubuntu-latest permissions: - contents: read # needed to check out the repository - id-token: write # needed to exchange the graph publish token for an access token + contents: write # needed to post a dependency graph + id-token: write # needed to exchange the graph publish token for an access token steps: - name: Harden Runner uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 @@ -23,9 +31,8 @@ jobs: - name: 'Checkout Repository' uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Maven Dependency Tree Dependency Submission + continue-on-error: true uses: advanced-security/maven-dependency-submission-action@bfd2106013da0957cdede0b6c39fb5ca25ae375e # v4.0.2 - with: - token: ${{ secrets.GH_GRAPH_PUBLISH_TOKEN }} - name: 'Dependency Review' uses: actions/dependency-review-action@9129d7d40b8c12c1ed0f60400d00c92d437adcce # v4.1.3 continue-on-error: true diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml index ab739790b00d..1f1cd14b51c9 100644 --- a/.github/workflows/gradle-wrapper-validation.yml +++ b/.github/workflows/gradle-wrapper-validation.yml @@ -1,18 +1,14 @@ name: "Validate Gradle Wrapper" on: - push: - branches: - - master - pull_request: - branches: - - master + workflow_call: {} + workflow_dispatch: {} permissions: contents: read jobs: validation: - name: "Validation" + name: "Gradle Wrapper Validate" runs-on: ubuntu-latest steps: - name: Harden Runner diff --git a/.github/workflows/on.pr.yml b/.github/workflows/on.pr.yml new file mode 100644 index 000000000000..dd0b9e7c3b0c --- /dev/null +++ b/.github/workflows/on.pr.yml @@ -0,0 +1,42 @@ +name: PR + +on: + pull_request: + branches: + - master + +permissions: + contents: read + +jobs: + ## Run main CI build and tests. + run-ci: + name: "Build & Test" + uses: ./.github/workflows/ci.yml + permissions: + actions: write + contents: write + + ## Validate the Gradle Wrapper binary + checks-gradle-wrapper: + name: "Checks" + uses: ./.github/workflows/gradle-wrapper-validation.yml + + ## Publish and check the dependency graph. + checks-dependency-graph: + name: "Checks" + uses: ./.github/workflows/dependency-review.yml + permissions: + contents: write + id-token: write + with: + review: true + + ## Run CodeQL checks + checks-codeql: + name: "Checks" + uses: ./.github/workflows/codeql.yml + permissions: + actions: read + contents: read + security-events: write diff --git a/.github/workflows/on.push.yml b/.github/workflows/on.push.yml new file mode 100644 index 000000000000..2afcceb30c50 --- /dev/null +++ b/.github/workflows/on.push.yml @@ -0,0 +1,31 @@ +name: Push + +on: + push: + branches: + - master + +permissions: + contents: read + +jobs: + ## Run main CI build and tests. + run-ci: + name: "Build & Test" + uses: ./.github/workflows/ci.yml + permissions: + actions: write + contents: write + + ## Publish and check the dependency graph. + checks-dependency-graph: + name: "Checks" + uses: ./.github/workflows/dependency-review.yml + permissions: + contents: write + id-token: write + + ## Validate the Gradle Wrapper binary + checks-gradle-wrapper: + name: "Checks" + uses: ./.github/workflows/gradle-wrapper-validation.yml From 4a825dff61b24f12e19970495224614e3e32f535 Mon Sep 17 00:00:00 2001 From: Sam Gammon Date: Thu, 7 Mar 2024 20:52:41 -0800 Subject: [PATCH 03/15] chore(ci): switch to enforced hardening mode This changeset switches the StepSecurity hardening action to enforced mode, where previously it was running in `audit` mode. Now, audit logs have been gathered and it is time to seal off the list of accessible network endpoints for a given job. - chore: gather and apply network endpoints for each job - chore: move to `block` mode for `egress-policy` in `step-security/harden-runner` Signed-off-by: Sam Gammon --- .github/workflows/ci.yml | 26 ++++++++++++------- .github/workflows/codeql.yml | 15 ++++++++++- .github/workflows/dependency-review.yml | 8 +++++- .../workflows/gradle-wrapper-validation.yml | 5 +++- 4 files changed, 42 insertions(+), 12 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 20181531a1e9..ec52065d2752 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,12 +12,12 @@ jobs: permissions: actions: write # for styfle/cancel-workflow-action to cancel/stop running workflows contents: read # for actions/checkout to fetch code - name: "${{ matrix.root-pom }} on JDK ${{ matrix.java }} on ${{ matrix.os }}" + name: "JDK ${{ matrix.java }} / ${{ matrix.mode }} (${{ matrix.os }})" strategy: matrix: os: [ ubuntu-latest ] java: [ 8, 11, 17 ] - root-pom: [ 'pom.xml', 'android/pom.xml' ] + mode: [ 'JRE', 'Android' ] include: - os: windows-latest java: 17 @@ -29,17 +29,25 @@ jobs: root-pom: pom.xml runs-on: ${{ matrix.os }} env: - ROOT_POM: ${{ matrix.root-pom }} + ROOT_POM: ${{ matrix.root-pom == 'Android' && 'android/pom.xml' || 'pom.xml' }} steps: - # Cancel any previous runs for the same branch that are still running. - name: Harden Runner uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 with: - egress-policy: audit - - name: 'Cancel previous runs' - uses: styfle/cancel-workflow-action@85880fa0301c86cca9da44039ee3bb12d3bedbfa # 0.12.1 - with: - access_token: ${{ github.token }} + disable-sudo: true + egress-policy: block + allowed-endpoints: > + api.azul.com:443 + api.github.com:443 + cdn.azul.com:443 + dl.google.com:443 + docs.oracle.com:443 + errorprone.info:443 + github.com:443 + objects.githubusercontent.com:443 + oss.sonatype.org:443 + repo.maven.apache.org:443 + services.gradle.org:443 - name: 'Check out repository' uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 with: diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 5835c9c94667..6a71219be7e3 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -42,7 +42,20 @@ jobs: - name: Harden Runner uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 with: - egress-policy: audit + disable-sudo: true + egress-policy: block + allowed-endpoints: > + api.azul.com:443 + api.github.com:443 + cdn.azul.com:443 + dl.google.com:443 + docs.oracle.com:443 + errorprone.info:443 + github.com:443 + objects.githubusercontent.com:443 + oss.sonatype.org:443 + repo.maven.apache.org:443 + services.gradle.org:443 - name: Checkout repository uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 with: diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index ea5d4df36afa..f302b07d983b 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -27,7 +27,13 @@ jobs: - name: Harden Runner uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 with: - egress-policy: audit + disable-sudo: true + egress-policy: block + allowed-endpoints: > + api.github.com:443 + github.com:443 + oss.sonatype.org:443 + repo.maven.apache.org:443 - name: 'Checkout Repository' uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Maven Dependency Tree Dependency Submission diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml index 1f1cd14b51c9..bedc36698d20 100644 --- a/.github/workflows/gradle-wrapper-validation.yml +++ b/.github/workflows/gradle-wrapper-validation.yml @@ -14,7 +14,10 @@ jobs: - name: Harden Runner uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 with: - egress-policy: audit + disable-sudo: true + egress-policy: block + allowed-endpoints: > + github.com:443 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 with: persist-credentials: false From 31002ed6f92871e8b3d726e3099940906f70d057 Mon Sep 17 00:00:00 2001 From: Sam Gammon Date: Thu, 7 Mar 2024 21:08:32 -0800 Subject: [PATCH 04/15] feat(ci): slsa provenance support This changeset adds SLSA 3+ provenance support to the workflow. The main CI run has now been split into two: `ci.build.yml`, which only builds the library and is provenance-capable, and `ci.test.yml`, which is the previous CI logic. The regular build logic is applied only on push, and can be applied on PRs too, with publish of provenance material turned off. The test suite is invoked from PRs. The workflows have been split into build/test phases to avoid publishing provenance data and GitHub artifacts for build matrix outputs. JARs are uniform across OS targets, so there is no need to gather and publish for more than Ubuntu. - feat: add slsa support to build workflow - chore: split `test` into `build` and `test` workflows - chore: use new workflows (build/test) from push/pr triggers Signed-off-by: Sam Gammon --- .github/workflows/ci.build.yml | 183 ++++++++++++++++++++++ .github/workflows/{ci.yml => ci.test.yml} | 98 +++++------- .github/workflows/on.pr.yml | 20 ++- .github/workflows/on.push.yml | 8 +- 4 files changed, 247 insertions(+), 62 deletions(-) create mode 100644 .github/workflows/ci.build.yml rename .github/workflows/{ci.yml => ci.test.yml} (52%) diff --git a/.github/workflows/ci.build.yml b/.github/workflows/ci.build.yml new file mode 100644 index 000000000000..79448d235219 --- /dev/null +++ b/.github/workflows/ci.build.yml @@ -0,0 +1,183 @@ +name: Build + +on: + workflow_call: + inputs: + provenance: + type: boolean + description: "Provenance" + default: false + provenance_publish: + type: boolean + description: "Publish: Provenance" + default: true + snapshot: + type: boolean + description: "Publish: Snapshot" + default: false + repository: + type: string + description: "Publish Repository" + default: "sonatype-nexus-snapshots" + + workflow_dispatch: + inputs: + provenance: + type: boolean + description: "Provenance" + default: false + provenance_publish: + type: boolean + description: "Publish: Provenance" + default: false + snapshot: + type: boolean + description: "Publish: Snapshot" + default: true + repository: + type: string + description: "Publish Repository" + default: "sonatype-nexus-snapshots" + +permissions: + contents: read + +jobs: + build: + strategy: + fail-fast: false + matrix: + mode: ["JRE", "Android"] + name: "Build Guava (${{ matrix.mode }})" + runs-on: ubuntu-latest + permissions: + contents: read # for actions/checkout to fetch code + outputs: + hashes: ${{ steps.hash.outputs.hashes }} + env: + ROOT_POM: ${{ matrix.mode == 'Android' && 'android/pom.xml' || 'pom.xml' }} + steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + disable-sudo: true + egress-policy: block + allowed-endpoints: > + api.azul.com:443 + api.github.com:443 + cdn.azul.com:443 + dl.google.com:443 + docs.oracle.com:443 + errorprone.info:443 + github.com:443 + objects.githubusercontent.com:443 + oss.sonatype.org:443 + repo.maven.apache.org:443 + services.gradle.org:443 + - name: 'Check out repository' + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + with: + persist-credentials: false + - name: 'Set up JDK 11' + uses: actions/setup-java@9704b39bf258b59bc04b50fa2dd55e9ed76b47a8 # v4.1.0 + with: + java-version: 11 + distribution: 'zulu' + cache: 'maven' + - name: 'Install' + shell: bash + run: ./mvnw -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn install -U -DskipTests=true -f $ROOT_POM + - name: Generate hashes + shell: bash + id: hash + if: matrix.mode == 'JRE' + run: | + echo "Building SLSA provenance material..." + ls guava/target/*.jar guava-gwt/target/*.jar guava-testlib/target/*.jar + echo "hashes=$(sha256sum guava/target/*.jar guava-gwt/target/*.jar guava-testlib/target/*.jar | base64 -w0)" >> ./provenance-hashes.txt + cat ./provenance-hashes.txt >> "$GITHUB_OUTPUT" + echo "Gathered provenance hashes:" + cat ./provenance-hashes.txt + - name: 'Upload artifacts' + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 + if: matrix.mode == 'JRE' + with: + name: guava-artifacts-${{ matrix.mode == 'Android' && 'android' || 'jre' }}-${{ github.sha }} + path: | + guava/target/*.jar + guava-gwt/target/*.jar + guava-testlib/target/*.jar + ./provenance-hashes.txt + if-no-files-found: warn + retention-days: 7 + + # Generate SLSA provenance + provenance: + needs: [build] + if: inputs.provenance + name: "SLSA Provenance" + uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v1.9.0 + permissions: + actions: read + id-token: write + contents: write + with: + base64-subjects: "${{ needs.build.outputs.hashes }}" + upload-assets: ${{ inputs.provenance_publish }} + + # Publish snapshot JAR + publish_snapshot: + name: 'Publish Snapshot' + needs: [build, provenance] + if: inputs.snapshot + runs-on: ubuntu-latest + steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: 'Check out repository' + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - name: 'Set up JDK 11' + uses: actions/setup-java@9704b39bf258b59bc04b50fa2dd55e9ed76b47a8 # v4.1.0 + with: + java-version: 11 + distribution: 'zulu' + server-id: ${{ inputs.repository }} + server-username: CI_DEPLOY_USERNAME + server-password: CI_DEPLOY_PASSWORD + cache: 'maven' + - name: "Download artifacts" + uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 + with: + name: guava-artifacts-jre-${{ github.sha }} + - name: 'Publish' + env: + CI_DEPLOY_USERNAME: ${{ secrets.CI_DEPLOY_USERNAME }} + CI_DEPLOY_PASSWORD: ${{ secrets.CI_DEPLOY_PASSWORD }} + run: ./util/deploy_snapshot.sh + + generate_docs: + permissions: + contents: write + name: 'Generate Docs' + needs: build + if: github.event_name == 'push' && github.repository == 'google/guava' + runs-on: ubuntu-latest + steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: 'Check out repository' + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - name: 'Set up JDK 11' + uses: actions/setup-java@9704b39bf258b59bc04b50fa2dd55e9ed76b47a8 # v4.1.0 + with: + java-version: 11 + distribution: 'zulu' + cache: 'maven' + - name: 'Generate latest docs' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: ./util/update_snapshot_docs.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.test.yml similarity index 52% rename from .github/workflows/ci.yml rename to .github/workflows/ci.test.yml index ec52065d2752..cff79c26c1a2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.test.yml @@ -1,8 +1,43 @@ -name: CI +name: Tests on: - workflow_call: {} - workflow_dispatch: {} + workflow_call: + inputs: + provenance: + type: boolean + description: "Provenance" + default: false + provenance_publish: + type: boolean + description: "Publish: Provenance" + default: true + snapshot: + type: boolean + description: "Publish: Snapshot" + default: false + repository: + type: string + description: "Publish Repository" + default: "sonatype-nexus-snapshots" + + workflow_dispatch: + inputs: + provenance: + type: boolean + description: "Provenance" + default: false + provenance_publish: + type: boolean + description: "Publish: Provenance" + default: false + snapshot: + type: boolean + description: "Publish: Snapshot" + default: true + repository: + type: string + description: "Publish Repository" + default: "sonatype-nexus-snapshots" permissions: contents: read @@ -10,9 +45,8 @@ permissions: jobs: test: permissions: - actions: write # for styfle/cancel-workflow-action to cancel/stop running workflows contents: read # for actions/checkout to fetch code - name: "JDK ${{ matrix.java }} / ${{ matrix.mode }} (${{ matrix.os }})" + name: "JDK ${{ matrix.java }} ${{ matrix.mode }} (${{ matrix.os }})" strategy: matrix: os: [ ubuntu-latest ] @@ -28,6 +62,8 @@ jobs: mode: Android root-pom: pom.xml runs-on: ${{ matrix.os }} + outputs: + hashes: ${{ steps.hash.outputs.hashes }} env: ROOT_POM: ${{ matrix.root-pom == 'Android' && 'android/pom.xml' || 'pom.xml' }} steps: @@ -73,55 +109,3 @@ jobs: if: matrix.java == 11 shell: bash run: util/gradle_integration_tests.sh - - publish_snapshot: - name: 'Publish snapshot' - needs: test - if: github.event_name == 'push' && github.repository == 'google/guava' - runs-on: ubuntu-latest - steps: - - name: Harden Runner - uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 - with: - egress-policy: audit - - name: 'Check out repository' - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - - name: 'Set up JDK 11' - uses: actions/setup-java@9704b39bf258b59bc04b50fa2dd55e9ed76b47a8 # v4.1.0 - with: - java-version: 11 - distribution: 'zulu' - server-id: sonatype-nexus-snapshots - server-username: CI_DEPLOY_USERNAME - server-password: CI_DEPLOY_PASSWORD - cache: 'maven' - - name: 'Publish' - env: - CI_DEPLOY_USERNAME: ${{ secrets.CI_DEPLOY_USERNAME }} - CI_DEPLOY_PASSWORD: ${{ secrets.CI_DEPLOY_PASSWORD }} - run: ./util/deploy_snapshot.sh - - generate_docs: - permissions: - contents: write - name: 'Generate latest docs' - needs: test - if: github.event_name == 'push' && github.repository == 'google/guava' - runs-on: ubuntu-latest - steps: - - name: Harden Runner - uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 - with: - egress-policy: audit - - name: 'Check out repository' - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - - name: 'Set up JDK 11' - uses: actions/setup-java@9704b39bf258b59bc04b50fa2dd55e9ed76b47a8 # v4.1.0 - with: - java-version: 11 - distribution: 'zulu' - cache: 'maven' - - name: 'Generate latest docs' - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: ./util/update_snapshot_docs.sh diff --git a/.github/workflows/on.pr.yml b/.github/workflows/on.pr.yml index dd0b9e7c3b0c..404f308f2319 100644 --- a/.github/workflows/on.pr.yml +++ b/.github/workflows/on.pr.yml @@ -9,13 +9,27 @@ permissions: contents: read jobs: + ## Build the library and provenance material, but don't publish + build: + name: "Build" + uses: ./.github/workflows/ci.build.yml + permissions: + actions: write + contents: write + id-token: write + with: + provenance: true + provenance_publish: false + snapshot: false + ## Run main CI build and tests. - run-ci: - name: "Build & Test" - uses: ./.github/workflows/ci.yml + test: + name: "Tests" + uses: ./.github/workflows/ci.test.yml permissions: actions: write contents: write + id-token: write ## Validate the Gradle Wrapper binary checks-gradle-wrapper: diff --git a/.github/workflows/on.push.yml b/.github/workflows/on.push.yml index 2afcceb30c50..76a87d7a6551 100644 --- a/.github/workflows/on.push.yml +++ b/.github/workflows/on.push.yml @@ -11,11 +11,15 @@ permissions: jobs: ## Run main CI build and tests. run-ci: - name: "Build & Test" - uses: ./.github/workflows/ci.yml + name: "Build" + uses: ./.github/workflows/ci.build.yml permissions: actions: write contents: write + id-token: write + with: + snapshot: github.repository == 'google/guava' + provenance: true ## Publish and check the dependency graph. checks-dependency-graph: From 3cd91de67d0f15f83311dcf747fc9d0ff6cbae54 Mon Sep 17 00:00:00 2001 From: Sam Gammon Date: Thu, 7 Mar 2024 22:05:03 -0800 Subject: [PATCH 05/15] chore(build): parameterize deploy repositories Adds two build parameters - `publishing.repository.snapshots`: Snapshot repo to deploy to - `publishing.repository.releases`: Releases repo to deploy to Both default to their current values, Sonatype. This small inert change allows a fork to easily publish to a different repository without resorting to a code change. Signed-off-by: Sam Gammon --- pom.xml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 83c3fa11ab3b..eacf7be35745 100644 --- a/pom.xml +++ b/pom.xml @@ -31,6 +31,8 @@ HEAD-android-SNAPSHOT android android + https://oss.sonatype.org/content/repositories/snapshots/ + https://oss.sonatype.org/service/local/staging/deploy/maven2/ GitHub Issues @@ -271,12 +273,12 @@ sonatype-nexus-snapshots Sonatype Nexus Snapshots - https://oss.sonatype.org/content/repositories/snapshots/ + ${publishing.repository.snapshots} sonatype-nexus-staging Nexus Release Repository - https://oss.sonatype.org/service/local/staging/deploy/maven2/ + ${publishing.repository.releases} guava-site From 63aa4ead481e41f18967079ecc3e49f73b083f95 Mon Sep 17 00:00:00 2001 From: Sam Gammon Date: Thu, 7 Mar 2024 22:10:45 -0800 Subject: [PATCH 06/15] feat(build): sigstore publishing plugin This changeset adds the Maven Sigstore plugin for use during publishing to Sonatype and other public repositories. - chore: add sigstore plugin to build Signed-off-by: Sam Gammon --- pom.xml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/pom.xml b/pom.xml index eacf7be35745..c6e62e1d2f12 100644 --- a/pom.xml +++ b/pom.xml @@ -320,6 +320,19 @@ sonatype-oss-release + + dev.sigstore + sigstore-maven-plugin + 0.4.0 + + + sign + + sign + + + + maven-gpg-plugin 3.0.1 From 1f9bc696bdfbea7d1ddce0b20c4dc3c05927d10a Mon Sep 17 00:00:00 2001 From: Sam Gammon Date: Thu, 7 Mar 2024 22:56:44 -0800 Subject: [PATCH 07/15] chore(ci): build with `--strict-checksums` Fails the build if any downloaded dependencies fail their checksum verification. - chore: add `--strict-checksums` flag to `mvnw` calls in ci --- .github/workflows/ci.build.yml | 2 +- .github/workflows/ci.test.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.build.yml b/.github/workflows/ci.build.yml index 79448d235219..7a13f13c9caa 100644 --- a/.github/workflows/ci.build.yml +++ b/.github/workflows/ci.build.yml @@ -86,7 +86,7 @@ jobs: cache: 'maven' - name: 'Install' shell: bash - run: ./mvnw -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn install -U -DskipTests=true -f $ROOT_POM + run: ./mvnw --strict-checksums -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn install -U -DskipTests=true -f $ROOT_POM - name: Generate hashes shell: bash id: hash diff --git a/.github/workflows/ci.test.yml b/.github/workflows/ci.test.yml index cff79c26c1a2..5ce567ae709d 100644 --- a/.github/workflows/ci.test.yml +++ b/.github/workflows/ci.test.yml @@ -96,10 +96,10 @@ jobs: cache: 'maven' - name: 'Install' shell: bash - run: ./mvnw -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn install -U -DskipTests=true -f $ROOT_POM + run: ./mvnw --strict-checksums -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn install -U -DskipTests=true -f $ROOT_POM - name: 'Test' shell: bash - run: ./mvnw -B -P!standard-with-extra-repos verify -U -Dmaven.javadoc.skip=true -f $ROOT_POM + run: ./mvnw --strict-checksums -B -P!standard-with-extra-repos verify -U -Dmaven.javadoc.skip=true -f $ROOT_POM - name: 'Print Surefire reports' # Note: Normally a step won't run if the job has failed, but this causes it to if: ${{ failure() }} From 5cf768afd5ddad264ccb5afb2ca77b84e3208ac9 Mon Sep 17 00:00:00 2001 From: Sam Gammon Date: Thu, 7 Mar 2024 23:17:57 -0800 Subject: [PATCH 08/15] chore(ci): document gha workflows Signed-off-by: Sam Gammon --- .github/workflows/ci.build.yml | 21 +++++++++++++++++++++ .github/workflows/ci.test.yml | 21 +++++++++++++++++++++ .github/workflows/dependency-review.yml | 13 +++++++++++++ .github/workflows/on.pr.yml | 8 ++++++++ .github/workflows/on.push.yml | 8 ++++++++ 5 files changed, 71 insertions(+) diff --git a/.github/workflows/ci.build.yml b/.github/workflows/ci.build.yml index 7a13f13c9caa..460bce180945 100644 --- a/.github/workflows/ci.build.yml +++ b/.github/workflows/ci.build.yml @@ -1,3 +1,24 @@ +# Guava GitHub CI +# --------------------------------------------------------------------------------------------------------------------- +# This is the main CI build on GitHub for the Google Guava project. This workflow is not invoked directly; instead, the +# `on.pr.yml` and `on.push.yml` workflows kick in on PR and push events, respectively, and call this workflow as a +# Reusable Workflow. +# +# This workflow can be tested independently of the entrypoint flow through the `workflow_dispatch` hook, which adds a +# button within the UI of the GitHub repository. You can trigger the workflow from here: +# +# https://github.com/google/guava/actions/workflows/ci.build.yml +# +# ## Inputs +# +# See the set of input parameters underneath the `workflow_call` and `workflow_dispatch` hooks for ways this workflow +# can be controlled when called. +# +# ## SLSA Provenance +# +# After building Guava in both JRE and Android variants, this workflow will (if enabled) generate provenance material +# and upload it to an associated release. Learn more about SLSA here: https://slsa.dev. + name: Build on: diff --git a/.github/workflows/ci.test.yml b/.github/workflows/ci.test.yml index 5ce567ae709d..bf65ba5c0e7b 100644 --- a/.github/workflows/ci.test.yml +++ b/.github/workflows/ci.test.yml @@ -1,3 +1,24 @@ +# Guava GitHub CI +# --------------------------------------------------------------------------------------------------------------------- +# This is the main CI testsuite on GitHub for the Google Guava project. This workflow is not invoked directly; instead, +# the `on.pr.yml` and `on.push.yml` workflows kick in on PR and push events, respectively, and call this workflow as a +# Reusable Workflow. +# +# This workflow can be tested independently of the entrypoint flow through the `workflow_dispatch` hook, which adds a +# button within the UI of the GitHub repository. You can trigger the workflow from here: +# +# https://github.com/google/guava/actions/workflows/ci.test.yml +# +# ## Inputs +# +# See the set of input parameters underneath the `workflow_call` and `workflow_dispatch` hooks for ways this workflow +# can be controlled when called. +# +# ## Multi-OS and Multi-JVM Testing +# +# Guava is tested against each LTS release at JDK 8 through JDK 21, on Linux and on Windows (starting at JDK 17), and +# in Android and JRE flavors. + name: Tests on: diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index f302b07d983b..abc802dae2ac 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -1,3 +1,16 @@ +# Guava GitHub CI +# --------------------------------------------------------------------------------------------------------------------- +# This workflow is called from `on.push.yml` and `on.pr.yml` to operate on Guava's dependency graph: +# +# - The dependency graph is calculated from pom.xml files +# - The graph is then published to GitHub, and associated with the Guava repository +# - When operating on a PR, Dependency Review can be invoked to check dependency changes +# +# ## Inputs +# +# See the set of input parameters underneath the `workflow_call` and `workflow_dispatch` hooks for ways this workflow +# can be controlled when called. + name: 'Dependency Graph' on: workflow_call: diff --git a/.github/workflows/on.pr.yml b/.github/workflows/on.pr.yml index 404f308f2319..a7cd494d7e69 100644 --- a/.github/workflows/on.pr.yml +++ b/.github/workflows/on.pr.yml @@ -1,3 +1,11 @@ +# Guava GitHub CI +# --------------------------------------------------------------------------------------------------------------------- +# This is an entrypoint workflow which operates on pull requests; this workflow doesn't do much on its own. Its job is +# to dispatch `on.build.yml` and check workflows, which can be found in this same directory. +# +# PR workflows are slightly different from push workflows (for example, they do not publish snapshots). See the +# `on.push.yml` workflow. PR and push flows are designed to be invoked separately. + name: PR on: diff --git a/.github/workflows/on.push.yml b/.github/workflows/on.push.yml index 76a87d7a6551..d34a85f6c1e7 100644 --- a/.github/workflows/on.push.yml +++ b/.github/workflows/on.push.yml @@ -1,3 +1,11 @@ +# Guava GitHub CI +# --------------------------------------------------------------------------------------------------------------------- +# This is an entrypoint workflow which operates on pushed revisions to Guava; this workflow doesn't do much on its own. +# Its job is to dispatch `on.build.yml` and check workflows, which can be found in this same directory. +# +# PR workflows are slightly different from push workflows (for example, the push workflow publishes snapshots). See the +# `on.pr.yml` workflow. PR and push flows are designed to be invoked separately. + name: Push on: From 97c12283c00d79c779c910aa983cac5f338be8d2 Mon Sep 17 00:00:00 2001 From: Sam Gammon Date: Fri, 8 Mar 2024 00:05:11 -0800 Subject: [PATCH 09/15] chore: add spdx plugin Signed-off-by: Sam Gammon --- guava/pom.xml | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/guava/pom.xml b/guava/pom.xml index 913fc387a619..2d9b1ab4b213 100644 --- a/guava/pom.xml +++ b/guava/pom.xml @@ -248,12 +248,43 @@ + + spdx + + 11 + + + + + org.spdx + spdx-maven-plugin + 0.7.3 + + + build-spdx + + createSPDX + + + + + true + false + + + + + srczip-parent ${java.home}/../src.zip + + maven.javadoc.skip + false + @@ -272,6 +303,10 @@ ${java.home}/lib/src.zip + + maven.javadoc.skip + false + From bcdfeeaa1243ebd291d65f201bc617da4d02c036 Mon Sep 17 00:00:00 2001 From: Sam Gammon Date: Fri, 8 Mar 2024 10:45:09 -0800 Subject: [PATCH 10/15] fixup! cleanup test workflow Signed-off-by: Sam Gammon --- .github/workflows/ci.test.yml | 39 ++--------------------------------- 1 file changed, 2 insertions(+), 37 deletions(-) diff --git a/.github/workflows/ci.test.yml b/.github/workflows/ci.test.yml index bf65ba5c0e7b..812d82244369 100644 --- a/.github/workflows/ci.test.yml +++ b/.github/workflows/ci.test.yml @@ -22,43 +22,8 @@ name: Tests on: - workflow_call: - inputs: - provenance: - type: boolean - description: "Provenance" - default: false - provenance_publish: - type: boolean - description: "Publish: Provenance" - default: true - snapshot: - type: boolean - description: "Publish: Snapshot" - default: false - repository: - type: string - description: "Publish Repository" - default: "sonatype-nexus-snapshots" - - workflow_dispatch: - inputs: - provenance: - type: boolean - description: "Provenance" - default: false - provenance_publish: - type: boolean - description: "Publish: Provenance" - default: false - snapshot: - type: boolean - description: "Publish: Snapshot" - default: true - repository: - type: string - description: "Publish Repository" - default: "sonatype-nexus-snapshots" + workflow_call: {} + workflow_dispatch: {} permissions: contents: read From f66df3e94e2f90085fa070f00bf01968e199ea12 Mon Sep 17 00:00:00 2001 From: Sam Gammon Date: Fri, 8 Mar 2024 10:48:16 -0800 Subject: [PATCH 11/15] fixup! cleanup codeql job Signed-off-by: Sam Gammon --- .github/workflows/codeql.yml | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 6a71219be7e3..f7ac0f8e3d35 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -1,14 +1,3 @@ -# For most projects, this workflow file will not need changing; you simply need -# to commit it to your repository. -# -# You may wish to alter this file to override the set of languages analyzed, -# or to provide custom queries or build logic. -# -# ******** NOTE ******** -# We have attempted to detect the languages in your repository. Please check -# the `language` matrix defined below to confirm you have the correct set of -# supported CodeQL languages. -# name: "CodeQL" on: From 55f607b4af3b0f3e40bc0d9ca45ca030c5742641 Mon Sep 17 00:00:00 2001 From: cpovirk Date: Fri, 8 Mar 2024 16:18:25 -0800 Subject: [PATCH 12/15] Avoid calling `checkNotNull` on nullable values except during actual precondition checks. It's not that we're not going to make such calls illegal, I promise :) I mean, we certainly aren't going to _in general_, but I am tempted for `com.google.common`, as discussed on cl/372346107 :) (It would have caught the problem of cl/612591080!) I'm testing what would happen if we did do it for `com.google.common` in case it shakes out any more bugs. It does reveal that I didn't complete the cleanup of cl/612591080. And it reveals a few places where we'd normally use `requireNonNull`, since the checks aren't "preconditions" in the sense of "the caller did something wrong" (from cl/15376243 and cl/526930990). I've made those changes. (I would have made some more changes if I had tried to address more of `com.google.common`. But I stuck to the "main" packages, and I didn't even fix enough errors to see full results.) Honestly, the more interesting thing that this exercise revealed was that there are more cases in which I'm especially sympathetic to calling `checkNotNull` on nullable values: - `DummyProxy` is making an `InvocationHandler` perform automatic precondition tests based on annotations on the interface it's implementing. - `EqualsTester` and Truth have permissive signatures because they're test utilities, as documented in cl/578260904 and discussed during the Truth CLs. And the yet more interesting thing that it revealed is that we may want to use `@NonNull` here in the future, similar to what we've discussed in https://github.com/google/guava/issues/6824. RELNOTES=n/a PiperOrigin-RevId: 614074533 --- .../google/common/testing/FreshValueGenerator.java | 3 ++- .../com/google/common/collect/TableCollectors.java | 14 ++++++-------- .../com/google/common/collect/TreeMultimap.java | 5 +++-- .../google/common/testing/FreshValueGenerator.java | 3 ++- .../com/google/common/collect/TableCollectors.java | 14 ++++++-------- .../com/google/common/collect/TreeMultimap.java | 5 +++-- 6 files changed, 22 insertions(+), 22 deletions(-) diff --git a/android/guava-testlib/src/com/google/common/testing/FreshValueGenerator.java b/android/guava-testlib/src/com/google/common/testing/FreshValueGenerator.java index 4cc25e1289fb..d1a7819f1977 100644 --- a/android/guava-testlib/src/com/google/common/testing/FreshValueGenerator.java +++ b/android/guava-testlib/src/com/google/common/testing/FreshValueGenerator.java @@ -18,6 +18,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Throwables.throwIfUnchecked; +import static java.util.Objects.requireNonNull; import com.google.common.annotations.GwtIncompatible; import com.google.common.annotations.J2ktIncompatible; @@ -211,7 +212,7 @@ final T newFreshProxy(final Class interfaceType) { return pickInstance(rawType.getEnumConstants(), null); } if (type.isArray()) { - TypeToken componentType = checkNotNull(type.getComponentType()); + TypeToken componentType = requireNonNull(type.getComponentType()); Object array = Array.newInstance(componentType.getRawType(), 1); Array.set(array, 0, generate(componentType)); return array; diff --git a/android/guava/src/com/google/common/collect/TableCollectors.java b/android/guava/src/com/google/common/collect/TableCollectors.java index 0508c4802fc9..f53569627e5e 100644 --- a/android/guava/src/com/google/common/collect/TableCollectors.java +++ b/android/guava/src/com/google/common/collect/TableCollectors.java @@ -199,14 +199,12 @@ void merge(V value, BinaryOperator mergeFunction) { } } - private static < - R extends @Nullable Object, C extends @Nullable Object, V extends @Nullable Object> - void mergeTables( - Table table, - @ParametricNullness R row, - @ParametricNullness C column, - @ParametricNullness V value, - BinaryOperator mergeFunction) { + private static void mergeTables( + Table table, + @ParametricNullness R row, + @ParametricNullness C column, + V value, + BinaryOperator mergeFunction) { checkNotNull(value); V oldValue = table.get(row, column); if (oldValue == null) { diff --git a/android/guava/src/com/google/common/collect/TreeMultimap.java b/android/guava/src/com/google/common/collect/TreeMultimap.java index 8e2afe3594eb..289ea54f67b2 100644 --- a/android/guava/src/com/google/common/collect/TreeMultimap.java +++ b/android/guava/src/com/google/common/collect/TreeMultimap.java @@ -17,6 +17,7 @@ package com.google.common.collect; import static com.google.common.base.Preconditions.checkNotNull; +import static java.util.Objects.requireNonNull; import com.google.common.annotations.GwtCompatible; import com.google.common.annotations.GwtIncompatible; @@ -217,8 +218,8 @@ private void writeObject(ObjectOutputStream stream) throws IOException { @SuppressWarnings("unchecked") // reading data stored by writeObject private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { stream.defaultReadObject(); - keyComparator = checkNotNull((Comparator) stream.readObject()); - valueComparator = checkNotNull((Comparator) stream.readObject()); + keyComparator = requireNonNull((Comparator) stream.readObject()); + valueComparator = requireNonNull((Comparator) stream.readObject()); setMap(new TreeMap>(keyComparator)); Serialization.populateMultimap(this, stream); } diff --git a/guava-testlib/src/com/google/common/testing/FreshValueGenerator.java b/guava-testlib/src/com/google/common/testing/FreshValueGenerator.java index 65e50df176e6..567b7a76aac7 100644 --- a/guava-testlib/src/com/google/common/testing/FreshValueGenerator.java +++ b/guava-testlib/src/com/google/common/testing/FreshValueGenerator.java @@ -18,6 +18,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Throwables.throwIfUnchecked; +import static java.util.Objects.requireNonNull; import com.google.common.annotations.GwtIncompatible; import com.google.common.annotations.J2ktIncompatible; @@ -215,7 +216,7 @@ final T newFreshProxy(final Class interfaceType) { return pickInstance(rawType.getEnumConstants(), null); } if (type.isArray()) { - TypeToken componentType = checkNotNull(type.getComponentType()); + TypeToken componentType = requireNonNull(type.getComponentType()); Object array = Array.newInstance(componentType.getRawType(), 1); Array.set(array, 0, generate(componentType)); return array; diff --git a/guava/src/com/google/common/collect/TableCollectors.java b/guava/src/com/google/common/collect/TableCollectors.java index 1164e822de53..ca67a693aec4 100644 --- a/guava/src/com/google/common/collect/TableCollectors.java +++ b/guava/src/com/google/common/collect/TableCollectors.java @@ -195,14 +195,12 @@ void merge(V value, BinaryOperator mergeFunction) { } } - private static < - R extends @Nullable Object, C extends @Nullable Object, V extends @Nullable Object> - void mergeTables( - Table table, - @ParametricNullness R row, - @ParametricNullness C column, - @ParametricNullness V value, - BinaryOperator mergeFunction) { + private static void mergeTables( + Table table, + @ParametricNullness R row, + @ParametricNullness C column, + V value, + BinaryOperator mergeFunction) { checkNotNull(value); V oldValue = table.get(row, column); if (oldValue == null) { diff --git a/guava/src/com/google/common/collect/TreeMultimap.java b/guava/src/com/google/common/collect/TreeMultimap.java index 8e2afe3594eb..289ea54f67b2 100644 --- a/guava/src/com/google/common/collect/TreeMultimap.java +++ b/guava/src/com/google/common/collect/TreeMultimap.java @@ -17,6 +17,7 @@ package com.google.common.collect; import static com.google.common.base.Preconditions.checkNotNull; +import static java.util.Objects.requireNonNull; import com.google.common.annotations.GwtCompatible; import com.google.common.annotations.GwtIncompatible; @@ -217,8 +218,8 @@ private void writeObject(ObjectOutputStream stream) throws IOException { @SuppressWarnings("unchecked") // reading data stored by writeObject private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { stream.defaultReadObject(); - keyComparator = checkNotNull((Comparator) stream.readObject()); - valueComparator = checkNotNull((Comparator) stream.readObject()); + keyComparator = requireNonNull((Comparator) stream.readObject()); + valueComparator = requireNonNull((Comparator) stream.readObject()); setMap(new TreeMap>(keyComparator)); Serialization.populateMultimap(this, stream); } From 67b1add71a655290ae884a99a5cdf024278847d6 Mon Sep 17 00:00:00 2001 From: cpovirk Date: Sat, 9 Mar 2024 15:32:40 -0800 Subject: [PATCH 13/15] Bump `j2objc-annotations` to 3.0.0. This is another baby step toward https://github.com/google/guava/issues/2970. RELNOTES=n/a PiperOrigin-RevId: 614287410 --- android/pom.xml | 2 +- integration-tests/gradle/build.gradle.kts | 4 ++-- pom.xml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/android/pom.xml b/android/pom.xml index d59ce39455b6..52837fa733d4 100644 --- a/android/pom.xml +++ b/android/pom.xml @@ -18,7 +18,7 @@ 3.0.2 3.42.0 2.24.1 - 2.8 + 3.0.0 9+181-r4173-1 diff --git a/integration-tests/gradle/build.gradle.kts b/integration-tests/gradle/build.gradle.kts index cafccc49b790..51c733a8cb6e 100644 --- a/integration-tests/gradle/build.gradle.kts +++ b/integration-tests/gradle/build.gradle.kts @@ -23,9 +23,9 @@ val expectedReducedRuntimeClasspathJreVersion = "listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar" ) val expectedCompileClasspathAndroidVersion = - expectedReducedRuntimeClasspathAndroidVersion + setOf("j2objc-annotations-2.8.jar") + expectedReducedRuntimeClasspathAndroidVersion + setOf("j2objc-annotations-3.0.0.jar") val expectedCompileClasspathJreVersion = - expectedReducedRuntimeClasspathJreVersion + setOf("j2objc-annotations-2.8.jar") + expectedReducedRuntimeClasspathJreVersion + setOf("j2objc-annotations-3.0.0.jar") val extraLegacyDependencies = setOf("google-collections-1.0.jar") diff --git a/pom.xml b/pom.xml index c6e62e1d2f12..97c774015192 100644 --- a/pom.xml +++ b/pom.xml @@ -18,7 +18,7 @@ 3.0.2 3.42.0 2.24.1 - 2.8 + 3.0.0 9+181-r4173-1 From 2d6a7e466b0893a729b38ae4c870bb8a64c23973 Mon Sep 17 00:00:00 2001 From: Sam Gammon Date: Fri, 8 Mar 2024 13:56:17 -0800 Subject: [PATCH 14/15] fix: drop jdk srzip javadoc infra - chore: drop jdk srczip dependencies - chore: cleanup comments and config related to srczip Signed-off-by: Sam Gammon --- android/guava/pom.xml | 69 --------------------------- guava/pom.xml | 107 ------------------------------------------ 2 files changed, 176 deletions(-) diff --git a/android/guava/pom.xml b/android/guava/pom.xml index 7444cd6972ba..18a37fae8be8 100644 --- a/android/guava/pom.xml +++ b/android/guava/pom.xml @@ -106,23 +106,8 @@ maven-source-plugin - maven-dependency-plugin - - - unpack-jdk-sources - generate-sources - unpack-dependencies - - srczip - ${project.build.directory}/jdk-sources - false - - **/module-info.java,**/java/io/FileDescriptor.java - - - org.codehaus.mojo @@ -131,11 +116,6 @@ maven-javadoc-plugin - - - - ${project.build.sourceDirectory}:${project.build.directory}/jdk-sources - @@ -247,53 +227,4 @@ - - - srczip-parent - - - ${java.home}/../src.zip - - - - - jdk - srczip - 999 - system - ${java.home}/../src.zip - true - - - - - srczip-lib - - - ${java.home}/lib/src.zip - - - - - jdk - srczip - 999 - system - ${java.home}/lib/src.zip - true - - - - - - maven-javadoc-plugin - - - ${project.build.sourceDirectory}:${project.build.directory}/jdk-sources/java.base - - - - - - diff --git a/guava/pom.xml b/guava/pom.xml index 2d9b1ab4b213..429ab9d85873 100644 --- a/guava/pom.xml +++ b/guava/pom.xml @@ -44,8 +44,6 @@ com.google.j2objc j2objc-annotations - - @@ -106,24 +104,6 @@ maven-source-plugin - - - maven-dependency-plugin - - - unpack-jdk-sources - generate-sources - unpack-dependencies - - srczip - ${project.build.directory}/jdk-sources - false - - **/module-info.java,**/java/io/FileDescriptor.java - - - - org.codehaus.mojo animal-sniffer-maven-plugin @@ -131,11 +111,6 @@ maven-javadoc-plugin - - - - ${project.build.sourceDirectory}:${project.build.directory}/jdk-sources - @@ -248,87 +223,5 @@ - - spdx - - 11 - - - - - org.spdx - spdx-maven-plugin - 0.7.3 - - - build-spdx - - createSPDX - - - - - true - false - - - - - - - srczip-parent - - - ${java.home}/../src.zip - - - maven.javadoc.skip - false - - - - - jdk - srczip - 999 - system - ${java.home}/../src.zip - true - - - - - srczip-lib - - - ${java.home}/lib/src.zip - - - maven.javadoc.skip - false - - - - - jdk - srczip - 999 - system - ${java.home}/lib/src.zip - true - - - - - - maven-javadoc-plugin - - - ${project.build.sourceDirectory}:${project.build.directory}/jdk-sources/java.base - - - - - From d6c654802cee6f9a097336f54ac1fb93db3c6419 Mon Sep 17 00:00:00 2001 From: Sam Gammon Date: Fri, 8 Mar 2024 16:58:13 -0800 Subject: [PATCH 15/15] chore(labs): improve build and test speed This changeset optimizes the Guava build significantly by enabling parallel build and test features supported by Maven. With these flags enabled, only a few tests exhibit flaky behavior; applying a sensible count of test retries (3) solves the problem. As a result, the testsuite can now be executed often, because it takes about 2 minutes to run. Building is also much faster. After benchmarking different configurations, 2-threads-per-core and 2-test-forks-per-core seems optimal: ``` [INFO] Guava Maven Parent ..................... SUCCESS [ 0.121 s] [INFO] Guava: Google Core Libraries for Java .. SUCCESS [ 9.681 s] [INFO] Guava BOM .............................. SUCCESS [ 0.120 s] [INFO] Guava Testing Library .................. SUCCESS [ 47.883 s] [INFO] Guava Unit Tests ....................... SUCCESS [01:57 min] <-- [INFO] Guava GWT compatible libs .............. SUCCESS [ 6.909 s] ``` When built and executed serially: ``` [INFO] Guava Maven Parent ..................... SUCCESS [ 0.129 s] [INFO] Guava: Google Core Libraries for Java .. SUCCESS [ 15.653 s] [INFO] Guava BOM .............................. SUCCESS [ 0.064 s] [INFO] Guava Testing Library .................. SUCCESS [01:26 min] [INFO] Guava Unit Tests ....................... SUCCESS [06:26 min] <-- [INFO] Guava GWT compatible libs .............. SUCCESS [ 11.092 s] ``` Benchmark hardware: - Apple M2 Max, 96GB RAM - macOS Sonoma 14.3.1 - GraalVM CE JVM 21.0.2 ``` openjdk version "21.0.2" 2024-01-16 OpenJDK Runtime Environment GraalVM CE 21.0.2+13.1 (build 21.0.2+13-jvmci-23.1-b30) OpenJDK 64-Bit Server VM GraalVM CE 21.0.2+13.1 (build 21.0.2+13-jvmci-23.1-b30, mixed mode, sharing) ``` - chore: enable parallel build - chore: enable parallel test execution - chore: enable parallel gc for maven - chore: tune tiered compilation for maven - chore: tune thread count for maven - fix: enable test retries (max = 3) for parallel-flaky tests Signed-off-by: Sam Gammon --- .mvn/jvm.config | 1 + .mvn/maven.config | 2 ++ pom.xml | 9 ++++++++- 3 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 .mvn/jvm.config create mode 100644 .mvn/maven.config diff --git a/.mvn/jvm.config b/.mvn/jvm.config new file mode 100644 index 000000000000..8fc30111dd55 --- /dev/null +++ b/.mvn/jvm.config @@ -0,0 +1 @@ +-XX:-TieredCompilation -XX:TieredStopAtLevel=1 -XX:+UseParallelGC -Djava.awt.headless=true \ No newline at end of file diff --git a/.mvn/maven.config b/.mvn/maven.config new file mode 100644 index 000000000000..cc57db8375d4 --- /dev/null +++ b/.mvn/maven.config @@ -0,0 +1,2 @@ +-T2C +--strict-checksums diff --git a/pom.xml b/pom.xml index 97c774015192..e04f2b4b6280 100644 --- a/pom.xml +++ b/pom.xml @@ -12,6 +12,10 @@ Parent for guava artifacts https://github.com/google/guava + + all + false + 48 %regex[.*.class] 1.4.2 @@ -33,6 +37,7 @@ android https://oss.sonatype.org/content/repositories/snapshots/ https://oss.sonatype.org/service/local/staging/deploy/maven2/ + 3 GitHub Issues @@ -232,7 +237,7 @@ maven-surefire-plugin - 2.7.2 + 3.2.5 ${test.include} @@ -251,6 +256,8 @@ -Xmx1536M -Duser.language=hi -Duser.country=IN ${test.add.opens} + true + 2C