├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── feature_request.md │ └── support_request.md ├── PULL_REQUEST_TEMPLATE.md ├── auto-label.yaml ├── blunderbuss.yml ├── dependabot.yml ├── release-please.yml ├── release-trigger.yml ├── snippet-bot.yml ├── sync-repo-settings.yaml ├── trusted-contribution.yml └── workflows │ ├── approve-readme.yaml │ ├── bom-content-test.yaml │ ├── ci-release-note-generation.yaml │ ├── ci-validate-bom.yaml │ ├── ci.yaml │ ├── dashboard.yaml │ ├── release-note-generation.yaml │ ├── renovate_config_check.yaml │ └── update-readme-table.yaml ├── .gitignore ├── .kokoro ├── build.bat ├── build.sh ├── coerce_logs.sh ├── common.cfg ├── common.sh ├── continuous │ ├── common.cfg │ ├── java8.cfg │ └── propose_release.sh ├── dashboard.sh ├── dependencies.sh ├── nightly │ ├── common.cfg │ ├── create-versions-csv.cfg │ ├── create-versions-csv.sh │ ├── dashboard.cfg │ ├── dashboard.sh │ ├── fetch-library-data.sh │ ├── get-apiary-service-names.sh │ ├── get-service-names.sh │ ├── integration.cfg │ ├── java11-integration.cfg │ ├── java11.cfg │ ├── java7.cfg │ ├── java8-osx.cfg │ ├── java8-win.cfg │ ├── java8.cfg │ └── samples.cfg ├── populate-secrets.sh ├── presubmit │ ├── clirr.cfg │ ├── common.cfg │ ├── dependencies.cfg │ ├── graalvm-native-17.cfg │ ├── graalvm-native.cfg │ ├── integration.cfg │ ├── java11.cfg │ ├── java7.cfg │ ├── java8-osx.cfg │ ├── java8-win.cfg │ ├── java8.cfg │ ├── linkage-monitor.cfg │ ├── lint.cfg │ └── samples.cfg ├── readme.sh └── trampoline.sh ├── .release-please-manifest.json ├── .repo-metadata.json ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── SECURITY.md ├── dashboard ├── README.md ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── google │ │ │ └── cloud │ │ │ └── tools │ │ │ └── opensource │ │ │ └── cloudbomdashboard │ │ │ ├── ArtifactCache.java │ │ │ ├── ArtifactInfo.java │ │ │ ├── ArtifactMavenData.java │ │ │ ├── ArtifactResults.java │ │ │ ├── DashboardArguments.java │ │ │ ├── DashboardMain.java │ │ │ └── VersionData.java │ └── resources │ │ ├── css │ │ └── dashboard.css │ │ ├── js │ │ └── dashboard.js │ │ ├── poms │ │ └── demo.xml │ │ └── templates │ │ ├── index.ftl │ │ └── macros.ftl │ └── test │ └── java │ └── com │ └── google │ └── cloud │ └── tools │ └── opensource │ └── cloudbomdashboard │ └── ArtifactMavenTest.java ├── google-cloud-bom ├── CHANGELOG.md ├── README.md └── pom.xml ├── java.header ├── libraries-bom-protobuf3 └── pom.xml ├── libraries-bom-table-generation ├── javaModulesMetadata.yaml └── updateREADMETable.py ├── libraries-bom ├── CHANGELOG.md └── pom.xml ├── libraries-release-data ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── google │ └── cloud │ └── dashboard │ └── GenerateLibrariesList.java ├── license-checks.xml ├── pom.xml ├── release-note-generation ├── pom.xml └── src │ ├── main │ └── java │ │ └── com │ │ └── google │ │ └── cloud │ │ └── ReleaseNoteGeneration.java │ └── test │ └── java │ └── com │ └── google │ └── cloud │ └── ReleaseNoteGenerationTest.java ├── release-please-config.json ├── renovate.json ├── tests ├── dependency-convergence │ ├── CHANGELOG.md │ └── pom.xml ├── pom.xml ├── release-repository-readiness │ ├── README.md │ ├── check_status.sh │ └── clone_repositories.sh ├── src │ └── test │ │ ├── java │ │ └── com │ │ │ └── google │ │ │ └── cloud │ │ │ ├── BomContentAssertionsTest.java │ │ │ ├── BomContentTest.java │ │ │ └── MaximumLinkageErrorsTest.java │ │ └── resources │ │ └── bom-with-typo-artifact.xml └── validate-bom │ ├── README.md │ ├── action.yml │ ├── pom.xml │ └── src │ └── main │ ├── java │ └── com │ │ └── google │ │ └── cloud │ │ └── CreateBomCanaryProject.java │ └── resources │ └── template.pom.xml └── versions.txt /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Code owners file. 2 | # This file controls who is tagged for review for any given pull request. 3 | 4 | # For syntax help see: 5 | # https://help.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners#codeowners-syntax 6 | 7 | * @googleapis/yoshi-java 8 | 9 | # The java-samples-reviewers team is the default owner for samples changes 10 | samples/**/*.java @googleapis/java-samples-reviewers 11 | 12 | # Generated snippets should not be owned by samples reviewers 13 | samples/snippets/generated/ @googleapis/yoshi-java 14 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | 5 | --- 6 | 7 | Thanks for stopping by to let us know something could be better! 8 | 9 | **PLEASE READ**: If you have a support contract with Google, please create an issue in the [support console](https://cloud.google.com/support/) instead of filing on GitHub. This will ensure a timely response. 10 | 11 | Please run down the following list and make sure you've tried the usual "quick fixes": 12 | 13 | - Search the issues already opened: https://github.com/googleapis/java-cloud-bom/issues 14 | - Check for answers on StackOverflow: http://stackoverflow.com/questions/tagged/google-cloud-platform 15 | 16 | If you are still having issues, please include as much information as possible: 17 | 18 | #### Environment details 19 | 20 | 1. Specify the API at the beginning of the title. For example, "BigQuery: ..."). 21 | General, Core, and Other are also allowed as types 22 | 2. OS type and version: 23 | 3. Java version: 24 | 4. version(s): 25 | 26 | #### Steps to reproduce 27 | 28 | 1. ? 29 | 2. ? 30 | 31 | #### Code example 32 | 33 | ```java 34 | // example 35 | ``` 36 | 37 | #### Stack trace 38 | ``` 39 | Any relevant stacktrace here. 40 | ``` 41 | 42 | #### External references such as API reference guides 43 | 44 | - ? 45 | 46 | #### Any additional information below 47 | 48 | 49 | Following these steps guarantees the quickest resolution possible. 50 | 51 | Thanks! 52 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this library 4 | 5 | --- 6 | 7 | Thanks for stopping by to let us know something could be better! 8 | 9 | **PLEASE READ**: If you have a support contract with Google, please create an issue in the [support console](https://cloud.google.com/support/) instead of filing on GitHub. This will ensure a timely response. 10 | 11 | **Is your feature request related to a problem? Please describe.** 12 | What the problem is. Example: I'm always frustrated when [...] 13 | 14 | **Describe the solution you'd like** 15 | What you want to happen. 16 | 17 | **Describe alternatives you've considered** 18 | Any alternative solutions or features you've considered. 19 | 20 | **Additional context** 21 | Any other context or screenshots about the feature request. 22 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/support_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Support request 3 | about: If you have a support contract with Google, please create an issue in the Google Cloud Support console. 4 | 5 | --- 6 | 7 | **PLEASE READ**: If you have a support contract with Google, please create an issue in the [support console](https://cloud.google.com/support/) instead of filing on GitHub. This will ensure a timely response. 8 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Thank you for opening a Pull Request! Before submitting your PR, there are a few things you can do to make sure it goes smoothly: 2 | - [ ] Make sure to open an issue as a [bug/issue](https://github.com/googleapis/java-cloud-bom/issues/new/choose) before writing your code! That way we can discuss the change, evaluate designs, and agree on the general idea 3 | - [ ] Ensure the tests and linter pass 4 | - [ ] Code coverage does not decrease (if any source code was changed) 5 | - [ ] Appropriate docs were updated (if necessary) 6 | 7 | Fixes # ☕️ 8 | 9 | If you write sample code, please follow the [samples format]( 10 | https://github.com/GoogleCloudPlatform/java-docs-samples/blob/main/SAMPLE_FORMAT.md). 11 | -------------------------------------------------------------------------------- /.github/auto-label.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2021 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | requestsize: 15 | enabled: true 16 | -------------------------------------------------------------------------------- /.github/blunderbuss.yml: -------------------------------------------------------------------------------- 1 | # Configuration for the Blunderbuss GitHub app. For more info see 2 | # https://github.com/googleapis/repo-automation-bots/tree/main/packages/blunderbuss 3 | assign_prs_by: 4 | - labels: 5 | - samples 6 | to: 7 | - googleapis/java-samples-reviewers -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "maven" 4 | directory: "/" 5 | schedule: 6 | interval: "daily" 7 | # Disable version updates for Maven dependencies 8 | # we use renovate-bot as well as shared-dependencies BOM to update maven dependencies. 9 | ignore: 10 | - dependency-name: "*" 11 | - package-ecosystem: "pip" 12 | directory: "/" 13 | schedule: 14 | interval: "daily" 15 | # Disable version updates for pip dependencies 16 | # If a security vulnerability comes in, we will be notified about 17 | # it via template in the synthtool repository. 18 | ignore: 19 | - dependency-name: "*" 20 | -------------------------------------------------------------------------------- /.github/release-please.yml: -------------------------------------------------------------------------------- 1 | releaseType: java-bom 2 | handleGHRelease: true 3 | manifest: true 4 | primaryBranch: main 5 | branches: 6 | - releaseType: java-yoshi 7 | handleGHRelease: true 8 | bumpMinorPreMajor: true 9 | branch: java7 10 | - releaseType: java-backport 11 | manifest: true 12 | handleGHRelease: true 13 | branch: 26.1.x 14 | -------------------------------------------------------------------------------- /.github/release-trigger.yml: -------------------------------------------------------------------------------- 1 | enabled: true 2 | multiScmName: java-cloud-bom 3 | -------------------------------------------------------------------------------- /.github/snippet-bot.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/googleapis/java-cloud-bom/5f56258af0cf11b396d2d6d39b5d2c0ca08edf6c/.github/snippet-bot.yml -------------------------------------------------------------------------------- /.github/sync-repo-settings.yaml: -------------------------------------------------------------------------------- 1 | rebaseMergeAllowed: false 2 | squashMergeAllowed: true 3 | mergeCommitAllowed: false 4 | branchProtectionRules: 5 | - pattern: main 6 | isAdminEnforced: true 7 | requiredApprovingReviewCount: 1 8 | requiresCodeOwnerReviews: true 9 | requiresStrictStatusChecks: false 10 | requiredStatusCheckContexts: 11 | - dependencies (17) 12 | - lint 13 | - clirr 14 | - units (8) 15 | - units (11) 16 | - cla/google 17 | - bom-content-test 18 | - pattern: java7 19 | isAdminEnforced: true 20 | requiredApprovingReviewCount: 1 21 | requiresCodeOwnerReviews: true 22 | requiresStrictStatusChecks: false 23 | requiredStatusCheckContexts: 24 | - dependencies (8) 25 | - dependencies (11) 26 | - lint 27 | - clirr 28 | - units (7) 29 | - units (8) 30 | - units (11) 31 | - cla/google 32 | - pattern: 26.1.x 33 | isAdminEnforced: true 34 | requiredApprovingReviewCount: 1 35 | requiresCodeOwnerReviews: true 36 | requiresStrictStatusChecks: false 37 | requiredStatusCheckContexts: 38 | - dependencies (8) 39 | - dependencies (11) 40 | - lint 41 | - units (8) 42 | - units (11) 43 | - cla/google 44 | - bom-content-test 45 | permissionRules: 46 | - team: yoshi-admins 47 | permission: admin 48 | - team: yoshi-java-admins 49 | permission: admin 50 | - team: yoshi-java 51 | permission: push 52 | -------------------------------------------------------------------------------- /.github/trusted-contribution.yml: -------------------------------------------------------------------------------- 1 | trustedContributors: [] 2 | -------------------------------------------------------------------------------- /.github/workflows/approve-readme.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2022 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # Github action job to test core java library features on 15 | # downstream client libraries before they are released. 16 | on: 17 | pull_request: 18 | name: auto-merge-readme 19 | jobs: 20 | approve: 21 | runs-on: ubuntu-latest 22 | if: github.repository_owner == 'googleapis' && github.head_ref == 'autosynth-readme' 23 | steps: 24 | - uses: actions/github-script@v7 25 | with: 26 | github-token: ${{secrets.YOSHI_APPROVER_TOKEN}} 27 | script: | 28 | // only approve PRs from yoshi-automation 29 | if (context.payload.pull_request.user.login !== "yoshi-automation") { 30 | return; 31 | } 32 | 33 | // only approve PRs like "chore: release " 34 | if (!context.payload.pull_request.title === "chore: regenerate README") { 35 | return; 36 | } 37 | 38 | // only approve PRs with README.md and synth.metadata changes 39 | const files = new Set( 40 | ( 41 | await github.paginate( 42 | github.pulls.listFiles.endpoint({ 43 | owner: context.repo.owner, 44 | repo: context.repo.repo, 45 | pull_number: context.payload.pull_request.number, 46 | }) 47 | ) 48 | ).map(file => file.filename) 49 | ); 50 | if (files.size != 2 || !files.has("README.md") || !files.has(".github/readme/synth.metadata/synth.metadata")) { 51 | return; 52 | } 53 | 54 | // approve README regeneration PR 55 | await github.pulls.createReview({ 56 | owner: context.repo.owner, 57 | repo: context.repo.repo, 58 | body: 'Rubber stamped PR!', 59 | pull_number: context.payload.pull_request.number, 60 | event: 'APPROVE' 61 | }); 62 | 63 | // attach automerge label 64 | await github.issues.addLabels({ 65 | owner: context.repo.owner, 66 | repo: context.repo.repo, 67 | issue_number: context.payload.pull_request.number, 68 | labels: ['automerge'] 69 | }); 70 | -------------------------------------------------------------------------------- /.github/workflows/bom-content-test.yaml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - main 5 | pull_request: 6 | name: ci 7 | jobs: 8 | bom-content-test: 9 | runs-on: ubuntu-latest 10 | if: github.repository_owner == 'googleapis' 11 | steps: 12 | - uses: actions/checkout@v4 13 | - uses: actions/setup-java@v4 14 | with: 15 | distribution: temurin 16 | java-version: 11 17 | cache: maven 18 | - run: java -version 19 | - name: Install BOMs 20 | run: | 21 | mvn -B -V -ntp install 22 | - name: Ensure the members of the Libraries BOM exist in Maven Central 23 | uses: ./tests/validate-bom 24 | with: 25 | bom-path: libraries-bom/pom.xml 26 | - name: Ensure the BOM has valid content (at releases) 27 | if: github.head_ref == 'release-please--branches--main' 28 | run: | 29 | mvn -B -V -ntp verify -Dtest="BomContentTest#testLibrariesBom" 30 | working-directory: tests 31 | 32 | bom-assertion-test: 33 | name: BomContentAssertionsTest (Test for assertion logic in BomContentTest) 34 | runs-on: ubuntu-latest 35 | if: github.repository_owner == 'googleapis' 36 | steps: 37 | - uses: actions/checkout@v4 38 | - uses: actions/setup-java@v4 39 | with: 40 | distribution: zulu 41 | java-version: 8 42 | - run: java -version 43 | - name: Install BOMs 44 | run: | 45 | mvn -B -V -ntp install 46 | - run: | 47 | mvn -B -V -ntp verify -Dtest="BomContentAssertionsTest" 48 | working-directory: tests 49 | 50 | -------------------------------------------------------------------------------- /.github/workflows/ci-release-note-generation.yaml: -------------------------------------------------------------------------------- 1 | on: 2 | pull_request: 3 | paths: 4 | - 'release-note-generation/**' 5 | name: release-note-generation-test 6 | jobs: 7 | test: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/checkout@v4 11 | - uses: actions/setup-java@v4 12 | with: 13 | distribution: temurin 14 | java-version: 11 15 | cache: maven 16 | - run: java -version 17 | - name: Run test in release-note-generation 18 | shell: bash 19 | run: | 20 | mvn -B -ntp verify 21 | working-directory: release-note-generation 22 | env: 23 | GH_TOKEN: ${{ github.token }} 24 | 25 | dry-run: 26 | runs-on: ubuntu-latest 27 | steps: 28 | - uses: actions/checkout@v4 29 | - uses: actions/setup-java@v4 30 | with: 31 | distribution: temurin 32 | java-version: 11 33 | cache: maven 34 | - run: java -version 35 | - name: Dry-run release-note-generation 36 | shell: bash 37 | run: | 38 | mvn -B -ntp compile 39 | # This generates release_note.md file 40 | mvn -B -ntp exec:java \ 41 | -Dlibraries-bom.version="26.2.0" \ 42 | -Dgoogle-cloud-java.version="1.1.0" 43 | working-directory: release-note-generation 44 | env: 45 | GH_TOKEN: ${{ github.token }} 46 | - name: Show generated release note 47 | shell: bash 48 | run: | 49 | # This fails if the file does not exist 50 | cat release_note.md 51 | working-directory: release-note-generation 52 | -------------------------------------------------------------------------------- /.github/workflows/ci-validate-bom.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # Github action job to test core java library features on 15 | # downstream client libraries before they are released. 16 | on: 17 | push: 18 | branches: 19 | - main 20 | pull_request: 21 | name: test for tests/validate-bom logic 22 | jobs: 23 | test-invalid-bom: 24 | runs-on: ubuntu-latest 25 | steps: 26 | - uses: actions/checkout@v4 27 | - name: Fetch the bad protobuf-bom version 3.22.1 28 | shell: bash 29 | # 3.22.1 had a issue in their pom.xml 30 | # https://github.com/protocolbuffers/protobuf/issues/12170 31 | run: | 32 | mkdir -p bad-protobuf-bom 33 | curl https://repo1.maven.org/maven2/com/google/protobuf/protobuf-bom/3.22.1/protobuf-bom-3.22.1.pom \ 34 | --output bad-protobuf-bom/pom.xml 35 | - name: Check the bad BOM 36 | uses: ./tests/validate-bom 37 | id: validate-bom 38 | with: 39 | bom-path: bad-protobuf-bom/pom.xml 40 | continue-on-error: true 41 | - name: Ensure the validate-bom invalidated the bad BOM 42 | shell: bash 43 | if: steps.validate-bom.outcome != 'failure' 44 | run: | 45 | echo "The validate-bom check should have invalidated the bad BOM" 46 | exit 1 47 | -------------------------------------------------------------------------------- /.github/workflows/ci.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2022 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # Github action job to test core java library features on 15 | # downstream client libraries before they are released. 16 | on: 17 | push: 18 | branches: 19 | - main 20 | pull_request: 21 | name: ci 22 | jobs: 23 | units: 24 | runs-on: ubuntu-latest 25 | strategy: 26 | fail-fast: false 27 | matrix: 28 | java: [11, 17, 21] 29 | steps: 30 | - uses: actions/checkout@v4 31 | - uses: actions/setup-java@v4 32 | with: 33 | distribution: temurin 34 | java-version: ${{matrix.java}} 35 | - run: java -version 36 | - run: .kokoro/build.sh 37 | env: 38 | JOB_TYPE: test 39 | units-java8: 40 | # Building using Java 17 and run the tests with Java 8 runtime 41 | name: "units (8)" 42 | runs-on: ubuntu-latest 43 | steps: 44 | - uses: actions/checkout@v4 45 | - uses: actions/setup-java@v4 46 | with: 47 | java-version: 8 48 | distribution: temurin 49 | - name: "Set jvm system property environment variable for surefire plugin (unit tests)" 50 | # Maven surefire plugin (unit tests) allows us to specify JVM to run the tests. 51 | # https://maven.apache.org/surefire/maven-surefire-plugin/test-mojo.html#jvm 52 | run: echo "SUREFIRE_JVM_OPT=-Djvm=${JAVA_HOME}/bin/java" >> $GITHUB_ENV 53 | shell: bash 54 | - uses: actions/setup-java@v4 55 | with: 56 | java-version: 17 57 | distribution: temurin 58 | - run: .kokoro/build.sh 59 | env: 60 | JOB_TYPE: test 61 | windows: 62 | runs-on: windows-latest 63 | steps: 64 | - name: Support longpaths 65 | run: git config --system core.longpaths true 66 | - uses: actions/checkout@v4 67 | - uses: actions/setup-java@v4 68 | with: 69 | distribution: temurin 70 | java-version: 8 71 | - run: java -version 72 | - run: .kokoro/build.bat 73 | env: 74 | JOB_TYPE: test 75 | dependencies: 76 | runs-on: ubuntu-latest 77 | strategy: 78 | matrix: 79 | java: [17] 80 | steps: 81 | - uses: actions/checkout@v4 82 | - uses: actions/setup-java@v4 83 | with: 84 | distribution: temurin 85 | java-version: ${{matrix.java}} 86 | - run: java -version 87 | - run: .kokoro/dependencies.sh 88 | javadoc: 89 | runs-on: ubuntu-latest 90 | steps: 91 | - uses: actions/checkout@v4 92 | - uses: actions/setup-java@v4 93 | with: 94 | distribution: temurin 95 | java-version: 17 96 | - run: java -version 97 | - run: .kokoro/build.sh 98 | env: 99 | JOB_TYPE: javadoc 100 | lint: 101 | runs-on: ubuntu-latest 102 | steps: 103 | - uses: actions/checkout@v4 104 | - uses: actions/setup-java@v4 105 | with: 106 | distribution: temurin 107 | java-version: 11 108 | - run: java -version 109 | - run: .kokoro/build.sh 110 | env: 111 | JOB_TYPE: lint 112 | clirr: 113 | runs-on: ubuntu-latest 114 | steps: 115 | - uses: actions/checkout@v4 116 | - uses: actions/setup-java@v4 117 | with: 118 | distribution: temurin 119 | java-version: 8 120 | - run: java -version 121 | - run: .kokoro/build.sh 122 | env: 123 | JOB_TYPE: clirr 124 | -------------------------------------------------------------------------------- /.github/workflows/dashboard.yaml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - main 5 | pull_request: 6 | name: ci 7 | jobs: 8 | dashboard: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v4 12 | - uses: actions/setup-java@v4 13 | with: 14 | distribution: temurin 15 | java-version: 8 16 | cache: maven 17 | - run: java -version 18 | - run: .kokoro/dashboard.sh 19 | env: 20 | JOB_TYPE: dashboard-units-check 21 | shared-dependencies-convergence: 22 | runs-on: ubuntu-latest 23 | if: github.repository_owner == 'googleapis' && github.head_ref == 'release-please--branches--main' 24 | steps: 25 | - uses: actions/checkout@v4 26 | - uses: actions/setup-java@v4 27 | with: 28 | distribution: temurin 29 | java-version: 8 30 | cache: maven 31 | - run: java -version 32 | - run: .kokoro/dashboard.sh 33 | env: 34 | JOB_TYPE: dependency-convergence-check 35 | -------------------------------------------------------------------------------- /.github/workflows/release-note-generation.yaml: -------------------------------------------------------------------------------- 1 | on: 2 | workflow_dispatch: 3 | inputs: 4 | librariesBomVersion: 5 | description: 'The version of the Libraries BOM we generate release note (e.g., 26.1.5)' 6 | required: true 7 | type: string 8 | 9 | release: # https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#release 10 | types: [released] 11 | 12 | name: release-notes 13 | jobs: 14 | release-note-generation: 15 | runs-on: ubuntu-latest 16 | permissions: 17 | contents: write 18 | pull-requests: write 19 | steps: 20 | - uses: actions/checkout@v4 21 | - uses: actions/setup-java@v4 22 | with: 23 | distribution: temurin 24 | java-version: 11 25 | cache: maven 26 | - run: java -version 27 | - name: Pick Libraries BOM version 28 | id: pick-version 29 | shell: bash 30 | run: | 31 | set -x 32 | if [ -n "${WORKFLOW_DISPATCH_INPUT}" ]; then 33 | echo "WORKFLOW_DISPATCH_INPUT: ${WORKFLOW_DISPATCH_INPUT}" 34 | echo "libraries-bom-version=${WORKFLOW_DISPATCH_INPUT}" >> $GITHUB_OUTPUT 35 | elif [[ "${GITHUB_REF}" == *"refs/tags/v"* ]]; then 36 | # https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#release 37 | # Example value of GITHUB_REF: refs/tags/v26.5.0 38 | # With the single-component setup of Release Please, the Libraries BOM 39 | # version is the version of this repository release. 40 | echo "GITHUB_REF: ${GITHUB_REF}" 41 | VERSION=${GITHUB_REF#refs/*/v} 42 | echo "libraries-bom-version=${VERSION}" >> $GITHUB_OUTPUT 43 | else 44 | echo "Couldn't find the Libraries BOM version. WORKFLOW_DISPATCH_INPUT \ 45 | was empty and GITHUB_REF was ${GITHUB_REF}." 46 | exit 1 47 | fi 48 | env: 49 | WORKFLOW_DISPATCH_INPUT: ${{ inputs.librariesBomVersion }} 50 | - name: Install the BOMs locally 51 | run: mvn install 52 | shell: bash 53 | - name: Generate release_note.md 54 | shell: bash 55 | run: | 56 | set -x 57 | mvn -B -ntp compile 58 | 59 | GOOGLE_CLOUD_JAVA_VERSION=$(grep -A1 'gapic-libraries-bom' \ 60 | ../google-cloud-bom/pom.xml |perl -nle 'print $1 if m/(.+) 0 ]] 44 | then 45 | echo "failure (${exit_code}), sleeping ${sleep_seconds}..." 46 | sleep ${sleep_seconds} 47 | new_attempts=$((${attempts_left} - 1)) 48 | new_sleep=$((${sleep_seconds} * 2)) 49 | retry_with_backoff ${new_attempts} ${new_sleep} ${command} 50 | fi 51 | 52 | return $exit_code 53 | } 54 | 55 | ## Helper functionss 56 | function now() { date +"%Y-%m-%d %H:%M:%S" | tr -d '\n'; } 57 | function msg() { println "$*" >&2; } 58 | function println() { printf '%s\n' "$(now) $*"; } 59 | 60 | ## Helper comment to trigger updated repo dependency release -------------------------------------------------------------------------------- /.kokoro/continuous/common.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | # Build logs will be here 4 | action { 5 | define_artifacts { 6 | regex: "**/*sponge_log.xml" 7 | regex: "**/*sponge_log.txt" 8 | } 9 | } 10 | 11 | # Download trampoline resources. 12 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" 13 | 14 | # Use the trampoline script to run in docker. 15 | build_file: "java-cloud-bom/.kokoro/trampoline.sh" 16 | 17 | env_vars: { 18 | key: "TRAMPOLINE_BUILD_FILE" 19 | value: "github/java-cloud-bom/.kokoro/build.sh" 20 | } 21 | 22 | env_vars: { 23 | key: "JOB_TYPE" 24 | value: "test" 25 | } 26 | -------------------------------------------------------------------------------- /.kokoro/continuous/java8.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | # Configure the docker image for kokoro-trampoline. 4 | env_vars: { 5 | key: "TRAMPOLINE_IMAGE" 6 | value: "gcr.io/cloud-devrel-kokoro-resources/java8" 7 | } 8 | 9 | env_vars: { 10 | key: "REPORT_COVERAGE" 11 | value: "true" 12 | } 13 | -------------------------------------------------------------------------------- /.kokoro/continuous/propose_release.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2019 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | set -eo pipefail 18 | 19 | export NPM_CONFIG_PREFIX=/home/node/.npm-global 20 | 21 | if [ -f ${KOKORO_KEYSTORE_DIR}/73713_github-magic-proxy-url-release-please ]; then 22 | # Groom the release PR as new commits are merged. 23 | npx release-please release-pr --token=${KOKORO_KEYSTORE_DIR}/73713_github-magic-proxy-token-release-please \ 24 | --repo-url=googleapis/java-cloud-bom \ 25 | --package-name="google-cloud-bom" \ 26 | --api-url=${KOKORO_KEYSTORE_DIR}/73713_github-magic-proxy-url-release-please \ 27 | --proxy-key=${KOKORO_KEYSTORE_DIR}/73713_github-magic-proxy-key-release-please \ 28 | --release-type=java-yoshi 29 | fi 30 | -------------------------------------------------------------------------------- /.kokoro/dashboard.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright 2021 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | set -eo pipefail 17 | 18 | ## Get the directory of the build script 19 | scriptDir=$(realpath $(dirname "${BASH_SOURCE[0]}")) 20 | ## cd to the parent directory, i.e. the root of the git repo 21 | cd ${scriptDir}/.. 22 | 23 | outputFile="$scriptDir/../dashboard/target/tmp/output.txt" 24 | ## Move into the dashboard directory 25 | cd dashboard/ 26 | 27 | echo -e "\n******************** BUILDING THE DASHBOARD ********************" 28 | 29 | mvn --fail-at-end -DskipTests=true clean install -B 30 | INSTALL_RETURN_CODE=$? 31 | RETURN_CODE=${INSTALL_RETURN_CODE} 32 | 33 | LINE_COUNT=0 34 | set +e 35 | 36 | case ${JOB_TYPE} in 37 | dashboard-units-check) 38 | echo -e "\n******************** RUNNING DASHBOARD TESTS ********************" 39 | mvn test -B 40 | RETURN_CODE=$? 41 | ;; 42 | dependency-convergence-check) 43 | echo -e "\n******************** CHECKING DEPENDENCY CONVERGENCE ********************" 44 | mvn exec:java -Dexec.args="-f ../google-cloud-bom/pom.xml --report -o target/tmp/output.txt" -B 45 | CONVERGE_RETURN_CODE=$? 46 | if [[ $INSTALL_RETURN_CODE -eq 0 && $CONVERGE_RETURN_CODE -eq 0 ]] 47 | then 48 | while IFS= read -r line; do 49 | echo "$line" 50 | LINE_COUNT=$((LINE_COUNT+1)) 51 | done < "$outputFile" 52 | fi 53 | RETURN_CODE=${CONVERGE_RETURN_CODE} 54 | ;; 55 | esac 56 | 57 | if [[ $RETURN_CODE -ne 0 || $LINE_COUNT -gt 1 ]] 58 | then 59 | RETURN_CODE=1 60 | fi 61 | 62 | echo "exiting with ${RETURN_CODE}" 63 | exit ${RETURN_CODE} 64 | -------------------------------------------------------------------------------- /.kokoro/dependencies.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright 2019 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | set -eo pipefail 17 | shopt -s nullglob 18 | 19 | ## Get the directory of the build script 20 | scriptDir=$(realpath $(dirname "${BASH_SOURCE[0]}")) 21 | ## cd to the parent directory, i.e. the root of the git repo 22 | cd ${scriptDir}/.. 23 | 24 | # include common functions 25 | source ${scriptDir}/common.sh 26 | 27 | # Print out Java 28 | java -version 29 | echo $JOB_TYPE 30 | 31 | function determineMavenOpts() { 32 | local javaVersion=$( 33 | # filter down to the version line, then pull out the version between quotes, 34 | # then trim the version number down to its minimal number (removing any 35 | # update or suffix number). 36 | java -version 2>&1 | grep "version" \ 37 | | sed -E 's/^.*"(.*?)".*$/\1/g' \ 38 | | sed -E 's/^(1\.[0-9]\.0).*$/\1/g' 39 | ) 40 | 41 | if [[ $javaVersion == 17* ]] 42 | then 43 | # MaxPermSize is no longer supported as of jdk 17 44 | echo -n "-Xmx1024m" 45 | else 46 | echo -n "-Xmx1024m -XX:MaxPermSize=128m" 47 | fi 48 | } 49 | 50 | export MAVEN_OPTS=$(determineMavenOpts) 51 | 52 | # this should run maven enforcer 53 | retry_with_backoff 3 10 \ 54 | mvn install -B -V -ntp \ 55 | -DskipTests=true \ 56 | -Dmaven.javadoc.skip=true \ 57 | -Dclirr.skip=true 58 | 59 | mvn -B dependency:analyze -DfailOnWarning=true 60 | -------------------------------------------------------------------------------- /.kokoro/nightly/common.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | # Build logs will be here 4 | action { 5 | define_artifacts { 6 | regex: "**/*sponge_log.xml" 7 | regex: "**/*sponge_log.txt" 8 | } 9 | } 10 | 11 | # Download trampoline resources. 12 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" 13 | 14 | # Use the trampoline script to run in docker. 15 | build_file: "java-cloud-bom/.kokoro/trampoline.sh" 16 | 17 | env_vars: { 18 | key: "TRAMPOLINE_BUILD_FILE" 19 | value: "github/java-cloud-bom/.kokoro/build.sh" 20 | } 21 | 22 | env_vars: { 23 | key: "JOB_TYPE" 24 | value: "test" 25 | } 26 | -------------------------------------------------------------------------------- /.kokoro/nightly/create-versions-csv.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | # Location of the periodic build bash script in git. 4 | build_file: "java-cloud-bom/.kokoro/nightly/create-versions-csv.sh" 5 | -------------------------------------------------------------------------------- /.kokoro/nightly/create-versions-csv.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Output: 4 | # The script generates cloud_java_client_library_release_dates.csv that holds the data defined below. 5 | # It has artifact_id,service_name,version, and release_date columns. 6 | # this csv file is uploaded to (project) cloud-java-metrics.(dataset) client_library_versions. (table) cloud_java_client_library_release_dates 7 | # using bq load command 8 | 9 | # Fail on any error. 10 | set -e 11 | # Display commands being run. 12 | set -x 13 | 14 | cd github/java-cloud-bom 15 | 16 | # prepare list of artifact id and service name match 17 | .kokoro/nightly/get-service-names.sh 18 | .kokoro/nightly/get-apiary-service-names.sh 19 | 20 | mvn -B clean install 21 | 22 | cd libraries-release-data 23 | 24 | mvn compile 25 | 26 | list=$(mvn -B exec:java -Dexec.mainClass="com.google.cloud.dashboard.GenerateLibrariesList") 27 | 28 | 29 | final_list=$(echo $list | grep -o 'com.google.cloud[^,]*' | tr '\n' ',' | sed 's/,$//') 30 | 31 | 32 | echo ${final_list} | tr ',' '\n' > unfiltered-libraries.txt 33 | sed -i '/libraries-release-data/d' unfiltered-libraries.txt 34 | sort unfiltered-libraries.txt | uniq > libraries.txt 35 | rm -f unfiltered-libraries.txt 36 | 37 | service_file="artifacts_to_services.txt" 38 | 39 | cat libraries.txt | while read line; do 40 | 41 | group_id=${line%:*} 42 | artifact_id=${line#*:} 43 | new_group_id="${group_id//.//}" 44 | # Check if artifactId contains "emulator" 45 | if [[ $artifact_id =~ .*emulator.* ]]; then 46 | echo "artifactId contains 'emulator': $artifactId" 47 | continue 48 | fi 49 | service_name=$(grep "^${artifact_id}," "$service_file" | cut -d ',' -f 2) 50 | if [[ -n $service_name ]]; then 51 | echo "Service Name found: $service_name" 52 | else 53 | echo "No matching service name found for artifactId: $artifact_id" 54 | fi 55 | 56 | URL=https://repo1.maven.org/maven2/$new_group_id/$artifact_id 57 | 58 | ../.kokoro/nightly/fetch-library-data.sh $URL $artifact_id $service_name >> cloud_java_client_library_release_dates.csv 59 | 60 | done 61 | 62 | # apiary list 63 | 64 | sort artifacts_to_services_apiary.txt | uniq > artifacts_to_services_apiary_uniq.txt 65 | 66 | apiary_list="artifacts_to_services_apiary_uniq.txt" 67 | 68 | # Read the input file line by line 69 | while IFS= read -r line; do 70 | # Split line into values using comma as delimiter 71 | IFS=',' read -r -a values <<< "$line" 72 | group_id=${values[0]} 73 | artifact_id=${values[1]} 74 | service_name=${values[2]} 75 | new_group_id="${group_id//./\/}" 76 | URL=https://repo1.maven.org/maven2/$new_group_id/$artifact_id 77 | ../.kokoro/nightly/fetch-library-data.sh $URL $artifact_id $service_name >> cloud_java_client_library_release_dates.csv 78 | done < "$apiary_list" 79 | 80 | # add spring cloud gcp and autogen, "service_name" is tool_name 81 | ../.kokoro/nightly/fetch-library-data.sh https://repo1.maven.org/maven2/com/google/cloud/spring-cloud-gcp-dependencies/ spring-cloud-gcp-dependencies spring-cloud-gcp >> cloud_java_client_library_release_dates.csv 82 | ../.kokoro/nightly/fetch-library-data.sh https://repo1.maven.org/maven2/org/springframework/cloud/spring-cloud-gcp-dependencies/ spring-cloud-gcp-dependencies spring-cloud-gcp >> cloud_java_client_library_release_dates.csv 83 | 84 | ../.kokoro/nightly/fetch-library-data.sh https://repo1.maven.org/maven2/com/google/cloud/google-cloud-language-spring-starter/ google-cloud-language-spring-starter spring-autogen >> cloud_java_client_library_release_dates.csv 85 | 86 | rm -f libraries.txt 87 | rm -f artifacts_to_services_apiary.txt 88 | rm -f "$apiary_list" 89 | 90 | sed -i '1s/^/version,release_date,artifact_id,service_name\n/' cloud_java_client_library_release_dates.csv 91 | 92 | # remove where service match not found 93 | sed -i '/,$/d' cloud_java_client_library_release_dates.csv 94 | 95 | echo "Inserting client_library_versions.cloud_java_client_library_release_dates. First 10 lines:" 96 | head cloud_java_client_library_release_dates.csv 97 | echo "====================" 98 | 99 | bq load --skip_leading_rows=1 --project_id=cloud-java-metrics --source_format=CSV --null_marker="-" \ 100 | client_library_versions.cloud_java_client_library_release_dates \ 101 | cloud_java_client_library_release_dates.csv 102 | 103 | rm -f cloud_java_client_library_release_dates.csv 104 | rm -f artifacts_to_services.txt 105 | -------------------------------------------------------------------------------- /.kokoro/nightly/dashboard.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | # Location of the periodic build bash script in git. 4 | build_file: "java-cloud-bom/.kokoro/nightly/dashboard.sh" 5 | 6 | action { 7 | define_artifacts { 8 | regex: "**/target/com.google.cloud/**" 9 | strip_prefix: "github/java-cloud-bom/dashboard/target" 10 | } 11 | } -------------------------------------------------------------------------------- /.kokoro/nightly/dashboard.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Fail on any error. 4 | set -e 5 | # Display commands being run. 6 | set -x 7 | 8 | cd github/java-cloud-bom/dashboard 9 | # M2_HOME is not used since Maven 3.5.0 https://maven.apache.org/docs/3.5.0/release-notes.html 10 | mvn -B clean install 11 | 12 | # Running target of dashboard submodule 13 | # https://stackoverflow.com/questions/3459928/running-a-specific-maven-plugin-goal-from-the-command-line-in-a-sub-module-of-a/26448447#26448447 14 | # https://stackoverflow.com/questions/11091311/maven-execjava-goal-on-a-multi-module-project 15 | 16 | # For all versions available in Maven Central and local repository 17 | mvn -B exec:java -Dexec.mainClass="com.google.cloud.tools.opensource.cloudbomdashboard.DashboardMain" \ 18 | -Dexec.arguments="-a com.google.cloud:google-cloud-bom" -------------------------------------------------------------------------------- /.kokoro/nightly/fetch-library-data.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # input for this script will be URL, artifact_id and service_name 4 | # example: https://repo1.maven.org/maven2/com/google/cloud/google-cloud-vision google-cloud-vision vision 5 | 6 | # output: a line in the format of 7 | # artifact_id,service_name,version, and release_date for the artifacts 8 | 9 | mavenCentralURL=$1 10 | artifact_id=$2 11 | service_name=$3 12 | 13 | ##why --header="User-Agent: ? -> Maven central denies CLI requests to browse a directory URL, so imitating a browser's behaviour by using this header. 14 | wget -O mavenFile --referer --recursive -nd --no-parent \ 15 | --header="User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36" \ 16 | ${1} 17 | 18 | outputFile="maven_versions_and_dates.txt" 19 | # assume semantic versions, starting with number. Get lines from file that looks like 20 | # '0.10.0-beta/ 2017-03-17 00:01 - ' 21 | grep -E '' 24 | sed -e 's/\/"\stitle=.*<\/a>//' | \ 25 | # remove content before version 26 | sed -e 's/> "$output_filename" 42 | else 43 | echo "$default_host: Not a valid URL or No 'name' field found in $file" 44 | fi 45 | 46 | done 47 | 48 | cd ../.. 49 | 50 | rm -rf discovery-artifact-manager/ 51 | -------------------------------------------------------------------------------- /.kokoro/nightly/get-service-names.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This scripts downloads google-cloud-java repo, loop through modules with names starting "java-", 4 | # grabs artifactId from pom.xml file within submodule name starting with "google-", and 5 | # service name from *StubSettings.java file. 6 | 7 | # Run this script from repo root dir 8 | # input: N/A 9 | # output: txt file with comma separated artifact_id, service_name. 10 | 11 | git clone https://github.com/googleapis/google-cloud-java.git 12 | 13 | cd ./google-cloud-java || exit 14 | filename="../artifacts_to_services.txt" 15 | 16 | for module in $(find . -mindepth 2 -maxdepth 2 -name pom.xml | sort | xargs dirname); do 17 | echo "module: ${module}" 18 | # Only modules starting with java- contain client library artifacts. 19 | if [[ ${module} != ./java-* ]]; then 20 | echo "not a client library, continue..." 21 | continue 22 | fi 23 | # special cases, add manually later. 24 | if [[ ${module} == ./java-dns ]] || [[ ${module} == ./java-grafeas ]] || [[ ${module} == ./java-notification ]] || [[ ${module} == ./java-alloydb-connectors ]]; then 25 | continue 26 | fi 27 | cd "${module}" || exit 28 | # Find submodule with name starting with "google-", this is to exclude proto, grpc and bom folders, 29 | # and locate artifact id of client library 30 | folder=$(find . -mindepth 1 -maxdepth 1 -type d -name "google-*" ! -name "*-bom" ) 31 | echo "folder: ${folder}" 32 | if [[ -z "${folder}" ]]; then 33 | echo "Warning: No 'google-*' folder found in ${module}, skipping..." 34 | cd .. # Ensure we go back to the parent directory 35 | continue 36 | fi 37 | cd "${folder}" || continue 38 | artifact_id_string=$(find . -name 'pom.xml' -print -quit | xargs grep -m 1 '' | cut -d '>' -f 2 | cut -d '<' -f 1) 39 | echo "artifact_id_string: ${artifact_id_string}" 40 | if [[ -z "${artifact_id_string}" ]]; then 41 | echo "Warning: Could not find in pom.xml within ${folder}, skipping..." 42 | cd .. # Exit from ${folder} 43 | cd .. # Exit from ${module} 44 | continue 45 | fi 46 | cd .. # exist from folder ${folder} 47 | 48 | # Find *StubSettings file, get the first line containing '.googleapis.com:443' 49 | # Extract service name from it 50 | first_line_contain_endpoint=$(find . -name '*StubSettings.java' -print -quit | xargs grep -m 1 '.googleapis.com:443') 51 | service_name="" # Initialize service_name to an empty string 52 | if [[ -n "${first_line_contain_endpoint}" ]]; then 53 | service_name=$(echo "${first_line_contain_endpoint}" | grep -o '".*"' | tr -d '"' | cut -d "." -f 1 | cut -d "-" -f 1) 54 | echo "service name: ${service_name}" 55 | else 56 | echo "Warning: Could not find '*StubSettings.java' containing '.googleapis.com:443' in ${module}" 57 | fi 58 | echo "${artifact_id_string}, ${service_name}" >> "$filename" 59 | cd .. # exit from ${module} 60 | done 61 | 62 | # add handwritten libraries manually. 63 | { 64 | echo "google-cloud-bigquery, bigquery" 65 | echo "google-cloud-bigtable, bigtable" 66 | echo "google-cloud-bigquerystorage, bigquerystorage" 67 | echo "google-cloud-datastore, datastore" 68 | echo "google-cloud-firestore, firestore" 69 | echo "google-cloud-logging, logging" 70 | echo "google-cloud-pubsub, pubsub" 71 | echo "google-cloud-pubsublite, pubsublite" 72 | echo "google-cloud-storage, bigstore" 73 | echo "google-cloud-storage-control, storage" 74 | echo "google-cloud-spanner, spanner" 75 | echo "google-cloud-dns, dns" 76 | } >> "./artifacts_to_services.txt" 77 | 78 | cd .. 79 | mv ./google-cloud-java/artifacts_to_services.txt ./libraries-release-data/artifacts_to_services.txt 80 | # clean up 81 | rm -rf google-cloud-java/ 82 | -------------------------------------------------------------------------------- /.kokoro/nightly/integration.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | # Configure the docker image for kokoro-trampoline. 4 | env_vars: { 5 | key: "TRAMPOLINE_IMAGE" 6 | value: "gcr.io/cloud-devrel-kokoro-resources/java8" 7 | } 8 | 9 | env_vars: { 10 | key: "JOB_TYPE" 11 | value: "integration" 12 | } 13 | # TODO: remove this after we've migrated all tests and scripts 14 | env_vars: { 15 | key: "GCLOUD_PROJECT" 16 | value: "java-docs-samples-testing" 17 | } 18 | 19 | env_vars: { 20 | key: "GOOGLE_CLOUD_PROJECT" 21 | value: "java-docs-samples-testing" 22 | } 23 | 24 | env_vars: { 25 | key: "ENABLE_FLAKYBOT" 26 | value: "true" 27 | } 28 | 29 | env_vars: { 30 | key: "GOOGLE_APPLICATION_CREDENTIALS" 31 | value: "secret_manager/java-it-service-account" 32 | } 33 | 34 | env_vars: { 35 | key: "SECRET_MANAGER_KEYS" 36 | value: "java-it-service-account" 37 | } 38 | 39 | -------------------------------------------------------------------------------- /.kokoro/nightly/java11-integration.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | # Configure the docker image for kokoro-trampoline. 4 | env_vars: { 5 | key: "TRAMPOLINE_IMAGE" 6 | value: "gcr.io/cloud-devrel-public-resources/java11014" 7 | } 8 | 9 | env_vars: { 10 | key: "JOB_TYPE" 11 | value: "integration" 12 | } 13 | # TODO: remove this after we've migrated all tests and scripts 14 | env_vars: { 15 | key: "GCLOUD_PROJECT" 16 | value: "gcloud-devel" 17 | } 18 | 19 | env_vars: { 20 | key: "GOOGLE_CLOUD_PROJECT" 21 | value: "gcloud-devel" 22 | } 23 | 24 | env_vars: { 25 | key: "ENABLE_FLAKYBOT" 26 | value: "true" 27 | } 28 | 29 | env_vars: { 30 | key: "GOOGLE_APPLICATION_CREDENTIALS" 31 | value: "secret_manager/java-it-service-account" 32 | } 33 | 34 | env_vars: { 35 | key: "SECRET_MANAGER_KEYS" 36 | value: "java-it-service-account" 37 | } 38 | 39 | -------------------------------------------------------------------------------- /.kokoro/nightly/java11.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | # Configure the docker image for kokoro-trampoline. 4 | env_vars: { 5 | key: "TRAMPOLINE_IMAGE" 6 | value: "gcr.io/cloud-devrel-kokoro-resources/java11" 7 | } 8 | -------------------------------------------------------------------------------- /.kokoro/nightly/java7.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | # Configure the docker image for kokoro-trampoline. 4 | env_vars: { 5 | key: "TRAMPOLINE_IMAGE" 6 | value: "gcr.io/cloud-devrel-kokoro-resources/java7" 7 | } 8 | -------------------------------------------------------------------------------- /.kokoro/nightly/java8-osx.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | build_file: "java-cloud-bom/.kokoro/build.sh" 4 | -------------------------------------------------------------------------------- /.kokoro/nightly/java8-win.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | build_file: "java-cloud-bom/.kokoro/build.bat" 4 | -------------------------------------------------------------------------------- /.kokoro/nightly/java8.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | # Configure the docker image for kokoro-trampoline. 4 | env_vars: { 5 | key: "TRAMPOLINE_IMAGE" 6 | value: "gcr.io/cloud-devrel-kokoro-resources/java8" 7 | } 8 | 9 | env_vars: { 10 | key: "REPORT_COVERAGE" 11 | value: "true" 12 | } 13 | -------------------------------------------------------------------------------- /.kokoro/nightly/samples.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | # Configure the docker image for kokoro-trampoline. 4 | env_vars: { 5 | key: "TRAMPOLINE_IMAGE" 6 | value: "gcr.io/cloud-devrel-kokoro-resources/java8" 7 | } 8 | 9 | env_vars: { 10 | key: "JOB_TYPE" 11 | value: "samples" 12 | } 13 | 14 | # TODO: remove this after we've migrated all tests and scripts 15 | env_vars: { 16 | key: "GCLOUD_PROJECT" 17 | value: "java-docs-samples-testing" 18 | } 19 | 20 | env_vars: { 21 | key: "GOOGLE_CLOUD_PROJECT" 22 | value: "java-docs-samples-testing" 23 | } 24 | 25 | env_vars: { 26 | key: "GOOGLE_APPLICATION_CREDENTIALS" 27 | value: "secret_manager/java-docs-samples-service-account" 28 | } 29 | 30 | env_vars: { 31 | key: "SECRET_MANAGER_KEYS" 32 | value: "java-docs-samples-service-account" 33 | } 34 | 35 | env_vars: { 36 | key: "ENABLE_FLAKYBOT" 37 | value: "true" 38 | } 39 | -------------------------------------------------------------------------------- /.kokoro/populate-secrets.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright 2020 Google LLC. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | set -eo pipefail 17 | 18 | function now { date +"%Y-%m-%d %H:%M:%S" | tr -d '\n' ;} 19 | function msg { println "$*" >&2 ;} 20 | function println { printf '%s\n' "$(now) $*" ;} 21 | 22 | 23 | # Populates requested secrets set in SECRET_MANAGER_KEYS from service account: 24 | # kokoro-trampoline@cloud-devrel-kokoro-resources.iam.gserviceaccount.com 25 | SECRET_LOCATION="${KOKORO_GFILE_DIR}/secret_manager" 26 | msg "Creating folder on disk for secrets: ${SECRET_LOCATION}" 27 | mkdir -p ${SECRET_LOCATION} 28 | for key in $(echo ${SECRET_MANAGER_KEYS} | sed "s/,/ /g") 29 | do 30 | msg "Retrieving secret ${key}" 31 | docker run --entrypoint=gcloud \ 32 | --volume=${KOKORO_GFILE_DIR}:${KOKORO_GFILE_DIR} \ 33 | gcr.io/google.com/cloudsdktool/cloud-sdk \ 34 | secrets versions access latest \ 35 | --project cloud-devrel-kokoro-resources \ 36 | --secret ${key} > \ 37 | "${SECRET_LOCATION}/${key}" 38 | if [[ $? == 0 ]]; then 39 | msg "Secret written to ${SECRET_LOCATION}/${key}" 40 | else 41 | msg "Error retrieving secret ${key}" 42 | fi 43 | done 44 | -------------------------------------------------------------------------------- /.kokoro/presubmit/clirr.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | # Configure the docker image for kokoro-trampoline. 4 | 5 | env_vars: { 6 | key: "TRAMPOLINE_IMAGE" 7 | value: "gcr.io/cloud-devrel-kokoro-resources/java8" 8 | } 9 | 10 | env_vars: { 11 | key: "JOB_TYPE" 12 | value: "clirr" 13 | } -------------------------------------------------------------------------------- /.kokoro/presubmit/common.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | # Build logs will be here 4 | action { 5 | define_artifacts { 6 | regex: "**/*sponge_log.xml" 7 | regex: "**/*sponge_log.txt" 8 | } 9 | } 10 | 11 | # Download trampoline resources. 12 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" 13 | 14 | # Use the trampoline script to run in docker. 15 | build_file: "java-cloud-bom/.kokoro/trampoline.sh" 16 | 17 | env_vars: { 18 | key: "TRAMPOLINE_BUILD_FILE" 19 | value: "github/java-cloud-bom/.kokoro/build.sh" 20 | } 21 | 22 | env_vars: { 23 | key: "JOB_TYPE" 24 | value: "test" 25 | } 26 | 27 | before_action { 28 | fetch_keystore { 29 | keystore_resource { 30 | keystore_config_id: 73713 31 | keyname: "dpebot_codecov_token" 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /.kokoro/presubmit/dependencies.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | # Configure the docker image for kokoro-trampoline. 4 | env_vars: { 5 | key: "TRAMPOLINE_IMAGE" 6 | value: "gcr.io/cloud-devrel-kokoro-resources/java8" 7 | } 8 | 9 | env_vars: { 10 | key: "TRAMPOLINE_BUILD_FILE" 11 | value: "github/java-cloud-bom/.kokoro/dependencies.sh" 12 | } 13 | -------------------------------------------------------------------------------- /.kokoro/presubmit/graalvm-native-17.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | # Configure the docker image for kokoro-trampoline. 4 | env_vars: { 5 | key: "TRAMPOLINE_IMAGE" 6 | value: "gcr.io/cloud-devrel-kokoro-resources/graalvm17:22.3.3" 7 | } 8 | 9 | env_vars: { 10 | key: "JOB_TYPE" 11 | value: "graalvm17" 12 | } 13 | 14 | # TODO: remove this after we've migrated all tests and scripts 15 | env_vars: { 16 | key: "GCLOUD_PROJECT" 17 | value: "gcloud-devel" 18 | } 19 | 20 | env_vars: { 21 | key: "GOOGLE_CLOUD_PROJECT" 22 | value: "gcloud-devel" 23 | } 24 | 25 | env_vars: { 26 | key: "GOOGLE_APPLICATION_CREDENTIALS" 27 | value: "secret_manager/java-it-service-account" 28 | } 29 | 30 | env_vars: { 31 | key: "SECRET_MANAGER_KEYS" 32 | value: "java-it-service-account" 33 | } -------------------------------------------------------------------------------- /.kokoro/presubmit/graalvm-native.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | # Configure the docker image for kokoro-trampoline. 4 | env_vars: { 5 | key: "TRAMPOLINE_IMAGE" 6 | value: "gcr.io/cloud-devrel-kokoro-resources/graalvm:22.3.3" 7 | } 8 | 9 | env_vars: { 10 | key: "JOB_TYPE" 11 | value: "graalvm" 12 | } 13 | 14 | # TODO: remove this after we've migrated all tests and scripts 15 | env_vars: { 16 | key: "GCLOUD_PROJECT" 17 | value: "gcloud-devel" 18 | } 19 | 20 | env_vars: { 21 | key: "GOOGLE_CLOUD_PROJECT" 22 | value: "gcloud-devel" 23 | } 24 | 25 | env_vars: { 26 | key: "GOOGLE_APPLICATION_CREDENTIALS" 27 | value: "secret_manager/java-it-service-account" 28 | } 29 | 30 | env_vars: { 31 | key: "SECRET_MANAGER_KEYS" 32 | value: "java-it-service-account" 33 | } 34 | -------------------------------------------------------------------------------- /.kokoro/presubmit/integration.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | # Configure the docker image for kokoro-trampoline. 4 | env_vars: { 5 | key: "TRAMPOLINE_IMAGE" 6 | value: "gcr.io/cloud-devrel-kokoro-resources/java8" 7 | } 8 | 9 | env_vars: { 10 | key: "JOB_TYPE" 11 | value: "integration" 12 | } 13 | 14 | # TODO: remove this after we've migrated all tests and scripts 15 | env_vars: { 16 | key: "GCLOUD_PROJECT" 17 | value: "gcloud-devel" 18 | } 19 | 20 | env_vars: { 21 | key: "GOOGLE_CLOUD_PROJECT" 22 | value: "gcloud-devel" 23 | } 24 | 25 | env_vars: { 26 | key: "GOOGLE_APPLICATION_CREDENTIALS" 27 | value: "secret_manager/java-it-service-account" 28 | } 29 | 30 | env_vars: { 31 | key: "SECRET_MANAGER_KEYS" 32 | value: "java-it-service-account" 33 | } 34 | 35 | -------------------------------------------------------------------------------- /.kokoro/presubmit/java11.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | # Configure the docker image for kokoro-trampoline. 4 | env_vars: { 5 | key: "TRAMPOLINE_IMAGE" 6 | value: "gcr.io/cloud-devrel-kokoro-resources/java11" 7 | } 8 | -------------------------------------------------------------------------------- /.kokoro/presubmit/java7.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | # Configure the docker image for kokoro-trampoline. 4 | env_vars: { 5 | key: "TRAMPOLINE_IMAGE" 6 | value: "gcr.io/cloud-devrel-kokoro-resources/java7" 7 | } 8 | -------------------------------------------------------------------------------- /.kokoro/presubmit/java8-osx.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | build_file: "java-cloud-bom/.kokoro/build.sh" 4 | -------------------------------------------------------------------------------- /.kokoro/presubmit/java8-win.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | build_file: "java-cloud-bom/.kokoro/build.bat" 4 | -------------------------------------------------------------------------------- /.kokoro/presubmit/java8.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | # Configure the docker image for kokoro-trampoline. 4 | env_vars: { 5 | key: "TRAMPOLINE_IMAGE" 6 | value: "gcr.io/cloud-devrel-kokoro-resources/java8" 7 | } 8 | 9 | env_vars: { 10 | key: "REPORT_COVERAGE" 11 | value: "true" 12 | } 13 | -------------------------------------------------------------------------------- /.kokoro/presubmit/linkage-monitor.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | # Configure the docker image for kokoro-trampoline. 4 | env_vars: { 5 | key: "TRAMPOLINE_IMAGE" 6 | value: "gcr.io/cloud-devrel-kokoro-resources/java8" 7 | } 8 | 9 | env_vars: { 10 | key: "TRAMPOLINE_BUILD_FILE" 11 | value: "github/java-cloud-bom/.kokoro/linkage-monitor.sh" 12 | } -------------------------------------------------------------------------------- /.kokoro/presubmit/lint.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | # Configure the docker image for kokoro-trampoline. 4 | 5 | env_vars: { 6 | key: "TRAMPOLINE_IMAGE" 7 | value: "gcr.io/cloud-devrel-kokoro-resources/java8" 8 | } 9 | 10 | env_vars: { 11 | key: "JOB_TYPE" 12 | value: "lint" 13 | } -------------------------------------------------------------------------------- /.kokoro/presubmit/samples.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | # Configure the docker image for kokoro-trampoline. 4 | env_vars: { 5 | key: "TRAMPOLINE_IMAGE" 6 | value: "gcr.io/cloud-devrel-kokoro-resources/java8" 7 | } 8 | 9 | env_vars: { 10 | key: "JOB_TYPE" 11 | value: "samples" 12 | } 13 | 14 | # TODO: remove this after we've migrated all tests and scripts 15 | env_vars: { 16 | key: "GCLOUD_PROJECT" 17 | value: "java-docs-samples-testing" 18 | } 19 | 20 | env_vars: { 21 | key: "GOOGLE_CLOUD_PROJECT" 22 | value: "java-docs-samples-testing" 23 | } 24 | 25 | env_vars: { 26 | key: "GOOGLE_APPLICATION_CREDENTIALS" 27 | value: "secret_manager/java-docs-samples-service-account" 28 | } 29 | 30 | env_vars: { 31 | key: "SECRET_MANAGER_KEYS" 32 | value: "java-docs-samples-service-account" 33 | } -------------------------------------------------------------------------------- /.kokoro/readme.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright 2020 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | set -eo pipefail 17 | 18 | cd ${KOKORO_ARTIFACTS_DIR}/github/java-cloud-bom 19 | 20 | # Disable buffering, so that the logs stream through. 21 | export PYTHONUNBUFFERED=1 22 | 23 | # Kokoro exposes this as a file, but the scripts expect just a plain variable. 24 | export GITHUB_TOKEN=$(cat ${KOKORO_KEYSTORE_DIR}/73713_yoshi-automation-github-key) 25 | 26 | # Setup git credentials 27 | echo "https://${GITHUB_TOKEN}:@github.com" >> ~/.git-credentials 28 | git config --global credential.helper 'store --file ~/.git-credentials' 29 | 30 | python3.6 -m pip install git+https://github.com/googleapis/synthtool.git#egg=gcp-synthtool 31 | 32 | set +e 33 | python3.6 -m autosynth.synth \ 34 | --repository=googleapis/java-cloud-bom \ 35 | --synth-file-name=.github/readme/synth.py \ 36 | --metadata-path=.github/readme/synth.metadata \ 37 | --pr-title="chore: regenerate README" \ 38 | --branch-suffix="readme" 39 | 40 | # autosynth returns 28 to signal there are no changes 41 | RETURN_CODE=$? 42 | if [[ ${RETURN_CODE} -ne 0 && ${RETURN_CODE} -ne 28 ]] 43 | then 44 | exit ${RETURN_CODE} 45 | fi 46 | -------------------------------------------------------------------------------- /.kokoro/trampoline.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright 2018 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | set -eo pipefail 16 | # Always run the cleanup script, regardless of the success of bouncing into 17 | # the container. 18 | function cleanup() { 19 | chmod +x ${KOKORO_GFILE_DIR}/trampoline_cleanup.sh 20 | ${KOKORO_GFILE_DIR}/trampoline_cleanup.sh 21 | echo "cleanup"; 22 | } 23 | trap cleanup EXIT 24 | 25 | $(dirname $0)/populate-secrets.sh # Secret Manager secrets. 26 | python3 "${KOKORO_GFILE_DIR}/trampoline_v1.py" 27 | -------------------------------------------------------------------------------- /.release-please-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | ".": "26.61.0" 3 | } -------------------------------------------------------------------------------- /.repo-metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "api_shortname": "google-cloud-bom", 3 | "name_pretty": "Google Cloud Bill of Materials", 4 | "release_level": "preview", 5 | "language": "java", 6 | "repo": "googleapis/java-cloud-bom", 7 | "repo_short": "java-cloud-bom", 8 | "library_type": "CORE", 9 | "client_documentation": "https://cloud.google.com/java/docs/bom", 10 | "distribution_name": "com.google.cloud:google-cloud-bom" 11 | } -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | 2 | # Code of Conduct 3 | 4 | ## Our Pledge 5 | 6 | In the interest of fostering an open and welcoming environment, we as 7 | contributors and maintainers pledge to making participation in our project and 8 | our community a harassment-free experience for everyone, regardless of age, body 9 | size, disability, ethnicity, gender identity and expression, level of 10 | experience, education, socio-economic status, nationality, personal appearance, 11 | race, religion, or sexual identity and orientation. 12 | 13 | ## Our Standards 14 | 15 | Examples of behavior that contributes to creating a positive environment 16 | include: 17 | 18 | * Using welcoming and inclusive language 19 | * Being respectful of differing viewpoints and experiences 20 | * Gracefully accepting constructive criticism 21 | * Focusing on what is best for the community 22 | * Showing empathy towards other community members 23 | 24 | Examples of unacceptable behavior by participants include: 25 | 26 | * The use of sexualized language or imagery and unwelcome sexual attention or 27 | advances 28 | * Trolling, insulting/derogatory comments, and personal or political attacks 29 | * Public or private harassment 30 | * Publishing others' private information, such as a physical or electronic 31 | address, without explicit permission 32 | * Other conduct which could reasonably be considered inappropriate in a 33 | professional setting 34 | 35 | ## Our Responsibilities 36 | 37 | Project maintainers are responsible for clarifying the standards of acceptable 38 | behavior and are expected to take appropriate and fair corrective action in 39 | response to any instances of unacceptable behavior. 40 | 41 | Project maintainers have the right and responsibility to remove, edit, or reject 42 | comments, commits, code, wiki edits, issues, and other contributions that are 43 | not aligned to this Code of Conduct, or to ban temporarily or permanently any 44 | contributor for other behaviors that they deem inappropriate, threatening, 45 | offensive, or harmful. 46 | 47 | ## Scope 48 | 49 | This Code of Conduct applies both within project spaces and in public spaces 50 | when an individual is representing the project or its community. Examples of 51 | representing a project or community include using an official project e-mail 52 | address, posting via an official social media account, or acting as an appointed 53 | representative at an online or offline event. Representation of a project may be 54 | further defined and clarified by project maintainers. 55 | 56 | This Code of Conduct also applies outside the project spaces when the Project 57 | Steward has a reasonable belief that an individual's behavior may have a 58 | negative impact on the project or its community. 59 | 60 | ## Conflict Resolution 61 | 62 | We do not believe that all conflict is bad; healthy debate and disagreement 63 | often yield positive results. However, it is never okay to be disrespectful or 64 | to engage in behavior that violates the project’s code of conduct. 65 | 66 | If you see someone violating the code of conduct, you are encouraged to address 67 | the behavior directly with those involved. Many issues can be resolved quickly 68 | and easily, and this gives people more control over the outcome of their 69 | dispute. If you are unable to resolve the matter for any reason, or if the 70 | behavior is threatening or harassing, report it. We are dedicated to providing 71 | an environment where participants feel welcome and safe. 72 | 73 | Reports should be directed to *googleapis-stewards@google.com*, the 74 | Project Steward(s) for *Google Cloud Client Libraries*. It is the Project Steward’s duty to 75 | receive and address reported violations of the code of conduct. They will then 76 | work with a committee consisting of representatives from the Open Source 77 | Programs Office and the Google Open Source Strategy team. If for any reason you 78 | are uncomfortable reaching out to the Project Steward, please email 79 | opensource@google.com. 80 | 81 | We will investigate every complaint, but you may not receive a direct response. 82 | We will use our discretion in determining when and how to follow up on reported 83 | incidents, which may range from not taking action to permanent expulsion from 84 | the project and project-sponsored spaces. We will notify the accused of the 85 | report and provide them an opportunity to discuss it before any action is taken. 86 | The identity of the reporter will be omitted from the details of the report 87 | supplied to the accused. In potentially harmful situations, such as ongoing 88 | harassment or threats to anyone's safety, we may take action without notice. 89 | 90 | ## Attribution 91 | 92 | This Code of Conduct is adapted from the Contributor Covenant, version 1.4, 93 | available at 94 | https://www.contributor-covenant.org/version/1/4/code-of-conduct.html -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to Contribute 2 | 3 | The code in this repository is only intended to be used as part of the Google Cloud SDK build/test/release infrastructure, and it is not a supported Google product. Please make sure you understand the purpose of this repo before contributing. If you still would like to contribute, please follow the guidelines below before opening an issue or a PR: 4 | 1. Ensure the issue was not already reported. 5 | 2. Open a new issue if you are unable to find an existing issue addressing your problem. Make sure to include a title and clear description, as much relevant information as possible, and a code sample or an executable test case demonstrating the expected behavior that is not occurring. 6 | 3. Discuss the priority and potential solutions with the maintainers in the issue. The maintainers would review the issue and add a label "Accepting Contributions" once the issue is ready for accepting contributions. 7 | 4. Open a PR only if the issue is labeled with "Accepting Contributions", ensure the PR description clearly describes the problem and solution. Note that an open PR without an "Accepting Contributions" issue will not be accepted. 8 | 9 | ## Contributor License Agreement 10 | 11 | Contributions to this project must be accompanied by a Contributor License 12 | Agreement. You (or your employer) retain the copyright to your contribution; 13 | this simply gives us permission to use and redistribute your contributions as 14 | part of the project. Head over to to see 15 | your current agreements on file or to sign a new one. 16 | 17 | You generally only need to submit a CLA once, so if you've already submitted one 18 | (even if it was for a different project), you probably don't need to do it 19 | again. 20 | 21 | ## Code reviews 22 | 23 | All submissions, including submissions by project members, require review. We 24 | use GitHub pull requests for this purpose. Consult 25 | [GitHub Help](https://help.github.com/articles/about-pull-requests/) for more 26 | information on using pull requests. 27 | 28 | ## Community Guidelines 29 | 30 | This project follows 31 | [Google's Open Source Community Guidelines](https://opensource.google.com/conduct/). 32 | 33 | ## Building the project 34 | 35 | To build, package, and run all unit tests run the command 36 | 37 | ``` 38 | mvn clean verify 39 | ``` 40 | 41 | ### Running Integration tests 42 | 43 | To include integration tests when building the project, you need access to 44 | a GCP Project with a valid service account. 45 | 46 | For instructions on how to generate a service account and corresponding 47 | credentials JSON see: [Creating a Service Account][1]. 48 | 49 | Then run the following to build, package, run all unit tests and run all 50 | integration tests. 51 | 52 | ```bash 53 | export GOOGLE_APPLICATION_CREDENTIALS=/path/to/service/account.json 54 | mvn -Penable-integration-tests clean verify 55 | ``` 56 | 57 | ## Code Samples 58 | 59 | All code samples must be in compliance with the [java sample formatting guide][3]. 60 | Code Samples must be bundled in separate Maven modules. 61 | 62 | The samples must be separate from the primary project for a few reasons: 63 | 1. Primary projects have a minimum Java version of Java 8 whereas samples can have 64 | Java version of Java 11. Due to this we need the ability to 65 | selectively exclude samples from a build run. 66 | 2. Many code samples depend on external GCP services and need 67 | credentials to access the service. 68 | 3. Code samples are not released as Maven artifacts and must be excluded from 69 | release builds. 70 | 71 | ### Building 72 | 73 | ```bash 74 | mvn clean verify 75 | ``` 76 | 77 | Some samples require access to GCP services and require a service account: 78 | 79 | ```bash 80 | export GOOGLE_APPLICATION_CREDENTIALS=/path/to/service/account.json 81 | mvn clean verify 82 | ``` 83 | 84 | ### Code Formatting 85 | 86 | Code in this repo is formatted with 87 | [google-java-format](https://github.com/google/google-java-format). 88 | To run formatting on your project, you can run: 89 | ``` 90 | mvn com.coveo:fmt-maven-plugin:format 91 | ``` 92 | 93 | [1]: https://cloud.google.com/docs/authentication/getting-started#creating_a_service_account 94 | [2]: https://maven.apache.org/settings.html#Active_Profiles 95 | [3]: https://github.com/GoogleCloudPlatform/java-docs-samples/blob/main/SAMPLE_FORMAT.md -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | To report a security issue, please use [g.co/vulnz](https://g.co/vulnz). 4 | 5 | The Google Security Team will respond within 5 working days of your report on g.co/vulnz. 6 | 7 | We use g.co/vulnz for our intake, and do coordination and disclosure here using GitHub Security Advisory to privately discuss and fix the issue. 8 | -------------------------------------------------------------------------------- /dashboard/README.md: -------------------------------------------------------------------------------- 1 | To generate the dashboard from the root directory, run: 2 | 3 | ```bash 4 | $ cd dashboard 5 | $ mvn clean install 6 | $ mvn exec:java -Dexec.args="-f ../pom.xml" 7 | ``` 8 | 9 | To generate all dashboards (version 0.124.0 and onwards), including the All Versions page, run: 10 | 11 | ```bash 12 | $ cd dashboard 13 | $ mvn clean install 14 | $ mvn exec:java -Dexec.args="-a com.google.cloud:google-cloud-bom" 15 | ``` 16 | 17 | To run a report, run: 18 | 19 | ```bash 20 | $ cd dashboard 21 | $ mvn clean install 22 | $ mvn exec:java -Dexec.args="-f ../pom.xml --report" 23 | ``` -------------------------------------------------------------------------------- /dashboard/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.google.cloud.tools 8 | dependencies-parent 9 | 1.5.13 10 | 11 | 12 | google-cloud-bom-dashboard 13 | 0.0.1-SNAPSHOT 14 | 15 | Google Cloud BOM Dashboard 16 | https://github.com/googleapis/java-cloud-bom/tree/master/dashboard 17 | 18 | Google LLC. 19 | https://www.google.com 20 | 21 | 22 | 23 | 24 | The Apache License, Version 2.0 25 | http://www.apache.org/licenses/LICENSE-2.0.txt 26 | 27 | 28 | 29 | 30 | UTF-8 31 | 1.8 32 | 1.8 33 | 34 | 35 | 36 | 37 | org.freemarker 38 | freemarker 39 | 2.3.34 40 | 41 | 42 | 43 | org.apache.maven 44 | maven-compat 45 | ${maven.version} 46 | 47 | 48 | org.apache.maven 49 | maven-model 50 | ${maven.version} 51 | 52 | 53 | org.apache.maven.resolver 54 | maven-resolver-api 55 | 1.9.23 56 | 57 | 58 | org.codehaus.plexus 59 | plexus-utils 60 | 3.6.0 61 | 62 | 63 | org.apache.maven 64 | maven-repository-metadata 65 | ${maven.version} 66 | 67 | 68 | junit 69 | junit 70 | 4.13.2 71 | 72 | 73 | com.google.truth 74 | truth 75 | 1.4.4 76 | test 77 | 78 | 79 | commons-cli 80 | commons-cli 81 | 1.9.0 82 | 83 | 84 | commons-io 85 | commons-io 86 | 2.17.0 87 | 88 | 89 | com.google.cloud.tools 90 | dependencies 91 | 1.5.13 92 | 93 | 94 | com.google.code.findbugs 95 | jsr305 96 | 3.0.2 97 | 98 | 99 | org.apache.maven 100 | maven-artifact 101 | 3.9.9 102 | 103 | 104 | 105 | 106 | 107 | 108 | org.codehaus.mojo 109 | exec-maven-plugin 110 | 111 | false 112 | com.google.cloud.tools.opensource.cloudbomdashboard.DashboardMain 113 | 114 | 115 | 116 | 117 | 118 | src/main/resources 119 | 120 | **/*.css 121 | **/*.js 122 | **/*.xml 123 | **/*.ftl 124 | 125 | false 126 | 127 | 128 | 129 | 130 | 131 | -------------------------------------------------------------------------------- /dashboard/src/main/java/com/google/cloud/tools/opensource/cloudbomdashboard/ArtifactCache.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Google LLC. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.cloud.tools.opensource.cloudbomdashboard; 18 | 19 | import com.google.cloud.tools.opensource.dependencies.DependencyGraph; 20 | import java.util.List; 21 | import java.util.Map; 22 | import org.eclipse.aether.artifact.Artifact; 23 | 24 | /** Unified return type to bundle a lot of information about multiple artifacts together. */ 25 | class ArtifactCache { 26 | 27 | private Map infoMap; 28 | private List globalDependencies; 29 | 30 | void setInfoMap(Map infoMap) { 31 | this.infoMap = infoMap; 32 | } 33 | 34 | void setGlobalDependencies(List globalDependencies) { 35 | this.globalDependencies = globalDependencies; 36 | } 37 | 38 | Map getInfoMap() { 39 | return infoMap; 40 | } 41 | 42 | List getGlobalDependencies() { 43 | return globalDependencies; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /dashboard/src/main/java/com/google/cloud/tools/opensource/cloudbomdashboard/ArtifactInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Google LLC. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.cloud.tools.opensource.cloudbomdashboard; 18 | 19 | import com.google.cloud.tools.opensource.dependencies.DependencyGraph; 20 | import org.eclipse.aether.RepositoryException; 21 | 22 | /** Cache of info looked up for an artifact. */ 23 | class ArtifactInfo { 24 | 25 | private DependencyGraph completeDependencies; 26 | private DependencyGraph transitiveDependencies; 27 | private RepositoryException exception; 28 | 29 | ArtifactInfo(DependencyGraph completeDependencies, DependencyGraph transitiveDependencies) { 30 | this.completeDependencies = completeDependencies; 31 | this.transitiveDependencies = transitiveDependencies; 32 | } 33 | 34 | ArtifactInfo(RepositoryException ex) { 35 | this.exception = ex; 36 | } 37 | 38 | DependencyGraph getCompleteDependencies() { 39 | return completeDependencies; 40 | } 41 | 42 | DependencyGraph getTransitiveDependencies() { 43 | return transitiveDependencies; 44 | } 45 | 46 | RepositoryException getException() { 47 | return exception; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /dashboard/src/main/java/com/google/cloud/tools/opensource/cloudbomdashboard/ArtifactResults.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Google LLC. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.cloud.tools.opensource.cloudbomdashboard; 18 | 19 | import com.google.cloud.tools.opensource.dependencies.Artifacts; 20 | import java.util.HashMap; 21 | import java.util.Map; 22 | import javax.annotation.Nullable; 23 | import org.eclipse.aether.artifact.Artifact; 24 | 25 | /** Collection of test results for a single artifact. */ 26 | public final class ArtifactResults { 27 | 28 | private final Map results = new HashMap<>(); 29 | private final Artifact artifact; 30 | private String exceptionMessage; 31 | 32 | public ArtifactResults(Artifact artifact) { 33 | this.artifact = artifact; 34 | } 35 | 36 | public void setExceptionMessage(String exceptionMessage) { 37 | this.exceptionMessage = exceptionMessage; 38 | } 39 | 40 | void addResult(String testName, int failures) { 41 | results.put(testName, failures); 42 | } 43 | 44 | /** @return true for pass, false for fail, null for unknown test */ 45 | @Nullable 46 | public Boolean getResult(String testName) { 47 | Integer failures = results.get(testName); 48 | if (failures != null) { 49 | return failures == 0; 50 | } 51 | return null; 52 | } 53 | 54 | public String getCoordinates() { 55 | return Artifacts.toCoordinates(artifact); 56 | } 57 | 58 | /** @return message of exception occurred when running test, null for no exception */ 59 | @Nullable 60 | public String getExceptionMessage() { 61 | return exceptionMessage; 62 | } 63 | 64 | /** @return number of times the specified test failed. Returns 0 if the test was not run. */ 65 | public int getFailureCount(String testName) { 66 | Integer failures = results.get(testName); 67 | if (failures == null) { 68 | return 0; 69 | } 70 | return failures; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /dashboard/src/main/java/com/google/cloud/tools/opensource/cloudbomdashboard/DashboardArguments.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Google LLC. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.cloud.tools.opensource.cloudbomdashboard; 18 | 19 | import java.nio.file.Path; 20 | import java.nio.file.Paths; 21 | import javax.annotation.Nullable; 22 | import org.apache.commons.cli.CommandLine; 23 | import org.apache.commons.cli.CommandLineParser; 24 | import org.apache.commons.cli.DefaultParser; 25 | import org.apache.commons.cli.HelpFormatter; 26 | import org.apache.commons.cli.Option; 27 | import org.apache.commons.cli.OptionGroup; 28 | import org.apache.commons.cli.Options; 29 | import org.apache.commons.cli.ParseException; 30 | 31 | /** 32 | * Command-line option for {@link DashboardMain}. The tool takes either a pom.xml file path or Maven 33 | * coordinates for a BOM. 34 | */ 35 | final class DashboardArguments { 36 | private static final Options options = configureOptions(); 37 | private static final HelpFormatter helpFormatter = new HelpFormatter(); 38 | 39 | private final CommandLine commandLine; 40 | 41 | private DashboardArguments(CommandLine commandLine) { 42 | this.commandLine = commandLine; 43 | } 44 | 45 | /** 46 | * Returns true if the argument for a file is specified. False if the argument for coordinates is 47 | * specified. 48 | * 49 | *

