From 316ce34b8a65bb6d4b6aaab1c7c46fbf8a4155e2 Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Mon, 27 Jul 2026 22:14:53 +0000 Subject: [PATCH 1/8] feat(ci): faster breaking change detector --- .github/backwards-compatibility-check.sh | 109 +++++++++++++++++++++++ .github/workflows/release-checks.yaml | 78 ++++++++++------ 2 files changed, 161 insertions(+), 26 deletions(-) create mode 100644 .github/backwards-compatibility-check.sh diff --git a/.github/backwards-compatibility-check.sh b/.github/backwards-compatibility-check.sh new file mode 100644 index 000000000000..0f4f0c9e425c --- /dev/null +++ b/.github/backwards-compatibility-check.sh @@ -0,0 +1,109 @@ +#!/bin/bash +# Copyright 2026 Google LLC +# +# Licensed 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. + +set -e + +# USAGE: +# +# backwards-compatibility-check.sh COMPONENT +# +# COMPONENT: The component directory name to run the backwards compatibility check for. + +if [ "$#" -ne 1 ]; then + echo "usage: backwards-compatibility-check.sh [COMPONENT]" + exit 1 +fi + +COMPONENT=$1 + +# Exception for 'dev' +if [ "${COMPONENT}" = "dev" ]; then + echo "Skipping dev directory (not a public component)." + exit 0 +fi + +# Check if component directory exists +if [ ! -d "${COMPONENT}" ]; then + echo "Error: Directory ${COMPONENT} does not exist!" >&2 + exit 1 +fi + +# Check if composer.json exists +COMP_JSON="${COMPONENT}/composer.json" +if [ ! -f "${COMP_JSON}" ]; then + echo "Error: composer.json not found in ${COMPONENT}!" >&2 + exit 1 +fi + +# Retrieve the split repository target using jq +TARGET_REPO=$(jq -r '.extra.component.target // empty' "${COMP_JSON}") +if [ -z "${TARGET_REPO}" ]; then + echo "Error: no split repository target configured in ${COMP_JSON}!" >&2 + exit 1 +fi + +echo "Checking backwards compatibility for component: ${COMPONENT}" >&2 +echo "Split repository target: ${TARGET_REPO}" >&2 + +# Create a temporary directory for cloning the split repository +TMP_DIR=$(mktemp -d) + +# Clone the split repository with a depth of 1 (containing only the latest commit) +echo "Cloning https://github.com/${TARGET_REPO}..." >&2 +if ! git clone -q --depth 1 "https://github.com/${TARGET_REPO}" "${TMP_DIR}"; then + echo "Failed to clone split repository ${TARGET_REPO}." >&2 + rm -rf "${TMP_DIR}" + exit 1 +fi + +# Copy the current local component files over the cloned split repository, +# making sure to exclude vendor directories or composer-local files. +echo "Applying local changes from ${COMPONENT} to the split clone..." >&2 +rsync -a --exclude="vendor/" --exclude="composer-local.json" "${COMPONENT}/" "${TMP_DIR}/" + +# Commit the changes in the cloned split repository so we can compare them +CODE=0 +if ( + cd "${TMP_DIR}" + git config user.name "Github Actions" + git config user.email "actions@github.com" + git add -A + + # Check if there are any changes to commit + if ! git diff --cached --quiet; then + git commit -q -m "Apply local PR changes" + echo "Running Roave Backward Compatibility Check..." >&2 + + # Locate the roave binary portably + COMPOSER_BIN=$(composer global config bin-dir --absolute 2>/dev/null || echo ~/.composer/vendor/bin) + ROAVE_BIN=$(command -v roave-backward-compatibility-check || echo "${COMPOSER_BIN}/roave-backward-compatibility-check") + + if ! "${ROAVE_BIN}" --from=HEAD~1 --format=markdown; then + echo "❌ BC Breaks detected in ${COMPONENT}!" >&2 + exit 1 + else + echo "✅ No BC Breaks detected in ${COMPONENT}." >&2 + fi + else + echo "No files modified for ${COMPONENT} compared to the split repository HEAD. Skipping check." >&2 + fi +); then + CODE=0 +else + CODE=1 +fi + +rm -rf "${TMP_DIR}" +exit $CODE diff --git a/.github/workflows/release-checks.yaml b/.github/workflows/release-checks.yaml index 336a93531f59..470130284b39 100644 --- a/.github/workflows/release-checks.yaml +++ b/.github/workflows/release-checks.yaml @@ -5,6 +5,7 @@ on: branches: ['main'] permissions: contents: read + pull-requests: write jobs: # More info at https://github.com/Roave/BackwardCompatibilityCheck. backwards-compatibility-check: @@ -19,28 +20,8 @@ jobs: uses: shivammathur/setup-php@v2 with: php-version: "8.1" - - name: "Rebase PR branch onto main branch" - if: github.event.pull_request.user.login != 'release-please[bot]' - run: | - git config user.name "Github Actions" - git config user.email "actions@github.com" - git checkout ${{ github.event.pull_request.head.sha }} - if ! git rebase origin/main; then - echo "Failed to rebase PR branch onto main. There may be conflicts. Please resolve conflicts or rebase manually." - exit 1 - fi - name: "Install dependencies" run: composer global require "roave/backward-compatibility-check:^8.2" - - name: "Check for BC breaks" - if: github.event.pull_request.user.login != 'release-please[bot]' - run: | - ~/.composer/vendor/bin/roave-backward-compatibility-check --from=origin/main --format=github-actions - - name: "Check for BC label" - run: | - if [[ "true" == "${{ contains(github.event.pull_request.title, '!:') }}" ]]; then - echo "Breaking change label found in PR title" - exit 1 - fi - name: Get Latest Release if: github.event.pull_request.user.login == 'release-please[bot]' id: latest-release @@ -48,14 +29,59 @@ jobs: with: repository: ${{ github.repository }} token: ${{ secrets.GITHUB_TOKEN }} - - name: "Check for BC breaks (Next Release)" + - name: "Check for BC breaks" + id: check-bc + run: | + BASE_REF="${{ steps.latest-release.outputs.release }}" + BASE_REF=${BASE_REF:-origin/main} + CHANGED_COMPONENTS=$(git diff ${BASE_REF} --name-only | grep -E '^[A-Z][a-zA-Z0-9]*/' | cut -d'/' -f1 | sort -u) + if [ -z "${CHANGED_COMPONENTS}" ]; then + echo "No public component directories have changed. Skipping backwards compatibility checks." + exit 0 + fi + BC_BREAKS="" + for COMPONENT in ${CHANGED_COMPONENTS}; do + BC_BREAKS="$BC_BREAKS$(bash .github/backwards-compatibility-check.sh "${COMPONENT}")" + done + printf "bc-breaks<> $GITHUB_OUTPUT + - name: "Validate standard PR results" + if: github.event.pull_request.user.login != 'release-please[bot]' + run: | + if [ -n "${{ steps.check-bc.outputs.bc-breaks }}" ]; then + echo "❌ Backwards compatibility breaks detected in this PR:" + echo "${{ steps.check-bc.outputs.bc-breaks }}" + exit 1 + elif [[ "true" == "${{ contains(github.event.pull_request.title, '!:') }}" ]]; then + echo "❌ Error: You indicated breaking changes in your PR title (!:), but no backwards compatibility breaks were detected by the automated check." + exit 1 + else + echo "✅ No backwards compatibility breaks detected." + fi + - name: "Add or update PR comment with BC breaks for Release PRs" if: github.event.pull_request.user.login == 'release-please[bot]' - # We've already approved and justified the breaking changes. Run the check but continue on error - continue-on-error: true + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - ~/.composer/vendor/bin/roave-backward-compatibility-check \ - --from=${{ steps.latest-release.outputs.release }} \ - --to=origin/main --format=github-actions + COMMENT_TAG="" + BC_BREAKS="${{ steps.check-bc.outputs.bc-breaks }}" + if [ -n "$BC_BREAKS" ]; then + COMMENT_BODY="$COMMENT_TAG +## ⚠️ Backwards Compatibility (BC) Breaking Changes Notice +This PR contains backward compatibility breaking changes detected by the automated BC check against the latest release. Please review the details below: + +$BC_BREAKS" + else + COMMENT_BODY="$COMMENT_TAG +## ⚠️ Backwards Compatibility (BC) Breaking Changes Notice +✅ No backwards compatibility breaking changes were detected for this release PR. +" + fi + COMMENT_ID=$(gh api "repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/comments" --paginate -q ".[] | select(.body | contains(\"$COMMENT_TAG\")) | .id" | head -n 1) + if [ -n "$COMMENT_ID" ]; then + gh api -X PATCH "repos/${{ github.repository }}/issues/comments/$COMMENT_ID" -f body="$COMMENT_BODY" >/dev/null + else + gh api -X POST "repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/comments" -f body="$COMMENT_BODY" >/dev/null + fi # Ensure the release PR does not contain an unexpected (e.g. 2.0.0) major version release # Add "MAJOR_VERSION_ALLOWED=component1,component2" to the PR description to allow major version From a6f4311206c8d1a511ea1d8598c23cf7c8f6559c Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Mon, 27 Jul 2026 22:41:40 +0000 Subject: [PATCH 2/8] use BASE_REF instead of last component release --- .github/backwards-compatibility-check.sh | 51 ++++++++++++++---------- .github/workflows/release-checks.yaml | 4 +- 2 files changed, 33 insertions(+), 22 deletions(-) diff --git a/.github/backwards-compatibility-check.sh b/.github/backwards-compatibility-check.sh index 0f4f0c9e425c..6eb418db05a7 100644 --- a/.github/backwards-compatibility-check.sh +++ b/.github/backwards-compatibility-check.sh @@ -17,16 +17,18 @@ set -e # USAGE: # -# backwards-compatibility-check.sh COMPONENT +# backwards-compatibility-check.sh COMPONENT [BASE_REF] # # COMPONENT: The component directory name to run the backwards compatibility check for. +# BASE_REF: Optional. The baseline git ref (e.g. 'main', 'origin/main' or a release tag) to compare against. Defaults to 'main'. -if [ "$#" -ne 1 ]; then - echo "usage: backwards-compatibility-check.sh [COMPONENT]" +if [ "$#" -lt 1 ] || [ "$#" -gt 2 ]; then + echo "usage: backwards-compatibility-check.sh COMPONENT [BASE_REF]" exit 1 fi COMPONENT=$1 +BASE_REF=${2:-main} # Exception for 'dev' if [ "${COMPONENT}" = "dev" ]; then @@ -47,38 +49,45 @@ if [ ! -f "${COMP_JSON}" ]; then exit 1 fi -# Retrieve the split repository target using jq -TARGET_REPO=$(jq -r '.extra.component.target // empty' "${COMP_JSON}") -if [ -z "${TARGET_REPO}" ]; then - echo "Error: no split repository target configured in ${COMP_JSON}!" >&2 - exit 1 -fi +echo "Checking backwards compatibility for component: ${COMPONENT} against baseline: ${BASE_REF}" >&2 -echo "Checking backwards compatibility for component: ${COMPONENT}" >&2 -echo "Split repository target: ${TARGET_REPO}" >&2 +# Check if the component existed in the baseline reference +if ! git rev-parse --verify "${BASE_REF}:${COMPONENT}" >/dev/null 2>&1; then + echo "Component ${COMPONENT} did not exist in baseline ${BASE_REF}. Skipping check (all additions)." >&2 + exit 0 +fi -# Create a temporary directory for cloning the split repository +# Create a temporary directory TMP_DIR=$(mktemp -d) -# Clone the split repository with a depth of 1 (containing only the latest commit) -echo "Cloning https://github.com/${TARGET_REPO}..." >&2 -if ! git clone -q --depth 1 "https://github.com/${TARGET_REPO}" "${TMP_DIR}"; then - echo "Failed to clone split repository ${TARGET_REPO}." >&2 +# Initialize a dummy git repo inside TMP_DIR so roave-backward-compatibility-check can compare revisions +( + cd "${TMP_DIR}" + git init -q +) + +# Extract baseline files from the BASE_REF, stripping the prefix folder so they land at the root of TMP_DIR +if ! git archive "${BASE_REF}" "${COMPONENT}" | tar -x --strip-components=1 -C "${TMP_DIR}" 2>/dev/null; then + echo "Error: Failed to archive and extract files for ${COMPONENT} from git ref ${BASE_REF}." >&2 rm -rf "${TMP_DIR}" exit 1 fi -# Copy the current local component files over the cloned split repository, +( + cd "${TMP_DIR}" + git add -A + git commit -q -m "Base state from ${BASE_REF}" +) + +# Copy the current local component files over the baseline repository, # making sure to exclude vendor directories or composer-local files. -echo "Applying local changes from ${COMPONENT} to the split clone..." >&2 +echo "Applying local changes from ${COMPONENT} to the baseline clone..." >&2 rsync -a --exclude="vendor/" --exclude="composer-local.json" "${COMPONENT}/" "${TMP_DIR}/" # Commit the changes in the cloned split repository so we can compare them CODE=0 if ( cd "${TMP_DIR}" - git config user.name "Github Actions" - git config user.email "actions@github.com" git add -A # Check if there are any changes to commit @@ -97,7 +106,7 @@ if ( echo "✅ No BC Breaks detected in ${COMPONENT}." >&2 fi else - echo "No files modified for ${COMPONENT} compared to the split repository HEAD. Skipping check." >&2 + echo "No files modified for ${COMPONENT} compared to ${BASE_REF}. Skipping check." >&2 fi ); then CODE=0 diff --git a/.github/workflows/release-checks.yaml b/.github/workflows/release-checks.yaml index 470130284b39..bcb559f24482 100644 --- a/.github/workflows/release-checks.yaml +++ b/.github/workflows/release-checks.yaml @@ -32,6 +32,8 @@ jobs: - name: "Check for BC breaks" id: check-bc run: | + git config --global user.name "Github Actions" + git config --global user.email "actions@github.com" BASE_REF="${{ steps.latest-release.outputs.release }}" BASE_REF=${BASE_REF:-origin/main} CHANGED_COMPONENTS=$(git diff ${BASE_REF} --name-only | grep -E '^[A-Z][a-zA-Z0-9]*/' | cut -d'/' -f1 | sort -u) @@ -41,7 +43,7 @@ jobs: fi BC_BREAKS="" for COMPONENT in ${CHANGED_COMPONENTS}; do - BC_BREAKS="$BC_BREAKS$(bash .github/backwards-compatibility-check.sh "${COMPONENT}")" + BC_BREAKS="$BC_BREAKS$(bash .github/backwards-compatibility-check.sh "${COMPONENT}" "${BASE_REF}")" done printf "bc-breaks<> $GITHUB_OUTPUT - name: "Validate standard PR results" From 4a896af282696fbfc7cddf591c2f1a12aae272a8 Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Mon, 27 Jul 2026 22:50:17 +0000 Subject: [PATCH 3/8] use marocchino/sticky-pull-request-comment --- .github/workflows/release-checks.yaml | 39 +++++++++++---------------- 1 file changed, 16 insertions(+), 23 deletions(-) diff --git a/.github/workflows/release-checks.yaml b/.github/workflows/release-checks.yaml index bcb559f24482..1cbb86f012aa 100644 --- a/.github/workflows/release-checks.yaml +++ b/.github/workflows/release-checks.yaml @@ -45,7 +45,17 @@ jobs: for COMPONENT in ${CHANGED_COMPONENTS}; do BC_BREAKS="$BC_BREAKS$(bash .github/backwards-compatibility-check.sh "${COMPONENT}" "${BASE_REF}")" done + # Formulate the comment body + if [ -n "$BC_BREAKS" ]; then + COMMENT_BODY="This PR contains backward compatibility breaking changes detected by the automated BC check against the latest release. Please review the details below: + +$BC_BREAKS" + else + COMMENT_BODY="✅ No backwards compatibility breaking changes were detected for this release PR." + fi + # Set GITHUB_OUTPUTs printf "bc-breaks<> $GITHUB_OUTPUT + printf "comment-body<> $GITHUB_OUTPUT - name: "Validate standard PR results" if: github.event.pull_request.user.login != 'release-please[bot]' run: | @@ -61,29 +71,12 @@ jobs: fi - name: "Add or update PR comment with BC breaks for Release PRs" if: github.event.pull_request.user.login == 'release-please[bot]' - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - COMMENT_TAG="" - BC_BREAKS="${{ steps.check-bc.outputs.bc-breaks }}" - if [ -n "$BC_BREAKS" ]; then - COMMENT_BODY="$COMMENT_TAG -## ⚠️ Backwards Compatibility (BC) Breaking Changes Notice -This PR contains backward compatibility breaking changes detected by the automated BC check against the latest release. Please review the details below: - -$BC_BREAKS" - else - COMMENT_BODY="$COMMENT_TAG -## ⚠️ Backwards Compatibility (BC) Breaking Changes Notice -✅ No backwards compatibility breaking changes were detected for this release PR. -" - fi - COMMENT_ID=$(gh api "repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/comments" --paginate -q ".[] | select(.body | contains(\"$COMMENT_TAG\")) | .id" | head -n 1) - if [ -n "$COMMENT_ID" ]; then - gh api -X PATCH "repos/${{ github.repository }}/issues/comments/$COMMENT_ID" -f body="$COMMENT_BODY" >/dev/null - else - gh api -X POST "repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/comments" -f body="$COMMENT_BODY" >/dev/null - fi + uses: marocchino/sticky-pull-request-comment@v2 + with: + header: bc-breaking-changes-comment + message: | + ## ⚠️ Backwards Compatibility (BC) Breaking Changes Notice + ${{ steps.check-bc.outputs.comment-body }} # Ensure the release PR does not contain an unexpected (e.g. 2.0.0) major version release # Add "MAJOR_VERSION_ALLOWED=component1,component2" to the PR description to allow major version From 16ad1a24c8d1754aed6a374c8621dc3a11d20834 Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Mon, 27 Jul 2026 22:56:23 +0000 Subject: [PATCH 4/8] split out format-comment step --- .github/workflows/release-checks.yaml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release-checks.yaml b/.github/workflows/release-checks.yaml index 1cbb86f012aa..d8e5838e1259 100644 --- a/.github/workflows/release-checks.yaml +++ b/.github/workflows/release-checks.yaml @@ -45,7 +45,13 @@ jobs: for COMPONENT in ${CHANGED_COMPONENTS}; do BC_BREAKS="$BC_BREAKS$(bash .github/backwards-compatibility-check.sh "${COMPONENT}" "${BASE_REF}")" done - # Formulate the comment body + # Set GITHUB_OUTPUT + printf "bc-breaks<> $GITHUB_OUTPUT + - name: "Prepare release PR comment" + id: format-comment + if: github.event.pull_request.user.login == 'release-please[bot]' + run: | + BC_BREAKS="${{ steps.check-bc.outputs.bc-breaks }}" if [ -n "$BC_BREAKS" ]; then COMMENT_BODY="This PR contains backward compatibility breaking changes detected by the automated BC check against the latest release. Please review the details below: @@ -53,8 +59,6 @@ $BC_BREAKS" else COMMENT_BODY="✅ No backwards compatibility breaking changes were detected for this release PR." fi - # Set GITHUB_OUTPUTs - printf "bc-breaks<> $GITHUB_OUTPUT printf "comment-body<> $GITHUB_OUTPUT - name: "Validate standard PR results" if: github.event.pull_request.user.login != 'release-please[bot]' @@ -76,7 +80,7 @@ $BC_BREAKS" header: bc-breaking-changes-comment message: | ## ⚠️ Backwards Compatibility (BC) Breaking Changes Notice - ${{ steps.check-bc.outputs.comment-body }} + ${{ steps.format-comment.outputs.comment-body }} # Ensure the release PR does not contain an unexpected (e.g. 2.0.0) major version release # Add "MAJOR_VERSION_ALLOWED=component1,component2" to the PR description to allow major version From a00160b1953110cd345d0195fe1ee4e733373853 Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Mon, 27 Jul 2026 23:06:21 +0000 Subject: [PATCH 5/8] simplify actions --- .github/workflows/release-checks.yaml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/.github/workflows/release-checks.yaml b/.github/workflows/release-checks.yaml index d8e5838e1259..573ca32c54f1 100644 --- a/.github/workflows/release-checks.yaml +++ b/.github/workflows/release-checks.yaml @@ -47,9 +47,8 @@ jobs: done # Set GITHUB_OUTPUT printf "bc-breaks<> $GITHUB_OUTPUT - - name: "Prepare release PR comment" + - name: "Prepare BC break report" id: format-comment - if: github.event.pull_request.user.login == 'release-please[bot]' run: | BC_BREAKS="${{ steps.check-bc.outputs.bc-breaks }}" if [ -n "$BC_BREAKS" ]; then @@ -57,15 +56,14 @@ jobs: $BC_BREAKS" else - COMMENT_BODY="✅ No backwards compatibility breaking changes were detected for this release PR." + COMMENT_BODY="✅ No backwards compatibility breaking changes were detected." fi printf "comment-body<> $GITHUB_OUTPUT - name: "Validate standard PR results" if: github.event.pull_request.user.login != 'release-please[bot]' run: | if [ -n "${{ steps.check-bc.outputs.bc-breaks }}" ]; then - echo "❌ Backwards compatibility breaks detected in this PR:" - echo "${{ steps.check-bc.outputs.bc-breaks }}" + echo "❌ ${{ steps.format-comment.outputs.comment-body }}" exit 1 elif [[ "true" == "${{ contains(github.event.pull_request.title, '!:') }}" ]]; then echo "❌ Error: You indicated breaking changes in your PR title (!:), but no backwards compatibility breaks were detected by the automated check." From 0a22200c304bf3934834b8784150791fa7f9ae09 Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Tue, 28 Jul 2026 15:45:20 +0000 Subject: [PATCH 6/8] fix newline break --- .github/workflows/release-checks.yaml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release-checks.yaml b/.github/workflows/release-checks.yaml index 573ca32c54f1..3022cf903fde 100644 --- a/.github/workflows/release-checks.yaml +++ b/.github/workflows/release-checks.yaml @@ -52,9 +52,8 @@ jobs: run: | BC_BREAKS="${{ steps.check-bc.outputs.bc-breaks }}" if [ -n "$BC_BREAKS" ]; then - COMMENT_BODY="This PR contains backward compatibility breaking changes detected by the automated BC check against the latest release. Please review the details below: - -$BC_BREAKS" + COMMENT_BODY="This PR contains backward compatibility breaking changes detected by the automated BC check against the latest release. Please review the details below:" + COMMENT_BODY="$COMMENT_BODY"$'\n\n'"$BC_BREAKS" else COMMENT_BODY="✅ No backwards compatibility breaking changes were detected." fi From 08a58d286d288dbf5a9f7defa794cf14535901d4 Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Wed, 29 Jul 2026 21:54:02 +0000 Subject: [PATCH 7/8] refactor breaking change script for sanity --- .github/backwards-compatibility-check.sh | 23 +++++++-- .github/workflows/release-checks.yaml | 65 +++++++++++++----------- 2 files changed, 53 insertions(+), 35 deletions(-) diff --git a/.github/backwards-compatibility-check.sh b/.github/backwards-compatibility-check.sh index 6eb418db05a7..9467e36a295b 100644 --- a/.github/backwards-compatibility-check.sh +++ b/.github/backwards-compatibility-check.sh @@ -99,11 +99,26 @@ if ( COMPOSER_BIN=$(composer global config bin-dir --absolute 2>/dev/null || echo ~/.composer/vendor/bin) ROAVE_BIN=$(command -v roave-backward-compatibility-check || echo "${COMPOSER_BIN}/roave-backward-compatibility-check") - if ! "${ROAVE_BIN}" --from=HEAD~1 --format=markdown; then - echo "❌ BC Breaks detected in ${COMPONENT}!" >&2 - exit 1 + FORMAT=${BC_FORMAT:-markdown} + if [ "${FORMAT}" = "markdown" ]; then + # Run Roave check and capture output + OUTPUT=$("${ROAVE_BIN}" --from=HEAD~1 --format=markdown 2>/dev/null || true) + if [ -n "${OUTPUT}" ]; then + echo "
" + echo "${COMPONENT}: Backwards Compatibility Breaks Detected" + echo "" + echo "${OUTPUT}" + echo "
" + echo "" + exit 1 + fi else - echo "✅ No BC Breaks detected in ${COMPONENT}." >&2 + if ! "${ROAVE_BIN}" --from=HEAD~1 --format="${FORMAT}"; then + echo "❌ BC Breaks detected in ${COMPONENT}!" >&2 + exit 1 + else + echo "✅ No BC Breaks detected in ${COMPONENT}." >&2 + fi fi else echo "No files modified for ${COMPONENT} compared to ${BASE_REF}. Skipping check." >&2 diff --git a/.github/workflows/release-checks.yaml b/.github/workflows/release-checks.yaml index 3022cf903fde..a4e8d90308c1 100644 --- a/.github/workflows/release-checks.yaml +++ b/.github/workflows/release-checks.yaml @@ -34,50 +34,53 @@ jobs: run: | git config --global user.name "Github Actions" git config --global user.email "actions@github.com" + + # Determine base ref for git diff BASE_REF="${{ steps.latest-release.outputs.release }}" BASE_REF=${BASE_REF:-origin/main} - CHANGED_COMPONENTS=$(git diff ${BASE_REF} --name-only | grep -E '^[A-Z][a-zA-Z0-9]*/' | cut -d'/' -f1 | sort -u) + + # Find changed component directories + CHANGED_COMPONENTS=$(git diff ${BASE_REF} --name-only | grep -E '^[A-Z][a-zA-Z0-9]*/' | cut -d'/' -f1 | sort -u || true) if [ -z "${CHANGED_COMPONENTS}" ]; then - echo "No public component directories have changed. Skipping backwards compatibility checks." + echo "No public component directories have changed." exit 0 fi - BC_BREAKS="" - for COMPONENT in ${CHANGED_COMPONENTS}; do - BC_BREAKS="$BC_BREAKS$(bash .github/backwards-compatibility-check.sh "${COMPONENT}" "${BASE_REF}")" - done - # Set GITHUB_OUTPUT - printf "bc-breaks<> $GITHUB_OUTPUT - - name: "Prepare BC break report" - id: format-comment - run: | - BC_BREAKS="${{ steps.check-bc.outputs.bc-breaks }}" - if [ -n "$BC_BREAKS" ]; then - COMMENT_BODY="This PR contains backward compatibility breaking changes detected by the automated BC check against the latest release. Please review the details below:" - COMMENT_BODY="$COMMENT_BODY"$'\n\n'"$BC_BREAKS" - else - COMMENT_BODY="✅ No backwards compatibility breaking changes were detected." - fi - printf "comment-body<> $GITHUB_OUTPUT - - name: "Validate standard PR results" - if: github.event.pull_request.user.login != 'release-please[bot]' - run: | - if [ -n "${{ steps.check-bc.outputs.bc-breaks }}" ]; then - echo "❌ ${{ steps.format-comment.outputs.comment-body }}" - exit 1 - elif [[ "true" == "${{ contains(github.event.pull_request.title, '!:') }}" ]]; then - echo "❌ Error: You indicated breaking changes in your PR title (!:), but no backwards compatibility breaks were detected by the automated check." - exit 1 + + IS_RELEASE_PR="${{ github.event.pull_request.user.login == 'release-please[bot]' }}" + + if [ "${IS_RELEASE_PR}" = "true" ]; then + # Release PR: gather markdown and do not fail the step + BC_BREAKS="" + for COMPONENT in ${CHANGED_COMPONENTS}; do + BC_BREAKS="$BC_BREAKS$(BC_FORMAT="markdown" bash .github/backwards-compatibility-check.sh "${COMPONENT}" "${BASE_REF}" || true)" + done + printf "bc-breaks<> $GITHUB_OUTPUT else - echo "✅ No backwards compatibility breaks detected." + # Normal PR: use github-actions format and fail if there are breaks + FAIL="" + for COMPONENT in ${CHANGED_COMPONENTS}; do + if ! BC_FORMAT="github-actions" bash .github/backwards-compatibility-check.sh "${COMPONENT}" "${BASE_REF}"; then + FAIL="true" + fi + done + + if [ "${FAIL}" = "true" ]; then + exit 1 + elif [[ "true" == "${{ contains(github.event.pull_request.title, '!:') }}" ]]; then + echo "❌ Error: You indicated breaking changes in your PR title (!:), but no backwards compatibility breaks were detected by the automated check." + exit 1 + fi fi - name: "Add or update PR comment with BC breaks for Release PRs" - if: github.event.pull_request.user.login == 'release-please[bot]' + if: github.event.pull_request.user.login == 'release-please[bot]' && steps.check-bc.outputs.bc-breaks != '' uses: marocchino/sticky-pull-request-comment@v2 with: header: bc-breaking-changes-comment message: | ## ⚠️ Backwards Compatibility (BC) Breaking Changes Notice - ${{ steps.format-comment.outputs.comment-body }} + This PR contains backward compatibility breaking changes detected by the automated BC check against the latest release. Please review the details below: + + ${{ steps.check-bc.outputs.bc-breaks }} # Ensure the release PR does not contain an unexpected (e.g. 2.0.0) major version release # Add "MAJOR_VERSION_ALLOWED=component1,component2" to the PR description to allow major version From 043647729e8d9d09c2c3b1e5b9809ebfd777d27a Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Thu, 30 Jul 2026 18:01:15 +0000 Subject: [PATCH 8/8] clear whitespace, gitignore test pem --- .github/workflows/release-checks.yaml | 10 +++++----- Gax/.gitignore | 1 + 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/release-checks.yaml b/.github/workflows/release-checks.yaml index a4e8d90308c1..0d1a14b5edc3 100644 --- a/.github/workflows/release-checks.yaml +++ b/.github/workflows/release-checks.yaml @@ -34,20 +34,20 @@ jobs: run: | git config --global user.name "Github Actions" git config --global user.email "actions@github.com" - + # Determine base ref for git diff BASE_REF="${{ steps.latest-release.outputs.release }}" BASE_REF=${BASE_REF:-origin/main} - + # Find changed component directories CHANGED_COMPONENTS=$(git diff ${BASE_REF} --name-only | grep -E '^[A-Z][a-zA-Z0-9]*/' | cut -d'/' -f1 | sort -u || true) if [ -z "${CHANGED_COMPONENTS}" ]; then echo "No public component directories have changed." exit 0 fi - + IS_RELEASE_PR="${{ github.event.pull_request.user.login == 'release-please[bot]' }}" - + if [ "${IS_RELEASE_PR}" = "true" ]; then # Release PR: gather markdown and do not fail the step BC_BREAKS="" @@ -63,7 +63,7 @@ jobs: FAIL="true" fi done - + if [ "${FAIL}" = "true" ]; then exit 1 elif [[ "true" == "${{ contains(github.event.pull_request.title, '!:') }}" ]]; then diff --git a/Gax/.gitignore b/Gax/.gitignore index 94e81fe0df3a..4f6a8850478d 100644 --- a/Gax/.gitignore +++ b/Gax/.gitignore @@ -6,6 +6,7 @@ composer.lock composer-test.lock vendor/ build/artifacts/ +tests/Conformance/showcase.pem artifacts/ .idea .metadata