wokku-cli 0.7.0 → 0.8.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/lib/wokku/commands/incidents.rb +65 -0
- data/lib/wokku/version.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: cce452abf4b37774f8aef5230edb8e3a1b88150ed88f69f9409474db937af0e6
|
|
4
|
+
data.tar.gz: a4b224d6cbcfa18aa08b5cf427c2dcab36c0ba5b5cb161647ce94f5abc043cc9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 69815ec5eb9d7869c7214190df8423632c94ad0e0f2a953ed09f0d9b5936aea0b0c431cc4ea5c3b7f3dd2d46f8263ea43d4ded955239f1794c3cf4a91eed924a
|
|
7
|
+
data.tar.gz: b43e5e78b17056f2ca1e82cf9e6cf60dd1d8977478654260201f5bd043d7685ed9117b28029712e2d2f61fe82cffa6468590d356315c92cf7ab70783c98622db
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.8.0 — 2026-10-23
|
|
4
|
+
|
|
5
|
+
- `incidents [--all] [--app APP]`, `incidents:info ID` — what is down now and recent outages.
|
|
6
|
+
- `alerts:mutes`, `alerts:mute [--app APP] [--event EVENT] [--for 1h|8h|1d]`, `alerts:unmute ID` — per-person push mutes.
|
|
7
|
+
- Coverage gate no longer needs ignores for `dynos.update`/`dynos.replace`/`servers.dokku` (deprecated in the contract).
|
|
8
|
+
|
|
3
9
|
## 0.7.0 — 2026-10-23
|
|
4
10
|
|
|
5
11
|
Full API parity for everything customers can do (CI now fails if the CLI falls behind the API contract).
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "time"
|
|
4
|
+
require "uri"
|
|
5
|
+
|
|
6
|
+
# --- Incidents & alert mutes ---
|
|
7
|
+
# Command files are required at top level, so helper names are prefixed to stay out of the global namespace.
|
|
8
|
+
def incidents_rows(list)
|
|
9
|
+
list.map do |x|
|
|
10
|
+
{ "id" => x["id"], "subject" => x["app_name"] || "server #{x['server_id']}", "reason" => x["reason"],
|
|
11
|
+
"started" => x["started_at"].to_s[0..18], "status" => x["open"] ? "OPEN" : "resolved after #{x['duration_seconds']}s" }
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def incidents_flag_value(name)
|
|
16
|
+
i = ARGV.index(name) or return nil
|
|
17
|
+
ARGV.delete_at(i)
|
|
18
|
+
ARGV.delete_at(i) || abort("Missing value for #{name}")
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
register "incidents", "List incidents (usage: wokku incidents [--all] [--app APP])" do
|
|
22
|
+
query = { state: ARGV.delete("--all") ? "all" : "open" }
|
|
23
|
+
app = incidents_flag_value("--app")
|
|
24
|
+
query[:app_id] = app if app
|
|
25
|
+
data = api(:get, "/incidents?#{URI.encode_www_form(query)}")
|
|
26
|
+
Wokku::Output.render(data) do |d|
|
|
27
|
+
next puts_json(d) unless d.is_a?(Array)
|
|
28
|
+
d.empty? ? puts("No incidents.") : table(incidents_rows(d))
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
register "incidents:info", "Show one incident (usage: wokku incidents:info ID)" do
|
|
33
|
+
id = ARGV.shift || abort("Usage: wokku incidents:info ID")
|
|
34
|
+
data = api(:get, "/incidents/#{id}")
|
|
35
|
+
Wokku::Output.render(data) { |d| puts_json d }
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
register "alerts:mutes", "List your push alert mutes (usage: wokku alerts:mutes)" do
|
|
39
|
+
data = api(:get, "/alert_mutes")
|
|
40
|
+
Wokku::Output.render(data) do |d|
|
|
41
|
+
next puts_json(d) unless d.is_a?(Array)
|
|
42
|
+
next puts("No mutes.") if d.empty?
|
|
43
|
+
table(d.map { |m| { "id" => m["id"], "app" => m["app_name"] || "(all apps)", "event" => m["event"] || "(all events)", "until" => m["until"].to_s[0..18].then { |u| u.empty? ? "(until unmuted)" : u } } })
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
MUTE_UNITS = { "m" => 60, "h" => 3600, "d" => 86_400 }.freeze
|
|
48
|
+
|
|
49
|
+
register "alerts:mute", "Mute push alerts on your phone (usage: wokku alerts:mute [--app APP] [--event EVENT] [--for 1h|8h|1d])" do
|
|
50
|
+
usage = "Usage: wokku alerts:mute [--app APP] [--event EVENT] [--for 1h|8h|1d]"
|
|
51
|
+
body = { app_id: incidents_flag_value("--app"), event: incidents_flag_value("--event") }.compact
|
|
52
|
+
abort "#{usage} (give --app and/or --event)" if body.empty?
|
|
53
|
+
if (span = incidents_flag_value("--for"))
|
|
54
|
+
m = span.match(/\A(\d+)([mhd])\z/) || abort("#{usage} (--for looks like 30m, 8h or 1d)")
|
|
55
|
+
body[:until] = (Time.now + m[1].to_i * MUTE_UNITS[m[2]]).utc.iso8601
|
|
56
|
+
end
|
|
57
|
+
data = api(:post, "/alert_mutes", body)
|
|
58
|
+
Wokku::Output.render(data) { |d| Wokku::Output.status "Muted (#{d['id']})." }
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
register "alerts:unmute", "Remove a push alert mute (usage: wokku alerts:unmute ID)" do
|
|
62
|
+
id = ARGV.shift || abort("Usage: wokku alerts:unmute ID")
|
|
63
|
+
api(:delete, "/alert_mutes/#{id}")
|
|
64
|
+
Wokku::Output.status "Unmuted."
|
|
65
|
+
end
|
data/lib/wokku/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: wokku-cli
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.8.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Johannes Dwicahyo
|
|
@@ -60,6 +60,7 @@ files:
|
|
|
60
60
|
- lib/wokku/commands/domains.rb
|
|
61
61
|
- lib/wokku/commands/github.rb
|
|
62
62
|
- lib/wokku/commands/https.rb
|
|
63
|
+
- lib/wokku/commands/incidents.rb
|
|
63
64
|
- lib/wokku/commands/logs.rb
|
|
64
65
|
- lib/wokku/commands/maintenance.rb
|
|
65
66
|
- lib/wokku/commands/mcp.rb
|