It is guaranteed that either a file path or Maven coordinates for a BOM are available. 50 | */ 51 | boolean hasFile() { 52 | return commandLine.hasOption('f'); 53 | } 54 | 55 | /** 56 | * Returns true if the argument for a versionless coordinates is specified; otherwise false. 57 | * 58 | *

It is guaranteed that either a file path or Maven coordinates for a BOM are available. 59 | */ 60 | boolean hasVersionlessCoordinates() { 61 | return commandLine.hasOption('a'); 62 | } 63 | 64 | /** Returns an absolute path to pom.xml file of a BOM. Null if file is not specified. */ 65 | @Nullable 66 | Path getBomFile() { 67 | if (!commandLine.hasOption('f')) { 68 | return null; 69 | } 70 | // Trim the value so that maven exec plugin can pass arguments with exec.arguments="-f pom.xml" 71 | return Paths.get(commandLine.getOptionValue('f').trim()).toAbsolutePath(); 72 | } 73 | 74 | /** Returns the Maven coordinates of a BOM. Null if coordinates are not specified. */ 75 | @Nullable 76 | String getBomCoordinates() { 77 | if (!commandLine.hasOption('c')) { 78 | return null; 79 | } 80 | return commandLine.getOptionValue('c').trim(); 81 | } 82 | 83 | /** 84 | * Returns the versionless Maven coordinates of a BOM. Null if versionless coordinates are not 85 | * specified. 86 | */ 87 | @Nullable 88 | String getVersionlessCoordinates() { 89 | if (!commandLine.hasOption('a')) { 90 | return null; 91 | } 92 | return commandLine.getOptionValue('a').trim(); 93 | } 94 | 95 | boolean getReport() { 96 | return commandLine.hasOption('r'); 97 | } 98 | 99 | Path getOutputFile() { 100 | if (!commandLine.hasOption('o')) { 101 | return null; 102 | } 103 | return Paths.get(commandLine.getOptionValue('o').trim()).toAbsolutePath(); 104 | } 105 | 106 | static DashboardArguments readCommandLine(String... arguments) throws ParseException { 107 | CommandLineParser parser = new DefaultParser(); 108 | 109 | try { 110 | // Throws ParseException if required option group ('-f' or '-c') is not specified 111 | return new DashboardArguments(parser.parse(options, arguments)); 112 | } catch (ParseException ex) { 113 | helpFormatter.printHelp("DashboardMain", options); 114 | throw ex; 115 | } 116 | } 117 | 118 | private static Options configureOptions() { 119 | Options options = new Options(); 120 | OptionGroup inputGroup = new OptionGroup(); 121 | inputGroup.setRequired(true); 122 | 123 | Option inputFileOption = 124 | Option.builder("f").longOpt("bom-file").hasArg().desc("File to a BOM (pom.xml)").build(); 125 | inputGroup.addOption(inputFileOption); 126 | 127 | Option inputCoordinatesOption = 128 | Option.builder("c") 129 | .longOpt("bom-coordinates") 130 | .hasArg() 131 | .desc("Maven coordinates of a BOM. For example, com.google.cloud:libraries-bom:1.0.0") 132 | .build(); 133 | inputGroup.addOption(inputCoordinatesOption); 134 | 135 | Option versionlessCoordinatesOption = 136 | Option.builder("a") 137 | .longOpt("all-versions") 138 | .hasArg() 139 | .desc( 140 | "Maven coordinates of a BOM without version. " 141 | + "For example, com.google.cloud:libraries-bom") 142 | .build(); 143 | inputGroup.addOption(versionlessCoordinatesOption); 144 | 145 | options.addOptionGroup(inputGroup); 146 | 147 | Option reportOption = 148 | Option.builder("r") 149 | .longOpt("report") 150 | .hasArg(false) 151 | .desc("Whether to print the report or build the dashboard") 152 | .build(); 153 | options.addOption(reportOption); 154 | 155 | Option outputOption = 156 | Option.builder("o") 157 | .longOpt("output-file") 158 | .hasArg() 159 | .desc("Whether to print the report to a file or display on console") 160 | .build(); 161 | options.addOption(outputOption); 162 | 163 | return options; 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /dashboard/src/main/java/com/google/cloud/tools/opensource/cloudbomdashboard/VersionData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Google LLC. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.cloud.tools.opensource.cloudbomdashboard; 18 | 19 | import java.time.LocalDateTime; 20 | import java.util.Arrays; 21 | import java.util.HashMap; 22 | import java.util.HashSet; 23 | import java.util.Map; 24 | import java.util.Set; 25 | import org.eclipse.aether.artifact.Artifact; 26 | 27 | /** 28 | * Consolidates all instances of ArtifactMavenData and assists in the creation of our template data 29 | * by constructing all maps for each artifact. 30 | */ 31 | public class VersionData { 32 | 33 | /* Contains all data from Maven central for the given artifact */ 34 | private static final Map artifactData = new HashMap<>(); 35 | private static final Map> cloudBomVersionToArtifacts = new HashMap<>(); 36 | 37 | public static final String ALL_VERSIONS_NAME = "all-versions"; 38 | 39 | private VersionData() {} 40 | 41 | /** 42 | * @param cloudBomVersion the version of google-cloud-bom associated with the set of artifacts 43 | * @param artifacts the set of artifacts to be pulled from Maven central 44 | */ 45 | public static void addData(String cloudBomVersion, Set artifacts) { 46 | cloudBomVersionToArtifacts.put(cloudBomVersion, artifacts); 47 | for (Artifact artifact : artifacts) { 48 | if (!artifactData.containsKey(artifact)) { 49 | artifactData.put(artifact, ArtifactMavenData.generateArtifactMavenData(artifact)); 50 | } 51 | } 52 | } 53 | 54 | /** Returns the Freemarker 'template data' formatting of our artifacts */ 55 | public static Map createTemplateData(String... versions) { 56 | // Freemarker template 57 | Map templateData = new HashMap<>(); 58 | 59 | // Mappings used within Freemarker file 60 | // All mappings are of the form key=artifactId:cloudBomVersion 61 | // value=currentVersion of artifact in cloudBomVersion, 62 | // value=newestVersion of artifact, etc. 63 | Map currentVersion = new HashMap<>(); 64 | Map newestVersion = new HashMap<>(); 65 | Map newestPomUrl = new HashMap<>(); 66 | Map sharedDependenciesVersion = new HashMap<>(); 67 | Map updatedTime = new HashMap<>(); 68 | Map metadataUrl = new HashMap<>(); 69 | Map sharedDependenciesPosition = new HashMap<>(); 70 | 71 | Set artifactIds = new HashSet<>(); 72 | 73 | Set versionSet = new HashSet<>(Arrays.asList(versions)); 74 | // There are no artifacts directly associated with the 'all-versions' name. 75 | // This acts as a check in case it is passed. 76 | versionSet.remove(ALL_VERSIONS_NAME); 77 | 78 | for (String cloudBomVersion : versionSet) { 79 | Set cloudBomArtifacts = cloudBomVersionToArtifacts.get(cloudBomVersion); 80 | if (cloudBomArtifacts == null) { 81 | continue; 82 | } 83 | for (Artifact artifact : cloudBomArtifacts) { 84 | String artifactKey = artifact.getArtifactId() + ":" + cloudBomVersion; 85 | ArtifactMavenData artifactMavenData = artifactData.get(artifact); 86 | 87 | artifactIds.add(artifact.getArtifactId()); 88 | currentVersion.put(artifactKey, artifact.getVersion()); 89 | newestVersion.put(artifactKey, artifactMavenData.getLatestVersion()); 90 | newestPomUrl.put(artifactKey, artifactMavenData.getPomFileUrl()); 91 | sharedDependenciesVersion.put( 92 | artifactKey, artifactMavenData.getSharedDependenciesVersion()); 93 | sharedDependenciesPosition.put( 94 | artifactKey, artifactMavenData.getSharedDependenciesPosition()); 95 | updatedTime.put(artifactKey, artifactMavenData.getLastUpdated()); 96 | metadataUrl.put(artifactKey, artifactMavenData.getMetadataUrl()); 97 | } 98 | } 99 | templateData.put("currentVersion", currentVersion); 100 | templateData.put("sharedDependenciesPosition", sharedDependenciesPosition); 101 | templateData.put("newestVersion", newestVersion); 102 | templateData.put("newestPomUrl", newestPomUrl); 103 | templateData.put("sharedDependenciesVersion", sharedDependenciesVersion); 104 | templateData.put("updatedTime", updatedTime); 105 | templateData.put("metadataUrl", metadataUrl); 106 | templateData.put("artifacts", artifactIds); 107 | templateData.put("versions", versionSet); 108 | if (versions.length == 1) { 109 | templateData.put("staticVersion", versions[0]); 110 | } else { 111 | templateData.put("staticVersion", "All Versions"); 112 | } 113 | templateData.put("lastUpdated", LocalDateTime.now()); 114 | return templateData; 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /dashboard/src/main/resources/css/dashboard.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: "Poppins", sans-serif; 3 | font-weight: 400; 4 | line-height: 1.625; 5 | margin-left: 2em; 6 | } 7 | 8 | #libraryVersions { 9 | font-family: "Trebuchet MS", Arial, Helvetica, sans-serif; 10 | border-collapse: collapse; 11 | margin-left: 12.5%; 12 | margin-right: 12.5%; 13 | width: 75%; 14 | } 15 | 16 | #libraryVersions td, #libraryVersions th { 17 | border: 1px solid #ddd; 18 | padding: 8px; 19 | text-align: center; 20 | } 21 | 22 | #libraryVersions th { 23 | cursor: pointer; 24 | } 25 | 26 | #libraryVersions tr:nth-child(even) { 27 | background-color: #f2f2f2; 28 | } 29 | 30 | #libraryVersions tr:hover { 31 | background-color: #ddd; 32 | } 33 | 34 | #libraryVersions th { 35 | padding-top: 12px; 36 | padding-bottom: 12px; 37 | text-align: left; 38 | background-color: #4CAF50; 39 | color: white; 40 | } 41 | 42 | h1, 43 | h2, 44 | h3 { 45 | color: #333333; 46 | font-weight: 700; 47 | line-height: 1.2; 48 | margin-top: 1ex; 49 | margin-bottom: 1ex; 50 | } 51 | 52 | h1 { 53 | font-size: 3em; 54 | } 55 | 56 | h2 { 57 | font-size: 2.5em; 58 | } 59 | 60 | h3 { 61 | font-size: 2em; 62 | } 63 | 64 | pre { 65 | line-height: normal; 66 | } 67 | 68 | .pass { 69 | background-color: lightgreen; 70 | font-weight: bold; 71 | } 72 | 73 | .fail { 74 | background-color: pink; 75 | font-weight: bold; 76 | } 77 | 78 | .unavailable { 79 | background-color: gray; 80 | font-weight: bold; 81 | } 82 | 83 | p.dependency-tree-node { 84 | margin-top: 0; 85 | margin-bottom: 0; 86 | } 87 | 88 | .linkage-check-dependency-paths, .jar-linkage-report { 89 | margin-left: 1em; 90 | } 91 | 92 | p.jar-linkage-report-cause { 93 | margin-bottom: 0; 94 | margin-left: 2em; 95 | } 96 | 97 | ul.jar-linkage-report-cause { 98 | margin-top: 0; 99 | margin-left: 3em; 100 | } 101 | 102 | ul.jar-linkage-report-cause > li { 103 | font: 1em 'Droid Sans Mono', monospace; 104 | } 105 | 106 | /* ----- Statistic ----- */ 107 | .statistics { 108 | padding-top: 50px; 109 | } 110 | 111 | .container { 112 | min-height: 20ex; 113 | display: flex; 114 | flex-wrap: wrap; 115 | align-items: flex-start; 116 | } 117 | 118 | .statistic-item { 119 | flex: 0 0 16em; 120 | padding: 1.6em 2.5em; 121 | position: relative; 122 | min-height: 180px; 123 | overflow: hidden; 124 | border-radius: 25px; 125 | box-shadow: 0 10px 20px 0 rgba(0, 0, 0, 0.03); 126 | margin: auto; 127 | border-style: solid; 128 | border-width: medium; 129 | } 130 | 131 | .statistic-item .desc { 132 | font-size: 1.15em; 133 | text-transform: uppercase; 134 | font-weight: 300; 135 | } 136 | 137 | .statistic-item h2 { 138 | font-size: 2.3em; 139 | font-weight: 300; 140 | } 141 | 142 | .statistic-item-green { 143 | border-color: #00b26f; 144 | } 145 | 146 | .statistic-item-orange { 147 | border-color: #ff8300; 148 | } 149 | 150 | .statistic-item-blue { 151 | border-color: #00b5e9; 152 | } 153 | 154 | .statistic-item-red { 155 | border-color: #fa4251; 156 | } 157 | 158 | .statistic-item-yellow { 159 | border-color: #f1c40f; 160 | } 161 | 162 | #filterBar { 163 | width: 50%; 164 | font-size: 16px; 165 | padding: 12px 40px 12px 40px; 166 | border: 1px solid #ddd; 167 | margin-left: 25%; 168 | margin-right: 25%; 169 | margin-bottom: 12px; 170 | background: #f1f1f1; 171 | height: 30px; 172 | } 173 | 174 | .dropdown-button { 175 | background-color: #00b26f; 176 | color: white; 177 | padding: 16px; 178 | font-size: 16px; 179 | border: none; 180 | cursor: pointer; 181 | } 182 | 183 | .dropdown { 184 | position: relative; 185 | display: inline-block; 186 | cursor: pointer; 187 | } 188 | 189 | .dropdown-content { 190 | display: none; 191 | position: absolute; 192 | background-color: white; 193 | box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.2); 194 | z-index: 1; 195 | cursor: pointer; 196 | } 197 | 198 | .dropdown-content a { 199 | color: black; 200 | padding: 12px 16px; 201 | text-decoration: none; 202 | display: block; 203 | cursor: pointer; 204 | } 205 | 206 | .dropdown-content a:hover { 207 | background-color: #ddd; 208 | cursor: pointer; 209 | } 210 | 211 | .dropdown:hover .dropdown-content { 212 | display: block; 213 | cursor: pointer; 214 | } 215 | 216 | .dropdown:hover .dropdown-button { 217 | cursor: pointer; 218 | } -------------------------------------------------------------------------------- /dashboard/src/main/resources/js/dashboard.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Google LLC. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Toggles the visibility of source class list below the button. 19 | * @param button clicked button element 20 | */ 21 | function toggleSourceClassListVisibility(button) { 22 | const classList = button.parentElement.nextElementSibling; 23 | const currentVisibility = classList.style.display !== "none"; 24 | const nextVisibility = !currentVisibility; 25 | classList.style.display = nextVisibility ? "" : "none"; 26 | button.innerText = nextVisibility ? "▼" : "▶"; 27 | } 28 | 29 | function compareVersions(v1, v2) { 30 | // create arrays of version numbers 31 | var mavenVersion1; 32 | if (v1.indexOf("-") >= 0) { 33 | mavenVersion1 = v1.substring(0, v1.indexOf("-")).split("."); 34 | } else { 35 | mavenVersion1 = v1.split("."); 36 | } 37 | var mavenVersion2; 38 | if (v2.indexOf("-") >= 0) { 39 | mavenVersion2 = v2.substring(0, v2.indexOf("-")).split("."); 40 | } else { 41 | mavenVersion2 = v2.split("."); 42 | } 43 | for (let i = 0; i < mavenVersion1.length && i < mavenVersion2.length; i++) { 44 | if (isNaN(mavenVersion1[i]) || isNaN(mavenVersion2[i])) { 45 | return v1.toString().localeCompare(v2); 46 | } 47 | if (Number(mavenVersion1[i]) != Number(mavenVersion2[i])) { 48 | return Number(mavenVersion1[i]) - Number(mavenVersion2[i]); 49 | } 50 | } 51 | return v1.toString().localeCompare(v2); 52 | } 53 | 54 | const getCellValue = (tr, idx) => tr.children[idx].innerText || tr.children[idx].textContent; 55 | 56 | // comparator for sorting 57 | const comparer = (columnHeader, idx, asc) => (a, b) => { 58 | return (function (v1, v2) { 59 | return compareVersions(v1, v2); 60 | }) 61 | (getCellValue(asc ? a : b, idx), getCellValue(asc ? b : a, idx)); 62 | }; 63 | 64 | document.querySelectorAll('th').forEach(th => th.addEventListener('click', (() => { 65 | const table = th.closest('table'); 66 | document.querySelectorAll('th').forEach(otherTh => { 67 | if (otherTh != th) { 68 | // Remove all special characters 69 | otherTh.innerText = otherTh.innerText.replace(/[^\x00-\x7F]/g, ""); 70 | } else { 71 | if (otherTh.innerText.indexOf('\u25BC') > -1) { 72 | otherTh.innerText = otherTh.innerText.split(" ")[0] + " \u25B2"; 73 | } else { 74 | otherTh.innerText = otherTh.innerText.split(" ")[0] + " \u25BC"; 75 | } 76 | } 77 | }); 78 | Array.from(table.querySelectorAll('tr:nth-child(n+2)')) 79 | .sort(comparer(th.innerText, Array.from(th.parentNode.children).indexOf(th), 80 | this.asc = !this.asc)) 81 | .forEach(tr => table.appendChild(tr)); 82 | }))); 83 | 84 | function colsContainAllInput(cols, input) { 85 | for (let i = 0; i < input.length; i++) { 86 | if (input[i].length == 0) { 87 | continue; 88 | } 89 | // by this point, our input is already split for us 90 | // search for column keys (shortened or full name) 91 | let found = false; 92 | let checkSpecificColumn = input[i].indexOf(":") > -1; 93 | let col = checkSpecificColumn ? input[i].split(":")[0] : ""; 94 | let currInput = checkSpecificColumn ? input[i].split(":")[1] : input[i]; 95 | /* Enough specific conditions that it's simpler to hard-code */ 96 | if (checkSpecificColumn) { 97 | var name; 98 | if (col.indexOf("google-cloud-bom") > -1 || col.indexOf("gcb") > -1) { 99 | name = cols[0].textContent || cols[0].innerText; 100 | } else if (col.indexOf("artifact") > -1 || col === "a") { 101 | name = cols[1].textContent || cols[1].innerText; 102 | } else if (col.indexOf("artifact-version") > -1 || col.indexOf("av") > -1) { 103 | name = cols[2].textContent || cols[2].innerText; 104 | } else if (col.indexOf("google-cloud-shared-dependencies") > -1 || col.indexOf("gcsd") 105 | > -1) { 106 | name = cols[cols.length - 1].textContent || cols[cols.length - 1].innerText; 107 | } 108 | // Make sure name has a non-empty value that matches a column name 109 | found = name && name !== "" && name.toLowerCase().indexOf(currInput) > -1; 110 | } else { 111 | check_all_cols: 112 | for (let j = 0; j < cols.length; j++) { 113 | let name = cols[j].textContent || cols[j].innerText; 114 | if (name.toLowerCase().indexOf(currInput) > -1) { 115 | found = true; 116 | break check_all_cols; 117 | } 118 | } 119 | } 120 | if (!found) { 121 | return false; 122 | } 123 | } 124 | return true; 125 | } 126 | 127 | function filterFunction() { 128 | const input = document.getElementById("filterBar").value.toLowerCase(); 129 | const table = document.getElementById("libraryVersions"); 130 | const rows = table.getElementsByTagName("tr") 131 | // if our input is empty, we should not filter anything 132 | if (input === "") { 133 | for (let i = 1; i < rows.length; i++) { 134 | rows[i].style.display = ""; 135 | } 136 | return; 137 | } 138 | // split the searchbar input by commas if present, or spaces otherwise 139 | const splitInput = input.indexOf(",") > -1 ? input.replace(/ /g, '').split(",") : input.split( 140 | " "); 141 | for (let i = 1; i < rows.length; i++) { 142 | const cols = rows[i].getElementsByTagName("td"); 143 | let isDisplay = colsContainAllInput(cols, splitInput); 144 | // remove a column's display if it does not match search bar input 145 | rows[i].style.display = isDisplay ? "" : "none"; 146 | } 147 | } 148 | 149 | /** 150 | * ------------------------------------------ 151 | * 152 | * +-------------------------------------+ 153 | * | Unit Tests for sorting code based | 154 | * | on Maven VersionComparator. | 155 | * | | 156 | * | Dashboard will still be created if | 157 | * | the unit tests do not pass, but the | 158 | * | console will log errors. | 159 | * +------------------------------------ | 160 | * 161 | * ------------------------------------------ 162 | */ 163 | function testCompareVersions() { 164 | console.assert(compareVersions("1.2.3", "1.3.3") < 0); 165 | console.assert(compareVersions("1.59.0", "1.100.1") < 0); 166 | console.assert(compareVersions("1.0.0-alpha", "1.0.0-beta") < 0); 167 | 168 | console.assert(compareVersions("1.0.0", "1.0.0") === 0); 169 | 170 | console.assert(compareVersions("1.22.3", "1.21.3") > 0); 171 | console.assert(compareVersions("1.22.3", "1.2.3") > 0); 172 | console.assert(compareVersions("1.20.3", "1.19.4") > 0); 173 | console.assert(compareVersions("22.99.33", "21.99.33") > 0); 174 | console.assert(compareVersions("200.99.33", "22.99.33") > 0); 175 | } 176 | 177 | testCompareVersions(); -------------------------------------------------------------------------------- /dashboard/src/main/resources/poms/demo.xml: -------------------------------------------------------------------------------- 1 | 4 | 4.0.0 5 | 6 | com.google.cloud 7 | demo 8 | 1.0-SNAPSHOT 9 | jar 10 | 11 | demo-pom 12 | 13 | 14 | UTF-8 15 | 1.8 16 | 17 | 18 | 19 | 20 | ${dependencyGroupId} 21 | ${dependencyArtifactId} 22 | ${dependencyVersion} 23 | test 24 | 25 | 26 | 27 | 28 | 29 | 30 | org.apache.maven.plugins 31 | maven-enforcer-plugin 32 | 3.0.0-M1 33 | 34 | 35 | enforce 36 | 37 | enforce 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /dashboard/src/main/resources/templates/index.ftl: -------------------------------------------------------------------------------- 1 | 2 | 3 | <#include "macros.ftl"> 4 | 5 | 6 | Google Cloud Platform Java Open Source Dependency Dashboard 7 | 8 | 9 | 10 |

Google-Cloud-BOM ${staticVersion}

11 |
12 | <#assign totalArtifacts = table?size> 13 | 14 |
22 | 23 | <#if coordinates != "all-versions"> 24 |
25 |
26 |
27 |

${table?size}

28 | Total Artifacts Checked 29 |
30 | 31 |
32 | <#assign localUpperBoundsErrorCount = dashboardMain.countFailures(table, "Upper Bounds")> 33 |

${dashboardMain.countFailures(table, "Upper Bounds")}

34 | ${(localUpperBoundsErrorCount == 1)?then("Has", "Have")} Upper Bounds Errors 35 |
36 | 37 |
38 | <#assign convergenceErrorCount = dashboardMain.countFailures(table, "Dependency Convergence")> 39 |

${dashboardMain.countFailures(table, "Dependency Convergence")}

40 | ${(convergenceErrorCount == 1)?then("Fails", "Fail")} to Converge 41 |
42 |
43 |
44 | 45 | 46 |

Search for artifacts and the versions of associated google-cloud-shared-dependencies each uses, 47 | within its correspondence of Google-Cloud-BOM.

48 |

Search by specifying "columnName:data".
49 | Multi-column search is supported. For example, column1:value1, column2:value2, column3:value3... 50 |
51 | Column name shorthand is supported. For example, gcb:0.132.0, gcsd:0.8.3
52 | Search for google-cloud-accesssapproval with version 1.4.0 53 | by using either 'artifact:approval artifact-version:1.4.0' or 'approval 1.4.0' or 'approval, 54 | 1.4.0')

