#!/usr/bin/env bash # archeflow-rollback.sh — Auto-revert a merge that fails post-merge tests. # # Usage: archeflow-rollback.sh [--test-cmd ] # # If --test-cmd not provided, reads test_command from .archeflow/config.yaml. # Returns 0 if tests pass, 1 if tests fail (merge reverted). set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" RUN_ID="${1:?Usage: archeflow-rollback.sh [--test-cmd ]}" shift # Parse optional --test-cmd TEST_CMD="" while [[ $# -gt 0 ]]; do case "$1" in --test-cmd) TEST_CMD="$2"; shift 2 ;; *) echo "Unknown option: $1" >&2; exit 2 ;; esac done # Read test_command from config if not provided if [[ -z "$TEST_CMD" ]]; then if [[ -f ".archeflow/config.yaml" ]]; then TEST_CMD=$(grep -E "^test_command:" .archeflow/config.yaml | sed 's/^test_command:\s*//' | tr -d '"' || true) fi fi if [[ -z "$TEST_CMD" ]]; then echo "ERROR: No test command specified (use --test-cmd or set test_command in .archeflow/config.yaml)" >&2 exit 2 fi # Verify HEAD is an ArcheFlow merge HEAD_MSG=$(git log -1 --format=%s HEAD) if [[ "$HEAD_MSG" != *"$RUN_ID"* ]] && [[ "$HEAD_MSG" != *"archeflow"* ]]; then echo "WARNING: HEAD commit does not appear to be an ArcheFlow merge: $HEAD_MSG" >&2 echo "Proceeding anyway..." >&2 fi echo "Running post-merge tests: $TEST_CMD" if timeout 300 bash -c "$TEST_CMD"; then echo "Tests passed — merge is good." exit 0 fi echo "Tests FAILED — reverting merge..." git revert --no-edit --mainline 1 HEAD # Emit event if event script exists if [[ -x "$SCRIPT_DIR/archeflow-event.sh" ]]; then "$SCRIPT_DIR/archeflow-event.sh" "$RUN_ID" decision act "" \ "{\"what\":\"post_merge_test\",\"chosen\":\"revert\",\"rationale\":\"test suite failed after merge\"}" "" fi REVERT_HASH=$(git rev-parse --short HEAD) echo "Merge reverted (commit: $REVERT_HASH). Tests must pass before re-merging." exit 1