From abfd78ced23f3329aa6a99611a224f2139d61b6c Mon Sep 17 00:00:00 2001 From: stktyagi Date: Sat, 14 Mar 2026 17:45:55 +0530 Subject: [PATCH 1/3] [chores] Added CI failure bot Added CI failure bot for netjsonconfig. --- .github/workflows/bot-ci-failure.yml | 83 ++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 .github/workflows/bot-ci-failure.yml diff --git a/.github/workflows/bot-ci-failure.yml b/.github/workflows/bot-ci-failure.yml new file mode 100644 index 000000000..05f500c0d --- /dev/null +++ b/.github/workflows/bot-ci-failure.yml @@ -0,0 +1,83 @@ +name: CI Failure Bot + +on: + workflow_run: + workflows: ["Netjsonconfig CI Build"] + types: + - completed + +permissions: + pull-requests: write + actions: read + contents: read + +concurrency: + group: ci-failure-${{ github.repository }}-${{ github.event.workflow_run.pull_requests[0].number || github.event.workflow_run.head_branch }} + cancel-in-progress: true + +jobs: + find-pr: + runs-on: ubuntu-latest + if: ${{ github.event.workflow_run.conclusion == 'failure' }} + outputs: + pr_number: ${{ steps.pr.outputs.number }} + pr_author: ${{ steps.pr.outputs.author }} + steps: + - name: Find PR Number + id: pr + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + REPO: ${{ github.repository }} + PR_NUMBER_PAYLOAD: ${{ github.event.workflow_run.pull_requests[0].number }} + EVENT_HEAD_SHA: ${{ github.event.workflow_run.head_sha }} + run: | + emit_pr() { + local pr_number="$1" + local pr_author + pr_author=$(gh pr view "$pr_number" --repo "$REPO" --json author --jq '.author.login' 2>/dev/null || echo "") + if [ -z "$pr_author" ]; then + echo "::warning::Could not fetch PR author for PR #$pr_number" + fi + echo "number=$pr_number" >> "$GITHUB_OUTPUT" + echo "author=$pr_author" >> "$GITHUB_OUTPUT" + } + PR_NUMBER="$PR_NUMBER_PAYLOAD" + if [ -n "$PR_NUMBER" ]; then + echo "Found PR #$PR_NUMBER from workflow payload." + emit_pr "$PR_NUMBER" + exit 0 + fi + HEAD_SHA="$EVENT_HEAD_SHA" + echo "Payload empty. Searching for PR via Commits API..." + PR_NUMBER=$(gh api repos/$REPO/commits/$HEAD_SHA/pulls -q '.[0].number' 2>/dev/null || true) + if [ -n "$PR_NUMBER" ] && [ "$PR_NUMBER" != "null" ]; then + echo "Found PR #$PR_NUMBER using Commits API." + emit_pr "$PR_NUMBER" + exit 0 + fi + echo "API lookup failed/empty. Scanning open PRs for matching head SHA..." + PR_NUMBER=$(gh pr list --repo "$REPO" --state open --limit 100 --json number,headRefOid --jq ".[] | select(.headRefOid == \"$HEAD_SHA\") | .number" | head -n 1) + if [ -n "$PR_NUMBER" ]; then + echo "Found PR #$PR_NUMBER by scanning open PRs." + emit_pr "$PR_NUMBER" + exit 0 + fi + echo "::warning::No open PR found. This workflow run might not be attached to an open PR." + exit 0 + + call-ci-failure-bot: + needs: find-pr + if: ${{ needs.find-pr.outputs.pr_number != '' }} + uses: openwisp/openwisp-utils/.github/workflows/reusable-bot-ci-failure.yml@master + with: + pr_number: ${{ needs.find-pr.outputs.pr_number }} + head_sha: ${{ github.event.workflow_run.head_sha }} + head_repo: ${{ github.event.workflow_run.head_repository.full_name }} + base_repo: ${{ github.repository }} + run_id: ${{ github.event.workflow_run.id }} + pr_author: ${{ needs.find-pr.outputs.pr_author }} + actor: ${{ github.event.workflow_run.actor.login }} + secrets: + GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }} + APP_ID: ${{ secrets.OPENWISP_BOT_APP_ID }} + PRIVATE_KEY: ${{ secrets.OPENWISP_BOT_PRIVATE_KEY }} From a47c3efa21dd57b94e15fd67730273c006cd1249 Mon Sep 17 00:00:00 2001 From: stktyagi Date: Sat, 14 Mar 2026 18:30:54 +0530 Subject: [PATCH 2/3] [chores] Followed principle of least privilege Moved pr write permission to caller from find-pr --- .github/workflows/bot-ci-failure.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/bot-ci-failure.yml b/.github/workflows/bot-ci-failure.yml index 05f500c0d..0710671f3 100644 --- a/.github/workflows/bot-ci-failure.yml +++ b/.github/workflows/bot-ci-failure.yml @@ -7,7 +7,7 @@ on: - completed permissions: - pull-requests: write + pull-requests: read actions: read contents: read @@ -36,7 +36,8 @@ jobs: local pr_author pr_author=$(gh pr view "$pr_number" --repo "$REPO" --json author --jq '.author.login' 2>/dev/null || echo "") if [ -z "$pr_author" ]; then - echo "::warning::Could not fetch PR author for PR #$pr_number" + pr_author="${{ github.event.workflow_run.actor.login }}" + echo "::warning::Could not fetch PR author for PR #$pr_number; falling back to @$pr_author" fi echo "number=$pr_number" >> "$GITHUB_OUTPUT" echo "author=$pr_author" >> "$GITHUB_OUTPUT" @@ -68,6 +69,10 @@ jobs: call-ci-failure-bot: needs: find-pr if: ${{ needs.find-pr.outputs.pr_number != '' }} + permissions: + actions: read + contents: read + pull-requests: write uses: openwisp/openwisp-utils/.github/workflows/reusable-bot-ci-failure.yml@master with: pr_number: ${{ needs.find-pr.outputs.pr_number }} From f5f23c46fd6844e9a5bc444956f64f7369eeff49 Mon Sep 17 00:00:00 2001 From: stktyagi Date: Tue, 24 Mar 2026 22:45:44 +0530 Subject: [PATCH 3/3] [chores] Improved scoping Updated ci failure bot for enhancements and scoping. --- .github/workflows/bot-ci-failure.yml | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/.github/workflows/bot-ci-failure.yml b/.github/workflows/bot-ci-failure.yml index 0710671f3..bb219d982 100644 --- a/.github/workflows/bot-ci-failure.yml +++ b/.github/workflows/bot-ci-failure.yml @@ -18,7 +18,7 @@ concurrency: jobs: find-pr: runs-on: ubuntu-latest - if: ${{ github.event.workflow_run.conclusion == 'failure' }} + if: ${{ github.event.workflow_run.conclusion == 'failure' && github.event.workflow_run.event == 'pull_request' }} outputs: pr_number: ${{ steps.pr.outputs.number }} pr_author: ${{ steps.pr.outputs.author }} @@ -34,10 +34,9 @@ jobs: emit_pr() { local pr_number="$1" local pr_author - pr_author=$(gh pr view "$pr_number" --repo "$REPO" --json author --jq '.author.login' 2>/dev/null || echo "") - if [ -z "$pr_author" ]; then - pr_author="${{ github.event.workflow_run.actor.login }}" - echo "::warning::Could not fetch PR author for PR #$pr_number; falling back to @$pr_author" + pr_author=$(gh pr view "$pr_number" --repo "$REPO" --json author --jq '.author.login // empty' 2>/dev/null || echo "") + if [ -z "$pr_author" ] || [ "$pr_author" = "null" ]; then + echo "::warning::Could not fetch PR author for PR #$pr_number" fi echo "number=$pr_number" >> "$GITHUB_OUTPUT" echo "author=$pr_author" >> "$GITHUB_OUTPUT" @@ -70,9 +69,9 @@ jobs: needs: find-pr if: ${{ needs.find-pr.outputs.pr_number != '' }} permissions: - actions: read - contents: read pull-requests: write + actions: write + contents: read uses: openwisp/openwisp-utils/.github/workflows/reusable-bot-ci-failure.yml@master with: pr_number: ${{ needs.find-pr.outputs.pr_number }}