From 7363a1985131508c42c521569e12843b777fb2c7 Mon Sep 17 00:00:00 2001 From: Bulat Yapparov Date: Mon, 14 Sep 2026 18:32:19 +0100 Subject: [PATCH 1/3] chore: remove automatic AI review trigger --- .github/workflows/code-review.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/code-review.yml b/.github/workflows/code-review.yml index c117f05..3489637 100644 --- a/.github/workflows/code-review.yml +++ b/.github/workflows/code-review.yml @@ -1,8 +1,6 @@ name: Aictrl Review on: - pull_request: - branches: [main, master] workflow_dispatch: concurrency: From 38210c5aa5b5a7ee6f7e7d91eedf456c21213a44 Mon Sep 17 00:00:00 2001 From: Bulat Yapparov Date: Mon, 14 Sep 2026 18:47:50 +0100 Subject: [PATCH 2/3] fix: repair manual AI review dispatch --- .github/workflows/code-review.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/code-review.yml b/.github/workflows/code-review.yml index 3489637..84926e2 100644 --- a/.github/workflows/code-review.yml +++ b/.github/workflows/code-review.yml @@ -1,5 +1,8 @@ name: Aictrl Review +# Policy: AI review is opt-in and advisory. Maintainers dispatch this workflow for +# PRs that need it; maintainer review plus the standard CI and CodeQL checks remain +# the merge-quality controls. on: workflow_dispatch: @@ -41,6 +44,13 @@ jobs: fi echo "Found PR #$PR_NUMBER for branch $BRANCH" echo "PR_NUMBER=$PR_NUMBER" >> $GITHUB_ENV + + PR_BASE_REF=$(gh pr view "$PR_NUMBER" --json baseRefName --jq '.baseRefName') + if [ -z "$PR_BASE_REF" ]; then + echo "Could not determine the base branch for PR #$PR_NUMBER." + exit 1 + fi + echo "PR_BASE_REF=$PR_BASE_REF" >> $GITHUB_ENV fi echo "Checking if SHA $PR_SHA was already reviewed..." From f8c294e49c28347e0dceffae37a92f506f664074 Mon Sep 17 00:00:00 2001 From: Bulat Yapparov Date: Mon, 14 Sep 2026 19:22:57 +0100 Subject: [PATCH 3/3] fix: harden manual AI review workflow --- .github/workflows/code-review.yml | 62 ++++++++++++++++++++++--------- 1 file changed, 45 insertions(+), 17 deletions(-) diff --git a/.github/workflows/code-review.yml b/.github/workflows/code-review.yml index 84926e2..fc5c9cf 100644 --- a/.github/workflows/code-review.yml +++ b/.github/workflows/code-review.yml @@ -1,13 +1,19 @@ name: Aictrl Review # Policy: AI review is opt-in and advisory. Maintainers dispatch this workflow for -# PRs that need it; maintainer review plus the standard CI and CodeQL checks remain -# the merge-quality controls. +# PRs that need it; maintainer review plus the standard CI checks remain the +# merge-quality controls. Set pr_number to review a fork PR or a PR other than the +# one associated with the selected base-repository ref. on: workflow_dispatch: + inputs: + pr_number: + description: PR number to review (required for fork PRs) + required: false + type: string concurrency: - group: aictrl-review-${{ github.event.pull_request.number || github.ref }} + group: aictrl-review-${{ inputs.pr_number || github.ref }} cancel-in-progress: true jobs: @@ -19,10 +25,7 @@ jobs: pull-requests: write issues: write env: - PR_SHA: ${{ github.event.pull_request.head.sha || github.sha }} - PR_NUMBER: ${{ github.event.pull_request.number }} - PR_BASE_REF: ${{ github.event.pull_request.base.ref }} - IS_MANUAL: ${{ github.event_name == 'workflow_dispatch' }} + PR_NUMBER: ${{ inputs.pr_number }} steps: - name: Checkout repository uses: actions/checkout@v6 @@ -34,6 +37,11 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | + if [ -n "$PR_NUMBER" ] && ! [[ "$PR_NUMBER" =~ ^[0-9]+$ ]]; then + echo "PR number must contain digits only." + exit 1 + fi + if [ -z "$PR_NUMBER" ]; then BRANCH="${GITHUB_HEAD_REF:-${GITHUB_REF_NAME}}" PR_NUMBER=$(gh pr list --head "$BRANCH" --json number --jq '.[0].number' 2>/dev/null || true) @@ -43,16 +51,32 @@ jobs: exit 0 fi echo "Found PR #$PR_NUMBER for branch $BRANCH" - echo "PR_NUMBER=$PR_NUMBER" >> $GITHUB_ENV + fi - PR_BASE_REF=$(gh pr view "$PR_NUMBER" --json baseRefName --jq '.baseRefName') - if [ -z "$PR_BASE_REF" ]; then - echo "Could not determine the base branch for PR #$PR_NUMBER." - exit 1 - fi - echo "PR_BASE_REF=$PR_BASE_REF" >> $GITHUB_ENV + PR_DATA=$(gh pr view "$PR_NUMBER" --json baseRefName,headRefOid --jq '[.baseRefName, .headRefOid] | @tsv' 2>/dev/null || true) + IFS=$'\t' read -r PR_BASE_REF PR_SHA <<< "$PR_DATA" + + if [ -z "$PR_BASE_REF" ] || [ -z "$PR_SHA" ]; then + echo "Could not determine the base branch and head SHA for PR #$PR_NUMBER." + exit 1 + fi + if ! [[ "$PR_BASE_REF" =~ ^[A-Za-z0-9._/-]+$ ]]; then + echo "PR #$PR_NUMBER has an unsafe base branch name." + exit 1 + fi + if ! git rev-parse --verify "refs/remotes/origin/$PR_BASE_REF^{commit}" >/dev/null; then + echo "Base branch '$PR_BASE_REF' does not resolve to an origin commit." + exit 1 + fi + if ! [[ "$PR_SHA" =~ ^[0-9a-f]{40}$ ]]; then + echo "PR #$PR_NUMBER has an invalid head SHA." + exit 1 fi + echo "PR_NUMBER=$PR_NUMBER" >> "$GITHUB_ENV" + echo "PR_BASE_REF=$PR_BASE_REF" >> "$GITHUB_ENV" + echo "PR_SHA=$PR_SHA" >> "$GITHUB_ENV" + echo "Checking if SHA $PR_SHA was already reviewed..." REVIEW_COMMENTS=$(gh pr view "$PR_NUMBER" --json comments --jq '.comments[].body' | grep -c "Reviewed SHA:" || true) LAST_REVIEW_SHA=$(gh pr view "$PR_NUMBER" --json comments --jq '.comments[].body' | grep -o "Reviewed SHA: [a-f0-9]\{40\}" | tail -n 1 | cut -d' ' -f3) @@ -63,14 +87,18 @@ jobs: exit 0 fi - if [ "$REVIEW_COMMENTS" -ge 2 ] && [ "$IS_MANUAL" != "true" ]; then - echo "PR already has $REVIEW_COMMENTS AI reviews. Skipping (use workflow_dispatch to force)." + if [ "$REVIEW_COMMENTS" -ge 2 ]; then + echo "PR already has $REVIEW_COMMENTS AI reviews. Skipping because the review cap is 2." echo "skip=true" >> $GITHUB_OUTPUT exit 0 fi echo "Checking changed files..." - CODE_CHANGES=$(git diff --name-only "origin/$PR_BASE_REF...$PR_SHA" | grep -E '\.(ts|js|json|sh|yml|yaml)$' | grep -vE '^docs/|.*\.md$' || true) + if ! CHANGED_FILES=$(gh pr diff "$PR_NUMBER" --name-only); then + echo "Could not load changed files for PR #$PR_NUMBER." + exit 1 + fi + CODE_CHANGES=$(printf '%s\n' "$CHANGED_FILES" | grep -E '\.(ts|js|json|sh|yml|yaml)$' | grep -vE '^docs/|.*\.md$' || true) if [ -z "$CODE_CHANGES" ]; then echo "No actual code changes detected. Skipping review."