55 | 56 | 57 | 58 | 59 | 60 | 61 | <#if coordinates != "all-versions"> 62 | 63 | 64 | 65 | <#else> 66 | 67 | 68 | 69 | <#list artifacts as artifact> 70 | <#list versions as version> 71 | 72 | <#assign key = artifact + ":" + version> 73 | 74 | 75 | <#if sharedDependenciesPosition[key]??> 76 | 78 | <#else> 79 | 80 | 81 | <#if coordinates != "all-versions"> 82 | 83 | 84 | 85 | <#if sharedDependenciesVersion[key]??> 86 | 87 | <#else> 88 | 89 | 90 | 91 | 92 | 93 |
google-cloud-bomartifactartifact-versionlatest-released-versionlatest-released-dategoogle-cloud-shared-dependenciesgoogle-cloud-shared-dependencies
${version}${artifact}${currentVersion[key]}N/A${newestVersion[key]}${updatedTime[key]}${sharedDependenciesVersion[key]}N/A
94 | 95 |
96 | 97 |

Last generated at ${lastUpdated}

98 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /dashboard/src/main/resources/templates/macros.ftl: -------------------------------------------------------------------------------- 1 | <#function pluralize number singularNoun pluralNoun> 2 | <#local plural = number gt 1 /> 3 | <#return number + " " + plural?string(pluralNoun, singularNoun)> 4 | 5 | 6 | <#function plural number singularNoun pluralNoun> 7 | <#local plural = number gt 1 /> 8 | <#return plural?string(pluralNoun, singularNoun)> 9 | 10 | 11 | <#macro formatJarLinkageReport classPathEntry problemsWithClass classPathResult dependencyPathRootCauses> 12 | 14 | <#assign problemsToClasses = problemsWithClass.asMap() /> 15 | <#assign symbolProblemCount = problemsToClasses?size /> 16 | <#assign referenceCount = 0 /> 17 | <#list problemsToClasses?values as classes> 18 | <#assign referenceCount += classes?size /> 19 | 20 | 21 |

