diff --git a/.gitea/workflows/mcp-external-artifact-mirror.yaml b/.gitea/workflows/mcp-external-artifact-mirror.yaml index 4017c8f30..1fa6be8da 100644 --- a/.gitea/workflows/mcp-external-artifact-mirror.yaml +++ b/.gitea/workflows/mcp-external-artifact-mirror.yaml @@ -3,7 +3,7 @@ # This Gitea-only lane accepts executable bytes from exact npm registry URLs in # committed policy, verifies them, mirrors a scratch OCI data bundle to Harbor, # independently reads the digest back without starting a container, then writes -# the two receipts to Gitea main with a normal non-force push. It never installs +# the two receipts to a Gitea audit branch with a normal non-force push. It never installs # or starts the MCP, opens a browser, writes external content to RAG, or changes a # production route. @@ -26,12 +26,13 @@ on: concurrency: group: awoooi-mcp-external-artifact-mirror - cancel-in-progress: false + cancel-in-progress: true env: GITEA_SOURCE_URL: http://192.168.0.110:3001/wooo/awoooi.git HARBOR_REGISTRY: registry.wooo.work POLICY_PATH: config/mcp/playwright-mcp-artifact-policy.json + RECEIPT_BRANCH: mcp-artifact-receipts CONTROLLER_RECEIPT_PATH: docs/operations/external-mcp-artifacts/playwright-mcp-0.0.78-controller.snapshot.json VERIFIER_RECEIPT_PATH: docs/operations/external-mcp-artifacts/playwright-mcp-0.0.78-verifier.snapshot.json @@ -185,7 +186,7 @@ jobs: print("production_route_changed=false") PY - - name: Commit verified receipts to Gitea main + - name: Commit verified receipts to Gitea audit branch env: CD_PUSH_TOKEN: ${{ secrets.CD_PUSH_TOKEN }} run: | @@ -230,14 +231,18 @@ jobs: git remote add gitea "${GITEA_SOURCE_URL}" for attempt in 1 2 3; do - git fetch --no-tags --depth=100 gitea main - if ! git merge --no-edit gitea/main; then - git merge --abort || true - echo "BLOCKER receipt_writeback_merge_conflict" - exit 1 + if git ls-remote --exit-code --heads gitea \ + "refs/heads/${RECEIPT_BRANCH}" >/dev/null 2>&1; then + git fetch --no-tags --depth=100 gitea "${RECEIPT_BRANCH}" + if ! git merge --no-edit FETCH_HEAD; then + git merge --abort || true + echo "BLOCKER receipt_writeback_merge_conflict" + exit 1 + fi fi - if git push gitea HEAD:main; then - echo "receipt_writeback=verified_normal_push" + if git push gitea "HEAD:refs/heads/${RECEIPT_BRANCH}"; then + echo "receipt_writeback=verified_audit_branch_normal_push" + echo "receipt_branch=${RECEIPT_BRANCH}" echo "receipt_commit_sha=$(git rev-parse HEAD)" exit 0 fi diff --git a/scripts/security/tests/test_external_mcp_artifact_controller.py b/scripts/security/tests/test_external_mcp_artifact_controller.py index cfce6178c..273b68ef6 100644 --- a/scripts/security/tests/test_external_mcp_artifact_controller.py +++ b/scripts/security/tests/test_external_mcp_artifact_controller.py @@ -123,13 +123,16 @@ class ExternalMcpArtifactControllerTest(unittest.TestCase): self.assertNotIn("@latest", lowered) self.assertNotIn(":latest", lowered) self.assertNotIn("git push --force", lowered) + self.assertIn("cancel-in-progress: true", raw) self.assertIn("runs-on: awoooi-non110-host", raw) self.assertIn("docker login", raw) self.assertIn("--password-stdin", raw) self.assertIn("docker logout", raw) self.assertIn("verify_external_mcp_artifact_receipt.py", raw) - self.assertIn("git merge --no-edit gitea/main", raw) - self.assertIn("git push gitea HEAD:main", raw) + self.assertIn("RECEIPT_BRANCH: mcp-artifact-receipts", raw) + self.assertIn('git merge --no-edit FETCH_HEAD', raw) + self.assertIn('HEAD:refs/heads/${RECEIPT_BRANCH}', raw) + self.assertNotIn("git push gitea HEAD:main", raw) self.assertIn('cron: "13 2 * * 3"', raw) def test_dependency_closure_rejects_drift(self) -> None: