Skip to content

ci: add breaking change detector #21

ci: add breaking change detector

ci: add breaking change detector #21

# 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.
# Detect semver-incompatible (breaking) API changes in crates modified by a PR.
#
# Only public workspace crates that have file changes are checked.
# Internal crates (benchmarks, test-utils, sqllogictest, doc) are excluded.
#
# If breaking changes are found, a sticky comment is posted on the PR.
# The comment is removed automatically once the issues are resolved.
name: "Detect breaking changes"
on:
pull_request:
branches:
- main
permissions:
contents: read
jobs:
check-semver:
name: Check semver
runs-on: ubuntu-latest
outputs:
logs: ${{ steps.check_semver.outputs.logs }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
# For fork PRs, `origin` points to the fork, not the upstream repo.
# Explicitly fetch the base branch from the upstream repo so we have
# a valid baseline ref for both diff and semver-checks.
- name: Fetch base branch
env:
BASE_REF: ${{ github.base_ref }}
REPO: ${{ github.repository }}
run: git fetch "https://github.com/${REPO}.git" "${BASE_REF}:refs/remotes/origin/${BASE_REF}"
- name: Determine changed crates
id: changed_crates
env:
BASE_REF: ${{ github.base_ref }}
run: |
PACKAGES=$(ci/scripts/changed_crates.sh changed-crates "origin/${BASE_REF}")
echo "packages=$PACKAGES" >> "$GITHUB_OUTPUT"
echo "Changed crates: $PACKAGES"
- name: Install cargo-semver-checks
if: steps.changed_crates.outputs.packages != ''
uses: taiki-e/install-action@94cb46f8d6e437890146ffbd78a778b78e623fb2 # v2.74.0
with:
tool: cargo-semver-checks
- name: Run cargo-semver-checks
id: check_semver
if: steps.changed_crates.outputs.packages != ''
env:
BASE_REF: ${{ github.base_ref }}
PACKAGES: ${{ steps.changed_crates.outputs.packages }}
run: |
set +e
# `tee` lets cargo's output stream live into the Actions log
# while we also keep a copy for the PR comment.
ci/scripts/changed_crates.sh semver-check "origin/${BASE_REF}" $PACKAGES \
2>&1 | tee /tmp/semver-output.txt
EXIT_CODE=${PIPESTATUS[0]}
{
echo "logs<<EOF"
sed 's/\x1b\[[0-9;]*m//g' /tmp/semver-output.txt
echo "EOF"
} >> "$GITHUB_OUTPUT"
exit $EXIT_CODE
# Post or remove a sticky comment on the PR based on the semver check result.
comment-on-pr:
name: Comment on pull request
runs-on: ubuntu-latest
needs: check-semver
if: always()
permissions:
contents: read
pull-requests: write
steps:
- name: Checkout
uses: actions/checkout@v4
with:
sparse-checkout: ci/scripts
- name: Update PR comment
env:
GH_TOKEN: ${{ github.token }}
REPO: ${{ github.repository }}
PR_NUMBER: ${{ github.event.pull_request.number }}
CHECK_RESULT: ${{ needs.check-semver.result }}
SEMVER_LOGS: ${{ needs.check-semver.outputs.logs }}
run: |
ci/scripts/changed_crates.sh comment \
"$REPO" "$PR_NUMBER" "$CHECK_RESULT" "$SEMVER_LOGS"