${classPathEntry?html}

22 |

23 | ${pluralize(symbolProblemCount, "target class", "target classes")} 24 | causing linkage errors referenced from 25 | ${pluralize(referenceCount, "source class", "source classes")}. 26 |

27 | <#assign jarsInProblem = {} > 28 | <#list problemsToClasses as symbolProblem, sourceClasses> 29 | <#if (symbolProblem.getContainingClass())?? > 30 | 32 | <#assign jarsInProblem = jarsInProblem 33 | + { symbolProblem.getContainingClass().getClassPathEntry().toString() : symbolProblem.getContainingClass().getClassPathEntry() } > 34 | 35 |

${symbolProblem?html}, referenced from ${ 36 | pluralize(sourceClasses?size, "class", "classes")?html} 37 | 40 |

41 | 42 | 43 | 48 | 49 | <#list jarsInProblem?values as jarInProblem> 50 | <@showDependencyPath dependencyPathRootCauses classPathResult jarInProblem /> 51 | 52 | <@showDependencyPath dependencyPathRootCauses classPathResult classPathEntry /> 53 | 54 | 55 | 56 | <#macro showDependencyPath dependencyPathRootCauses classPathResult classPathEntry> 57 | <#assign dependencyPaths = classPathResult.getDependencyPaths(classPathEntry) /> 58 |

