| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
set -uo pipefail |
| 13 |
|
| 14 |
export PATH="$HOME/.cargo/bin:$PATH" |
| 15 |
|
| 16 |
BRANCH="${1:-main}" |
| 17 |
REPO_DIR="$HOME/mnw-ci" |
| 18 |
SERVER_DIR="$REPO_DIR/server" |
| 19 |
WAM_URL="${WAM_URL:-http://127.0.0.1:7890}" |
| 20 |
START_TIME=$(date +%s) |
| 21 |
LOG_FILE="$REPO_DIR/ci-latest.log" |
| 22 |
|
| 23 |
echo "=== CI triggered for branch: $BRANCH ===" |
| 24 |
echo "Started: $(date -u +%Y-%m-%dT%H:%M:%SZ)" |
| 25 |
|
| 26 |
|
| 27 |
cd "$REPO_DIR" || exit 1 |
| 28 |
echo "[pull] Fetching latest..." |
| 29 |
git fetch origin "$BRANCH" 2>&1 |
| 30 |
|
| 31 |
|
| 32 |
OLD_HEAD=$(git rev-parse HEAD 2>/dev/null || echo "none") |
| 33 |
git reset --hard "origin/$BRANCH" 2>&1 |
| 34 |
NEW_HEAD=$(git rev-parse HEAD) |
| 35 |
COMMIT_MSG=$(git log --oneline -1) |
| 36 |
|
| 37 |
echo "[pull] $OLD_HEAD -> $NEW_HEAD" |
| 38 |
echo "[pull] $COMMIT_MSG" |
| 39 |
|
| 40 |
|
| 41 |
cd "$SERVER_DIR" || exit 1 |
| 42 |
|
| 43 |
export DATABASE_URL="${DATABASE_URL:-postgres:///makenotwork_staging}" |
| 44 |
export TEST_DATABASE_URL="${TEST_DATABASE_URL:-postgres:///postgres}" |
| 45 |
export RUST_TEST_THREADS="${RUST_TEST_THREADS:-8}" |
| 46 |
export CARGO_INCREMENTAL=0 |
| 47 |
export RUST_BACKTRACE=1 |
| 48 |
|
| 49 |
echo "[ci] Running CI suite..." |
| 50 |
CI_OUTPUT=$("$REPO_DIR/server/deploy/run-ci.sh" 2>&1) || true |
| 51 |
CI_EXIT=$? |
| 52 |
|
| 53 |
END_TIME=$(date +%s) |
| 54 |
DURATION=$(( END_TIME - START_TIME )) |
| 55 |
|
| 56 |
|
| 57 |
PASS_COUNT=$(echo "$CI_OUTPUT" | grep -c "^ PASS" || true) |
| 58 |
FAIL_COUNT=$(echo "$CI_OUTPUT" | grep -c "^ FAIL" || true) |
| 59 |
|
| 60 |
|
| 61 |
echo "$CI_OUTPUT" > "$LOG_FILE" |
| 62 |
|
| 63 |
|
| 64 |
|
| 65 |
wam_ticket() { |
| 66 |
local title="$1" body="$2" priority="$3" source_ref="$4" |
| 67 |
local escaped_title escaped_body |
| 68 |
escaped_title=$(echo "$title" | python3 -c 'import sys,json; print(json.dumps(sys.stdin.read().strip()))' 2>/dev/null || echo "\"$title\"") |
| 69 |
escaped_body=$(echo "$body" | python3 -c 'import sys,json; print(json.dumps(sys.stdin.read()))' 2>/dev/null || echo '""') |
| 70 |
curl -sf -X POST "$WAM_URL/tickets" \ |
| 71 |
-H "Content-Type: application/json" \ |
| 72 |
-d "{\"title\": $escaped_title, \"body\": $escaped_body, \"priority\": \"$priority\", \"source\": \"ci\", \"source_ref\": \"$source_ref\"}" \ |
| 73 |
>/dev/null 2>&1 || echo "[warn] Failed to create WAM ticket" |
| 74 |
} |
| 75 |
|
| 76 |
if [ $CI_EXIT -eq 0 ]; then |
| 77 |
|
| 78 |
TITLE="CI passed: $BRANCH ($PASS_COUNT steps, ${DURATION}s)" |
| 79 |
BODY="Commit: $COMMIT_MSG |
| 80 |
Duration: ${DURATION}s |
| 81 |
Steps passed: $PASS_COUNT |
| 82 |
|
| 83 |
All steps passed." |
| 84 |
|
| 85 |
wam_ticket "$TITLE" "$BODY" "low" "$NEW_HEAD" |
| 86 |
echo "" |
| 87 |
echo "=== CI PASSED ($PASS_COUNT steps, ${DURATION}s) ===" |
| 88 |
else |
| 89 |
|
| 90 |
FAILED_STEPS=$(echo "$CI_OUTPUT" | grep "^ FAIL" | sed 's/^ FAIL / - /') |
| 91 |
|
| 92 |
echo "" |
| 93 |
echo "=== CI FAILED — REVERTING ===" |
| 94 |
echo "" |
| 95 |
|
| 96 |
cd "$REPO_DIR" || exit 1 |
| 97 |
|
| 98 |
|
| 99 |
if [ "$OLD_HEAD" = "none" ] || [ "$OLD_HEAD" = "$NEW_HEAD" ]; then |
| 100 |
|
| 101 |
REVERT_STATUS="could not determine commits to revert" |
| 102 |
else |
| 103 |
NEW_COMMITS=$(git rev-list "$OLD_HEAD..$NEW_HEAD" --count 2>/dev/null || echo "0") |
| 104 |
|
| 105 |
if [ "$NEW_COMMITS" -eq 1 ]; then |
| 106 |
|
| 107 |
git revert --no-edit HEAD 2>&1 |
| 108 |
REVERT_STATUS="reverted 1 commit ($NEW_HEAD)" |
| 109 |
elif [ "$NEW_COMMITS" -gt 1 ]; then |
| 110 |
|
| 111 |
git revert --no-edit "$OLD_HEAD..$NEW_HEAD" 2>&1 |
| 112 |
REVERT_STATUS="reverted $NEW_COMMITS commits ($OLD_HEAD..$NEW_HEAD)" |
| 113 |
else |
| 114 |
REVERT_STATUS="no new commits to revert" |
| 115 |
fi |
| 116 |
|
| 117 |
|
| 118 |
if git push origin "$BRANCH" 2>&1; then |
| 119 |
REVERT_STATUS="$REVERT_STATUS — pushed to origin" |
| 120 |
else |
| 121 |
REVERT_STATUS="$REVERT_STATUS — PUSH FAILED (manual intervention needed)" |
| 122 |
fi |
| 123 |
fi |
| 124 |
|
| 125 |
TITLE="CI FAILED + REVERTED: $BRANCH ($FAIL_COUNT step(s) failed)" |
| 126 |
BODY="Commit: $COMMIT_MSG |
| 127 |
Duration: ${DURATION}s |
| 128 |
Steps passed: $PASS_COUNT |
| 129 |
Steps failed: $FAIL_COUNT |
| 130 |
|
| 131 |
Failed steps: |
| 132 |
$FAILED_STEPS |
| 133 |
|
| 134 |
Revert: $REVERT_STATUS |
| 135 |
|
| 136 |
No-regressions rule enforced automatically. |
| 137 |
Fix the issue and re-push. |
| 138 |
|
| 139 |
Last 30 lines of output: |
| 140 |
$(echo "$CI_OUTPUT" | tail -30)" |
| 141 |
|
| 142 |
wam_ticket "$TITLE" "$BODY" "critical" "$NEW_HEAD" |
| 143 |
echo "Revert: $REVERT_STATUS" |
| 144 |
echo "" |
| 145 |
fi |
| 146 |
|
| 147 |
exit $CI_EXIT |
| 148 |
|