hecks 3.4.2 → 3.5.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/lib/hecks/deploy/bluebook/deploy.bluebook +1510 -3
- data/lib/hecks/deploy/bluebook/deploy.hecksagon +57 -0
- data/lib/hecks/deploy/oidc.json +225 -0
- data/lib/hecks/hecks/adapters/bluebook_report.rb +91 -0
- data/lib/hecks/hecks/adapters/deploy_plans.rb +49 -0
- data/lib/hecks/hecks/adapters/deploy_toolchain.rb +295 -14
- data/lib/hecks/hecks/adapters/in_process_operations.rb +6 -2
- data/lib/hecks/hecks/adapters/site_toolchain.rb +3 -3
- data/lib/hecks/hecks/custodian.bluebook +12 -2
- data/lib/hecks/hecks/hecks.hecksagon +57 -0
- data/lib/hecks/hecks/hecks.world +5 -1
- data/lib/hecks/projections/deploy/box/hosting.rb +13 -4
- data/lib/hecks/projections/deploy/box/roll_recipe.rb +62 -0
- data/lib/hecks/projections/deploy/box/templates/deploy-box.sh.tmpl +10 -3
- data/lib/hecks/projections/deploy/box/templates/deploy-service.services-roll.part +2 -2
- data/lib/hecks/projections/deploy/box/templates/deploy-service.sh.tmpl +16 -4
- data/lib/hecks/projections/deploy/box/templates/deploy-service.taskdef-roll.part +6 -6
- data/lib/hecks/projections/deploy/box/templates/deploy-service.taskdef.part +1 -1
- data/lib/hecks/projections/deploy/box/templates/hosting.mk.tmpl +6 -3
- data/lib/hecks/projections/deploy/box/templates/restore-to-rds.sh.tmpl +8 -3
- data/lib/hecks/projections/deploy/box/templates/verify-copy.sh.tmpl +2 -2
- data/lib/hecks/projections/deploy/box.rb +8 -14
- data/lib/hecks/projections/site/admin.rb +140 -0
- data/lib/hecks/projections/site/admin_cms/templates.rb +388 -0
- data/lib/hecks/projections/site/admin_cms.rb +72 -0
- data/lib/hecks/projections/site/payload/fields.rb +234 -0
- data/lib/hecks/projections/site/payload/lifecycle.rb +191 -0
- data/lib/hecks/projections/site/payload/model.rb +128 -0
- data/lib/hecks/projections/site/payload/specs.rb +179 -0
- data/lib/hecks/projections/site/payload_driver.rb +93 -0
- data/lib/hecks/projections/site/root_rows.rb +59 -0
- data/lib/hecks/projections/site/site_admin.rb +292 -0
- data/lib/hecks/projections/site/site_host/templates.rb +165 -0
- data/lib/hecks/projections/site/site_host.rb +58 -0
- data/lib/hecks/projections/site/site_root.rb +179 -0
- data/lib/hecks/site/bluebook/site.bluebook +7 -1
- data/lib/hecks/tools/site_routes.rb +78 -8
- data/lib/hecks/version.rb +1 -1
- data/rust/host/HECKS_RELEASE +1 -1
- metadata +17 -1
|
@@ -46,11 +46,68 @@ Hecks.hecksagon "Deploy" do
|
|
|
46
46
|
Deploy::SmokeRun.port "DeployToolchain" do
|
|
47
47
|
asks "Smoke", to: SmokeRun do
|
|
48
48
|
attribute :run, RunKey
|
|
49
|
+
attribute :after, Origin, default: { value: "alone" }
|
|
49
50
|
answers "SmokeAnswered"
|
|
50
51
|
refuses "SmokeRefused"
|
|
51
52
|
end
|
|
52
53
|
end
|
|
53
54
|
|
|
55
|
+
Deploy::ServiceRoll.port "DeployToolchain" do
|
|
56
|
+
asks "RollService", to: ServiceRoll do
|
|
57
|
+
attribute :run, RunKey
|
|
58
|
+
answers "ServiceRollAnswered"
|
|
59
|
+
refuses "ServiceRollRefused"
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
Deploy::BoxRoll.port "DeployToolchain" do
|
|
64
|
+
asks "RollBox", to: BoxRoll do
|
|
65
|
+
attribute :run, RunKey
|
|
66
|
+
answers "BoxRollAnswered"
|
|
67
|
+
refuses "BoxRollRefused"
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
Deploy::DataCopy.port "DeployToolchain" do
|
|
72
|
+
asks "CopyData", to: DataCopy do
|
|
73
|
+
attribute :run, RunKey
|
|
74
|
+
answers "DataCopyAnswered"
|
|
75
|
+
refuses "DataCopyRefused"
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
Deploy::CopyVerification.port "DeployToolchain" do
|
|
80
|
+
asks "CompareCopy", to: CopyVerification do
|
|
81
|
+
attribute :run, RunKey
|
|
82
|
+
answers "CopyVerificationAnswered"
|
|
83
|
+
refuses "CopyVerificationRefused"
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
Deploy::BluebookDiff.port "DeployToolchain" do
|
|
88
|
+
asks "CompareBluebooks", to: BluebookDiff do
|
|
89
|
+
attribute :run, RunKey
|
|
90
|
+
answers "BluebookDiffAnswered"
|
|
91
|
+
refuses "BluebookDiffRefused"
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
Deploy::PreviewRun.port "DeployToolchain" do
|
|
96
|
+
asks "RunPreview", to: PreviewRun do
|
|
97
|
+
attribute :run, RunKey
|
|
98
|
+
answers "PreviewRunAnswered"
|
|
99
|
+
refuses "PreviewRunRefused"
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
Deploy::CompanionRoll.port "DeployToolchain" do
|
|
104
|
+
asks "RollCompanion", to: CompanionRoll do
|
|
105
|
+
attribute :run, RunKey
|
|
106
|
+
answers "CompanionRollAnswered"
|
|
107
|
+
refuses "CompanionRollRefused"
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
54
111
|
Deploy::TemplateComparison.port "DeployToolchain" do
|
|
55
112
|
asks "Compare", to: TemplateComparison do
|
|
56
113
|
attribute :run, RunKey
|
data/lib/hecks/deploy/oidc.json
CHANGED
|
@@ -1,11 +1,101 @@
|
|
|
1
1
|
{
|
|
2
2
|
"audience": "Deploy",
|
|
3
3
|
"scopes": [
|
|
4
|
+
{
|
|
5
|
+
"scope": "deploy:bluebook_diff.differ",
|
|
6
|
+
"verb": "Deploy::BluebookDiff.Differ",
|
|
7
|
+
"role": null
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"scope": "deploy:bluebook_diff.flag",
|
|
11
|
+
"verb": "Deploy::BluebookDiff.Flag",
|
|
12
|
+
"role": null
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"scope": "deploy:bluebook_diff.match",
|
|
16
|
+
"verb": "Deploy::BluebookDiff.Match",
|
|
17
|
+
"role": null
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"scope": "deploy:bluebook_diff.run",
|
|
21
|
+
"verb": "Deploy::BluebookDiff.Run",
|
|
22
|
+
"role": null
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"scope": "deploy:bluebook_diff.withhold",
|
|
26
|
+
"verb": "Deploy::BluebookDiff.Withhold",
|
|
27
|
+
"role": null
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"scope": "deploy:box_roll.complete",
|
|
31
|
+
"verb": "Deploy::BoxRoll.Complete",
|
|
32
|
+
"role": null
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"scope": "deploy:box_roll.flag",
|
|
36
|
+
"verb": "Deploy::BoxRoll.Flag",
|
|
37
|
+
"role": null
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"scope": "deploy:box_roll.flag_smoke",
|
|
41
|
+
"verb": "Deploy::BoxRoll.FlagSmoke",
|
|
42
|
+
"role": null
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"scope": "deploy:box_roll.run",
|
|
46
|
+
"verb": "Deploy::BoxRoll.Run",
|
|
47
|
+
"role": null
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"scope": "deploy:box_roll.verify",
|
|
51
|
+
"verb": "Deploy::BoxRoll.Verify",
|
|
52
|
+
"role": null
|
|
53
|
+
},
|
|
4
54
|
{
|
|
5
55
|
"scope": "deploy:box_target.declare",
|
|
6
56
|
"verb": "Deploy::BoxTarget.Declare",
|
|
7
57
|
"role": null
|
|
8
58
|
},
|
|
59
|
+
{
|
|
60
|
+
"scope": "deploy:companion_roll.complete",
|
|
61
|
+
"verb": "Deploy::CompanionRoll.Complete",
|
|
62
|
+
"role": null
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"scope": "deploy:companion_roll.flag",
|
|
66
|
+
"verb": "Deploy::CompanionRoll.Flag",
|
|
67
|
+
"role": null
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"scope": "deploy:companion_roll.plan",
|
|
71
|
+
"verb": "Deploy::CompanionRoll.Plan",
|
|
72
|
+
"role": null
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"scope": "deploy:companion_roll.run",
|
|
76
|
+
"verb": "Deploy::CompanionRoll.Run",
|
|
77
|
+
"role": null
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"scope": "deploy:copy_verification.differ",
|
|
81
|
+
"verb": "Deploy::CopyVerification.Differ",
|
|
82
|
+
"role": null
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"scope": "deploy:copy_verification.flag",
|
|
86
|
+
"verb": "Deploy::CopyVerification.Flag",
|
|
87
|
+
"role": null
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
"scope": "deploy:copy_verification.match",
|
|
91
|
+
"verb": "Deploy::CopyVerification.Match",
|
|
92
|
+
"role": null
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
"scope": "deploy:copy_verification.run",
|
|
96
|
+
"verb": "Deploy::CopyVerification.Run",
|
|
97
|
+
"role": null
|
|
98
|
+
},
|
|
9
99
|
{
|
|
10
100
|
"scope": "deploy:cost_check.check",
|
|
11
101
|
"verb": "Deploy::CostCheck.Check",
|
|
@@ -21,6 +111,46 @@
|
|
|
21
111
|
"verb": "Deploy::CostCheck.Pass",
|
|
22
112
|
"role": null
|
|
23
113
|
},
|
|
114
|
+
{
|
|
115
|
+
"scope": "deploy:data_copy.complete",
|
|
116
|
+
"verb": "Deploy::DataCopy.Complete",
|
|
117
|
+
"role": null
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
"scope": "deploy:data_copy.confirm",
|
|
121
|
+
"verb": "Deploy::DataCopy.Confirm",
|
|
122
|
+
"role": null
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
"scope": "deploy:data_copy.drift",
|
|
126
|
+
"verb": "Deploy::DataCopy.Drift",
|
|
127
|
+
"role": null
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
"scope": "deploy:data_copy.flag",
|
|
131
|
+
"verb": "Deploy::DataCopy.Flag",
|
|
132
|
+
"role": null
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
"scope": "deploy:data_copy.flag_verification",
|
|
136
|
+
"verb": "Deploy::DataCopy.FlagVerification",
|
|
137
|
+
"role": null
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
"scope": "deploy:data_copy.plan",
|
|
141
|
+
"verb": "Deploy::DataCopy.Plan",
|
|
142
|
+
"role": null
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
"scope": "deploy:data_copy.restore",
|
|
146
|
+
"verb": "Deploy::DataCopy.Restore",
|
|
147
|
+
"role": null
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
"scope": "deploy:data_copy.verify",
|
|
151
|
+
"verb": "Deploy::DataCopy.Verify",
|
|
152
|
+
"role": null
|
|
153
|
+
},
|
|
24
154
|
{
|
|
25
155
|
"scope": "deploy:fargate_target.declare",
|
|
26
156
|
"verb": "Deploy::FargateTarget.Declare",
|
|
@@ -61,6 +191,76 @@
|
|
|
61
191
|
"verb": "Deploy::OidcManifest.ProjectOidc",
|
|
62
192
|
"role": null
|
|
63
193
|
},
|
|
194
|
+
{
|
|
195
|
+
"scope": "deploy:preview_run.deploy",
|
|
196
|
+
"verb": "Deploy::PreviewRun.Deploy",
|
|
197
|
+
"role": null
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
"scope": "deploy:preview_run.destroy",
|
|
201
|
+
"verb": "Deploy::PreviewRun.Destroy",
|
|
202
|
+
"role": null
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
"scope": "deploy:preview_run.flag",
|
|
206
|
+
"verb": "Deploy::PreviewRun.Flag",
|
|
207
|
+
"role": null
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
"scope": "deploy:preview_run.list",
|
|
211
|
+
"verb": "Deploy::PreviewRun.List",
|
|
212
|
+
"role": null
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
"scope": "deploy:preview_run.login",
|
|
216
|
+
"verb": "Deploy::PreviewRun.Login",
|
|
217
|
+
"role": null
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
"scope": "deploy:preview_run.name",
|
|
221
|
+
"verb": "Deploy::PreviewRun.Name",
|
|
222
|
+
"role": null
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
"scope": "deploy:preview_run.plan",
|
|
226
|
+
"verb": "Deploy::PreviewRun.Plan",
|
|
227
|
+
"role": null
|
|
228
|
+
},
|
|
229
|
+
{
|
|
230
|
+
"scope": "deploy:preview_run.record_deploy",
|
|
231
|
+
"verb": "Deploy::PreviewRun.RecordDeploy",
|
|
232
|
+
"role": null
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
"scope": "deploy:preview_run.record_destroy",
|
|
236
|
+
"verb": "Deploy::PreviewRun.RecordDestroy",
|
|
237
|
+
"role": null
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
"scope": "deploy:preview_run.record_list",
|
|
241
|
+
"verb": "Deploy::PreviewRun.RecordList",
|
|
242
|
+
"role": null
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
"scope": "deploy:preview_run.record_login",
|
|
246
|
+
"verb": "Deploy::PreviewRun.RecordLogin",
|
|
247
|
+
"role": null
|
|
248
|
+
},
|
|
249
|
+
{
|
|
250
|
+
"scope": "deploy:preview_run.record_name",
|
|
251
|
+
"verb": "Deploy::PreviewRun.RecordName",
|
|
252
|
+
"role": null
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
"scope": "deploy:preview_run.record_url",
|
|
256
|
+
"verb": "Deploy::PreviewRun.RecordUrl",
|
|
257
|
+
"role": null
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
"scope": "deploy:preview_run.url",
|
|
261
|
+
"verb": "Deploy::PreviewRun.Url",
|
|
262
|
+
"role": null
|
|
263
|
+
},
|
|
64
264
|
{
|
|
65
265
|
"scope": "deploy:recipe.complete",
|
|
66
266
|
"verb": "Deploy::Recipe.Complete",
|
|
@@ -76,6 +276,31 @@
|
|
|
76
276
|
"verb": "Deploy::Recipe.Project",
|
|
77
277
|
"role": null
|
|
78
278
|
},
|
|
279
|
+
{
|
|
280
|
+
"scope": "deploy:service_roll.complete",
|
|
281
|
+
"verb": "Deploy::ServiceRoll.Complete",
|
|
282
|
+
"role": null
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
"scope": "deploy:service_roll.flag",
|
|
286
|
+
"verb": "Deploy::ServiceRoll.Flag",
|
|
287
|
+
"role": null
|
|
288
|
+
},
|
|
289
|
+
{
|
|
290
|
+
"scope": "deploy:service_roll.flag_smoke",
|
|
291
|
+
"verb": "Deploy::ServiceRoll.FlagSmoke",
|
|
292
|
+
"role": null
|
|
293
|
+
},
|
|
294
|
+
{
|
|
295
|
+
"scope": "deploy:service_roll.run",
|
|
296
|
+
"verb": "Deploy::ServiceRoll.Run",
|
|
297
|
+
"role": null
|
|
298
|
+
},
|
|
299
|
+
{
|
|
300
|
+
"scope": "deploy:service_roll.verify",
|
|
301
|
+
"verb": "Deploy::ServiceRoll.Verify",
|
|
302
|
+
"role": null
|
|
303
|
+
},
|
|
79
304
|
{
|
|
80
305
|
"scope": "deploy:smoke_run.flag",
|
|
81
306
|
"verb": "Deploy::SmokeRun.Flag",
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "json"
|
|
4
|
+
|
|
5
|
+
module Hecks
|
|
6
|
+
module Adapters
|
|
7
|
+
# Which bluebook releases one deploy changes: two `hecks package.verify` outputs compared by
|
|
8
|
+
# bluebook name, version, shape and digest.
|
|
9
|
+
#
|
|
10
|
+
# A bluebook is added, removed, re-versioned (a new era when its shape changed too), or has the
|
|
11
|
+
# same version with different content (a vendored copy edited or re-tagged). The comparison is
|
|
12
|
+
# pure; reading the running image's label out of a registry is not done here.
|
|
13
|
+
class BluebookReport
|
|
14
|
+
ROW = " %-24s %s"
|
|
15
|
+
|
|
16
|
+
# @param old_json [String] the running side's `package.verify` output
|
|
17
|
+
# @param new_json [String] the side about to ship
|
|
18
|
+
# @param label [String] what the old side is called in the heading
|
|
19
|
+
# @raise [JSON::ParserError] when either side is not JSON
|
|
20
|
+
def initialize(old_json, new_json, label: "old")
|
|
21
|
+
@old = JSON.parse(old_json)
|
|
22
|
+
@new = JSON.parse(new_json)
|
|
23
|
+
@label = label
|
|
24
|
+
@changed = false
|
|
25
|
+
@era = false
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# @return [Boolean] whether any bluebook was added, removed, re-versioned or changed
|
|
29
|
+
def changed?
|
|
30
|
+
text
|
|
31
|
+
@changed
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# @return [String] the heading, one line per bluebook, the commits, and a note on a new era
|
|
35
|
+
def text
|
|
36
|
+
@text ||= build.join("\n")
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
private
|
|
40
|
+
|
|
41
|
+
def build
|
|
42
|
+
old_books = @old.fetch("bluebooks", {})
|
|
43
|
+
new_books = @new.fetch("bluebooks", {})
|
|
44
|
+
lines = ["==> bluebooks in this deploy (#{@label} -> this build)"]
|
|
45
|
+
(old_books.keys | new_books.keys).sort.each { |name| lines << row(name, old_books[name], new_books[name]) }
|
|
46
|
+
lines << commits
|
|
47
|
+
lines << " no bluebook changes." unless @changed
|
|
48
|
+
lines << " NOTE: a shape change mints a new era when the domain boots on it." if @era
|
|
49
|
+
lines
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def row(name, old, new)
|
|
53
|
+
return mark(name, "ADDED #{new['version']}") if old.nil?
|
|
54
|
+
return mark(name, "REMOVED (was #{old['version']})") if new.nil?
|
|
55
|
+
return reversioned(name, old, new) if old["version"] != new["version"]
|
|
56
|
+
return same_version_changed(name, old, new) if old["digest"] != new["digest"]
|
|
57
|
+
|
|
58
|
+
format(ROW, name, "#{new['version']} unchanged")
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def same_version_changed(name, old, new)
|
|
62
|
+
mark(name, "#{new['version']} SAME VERSION, DIFFERENT CONTENT (digest #{old['digest'][0, 8]} -> " \
|
|
63
|
+
"#{new['digest'][0, 8]}); a vendored copy was edited or re-tagged")
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def reversioned(name, old, new)
|
|
67
|
+
line = "#{old['version']} -> #{new['version']}"
|
|
68
|
+
if old["shape"] != new["shape"]
|
|
69
|
+
line += " shape #{shape(old)} -> #{shape(new)} NEW ERA (its translation edge must already be in " \
|
|
70
|
+
"bluebook/translations/)"
|
|
71
|
+
@era = true
|
|
72
|
+
end
|
|
73
|
+
mark(name, line)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def mark(name, text)
|
|
77
|
+
@changed = true
|
|
78
|
+
format(ROW, name, text)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def shape(book) = book["shape"].map { |entry| entry.split.last }.join(", ")
|
|
82
|
+
|
|
83
|
+
def commits
|
|
84
|
+
old = @old.dig("built_from", "commit") || "?"
|
|
85
|
+
new = @new.dig("built_from", "commit") || "?"
|
|
86
|
+
dirty = @new.dig("built_from", "dirty") ? " (uncommitted changes)" : ""
|
|
87
|
+
" built from #{old[0, 7]} -> #{new[0, 7]}#{dirty}"
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Hecks
|
|
4
|
+
module Adapters
|
|
5
|
+
# The plan a write to AWS prints when it is refused unconfirmed or run with `dry_run`: what the
|
|
6
|
+
# project's script would do, read from the script's own text, so nothing is run to say it.
|
|
7
|
+
module DeployPlans
|
|
8
|
+
module_function
|
|
9
|
+
|
|
10
|
+
# What `preview.sh <action>` would do for a branch.
|
|
11
|
+
#
|
|
12
|
+
# @param text [String] the preview script's source
|
|
13
|
+
# @param action [String] `deploy`, `destroy` or `login`
|
|
14
|
+
# @param branch [String, nil] the branch named, or nil for the checked-out one
|
|
15
|
+
# @return [String]
|
|
16
|
+
def preview(text, action, branch)
|
|
17
|
+
stack = "#{variable(text, 'PREFIX') || '<prefix>'}-<name derived from #{branch || 'the checked-out branch'}>"
|
|
18
|
+
region = variable(text, "REGION")
|
|
19
|
+
where = region ? " in #{region}" : ""
|
|
20
|
+
case action
|
|
21
|
+
when "deploy"
|
|
22
|
+
"push the locally built images and create or update the preview stack #{stack}#{where}, " \
|
|
23
|
+
"create its database and start its service"
|
|
24
|
+
when "destroy" then "empty the preview's storage and delete the preview stack #{stack}#{where}"
|
|
25
|
+
else "read the session secret of the preview stack #{stack}#{where} and mint a signed-in admin session"
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# What `deploy-<companion>.sh` would roll, and onto which box.
|
|
30
|
+
#
|
|
31
|
+
# @param text [String] the companion script's source
|
|
32
|
+
# @param companion [String] the companion's name
|
|
33
|
+
# @param taskdef [String] the task definition its image and settings are read from
|
|
34
|
+
# @return [String]
|
|
35
|
+
def companion(text, companion, taskdef)
|
|
36
|
+
stack = text[/out\s+(\S+)\s+InstanceId/, 1]
|
|
37
|
+
project = text[/compose -p (\w+)/, 1] || companion
|
|
38
|
+
directory = text[%r{mkdir -p (/\S+)}, 1]
|
|
39
|
+
place = directory ? " in #{directory}" : String.new
|
|
40
|
+
"roll #{companion} (Compose project #{project}#{place}) from task definition " \
|
|
41
|
+
"#{taskdef} onto the box of stack #{stack || '<box stack>'} over SSM, beside the app's project, " \
|
|
42
|
+
"then check it on the box"
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# The value a script assigns to an upper-case variable at the start of a line.
|
|
46
|
+
def variable(text, name) = text[/^#{name}=["']?([^"'\s]+)/, 1]
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|