59 | The following ${plural(dependencyPaths?size, "path contains", "paths contain")} ${classPathEntry?html}: 60 |

61 | 62 | <#if dependencyPathRootCauses[classPathEntry]?? > 63 |

${dependencyPathRootCauses[classPathEntry]?html} 64 |

65 | <#else> 66 |
    67 | <#list dependencyPaths as dependencyPath > 68 |
  • ${dependencyPath}
  • 69 | 70 |
71 | 72 | 73 | 74 | <#macro formatDependencyGraph graph node parent> 75 | <#if node == graph.getRootPath() > 76 | <#assign label = 'root' /> 77 | <#else> 78 | <#assign label = 'parent: ' + parent.getLeaf() /> 79 | 80 |

${node.getLeaf()}

81 |
    82 | <#list graph.getChildren(node) as childNode> 83 | <#if node != childNode> 84 |
  • 85 | <@formatDependencyGraph graph childNode node /> 86 |
  • 87 | 88 | 89 |
90 | 91 | 92 | <#macro testResult row name> 93 | <#if row.getResult(name)?? ><#-- checking isNotNull() --> 94 | <#-- When it's not null, the test ran. It's either PASS or FAIL --> 95 | <#assign test_label = row.getResult(name)?then('PASS', 'FAIL')> 96 | <#assign failure_count = row.getFailureCount(name)> 97 | <#else> 98 | <#-- Null means there's an exception and test couldn't run --> 99 | <#assign test_label = "UNAVAILABLE"> 100 | 101 | 102 | <#if row.getResult(name)?? > 103 | <#assign page_anchor = name?replace(" ", "-")?lower_case /> 104 | 105 | <#if failure_count gt 0>${pluralize(failure_count, "FAILURE", "FAILURES")} 106 | <#else>PASS 107 | 108 | 109 | <#else>UNAVAILABLE 110 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /dashboard/src/test/java/com/google/cloud/tools/opensource/cloudbomdashboard/ArtifactMavenTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Google LLC. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.cloud.tools.opensource.cloudbomdashboard; 18 | 19 | import static com.google.cloud.tools.opensource.cloudbomdashboard.ArtifactMavenData.isReachable; 20 | import static com.google.cloud.tools.opensource.cloudbomdashboard.ArtifactMavenData.sharedDependencyPositionAndVersion; 21 | import static com.google.common.truth.Truth.assertThat; 22 | 23 | import java.io.IOException; 24 | import java.net.URL; 25 | import org.eclipse.aether.artifact.DefaultArtifact; 26 | import org.junit.Test; 27 | 28 | public class ArtifactMavenTest { 29 | @Test 30 | public void testSharedDependencies() { 31 | DefaultArtifact artifact = 32 | new DefaultArtifact("com.google.cloud:google-cloud-storage-control:2.37.0-alpha"); 33 | String groupPath = artifact.getGroupId().replace('.', '/'); 34 | String pomUrl = 35 | DashboardMain.basePath 36 | + "/" 37 | + groupPath 38 | + "/" 39 | + artifact.getArtifactId() 40 | + "/" 41 | + artifact.getVersion() 42 | + "/" 43 | + artifact.getArtifactId() 44 | + "-" 45 | + artifact.getVersion() 46 | + ".pom"; 47 | ArtifactMavenData.SharedDependenciesData sharedDependenciesData = 48 | sharedDependencyPositionAndVersion(pomUrl, artifact); 49 | assertThat(sharedDependenciesData.getSharedDependencyPosition()).isEqualTo(pomUrl); 50 | assertThat(sharedDependenciesData.getSharedDependencyVersion()).isEqualTo("3.29.0"); 51 | } 52 | 53 | @Test 54 | public void testSharedDependencies_invalidPomUrl() { 55 | DefaultArtifact artifact = 56 | new DefaultArtifact("com.google.cloud:google-cloud-storage-control:2.37.0-alpha"); 57 | String groupPath = artifact.getGroupId().replace('.', '/'); 58 | String parentPath = 59 | DashboardMain.basePath 60 | + "/" 61 | + groupPath 62 | + "/" 63 | + artifact.getArtifactId() 64 | + "-parent" 65 | + "/" 66 | + artifact.getVersion() 67 | + "/" 68 | + artifact.getArtifactId() 69 | + "-parent-" 70 | + artifact.getVersion() 71 | + ".pom"; 72 | ArtifactMavenData.SharedDependenciesData sharedDependenciesData = 73 | sharedDependencyPositionAndVersion(parentPath, artifact); 74 | assertThat(sharedDependenciesData.getSharedDependencyPosition()).isEmpty(); 75 | assertThat(sharedDependenciesData.getSharedDependencyVersion()).isEmpty(); 76 | } 77 | 78 | @Test 79 | public void testIsReachable_validUrl() throws IOException { 80 | DefaultArtifact artifact = 81 | new DefaultArtifact("com.google.cloud:google-cloud-storage-control:2.37.0-alpha"); 82 | String groupPath = artifact.getGroupId().replace('.', '/'); 83 | String pomUrl = 84 | DashboardMain.basePath 85 | + "/" 86 | + groupPath 87 | + "/" 88 | + artifact.getArtifactId() 89 | + "/" 90 | + artifact.getVersion() 91 | + "/" 92 | + artifact.getArtifactId() 93 | + "-" 94 | + artifact.getVersion() 95 | + ".pom"; 96 | assertThat(isReachable(new URL(pomUrl))).isTrue(); 97 | } 98 | 99 | @Test 100 | public void testIsReachable_invalidUrl() throws IOException { 101 | DefaultArtifact artifact = 102 | new DefaultArtifact("com.google.cloud:google-cloud-storage-control:2.37.0-alpha"); 103 | String groupPath = artifact.getGroupId().replace('.', '/'); 104 | String parentPath = 105 | DashboardMain.basePath 106 | + "/" 107 | + groupPath 108 | + "/" 109 | + artifact.getArtifactId() 110 | + "-parent" 111 | + "/" 112 | + artifact.getVersion() 113 | + "/" 114 | + artifact.getArtifactId() 115 | + "-parent-" 116 | + artifact.getVersion() 117 | + ".pom"; 118 | assertThat(isReachable(new URL(parentPath))).isFalse(); 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /google-cloud-bom/README.md: -------------------------------------------------------------------------------- 1 | # Google Cloud BOM 2 | 3 | Google Cloud BOM (Maven artifact ID `com.google.cloud:google-cloud-bom`) lists 4 | Google Cloud Java client libraries. The Google Cloud Libraries BOM imports 5 | Google Cloud BOM. 6 | 7 | Google Cloud recommends Java users to use the Libraries BOM (Maven artifact ID 8 | `com.google.cloud:libraries-bom`), instead of Google Cloud BOM. 9 | It's because the Libraries BOM sets the consistent versions of libraries 10 | including the core Java libraries. 11 | Cloud's documentation and samples also use the Libraries BOM. 12 | -------------------------------------------------------------------------------- /java.header: -------------------------------------------------------------------------------- 1 | ^/\*$ 2 | ^ \* Copyright \d\d\d\d,? Google (Inc\.|LLC)$ 3 | ^ \*$ 4 | ^ \* Licensed under the Apache License, Version 2\.0 \(the "License"\);$ 5 | ^ \* you may not use this file except in compliance with the License\.$ 6 | ^ \* You may obtain a copy of the License at$ 7 | ^ \*$ 8 | ^ \*[ ]+https?://www.apache.org/licenses/LICENSE-2\.0$ 9 | ^ \*$ 10 | ^ \* Unless required by applicable law or agreed to in writing, software$ 11 | ^ \* distributed under the License is distributed on an "AS IS" BASIS,$ 12 | ^ \* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied\.$ 13 | ^ \* See the License for the specific language governing permissions and$ 14 | ^ \* limitations under the License\.$ 15 | ^ \*/$ 16 | -------------------------------------------------------------------------------- /libraries-bom-protobuf3/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | com.google.cloud 5 | libraries-bom-protobuf3 6 | 26.62.0-SNAPSHOT 7 | pom 8 | 9 | 10 | com.google.cloud 11 | libraries-bom 12 | 26.62.0-SNAPSHOT 13 | ../libraries-bom 14 | 15 | 16 | Google Cloud Platform Supported Libraries (Protobuf3 compatible) 17 | 18 | A compatible set of Google Cloud open source libraries. This BOM is compatible with protobuf-java 3.x versions. 19 | Document: https://cloud.google.com/java/docs/bom 20 | 21 | 2024 22 | 23 | 24 | 25 | 26 | com.google.protobuf 27 | protobuf-bom 28 | 3.25.5 29 | pom 30 | import 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /libraries-bom-table-generation/updateREADMETable.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import xml.etree.ElementTree as ET 3 | import yaml 4 | import re 5 | 6 | def run_maven_flatten(): 7 | subprocess.run(['mvn', 'flatten:flatten']) 8 | 9 | def run_maven_flatten_clean(): 10 | subprocess.run(['mvn', 'flatten:clean']) 11 | 12 | run_maven_flatten() 13 | # Load the flattened pom.xml file 14 | pom_file = "libraries-bom/.flattened-pom.xml" 15 | namespaces = { 16 | "m": "http://maven.apache.org/POM/4.0.0" 17 | } 18 | tree = ET.parse(pom_file) 19 | root = tree.getroot() 20 | 21 | # Load the metadata 22 | with open('libraries-bom-table-generation/javaModulesMetadata.yaml', 'r') as metadata_file: 23 | metadata = yaml.safe_load(metadata_file) 24 | 25 | # Manual list of runtime modules 26 | runtime_modules = ['google-http-client', 27 | 'gax', 28 | 'api-common', 29 | 'google-cloud-core', 30 | 'google-iam-policy' 31 | 'google-auth-library', 32 | ] 33 | 34 | # List of modules to ignore for table creation 35 | modules_to_skip = ['libraries-bom', 36 | 'gapic-libraries-bom', 37 | 'github-repo', 38 | 'gax-httpjson', 39 | 'google-cloud-shared-dependencies', 40 | 'first-party-dependencies', 41 | 'full-convergence-check', 42 | 'gapic-generator-java', 43 | 'java-cloud-bom-tests', 44 | 'gax-grpc', 45 | 'grpc-google-', 46 | 'proto-google-', 47 | 'google-cloud-bom', 48 | 'google-cloud-java', 49 | 'google-java-format', 50 | 'google-api-client', 51 | 'google-http-client-', 52 | 'grpc-', 53 | 'protobuf-', 54 | 'guava', 55 | 'protoc', 56 | 'gson', 57 | 'google-oauth', 58 | 'google-auth-library-oauth2-http', 59 | 'google-auth-library-appengine', 60 | 'google-cloud-bigtable-emulator', 61 | 'auto-value-annotations', 62 | 'gapic-google-cloud-storage-v2', 63 | 'google-cloud-core-grpc', 64 | 'google-cloud-core-http', 65 | 'google-cloud-firestore-admin', 66 | 'google-cloud-spanner-executor', 67 | 'google-cloud-bigtable-stats' #exclude per https://github.com/googleapis/java-bigtable/blob/v2.32.0/pom.xml#L334 68 | ] 69 | regex_modules_to_skip = "(" + ")|(".join(modules_to_skip) + ")" 70 | 71 | # Prepare the dependencies list 72 | dependencies = [] 73 | 74 | # Iterate over the dependencies in the flattened pom.xml 75 | for dependency in root.findall(".//m:dependencies/m:dependency", namespaces): 76 | artifactId = dependency.find("m:artifactId", namespaces) 77 | version = dependency.find("m:version", namespaces) 78 | # If the dependency is in the list of modules to skip, continue to next iteration 79 | if re.match(regex_modules_to_skip, artifactId.text): 80 | continue 81 | # Generate a unique key for each dependency using artifactId and version 82 | dependency_key = (artifactId.text, version.text) 83 | # Check if the dependency is already encountered 84 | if dependency_key not in dependencies: 85 | # Add the dependency to the list 86 | dependencies.append(dependency_key) 87 | 88 | # Alphabetize the output list by the 'artifact' key 89 | dependencies.sort(key=lambda dep: dep[0]) 90 | 91 | # Generate Markdown table 92 | table = "| Artifact ID | Library Type | Google Cloud Library Reference | Google Cloud Product Reference | \n" 93 | table += "| --------- | ------------ | ------------ | ------------ |\n" 94 | 95 | # Iterate over the sorted dependencies and append the rows to the markdown table 96 | for artifact_id, version in dependencies: 97 | # Use aggregated artifact_id for google-auth-library 98 | if artifact_id == 'google-auth-library-credentials': 99 | artifact_id = 'google-auth-library' 100 | 101 | if artifact_id in runtime_modules: 102 | library_type = "Runtime" 103 | else: 104 | library_type = "Product" 105 | 106 | # Get name_pretty and product reference link from javaModulesMetadata.yaml 107 | metadata_value = metadata.get(artifact_id) 108 | if metadata_value is not None: 109 | product_reference_link = metadata_value.split(",")[0].strip() 110 | name_pretty = metadata_value.split(",")[1].strip() 111 | else: 112 | name_pretty = "N/A" 113 | product_reference_link = "N/A" 114 | 115 | # Convert reference links to hyperlinks 116 | library_reference_link = f"https://cloud.google.com/java/docs/reference/{artifact_id}/latest/overview" 117 | library_reference_hyperlink = f"[{version}]({library_reference_link})" 118 | product_reference_hyperlink = f"[{name_pretty}]({product_reference_link})" if product_reference_link != 'N/A' else 'N/A' 119 | 120 | # Append the dependency to the table 121 | table += f"| {artifact_id} | {library_type} | {library_reference_hyperlink} | {product_reference_hyperlink} |\n" 122 | 123 | with open('README.md', 'r') as readme_file: 124 | readme = readme_file.read() 125 | 126 | # Update existing table in README.md 127 | table_start_comment = "" 128 | table_end_comment = "" 129 | table_pattern = re.compile(r'(?s).*?') 130 | updated_readme = table_pattern.sub(table_start_comment + "\n" + table + table_end_comment, readme) 131 | 132 | with open('README.md', 'w') as readme_file: 133 | readme_file.write(updated_readme) 134 | run_maven_flatten_clean() -------------------------------------------------------------------------------- /libraries-bom/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## [26.4.0](https://github.com/googleapis/java-cloud-bom/compare/libraries-bom-v26.3.0...libraries-bom-v26.4.0) (2023-01-17) 4 | 5 | 6 | ### Dependencies 7 | 8 | * update dependency com.google.cloud:first-party-dependencies to v3.1.1 ([a6b8962](https://github.com/googleapis/java-cloud-bom/commit/a6b8962a5c9c185f35072a6710ef53fff746fc0b)) 9 | * The following workspace dependencies were updated 10 | * com.google.cloud:google-cloud-bom bumped to 0.185.0 11 | 12 | ## [26.3.0](https://github.com/googleapis/java-cloud-bom/compare/libraries-bom-v26.2.0...libraries-bom-v26.3.0) (2023-01-05) 13 | 14 | 15 | ### Miscellaneous Chores 16 | 17 | * Release as version 26.3.0 ([#5709](https://github.com/googleapis/java-cloud-bom/issues/5709)) ([01ddc8a](https://github.com/googleapis/java-cloud-bom/commit/01ddc8a72f1741316476dcaa7532265b5a71137d)) 18 | 19 | 20 | ### Dependencies 21 | 22 | * The following workspace dependencies were updated 23 | * com.google.cloud:google-cloud-bom bumped to 0.184.0 24 | 25 | ## [26.2.0](https://github.com/googleapis/java-cloud-bom/compare/libraries-bom-v26.1.5...libraries-bom-v26.2.0) (2022-12-15) 26 | 27 | 28 | ### Dependencies 29 | 30 | * update dependency com.google.cloud:first-party-dependencies to v3.1.0 ([#5665](https://github.com/googleapis/java-cloud-bom/issues/5665)) ([91bb1f7](https://github.com/googleapis/java-cloud-bom/commit/91bb1f7586e0ab473a92fc16add24c39df0df0a3)) 31 | * The following workspace dependencies were updated 32 | * com.google.cloud:google-cloud-bom bumped to 0.183.0 33 | 34 | ## [26.1.5](https://github.com/googleapis/java-cloud-bom/compare/libraries-bom-v26.1.4...libraries-bom-v26.1.5) (2022-11-18) 35 | 36 | 37 | ### Dependencies 38 | 39 | * update dependency com.google.cloud:first-party-dependencies to v3.0.6 ([#5612](https://github.com/googleapis/java-cloud-bom/issues/5612)) ([756a606](https://github.com/googleapis/java-cloud-bom/commit/756a606dfebe3a0d6be3e49b002a86931c7ea211)) 40 | * The following workspace dependencies were updated 41 | * com.google.cloud:google-cloud-bom bumped to 0.182.0 42 | 43 | ## [26.1.4](https://github.com/googleapis/java-cloud-bom/compare/libraries-bom-v26.1.4-SNAPSHOT...libraries-bom-v26.1.4) (2022-10-31) 44 | 45 | 46 | ### Dependencies 47 | 48 | * update dependency com.google.cloud:first-party-dependencies to v3.0.4 ([#5289](https://github.com/googleapis/java-cloud-bom/issues/5289)) ([60cd80b](https://github.com/googleapis/java-cloud-bom/commit/60cd80b57992c7310e5ac3ff6cad2a25a8065788)) 49 | * update dependency com.google.cloud:first-party-dependencies to v3.0.5 ([#5565](https://github.com/googleapis/java-cloud-bom/issues/5565)) ([4d5ce23](https://github.com/googleapis/java-cloud-bom/commit/4d5ce2347695535e839466871576af5b0f124c9e)) 50 | * use first-party-dependencies in libraries-bom ([#5125](https://github.com/googleapis/java-cloud-bom/issues/5125)) ([b1d1576](https://github.com/googleapis/java-cloud-bom/commit/b1d15763a9364f761d1e03f92feb87033c0cbba0)) 51 | * The following workspace dependencies were updated 52 | * com.google.cloud:google-cloud-bom bumped to 0.181.0 53 | 54 | ## [26.1.3](https://github.com/googleapis/java-cloud-bom/compare/libraries-bom-v26.1.2...libraries-bom-v26.1.3) (2022-10-06) 55 | 56 | 57 | ### Dependencies 58 | 59 | * update dependency com.google.cloud:first-party-dependencies to v3.0.4 ([#5289](https://github.com/googleapis/java-cloud-bom/issues/5289)) ([60cd80b](https://github.com/googleapis/java-cloud-bom/commit/60cd80b57992c7310e5ac3ff6cad2a25a8065788)) 60 | * The following workspace dependencies were updated 61 | * com.google.cloud:google-cloud-bom bumped to 0.180.0 62 | 63 | ## [26.1.2](https://github.com/googleapis/java-cloud-bom/compare/libraries-bom-v26.1.1...libraries-bom-v26.1.2) (2022-09-19) 64 | 65 | 66 | ### Dependencies 67 | 68 | * use first-party-dependencies in libraries-bom ([#5125](https://github.com/googleapis/java-cloud-bom/issues/5125)) ([b1d1576](https://github.com/googleapis/java-cloud-bom/commit/b1d15763a9364f761d1e03f92feb87033c0cbba0)) 69 | * The following workspace dependencies were updated 70 | * com.google.cloud:google-cloud-bom bumped to 0.179.0 71 | 72 | ## [26.1.1](https://github.com/googleapis/java-cloud-bom/compare/libraries-bom-v26.1.0...libraries-bom-v26.1.1) (2022-08-30) 73 | 74 | 75 | ### Bug Fixes 76 | 77 | * touching libraries-bom/pom.xml ([#4964](https://github.com/googleapis/java-cloud-bom/issues/4964)) ([0ee7be1](https://github.com/googleapis/java-cloud-bom/commit/0ee7be1fd563b822737fbe0992e0412a81042dea)) 78 | 79 | 80 | ### Dependencies 81 | 82 | * The following workspace dependencies were updated 83 | * com.google.cloud:google-cloud-bom bumped to 0.178.0 84 | 85 | ## [26.1.0](https://github.com/googleapis/java-cloud-bom/compare/libraries-bom-v26.0.0...libraries-bom-v26.1.0) (2022-08-12) 86 | 87 | 88 | ### Features 89 | 90 | * Verifying that tests module do not get picked up release please ([#4783](https://github.com/googleapis/java-cloud-bom/issues/4783)) ([e037c08](https://github.com/googleapis/java-cloud-bom/commit/e037c08a4e2cafcebba9f1590d10d0c3b0a8dce1)) 91 | 92 | 93 | ### Dependencies 94 | 95 | * java-shared-dependencies 3.0.1 and using gax-bom ([#4893](https://github.com/googleapis/java-cloud-bom/issues/4893)) ([cf848b5](https://github.com/googleapis/java-cloud-bom/commit/cf848b5986f1513087cce90ee2b36bee455a05c5)) 96 | * The following workspace dependencies were updated 97 | * com.google.cloud:google-cloud-bom bumped to 0.177.0 98 | 99 | ## [26.0.0](https://github.com/googleapis/java-cloud-bom/compare/libraries-bom-v25.4.0...libraries-bom-v26.0.0) (2022-07-07) 100 | 101 | 102 | ### ⚠ BREAKING CHANGES 103 | 104 | * preparing for next release (#4691) 105 | 106 | ### Features 107 | 108 | * preparing for next release ([#4691](https://github.com/googleapis/java-cloud-bom/issues/4691)) ([c07cf23](https://github.com/googleapis/java-cloud-bom/commit/c07cf2354c0799e4da7f3a75e4034f1141ad2056)) 109 | 110 | 111 | ### Dependencies 112 | 113 | * shared dependencies BOM 2.13.0 ([#4689](https://github.com/googleapis/java-cloud-bom/issues/4689)) ([2cf36b6](https://github.com/googleapis/java-cloud-bom/commit/2cf36b694547800df497be55351ba8f12278933c)) 114 | * The following workspace dependencies were updated 115 | * com.google.cloud:google-cloud-bom bumped to 0.176.0 116 | 117 | ## [25.4.0](https://github.com/googleapis/java-cloud-bom/compare/libraries-bom-v25.3.0...libraries-bom-v25.4.0) (2022-06-02) 118 | 119 | 120 | ### Features 121 | 122 | * moving libraries-bom to this repository ([#4308](https://github.com/googleapis/java-cloud-bom/issues/4308)) ([db2ecb0](https://github.com/googleapis/java-cloud-bom/commit/db2ecb04508571ed7f913705aab5069ddf867ebe)) 123 | 124 | 125 | ### Dependencies 126 | 127 | * update dependency com.google.api:api-common to v2.2.0 ([#4314](https://github.com/googleapis/java-cloud-bom/issues/4314)) ([6c231e2](https://github.com/googleapis/java-cloud-bom/commit/6c231e2e11db012fb172a0fe0a3c421bdd502be8)) 128 | * update dependency com.google.api:gax-httpjson to v0.103.1 ([#4315](https://github.com/googleapis/java-cloud-bom/issues/4315)) ([81a3c8d](https://github.com/googleapis/java-cloud-bom/commit/81a3c8dd5f224c879313cc84f2e94e104b0c510d)) 129 | * update dependency com.google.auth:google-auth-library-bom to v1.7.0 ([#4316](https://github.com/googleapis/java-cloud-bom/issues/4316)) ([6476251](https://github.com/googleapis/java-cloud-bom/commit/6476251ce1ffffc49015b51675851de5b81e86b8)) 130 | * update dependency com.google.cloud:google-cloud-core-bom to v2.7.1 ([#4317](https://github.com/googleapis/java-cloud-bom/issues/4317)) ([e898014](https://github.com/googleapis/java-cloud-bom/commit/e898014aa533d68a826482c94d3b7df91ef4fef5)) 131 | * update dependency com.google.protobuf:protobuf-bom to v3.20.1 ([#4318](https://github.com/googleapis/java-cloud-bom/issues/4318)) ([25396ad](https://github.com/googleapis/java-cloud-bom/commit/25396ad6e0efbc4a3e5bed2302b4f20afa1493ad)) 132 | * update dependency com.google.protobuf:protobuf-bom to v3.21.0 ([#4439](https://github.com/googleapis/java-cloud-bom/issues/4439)) ([88da12a](https://github.com/googleapis/java-cloud-bom/commit/88da12a9957497bbfa541773574a98a87f7f4425)) 133 | * update gax.version to v2.18.1 ([#4319](https://github.com/googleapis/java-cloud-bom/issues/4319)) ([67b8b58](https://github.com/googleapis/java-cloud-bom/commit/67b8b58159b86e1929c45bfc63dfa09f34e18146)) 134 | * update http.version to v1.41.8 ([#4312](https://github.com/googleapis/java-cloud-bom/issues/4312)) ([6ab6a1f](https://github.com/googleapis/java-cloud-bom/commit/6ab6a1fdb60bc0b3d160352a4ad095ccfe7d8034)) 135 | * update iam.protos.version to v1.3.4 ([#4313](https://github.com/googleapis/java-cloud-bom/issues/4313)) ([a719aa0](https://github.com/googleapis/java-cloud-bom/commit/a719aa00a566549fa0f6e298347e1aa3442dc673)) 136 | * update iam.protos.version to v1.4.0 ([#4385](https://github.com/googleapis/java-cloud-bom/issues/4385)) ([fe1f7ad](https://github.com/googleapis/java-cloud-bom/commit/fe1f7ad0cb338ca27f6adc46f62c45bebf12d6b5)) 137 | * update io.grpc.version to v1.46.0 ([#4320](https://github.com/googleapis/java-cloud-bom/issues/4320)) ([ffaba52](https://github.com/googleapis/java-cloud-bom/commit/ffaba5213aa91ef8e384c6d3e5b4b554819b7b38)) 138 | * use first party dependenceis in shared deps 2.12.0 ([#4448](https://github.com/googleapis/java-cloud-bom/issues/4448)) ([196198c](https://github.com/googleapis/java-cloud-bom/commit/196198c62a720ff364e0b547c2f7a73783d884e5)) 139 | * The following workspace dependencies were updated 140 | * com.google.cloud:google-cloud-bom bumped to 0.175.0 141 | -------------------------------------------------------------------------------- /libraries-bom/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | com.google.cloud 6 | libraries-bom 7 | 26.62.0-SNAPSHOT 8 | pom 9 | 10 | Google Cloud Platform Supported Libraries 11 | 12 | A compatible set of Google Cloud open source libraries. 13 | Document: https://cloud.google.com/java/docs/bom 14 | 15 | https://cloud.google.com/java/docs/bom 16 | 17 | Google LLC 18 | https://cloud.google.com 19 | 20 | 2019 21 | 22 | 23 | Cloud Java team 24 | 25 | 26 | 27 | 28 | https://github.com/googleapis/java-cloud-bom/issues 29 | 30 | 31 | scm:git:git@github.com:googleapis/java-cloud-bom.git 32 | scm:git:git@github.com:googleapis/java-cloud-bom.git 33 | 34 | https://github.com/googleapis/java-cloud-bom 35 | HEAD 36 | 37 | 38 | 39 | 40 | The Apache License, Version 2.0 41 | https://raw.githubusercontent.com/googleapis/google-cloud-java/main/LICENSE 42 | 43 | 44 | 45 | 46 | UTF-8 47 | 48 | 49 | 50 | 51 | sonatype-nexus-snapshots 52 | https://google.oss.sonatype.org/content/repositories/snapshots 53 | 54 | 55 | sonatype-nexus-staging 56 | https://google.oss.sonatype.org/service/local/staging/deploy/maven2/ 57 | 58 | 59 | 60 | 61 | 62 | 65 | 66 | com.google.protobuf 67 | protobuf-bom 68 | 4.29.4 69 | pom 70 | import 71 | 72 | 73 | 76 | 77 | com.google.cloud 78 | first-party-dependencies 79 | 3.48.0 80 | pom 81 | import 82 | 83 | 84 | 85 | 86 | com.google.cloud 87 | google-cloud-bom 88 | 0.243.0-SNAPSHOT 89 | pom 90 | import 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | org.sonatype.plugins 100 | nexus-staging-maven-plugin 101 | 1.7.0 102 | true 103 | 104 | sonatype-nexus-staging 105 | https://google.oss.sonatype.org/ 106 | false 107 | 108 | 109 | 110 | 111 | 112 | 113 | org.codehaus.mojo 114 | flatten-maven-plugin 115 | 116 | 117 | expand 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 127 | release-sonatype 128 | 129 | 130 | 133 | !artifact-registry-url 134 | 135 | 136 | 137 | 138 | 139 | org.sonatype.plugins 140 | nexus-staging-maven-plugin 141 | 142 | 143 | 144 | 145 | 146 | release 147 | 148 | 149 | performRelease 150 | 151 | 152 | 153 | 154 | 155 | org.apache.maven.plugins 156 | maven-gpg-plugin 157 | 3.2.7 158 | 159 | 160 | sign-artifacts 161 | verify 162 | 163 | sign 164 | 165 | 166 | 167 | --pinentry-mode 168 | loopback 169 | 170 | 171 | 172 | 173 | 174 | 175 | org.apache.maven.plugins 176 | maven-source-plugin 177 | 3.3.1 178 | 179 | 180 | attach-sources 181 | 182 | jar-no-fork 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | -------------------------------------------------------------------------------- /libraries-release-data/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | java-cloud-bom-root 8 | com.google.cloud 9 | 0.1.0 10 | 11 | libraries-release-data 12 | 13 | 14 | com.google.cloud.tools 15 | dependencies 16 | 1.5.13 17 | compile 18 | 19 | 20 | 21 | 22 | UTF-8 23 | 1.8 24 | 1.8 25 | 26 | 27 | 28 | 29 | 30 | org.codehaus.mojo 31 | exec-maven-plugin 32 | 33 | false 34 | com.google.cloud.dashboard.GenerateLibrariesList 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /libraries-release-data/src/main/java/com/google/cloud/dashboard/GenerateLibrariesList.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Google LLC. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.cloud.dashboard; 18 | 19 | import com.google.cloud.tools.opensource.dependencies.Bom; 20 | import com.google.cloud.tools.opensource.dependencies.MavenRepositoryException; 21 | import java.nio.file.Path; 22 | import java.nio.file.Paths; 23 | import java.util.ArrayList; 24 | import java.util.List; 25 | import org.eclipse.aether.artifact.Artifact; 26 | 27 | /** Class to generate a list of all libraries included in the libraries-bom */ 28 | public class GenerateLibrariesList { 29 | 30 | public static void main(String[] argument) throws MavenRepositoryException { 31 | 32 | Path bomPath = Paths.get("..", "libraries-bom", "pom.xml").toAbsolutePath(); 33 | Bom bom = Bom.readBom(bomPath); 34 | List artifacts = bom.getManagedDependencies(); 35 | List artifactList = new ArrayList<>(); 36 | 37 | for (Artifact art : artifacts) { 38 | artifactList.add(art.getGroupId() + ":" + art.getArtifactId()); 39 | } 40 | 41 | System.out.println(artifactList); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /license-checks.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | com.google.cloud 5 | java-cloud-bom-root 6 | pom 7 | 8 | 0.1.0 9 | Google Cloud Java BOM root project 10 | https://github.com/googleapis/java-cloud-bom 11 | 12 | BOMs for Google Cloud Java SDK 13 | 14 | 15 | Google 16 | 17 | 18 | scm:git:git@github.com:googleapis/java-cloud-bom.git 19 | scm:git:git@github.com:googleapis/java-cloud-bom-java.git 20 | https://github.com/googleapis/java-cloud-bom 21 | HEAD 22 | 23 | 24 | 25 | Google Cloud Software License 26 | https://raw.githubusercontent.com/googleapis/google-cloud-java/main/LICENSE 27 | 28 | 29 | 30 | 31 | google-cloud-bom 32 | libraries-bom 33 | libraries-bom-protobuf3 34 | 35 | 36 | 37 | 38 | 39 | 42 | maven-deploy-plugin 43 | 3.1.3 44 | 45 | true 46 | 47 | 48 | 60 | 61 | 62 | 63 | 64 | 65 | release-staging-repository 66 | 67 | 68 | sonatype-nexus-snapshots 69 | https://google.oss.sonatype.org/content/repositories/snapshots 70 | 71 | 72 | sonatype-nexus-staging 73 | https://google.oss.sonatype.org/service/local/staging/deploy/maven2/ 74 | 75 | 76 | 77 | 78 | 79 | 80 | org.sonatype.plugins 81 | nexus-staging-maven-plugin 82 | 1.7.0 83 | true 84 | 85 | sonatype-nexus-staging 86 | https://google.oss.sonatype.org/ 87 | false 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /release-note-generation/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | java-cloud-bom-root 8 | com.google.cloud 9 | 0.1.0 10 | 11 | 4.0.0 12 | 13 | release-note-generation 14 | 15 | Release Note Generation for Cloud SDK for Java 16 | 17 | 18 | UTF-8 19 | 11 20 | 11 21 | 22 | 23 | 24 | 25 | com.google.cloud.tools 26 | dependencies 27 | 1.5.13 28 | 29 | 30 | junit 31 | junit 32 | 4.13.1 33 | test 34 | 35 | 36 | com.google.truth 37 | truth 38 | 1.4.4 39 | test 40 | 41 | 42 | 43 | 44 | 45 | 46 | org.codehaus.mojo 47 | exec-maven-plugin 48 | 49 | false 50 | com.google.cloud.ReleaseNoteGeneration 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /release-note-generation/src/test/java/com/google/cloud/ReleaseNoteGenerationTest.java: -------------------------------------------------------------------------------- 1 | package com.google.cloud; 2 | 3 | import static org.junit.Assert.assertFalse; 4 | import static org.junit.Assert.assertTrue; 5 | 6 | import com.google.cloud.tools.opensource.dependencies.Bom; 7 | import com.google.common.collect.ImmutableList; 8 | import com.google.common.collect.ImmutableMap; 9 | import com.google.common.truth.Truth; 10 | import org.junit.Test; 11 | 12 | public class ReleaseNoteGenerationTest { 13 | // Uses the released BOM, not the one in this repository, to avoid unnecessarily updating the 14 | // assertions. 15 | static final String LIBRARIES_BOM_COORDINATES = "com.google.cloud:libraries-bom:26.1.5"; 16 | 17 | @Test 18 | public void testPreviousBom() throws Exception { 19 | Bom bom = Bom.readBom(LIBRARIES_BOM_COORDINATES); 20 | Bom previousBom = ReleaseNoteGeneration.previousBom(bom); 21 | Truth.assertThat(previousBom.getCoordinates()) 22 | .isEqualTo("com.google.cloud:libraries-bom:pom:26.1.4"); 23 | } 24 | 25 | @Test 26 | public void testCreateVersionLessCoordinatesToKey() throws Exception { 27 | Bom bom = Bom.readBom(LIBRARIES_BOM_COORDINATES); 28 | ImmutableMap versionLessCoordinatesToKey = 29 | ReleaseNoteGeneration.createVersionLessCoordinatesToKey(bom); 30 | 31 | // google-cloud-apigee-registry represents the libraries from google-cloud-java 32 | // google-cloud-bigtable represents the libraries from handwritten repositories 33 | Truth.assertThat(versionLessCoordinatesToKey) 34 | .containsAtLeast( 35 | "com.google.cloud:google-cloud-apigee-registry", "0.6.0", 36 | "com.google.cloud:google-cloud-bigtable", "2.16.0"); 37 | } 38 | 39 | @Test 40 | public void testIsMajorVersionBump() { 41 | assertTrue(ReleaseNoteGeneration.isMajorVersionBump("1.2.3", "2.0.1")); 42 | assertFalse(ReleaseNoteGeneration.isMajorVersionBump("2.2.3", "2.3.1")); 43 | } 44 | 45 | @Test 46 | public void testIsMinorVersionBump() { 47 | assertTrue(ReleaseNoteGeneration.isMinorVersionBump("1.2.3", "1.3.0")); 48 | assertFalse(ReleaseNoteGeneration.isMinorVersionBump("1.2.3", "1.2.5")); 49 | assertFalse(ReleaseNoteGeneration.isMinorVersionBump("1.2.3", "2.2.3")); 50 | } 51 | 52 | @Test 53 | public void testIsPatchVersionBump() { 54 | assertTrue(ReleaseNoteGeneration.isPatchVersionBump("1.2.3", "1.2.5")); 55 | assertFalse(ReleaseNoteGeneration.isPatchVersionBump("1.2.3", "1.2.3")); 56 | assertFalse(ReleaseNoteGeneration.isPatchVersionBump("1.2.3", "2.2.3")); 57 | assertFalse(ReleaseNoteGeneration.isPatchVersionBump("1.2.3", "1.3.3")); 58 | } 59 | 60 | @Test 61 | public void testPrintClientLibraryVersionDifference() throws Exception { 62 | ReleaseNoteGeneration generation = new ReleaseNoteGeneration(); 63 | generation.reportClientLibraryVersionDifference( 64 | ImmutableList.of( 65 | "com.google.cloud:google-cloud-redis", "com.google.cloud:google-cloud-logging"), 66 | ImmutableMap.of( 67 | "com.google.cloud:google-cloud-redis", 68 | "2.8.0", 69 | "com.google.cloud:google-cloud-logging", 70 | "3.12.0"), 71 | ImmutableMap.of( 72 | "com.google.cloud:google-cloud-redis", 73 | "2.9.0", 74 | "com.google.cloud:google-cloud-logging", 75 | "3.13.1"), 76 | "1.1.0"); 77 | 78 | String report = generation.report.toString(); 79 | Truth.assertThat(report) 80 | .contains( 81 | "- google-cloud-redis:2.9.0 (prev:2.8.0; Release Notes: " 82 | + "[v2.9.0](https://github.com/googleapis/google-cloud-java/releases/tag/v1.1.0))"); 83 | Truth.assertThat(report) 84 | .contains( 85 | "- google-cloud-logging:3.13.1 (prev:3.12.0; Release Notes: " 86 | + "[v3.12.1](https://github.com/googleapis/java-logging/releases/tag/v3.12.1), " 87 | + "[v3.13.0](https://github.com/googleapis/java-logging/releases/tag/v3.13.0), " 88 | + "[v3.13.1](https://github.com/googleapis/java-logging/releases/tag/v3.13.1))"); 89 | } 90 | 91 | @Test 92 | public void testReportClientLibrariesNotableChangeLogs() throws Exception {} 93 | 94 | @Test 95 | public void testFetchClientLibraryNotableChangeLog() throws Exception { 96 | String notableChangelog = 97 | ReleaseNoteGeneration.fetchClientLibraryNotableChangeLog( 98 | "java-storage", ImmutableList.of("2.16.0", "2.15.1")); 99 | 100 | // A new feature in 2.16.0 101 | Truth.assertThat(notableChangelog) 102 | .contains("- Added a new retention_duration field of Duration type"); 103 | 104 | // A bug fix in 2.15.1 105 | Truth.assertThat(notableChangelog).contains("- Disable REGAPIC transport in storage v2"); 106 | 107 | // A dependency update in 2.16.0. A dependency update is not notable. 108 | Truth.assertThat(notableChangelog).doesNotContain("native-maven-plugin"); 109 | 110 | Truth.assertThat(notableChangelog).doesNotContainMatch("^$"); 111 | } 112 | 113 | @Test 114 | public void testFilterOnlyRelevantChangelog_splitRepo() throws Exception { 115 | String rawChangelog = 116 | "### Features\n" 117 | + "\n" 118 | + "* Add {Compose,Rewrite,StartResumableWrite}Request.object_checksums and" 119 | + " Bucket.RetentionPolicy.retention_duration" 120 | + " ([#1790](https://github.com/googleapis/java-storage/issues/1790))" 121 | + " ([31c1b18](https://github.com/googleapis/java-storage/commit/31c1b18acc3c118e39eb613a82ee292f3e246b8f))\n" 122 | + "* Added a new retention_duration field of Duration type" 123 | + " ([31c1b18](https://github.com/googleapis/java-storage/commit/31c1b18acc3c118e39eb613a82ee292f3e246b8f))\n" 124 | + "* Next release from main branch is 1.122.0\n" 125 | + "\n" 126 | + "\n" 127 | + "### Bug Fixes\n" 128 | + "\n" 129 | + "* Removed WriteObject routing annotations" 130 | + " ([31c1b18](https://github.com/googleapis/java-storage/commit/31c1b18acc3c118e39eb613a82ee292f3e246b8f))\n" 131 | + "* Disable REGAPIC transport in storage v2\n" 132 | + "* **deps:** update dependency com.google.apis:google-api-services-dns to" 133 | + " v1-rev20221110-2.0.0\n" 134 | + "\n" 135 | + "\n" 136 | + "### Documentation"; 137 | String notableChangelog = ReleaseNoteGeneration.filterOnlyRelevantChangelog(rawChangelog); 138 | // A new feature in 2.16.0 139 | Truth.assertThat(notableChangelog) 140 | .contains("- Added a new retention_duration field of Duration type"); 141 | 142 | // A bug fix in 2.15.1 143 | Truth.assertThat(notableChangelog).contains("- Disable REGAPIC transport in storage v2"); 144 | 145 | // A dependency update in 2.16.0. A dependency update is not notable. 146 | Truth.assertThat(notableChangelog).doesNotContain("native-maven-plugin"); 147 | 148 | // The forced minor version upgrade is irrelevant to customer 149 | Truth.assertThat(notableChangelog).doesNotContain("1.122.0"); 150 | 151 | Truth.assertThat(notableChangelog).doesNotContainMatch("^$"); 152 | // The list item is replaced with "- " 153 | Truth.assertThat(notableChangelog).doesNotContainMatch("^\\* "); 154 | 155 | // Dependency changes, even if it's noted in bug fixes section, shouldn't appear here. 156 | Truth.assertThat(notableChangelog).doesNotContainMatch("deps:"); 157 | } 158 | 159 | @Test 160 | public void testFetchReleaseNote() throws Exception { 161 | String storageReleaseNote2_16_0 = 162 | ReleaseNoteGeneration.fetchReleaseNote("googleapis", "java-storage", "v2.16.0"); 163 | Truth.assertThat(storageReleaseNote2_16_0) 164 | .contains( 165 | "* Add {Compose,Rewrite,StartResumableWrite}Request.object_checksums and" 166 | + " Bucket.RetentionPolicy.retention_duration" 167 | + " ([#1790](https://github.com/googleapis/java-storage/issues/1790)) " 168 | + "([31c1b18](https://github.com/googleapis/java-storage/commit/31c1b18acc3c118e39eb613a82ee292f3e246b8f))"); 169 | } 170 | } 171 | -------------------------------------------------------------------------------- /release-please-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "release-type": "java-yoshi", 3 | "versioning": "always-bump-minor", 4 | "separate-pull-requests": false, 5 | "include-component-in-tag": false, 6 | "packages": { 7 | ".": { 8 | "extra-files": ["README.md"] 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | ":separateMajorReleases", 4 | ":combinePatchMinorReleases", 5 | ":ignoreUnstable", 6 | ":prImmediately", 7 | ":updateNotScheduled", 8 | ":automergeDisabled", 9 | ":ignoreModulesAndTests", 10 | ":maintainLockFilesDisabled" 11 | ], 12 | "ignorePaths": [ 13 | ".kokoro/requirements.txt" 14 | ], 15 | "packageRules": [ 16 | { 17 | "versioning": "docker", 18 | "matchPackageNames": [ 19 | "/^com.google.guava:/" 20 | ] 21 | }, 22 | { 23 | "semanticCommitType": "deps", 24 | "semanticCommitScope": null, 25 | "matchPackageNames": [ 26 | "*" 27 | ] 28 | }, 29 | { 30 | "semanticCommitType": "build", 31 | "semanticCommitScope": "deps", 32 | "matchPackageNames": [ 33 | "/^org.apache.maven/", 34 | "/^org.jacoco:/", 35 | "/^org.codehaus.mojo:/", 36 | "/^org.sonatype.plugins:/", 37 | "/^com.coveo:/", 38 | "/^com.google.cloud:google-cloud-shared-config/" 39 | ] 40 | }, 41 | { 42 | "semanticCommitType": "chore", 43 | "semanticCommitScope": "deps", 44 | "matchPackageNames": [ 45 | "/^com.google.cloud:google-cloud-bom/", 46 | "/^com.google.cloud:libraries-bom/", 47 | "/^com.google.cloud.samples:shared-configuration/" 48 | ] 49 | }, 50 | { 51 | "semanticCommitType": "test", 52 | "semanticCommitScope": "deps", 53 | "matchPackageNames": [ 54 | "/^junit:junit/", 55 | "/^com.google.truth:truth/", 56 | "/^org.mockito:mockito-core/", 57 | "/^org.objenesis:objenesis/", 58 | "/^com.google.cloud:google-cloud-conformance-tests/" 59 | ] 60 | }, 61 | { 62 | "ignoreUnstable": false, 63 | "matchPackageNames": [ 64 | "/^com.google.cloud:google-cloud-/" 65 | ] 66 | }, 67 | { 68 | "groupName": "jackson dependencies", 69 | "matchPackageNames": [ 70 | "/^com.fasterxml.jackson.core/" 71 | ] 72 | }, 73 | { 74 | "enabled": false, 75 | "matchPackageNames": [ 76 | "/^com.google.protobuf:/" 77 | ] 78 | } 79 | ], 80 | "semanticCommits": "enabled", 81 | "dependencyDashboard": true 82 | } 83 | -------------------------------------------------------------------------------- /tests/dependency-convergence/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | * The following workspace dependencies were updated 4 | * com.google.cloud:google-cloud-bom bumped to 0.180.1-SNAPSHOT 5 | 6 | * The following workspace dependencies were updated 7 | * com.google.cloud:google-cloud-bom bumped to 0.181.0 8 | 9 | * The following workspace dependencies were updated 10 | * com.google.cloud:google-cloud-bom bumped to 0.181.1-SNAPSHOT 11 | 12 | * The following workspace dependencies were updated 13 | * com.google.cloud:google-cloud-bom bumped to 0.182.0 14 | 15 | * The following workspace dependencies were updated 16 | * com.google.cloud:google-cloud-bom bumped to 0.182.1-SNAPSHOT 17 | 18 | * The following workspace dependencies were updated 19 | * com.google.cloud:google-cloud-bom bumped to 0.183.0 20 | 21 | * The following workspace dependencies were updated 22 | * com.google.cloud:google-cloud-bom bumped to 0.183.1-SNAPSHOT 23 | 24 | * The following workspace dependencies were updated 25 | * com.google.cloud:google-cloud-bom bumped to 0.184.0 26 | 27 | * The following workspace dependencies were updated 28 | * com.google.cloud:google-cloud-bom bumped to 0.184.1-SNAPSHOT 29 | 30 | * The following workspace dependencies were updated 31 | * com.google.cloud:google-cloud-bom bumped to 0.185.0 32 | 33 | * The following workspace dependencies were updated 34 | * com.google.cloud:google-cloud-bom bumped to 0.185.1-SNAPSHOT 35 | 36 | ## [0.3.0](https://github.com/googleapis/java-cloud-bom/compare/tests-dependency-convergence-v0.2.0...tests-dependency-convergence-v0.3.0) (2022-09-19) 37 | 38 | 39 | ### ⚠ BREAKING CHANGES 40 | 41 | * preparing for next release (#4691) 42 | 43 | ### Features 44 | 45 | * preparing for next release ([#4691](https://github.com/googleapis/java-cloud-bom/issues/4691)) ([c07cf23](https://github.com/googleapis/java-cloud-bom/commit/c07cf2354c0799e4da7f3a75e4034f1141ad2056)) 46 | * Verifying that tests module do not get picked up release please ([#4783](https://github.com/googleapis/java-cloud-bom/issues/4783)) ([e037c08](https://github.com/googleapis/java-cloud-bom/commit/e037c08a4e2cafcebba9f1590d10d0c3b0a8dce1)) 47 | 48 | 49 | ### Dependencies 50 | 51 | * The following workspace dependencies were updated 52 | * com.google.cloud:google-cloud-bom bumped to 0.179.0 53 | 54 | ## [0.2.0](https://github.com/googleapis/java-cloud-bom/compare/tests-dependency-convergence-v0.1.0...tests-dependency-convergence-v0.2.0) (2022-08-30) 55 | 56 | 57 | ### ⚠ BREAKING CHANGES 58 | 59 | * preparing for next release (#4691) 60 | 61 | ### Features 62 | 63 | * preparing for next release ([#4691](https://github.com/googleapis/java-cloud-bom/issues/4691)) ([c07cf23](https://github.com/googleapis/java-cloud-bom/commit/c07cf2354c0799e4da7f3a75e4034f1141ad2056)) 64 | * Verifying that tests module do not get picked up release please ([#4783](https://github.com/googleapis/java-cloud-bom/issues/4783)) ([e037c08](https://github.com/googleapis/java-cloud-bom/commit/e037c08a4e2cafcebba9f1590d10d0c3b0a8dce1)) 65 | 66 | 67 | ### Dependencies 68 | 69 | * The following workspace dependencies were updated 70 | * com.google.cloud:google-cloud-bom bumped to 0.178.0 71 | 72 | ## [0.1.0](https://github.com/googleapis/java-cloud-bom/compare/tests-dependency-convergence-v0.0.1...tests-dependency-convergence-v0.1.0) (2022-08-12) 73 | 74 | 75 | ### ⚠ BREAKING CHANGES 76 | 77 | * preparing for next release (#4691) 78 | 79 | ### Features 80 | 81 | * preparing for next release ([#4691](https://github.com/googleapis/java-cloud-bom/issues/4691)) ([c07cf23](https://github.com/googleapis/java-cloud-bom/commit/c07cf2354c0799e4da7f3a75e4034f1141ad2056)) 82 | * Verifying that tests module do not get picked up release please ([#4783](https://github.com/googleapis/java-cloud-bom/issues/4783)) ([e037c08](https://github.com/googleapis/java-cloud-bom/commit/e037c08a4e2cafcebba9f1590d10d0c3b0a8dce1)) 83 | 84 | 85 | ### Dependencies 86 | 87 | * The following workspace dependencies were updated 88 | * com.google.cloud:google-cloud-bom bumped to 0.177.0 89 | -------------------------------------------------------------------------------- /tests/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | com.google.cloud 5 | java-cloud-bom-tests 6 | 0.58.0-SNAPSHOT 7 | A module to test Google Cloud Java BOMs 8 | https://github.com/googleapis/java-cloud-bom 9 | 10 | A module to test Google Cloud Java BOMs 11 | 12 | 13 | Google 14 | 15 | 16 | scm:git:git@github.com:googleapis/java-cloud-bom.git 17 | scm:git:git@github.com:googleapis/java-cloud-bom-java.git 18 | https://github.com/googleapis/java-cloud-bom 19 | HEAD 20 | 21 | 22 | UTF-8 23 | 1.8 24 | 1.8 25 | 26 | 27 | 28 | Google Cloud Software License 29 | https://raw.githubusercontent.com/googleapis/google-cloud-java/master/LICENSE 30 | 31 | 32 | 33 | 34 | 35 | com.google.cloud.tools 36 | dependencies 37 | 1.5.13 38 | 39 | 40 | com.google.truth 41 | truth 42 | 1.4.4 43 | 44 | 45 | junit 46 | junit 47 | 4.13.2 48 | test 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | org.apache.maven.plugins 57 | maven-surefire-plugin 58 | 3.5.3 59 | 60 | -Xmx8g 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /tests/release-repository-readiness/README.md: -------------------------------------------------------------------------------- 1 | # Repository Readiness for Releases 2 | 3 | This tool helps release managers to assess the readiness of the ~14 upstream GitHub 4 | repositories for the libraries-bom, such as the java-bigtable and google-cloud-java repositories. 5 | 6 | ## clone_repositories.sh 7 | 8 | `clone_repositories.sh` clones the upstream repositories in your /tmp directory. You run this after the sdk-platform-java release for your release cycle is available. 9 | 10 | ``` 11 | cd tests/release-repository-readiness 12 | ./clone_repositories.sh v2.55.1 13 | ... 14 | Updating files: 100% (93964/93964), done. 15 | /tmp/release-readiness/google-cloud-java ~/java-cloud-bom/tests/release-repository-readiness 16 | ~/java-cloud-bom/tests/release-repository-readiness 17 | ``` 18 | 19 | ## check_status.sh: 20 | 21 | `check_status.sh` fetches the latest information of each upstream repository 22 | using the cloned repositories, and displays the status of the main branch and 23 | the latest released source tree. 24 | 25 | A status consists of the shared dependencies BOM version (`shared dep` column) 26 | and hermetic build code generation (`code gen` column). 27 | 28 | During the handwritten libraries phase in your release cycle, you run this 29 | occasionally to find actions needed for the repositories. 30 | 31 | ``` 32 | suztomo@suztomo2:~/java-cloud-bom/tests/release-repository-readiness$ ./check_status.sh 33 | Expected google-cloud-shared-dependencies BOM version: 3.45.1 34 | Expected GAPIC generator Java version: 2.55.1 35 | | main | released | 36 | repository |shared dep|code gen |shared dep|code gen | 37 | google-cloud-java |OK |OK |OK |OK | 38 | java-bigquerystorage|OK |OK |OK |OK | 39 | java-bigquery |! 3.44.0 |N/A |! 3.44.0 |N/A | 40 | java-bigtable |OK |OK |OK |OK | 41 | java-datastore |OK |OK |OK |OK | 42 | java-firestore |OK |OK |! 3.44.0 |! 2.54.0 | 43 | java-logging |OK |OK |OK |OK | 44 | java-logging-logback|OK |N/A |OK |N/A | 45 | java-pubsub |OK |OK |OK |OK | 46 | java-pubsublite |OK |OK |OK |OK | 47 | java-spanner |! 3.44.0 |! 2.54.0 |! 3.44.0 |! 2.54.0 | 48 | java-spanner-jdbc |OK |N/A |OK |N/A | 49 | java-storage |OK |OK |OK |OK | 50 | java-storage-nio |OK |N/A |OK |N/A | 51 | ``` 52 | 53 | - In this example output above, you can see: 54 | - The java-bigquery and java-spanner repositories need to merge pull requests 55 | for the sdk-platform-java-config and hermetic code generation. 56 | - java-firestore repository has merged the changes in the main branch but 57 | it hasn't made a release with the changes. 58 | - The rest of the repositories show the changes are already in the latest release. 59 | - "N/A" means that there's no hermetic code generation in the repository. 60 | -------------------------------------------------------------------------------- /tests/release-repository-readiness/check_status.sh: -------------------------------------------------------------------------------- 1 | # Given the repositories are checked out in the WORK_DIR below 2 | # find the shared dependencies BOM version in current release 3 | # and find any missing updates. 4 | 5 | set -ef 6 | 7 | WORK_DIR=/tmp/release-readiness 8 | 9 | if [[ ! -d "${WORK_DIR}/sdk-platform-java" ]]; then 10 | echo "The repositories are missing in ${WORK_DIR}. Please use clone_repositories.sh first" 11 | exit 1 12 | fi 13 | 14 | cd "${WORK_DIR}/sdk-platform-java" 15 | expected_shared_deps_version=$(mvn -pl java-shared-dependencies help:evaluate -Dexpression=project.version -q -DforceStdout) 16 | expected_generator_version=$(mvn -pl gapic-generator-java help:evaluate -Dexpression=project.version -q -DforceStdout) 17 | echo "Expected google-cloud-shared-dependencies BOM version: ${expected_shared_deps_version}" 18 | echo "Expected GAPIC generator Java version: ${expected_generator_version}" 19 | 20 | 21 | function check_shared_dependency_status() { 22 | local project=$1 23 | local actual_shared_deps_version=$(mvn -pl ${project} help:evaluate -Dexpression=google-cloud-shared-dependencies.version -q -DforceStdout) 24 | if [[ "${expected_shared_deps_version}" != "${actual_shared_deps_version}" ]]; then 25 | local shared_deps_status="! ${actual_shared_deps_version}" 26 | else 27 | local shared_deps_status="OK" 28 | fi 29 | echo "${shared_deps_status}" 30 | } 31 | 32 | function check_generated_code_status() { 33 | if [ -r "generation_config.yaml" ]; then 34 | local actual_generator_version=$(perl -nle 'print $1 if m/gapic_generator_version:\s*(.+)/' generation_config.yaml) 35 | if [[ "${expected_generator_version}" != "${actual_generator_version}" ]]; then 36 | local generator_status="! ${actual_generator_version}" 37 | else 38 | local generator_status="OK" 39 | fi 40 | else 41 | local generator_status="N/A" 42 | fi 43 | echo "${generator_status}" 44 | } 45 | echo ", main, released" |\ 46 | awk -F',' '{printf "%-20s|%-21s|%-21s|\n", $1, $2, $3}' 47 | 48 | echo " repository,shared dep,code gen,shared dep,code gen" |\ 49 | awk -F',' '{printf "%-20s|%-10s|%-10s|%-10s|%-10s|\n", $1, $2, $3, $4, $5}' 50 | 51 | repositories=$(find "${WORK_DIR}" -mindepth 1 -maxdepth 1 -type d -not -name "sdk-platform-java") 52 | for repo_folder in $repositories; do 53 | cd "${repo_folder}" 54 | repo=$(basename "${repo_folder}") 55 | git fetch -q origin main > /dev/null 56 | git checkout -q main > /dev/null 57 | git pull -q origin main > /dev/null 58 | if [[ "$repo" == "google-cloud-java" ]]; then 59 | # In google-cloud-java repository, the parent pom module 60 | # inherits the property. 61 | project=google-cloud-pom-parent 62 | else 63 | # In normal handwritten libraries, the root project receives the property. 64 | project=. 65 | fi 66 | shared_deps_status_main=$(check_shared_dependency_status "${project}") 67 | generated_code_status_main=$(check_generated_code_status) 68 | 69 | last_release_tag=$(gh release list --limit 1 --order desc --json 'tagName' --jq '.[].tagName') 70 | git fetch -q origin tag ${last_release_tag} --no-tags > /dev/null 71 | git checkout -q ${last_release_tag} > /dev/null 72 | shared_deps_status_last_release=$(check_shared_dependency_status "${project}") 73 | generated_code_status_last_release=$(check_generated_code_status) 74 | 75 | echo "${repo},${shared_deps_status_main},${generated_code_status_main},\ 76 | ${shared_deps_status_last_release},${generated_code_status_last_release}" | \ 77 | awk -F',' '{printf "%-20s|%-10s|%-10s|%-10s|%-10s|\n", $1, $2, $3, $4, $5}' 78 | done 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /tests/release-repository-readiness/clone_repositories.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Clones the repositories we check in the workspace directory 4 | # (/tmp/release-readiness). It's convenient to separate the data 5 | # retrieval part (this script) and the logic (check_readiness.sh) 6 | # separated, so that the maitnainers can iterate the logic without 7 | # needing cloning the repositories. 8 | 9 | set -ef 10 | 11 | WORK_DIR=/tmp/release-readiness 12 | mkdir -p ${WORK_DIR} 13 | 14 | function clone_repository() { 15 | # e.g., "java-bigtable" 16 | repo_name=$1 17 | # e.g., "v2.55.1" or left empty 18 | revision=$2 19 | 20 | repo_dir="${WORK_DIR}/${repo_name}" 21 | if [ ! -d "${repo_dir}" ]; then 22 | repo_url="https://github.com/googleapis/${repo_name}" 23 | git clone ${repo_url} ${repo_dir} 24 | fi 25 | pushd "${repo_dir}" 26 | if [ -n "${revision}" ]; then 27 | git fetch origin 28 | git checkout "${revision}" 29 | else 30 | # There may be new updates since last run 31 | git pull 32 | fi 33 | popd 34 | } 35 | 36 | 37 | # sdk-platform-java release 38 | # https://github.com/googleapis/sdk-platform-java/releases 39 | sdk_platform_java_version=$1 40 | if [ -z "$sdk_platform_java_version" ]; then 41 | echo "Specify sdk-platform-java release tag. Example: v2.55.1" 42 | exit 1 43 | fi 44 | 45 | # This requires to checkout the specific release version 46 | clone_repository "sdk-platform-java" "${sdk_platform_java_version}" 47 | 48 | repos=("java-storage-nio" "java-storage" "java-spanner-jdbc" "java-spanner" \ 49 | "java-pubsublite" "java-pubsub" "java-logging-logback" "java-logging" \ 50 | "java-firestore" "java-datastore" "java-bigtable" "java-bigquery" \ 51 | "java-bigquerystorage" "google-cloud-java") 52 | for repo in ${repos[@]}; do 53 | clone_repository "${repo}" 54 | done 55 | -------------------------------------------------------------------------------- /tests/src/test/java/com/google/cloud/BomContentAssertionsTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Google LLC. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.cloud; 18 | 19 | import com.google.cloud.tools.opensource.dependencies.Bom; 20 | import com.google.common.truth.Truth; 21 | import java.io.IOException; 22 | import java.nio.file.Path; 23 | import java.nio.file.Paths; 24 | import org.junit.Assert; 25 | import org.junit.Test; 26 | 27 | /** Tests for the assertions in BomContentTest. */ 28 | public class BomContentAssertionsTest { 29 | 30 | @Test(expected = IOException.class) 31 | public void testInvalidBomUnreachable() throws Exception { 32 | Path bomPath = 33 | Paths.get("src", "test", "resources", "bom-with-typo-artifact.xml").toAbsolutePath(); 34 | BomContentTest.checkBomReachable(bomPath); 35 | } 36 | 37 | @Test 38 | public void testAssertDependencyConvergenceWithinCloudJavaLibraries() throws Exception { 39 | // Our old BOM release had the problem of non-convergence. 40 | Bom bom = Bom.readBom("com.google.cloud:libraries-bom:26.0.0"); 41 | try { 42 | BomContentTest.assertDependencyConvergenceWithinCloudJavaLibraries(bom); 43 | Assert.fail(); 44 | } catch (AssertionError ex) { 45 | String message = ex.getMessage(); 46 | Truth.assertThat(message) 47 | .contains( 48 | "Managed dependency com.google.cloud:google-cloud-bigquery:jar:2.13.8 has dependency" 49 | + " com.google.cloud:google-cloud-bigquerystorage:jar:2.14.2, which should be" 50 | + " 2.15.0 (the version in the BOM)"); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /tests/src/test/java/com/google/cloud/MaximumLinkageErrorsTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Google LLC. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.cloud; 18 | 19 | import com.google.cloud.tools.opensource.classpath.ClassPathBuilder; 20 | import com.google.cloud.tools.opensource.classpath.ClassPathEntry; 21 | import com.google.cloud.tools.opensource.classpath.ClassPathResult; 22 | import com.google.cloud.tools.opensource.classpath.DependencyMediation; 23 | import com.google.cloud.tools.opensource.classpath.LinkageChecker; 24 | import com.google.cloud.tools.opensource.classpath.LinkageProblem; 25 | import com.google.cloud.tools.opensource.dependencies.Bom; 26 | import com.google.cloud.tools.opensource.dependencies.MavenRepositoryException; 27 | import com.google.cloud.tools.opensource.dependencies.RepositoryUtility; 28 | import com.google.cloud.tools.opensource.dependencies.UnresolvableArtifactProblem; 29 | import com.google.common.collect.ImmutableList; 30 | import com.google.common.collect.ImmutableSet; 31 | import com.google.common.collect.Sets; 32 | import java.io.IOException; 33 | import java.nio.file.Path; 34 | import java.nio.file.Paths; 35 | import java.util.List; 36 | import java.util.Optional; 37 | import java.util.Set; 38 | import java.util.stream.Collectors; 39 | import org.eclipse.aether.RepositoryException; 40 | import org.eclipse.aether.artifact.Artifact; 41 | import org.eclipse.aether.version.InvalidVersionSpecificationException; 42 | import org.junit.Assert; 43 | import org.junit.Test; 44 | 45 | public class MaximumLinkageErrorsTest { 46 | 47 | @Test 48 | public void testForNewLinkageErrors() 49 | throws IOException, MavenRepositoryException, RepositoryException { 50 | // Not using RepositoryUtility.findLatestCoordinates, which may return a snapshot version 51 | String version = findLatestNonSnapshotVersion(); 52 | String baselineCoordinates = "com.google.cloud:libraries-bom:" + version; 53 | Bom baseline = Bom.readBom(baselineCoordinates); 54 | 55 | Path bomFile = Paths.get("../libraries-bom/pom.xml"); 56 | Bom bom = Bom.readBom(bomFile); 57 | 58 | ImmutableSet oldProblems = createLinkageChecker(baseline).findLinkageProblems(); 59 | LinkageChecker checker = createLinkageChecker(bom); 60 | ImmutableSet currentProblems = checker.findLinkageProblems(); 61 | 62 | // This only tests for newly missing methods, not new invocations of 63 | // previously missing methods. 64 | Set newProblems = Sets.difference(currentProblems, oldProblems); 65 | 66 | // Appengine-api-1.0-sdk is known to contain linkage errors because it shades dependencies 67 | // https://github.com/GoogleCloudPlatform/cloud-opensource-java/issues/441 68 | newProblems = 69 | newProblems.stream() 70 | .filter(problem -> !hasLinkageProblemFromArtifactId(problem, "appengine-api-1.0-sdk")) 71 | .collect(Collectors.toSet()); 72 | 73 | // Check that no new linkage errors have been introduced since the baseline 74 | StringBuilder message = new StringBuilder("Baseline BOM: " + baselineCoordinates + "\n"); 75 | if (!newProblems.isEmpty()) { 76 | message.append("Newly introduced problems:\n"); 77 | message.append(LinkageProblem.formatLinkageProblems(newProblems, null)); 78 | Assert.fail(message.toString()); 79 | } 80 | } 81 | 82 | private LinkageChecker createLinkageChecker(Bom bom) 83 | throws InvalidVersionSpecificationException, IOException { 84 | ImmutableList managedDependencies = bom.getManagedDependencies(); 85 | ClassPathBuilder classPathBuilder = new ClassPathBuilder(); 86 | 87 | // full: false to avoid fetching optional dependencies. 88 | ClassPathResult classPathResult = 89 | classPathBuilder.resolve(managedDependencies, false, DependencyMediation.MAVEN); 90 | ImmutableList classpath = classPathResult.getClassPath(); 91 | ImmutableList artifactProblems = 92 | classPathResult.getArtifactProblems(); 93 | if (!artifactProblems.isEmpty()) { 94 | throw new IOException("Could not resolve artifacts: " + artifactProblems); 95 | } 96 | List artifactsInBom = classpath.subList(0, managedDependencies.size()); 97 | ImmutableSet entryPoints = ImmutableSet.copyOf(artifactsInBom); 98 | return LinkageChecker.create(classpath, entryPoints, null); 99 | } 100 | 101 | private boolean hasLinkageProblemFromArtifactId(LinkageProblem problem, String artifactId) { 102 | ClassPathEntry sourceClassPathEntry = problem.getSourceClass().getClassPathEntry(); 103 | Artifact sourceArtifact = sourceClassPathEntry.getArtifact(); 104 | return artifactId.equals(sourceArtifact.getArtifactId()); 105 | } 106 | 107 | private String findLatestNonSnapshotVersion() throws MavenRepositoryException { 108 | ImmutableList versions = 109 | RepositoryUtility.findVersions( 110 | RepositoryUtility.newRepositorySystem(), "com.google.cloud", "libraries-bom"); 111 | ImmutableList versionsLatestFirst = versions.reverse(); 112 | Optional highestNonsnapshotVersion = 113 | versionsLatestFirst.stream().filter(version -> !version.contains("SNAPSHOT")).findFirst(); 114 | if (!highestNonsnapshotVersion.isPresent()) { 115 | Assert.fail("Could not find non-snapshot version of the BOM"); 116 | } 117 | return highestNonsnapshotVersion.get(); 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /tests/src/test/resources/bom-with-typo-artifact.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 4.0.0 7 | 8 | com.google.cloud 9 | invalid-libraries-bom 10 | 25.3.1-SNAPSHOT 11 | pom 12 | 13 | GCP Library Invalid Bom 14 | 15 | This is a sample bom with an invalid artifact (guava-invalid) to create a 404 16 | 17 | https://cloud.google.com/java/docs/bom 18 | 19 | Google LLC 20 | https://cloud.google.com 21 | 22 | 23 | 24 | The Apache License, Version 2.0 25 | http://www.apache.org/licenses/LICENSE-2.0.txt 26 | 27 | 28 | 29 | 30 | 31 | 32 | com.google.guava 33 | guava-invalid 34 | 31.1-jre 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /tests/validate-bom/README.md: -------------------------------------------------------------------------------- 1 | # Validate Maven BOM GitHub Action 2 | 3 | This action validates a [Maven BOM](https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#bill-of-materials-bom-poms 4 | ) specified as argument. 5 | 6 | This action performs the following steps: 7 | 8 | - It reads the BOM and gets all artifacts. 9 | - It may filter out "testlib" artifacts if they cause problems in subsequent steps 10 | - It creates a canary Maven project (a directory with a pom.xml file) with the artifacts as the dependencies. 11 | The canary project uses the BOM and declares the artifacts in the BOM as dependencies. 12 | - It runs `mvn install` in the canary project. 13 | If the BOM is valid, it should fetch dependencies (the artifacts in the BOM) without an error. 14 | 15 | ## Usage 16 | 17 | You can use this action via `uses: googleapis/java-cloud-bom/tests/validate-bom@main` 18 | in one of the steps in a job in your GitHub repository. 19 | 20 | Note that before running this action the caller needs to make the BOM and its 21 | listing artifacts available in Maven Central or local Maven repository. 22 | 23 | Here is a concrete example to define a job to use this "validate-bom" action in 24 | a GitHub Actions workflow file: 25 | 26 | ``` 27 | validate-bom: 28 | runs-on: ubuntu-latest 29 | steps: 30 | - uses: actions/checkout@v3 31 | - uses: actions/setup-java@v3 32 | with: 33 | java-version: 11 34 | distribution: temurin 35 | cache: maven 36 | - name: Install Maven artifacts locally 37 | run: | 38 | mvn install -B -ntp -DskipTests 39 | - uses: googleapis/java-cloud-bom/tests/validate-bom@main 40 | with: 41 | path: 42 | ``` 43 | 44 | ### Results 45 | 46 | If there's an error in building the canary project, the check fails. 47 | You see errors in the log: 48 | 49 | ``` 50 | [INFO] ------------------------------------------------------------------------ 51 | [INFO] BUILD FAILURE 52 | [INFO] ------------------------------------------------------------------------ 53 | [INFO] Total time: 14.253 s 54 | [INFO] Finished at: 2023-04-14T20:41:59Z 55 | [INFO] ------------------------------------------------------------------------ 56 | Error: Failed to execute goal on project bom-validation-canary-project: Could n 57 | ot resolve dependencies for project com.google.cloud:bom-validation-canary-proje 58 | ct:jar:0.0.1-SNAPSHOT: The following artifacts could not be resolved: com.google 59 | .analytics.api.grpc:grpc-google-analytics-admin-v1alpha:jar:0.24.0 ... 60 | ``` 61 | 62 | In this error message, there were invalid artifacts defined in the BOM 63 | (wrong group IDs). 64 | 65 | If there's no error, the check passes with a successful message: 66 | 67 | ``` 68 | [INFO] Installing /tmp/bom-validation/pom.xml to /home/runner/.m2/repository/... 69 | [INFO] ------------------------------------------------------------------------ 70 | [INFO] BUILD SUCCESS 71 | [INFO] ------------------------------------------------------------------------ 72 | [INFO] Total time: 5.147 s 73 | [INFO] Finished at: 2023-04-14T20:35:58Z 74 | [INFO] ------------------------------------------------------------------------ 75 | ``` 76 | 77 | # Disclaimer 78 | 79 | This is not an official Google product. 80 | This is intended for Google-internal usages only. 81 | -------------------------------------------------------------------------------- /tests/validate-bom/action.yml: -------------------------------------------------------------------------------- 1 | name: 'Maven BOM Validation' 2 | description: 'Validation for the content of a Maven BOM' 3 | inputs: 4 | bom-path: 5 | description: "The relative path from the repository root to the pom.xml file" 6 | required: true 7 | runs: 8 | using: "composite" 9 | steps: 10 | - uses: actions/setup-java@v4 11 | with: 12 | distribution: temurin 13 | java-version: 11 14 | cache: maven 15 | - name: Set up Maven 16 | uses: stCarolas/setup-maven@v4.5 17 | with: 18 | maven-version: 3.8.4 19 | - name: Create temporary directory /tmp/bom-validation 20 | shell: bash 21 | run: mkdir -p /tmp/bom-validation 22 | - name: Create a canary project that uses the BOM 23 | shell: bash 24 | run: | 25 | if [ ! -r "${{ inputs.bom-path }}" ]; then 26 | echo "The input bom-path ${{ inputs.bom-path }} is not readable" 27 | exit 1 28 | fi 29 | 30 | bom_absolute_path=$(realpath "${{ inputs.bom-path }}") 31 | 32 | # Before this "cd", the working directory is the repository that calls 33 | # this action. To use validate-bom classes, it needs to change directory 34 | # to the directory that defines this action. 35 | cd ${{ github.action_path }} 36 | 37 | echo "Compiling CreateBomCanaryProject.java in $(pwd)" 38 | mvn -V -ntp compile 39 | echo "Running CreateBomCanaryProject with ${bom_absolute_path}" 40 | mvn -V -ntp -B exec:java -DoutputPath=/tmp/bom-validation -DbomPath="${bom_absolute_path}" 41 | - name: Build the canary project that uses the BOM 42 | shell: bash 43 | working-directory: /tmp/bom-validation 44 | run: | 45 | echo "working directory: $(pwd)" 46 | mvn -ntp -B install 47 | - name: Examine dependency tree for any error 48 | shell: bash 49 | working-directory: /tmp/bom-validation 50 | run: | 51 | echo "working directory: $(pwd)" 52 | # This dependency tree check can detect errors that pass "mvn install". 53 | # For example, an invalid group ID in one of pom.xml files: 54 | # [ERROR] 'dependencies.dependency.groupId' for $com.google.protobuf:protobuf-java:jar with value '$com.google.protobuf' does not match a valid id pattern. 55 | # https://github.com/googleapis/java-cloud-bom/issues/5936 56 | ERROR_MESSAGE=$(mvn dependency:tree -X |grep "ERROR" || true) 57 | echo "ERROR_MESSAGE: ${ERROR_MESSAGE}" 58 | if [ -n "${ERROR_MESSAGE}" ]; then 59 | echo "${ERROR_MESSAGE}" 60 | exit 1 61 | fi 62 | 63 | -------------------------------------------------------------------------------- /tests/validate-bom/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | java-cloud-bom-root 8 | com.google.cloud 9 | 0.1.0 10 | ../../ 11 | 12 | 4.0.0 13 | 14 | bom-canary-project-creation 15 | 16 | BOM Canary Project Creation 17 | 18 | 19 | UTF-8 20 | 11 21 | 11 22 | 23 | 24 | 25 | 26 | com.google.cloud.tools 27 | dependencies 28 | 1.5.13 29 | 30 | 31 | junit 32 | junit 33 | 4.13.1 34 | test 35 | 36 | 37 | com.google.truth 38 | truth 39 | 1.4.4 40 | test 41 | 42 | 43 | 44 | 45 | 46 | 47 | org.codehaus.mojo 48 | exec-maven-plugin 49 | 50 | false 51 | com.google.cloud.CreateBomCanaryProject 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /tests/validate-bom/src/main/java/com/google/cloud/CreateBomCanaryProject.java: -------------------------------------------------------------------------------- 1 | package com.google.cloud; 2 | 3 | import static com.google.common.base.Preconditions.checkNotNull; 4 | 5 | import com.google.cloud.tools.opensource.dependencies.Bom; 6 | import com.google.cloud.tools.opensource.dependencies.MavenRepositoryException; 7 | import com.google.common.base.Verify; 8 | import java.io.IOException; 9 | import java.io.InputStream; 10 | import java.nio.file.Files; 11 | import java.nio.file.Path; 12 | import java.nio.file.Paths; 13 | import java.util.Map; 14 | import org.eclipse.aether.artifact.Artifact; 15 | 16 | /** 17 | * Creates a Maven project that uses the specified BOM at the specified directory. This class reads 18 | * the following system properties: 19 | * 20 | *
    21 | *
  • outputPath: the path to the directory to create the Maven project 22 | *
  • bomPath: the path to the BOM 23 | *
