mirror of
https://github.com/basicmachines-co/basic-memory
synced 2026-06-21 13:47:35 +00:00
d8c9156ffd
Remove the Codex LLM review and the per-PR image job — both spent API tokens on every Bossbot run and the connector review already covers code review. The gate is now fully deterministic: Tests passed for the head SHA, non-draft, trusted author, zero unresolved review threads. Prompt/schema files removed; guard tests updated to forbid openai/codex-action and image generation from reappearing. Signed-off-by: phernandez <paul@basicmachines.co>
194 lines
7.3 KiB
YAML
194 lines
7.3 KiB
YAML
name: BM Bossbot
|
|
|
|
"on":
|
|
workflow_run:
|
|
workflows:
|
|
- Tests
|
|
types:
|
|
- completed
|
|
workflow_dispatch:
|
|
inputs:
|
|
pr_number:
|
|
description: Pull request number to review
|
|
required: true
|
|
# Review-thread activity re-evaluates the approval status without re-running
|
|
# the full LLM review: new feedback flips the gate to failure, resolving the
|
|
# last thread restores a previously earned approval for the same head SHA.
|
|
pull_request_review:
|
|
types:
|
|
- submitted
|
|
pull_request_review_comment:
|
|
types:
|
|
- created
|
|
pull_request_review_thread:
|
|
types:
|
|
- resolved
|
|
- unresolved
|
|
|
|
permissions:
|
|
contents: read
|
|
pull-requests: write
|
|
statuses: write
|
|
issues: read
|
|
|
|
env:
|
|
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"
|
|
BM_BOSSBOT_STATUS_CONTEXT: "BM Bossbot Approval"
|
|
|
|
jobs:
|
|
review:
|
|
name: BM Bossbot Review
|
|
# Job-level concurrency (not workflow-level): thread-recheck events for the
|
|
# same PR must never cancel an in-flight review run, and vice versa.
|
|
concurrency:
|
|
group: bm-bossbot-review-${{ github.event.workflow_run.pull_requests[0].number || inputs.pr_number }}
|
|
cancel-in-progress: true
|
|
if: |
|
|
github.event_name == 'workflow_dispatch' ||
|
|
(
|
|
github.event_name == 'workflow_run' &&
|
|
github.event.workflow_run.conclusion == 'success' &&
|
|
github.event.workflow_run.pull_requests[0].number != ''
|
|
)
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
pr_number: ${{ steps.pr.outputs.pr_number }}
|
|
should_review: ${{ steps.pr.outputs.should_review }}
|
|
|
|
steps:
|
|
- name: Checkout trusted base ref
|
|
uses: actions/checkout@v6
|
|
with:
|
|
ref: ${{ github.event.repository.default_branch }}
|
|
fetch-depth: 1
|
|
|
|
- name: Set up uv
|
|
uses: astral-sh/setup-uv@v3
|
|
|
|
- name: Normalize PR event
|
|
id: pr
|
|
env:
|
|
GH_TOKEN: ${{ github.token }}
|
|
run: |
|
|
set -euo pipefail
|
|
event_file="${RUNNER_TEMP}/bm-bossbot-event.json"
|
|
should_review=true
|
|
|
|
if [ "${GITHUB_EVENT_NAME}" = "workflow_dispatch" ]; then
|
|
pr_number="${{ inputs.pr_number }}"
|
|
tested_sha=""
|
|
else
|
|
pr_number="$(jq -r '.workflow_run.pull_requests[0].number // ""' "${GITHUB_EVENT_PATH}")"
|
|
tested_sha="$(jq -r '.workflow_run.head_sha // ""' "${GITHUB_EVENT_PATH}")"
|
|
fi
|
|
|
|
gh api "repos/${GITHUB_REPOSITORY}/pulls/${pr_number}" > "${RUNNER_TEMP}/pull.json"
|
|
current_head_sha="$(jq -r '.head.sha' "${RUNNER_TEMP}/pull.json")"
|
|
draft="$(jq -r '.draft' "${RUNNER_TEMP}/pull.json")"
|
|
|
|
if [ "${GITHUB_EVENT_NAME}" = "workflow_dispatch" ]; then
|
|
tests_run_id="$(
|
|
gh api -X GET "repos/${GITHUB_REPOSITORY}/actions/workflows/test.yml/runs" \
|
|
-f event=push \
|
|
-f head_sha="${current_head_sha}" \
|
|
-f status=completed \
|
|
--jq '[.workflow_runs[] | select(.conclusion == "success")][0].id // ""'
|
|
)"
|
|
if [ -z "${tests_run_id}" ]; then
|
|
should_review=false
|
|
echo "BM Bossbot skipped PR ${pr_number}: no successful Tests workflow for ${current_head_sha}."
|
|
fi
|
|
fi
|
|
|
|
if [ "${draft}" = "true" ]; then
|
|
should_review=false
|
|
echo "BM Bossbot skipped PR ${pr_number}: draft pull request."
|
|
fi
|
|
|
|
if [ -n "${tested_sha}" ] && [ "${tested_sha}" != "${current_head_sha}" ]; then
|
|
should_review=false
|
|
echo "BM Bossbot skipped PR ${pr_number}: Tests passed for ${tested_sha}, but current head is ${current_head_sha}."
|
|
fi
|
|
|
|
jq --arg repo "${GITHUB_REPOSITORY}" \
|
|
'{repository:{full_name:$repo}, pull_request:{number:.number,title:.title,body:(.body // ""),html_url:.html_url,head:{sha:.head.sha,ref:.head.ref},base:{ref:.base.ref,sha:.base.sha},author_association:.author_association,draft:.draft}}' \
|
|
"${RUNNER_TEMP}/pull.json" > "${event_file}"
|
|
|
|
echo "event_file=${event_file}" >> "${GITHUB_OUTPUT}"
|
|
echo "pr_number=$(jq -r '.pull_request.number' "${event_file}")" >> "${GITHUB_OUTPUT}"
|
|
echo "head_sha=$(jq -r '.pull_request.head.sha' "${event_file}")" >> "${GITHUB_OUTPUT}"
|
|
echo "head_ref=$(jq -r '.pull_request.head.ref' "${event_file}")" >> "${GITHUB_OUTPUT}"
|
|
echo "author_association=$(jq -r '.pull_request.author_association // ""' "${event_file}")" >> "${GITHUB_OUTPUT}"
|
|
echo "tested_sha=${tested_sha}" >> "${GITHUB_OUTPUT}"
|
|
echo "should_review=${should_review}" >> "${GITHUB_OUTPUT}"
|
|
|
|
- name: Classify PR author
|
|
id: trust
|
|
if: steps.pr.outputs.should_review == 'true'
|
|
env:
|
|
AUTHOR_ASSOCIATION: ${{ steps.pr.outputs.author_association }}
|
|
run: |
|
|
set -euo pipefail
|
|
case "${AUTHOR_ASSOCIATION}" in
|
|
OWNER|MEMBER|COLLABORATOR)
|
|
trusted_author=true
|
|
;;
|
|
*)
|
|
trusted_author=false
|
|
;;
|
|
esac
|
|
echo "trusted_author=${trusted_author}" >> "${GITHUB_OUTPUT}"
|
|
echo "author_association=${AUTHOR_ASSOCIATION}" >> "${GITHUB_OUTPUT}"
|
|
|
|
- name: Mark BM Bossbot approval pending
|
|
if: steps.pr.outputs.should_review == 'true'
|
|
env:
|
|
GITHUB_TOKEN: ${{ github.token }}
|
|
run: |
|
|
uv run --script scripts/bm_bossbot_status.py pending \
|
|
--event "${{ steps.pr.outputs.event_file }}" \
|
|
--repo "${GITHUB_REPOSITORY}" \
|
|
--run-url "${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}"
|
|
|
|
- name: Finalize BM Bossbot approval
|
|
if: always() && steps.pr.outputs.should_review == 'true'
|
|
env:
|
|
GITHUB_TOKEN: ${{ github.token }}
|
|
run: |
|
|
uv run --script scripts/bm_bossbot_status.py finalize \
|
|
--event "${{ steps.pr.outputs.event_file }}" \
|
|
--trusted "${{ steps.trust.outputs.trusted_author }}" \
|
|
--repo "${GITHUB_REPOSITORY}" \
|
|
--run-url "${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}"
|
|
|
|
recheck:
|
|
name: BM Bossbot Thread Recheck
|
|
if: |
|
|
github.event_name == 'pull_request_review' ||
|
|
github.event_name == 'pull_request_review_comment' ||
|
|
github.event_name == 'pull_request_review_thread'
|
|
runs-on: ubuntu-latest
|
|
# Job-level concurrency: collapse bursts of thread events for one PR while
|
|
# staying isolated from the review job's group so neither cancels the other.
|
|
concurrency:
|
|
group: bm-bossbot-recheck-${{ github.event.pull_request.number }}
|
|
cancel-in-progress: true
|
|
steps:
|
|
- name: Checkout trusted base ref
|
|
uses: actions/checkout@v6
|
|
with:
|
|
ref: ${{ github.event.repository.default_branch }}
|
|
fetch-depth: 1
|
|
|
|
- name: Set up uv
|
|
uses: astral-sh/setup-uv@v3
|
|
|
|
- name: Re-evaluate approval from review-thread state
|
|
env:
|
|
GITHUB_TOKEN: ${{ github.token }}
|
|
run: |
|
|
uv run --script scripts/bm_bossbot_status.py recheck \
|
|
--pr-number "${{ github.event.pull_request.number }}" \
|
|
--repo "${GITHUB_REPOSITORY}" \
|
|
--run-url "${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}"
|