diff --git a/.github/scripts/check_pr_status.sh b/.github/scripts/check_pr_status.sh new file mode 100755 index 0000000000..2e4810b8d5 --- /dev/null +++ b/.github/scripts/check_pr_status.sh @@ -0,0 +1,75 @@ +#!/bin/bash + +# A script to check the status of a specific CI job ("Kokoro - Test: Integration") +# for a list of GitHub Pull Requests. +# +# Assumes the user has the GitHub CLI (`gh`) installed and is authenticated. + +# Hardcoded list of downstream Protobuf testing PRs to check the status of +PULL_REQUESTS=( + "https://github.com/googleapis/java-bigtable/pull/2663" + "https://github.com/googleapis/java-bigquery/pull/3942" + "https://github.com/googleapis/java-firestore/pull/2227" + "https://github.com/googleapis/java-pubsub/pull/2537" + "https://github.com/googleapis/java-pubsublite/pull/1917" + "https://github.com/googleapis/java-spanner/pull/4026" + "https://github.com/googleapis/java-spanner-jdbc/pull/2191" + "https://github.com/googleapis/java-storage/pull/3266" + "https://github.com/googleapis/java-storage-nio/pull/1644" +) + +# The name of the Integration Testing CI job +JOB_NAME="Kokoro - Test: Integration" + +# --- Script Logic --- +echo "🔎 Starting check for '${JOB_NAME}' status..." +echo "------------------------------------------------" + +# A counter for failed or pending jobs. +FAILURES=0 +PENDING=0 + +# Loop through each PR in the array. +for pr_url in "${PULL_REQUESTS[@]}"; do + echo "Checking PR: ${pr_url}" + + # Use `gh pr checks` to get the status of all checks for the PR. + # Then, use `grep` to find the line for our specific job. + # We anchor the search to the beginning of the line (^) and ensure it is + # followed by whitespace to avoid partial matches with other job names. + check_status_line=$(gh pr checks "${pr_url}" | grep "^${JOB_NAME}[[:space:]]") + + if [[ -z "${check_status_line}" ]]; then + # If `grep` returns nothing, the job was not found. + echo " -> 🟡 WARNING: Could not find the '${JOB_NAME}' job." + ((FAILURES++)) + else + # Get the json values for the name of the job and the status + status=$(gh pr checks ${pr_url} --json name,state -q ".[] | select(.name == \"${JOB_NAME}\") | .state") + + # Check the status and report accordingly. + if [[ "${status}" == "SUCCESS" ]]; then + echo " -> ✅ SUCCESS: The job passed." + elif [[ "${status}" == "FAILURE" ]]; then + echo " -> ❌ FAILURE: The job failed." + ((FAILURES++)) + elif [[ "${status}" == "PENDING" ]]; then + echo " -> ⏳ PENDING: The job is still running." + ((PENDING++)) + else + # Handle any other statuses (e.g., SKIPPED, CANCELED). + echo " -> ⚪️ INFO: The job status is '${status}'." + fi + fi + echo "" # Add a newline for better readability. +done + +echo "------------------------------------------------" + +# Final summary report. +if [[ ${FAILURES} -eq 0 && ${PENDING} -eq 0 ]]; then + echo "🎉 All checks for '${JOB_NAME}' passed successfully!" +else + echo "🚨 Found ${FAILURES} PR(s) where '${JOB_NAME}' did not succeed." + echo "🚨 Found ${PENDING} PR(s) where '${JOB_NAME}' status is unknown." +fi \ No newline at end of file diff --git a/.github/scripts/update_prs.sh b/.github/scripts/update_prs.sh new file mode 100755 index 0000000000..1d12dd683b --- /dev/null +++ b/.github/scripts/update_prs.sh @@ -0,0 +1,149 @@ +#!/bin/bash + +# A script to update GitHub PRs with the latest from the main branch. +# +# It checks out each PR, merges main using the 'ours' strategy for conflicts +# (which keeps the PR's changes), and pushes the updated branch. +# +# Dependencies: +# - git +# - gh (GitHub CLI) +# +# Usage: +# ./update_prs.sh + +# ----------------------------------------------------------------------------- +# Configuration & Safety Checks +# ----------------------------------------------------------------------------- + +# Exit the script immediately if any command fails. +set -e + +# Ensure required command-line tools are installed. +if ! command -v git &> /dev/null; then + echo "❌ Error: 'git' is not installed. Please install it to continue." + exit 1 +fi + +if ! command -v gh &> /dev/null; then + echo "❌ Error: 'gh' (GitHub CLI) is not installed. Please install it to continue." + exit 1 +fi + +# Ensure the user is authenticated with the GitHub CLI. +if ! gh auth status &> /dev/null; then + echo "❌ Error: You are not logged into the GitHub CLI. Please run 'gh auth login'." + exit 1 +fi + +# ----------------------------------------------------------------------------- +# Main Logic +# ----------------------------------------------------------------------------- + +# Hardcoded list of downstream PRs testing Protobuf 4.29.x Compatibility +PR_URLS_429=( + "https://github.com/googleapis/java-bigtable/pull/2614" + "https://github.com/googleapis/java-bigquery/pull/3867" + "https://github.com/googleapis/java-bigquerystorage/pull/3030" + "https://github.com/googleapis/java-datastore/pull/1900" + "https://github.com/googleapis/java-firestore/pull/2165" + "https://github.com/googleapis/java-logging/pull/1825" + "https://github.com/googleapis/java-logging-logback/pull/1492" + "https://github.com/googleapis/java-pubsub/pull/2470" + "https://github.com/googleapis/java-pubsublite/pull/1889" + "https://github.com/googleapis/java-spanner/pull/3928" + "https://github.com/googleapis/java-spanner-jdbc/pull/2113" + "https://github.com/googleapis/java-storage/pull/3178" + "https://github.com/googleapis/java-storage-nio/pull/1612" +) + +# Hardcoded list of downstream PRs testing Protobuf 4.31.x Compatibility +PR_URLS_431=( + "https://github.com/googleapis/java-bigtable/pull/2663" + "https://github.com/googleapis/java-bigquery/pull/3942" + "https://github.com/googleapis/java-bigquerystorage/pull/3083" + "https://github.com/googleapis/java-datastore/pull/1954" + "https://github.com/googleapis/java-firestore/pull/2227" + "https://github.com/googleapis/java-logging/pull/1851" + "https://github.com/googleapis/java-logging-logback/pull/1512" + "https://github.com/googleapis/java-pubsub/pull/2537" + "https://github.com/googleapis/java-pubsublite/pull/1917" + "https://github.com/googleapis/java-spanner/pull/4026" + "https://github.com/googleapis/java-spanner-jdbc/pull/2191" + "https://github.com/googleapis/java-storage/pull/3266" + "https://github.com/googleapis/java-storage-nio/pull/1644" +) + +function processPRs() { + pushd "/tmp" + PR_URLS=("$@") + # Loop through all PR URLs defined in the PR_URLS array. + for pr_url in "${PR_URLS[@]}"; do + echo "🚀 Processing PR: $pr_url" + + # Parse the URL to get the repository and PR number. + # Example: https://github.com/googleapis/java-bigtable/pull/2614 + # REPO_OWNER -> googleapis + # REPO_NAME -> java-bigtable + # PR_NUMBER -> 2614 + REPO_OWNER=$(echo "$pr_url" | cut -d'/' -f4) + REPO_NAME=$(echo "$pr_url" | cut -d'/' -f5) + PR_NUMBER=$(echo "$pr_url" | cut -d'/' -f7) + + # Basic validation of the parsed components. + if [ -z "$REPO_OWNER" ] || [ -z "$REPO_NAME" ] || [ -z "$PR_NUMBER" ]; then + echo "⚠️ Could not parse URL: $pr_url. Skipping." + echo "-----------------------------------------" + continue + fi + + REPO_FULL_NAME="$REPO_OWNER/$REPO_NAME" + + # Clone the repo into a subdirectory if it doesn't already exist. + if [ ! -d "$REPO_NAME" ]; then + echo "Cloning repository $REPO_FULL_NAME..." + gh repo clone "$REPO_FULL_NAME" + fi + + # Navigate into the repository's directory. + pushd "$REPO_NAME" + + # Stash any existing changes in the repo + git stash + + echo "Checking out PR #$PR_NUMBER..." + gh pr checkout "$PR_NUMBER" + + echo "Fetching latest updates from origin..." + git fetch origin + + echo "Merging latest 'origin/main' into the branch..." + # The `-X ours` option is the key. It resolves any merge conflicts + # by automatically favoring the version of the code from the + # current branch (your PR branch). + git merge -m "Merge branch 'main' into PR #$PR_NUMBER to update" -X ours origin/main + + echo "Pushing updated branch to remote..." + git push + + echo "✅ Successfully updated PR #$PR_NUMBER in $REPO_FULL_NAME." + + if git stash list | grep -q 'stash@{0}'; then + git stash pop + else + echo "No stash entries found, skipping git stash pop." + fi + + popd + echo "-----------------------------------------" + done + echo "🎉 All done!" + popd +} + +echo "Running for all 4.29 Protobuf PRs..." +processPRs "${PR_URLS_429[@]}" +echo "-----------------------------------------" +echo "Running for all 4.31 Protobuf PRs..." +processPRs "${PR_URLS_431[@]}" +echo "-----------------------------------------" \ No newline at end of file diff --git a/.github/workflows/update_downstream_protobuf_test.yaml b/.github/workflows/update_downstream_protobuf_test.yaml new file mode 100644 index 0000000000..ca29b44af4 --- /dev/null +++ b/.github/workflows/update_downstream_protobuf_test.yaml @@ -0,0 +1,32 @@ +# This is a GitHub Actions workflow to run the check_pr_status.sh script nightly. +name: Nightly PR Status Check + +on: + schedule: + # This cron schedule runs at 03:00 UTC every day. + # This corresponds to 11:00 PM EST during Daylight Saving Time (EDT). + # Note: During Standard Time, this will be 10:00 PM EST. + - cron: '0 3 * * *' + + # This allows you to manually run the workflow from the Actions tab in GitHub. + workflow_dispatch: + +jobs: + run_pr_check: + # The type of runner that the job will run on. + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v5 + + # The GH_TOKEN is set automatically using GitHub's built-in secret. + # The `gh` CLI tool will automatically use this token for authentication. + - name: Run PR status check script + env: + GH_TOKEN: ${{ secrets.PAT }} + run: | + git config --global user.name 'Lawrence Qiu' + git config --global user.email 'lawrenceqiu@google.com' + gh auth setup-git + ./.github/scripts/update_prs.sh \ No newline at end of file diff --git a/renovate.json b/renovate.json index d2b21a583a..ace7276a47 100644 --- a/renovate.json +++ b/renovate.json @@ -89,56 +89,37 @@ ], "packageRules": [ { - "matchPackageNames": [ - "com.google.cloud:google-cloud-shared-config" - ], - "registryUrls": [ - "https://repo.maven.apache.org/maven2/", - "https://repo1.maven.org/maven2" - ] - }, - { - "matchUpdateTypes": [ - "major" - ], "enabled": false, - "matchPackageNames": [ - "*" - ] - }, - { - "enabled": false, - "matchPackageNames": [ - "/^com.google.protobuf:/" - ] + "matchFileNames": ["**/pom.xml", "gax-java/dependencies.properties"], + "description": "Disable all Java dependency bumps" }, { - "versioning": "docker", + "semanticCommitType": "deps", + "semanticCommitScope": null, "matchPackageNames": [ - "/^com.google.guava:/" + "*" ], - "enabled": false + "description": "Prefix version bumps with `deps:` Conventional Commit" }, { - "semanticCommitType": "deps", - "semanticCommitScope": null, + "ignoreUnstable": false, "matchPackageNames": [ - "*" + "/^com.google.cloud:google-cloud-/" ] }, { + "enabled": true, "semanticCommitType": "build", "semanticCommitScope": "deps", - "enabled": true, "matchPackageNames": [ "/^org.apache.maven/", "/^org.jacoco:/", "/^org.codehaus.mojo:/", - "/^org.sonatype.plugins:/", - "/^com.google.cloud:google-cloud-shared-config/" + "/^org.sonatype.plugins:/" ] }, { + "enabled": true, "semanticCommitType": "chore", "semanticCommitScope": "deps", "matchPackageNames": [ @@ -148,6 +129,7 @@ ] }, { + "enabled": true, "semanticCommitType": "test", "semanticCommitScope": "deps", "matchPackageNames": [ @@ -159,24 +141,11 @@ ] }, { - "ignoreUnstable": false, + "groupName": "Google Java Shared Config", "matchPackageNames": [ - "/^com.google.cloud:google-cloud-/" - ] - }, - { - "groupName": "jackson dependencies", - "matchPackageNames": [ - "/^com.fasterxml.jackson.core/" + "/^com.google.cloud:google-cloud-shared-config/" ] }, - { - "groupName": "gRPC dependencies", - "matchPackageNames": [ - "/^io.grpc/" - ], - "enabled": false - }, { "groupName": "Google Auth Library dependencies", "matchPackageNames": [ @@ -200,31 +169,46 @@ ] }, { - "groupName": "OpenCensus dependencies", - "matchPackageNames": [ - "/^io.opencensus/" - ] + "matchFileNames": ["hermetic_build/**"], + "groupName": "Hermetic Build Library Generation Dependencies", + "matchPackageNames": ["*"] }, { - "groupName": "Netty dependencies", - "matchPackageNames": [ - "/^io.netty/" - ] + "matchFileNames": [ + ".cloudbuild/library_generation/**" + ], + "groupName": "Cloud Build Library Generation Dependencies" + }, + { + "enabled": false, + "fileMatch": [ + "^\\.cloudbuild/library_generation/library_generation.*\\.Dockerfile$" + ], + "matchPackageNames": ["/^io.grpc:grpc-core/"], + "datasourceTemplate": "maven" }, { - "groupName": "Error Prone dependencies", + "enabled": false, + "matchUpdateTypes": [ + "major" + ], "matchPackageNames": [ - "/^com.google.errorprone/" - ] + "*" + ], + "description": "Disable all major version bumps everywhere" }, { + "enabled": true, "matchManagers": [ "regex" ], + "matchUpdateTypes": ["major", "minor", "patch"], + "semanticCommitType": "chore", "matchFileNames": ["dependencies.txt"], + "matchPackageNames": ["*"], "matchDatasources": ["maven"], "groupName": "Upper Bound Dependencies File", - "description": "Group all dependencies from the Upper Bound Dependencies File" + "description": "Dependencies from the Upper Bound Dependencies File" } ] }