diff options
| author | Paul Spooren | 2025-06-24 08:28:38 +0000 |
|---|---|---|
| committer | Paul Spooren | 2025-06-24 14:16:43 +0000 |
| commit | 8186e5e5a46eccf0e83776d0c1c2ba1ea78f2d83 (patch) | |
| tree | 6c28f6c119cb8c25edd9c70403ddd96158c50b81 | |
| parent | b48925fd9cf6a4891ce0c2085c18ec0af58b540c (diff) | |
| download | openwrt-8186e5e5a46eccf0e83776d0c1c2ba1ea78f2d83.tar.gz | |
ci: add bot to build on comment
This has been requested many times, so let's add this to speed up reviews. When
a member of the "reviewers" group comments the magic word written below, that
specific firmware is created and attached by a bot.
build <target>/<subtarget>/<profile>
Members of the "reviewers" group have no extra privileges, they can not commit
to the repository nor perform any action outside the `build-on-comment` action.
Motivation is to speedup reviews and have a better source for sharing compiled
firmware.
Signed-off-by: Paul Spooren <mail@aparcar.org>
| -rw-r--r-- | .github/workflows/build-on-comment.yml | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/.github/workflows/build-on-comment.yml b/.github/workflows/build-on-comment.yml new file mode 100644 index 0000000000..ffb20d1f23 --- /dev/null +++ b/.github/workflows/build-on-comment.yml @@ -0,0 +1,161 @@ +name: Build on Comment + +on: + issue_comment: + types: [created, edited] + +concurrency: + group: build-on-comment-${{ github.event.issue.number || github.event.pull_request.number }} + cancel-in-progress: true + +jobs: + check-and-build: + if: github.event.issue.pull_request != null + runs-on: ubuntu-latest + + steps: + - name: Check if user is in reviewers team + id: check-reviewer + run: | + USERNAME="${{ github.event.comment.user.login }}" + + STATUS_CODE=$(curl -s -H "Authorization: token ${{ secrets.LOOKUP_MEMBERS }}" \ + -o response.json -w "%{http_code}" \ + https://api.github.com/orgs/openwrt/teams/reviewers/memberships/$USERNAME) + + if grep -q '"state": "active"' response.json && [ "$STATUS_CODE" -eq 200 ]; then + echo "authorized=true" >> $GITHUB_OUTPUT + else + echo "authorized=false" >> $GITHUB_OUTPUT + fi + + - name: Parse build command + if: steps.check-reviewer.outputs.authorized == 'true' + id: parse-command + run: | + COMMENT="${{ github.event.comment.body }}" + if echo "$COMMENT" | grep -q "build [a-zA-Z0-9_-]\+/[a-zA-Z0-9_-]\+/[a-zA-Z0-9_-]\+"; then + BUILD_PATH=$(echo "$COMMENT" | grep -o "build [a-zA-Z0-9_-]\+/[a-zA-Z0-9_-]\+/[a-zA-Z0-9_-]\+" | sed 's/build //') + TARGET=$(echo "$BUILD_PATH" | cut -d'/' -f1) + SUBTARGET=$(echo "$BUILD_PATH" | cut -d'/' -f2) + PROFILE=$(echo "$BUILD_PATH" | cut -d'/' -f3) + echo "build_requested=true" >> $GITHUB_OUTPUT + echo "target=$TARGET" >> $GITHUB_OUTPUT + echo "subtarget=$SUBTARGET" >> $GITHUB_OUTPUT + echo "profile=$PROFILE" >> $GITHUB_OUTPUT + echo "build_path=$BUILD_PATH" >> $GITHUB_OUTPUT + else + echo "build_requested=false" >> $GITHUB_OUTPUT + fi + + - name: Find existing build comment + if: steps.parse-command.outputs.build_requested == 'true' + id: find-comment + uses: peter-evans/find-comment@v2 + with: + issue-number: ${{ github.event.pull_request.number || github.event.issue.number }} + comment-author: "github-actions[bot]" + + - name: Create early build comment + if: steps.parse-command.outputs.build_requested == 'true' + id: start-comment + uses: peter-evans/create-or-update-comment@v3 + with: + issue-number: ${{ github.event.pull_request.number || github.event.issue.number }} + comment-id: ${{ steps.find-comment.outputs.comment-id }} + body: | + 🚧 **Build in progress for** `${{ steps.parse-command.outputs.build_path }}`... + + You can follow progress [here](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}) + + *Triggered by: @${{ github.event.comment.user.login }}* + edit-mode: replace + + - name: Checkout repository + if: steps.parse-command.outputs.build_requested == 'true' + uses: actions/checkout@v4 + with: + token: ${{ secrets.GITHUB_TOKEN }} + fetch-depth: 0 + ref: refs/pull/${{ github.event.issue.number }}/merge + + - name: Setup build environment + if: steps.parse-command.outputs.build_requested == 'true' + continue-on-error: true + run: | + sudo apt-get update + sudo apt-get install -y build-essential libncurses5-dev gawk git subversion libssl-dev gettext zlib1g-dev swig unzip time rsync + + - name: Build target + if: steps.parse-command.outputs.build_requested == 'true' + id: build + run: | + make defconfig + echo "CONFIG_DEVEL=y" > .config + echo "CONFIG_BPF_TOOLCHAIN_HOST=y" >> .config + echo "CONFIG_TARGET_${{ steps.parse-command.outputs.target }}=y" >> .config + echo "CONFIG_TARGET_${{ steps.parse-command.outputs.target }}_${{ steps.parse-command.outputs.subtarget }}=y" >> .config + echo "CONFIG_TARGET_${{ steps.parse-command.outputs.target }}_${{ steps.parse-command.outputs.subtarget }}_DEVICE_${{ steps.parse-command.outputs.profile }}=y" >> .config + + make defconfig + make -j$(nproc) BUILD_LOG=1 + + echo "build_success=true" >> $GITHUB_OUTPUT + + - name: Upload log + uses: actions/upload-artifact@v4 + if: steps.check-reviewer.outputs.authorized == 'true' && (success() || failure()) + with: + name: build-log-${{ steps.parse-command.outputs.target }}-${{ steps.parse-command.outputs.subtarget }}-${{ steps.parse-command.outputs.profile }} + path: logs/ + + - name: Create artifact archive + if: steps.build.outputs.build_success == 'true' + run: | + cd bin/ + tar -czf ../build-artifacts.tar.gz * + cd .. + + - name: Upload build artifacts + if: steps.build.outputs.build_success == 'true' + uses: actions/upload-artifact@v4 + with: + name: build-${{ steps.parse-command.outputs.target }}-${{ steps.parse-command.outputs.subtarget }}-${{ steps.parse-command.outputs.profile }} + path: build-artifacts.tar.gz + + - name: Update comment with build results + if: steps.build.outputs.build_success == 'true' + uses: peter-evans/create-or-update-comment@v3 + with: + comment-id: ${{ steps.start-comment.outputs.comment-id }} + issue-number: ${{ github.event.pull_request.number || github.event.issue.number }} + body: | + ## Build Results for `${{ steps.parse-command.outputs.build_path }}` + + ✅ **Build completed successfully!** + + **Target:** `${{ steps.parse-command.outputs.target }}` + **Subtarget:** `${{ steps.parse-command.outputs.subtarget }}` + **Profile:** `${{ steps.parse-command.outputs.profile }}` + + 📦 **Artifacts:** [Download build-${{ steps.parse-command.outputs.target }}-${{ steps.parse-command.outputs.subtarget }}-${{ steps.parse-command.outputs.profile }}](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}) + + *Build triggered by: @${{ github.event.comment.user.login }}* + *Last updated: ${{ github.event.comment.created_at }}* + edit-mode: replace + + - name: Update comment on build failure + if: steps.parse-command.outputs.build_requested == 'true' && steps.build.outputs.build_success == 'false' + uses: peter-evans/create-or-update-comment@v3 + with: + comment-id: ${{ steps.start-comment.outputs.comment-id }} + issue-number: ${{ github.event.pull_request.number || github.event.issue.number }} + body: | + ## Build Results for `${{ steps.parse-command.outputs.build_path }}` + + ❌ **Build failed!** + + Please check the [action logs](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}) for more details. + + *Build triggered by: @${{ github.event.comment.user.login }}* + edit-mode: replace |