diff --git a/.github/workflows/README.md b/.github/workflows/README.md index c6a95b29b4c0..30225a999411 100644 --- a/.github/workflows/README.md +++ b/.github/workflows/README.md @@ -542,3 +542,4 @@ PostCommit Jobs run in a schedule against master branch and generally do not get | [ Infrastructure Policy Enforcer ](https://github.com/apache/beam/actions/workflows/beam_Infrastructure_PolicyEnforcer.yml) | N/A | [![.github/workflows/beam_Infrastructure_PolicyEnforcer.yml](https://github.com/apache/beam/actions/workflows/beam_Infrastructure_PolicyEnforcer.yml/badge.svg?event=schedule)](https://github.com/apache/beam/actions/workflows/beam_Infrastructure_PolicyEnforcer.yml?query=event%3Aschedule) | | [ Modify the GCP User Roles according to the infra/users.yml file ](https://github.com/apache/beam/actions/workflows/beam_Infrastructure_UsersPermissions.yml) | N/A | [![.github/workflows/beam_Infrastructure_UsersPermissions.yml](https://github.com/apache/beam/actions/workflows/beam_Infrastructure_UsersPermissions.yml/badge.svg?event=schedule)](https://github.com/apache/beam/actions/workflows/beam_Infrastructure_UsersPermissions.yml?query=event%3Aschedule) | | [ Service Account Keys Management ](https://github.com/apache/beam/actions/workflows/beam_Infrastructure_ServiceAccountKeys.yml) | N/A | [![.github/workflows/beam_Infrastructure_ServiceAccountKeys.yml](https://github.com/apache/beam/actions/workflows/beam_Infrastructure_ServiceAccountKeys.yml/badge.svg?event=schedule)](https://github.com/apache/beam/actions/workflows/beam_Infrastructure_ServiceAccountKeys.yml?query=event%3Aschedule) | +| [ Upgrade GCP Libraries BOM ](https://github.com/apache/beam/actions/workflows/beam_Upgrade_GCP_BOM.yml) | N/A | [![.github/workflows/beam_Upgrade_GCP_BOM.yml](https://github.com/apache/beam/actions/workflows/beam_Upgrade_GCP_BOM.yml/badge.svg?event=schedule)](https://github.com/apache/beam/actions/workflows/beam_Upgrade_GCP_BOM.yml?query=event%3Aschedule) | diff --git a/.github/workflows/beam_Upgrade_GCP_BOM.yml b/.github/workflows/beam_Upgrade_GCP_BOM.yml new file mode 100644 index 000000000000..ffa5a5073ee4 --- /dev/null +++ b/.github/workflows/beam_Upgrade_GCP_BOM.yml @@ -0,0 +1,85 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: Upgrade GCP Libraries BOM + +on: + schedule: + - cron: "0 0 * * 0" # Weekly on Sundays at 00:00 UTC + workflow_dispatch: + +permissions: + contents: write + pull-requests: write + checks: read + issues: read + statuses: read + +concurrency: + group: '${{ github.workflow }} @ ${{ github.ref }}' + cancel-in-progress: true + +jobs: + upgrade_gcp_bom: + runs-on: [self-hosted, ubuntu-24.04, main] + name: Upgrade GCP BOM + steps: + - name: Checkout code + uses: actions/checkout@v6 + - name: Setup environment + uses: ./.github/actions/setup-environment-action + with: + python-version: 3.11 + java-version: default + go-version: default + - name: Check if new BOM is available + id: check_bom + run: python3 scripts/tools/gcp_bom_upgrade_check.py + - name: Run bomupgrader + if: steps.check_bom.outputs.should_upgrade == 'true' + run: python3 scripts/tools/bomupgrader.py ${{ steps.check_bom.outputs.latest_version }} + - name: Install gh cli + if: steps.check_bom.outputs.should_upgrade == 'true' + uses: ./.github/actions/setup-gh-cli-linux + - name: Set git config + if: steps.check_bom.outputs.should_upgrade == 'true' + run: | + git config user.name $GITHUB_ACTOR + git config user.email actions@"$RUNNER_NAME".local + - name: Commit Changes and create PR + if: steps.check_bom.outputs.should_upgrade == 'true' + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + LATEST_VER: ${{ steps.check_bom.outputs.latest_version }} + CURRENT_VER: ${{ steps.check_bom.outputs.current_version }} + run: | + branchName=upgrade_gcp_bom_${LATEST_VER//./_} + git checkout -b $branchName + git add -A + git diff-index --quiet HEAD || gitdiff=$? || echo $? + if [[ $gitDiff != 0 ]]; then + echo "Changes are ready to commit" + git commit -m "Upgrade GCP Libraries BOM to ${LATEST_VER}" --quiet + git push origin $branchName --quiet + + PR_BODY="This PR was created by automation. It upgrades the Google Cloud Platform Libraries BOM from **${CURRENT_VER}** to **${LATEST_VER}** and updates Netty, gRPC, Arrow, Gax, Protobuf, and OpenTelemetry versions to match. + + Please review the changes and merge if all tests pass." + + GITHUB_PR_URL=$(gh pr create --title "Upgrade GCP Libraries BOM to ${LATEST_VER}" --body "$PR_BODY" --label "dependencies" --base master) + echo "Link of the new PR: $GITHUB_PR_URL" + else + echo "No changes on the files" + fi diff --git a/scripts/tools/gcp_bom_upgrade_check.py b/scripts/tools/gcp_bom_upgrade_check.py new file mode 100644 index 000000000000..40943dafdf2c --- /dev/null +++ b/scripts/tools/gcp_bom_upgrade_check.py @@ -0,0 +1,66 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import urllib.request +import re +import os + +def get_latest_bom(): + url = "https://repo1.maven.org/maven2/com/google/cloud/libraries-bom/maven-metadata.xml" + with urllib.request.urlopen(url, timeout=15) as response: + xml = response.read().decode('utf-8') + match = re.search(r'([^<]+)', xml) + if match: + return match.group(1) + raise RuntimeError("Could not find latest release in Maven metadata") + +def get_current_bom(): + path = "buildSrc/src/main/groovy/org/apache/beam/gradle/BeamModulePlugin.groovy" + with open(path) as f: + content = f.read() + match = re.search(r'google_cloud_platform_libraries_bom\s*:\s*[\"\']com\.google\.cloud:libraries-bom:([0-9.]+)[\"\']', content) + if match: + return match.group(1) + raise RuntimeError("Could not find current libraries-bom in BeamModulePlugin.groovy") + +def to_tuple(version_str): + parts = [] + for part in version_str.split('.'): + match = re.match(r'^(\d+)', part) + parts.append(int(match.group(1)) if match else 0) + return tuple(parts) + +def main(): + latest = get_latest_bom() + current = get_current_bom() + print(f"Latest libraries-bom version: {latest}") + print(f"Current libraries-bom version: {current}") + + should_upgrade = to_tuple(latest) > to_tuple(current) + + github_output = os.getenv('GITHUB_OUTPUT') + if github_output: + with open(github_output, 'a') as f: + f.write(f"should_upgrade={str(should_upgrade).lower()}\n") + f.write(f"latest_version={latest}\n") + f.write(f"current_version={current}\n") + + if should_upgrade: + print("A newer version of libraries-bom is available. Upgrade needed.") + else: + print("libraries-bom is up-to-date.") + +if __name__ == '__main__': + main()