diff --git a/.github/workflows/apidiff.yml b/.github/workflows/apidiff.yml new file mode 100644 index 000000000000..1b4642f05082 --- /dev/null +++ b/.github/workflows/apidiff.yml @@ -0,0 +1,79 @@ +--- +name: apidiff +on: + pull_request: + +jobs: + setup: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + ref: main + - name: Get main commit + id: main + run: echo "::set-output name=hash::$(git rev-parse HEAD)" + - uses: actions/checkout@v3 + - name: Get changed directories + id: changed_dirs + # Ignore changes to the internal and root directories. + run: | + dirs=$(git diff-tree --no-commit-id --name-only --diff-filter=DMR -r ${{ steps.main.outputs.hash }}..HEAD | xargs -r -L1 dirname | uniq | grep -v -e 'internal' -e '\.') + if [ -z "$dirs" ] + then + echo "::set-output name=changed::{\"changed\":[]}" + else + for d in $dirs; do list=${list},\"${d}\"; done + echo "::set-output name=changed::{\"changed\":[${list#,}]}" + fi + outputs: + changed_dirs: ${{ steps.changed_dirs.outputs.changed }} + apidiff: + needs: setup + runs-on: ubuntu-latest + if: "!contains(github.event.pull_request.labels.*.name, 'breaking change allowed')" + continue-on-error: true + strategy: + matrix: ${{ fromJson(needs.setup.outputs.changed_dirs) }} + steps: + - uses: actions/setup-go@v3 + with: + go-version: '1.18.3' + - name: Install latest apidiff + run: go install golang.org/x/exp/cmd/apidiff@latest + - uses: actions/checkout@v3 + with: + ref: main + - name: Baseline name + id: baseline + run: | + export CHANGED=${{ matrix.changed }} + echo ::set-output name=pkg::"${CHANGED//\//_}_pkg.main" + - name: Create Go package baseline + run: cd {{ matrix.changed }} && apidiff -w ${{ steps.baseline.outputs.pkg }} . + - name: Upload baseline package data + uses: actions/upload-artifact@v3 + with: + name: ${{ steps.baseline.outputs.pkg }} + path: ${{ steps.baseline.outputs.pkg }} + retention-days: 1 + - uses: actions/checkout@v3 + - name: Download baseline package data + uses: actions/download-artifact@v3 + with: + name: ${{ steps.baseline.outputs.pkg }} + - name: Compare regenerated code to baseline + run: | + cd {{ matrix.changed }} && apidiff -incompatible ${{ steps.baseline.outputs.pkg }} . > diff.txt + cat diff.txt && ! [ -s diff.txt ] + - name: Add breaking change label + if: ${{ failure() && !github.event.pull_request.head.repo.fork }} + uses: actions/github-script@v6 + with: + script: | + github.rest.issues.addLabels({ + issue_number: ${{ github.event.number }}, + owner: context.repo.owner, + repo: context.repo.repo, + labels: ['breaking change'] + }) \ No newline at end of file