24 | */ 25 | public class CreateBomCanaryProject { 26 | 27 | public static void main(String[] arguments) throws Exception { 28 | String outputPathProperty = System.getProperty("outputPath"); 29 | checkNotNull(outputPathProperty, "System property outputPath should not be null"); 30 | Path outputProjectDirectory = Paths.get(outputPathProperty); 31 | String bomPathProperty = System.getProperty("bomPath"); 32 | checkNotNull(bomPathProperty, "System property bomPath should not be null"); 33 | Path bomPath = Paths.get(bomPathProperty); 34 | 35 | Bom bom; 36 | try { 37 | bom = Bom.readBom(bomPath); 38 | } catch (MavenRepositoryException exception) { 39 | throw new IOException( 40 | "Could not read the BOM: " 41 | + bomPath 42 | + ". Please ensure all artifacts in the BOM are available in Maven Central or local" 43 | + " Maven repository.", 44 | exception); 45 | } 46 | 47 | String pomTemplate = readPomTemplate(); 48 | 49 | String dependencyManagementSection = calculateDependencyManagementSection(bom); 50 | String dependenciesSection = calculateDependenciesSection(bom); 51 | 52 | String replacedContent = 53 | pomTemplate 54 | .replace("DEPENDENCY_MANAGEMENT", dependencyManagementSection) 55 | .replace("DEPENDENCIES", dependenciesSection); 56 | 57 | Path pomToWrite = outputProjectDirectory.resolve("pom.xml"); 58 | Files.write(pomToWrite, replacedContent.getBytes()); 59 | System.out.println("Wrote " + pomToWrite); 60 | } 61 | 62 | /** Returns the pom.xml template content. */ 63 | private static String readPomTemplate() throws IOException { 64 | try (InputStream inputStream = 65 | CreateBomCanaryProject.class.getClassLoader().getResourceAsStream("template.pom.xml")) { 66 | Verify.verifyNotNull(inputStream); 67 | return new String(inputStream.readAllBytes()); 68 | } 69 | } 70 | 71 | /** Returns the dependencyManagement section to import {@code bom}. */ 72 | private static String calculateDependencyManagementSection(Bom bom) { 73 | String[] coordinatesElements = bom.getCoordinates().split(":"); 74 | Verify.verify(coordinatesElements.length == 3); 75 | String groupId = coordinatesElements[0]; 76 | String artifactId = coordinatesElements[1]; 77 | String version = coordinatesElements[2]; 78 | 79 | StringBuilder builder = new StringBuilder(); 80 | builder.append(" \n"); 81 | builder.append(" \n"); 82 | builder.append(" \n"); 83 | builder.append(" ").append(groupId).append("\n"); 84 | builder.append(" ").append(artifactId).append("\n"); 85 | builder.append(" ").append(version).append("\n"); 86 | builder.append(" pom\n"); 87 | builder.append(" import\n"); 88 | builder.append(" \n"); 89 | builder.append(" \n"); 90 | builder.append(" \n"); 91 | return builder.toString(); 92 | } 93 | 94 | /** Returns the "dependencies" section that would declare all artifacts appear in {@code bom}. */ 95 | private static String calculateDependenciesSection(Bom bom) { 96 | StringBuilder builder = new StringBuilder(); 97 | builder.append(" \n"); 98 | 99 | for (Artifact managedDependency : bom.getManagedDependencies()) { 100 | Map properties = managedDependency.getProperties(); 101 | String classifier = managedDependency.getClassifier(); 102 | if ("tests".equals(classifier)) { 103 | // Tests classifier artifacts are not for customers 104 | continue; 105 | } 106 | String type = properties.get("type"); 107 | if ("pom".equals(type)) { 108 | // Some artifacts have :pom" type, such as io.grpc:protoc-gen-grpc-java 109 | // and com.google.api-client:google-api-client-assembly. We are only interested 110 | // in "jar" artifacts. 111 | continue; 112 | } 113 | 114 | // Skipping grpc-android, grpc-binder and grpc-cronet as they are not used by Google Cloud 115 | // Client Libraries for Java. Checking for availability of these unused artifacts on Maven 116 | // Central has caused BOM validation check to fail in the past. See 117 | // https://github.com/googleapis/sdk-platform-java/pull/1989#issuecomment-1724039670 118 | if ("grpc-android".equals(managedDependency.getArtifactId()) 119 | || "grpc-binder".equals(managedDependency.getArtifactId()) 120 | || "grpc-cronet".equals(managedDependency.getArtifactId())) { 121 | continue; 122 | } 123 | 124 | builder.append(" \n"); 125 | builder 126 | .append(" ") 127 | .append(managedDependency.getGroupId()) 128 | .append("\n"); 129 | builder 130 | .append(" ") 131 | .append(managedDependency.getArtifactId()) 132 | .append("\n"); 133 | builder.append(" \n"); 134 | } 135 | builder.append(" \n"); 136 | 137 | return builder.toString(); 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /tests/validate-bom/src/main/resources/template.pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | com.google.cloud 7 | bom-validation-canary-project 8 | 9 | 0.0.1-SNAPSHOT 10 | 11 | 12 | UTF-8 13 | 11 14 | 11 15 | 16 | 17 | DEPENDENCY_MANAGEMENT 18 | 19 | DEPENDENCIES 20 | -------------------------------------------------------------------------------- /versions.txt: -------------------------------------------------------------------------------- 1 | # Format: 2 | # module:released-version:current-version 3 | 4 | google-cloud-bom:0.242.0:0.243.0-SNAPSHOT 5 | libraries-bom:26.61.0:26.62.0-SNAPSHOT 6 | java-cloud-bom-tests:0.57.0:0.58.0-SNAPSHOT 7 | full-convergence-check:0.60.0:0.61.0-SNAPSHOT 8 | --------------------------------------------------------------------------------