diff --git a/.github/workflows/build-pr-profile.yml b/.github/workflows/build-pr-profile.yml new file mode 100644 index 0000000..058ba7a --- /dev/null +++ b/.github/workflows/build-pr-profile.yml @@ -0,0 +1,144 @@ +name: Build PR Profile + +on: + workflow_call: + +permissions: + pull-requests: write + +concurrency: + group: build-on-pr-${{ github.event.pull_request.number }} + cancel-in-progress: true + +jobs: + check-and-build: + runs-on: ubuntu-latest + + steps: + - name: Parse build command from PR description + id: parse-command + run: | + DESCRIPTION=$(cat <<'EOF' + ${{ github.event.pull_request.body }} + EOF + ) + if echo "$DESCRIPTION" | grep -q "build [a-zA-Z0-9_-]\+/[a-zA-Z0-9_-]\+/[a-zA-Z0-9_-]\+"; then + BUILD_PATH=$(echo "$DESCRIPTION" | grep -o "build [a-zA-Z0-9_-]\+/[a-zA-Z0-9_-]\+/[a-zA-Z0-9_-]\+" | head -1 | 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 }} + comment-author: "github-actions[bot]" + body-includes: "Build Results for" + + - 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 }} + comment-id: ${{ steps.find-comment.outputs.comment-id }} + body: | + ## Build Results for `${{ steps.parse-command.outputs.build_path }}` + + Build in progress... + + [Follow progress](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}) + 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 + + - 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.parse-command.outputs.build_requested == '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 }} + 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 }}` + + [Download artifacts](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}) + edit-mode: replace + + - name: Update comment on build failure + if: steps.parse-command.outputs.build_requested == 'true' && failure() + uses: peter-evans/create-or-update-comment@v3 + with: + comment-id: ${{ steps.start-comment.outputs.comment-id }} + issue-number: ${{ github.event.pull_request.number }} + body: | + ## Build Results for `${{ steps.parse-command.outputs.build_path }}` + + Build failed + + [Check logs](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}) + edit-mode: replace