shipwright-cli 2.0.0 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +160 -72
- package/completions/_shipwright +59 -7
- package/completions/shipwright.bash +24 -4
- package/completions/shipwright.fish +80 -2
- package/dashboard/server.ts +208 -0
- package/docs/tmux-research/TMUX-ARCHITECTURE.md +567 -0
- package/docs/tmux-research/TMUX-AUDIT.md +925 -0
- package/docs/tmux-research/TMUX-BEST-PRACTICES-2025-2026.md +829 -0
- package/docs/tmux-research/TMUX-QUICK-REFERENCE.md +543 -0
- package/docs/tmux-research/TMUX-RESEARCH-INDEX.md +438 -0
- package/package.json +2 -2
- package/scripts/lib/helpers.sh +7 -0
- package/scripts/sw +116 -2
- package/scripts/sw-activity.sh +1 -1
- package/scripts/sw-adaptive.sh +1 -1
- package/scripts/sw-adversarial.sh +1 -1
- package/scripts/sw-architecture-enforcer.sh +1 -1
- package/scripts/sw-auth.sh +1 -1
- package/scripts/sw-autonomous.sh +128 -38
- package/scripts/sw-changelog.sh +1 -1
- package/scripts/sw-checkpoint.sh +1 -1
- package/scripts/sw-ci.sh +1 -1
- package/scripts/sw-cleanup.sh +1 -1
- package/scripts/sw-code-review.sh +62 -1
- package/scripts/sw-connect.sh +1 -1
- package/scripts/sw-context.sh +1 -1
- package/scripts/sw-cost.sh +44 -3
- package/scripts/sw-daemon.sh +155 -27
- package/scripts/sw-dashboard.sh +1 -1
- package/scripts/sw-db.sh +958 -118
- package/scripts/sw-decompose.sh +1 -1
- package/scripts/sw-deps.sh +1 -1
- package/scripts/sw-developer-simulation.sh +1 -1
- package/scripts/sw-discovery.sh +1 -1
- package/scripts/sw-docs-agent.sh +1 -1
- package/scripts/sw-docs.sh +1 -1
- package/scripts/sw-doctor.sh +49 -1
- package/scripts/sw-dora.sh +1 -1
- package/scripts/sw-durable.sh +1 -1
- package/scripts/sw-e2e-orchestrator.sh +1 -1
- package/scripts/sw-eventbus.sh +1 -1
- package/scripts/sw-feedback.sh +23 -15
- package/scripts/sw-fix.sh +1 -1
- package/scripts/sw-fleet-discover.sh +1 -1
- package/scripts/sw-fleet-viz.sh +1 -1
- package/scripts/sw-fleet.sh +1 -1
- package/scripts/sw-github-app.sh +1 -1
- package/scripts/sw-github-checks.sh +4 -4
- package/scripts/sw-github-deploy.sh +1 -1
- package/scripts/sw-github-graphql.sh +1 -1
- package/scripts/sw-guild.sh +1 -1
- package/scripts/sw-heartbeat.sh +1 -1
- package/scripts/sw-hygiene.sh +1 -1
- package/scripts/sw-incident.sh +45 -6
- package/scripts/sw-init.sh +150 -24
- package/scripts/sw-instrument.sh +1 -1
- package/scripts/sw-intelligence.sh +1 -1
- package/scripts/sw-jira.sh +1 -1
- package/scripts/sw-launchd.sh +1 -1
- package/scripts/sw-linear.sh +1 -1
- package/scripts/sw-logs.sh +1 -1
- package/scripts/sw-loop.sh +204 -19
- package/scripts/sw-memory.sh +18 -1
- package/scripts/sw-mission-control.sh +1 -1
- package/scripts/sw-model-router.sh +1 -1
- package/scripts/sw-otel.sh +1 -1
- package/scripts/sw-oversight.sh +76 -1
- package/scripts/sw-pipeline-composer.sh +1 -1
- package/scripts/sw-pipeline-vitals.sh +1 -1
- package/scripts/sw-pipeline.sh +302 -18
- package/scripts/sw-pm.sh +70 -5
- package/scripts/sw-pr-lifecycle.sh +1 -1
- package/scripts/sw-predictive.sh +8 -1
- package/scripts/sw-prep.sh +1 -1
- package/scripts/sw-ps.sh +1 -1
- package/scripts/sw-public-dashboard.sh +1 -1
- package/scripts/sw-quality.sh +1 -1
- package/scripts/sw-reaper.sh +1 -1
- package/scripts/sw-recruit.sh +1853 -178
- package/scripts/sw-regression.sh +1 -1
- package/scripts/sw-release-manager.sh +1 -1
- package/scripts/sw-release.sh +1 -1
- package/scripts/sw-remote.sh +1 -1
- package/scripts/sw-replay.sh +1 -1
- package/scripts/sw-retro.sh +1 -1
- package/scripts/sw-scale.sh +1 -1
- package/scripts/sw-security-audit.sh +1 -1
- package/scripts/sw-self-optimize.sh +1 -1
- package/scripts/sw-session.sh +1 -1
- package/scripts/sw-setup.sh +263 -127
- package/scripts/sw-standup.sh +1 -1
- package/scripts/sw-status.sh +44 -2
- package/scripts/sw-strategic.sh +189 -41
- package/scripts/sw-stream.sh +1 -1
- package/scripts/sw-swarm.sh +42 -5
- package/scripts/sw-team-stages.sh +1 -1
- package/scripts/sw-templates.sh +4 -4
- package/scripts/sw-testgen.sh +66 -15
- package/scripts/sw-tmux-pipeline.sh +1 -1
- package/scripts/sw-tmux-role-color.sh +58 -0
- package/scripts/sw-tmux-status.sh +128 -0
- package/scripts/sw-tmux.sh +1 -1
- package/scripts/sw-trace.sh +1 -1
- package/scripts/sw-tracker.sh +1 -1
- package/scripts/sw-triage.sh +61 -37
- package/scripts/sw-upgrade.sh +1 -1
- package/scripts/sw-ux.sh +30 -2
- package/scripts/sw-webhook.sh +1 -1
- package/scripts/sw-widgets.sh +1 -1
- package/scripts/sw-worktree.sh +1 -1
- package/tmux/shipwright-overlay.conf +35 -17
- package/tmux/tmux.conf +26 -21
package/scripts/sw-decompose.sh
CHANGED
package/scripts/sw-deps.sh
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
set -euo pipefail
|
|
7
7
|
trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
|
|
8
8
|
|
|
9
|
-
VERSION="2.
|
|
9
|
+
VERSION="2.1.1"
|
|
10
10
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
11
|
|
|
12
12
|
# ─── Colors (matches Seth's tmux theme) ─────────────────────────────────────
|
package/scripts/sw-discovery.sh
CHANGED
package/scripts/sw-docs-agent.sh
CHANGED
package/scripts/sw-docs.sh
CHANGED
package/scripts/sw-doctor.sh
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# ║ ║
|
|
5
5
|
# ║ Checks prerequisites, installed files, PATH, and common issues. ║
|
|
6
6
|
# ╚═══════════════════════════════════════════════════════════════════════════╝
|
|
7
|
-
VERSION="2.
|
|
7
|
+
VERSION="2.1.1"
|
|
8
8
|
set -euo pipefail
|
|
9
9
|
trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
|
|
10
10
|
|
|
@@ -943,6 +943,54 @@ else
|
|
|
943
943
|
info " Port check skipped ${DIM}(lsof/ss not found)${RESET}"
|
|
944
944
|
fi
|
|
945
945
|
|
|
946
|
+
# ═════════════════════════════════════════════════════════════════════════════
|
|
947
|
+
# 15. Database Health
|
|
948
|
+
# ═════════════════════════════════════════════════════════════════════════════
|
|
949
|
+
echo ""
|
|
950
|
+
echo -e "${PURPLE}${BOLD} DATABASE HEALTH${RESET}"
|
|
951
|
+
echo -e "${DIM} ──────────────────────────────────────────${RESET}"
|
|
952
|
+
|
|
953
|
+
if command -v sqlite3 &>/dev/null; then
|
|
954
|
+
_sqlite_ver="$(sqlite3 --version 2>/dev/null | cut -d' ' -f1 || echo "unknown")"
|
|
955
|
+
check_pass "sqlite3 ${_sqlite_ver}"
|
|
956
|
+
|
|
957
|
+
_db_file="${HOME}/.shipwright/shipwright.db"
|
|
958
|
+
if [[ -f "$_db_file" ]]; then
|
|
959
|
+
check_pass "Database exists: ${DIM}${_db_file}${RESET}"
|
|
960
|
+
|
|
961
|
+
# Check WAL mode
|
|
962
|
+
_wal_mode=$(sqlite3 "$_db_file" "PRAGMA journal_mode;" 2>/dev/null || echo "unknown")
|
|
963
|
+
if [[ "$_wal_mode" == "wal" ]]; then
|
|
964
|
+
check_pass "WAL mode enabled"
|
|
965
|
+
else
|
|
966
|
+
check_warn "WAL mode not enabled (current: ${_wal_mode})"
|
|
967
|
+
fi
|
|
968
|
+
|
|
969
|
+
# Check schema version
|
|
970
|
+
_schema_ver=$(sqlite3 "$_db_file" "SELECT MAX(version) FROM _schema;" 2>/dev/null || echo "0")
|
|
971
|
+
if [[ "${_schema_ver:-0}" -ge 2 ]]; then
|
|
972
|
+
check_pass "Schema version: ${_schema_ver}"
|
|
973
|
+
else
|
|
974
|
+
check_warn "Schema version ${_schema_ver:-0} — expected >= 2. Run: shipwright db init"
|
|
975
|
+
fi
|
|
976
|
+
|
|
977
|
+
# Check file size
|
|
978
|
+
_db_size=$(ls -l "$_db_file" 2>/dev/null | awk '{print $5}')
|
|
979
|
+
_db_size_mb=$(awk -v s="${_db_size:-0}" 'BEGIN { printf "%.1f", s / 1048576 }')
|
|
980
|
+
check_pass "Database size: ${_db_size_mb} MB"
|
|
981
|
+
|
|
982
|
+
# Check table counts
|
|
983
|
+
_event_count=$(sqlite3 "$_db_file" "SELECT COUNT(*) FROM events;" 2>/dev/null || echo "0")
|
|
984
|
+
_run_count=$(sqlite3 "$_db_file" "SELECT COUNT(*) FROM pipeline_runs;" 2>/dev/null || echo "0")
|
|
985
|
+
info " Tables: events=${_event_count} pipeline_runs=${_run_count}"
|
|
986
|
+
else
|
|
987
|
+
check_warn "Database not initialized — run: shipwright db init"
|
|
988
|
+
fi
|
|
989
|
+
else
|
|
990
|
+
check_warn "sqlite3 not installed — DB features disabled"
|
|
991
|
+
echo -e " ${DIM}Install: brew install sqlite (macOS) or apt install sqlite3 (Linux)${RESET}"
|
|
992
|
+
fi
|
|
993
|
+
|
|
946
994
|
# ═════════════════════════════════════════════════════════════════════════════
|
|
947
995
|
# Summary
|
|
948
996
|
# ═════════════════════════════════════════════════════════════════════════════
|
package/scripts/sw-dora.sh
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
set -euo pipefail
|
|
9
9
|
trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
|
|
10
10
|
|
|
11
|
-
VERSION="2.
|
|
11
|
+
VERSION="2.1.1"
|
|
12
12
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
13
13
|
|
|
14
14
|
# ─── Colors (matches Seth's tmux theme) ─────────────────────────────────────
|
package/scripts/sw-durable.sh
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
set -euo pipefail
|
|
8
8
|
trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
|
|
9
9
|
|
|
10
|
-
VERSION="2.
|
|
10
|
+
VERSION="2.1.1"
|
|
11
11
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
12
12
|
|
|
13
13
|
# ─── Colors (matches Seth's tmux theme) ─────────────────────────────────────
|
package/scripts/sw-eventbus.sh
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
set -euo pipefail
|
|
8
8
|
trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
|
|
9
9
|
|
|
10
|
-
VERSION="2.
|
|
10
|
+
VERSION="2.1.1"
|
|
11
11
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
12
12
|
|
|
13
13
|
# ─── Colors (matches Seth's tmux theme) ─────────────────────────────────────
|
package/scripts/sw-feedback.sh
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
set -euo pipefail
|
|
7
7
|
trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
|
|
8
8
|
|
|
9
|
-
VERSION="2.
|
|
9
|
+
VERSION="2.1.1"
|
|
10
10
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
11
|
REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
12
12
|
|
|
@@ -59,7 +59,7 @@ emit_event() {
|
|
|
59
59
|
INCIDENTS_FILE="${HOME}/.shipwright/incidents.jsonl"
|
|
60
60
|
ERROR_THRESHOLD=5 # Create issue if error count >= threshold
|
|
61
61
|
ERROR_LOG_DIR="${REPO_DIR}/.claude/pipeline-artifacts"
|
|
62
|
-
ARTIFACTS_DIR="${REPO_DIR}/.claude/pipeline-artifacts"
|
|
62
|
+
ARTIFACTS_DIR="${ARTIFACTS_DIR:-${REPO_DIR}/.claude/pipeline-artifacts}"
|
|
63
63
|
|
|
64
64
|
# ─── Initialize directories ────────────────────────────────────────────────
|
|
65
65
|
ensure_dirs() {
|
|
@@ -220,6 +220,12 @@ cmd_create_issue() {
|
|
|
220
220
|
|
|
221
221
|
info "Creating GitHub issue for regression..."
|
|
222
222
|
|
|
223
|
+
# Check if NO_GITHUB is set before attempting GitHub operations
|
|
224
|
+
if [[ "${NO_GITHUB:-}" == "true" || "${NO_GITHUB:-}" == "1" ]]; then
|
|
225
|
+
warn "NO_GITHUB set — skipping GitHub issue creation"
|
|
226
|
+
return 0
|
|
227
|
+
fi
|
|
228
|
+
|
|
223
229
|
# Get repo info
|
|
224
230
|
local owner_repo
|
|
225
231
|
owner_repo=$(get_owner_repo) || {
|
|
@@ -267,12 +273,6 @@ git show $regression_commit
|
|
|
267
273
|
EOF
|
|
268
274
|
)
|
|
269
275
|
|
|
270
|
-
# Check if gh is available and NO_GITHUB is not set
|
|
271
|
-
if [[ "${NO_GITHUB:-}" == "true" || "${NO_GITHUB:-}" == "1" ]]; then
|
|
272
|
-
warn "NO_GITHUB set — skipping GitHub issue creation"
|
|
273
|
-
return 0
|
|
274
|
-
fi
|
|
275
|
-
|
|
276
276
|
if ! command -v gh &>/dev/null; then
|
|
277
277
|
error "gh CLI not found — cannot create issue"
|
|
278
278
|
return 1
|
|
@@ -319,20 +319,28 @@ cmd_rollback() {
|
|
|
319
319
|
return 1
|
|
320
320
|
}
|
|
321
321
|
|
|
322
|
-
#
|
|
323
|
-
|
|
322
|
+
# Trigger real rollback via sw-github-deploy.sh (GitHub Deployments API)
|
|
323
|
+
local rollback_status="initiated"
|
|
324
|
+
local rollback_rc=0
|
|
325
|
+
bash "$SCRIPT_DIR/sw-github-deploy.sh" rollback "$environment" 2>&1 | tee -a "${ARTIFACTS_DIR}/rollback-output.log"
|
|
326
|
+
rollback_rc=${PIPESTATUS[0]:-$?}
|
|
327
|
+
if [[ "$rollback_rc" -eq 0 ]]; then
|
|
328
|
+
rollback_status="executed"
|
|
329
|
+
success "Rollback executed for $environment via GitHub Deployments API"
|
|
330
|
+
else
|
|
331
|
+
warn "GitHub Deployments rollback failed or unavailable (exit $rollback_rc, see rollback-output.log)"
|
|
332
|
+
fi
|
|
333
|
+
|
|
324
334
|
local rollback_entry
|
|
325
335
|
rollback_entry=$(jq -n \
|
|
326
336
|
--arg ts "$(now_iso)" \
|
|
327
337
|
--arg env "$environment" \
|
|
328
338
|
--arg reason "$reason" \
|
|
329
|
-
|
|
339
|
+
--arg status "$rollback_status" \
|
|
340
|
+
'{timestamp: $ts, environment: $env, reason: $reason, status: $status}')
|
|
330
341
|
|
|
331
342
|
echo "$rollback_entry" >> "${ARTIFACTS_DIR}/rollbacks.jsonl"
|
|
332
|
-
|
|
333
|
-
success "Rollback initiated for $environment"
|
|
334
|
-
emit_event "feedback_rollback" "environment=$environment" "reason=$reason"
|
|
335
|
-
info "Note: Full rollback requires manual GitHub Deployments API call"
|
|
343
|
+
emit_event "feedback_rollback" "environment=$environment" "reason=$reason" "status=$rollback_status"
|
|
336
344
|
}
|
|
337
345
|
|
|
338
346
|
# ─── Capture incident in memory system ───────────────────────────────────────
|
package/scripts/sw-fix.sh
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
set -euo pipefail
|
|
7
7
|
trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
|
|
8
8
|
|
|
9
|
-
VERSION="2.
|
|
9
|
+
VERSION="2.1.1"
|
|
10
10
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
11
|
|
|
12
12
|
# ─── Colors (matches Seth's tmux theme) ─────────────────────────────────────
|
package/scripts/sw-fleet-viz.sh
CHANGED
package/scripts/sw-fleet.sh
CHANGED
package/scripts/sw-github-app.sh
CHANGED
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
set -euo pipefail
|
|
7
7
|
trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
|
|
8
8
|
|
|
9
|
-
VERSION="2.
|
|
10
|
-
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
|
-
REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
9
|
+
VERSION="2.1.1"
|
|
10
|
+
SCRIPT_DIR="${SCRIPT_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)}"
|
|
11
|
+
REPO_DIR="${REPO_DIR:-$(cd "$SCRIPT_DIR/.." && pwd)}"
|
|
12
12
|
|
|
13
13
|
# ─── Colors (matches Seth's tmux theme) ─────────────────────────────────────
|
|
14
14
|
CYAN='\033[38;2;0;212;255m' # #00d4ff — primary accent
|
|
@@ -516,6 +516,6 @@ main() {
|
|
|
516
516
|
}
|
|
517
517
|
|
|
518
518
|
# Only run main if executed directly (not sourced)
|
|
519
|
-
if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
|
|
519
|
+
if [[ "${BASH_SOURCE[0]:-}" == "$0" ]]; then
|
|
520
520
|
main "$@"
|
|
521
521
|
fi
|
package/scripts/sw-guild.sh
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
set -euo pipefail
|
|
7
7
|
trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
|
|
8
8
|
|
|
9
|
-
VERSION="2.
|
|
9
|
+
VERSION="2.1.1"
|
|
10
10
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
11
|
|
|
12
12
|
# ─── Colors (matches Seth's tmux theme) ─────────────────────────────────────
|
package/scripts/sw-heartbeat.sh
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
set -euo pipefail
|
|
7
7
|
trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
|
|
8
8
|
|
|
9
|
-
VERSION="2.
|
|
9
|
+
VERSION="2.1.1"
|
|
10
10
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
11
|
|
|
12
12
|
# ─── Colors (matches Seth's tmux theme) ─────────────────────────────────────
|
package/scripts/sw-hygiene.sh
CHANGED
package/scripts/sw-incident.sh
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
set -euo pipefail
|
|
7
7
|
trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
|
|
8
8
|
|
|
9
|
-
VERSION="2.
|
|
9
|
+
VERSION="2.1.1"
|
|
10
10
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
11
|
REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
12
12
|
|
|
@@ -252,12 +252,15 @@ See incident details: \`shipwright incident show $incident_id\`
|
|
|
252
252
|
This issue was automatically created by the incident commander.
|
|
253
253
|
"
|
|
254
254
|
|
|
255
|
+
# shipwright label so daemon picks up; hotfix for routing
|
|
255
256
|
local issue_url
|
|
256
|
-
issue_url=$(gh issue create --title "$title" --body "$body" --label "hotfix" 2>/dev/null || echo "")
|
|
257
|
+
issue_url=$(gh issue create --title "$title" --body "$body" --label "hotfix,shipwright" 2>/dev/null || echo "")
|
|
257
258
|
|
|
258
259
|
if [[ -n "$issue_url" ]]; then
|
|
259
260
|
success "Created hotfix issue: $issue_url"
|
|
260
|
-
|
|
261
|
+
local issue_num
|
|
262
|
+
issue_num=$(echo "$issue_url" | sed -n 's|.*/issues/\([0-9]*\)|\1|p')
|
|
263
|
+
[[ -n "$issue_num" ]] && echo "$issue_num"
|
|
261
264
|
return 0
|
|
262
265
|
fi
|
|
263
266
|
|
|
@@ -265,6 +268,33 @@ This issue was automatically created by the incident commander.
|
|
|
265
268
|
return 1
|
|
266
269
|
}
|
|
267
270
|
|
|
271
|
+
# Trigger pipeline for P0/P1 hotfix issue (auto-remediation)
|
|
272
|
+
trigger_pipeline_for_incident() {
|
|
273
|
+
local issue_num="$1"
|
|
274
|
+
local incident_id="$2"
|
|
275
|
+
if [[ -z "$issue_num" || ! "$issue_num" =~ ^[0-9]+$ ]]; then
|
|
276
|
+
return 0
|
|
277
|
+
fi
|
|
278
|
+
if [[ ! -x "$SCRIPT_DIR/sw-pipeline.sh" ]]; then
|
|
279
|
+
return 0
|
|
280
|
+
fi
|
|
281
|
+
info "Auto-triggering pipeline for P0/P1 hotfix issue #${issue_num} (incident: $incident_id)"
|
|
282
|
+
(cd "$REPO_DIR" && export REPO_DIR SCRIPT_DIR && bash "$SCRIPT_DIR/sw-pipeline.sh" start --issue "$issue_num" --template hotfix 2>/dev/null) &
|
|
283
|
+
emit_event "incident.pipeline_triggered" "incident_id=$incident_id" "issue=$issue_num"
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
# Execute rollback when auto_rollback_enabled (wire to sw-feedback / sw-github-deploy)
|
|
287
|
+
trigger_rollback_for_incident() {
|
|
288
|
+
local incident_id="$1"
|
|
289
|
+
local reason="${2:-P0/P1 incident}"
|
|
290
|
+
if [[ ! -x "$SCRIPT_DIR/sw-feedback.sh" ]]; then
|
|
291
|
+
return 0
|
|
292
|
+
fi
|
|
293
|
+
info "Auto-rollback triggered for incident $incident_id: $reason"
|
|
294
|
+
(cd "$REPO_DIR" && bash "$SCRIPT_DIR/sw-feedback.sh" rollback production "$reason" 2>/dev/null) || true
|
|
295
|
+
emit_event "incident.rollback_triggered" "incident_id=$incident_id" "reason=$reason"
|
|
296
|
+
}
|
|
297
|
+
|
|
268
298
|
# ─── Watch Command ─────────────────────────────────────────────────────────
|
|
269
299
|
|
|
270
300
|
cmd_watch() {
|
|
@@ -284,7 +314,7 @@ cmd_watch() {
|
|
|
284
314
|
# Background process
|
|
285
315
|
(
|
|
286
316
|
echo $$ > "$MONITOR_PID_FILE"
|
|
287
|
-
trap
|
|
317
|
+
trap 'rm -f "'"$MONITOR_PID_FILE"'"' EXIT
|
|
288
318
|
|
|
289
319
|
while true; do
|
|
290
320
|
sleep "$interval"
|
|
@@ -313,12 +343,21 @@ cmd_watch() {
|
|
|
313
343
|
info "Incident $incident_id created (severity: $severity)"
|
|
314
344
|
emit_event "incident.detected" "incident_id=$incident_id" "severity=$severity"
|
|
315
345
|
|
|
316
|
-
# Auto-response for P0/P1
|
|
346
|
+
# Auto-response for P0/P1: hotfix issue, trigger pipeline, optional rollback
|
|
317
347
|
if [[ "$severity" == "P0" ]] || [[ "$severity" == "P1" ]]; then
|
|
348
|
+
local auto_rollback
|
|
349
|
+
auto_rollback=$(jq -r '.auto_rollback_enabled // false' "$INCIDENT_CONFIG" 2>/dev/null || echo "false")
|
|
350
|
+
if [[ "$auto_rollback" == "true" ]]; then
|
|
351
|
+
trigger_rollback_for_incident "$incident_id" "P0/P1 incident: $root_cause"
|
|
352
|
+
fi
|
|
318
353
|
local auto_hotfix
|
|
319
354
|
auto_hotfix=$(jq -r '.p0_auto_hotfix // .p1_auto_hotfix' "$INCIDENT_CONFIG" 2>/dev/null || echo "false")
|
|
320
355
|
if [[ "$auto_hotfix" == "true" ]]; then
|
|
321
|
-
|
|
356
|
+
local issue_num
|
|
357
|
+
issue_num=$(create_hotfix_issue "$incident_id" "$severity" "$root_cause")
|
|
358
|
+
if [[ -n "$issue_num" ]]; then
|
|
359
|
+
trigger_pipeline_for_incident "$issue_num" "$incident_id"
|
|
360
|
+
fi
|
|
322
361
|
fi
|
|
323
362
|
fi
|
|
324
363
|
fi
|