From 805812ec90ea06a1c81b1915bbdf6419c00a7f1a Mon Sep 17 00:00:00 2001 From: Adam Cozzette Date: Fri, 16 Sep 2022 15:11:30 -0700 Subject: [PATCH] Auto-generate CMake file lists in GitHub action (#10592) This GitHub action will run after each pull request merge and will auto-update the file lists in in src/file_lists.cmake. The action will run as our bot account. I realized that if a bug somehow made the file generation non-idempotent, this could trigger an infinite loop of commits, so I put in an extra safeguard against that. If the previous commit was by "Protobuf Team Bot", the GitHub action will revert any local changes to ensure that no new commit will be made. --- .github/workflows/generated_cmake.yml | 30 +++++++++++--------- cmake/push_auto_update.sh | 41 +++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 13 deletions(-) create mode 100755 cmake/push_auto_update.sh diff --git a/.github/workflows/generated_cmake.yml b/.github/workflows/generated_cmake.yml index 91dcd4f1e7..b63f16c0cc 100644 --- a/.github/workflows/generated_cmake.yml +++ b/.github/workflows/generated_cmake.yml @@ -1,8 +1,13 @@ -name: Generated CMake File Lists +name: Generate CMake File Lists on: - - push - - pull_request + push: + branches: + - main + - '[0-9]+.x' + # The 21.x branch predates support for auto-generation of the CMake file + # lists, so we make sure to exclude it. + - '!21.x' jobs: cmake: @@ -12,13 +17,12 @@ jobs: fail-fast: false # Don't cancel all jobs if one fails. steps: - - uses: actions/checkout@v2 - - name: Set up Bazel read-only caching - run: echo "BAZEL_CACHE_AUTH=--remote_upload_local_results=false" >> $GITHUB_ENV - - name: Generate CMake files - run: cd ${{ github.workspace }} && bazel build //pkg:gen_src_file_lists --test_output=errors $BAZEL_CACHE $BAZEL_CACHE_AUTH - - name: Compare to Golden file - run: diff -du bazel-bin/pkg/src_file_lists.cmake src/file_lists.cmake - - name: Report - run: echo "::error file=cmake/update_file_lists.sh::CMake files are stale, please run cmake/update_file_lists.sh" - if: failure() + - uses: actions/checkout@v3 + with: + # Note: this token has an expiration date, so if the workflow starts + # failing then you may need to generate a fresh token. + token: ${{ secrets.BOT_ACCESS_TOKEN }} + - name: Configure name and email address in Git + run: cd ${{ github.workspace }} && git config user.name "Protobuf Team Bot" && git config user.email "protobuf-team-bot@google.com" + - name: Commit and push update + run: cd ${{ github.workspace }} && ./cmake/push_auto_update.sh diff --git a/cmake/push_auto_update.sh b/cmake/push_auto_update.sh new file mode 100755 index 0000000000..abae4f4c0c --- /dev/null +++ b/cmake/push_auto_update.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +# This script updates the CMake file lists (i.e. src/file_lists.cmake), commits +# the resulting change, and pushes it. This does not do anything useful when +# run manually, but should be run by our GitHub action instead. + +set -ex + +# Exit early if the previous commit was made by the bot. This reduces the risk +# of a bug causing an infinite loop of auto-generated commits. +if (git log -1 --pretty=format:'%an' | grep -q "Protobuf Team Bot"); then + echo "Previous commit was authored by bot" + exit 0 +fi + +$(dirname -- "$0")/update_file_lists.sh + +# Try to determine the most recent pull request number. +title=$(git log -1 --pretty='%s') +pr_from_merge=$(echo "$title" | sed -n 's/^Merge pull request #\([0-9]\+\).*/\1/p') +pr_from_squash=$(echo "$title" | sed -n 's/^.*(#\([0-9]\+\))$/\1/p') + +pr="" +if [ ! -z "$pr_from_merge" ]; then + pr="$pr_from_merge" +elif [ ! -z "$pr_from_squash" ]; then + pr="$pr_from_squash" +fi + +if [ ! -z "$pr" ]; then + commit_message="Auto-generate CMake file lists after PR #$pr" +else + # If we are unable to determine the pull request number, we fall back on this + # default commit message. Typically this should not occur, but could happen + # if a pull request was merged via a rebase. + commit_message="Auto-generate CMake file lists" +fi + +git add -A +git diff --staged --quiet || git commit -am "$commit_message" +git push