diff --git a/lib/archeflow-rollback.sh b/lib/archeflow-rollback.sh index 7a793e1..50fec3a 100755 --- a/lib/archeflow-rollback.sh +++ b/lib/archeflow-rollback.sh @@ -1,26 +1,67 @@ #!/usr/bin/env bash -# archeflow-rollback.sh — Auto-revert a merge that fails post-merge tests. +# archeflow-rollback.sh — Auto-revert a merge that fails post-merge tests, +# or roll back to a specific PDCA phase boundary. # -# Usage: archeflow-rollback.sh [--test-cmd ] +# Usage: +# archeflow-rollback.sh [--test-cmd ] # Post-merge test + revert +# archeflow-rollback.sh --to # Roll back to phase boundary # -# If --test-cmd not provided, reads test_command from .archeflow/config.yaml. -# Returns 0 if tests pass, 1 if tests fail (merge reverted). +# --to : Roll back to the given phase boundary (plan, do, or check). +# Delegates to archeflow-git.sh rollback and emits a decision event. +# +# If --test-cmd not provided (and --to not used), reads test_command from .archeflow/config.yaml. +# Returns 0 if tests pass (or rollback succeeds), 1 if tests fail (merge reverted). set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" -RUN_ID="${1:?Usage: archeflow-rollback.sh [--test-cmd ]}" +RUN_ID="${1:?Usage: archeflow-rollback.sh [--test-cmd ] [--to ]}" shift -# Parse optional --test-cmd +# Parse options TEST_CMD="" +TARGET_PHASE="" while [[ $# -gt 0 ]]; do case "$1" in --test-cmd) TEST_CMD="$2"; shift 2 ;; + --to) TARGET_PHASE="$2"; shift 2 ;; *) echo "Unknown option: $1" >&2; exit 2 ;; esac done +# --- Phase rollback mode --- +if [[ -n "$TARGET_PHASE" ]]; then + # Validate phase name + case "$TARGET_PHASE" in + plan|do|check) ;; + *) + echo "ERROR: Invalid phase '$TARGET_PHASE'. Must be one of: plan, do, check" >&2 + exit 2 + ;; + esac + + echo "Rolling back run $RUN_ID to phase boundary: $TARGET_PHASE" + + # Delegate to archeflow-git.sh + if [[ ! -x "$SCRIPT_DIR/archeflow-git.sh" ]]; then + echo "ERROR: archeflow-git.sh not found or not executable" >&2 + exit 1 + fi + + "$SCRIPT_DIR/archeflow-git.sh" rollback "$RUN_ID" --to "$TARGET_PHASE" + + # Emit decision event + if [[ -x "$SCRIPT_DIR/archeflow-event.sh" ]]; then + "$SCRIPT_DIR/archeflow-event.sh" "$RUN_ID" decision act "" \ + "{\"what\":\"phase_rollback\",\"chosen\":\"rollback_to_${TARGET_PHASE}\",\"rationale\":\"user requested rollback to ${TARGET_PHASE} phase boundary\"}" "" + fi + + echo "Rollback to $TARGET_PHASE complete for run $RUN_ID." + exit 0 +fi + +# --- Post-merge test mode --- + # Read test_command from config if not provided if [[ -z "$TEST_CMD" ]]; then if [[ -f ".archeflow/config.yaml" ]]; then