fix(ci): correct merge-queue context + delete obsolete auto-promote (mcp-server) #46

Merged
agent-dev-a merged 1 commits from fix/mcp-server-merge-queue-plus-cleanup into main 2026-06-07 22:03:33 +00:00
2 changed files with 6 additions and 125 deletions
-119
View File
@@ -1,119 +0,0 @@
name: Auto-promote staging → main
# Fast-forwards `main` to `staging` when staging is strictly ahead (main
# is an ancestor). Eliminates the manual sync-PR round for non-critical
# repos.
#
# Gate handling:
# - If the repo has required_status_checks configured AND the API
# returns them, all must be SUCCESS on the staging HEAD commit.
# - If no gates are configured (or the API 403s on a private free-tier
# repo), `--ff-only` is the sole safety. It refuses if main has
# independent commits staging doesn't contain.
#
# Excluded by policy: molecule-core + molecule-controlplane. Those two
# stay manual per CEO directive 2026-04-24.
#
# Safety:
# - Only fires on push to staging (PRs into staging don't promote)
# - `--ff-only` refuses if main has diverged (hotfix landed directly)
# - Promote commit goes through GITHUB_TOKEN; shows up in git log as
# a deliberate act
on:
push:
branches: [staging]
workflow_dispatch:
permissions:
contents: write
statuses: read
jobs:
promote:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
- name: Check required gates (if configured) on staging HEAD
id: gates
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REPO: ${{ github.repository }}
HEAD_SHA: ${{ github.sha }}
shell: bash
run: |
set -euo pipefail
# Try to read required gates from branch protection. Free-tier
# private repos may 403; handle that gracefully.
GATES_JSON=$(gh api "repos/${REPO}/branches/staging/protection/required_status_checks" 2>/dev/null || echo '{}')
GATES=$(echo "${GATES_JSON}" | jq -r '.contexts[]?' 2>/dev/null || true)
if [ -z "$GATES" ]; then
echo "No required gates configured (or API inaccessible). Relying on --ff-only safety."
echo "ok=true" >> "$GITHUB_OUTPUT"
exit 0
fi
echo "Required gates on staging:"
echo "${GATES}" | sed 's/^/ - /'
ALL_GREEN=true
while IFS= read -r gate; do
[ -z "$gate" ] && continue
conclusion=$(gh api "repos/${REPO}/commits/${HEAD_SHA}/check-runs" \
--jq "[.check_runs[] | select(.name == \"${gate}\")] | sort_by(.completed_at) | last.conclusion" \
2>/dev/null || echo "")
if [ -z "$conclusion" ] || [ "$conclusion" = "null" ]; then
conclusion=$(gh api "repos/${REPO}/commits/${HEAD_SHA}/status" \
--jq "[.statuses[] | select(.context == \"${gate}\")] | sort_by(.updated_at) | last.state" \
2>/dev/null || echo "")
fi
if [ "$conclusion" != "success" ] && [ "$conclusion" != "SUCCESS" ]; then
echo "::warning::Gate '${gate}' is '${conclusion:-missing}' on ${HEAD_SHA} — skipping promote."
ALL_GREEN=false
else
echo " ✓ ${gate}: success"
fi
done <<< "$GATES"
echo "ok=${ALL_GREEN}" >> "$GITHUB_OUTPUT"
- name: Fast-forward main to staging
if: steps.gates.outputs.ok == 'true'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
shell: bash
run: |
set -euo pipefail
git config user.email "actions@github.com"
git config user.name "github-actions[bot]"
# staging is the checked-out branch (workflow fires on push to
# staging). Can't fetch into it. Fetch main into a local main.
git fetch origin main
git checkout -B main origin/main
# Check if main is already at or ahead of origin/staging.
if git merge-base --is-ancestor origin/staging main 2>/dev/null; then
echo "main already contains staging; nothing to promote."
exit 0
fi
# --ff-only refuses if main has independent commits not on
# staging (divergence — hotfix direct to main). Human resolves.
if ! git merge --ff-only origin/staging 2>&1; then
echo "::warning::main has diverged from staging — refusing fast-forward. Resolve manually (likely a direct-to-main commit exists that staging doesn't have)."
exit 0
fi
git push origin main
echo "::notice::Promoted: main is now at $(git rev-parse --short HEAD)"
+6 -6
View File
@@ -68,13 +68,13 @@ jobs:
# (fail-closed). REQUIRED_APPROVALS below is only a fallback used when
# branch protection does not specify required_approvals.
REQUIRED_APPROVALS: "2"
# Push-side required contexts. Checking CI / all-required (push)
# Push-side required contexts. Checking CI / test (push)
# explicitly instead of the combined state avoids false-pause when
# non-blocking jobs (continue-on-error: true) have failed — those
# failures pollute combined state but do not gate merges.
# NOTE: the event-suffixed context name is intentional — branch protection
# MUST require `CI / all-required (pull_request)` (with suffix), NOT the
# bare `CI / all-required`. Gitea treats absent contexts as pending, not
# skipped; requiring the bare name silently blocks all merges (issue #1473).
PUSH_REQUIRED_CONTEXTS: CI / all-required (push)
# NOTE: molecule-mcp-server's CI workflow (.gitea/workflows/ci.yml)
# has a single job named "test", not "all-required" (that name is
# specific to molecule-core's aggregated sentinel). The context
# must match the actual job key or the queue will pause forever.
PUSH_REQUIRED_CONTEXTS: CI / test (push)
run: python3 molecule-core/.gitea/scripts/gitea-merge-queue.py