fix(ci): make MCP audit writeback repeatable
This commit is contained in:
290
scripts/ci/tests/test_write_gitea_audit_receipts.py
Normal file
290
scripts/ci/tests/test_write_gitea_audit_receipts.py
Normal file
@@ -0,0 +1,290 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Functional tests for linear Gitea audit-branch receipt writeback."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[3]
|
||||
SCRIPT = ROOT / "scripts/ci/write-gitea-audit-receipts.sh"
|
||||
CONTROLLER_TARGET = (
|
||||
"docs/operations/external-mcp-replays/fixture-controller.snapshot.json"
|
||||
)
|
||||
VERIFIER_TARGET = (
|
||||
"docs/operations/external-mcp-replays/fixture-verifier.snapshot.json"
|
||||
)
|
||||
|
||||
|
||||
def _run(command: list[str], *, cwd: Path, env: dict[str, str] | None = None) -> str:
|
||||
completed = subprocess.run(
|
||||
command,
|
||||
cwd=cwd,
|
||||
env=env,
|
||||
check=False,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=30,
|
||||
)
|
||||
if completed.returncode != 0:
|
||||
raise AssertionError(
|
||||
f"command failed: {command}\nstdout={completed.stdout}\nstderr={completed.stderr}"
|
||||
)
|
||||
return completed.stdout.strip()
|
||||
|
||||
|
||||
def _receipt(schema: str, run_id: str) -> dict:
|
||||
return {
|
||||
"schema_version": schema,
|
||||
"run_id": run_id,
|
||||
"trace_id": f"mcp-replay-{run_id}",
|
||||
"work_item_id": "MCP-REPLAY-PLAYWRIGHT-001",
|
||||
"status": "fixture_verified",
|
||||
}
|
||||
|
||||
|
||||
def _write_receipts(directory: Path, run_id: str) -> tuple[Path, Path]:
|
||||
controller = directory / "controller.json"
|
||||
verifier = directory / "verifier.json"
|
||||
controller.write_text(
|
||||
json.dumps(
|
||||
_receipt("awoooi_external_mcp_replay_receipt_v1", run_id),
|
||||
sort_keys=True,
|
||||
)
|
||||
+ "\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
verifier.write_text(
|
||||
json.dumps(
|
||||
_receipt("awoooi_external_mcp_replay_verifier_receipt_v1", run_id),
|
||||
sort_keys=True,
|
||||
)
|
||||
+ "\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
return controller, verifier
|
||||
|
||||
|
||||
class AuditReceiptWritebackTests(unittest.TestCase):
|
||||
def setUp(self) -> None:
|
||||
self.temp = tempfile.TemporaryDirectory()
|
||||
self.root = Path(self.temp.name)
|
||||
self.remote = self.root / "remote.git"
|
||||
self.seed = self.root / "seed"
|
||||
_run(["git", "init", "--bare", str(self.remote)], cwd=self.root)
|
||||
self.seed.mkdir()
|
||||
_run(["git", "init"], cwd=self.seed)
|
||||
_run(["git", "config", "user.email", "fixture@awoooi.internal"], cwd=self.seed)
|
||||
_run(["git", "config", "user.name", "Fixture"], cwd=self.seed)
|
||||
(self.seed / "base.txt").write_text("base\n", encoding="utf-8")
|
||||
_run(["git", "add", "base.txt"], cwd=self.seed)
|
||||
_run(["git", "commit", "-m", "base"], cwd=self.seed)
|
||||
_run(["git", "branch", "-M", "main"], cwd=self.seed)
|
||||
_run(["git", "remote", "add", "origin", f"file://{self.remote}"], cwd=self.seed)
|
||||
_run(["git", "push", "origin", "main"], cwd=self.seed)
|
||||
|
||||
_run(["git", "checkout", "-b", "mcp-replay-receipts"], cwd=self.seed)
|
||||
initial_controller, initial_verifier = _write_receipts(
|
||||
self.seed, "00000000-0000-4000-8000-000000000000"
|
||||
)
|
||||
(self.seed / CONTROLLER_TARGET).parent.mkdir(parents=True)
|
||||
(self.seed / CONTROLLER_TARGET).write_bytes(initial_controller.read_bytes())
|
||||
(self.seed / VERIFIER_TARGET).write_bytes(initial_verifier.read_bytes())
|
||||
_run(["git", "add", "docs"], cwd=self.seed)
|
||||
_run(["git", "commit", "-m", "initial audit receipt"], cwd=self.seed)
|
||||
_run(["git", "push", "origin", "mcp-replay-receipts"], cwd=self.seed)
|
||||
self.initial_audit_sha = _run(["git", "rev-parse", "HEAD"], cwd=self.seed)
|
||||
|
||||
_run(["git", "checkout", "main"], cwd=self.seed)
|
||||
(self.seed / "main-only.txt").write_text("new main\n", encoding="utf-8")
|
||||
_run(["git", "add", "main-only.txt"], cwd=self.seed)
|
||||
_run(["git", "commit", "-m", "advance main"], cwd=self.seed)
|
||||
_run(["git", "push", "origin", "main"], cwd=self.seed)
|
||||
|
||||
def tearDown(self) -> None:
|
||||
self.temp.cleanup()
|
||||
|
||||
def _fresh_main_clone(self, name: str) -> Path:
|
||||
clone = self.root / name
|
||||
_run(
|
||||
[
|
||||
"git",
|
||||
"clone",
|
||||
"--depth=1",
|
||||
"--branch",
|
||||
"main",
|
||||
f"file://{self.remote}",
|
||||
str(clone),
|
||||
],
|
||||
cwd=self.root,
|
||||
)
|
||||
_run(["git", "config", "user.email", "fixture@awoooi.internal"], cwd=clone)
|
||||
_run(["git", "config", "user.name", "Fixture"], cwd=clone)
|
||||
return clone
|
||||
|
||||
def _apply(self, clone: Path, run_id: str) -> str:
|
||||
source_dir = self.root / f"source-{run_id}"
|
||||
source_dir.mkdir()
|
||||
controller, verifier = _write_receipts(source_dir, run_id)
|
||||
env = {
|
||||
**os.environ,
|
||||
"GIT_TERMINAL_PROMPT": "0",
|
||||
"GITEA_AUDIT_TEST_FILE_REMOTE": "1",
|
||||
"GITEA_AUDIT_REMOTE_URL": f"file://{self.remote}",
|
||||
"GITEA_AUDIT_BRANCH": "mcp-replay-receipts",
|
||||
"GITEA_AUDIT_CONTROLLER_SOURCE": str(controller),
|
||||
"GITEA_AUDIT_VERIFIER_SOURCE": str(verifier),
|
||||
"GITEA_AUDIT_CONTROLLER_TARGET": CONTROLLER_TARGET,
|
||||
"GITEA_AUDIT_VERIFIER_TARGET": VERIFIER_TARGET,
|
||||
"GITEA_AUDIT_COMMIT_MESSAGE": "fixture audit receipt",
|
||||
}
|
||||
return _run(["bash", str(SCRIPT)], cwd=clone, env=env)
|
||||
|
||||
def test_second_and_third_writebacks_are_linear_normal_pushes(self) -> None:
|
||||
first_clone = self._fresh_main_clone("clone-one")
|
||||
first_output = self._apply(
|
||||
first_clone, "11111111-1111-4111-8111-111111111111"
|
||||
)
|
||||
self.assertIn("receipt_writeback=verified_audit_branch_normal_push", first_output)
|
||||
first_sha = _run(
|
||||
["git", "--git-dir", str(self.remote), "rev-parse", "mcp-replay-receipts"],
|
||||
cwd=self.root,
|
||||
)
|
||||
first_parent = _run(
|
||||
["git", "--git-dir", str(self.remote), "rev-parse", f"{first_sha}^"],
|
||||
cwd=self.root,
|
||||
)
|
||||
self.assertEqual(first_parent, self.initial_audit_sha)
|
||||
|
||||
second_clone = self._fresh_main_clone("clone-two")
|
||||
second_output = self._apply(
|
||||
second_clone, "22222222-2222-4222-8222-222222222222"
|
||||
)
|
||||
self.assertIn("receipt_writeback=verified_audit_branch_normal_push", second_output)
|
||||
second_sha = _run(
|
||||
["git", "--git-dir", str(self.remote), "rev-parse", "mcp-replay-receipts"],
|
||||
cwd=self.root,
|
||||
)
|
||||
second_parent = _run(
|
||||
["git", "--git-dir", str(self.remote), "rev-parse", f"{second_sha}^"],
|
||||
cwd=self.root,
|
||||
)
|
||||
self.assertEqual(second_parent, first_sha)
|
||||
latest = _run(
|
||||
[
|
||||
"git",
|
||||
"--git-dir",
|
||||
str(self.remote),
|
||||
"show",
|
||||
f"mcp-replay-receipts:{CONTROLLER_TARGET}",
|
||||
],
|
||||
cwd=self.root,
|
||||
)
|
||||
self.assertEqual(
|
||||
json.loads(latest)["run_id"],
|
||||
"22222222-2222-4222-8222-222222222222",
|
||||
)
|
||||
|
||||
def test_non_allowlisted_branch_is_rejected_without_push(self) -> None:
|
||||
clone = self._fresh_main_clone("clone-rejected")
|
||||
source_dir = self.root / "source-rejected"
|
||||
source_dir.mkdir()
|
||||
controller, verifier = _write_receipts(
|
||||
source_dir, "33333333-3333-4333-8333-333333333333"
|
||||
)
|
||||
env = {
|
||||
**os.environ,
|
||||
"GITEA_AUDIT_TEST_FILE_REMOTE": "1",
|
||||
"GITEA_AUDIT_REMOTE_URL": f"file://{self.remote}",
|
||||
"GITEA_AUDIT_BRANCH": "main",
|
||||
"GITEA_AUDIT_CONTROLLER_SOURCE": str(controller),
|
||||
"GITEA_AUDIT_VERIFIER_SOURCE": str(verifier),
|
||||
"GITEA_AUDIT_CONTROLLER_TARGET": CONTROLLER_TARGET,
|
||||
"GITEA_AUDIT_VERIFIER_TARGET": VERIFIER_TARGET,
|
||||
"GITEA_AUDIT_COMMIT_MESSAGE": "must not commit",
|
||||
}
|
||||
completed = subprocess.run(
|
||||
["bash", str(SCRIPT)],
|
||||
cwd=clone,
|
||||
env=env,
|
||||
check=False,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=30,
|
||||
)
|
||||
self.assertEqual(completed.returncode, 2)
|
||||
self.assertIn("audit_writeback_branch_not_allowlisted", completed.stdout)
|
||||
|
||||
def test_branch_and_receipt_directory_must_match(self) -> None:
|
||||
clone = self._fresh_main_clone("clone-mismatched-target")
|
||||
source_dir = self.root / "source-mismatched-target"
|
||||
source_dir.mkdir()
|
||||
controller, verifier = _write_receipts(
|
||||
source_dir, "44444444-4444-4444-8444-444444444444"
|
||||
)
|
||||
env = {
|
||||
**os.environ,
|
||||
"GITEA_AUDIT_TEST_FILE_REMOTE": "1",
|
||||
"GITEA_AUDIT_REMOTE_URL": f"file://{self.remote}",
|
||||
"GITEA_AUDIT_BRANCH": "mcp-artifact-receipts",
|
||||
"GITEA_AUDIT_CONTROLLER_SOURCE": str(controller),
|
||||
"GITEA_AUDIT_VERIFIER_SOURCE": str(verifier),
|
||||
"GITEA_AUDIT_CONTROLLER_TARGET": CONTROLLER_TARGET,
|
||||
"GITEA_AUDIT_VERIFIER_TARGET": VERIFIER_TARGET,
|
||||
"GITEA_AUDIT_COMMIT_MESSAGE": "must not commit",
|
||||
}
|
||||
completed = subprocess.run(
|
||||
["bash", str(SCRIPT)],
|
||||
cwd=clone,
|
||||
env=env,
|
||||
check=False,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=30,
|
||||
)
|
||||
self.assertEqual(completed.returncode, 2)
|
||||
self.assertIn("audit_writeback_branch_target_mismatch", completed.stdout)
|
||||
|
||||
def test_controller_and_verifier_identity_must_match(self) -> None:
|
||||
clone = self._fresh_main_clone("clone-mismatched-identity")
|
||||
source_dir = self.root / "source-mismatched-identity"
|
||||
source_dir.mkdir()
|
||||
controller, verifier = _write_receipts(
|
||||
source_dir, "55555555-5555-4555-8555-555555555555"
|
||||
)
|
||||
verifier_payload = json.loads(verifier.read_text(encoding="utf-8"))
|
||||
verifier_payload["run_id"] = "66666666-6666-4666-8666-666666666666"
|
||||
verifier.write_text(
|
||||
json.dumps(verifier_payload, sort_keys=True) + "\n", encoding="utf-8"
|
||||
)
|
||||
env = {
|
||||
**os.environ,
|
||||
"GITEA_AUDIT_TEST_FILE_REMOTE": "1",
|
||||
"GITEA_AUDIT_REMOTE_URL": f"file://{self.remote}",
|
||||
"GITEA_AUDIT_BRANCH": "mcp-replay-receipts",
|
||||
"GITEA_AUDIT_CONTROLLER_SOURCE": str(controller),
|
||||
"GITEA_AUDIT_VERIFIER_SOURCE": str(verifier),
|
||||
"GITEA_AUDIT_CONTROLLER_TARGET": CONTROLLER_TARGET,
|
||||
"GITEA_AUDIT_VERIFIER_TARGET": VERIFIER_TARGET,
|
||||
"GITEA_AUDIT_COMMIT_MESSAGE": "must not commit",
|
||||
}
|
||||
completed = subprocess.run(
|
||||
["bash", str(SCRIPT)],
|
||||
cwd=clone,
|
||||
env=env,
|
||||
check=False,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=30,
|
||||
)
|
||||
self.assertEqual(completed.returncode, 2)
|
||||
self.assertIn("audit_writeback_receipt_identity_mismatch", completed.stdout)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
188
scripts/ci/write-gitea-audit-receipts.sh
Executable file
188
scripts/ci/write-gitea-audit-receipts.sh
Executable file
@@ -0,0 +1,188 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
set +x
|
||||
|
||||
# Append two verified JSON receipts to a dedicated Gitea audit branch without
|
||||
# merging the shallow workflow checkout. Authentication is supplied by the
|
||||
# caller through GIT_ASKPASS; this script never accepts a token argument.
|
||||
|
||||
required_env=(
|
||||
GITEA_AUDIT_REMOTE_URL
|
||||
GITEA_AUDIT_BRANCH
|
||||
GITEA_AUDIT_CONTROLLER_SOURCE
|
||||
GITEA_AUDIT_VERIFIER_SOURCE
|
||||
GITEA_AUDIT_CONTROLLER_TARGET
|
||||
GITEA_AUDIT_VERIFIER_TARGET
|
||||
GITEA_AUDIT_COMMIT_MESSAGE
|
||||
)
|
||||
for name in "${required_env[@]}"; do
|
||||
if [ -z "${!name:-}" ]; then
|
||||
echo "BLOCKER audit_writeback_missing_${name}"
|
||||
exit 2
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "${GITEA_AUDIT_REMOTE_URL}" = "http://192.168.0.110:3001/wooo/awoooi.git" ]; then
|
||||
if [ -z "${GIT_ASKPASS:-}" ] || [ ! -x "${GIT_ASKPASS}" ]; then
|
||||
echo "BLOCKER audit_writeback_askpass_missing_or_not_executable"
|
||||
exit 2
|
||||
fi
|
||||
elif [[ "${GITEA_AUDIT_REMOTE_URL}" == file://* ]] && \
|
||||
[ "${GITEA_AUDIT_TEST_FILE_REMOTE:-0}" = "1" ]; then
|
||||
:
|
||||
else
|
||||
echo "BLOCKER audit_writeback_remote_not_allowlisted"
|
||||
exit 2
|
||||
fi
|
||||
if ! [[ "${GITEA_AUDIT_BRANCH}" =~ ^mcp-(artifact|replay)-receipts$ ]]; then
|
||||
echo "BLOCKER audit_writeback_branch_not_allowlisted"
|
||||
exit 2
|
||||
fi
|
||||
if ! [[ "${GITEA_AUDIT_CONTROLLER_TARGET}" =~ ^docs/operations/external-mcp-(artifacts|replays)/[A-Za-z0-9._-]+-controller\.snapshot\.json$ ]]; then
|
||||
echo "BLOCKER audit_writeback_controller_target_not_allowlisted"
|
||||
exit 2
|
||||
fi
|
||||
if ! [[ "${GITEA_AUDIT_VERIFIER_TARGET}" =~ ^docs/operations/external-mcp-(artifacts|replays)/[A-Za-z0-9._-]+-verifier\.snapshot\.json$ ]]; then
|
||||
echo "BLOCKER audit_writeback_verifier_target_not_allowlisted"
|
||||
exit 2
|
||||
fi
|
||||
if [ "$(dirname "${GITEA_AUDIT_CONTROLLER_TARGET}")" != "$(dirname "${GITEA_AUDIT_VERIFIER_TARGET}")" ]; then
|
||||
echo "BLOCKER audit_writeback_target_directory_mismatch"
|
||||
exit 2
|
||||
fi
|
||||
case "${GITEA_AUDIT_BRANCH}" in
|
||||
mcp-artifact-receipts)
|
||||
expected_target_directory="docs/operations/external-mcp-artifacts"
|
||||
expected_controller_schema="awoooi_external_mcp_artifact_receipt_v1"
|
||||
expected_verifier_schema="awoooi_external_mcp_artifact_verifier_receipt_v1"
|
||||
;;
|
||||
mcp-replay-receipts)
|
||||
expected_target_directory="docs/operations/external-mcp-replays"
|
||||
expected_controller_schema="awoooi_external_mcp_replay_receipt_v1"
|
||||
expected_verifier_schema="awoooi_external_mcp_replay_verifier_receipt_v1"
|
||||
;;
|
||||
esac
|
||||
if [ "$(dirname "${GITEA_AUDIT_CONTROLLER_TARGET}")" != "${expected_target_directory}" ]; then
|
||||
echo "BLOCKER audit_writeback_branch_target_mismatch"
|
||||
exit 2
|
||||
fi
|
||||
if [ "${#GITEA_AUDIT_COMMIT_MESSAGE}" -gt 200 ] || \
|
||||
[[ "${GITEA_AUDIT_COMMIT_MESSAGE}" == *$'\n'* ]] || \
|
||||
[[ "${GITEA_AUDIT_COMMIT_MESSAGE}" == *$'\r'* ]]; then
|
||||
echo "BLOCKER audit_writeback_commit_message_invalid"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
for source_path in \
|
||||
"${GITEA_AUDIT_CONTROLLER_SOURCE}" \
|
||||
"${GITEA_AUDIT_VERIFIER_SOURCE}"; do
|
||||
if [ ! -f "${source_path}" ] || [ -L "${source_path}" ]; then
|
||||
echo "BLOCKER audit_writeback_source_invalid"
|
||||
exit 2
|
||||
fi
|
||||
source_size="$(wc -c < "${source_path}" | tr -d ' ')"
|
||||
if [ "${source_size}" -le 0 ] || [ "${source_size}" -gt 4194304 ]; then
|
||||
echo "BLOCKER audit_writeback_source_size_invalid"
|
||||
exit 2
|
||||
fi
|
||||
done
|
||||
|
||||
python3 - \
|
||||
"${GITEA_AUDIT_CONTROLLER_SOURCE}" \
|
||||
"${GITEA_AUDIT_VERIFIER_SOURCE}" \
|
||||
"${expected_controller_schema}" \
|
||||
"${expected_verifier_schema}" <<'PY'
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
def fail(message: str) -> None:
|
||||
print(message)
|
||||
raise SystemExit(2)
|
||||
|
||||
|
||||
try:
|
||||
receipts = [
|
||||
json.loads(Path(value).read_text(encoding="utf-8")) for value in sys.argv[1:3]
|
||||
]
|
||||
except (OSError, UnicodeError, json.JSONDecodeError):
|
||||
fail("BLOCKER audit_writeback_receipt_json_invalid")
|
||||
|
||||
expected_schemas = sys.argv[3:5]
|
||||
identity_fields = ("run_id", "trace_id", "work_item_id")
|
||||
for payload, expected_schema in zip(receipts, expected_schemas):
|
||||
if not isinstance(payload, dict) or payload.get("schema_version") != expected_schema:
|
||||
fail("BLOCKER audit_writeback_receipt_schema_invalid")
|
||||
if any(not str(payload.get(field) or "") for field in identity_fields):
|
||||
fail("BLOCKER audit_writeback_receipt_identity_missing")
|
||||
if any(receipts[0][field] != receipts[1][field] for field in identity_fields):
|
||||
fail("BLOCKER audit_writeback_receipt_identity_mismatch")
|
||||
PY
|
||||
|
||||
remote_name="gitea-audit"
|
||||
git remote remove "${remote_name}" >/dev/null 2>&1 || true
|
||||
git remote add "${remote_name}" "${GITEA_AUDIT_REMOTE_URL}"
|
||||
rm -f \
|
||||
"${GITEA_AUDIT_CONTROLLER_TARGET}" \
|
||||
"${GITEA_AUDIT_VERIFIER_TARGET}"
|
||||
|
||||
for attempt in 1 2 3; do
|
||||
if git ls-remote --exit-code --heads "${remote_name}" \
|
||||
"refs/heads/${GITEA_AUDIT_BRANCH}" >/dev/null 2>&1; then
|
||||
git fetch --no-tags --depth=1 "${remote_name}" "${GITEA_AUDIT_BRANCH}"
|
||||
git checkout --force --detach FETCH_HEAD
|
||||
fi
|
||||
|
||||
target_directory="$(dirname "${GITEA_AUDIT_CONTROLLER_TARGET}")"
|
||||
for ancestor in docs docs/operations "${target_directory}"; do
|
||||
if [ -L "${ancestor}" ]; then
|
||||
echo "BLOCKER audit_writeback_target_symlink_rejected"
|
||||
exit 2
|
||||
fi
|
||||
done
|
||||
mkdir -p "${target_directory}"
|
||||
for target_path in \
|
||||
"${GITEA_AUDIT_CONTROLLER_TARGET}" \
|
||||
"${GITEA_AUDIT_VERIFIER_TARGET}"; do
|
||||
if [ -L "${target_path}" ]; then
|
||||
echo "BLOCKER audit_writeback_target_symlink_rejected"
|
||||
exit 2
|
||||
fi
|
||||
done
|
||||
install -m 0644 \
|
||||
"${GITEA_AUDIT_CONTROLLER_SOURCE}" \
|
||||
"${GITEA_AUDIT_CONTROLLER_TARGET}"
|
||||
install -m 0644 \
|
||||
"${GITEA_AUDIT_VERIFIER_SOURCE}" \
|
||||
"${GITEA_AUDIT_VERIFIER_TARGET}"
|
||||
git add \
|
||||
"${GITEA_AUDIT_CONTROLLER_TARGET}" \
|
||||
"${GITEA_AUDIT_VERIFIER_TARGET}"
|
||||
|
||||
while IFS= read -r staged_path; do
|
||||
if [ "${staged_path}" != "${GITEA_AUDIT_CONTROLLER_TARGET}" ] && \
|
||||
[ "${staged_path}" != "${GITEA_AUDIT_VERIFIER_TARGET}" ]; then
|
||||
echo "BLOCKER audit_writeback_unexpected_staged_path"
|
||||
exit 2
|
||||
fi
|
||||
done < <(git diff --cached --name-only)
|
||||
|
||||
if git diff --cached --quiet; then
|
||||
echo "receipt_writeback=no_change"
|
||||
echo "receipt_branch=${GITEA_AUDIT_BRANCH}"
|
||||
echo "receipt_commit_sha=$(git rev-parse HEAD)"
|
||||
exit 0
|
||||
fi
|
||||
git commit -m "${GITEA_AUDIT_COMMIT_MESSAGE}"
|
||||
if git push "${remote_name}" "HEAD:refs/heads/${GITEA_AUDIT_BRANCH}"; then
|
||||
echo "receipt_writeback=verified_audit_branch_normal_push"
|
||||
echo "receipt_branch=${GITEA_AUDIT_BRANCH}"
|
||||
echo "receipt_commit_sha=$(git rev-parse HEAD)"
|
||||
exit 0
|
||||
fi
|
||||
echo "receipt_writeback_retry=${attempt}"
|
||||
sleep 5
|
||||
done
|
||||
|
||||
echo "BLOCKER receipt_writeback_non_fast_forward_after_bounded_retry"
|
||||
exit 1
|
||||
Reference in New Issue
Block a user