Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 33 additions & 33 deletions TEMPLATES.md
Original file line number Diff line number Diff line change
Expand Up @@ -1572,7 +1572,7 @@ ALTER TABLE `users` ADD INDEX `idx_email`(`email`);
ALTER TABLE `orders` ADD INDEX `idx_user_id`(`user_id`);
```

**`products`**: ⊘ Cancelled (not started)
**`products`**: 🚫 Cancelled (not started)

```sql
ALTER TABLE `products` ADD INDEX `idx_price`(`price_cents`);
Expand Down Expand Up @@ -3908,13 +3908,13 @@ _Last updated: <relative-time datetime="2026-01-01T00:00:00Z">2026-01-01 00:00:0
ALTER TABLE `orders` ADD INDEX `idx_user_id`(`user_id`);
```

**`users`**: ⊘ Cancelled (not started)
**`users`**: 🚫 Cancelled (not started)

```sql
ALTER TABLE `users` ADD INDEX `idx_email`(`email`);
```

**`products`**: ⊘ Cancelled (not started)
**`products`**: 🚫 Cancelled (not started)

```sql
ALTER TABLE `products` ADD INDEX `idx_price`(`price_cents`);
Expand Down Expand Up @@ -3961,7 +3961,7 @@ ALTER TABLE `users` ADD INDEX `idx_email`(`email`);
ALTER TABLE `orders` ADD INDEX `idx_user_id`(`user_id`);
```

**`products`**: ⊘ Cancelled (not started)
**`products`**: 🚫 Cancelled (not started)

```sql
ALTER TABLE `products` ADD INDEX `idx_price`(`price_cents`);
Expand Down Expand Up @@ -4003,13 +4003,13 @@ ALTER TABLE `orders` MODIFY COLUMN `status` enum('NEW','PENDING','SHIPPED','DELI
```
> ❌ Last error: preflight enumReorder check failed: reordering existing ENUM values on column `status` is unsafe: retained values must keep their relative order and new values must be appended at the end

**`users`**: ⊘ Cancelled (not started)
**`users`**: 🚫 Cancelled (not started)

```sql
ALTER TABLE `users` ADD INDEX `idx_email`(`email`);
```

**`products`**: ⊘ Cancelled (not started)
**`products`**: 🚫 Cancelled (not started)

```sql
ALTER TABLE `products` ADD INDEX `idx_price`(`price_cents`);
Expand Down Expand Up @@ -4119,7 +4119,7 @@ _Last updated: <relative-time datetime="2026-01-01T00:00:00Z">2026-01-01 00:00:0
ALTER TABLE `orders` ADD INDEX `idx_user_id`(`user_id`);
```

**`users`**: ⊘ Cancelled (not started)
**`users`**: 🚫 Cancelled (not started)

```sql
ALTER TABLE `users` ADD INDEX `idx_email`(`email`);
Expand Down Expand Up @@ -5140,7 +5140,7 @@ ALTER TABLE `payments` ADD INDEX `idx_order_id`(`order_id`);
```


### ⊘ analytics
### 🚫 analytics

**`events`** β€” Cancelled
```sql
Expand Down Expand Up @@ -5734,10 +5734,10 @@ Sequential mode: First table failed (others cancelled)
~ users: πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯⬜⬜⬜⬜⬜⬜⬜ ❌ Failed
ALTER TABLE `users` ADD INDEX `idx_email_created`(`email`, `created_at`);

~ orders: ⊘ Cancelled (not started)
~ orders: 🚫 Cancelled (not started)
ALTER TABLE `orders` ADD INDEX `idx_user_status`(`user_id`, `status`);

~ products: ⊘ Cancelled (not started)
~ products: 🚫 Cancelled (not started)
ALTER TABLE `products` ADD COLUMN `weight_grams` int DEFAULT 0;


Expand Down Expand Up @@ -5770,7 +5770,7 @@ Sequential mode: Middle table failed
~ users: 🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩 βœ“ Complete
ALTER TABLE `users` ADD INDEX `idx_email_created`(`email`, `created_at`);

~ products: ⊘ Cancelled (not started)
~ products: 🚫 Cancelled (not started)
ALTER TABLE `products` ADD COLUMN `weight_grams` int DEFAULT 0;


Expand Down Expand Up @@ -6148,7 +6148,7 @@ Press Enter to deploy or proceed via the PlanetScale console (ESC to detach)

── myapp_sharded ──

~ orders: 🟧🟧🟧🟧🟧🟧⬜⬜⬜⬜⬜⬜⬜⬜⬜⬜⬜⬜⬜⬜ ⊘ Cancelled at 30%
~ orders: 🟧🟧🟧🟧🟧🟧⬜⬜⬜⬜⬜⬜⬜⬜⬜⬜⬜⬜⬜⬜ 🚫 Cancelled at 30%
ALTER TABLE `orders` ADD INDEX `idx_total`(`total_cents`);

β€’ Shards: 2 (2 cancelled)
Expand Down Expand Up @@ -6698,7 +6698,7 @@ ESC detach β€’ s stop β€’ v volume

Stop command: User runs 'schemabot stop -e staging <apply_id>'

⏸️ Schema change stopped
⏹️ Schema change stopped

Database: myapp
Environment: staging
Expand Down Expand Up @@ -7059,8 +7059,8 @@ schemabot apply -e production

- βœ… eu β€” completed
- ❌ us β€” failed
- ⏸ au β€” halted β€” us failed
- ⏸ ca β€” halted β€” us failed
- ⏸️ au β€” halted β€” us failed
- ⏸️ ca β€” halted β€” us failed

<details>
<summary>βœ… eu β€” completed</summary>
Expand Down Expand Up @@ -7122,7 +7122,7 @@ ALTER TABLE `users` ADD INDEX `idx_email`(`email`);
ALTER TABLE `orders` ADD INDEX `idx_user_id`(`user_id`);
```

**`products`**: ⊘ Cancelled (not started)
**`products`**: 🚫 Cancelled (not started)

```sql
ALTER TABLE `products` ADD INDEX `idx_price`(`price_cents`);
Expand All @@ -7141,14 +7141,14 @@ schemabot apply -e production
</details>

<details open>
<summary>⏸ au β€” halted β€” us failed</summary>
<summary>⏸️ au β€” halted β€” us failed</summary>

_No details available yet._

</details>

<details open>
<summary>⏸ ca β€” halted β€” us failed</summary>
<summary>⏸️ ca β€” halted β€” us failed</summary>

_No details available yet._

Expand Down Expand Up @@ -7420,8 +7420,8 @@ schemabot apply -e production

- βœ… eu β€” completed
- ❌ us β€” failed
- ⏸ au β€” halted β€” us failed
- ⏸ ca β€” halted β€” us failed
- ⏸️ au β€” halted β€” us failed
- ⏸️ ca β€” halted β€” us failed

<details>
<summary>βœ… eu β€” completed</summary>
Expand Down Expand Up @@ -7497,14 +7497,14 @@ schemabot apply -e production
</details>

<details open>
<summary>⏸ au β€” halted β€” us failed</summary>
<summary>⏸️ au β€” halted β€” us failed</summary>

_No details available yet._

</details>

<details open>
<summary>⏸ ca β€” halted β€” us failed</summary>
<summary>⏸️ ca β€” halted β€” us failed</summary>

_No details available yet._

Expand Down Expand Up @@ -7713,9 +7713,9 @@ _Last updated: <relative-time datetime="2026-01-01T00:00:00Z">2026-01-01 00:00:0
| Shard | Status |
| --- | --- |
| `-40` | ❌ failed β€” resolve shard primary for `-40`: context deadline exceeded |
| `40-80` | ⏸ halted β€” -40 failed |
| `80-c0` | ⏸ halted β€” -40 failed |
| `c0-` | ⏸ halted β€” -40 failed |
| `40-80` | ⏸️ halted β€” -40 failed |
| `80-c0` | ⏸️ halted β€” -40 failed |
| `c0-` | ⏸️ halted β€” -40 failed |

---

Expand Down Expand Up @@ -7865,9 +7865,9 @@ _Last updated: <relative-time datetime="2026-01-01T00:00:00Z">2026-01-01 00:00:0
| Shard | Status |
| --- | --- |
| `-40` | ❌ failed β€” resolve shard primary for `-40`: context deadline exceeded |
| `40-80` | ⏸ halted β€” -40 failed |
| `80-c0` | ⏸ halted β€” -40 failed |
| `c0-` | ⏸ halted β€” -40 failed |
| `40-80` | ⏸️ halted β€” -40 failed |
| `80-c0` | ⏸️ halted β€” -40 failed |
| `c0-` | ⏸️ halted β€” -40 failed |

### VSchema

Expand Down Expand Up @@ -7958,9 +7958,9 @@ schemabot apply -e production
ALTER TABLE `orders` ADD INDEX `idx_orders_source`(`source`);


⏸ ap-south β€” halted β€” eu-west failed (orders-ap-south)
⏸️ ap-south β€” halted β€” eu-west failed (orders-ap-south)

~ orders: ⊘ Cancelled (not started)
~ orders: 🚫 Cancelled (not started)
ALTER TABLE `orders` ADD COLUMN `source` varchar(32);


Expand Down Expand Up @@ -8163,10 +8163,10 @@ Sequential mode: First table failed (others cancelled)
~ users: πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯⬜⬜⬜⬜⬜⬜⬜ ❌ Failed
ALTER TABLE `users` ADD INDEX `idx_email_created`(`email`, `created_at`);

~ orders: ⊘ Cancelled (not started)
~ orders: 🚫 Cancelled (not started)
ALTER TABLE `orders` ADD INDEX `idx_user_status`(`user_id`, `status`);

~ products: ⊘ Cancelled (not started)
~ products: 🚫 Cancelled (not started)
ALTER TABLE `products` ADD COLUMN `weight_grams` int DEFAULT 0;


Expand Down Expand Up @@ -8199,7 +8199,7 @@ Sequential mode: Middle table failed
~ users: 🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩 βœ“ Complete
ALTER TABLE `users` ADD INDEX `idx_email_created`(`email`, `created_at`);

~ products: ⊘ Cancelled (not started)
~ products: 🚫 Cancelled (not started)
ALTER TABLE `products` ADD COLUMN `weight_grams` int DEFAULT 0;


Expand Down
2 changes: 1 addition & 1 deletion pkg/cmd/commands/watch_tui_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ func TestWatchModel_MultiDeploymentView(t *testing.T) {
"External operation ID: remote-op-us-east-test",
"External apply ID: remote-apply-us-east-test",
"❌ eu-west β€” failed (orders-eu-west)",
"⏸ ap-south β€” halted β€” eu-west failed (orders-ap-south)",
"⏸️ ap-south β€” halted β€” eu-west failed (orders-ap-south)",
)
assert.Contains(t, view, "duplicate key name 'idx_orders_source'")
assert.Contains(t, view, "orders")
Expand Down
8 changes: 4 additions & 4 deletions pkg/cmd/internal/templates/progress.go
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,7 @@ func FormatProgressState(s string) string {
case state.Apply.Failed:
return ANSIRed + "βœ— Failed" + ANSIReset
case state.Apply.Stopped:
return ANSIOrange + "⏸️ Stopped" + ANSIReset
return ANSIOrange + "⏹️ Stopped" + ANSIReset
case state.Apply.Cancelled:
return ANSIOrange + "🚫 Cancelled" + ANSIReset
case state.Apply.RevertWindow:
Expand Down Expand Up @@ -650,9 +650,9 @@ func FormatTableProgressWithActivity(t TableProgress, activityBar, activityLabel
if t.PercentComplete > 0 || t.RowsCopied > 0 {
cancelledPercent := ui.RowCopyDisplayPercent(t.PercentComplete, t.RowsCopied)
bar := ui.ProgressBar(cancelledPercent, ui.ColorOrange)
fmt.Fprintf(&b, indentTable+progressSymbol(t.ChangeType)+"%s: %s ⊘ Cancelled at %d%%\n", t.TableName, bar, cancelledPercent)
fmt.Fprintf(&b, indentTable+progressSymbol(t.ChangeType)+"%s: %s 🚫 Cancelled at %d%%\n", t.TableName, bar, cancelledPercent)
} else {
fmt.Fprintf(&b, indentTable+progressSymbol(t.ChangeType)+"%s: ⊘ Cancelled (not started)\n", t.TableName)
fmt.Fprintf(&b, indentTable+progressSymbol(t.ChangeType)+"%s: 🚫 Cancelled (not started)\n", t.TableName)
}
if t.DDL != "" {
b.WriteString(formatProgressDDLForDialect(t.Dialect, t.DDL))
Expand Down Expand Up @@ -838,7 +838,7 @@ type StopData struct {

// WriteStopSuccess writes the stop command success output.
func WriteStopSuccess(data StopData) {
fmt.Printf("%s%s⏸️ Schema change stopped%s\n", ANSIBold, ANSIYellow, ANSIReset)
fmt.Printf("%s%s⏹️ Schema change stopped%s\n", ANSIBold, ANSIYellow, ANSIReset)
fmt.Println()
fmt.Printf("Database: %s\n", data.Database)
fmt.Printf("Environment: %s\n", data.Environment)
Expand Down
2 changes: 1 addition & 1 deletion pkg/cmd/internal/templates/progress_multi_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func TestWriteProgressMultiDeploymentRendersAggregateAndSections(t *testing.T) {
assertLess(t, output, "βœ… region-a β€” completed", "❌ region-b β€” failed")
assert.Contains(t, output, "External operation ID: remote-region-a")
assert.Contains(t, output, "External apply ID: remote-apply-region-a")
assertLess(t, output, "❌ region-b β€” failed", "⏸ region-c β€” halted β€” region-b failed")
assertLess(t, output, "❌ region-b β€” failed", "⏸️ region-c β€” halted β€” region-b failed")
assert.Contains(t, output, "users_a")
assert.Contains(t, output, "users_b")
assert.Contains(t, output, "users_c")
Expand Down
2 changes: 1 addition & 1 deletion pkg/cmd/internal/templates/progress_states_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -950,7 +950,7 @@ func TestFormatTableProgressOperatorHaltedBars(t *testing.T) {
RowsCopied: 300,
RowsTotal: 1000,
})
assert.Contains(t, cancelled, "⊘ Cancelled at 30%")
assert.Contains(t, cancelled, "🚫 Cancelled at 30%")
assert.Contains(t, cancelled, ui.ColorOrange)
assert.NotContains(t, cancelled, ui.ColorRed)

Expand Down
8 changes: 4 additions & 4 deletions pkg/presentation/presentation.go
Original file line number Diff line number Diff line change
Expand Up @@ -285,11 +285,11 @@ func deriveDeployment(ops []Operation, i int) Deployment {
case state.ApplyOperation.FailedRetryable:
d.set(StateRetrying, "retrying", "πŸ”", true)
case state.ApplyOperation.Stopped:
d.set(StateStopped, "stopped β€” resume to continue", "⏸", true)
d.set(StateStopped, "stopped β€” resume to continue", "⏹️", true)
case state.ApplyOperation.RevertWindow:
d.set(StateRevertWindow, "in revert window", "⏳", true)
case state.ApplyOperation.Cancelled:
d.set(StateCancelled, "cancelled", "β›”", false)
d.set(StateCancelled, "cancelled", "🚫", false)
case state.ApplyOperation.Reverted:
d.set(StateReverted, "reverted", "↩️", false)
case state.ApplyOperation.Pending:
Expand Down Expand Up @@ -319,10 +319,10 @@ func derivePending(d *Deployment, ops []Operation, i int) {
}
if h, paused := blockingSibling(ops, i); h != nil {
if paused {
d.set(StatePaused, fmt.Sprintf("paused β€” %s failed; release or stop", h.Deployment), "⏸", true)
d.set(StatePaused, fmt.Sprintf("paused β€” %s failed; release or stop", h.Deployment), "⏸️", true)
return
}
d.set(StateHalted, fmt.Sprintf("halted β€” %s %s", h.Deployment, haltedReason(h.State)), "⏸", true)
d.set(StateHalted, fmt.Sprintf("halted β€” %s %s", h.Deployment, haltedReason(h.State)), "⏸️", true)
return
}
for j := range i {
Expand Down
4 changes: 2 additions & 2 deletions pkg/presentation/presentation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,9 @@ func TestDeriveDeployment_StateLabels(t *testing.T) {
{so.CuttingOver, StateCuttingOver, "cutting over", "πŸ”", true},
{so.Failed, StateFailed, "failed", "❌", true},
{so.FailedRetryable, StateRetrying, "retrying", "πŸ”", true},
{so.Stopped, StateStopped, "stopped β€” resume to continue", "⏸", true},
{so.Stopped, StateStopped, "stopped β€” resume to continue", "⏹️", true},
{so.RevertWindow, StateRevertWindow, "in revert window", "⏳", true},
{so.Cancelled, StateCancelled, "cancelled", "β›”", false},
{so.Cancelled, StateCancelled, "cancelled", "🚫", false},
{so.Reverted, StateReverted, "reverted", "↩️", false},
{"some_engine_state", StateUnknown, "some_engine_state", "", true},
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/webhook/templates/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -849,7 +849,7 @@ func renderTableProgress(sb *strings.Builder, dialect schema.Dialect, table Tabl
}

case state.Task.Cancelled:
fmt.Fprintf(sb, "**`%s`**: \u2298 Cancelled (not started)\n", table.TableName)
fmt.Fprintf(sb, "**`%s`**: 🚫 Cancelled (not started)\n", table.TableName)
writeDDLLine(sb, dialect, table.DDL)

case state.Task.RevertWindow:
Expand Down Expand Up @@ -1661,7 +1661,7 @@ func groupStateEmoji(tables []TableProgressData) string {
return "⏹️"
}
if states[state.Task.Cancelled] && !states[state.Task.Completed] {
return "⊘"
return "🚫"
}
return "βœ…"
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/webhook/templates/apply_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -967,7 +967,7 @@ func TestRenderApplyStatusComment_Failed(t *testing.T) {
assert.Contains(t, result, "lock wait timeout exceeded")
assert.Contains(t, result, "πŸŸ₯") // red bar for failed table
assert.Contains(t, result, "❌ Failed")
assert.Contains(t, result, "⊘ Cancelled (not started)")
assert.Contains(t, result, "🚫 Cancelled (not started)")
// Progress summary
assert.Contains(t, result, "πŸ“Š 1/3 complete")
assert.Contains(t, result, "1 failed")
Expand Down
6 changes: 3 additions & 3 deletions pkg/webhook/templates/multi_apply_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,8 @@ func TestRenderMultiDeploymentApplyComment_FailedHalt(t *testing.T) {
assert.Contains(t, out, "schemabot apply -e production")
assert.NotContains(t, out, "schemabot revert")
assert.Contains(t, out, "- ❌ us β€” failed")
assert.Contains(t, out, "- ⏸ au β€” halted β€” us failed")
assert.Contains(t, out, "<details open>\n<summary>⏸ au β€” halted β€” us failed</summary>")
assert.Contains(t, out, "- ⏸️ au β€” halted β€” us failed")
assert.Contains(t, out, "<details open>\n<summary>⏸️ au β€” halted β€” us failed</summary>")
// With no error detail on the failed operation, the first-failure line names
// the deployment without a reason.
assert.Contains(t, out, "> ❌ **First failure:** <code>us</code>\n")
Expand Down Expand Up @@ -467,7 +467,7 @@ func TestRenderMultiDeploymentApplyComment_HaltedDetailUsesDerivedStatus(t *test
},
})

assert.Contains(t, out, "**Status**: ⏸ Halted β€” apse2 failed")
assert.Contains(t, out, "**Status**: ⏸️ Halted β€” apse2 failed")
assert.NotContains(t, out, "**Status**: Starting")
// The failed deployment keeps its raw-state gloss.
assert.Contains(t, out, "**Status**: Failed")
Expand Down
4 changes: 2 additions & 2 deletions pkg/webhook/templates/sharded_apply_tenant_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ func TestShardedApplyHintsCarryTenant(t *testing.T) {
Keyspaces: []ShardedKeyspace{{
Keyspace: "cdb_resolute_sharded",
Shards: []ShardStatus{
{Shard: "-40", Emoji: "⏸", Label: "stopped", State: state.ApplyOperation.Stopped},
{Shard: "80-", Emoji: "⏸", Label: "stopped", State: state.ApplyOperation.Stopped},
{Shard: "-40", Emoji: "⏹️", Label: "stopped", State: state.ApplyOperation.Stopped},
{Shard: "80-", Emoji: "⏹️", Label: "stopped", State: state.ApplyOperation.Stopped},
},
Cells: []ShardCell{mutesCell("-40"), mutesCell("80-")},
}},
Expand Down
Loading
Loading