ci-buildbot 0.11.0__py3-none-any.whl
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.
- ci_buildbot/__init__.py +1 -0
- ci_buildbot/cli.py +420 -0
- ci_buildbot/context_processors/__init__.py +8 -0
- ci_buildbot/context_processors/base.py +27 -0
- ci_buildbot/context_processors/codebuild.py +53 -0
- ci_buildbot/context_processors/deployfish.py +32 -0
- ci_buildbot/context_processors/docker.py +39 -0
- ci_buildbot/context_processors/generic.py +17 -0
- ci_buildbot/context_processors/git.py +240 -0
- ci_buildbot/context_processors/project.py +167 -0
- ci_buildbot/context_processors/unittest.py +58 -0
- ci_buildbot/exc.py +4 -0
- ci_buildbot/messages/__init__.py +33 -0
- ci_buildbot/messages/archive.py +24 -0
- ci_buildbot/messages/base.py +68 -0
- ci_buildbot/messages/deployfish.py +52 -0
- ci_buildbot/messages/deployfish_tasks.py +52 -0
- ci_buildbot/messages/docker.py +54 -0
- ci_buildbot/messages/docs.py +48 -0
- ci_buildbot/messages/general.py +40 -0
- ci_buildbot/messages/unittests.py +39 -0
- ci_buildbot/settings.py +36 -0
- ci_buildbot/templates/archive.tpl +42 -0
- ci_buildbot/templates/deploy_failed.tpl +26 -0
- ci_buildbot/templates/deploy_start.tpl +27 -0
- ci_buildbot/templates/deploy_success.tpl +26 -0
- ci_buildbot/templates/deploy_tasks_failed.tpl +26 -0
- ci_buildbot/templates/deploy_tasks_start.tpl +27 -0
- ci_buildbot/templates/deploy_tasks_success.tpl +26 -0
- ci_buildbot/templates/docker_failed.tpl +26 -0
- ci_buildbot/templates/docker_start.tpl +26 -0
- ci_buildbot/templates/docker_success.tpl +26 -0
- ci_buildbot/templates/docs_failed.tpl +26 -0
- ci_buildbot/templates/docs_start.tpl +27 -0
- ci_buildbot/templates/docs_success.tpl +26 -0
- ci_buildbot/templates/general_failed.tpl +26 -0
- ci_buildbot/templates/general_start.tpl +27 -0
- ci_buildbot/templates/general_success.tpl +26 -0
- ci_buildbot/templates/unittests_failed.tpl +26 -0
- ci_buildbot/templates/unittests_start.tpl +26 -0
- ci_buildbot/templates/unittests_success.tpl +26 -0
- ci_buildbot/typedefs.py +4 -0
- ci_buildbot-0.11.0.dist-info/METADATA +107 -0
- ci_buildbot-0.11.0.dist-info/RECORD +47 -0
- ci_buildbot-0.11.0.dist-info/WHEEL +5 -0
- ci_buildbot-0.11.0.dist-info/entry_points.txt +2 -0
- ci_buildbot-0.11.0.dist-info/top_level.txt +1 -0
ci_buildbot/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.11.0"
|
ci_buildbot/cli.py
ADDED
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
import pprint
|
|
3
|
+
import sys
|
|
4
|
+
|
|
5
|
+
import click
|
|
6
|
+
import slack
|
|
7
|
+
from slack.errors import SlackApiError
|
|
8
|
+
|
|
9
|
+
import ci_buildbot
|
|
10
|
+
|
|
11
|
+
from .messages import (
|
|
12
|
+
ArchiveCodeMessage,
|
|
13
|
+
DeployfishDeployFailureMessage,
|
|
14
|
+
DeployfishDeployStartMessage,
|
|
15
|
+
DeployfishDeploySuccessMessage,
|
|
16
|
+
DeployfishTasksDeployFailureMessage,
|
|
17
|
+
DeployfishTasksDeployStartMessage,
|
|
18
|
+
DeployfishTasksDeploySuccessMessage,
|
|
19
|
+
DockerFailureMessage,
|
|
20
|
+
DockerStartMessage,
|
|
21
|
+
DockerSuccessMessage,
|
|
22
|
+
DocsFailureMessage,
|
|
23
|
+
DocsStartMessage,
|
|
24
|
+
DocsSuccessMessage,
|
|
25
|
+
GeneralFailureMessage,
|
|
26
|
+
GeneralStartMessage,
|
|
27
|
+
GeneralSuccessMessage,
|
|
28
|
+
UnittestsFailureMessage,
|
|
29
|
+
UnittestsStartMessage,
|
|
30
|
+
UnittestsSuccessMessage,
|
|
31
|
+
)
|
|
32
|
+
from .settings import Settings
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@click.group(invoke_without_command=True)
|
|
36
|
+
@click.option(
|
|
37
|
+
"--version/--no-version",
|
|
38
|
+
"-v",
|
|
39
|
+
default=False,
|
|
40
|
+
help="Print the current version and exit.",
|
|
41
|
+
)
|
|
42
|
+
@click.pass_context
|
|
43
|
+
def cli(ctx, version):
|
|
44
|
+
"""
|
|
45
|
+
buildbot command line interaface.
|
|
46
|
+
"""
|
|
47
|
+
ctx.obj["settings"] = Settings()
|
|
48
|
+
ctx.obj["slack"] = slack.WebClient(token=ctx.obj["settings"].api_token)
|
|
49
|
+
|
|
50
|
+
if version:
|
|
51
|
+
print(ci_buildbot.__version__)
|
|
52
|
+
sys.exit(0)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
@cli.command("settings", short_help="Print our application settings.")
|
|
56
|
+
@click.pass_context
|
|
57
|
+
def settings(ctx):
|
|
58
|
+
"""
|
|
59
|
+
Print our settings to stdout. This should be the completely evaluated
|
|
60
|
+
settings including those imported from any environment variable.
|
|
61
|
+
"""
|
|
62
|
+
pp = pprint.PrettyPrinter(indent=2)
|
|
63
|
+
pp.pprint(ctx.obj["settings"].dict())
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
@cli.command("channels", short_help="Print our available channels.")
|
|
67
|
+
@click.pass_context
|
|
68
|
+
def channels(ctx):
|
|
69
|
+
pp = pprint.PrettyPrinter(indent=2)
|
|
70
|
+
pp.pprint(ctx.obj["slack"].conversations_list(types="private_channel")["channels"])
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
@cli.group("report", short_help="Report about a build step")
|
|
74
|
+
def report():
|
|
75
|
+
pass
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
@report.command("archive", short_help="Report about an archive-to-code-drop step")
|
|
79
|
+
@click.pass_context
|
|
80
|
+
def archive(ctx):
|
|
81
|
+
blocks = ArchiveCodeMessage().format()
|
|
82
|
+
client = ctx.obj["slack"]
|
|
83
|
+
try:
|
|
84
|
+
client.chat_postMessage(
|
|
85
|
+
channel=ctx.obj["settings"].channel, blocks=blocks, as_user=True
|
|
86
|
+
)
|
|
87
|
+
except SlackApiError as e:
|
|
88
|
+
print(f"Got an error: {e.response['error']}")
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
@report.group(
|
|
92
|
+
"docker",
|
|
93
|
+
short_help="A group of commands that report about a Docker bmage build step",
|
|
94
|
+
)
|
|
95
|
+
def report_docker():
|
|
96
|
+
pass
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
@report_docker.command("start", short_help="Report about starting a docker build")
|
|
100
|
+
@click.option(
|
|
101
|
+
"--changelog/--no-changelog", default=False, help="Include the git changelog."
|
|
102
|
+
)
|
|
103
|
+
@click.argument("image")
|
|
104
|
+
@click.pass_context
|
|
105
|
+
def report_docker_start(ctx, image: str, changelog: bool = False) -> None:
|
|
106
|
+
blocks = DockerStartMessage().format(image=image, changelog=changelog)
|
|
107
|
+
client = ctx.obj["slack"]
|
|
108
|
+
try:
|
|
109
|
+
client.chat_postMessage(
|
|
110
|
+
channel=ctx.obj["settings"].channel, blocks=blocks, as_user=True
|
|
111
|
+
)
|
|
112
|
+
except SlackApiError as e:
|
|
113
|
+
print(f"Got an error: {e.response['error']}")
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
@report_docker.command("success", short_help="Report a successful docker build")
|
|
117
|
+
@click.argument("image")
|
|
118
|
+
@click.pass_context
|
|
119
|
+
def report_docker_success(ctx, image):
|
|
120
|
+
blocks = DockerSuccessMessage().format(image=image)
|
|
121
|
+
client = ctx.obj["slack"]
|
|
122
|
+
try:
|
|
123
|
+
client.chat_postMessage(
|
|
124
|
+
channel=ctx.obj["settings"].channel, blocks=blocks, as_user=True
|
|
125
|
+
)
|
|
126
|
+
except SlackApiError as e:
|
|
127
|
+
print(f"Got an error: {e.response['error']}")
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
@report_docker.command("failure", short_help="Report a failed docker build")
|
|
131
|
+
@click.argument("image")
|
|
132
|
+
@click.pass_context
|
|
133
|
+
def report_docker_failure(ctx, image):
|
|
134
|
+
blocks = DockerFailureMessage().format(image=image)
|
|
135
|
+
client = ctx.obj["slack"]
|
|
136
|
+
try:
|
|
137
|
+
client.chat_postMessage(
|
|
138
|
+
channel=ctx.obj["settings"].channel, blocks=blocks, as_user=True
|
|
139
|
+
)
|
|
140
|
+
except SlackApiError as e:
|
|
141
|
+
print(f"Got an error: {e.response['error']}")
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
@report.group(
|
|
145
|
+
"unittests",
|
|
146
|
+
short_help="A group of commands that report about a test runner build step",
|
|
147
|
+
)
|
|
148
|
+
def report_unittests():
|
|
149
|
+
pass
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
@report_unittests.command(
|
|
153
|
+
"start", short_help="Report about starting a test runner build"
|
|
154
|
+
)
|
|
155
|
+
@click.pass_context
|
|
156
|
+
def report_unittests_start(ctx):
|
|
157
|
+
blocks = UnittestsStartMessage().format()
|
|
158
|
+
client = ctx.obj["slack"]
|
|
159
|
+
try:
|
|
160
|
+
client.chat_postMessage(
|
|
161
|
+
channel=ctx.obj["settings"].channel, blocks=blocks, as_user=True
|
|
162
|
+
)
|
|
163
|
+
except SlackApiError as e:
|
|
164
|
+
print(f"Got an error: {e.response['error']}")
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
@report_unittests.command("success", short_help="Report a successful test runner build")
|
|
168
|
+
@click.argument("report_group")
|
|
169
|
+
@click.pass_context
|
|
170
|
+
def report_unittests_success(ctx, report_group):
|
|
171
|
+
blocks = UnittestsSuccessMessage().format(report_group=report_group)
|
|
172
|
+
client = ctx.obj["slack"]
|
|
173
|
+
try:
|
|
174
|
+
client.chat_postMessage(
|
|
175
|
+
channel=ctx.obj["settings"].channel, blocks=blocks, as_user=True
|
|
176
|
+
)
|
|
177
|
+
except SlackApiError as e:
|
|
178
|
+
print(f"Got an error: {e.response['error']}")
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
@report_unittests.command("failure", short_help="Report a failed test runner build")
|
|
182
|
+
@click.argument("report_group")
|
|
183
|
+
@click.pass_context
|
|
184
|
+
def report_unittests_failure(ctx, report_group):
|
|
185
|
+
blocks = UnittestsFailureMessage().format(report_group=report_group)
|
|
186
|
+
client = ctx.obj["slack"]
|
|
187
|
+
try:
|
|
188
|
+
client.chat_postMessage(
|
|
189
|
+
channel=ctx.obj["settings"].channel, blocks=blocks, as_user=True
|
|
190
|
+
)
|
|
191
|
+
except SlackApiError as e:
|
|
192
|
+
print(f"Got an error: {e.response['error']}")
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
@report.group(
|
|
196
|
+
"deployfish",
|
|
197
|
+
short_help="A group of commands that report about a Deployfish service build step",
|
|
198
|
+
)
|
|
199
|
+
def report_deployfish():
|
|
200
|
+
pass
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
@report_deployfish.command(
|
|
204
|
+
"start", short_help="Report about starting a deployfish service deploy"
|
|
205
|
+
)
|
|
206
|
+
@click.argument("service")
|
|
207
|
+
@click.pass_context
|
|
208
|
+
def report_deployfish_start(ctx, service):
|
|
209
|
+
blocks = DeployfishDeployStartMessage().format(service=service)
|
|
210
|
+
client = ctx.obj["slack"]
|
|
211
|
+
try:
|
|
212
|
+
client.chat_postMessage(
|
|
213
|
+
channel=ctx.obj["settings"].channel, blocks=blocks, as_user=True
|
|
214
|
+
)
|
|
215
|
+
except SlackApiError as e:
|
|
216
|
+
print(f"Got an error: {e.response['error']}")
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
@report_deployfish.command(
|
|
220
|
+
"success", short_help="Report a successful deployfish service deploy"
|
|
221
|
+
)
|
|
222
|
+
@click.argument("service")
|
|
223
|
+
@click.pass_context
|
|
224
|
+
def report_deployfish_success(ctx, service):
|
|
225
|
+
blocks = DeployfishDeploySuccessMessage().format(service=service)
|
|
226
|
+
client = ctx.obj["slack"]
|
|
227
|
+
try:
|
|
228
|
+
client.chat_postMessage(
|
|
229
|
+
channel=ctx.obj["settings"].channel, blocks=blocks, as_user=True
|
|
230
|
+
)
|
|
231
|
+
except SlackApiError as e:
|
|
232
|
+
print(f"Got an error: {e.response['error']}")
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
@report_deployfish.command(
|
|
236
|
+
"failure", short_help="Report a failed deployfish service deploy"
|
|
237
|
+
)
|
|
238
|
+
@click.argument("service")
|
|
239
|
+
@click.pass_context
|
|
240
|
+
def report_deployfish_failure(ctx, service):
|
|
241
|
+
blocks = DeployfishDeployFailureMessage().format(service=service)
|
|
242
|
+
client = ctx.obj["slack"]
|
|
243
|
+
try:
|
|
244
|
+
client.chat_postMessage(
|
|
245
|
+
channel=ctx.obj["settings"].channel, blocks=blocks, as_user=True
|
|
246
|
+
)
|
|
247
|
+
except SlackApiError as e:
|
|
248
|
+
print(f"Got an error: {e.response['error']}")
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
@report.group(
|
|
252
|
+
"deployfish-tasks",
|
|
253
|
+
short_help="A group of commands that report about a Deployfish one-off tasks "
|
|
254
|
+
"build step",
|
|
255
|
+
)
|
|
256
|
+
def report_deployfish_tasks():
|
|
257
|
+
pass
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
@report_deployfish_tasks.command(
|
|
261
|
+
"start", short_help="Report about starting a deployfish one-off tasks deploy"
|
|
262
|
+
)
|
|
263
|
+
@click.argument("tasks", nargs=-1, required=True)
|
|
264
|
+
@click.pass_context
|
|
265
|
+
def report_deployfish_tasks_start(ctx, tasks):
|
|
266
|
+
blocks = DeployfishTasksDeployStartMessage().format(tasks=tasks)
|
|
267
|
+
client = ctx.obj["slack"]
|
|
268
|
+
try:
|
|
269
|
+
client.chat_postMessage(
|
|
270
|
+
channel=ctx.obj["settings"].channel, blocks=blocks, as_user=True
|
|
271
|
+
)
|
|
272
|
+
except SlackApiError as e:
|
|
273
|
+
print(f"Got an error: {e.response['error']}")
|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
@report_deployfish_tasks.command(
|
|
277
|
+
"success", short_help="Report a successful deployfish one-off tasks deploy"
|
|
278
|
+
)
|
|
279
|
+
@click.argument("tasks", nargs=-1, required=True)
|
|
280
|
+
@click.pass_context
|
|
281
|
+
def report_deployfish_tasks_success(ctx, tasks):
|
|
282
|
+
blocks = DeployfishTasksDeploySuccessMessage().format(tasks=tasks)
|
|
283
|
+
client = ctx.obj["slack"]
|
|
284
|
+
try:
|
|
285
|
+
client.chat_postMessage(
|
|
286
|
+
channel=ctx.obj["settings"].channel, blocks=blocks, as_user=True
|
|
287
|
+
)
|
|
288
|
+
except SlackApiError as e:
|
|
289
|
+
print(f"Got an error: {e.response['error']}")
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
@report_deployfish_tasks.command(
|
|
293
|
+
"failure", short_help="Report a failed deployfish one-off tasks deploy"
|
|
294
|
+
)
|
|
295
|
+
@click.argument("tasks", nargs=-1, required=True)
|
|
296
|
+
@click.pass_context
|
|
297
|
+
def report_deployfish_tasks_failure(ctx, tasks):
|
|
298
|
+
blocks = DeployfishTasksDeployFailureMessage().format(tasks=tasks)
|
|
299
|
+
client = ctx.obj["slack"]
|
|
300
|
+
try:
|
|
301
|
+
client.chat_postMessage(
|
|
302
|
+
channel=ctx.obj["settings"].channel, blocks=blocks, as_user=True
|
|
303
|
+
)
|
|
304
|
+
except SlackApiError as e:
|
|
305
|
+
print(f"Got an error: {e.response['error']}")
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
@report.group(
|
|
309
|
+
"docs",
|
|
310
|
+
short_help="A group of commands that report about a Deployfish service build step",
|
|
311
|
+
)
|
|
312
|
+
def report_docs():
|
|
313
|
+
pass
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
@report_docs.command(
|
|
317
|
+
"start", short_help="Report about starting a Sphinx docs build and deploy"
|
|
318
|
+
)
|
|
319
|
+
@click.pass_context
|
|
320
|
+
def report_docs_start(ctx):
|
|
321
|
+
blocks = DocsStartMessage().format()
|
|
322
|
+
client = ctx.obj["slack"]
|
|
323
|
+
try:
|
|
324
|
+
client.chat_postMessage(
|
|
325
|
+
channel=ctx.obj["settings"].channel, blocks=blocks, as_user=True
|
|
326
|
+
)
|
|
327
|
+
except SlackApiError as e:
|
|
328
|
+
print(f"Got an error: {e.response['error']}")
|
|
329
|
+
|
|
330
|
+
|
|
331
|
+
@report_docs.command(
|
|
332
|
+
"success", short_help="Report a successful Sphinx docs build and deploy"
|
|
333
|
+
)
|
|
334
|
+
@click.pass_context
|
|
335
|
+
def report_docs_success(ctx):
|
|
336
|
+
blocks = DocsSuccessMessage().format()
|
|
337
|
+
client = ctx.obj["slack"]
|
|
338
|
+
try:
|
|
339
|
+
client.chat_postMessage(
|
|
340
|
+
channel=ctx.obj["settings"].channel, blocks=blocks, as_user=True
|
|
341
|
+
)
|
|
342
|
+
except SlackApiError as e:
|
|
343
|
+
print(f"Got an error: {e.response['error']}")
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
@report_docs.command(
|
|
347
|
+
"failure", short_help="Report a failed Sphinx docs build and deploy"
|
|
348
|
+
)
|
|
349
|
+
@click.pass_context
|
|
350
|
+
def report_docs_failure(ctx):
|
|
351
|
+
blocks = DocsFailureMessage().format()
|
|
352
|
+
client = ctx.obj["slack"]
|
|
353
|
+
try:
|
|
354
|
+
client.chat_postMessage(
|
|
355
|
+
channel=ctx.obj["settings"].channel, blocks=blocks, as_user=True
|
|
356
|
+
)
|
|
357
|
+
except SlackApiError as e:
|
|
358
|
+
print(f"Got an error: {e.response['error']}")
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+
@report.group(
|
|
362
|
+
"general",
|
|
363
|
+
short_help="A group of commands that report about a Deployfish service build step",
|
|
364
|
+
)
|
|
365
|
+
def report_general():
|
|
366
|
+
pass
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
@report_general.command(
|
|
370
|
+
"start", short_help="Report about starting a general service deploy"
|
|
371
|
+
)
|
|
372
|
+
@click.argument("label")
|
|
373
|
+
@click.pass_context
|
|
374
|
+
def report_general_start(ctx, label):
|
|
375
|
+
blocks = GeneralStartMessage().format(label=label)
|
|
376
|
+
client = ctx.obj["slack"]
|
|
377
|
+
try:
|
|
378
|
+
client.chat_postMessage(
|
|
379
|
+
channel=ctx.obj["settings"].channel, blocks=blocks, as_user=True
|
|
380
|
+
)
|
|
381
|
+
except SlackApiError as e:
|
|
382
|
+
print(f"Got an error: {e.response['error']}")
|
|
383
|
+
|
|
384
|
+
|
|
385
|
+
@report_general.command(
|
|
386
|
+
"success", short_help="Report a successful general service deploy"
|
|
387
|
+
)
|
|
388
|
+
@click.argument("label")
|
|
389
|
+
@click.pass_context
|
|
390
|
+
def report_general_success(ctx, label):
|
|
391
|
+
blocks = GeneralSuccessMessage().format(label=label)
|
|
392
|
+
client = ctx.obj["slack"]
|
|
393
|
+
try:
|
|
394
|
+
client.chat_postMessage(
|
|
395
|
+
channel=ctx.obj["settings"].channel, blocks=blocks, as_user=True
|
|
396
|
+
)
|
|
397
|
+
except SlackApiError as e:
|
|
398
|
+
print(f"Got an error: {e.response['error']}")
|
|
399
|
+
|
|
400
|
+
|
|
401
|
+
@report_general.command("failure", short_help="Report a failed general service deploy")
|
|
402
|
+
@click.argument("label")
|
|
403
|
+
@click.pass_context
|
|
404
|
+
def report_general_failure(ctx, label):
|
|
405
|
+
blocks = GeneralFailureMessage().format(label=label)
|
|
406
|
+
client = ctx.obj["slack"]
|
|
407
|
+
try:
|
|
408
|
+
client.chat_postMessage(
|
|
409
|
+
channel=ctx.obj["settings"].channel, blocks=blocks, as_user=True
|
|
410
|
+
)
|
|
411
|
+
except SlackApiError as e:
|
|
412
|
+
print(f"Got an error: {e.response['error']}")
|
|
413
|
+
|
|
414
|
+
|
|
415
|
+
def main():
|
|
416
|
+
cli(obj={})
|
|
417
|
+
|
|
418
|
+
|
|
419
|
+
if __name__ == "__main__":
|
|
420
|
+
main()
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
from .base import * # noqa:F403,F401
|
|
2
|
+
from .codebuild import * # noqa:F403,F401
|
|
3
|
+
from .deployfish import * # noqa:F403,F401
|
|
4
|
+
from .docker import * # noqa:F403,F401
|
|
5
|
+
from .generic import * # noqa:F403,F401
|
|
6
|
+
from .git import * # noqa:F403,F401
|
|
7
|
+
from .project import * # noqa:F403,F401
|
|
8
|
+
from .unittest import * # noqa:F403,F401
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from abc import ABC, abstractmethod
|
|
2
|
+
|
|
3
|
+
from ..typedefs import MessageContext
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class AbstractContextProcessor(ABC):
|
|
7
|
+
"""
|
|
8
|
+
Base class for all context processors.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
def __init__(self, **kwargs): # noqa: B027
|
|
12
|
+
"""
|
|
13
|
+
Args:
|
|
14
|
+
kwargs: the keyword arguments passed to the context processor
|
|
15
|
+
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
@abstractmethod
|
|
19
|
+
def annotate(self, context: MessageContext) -> None:
|
|
20
|
+
"""
|
|
21
|
+
Add values to the message context ``context``.
|
|
22
|
+
|
|
23
|
+
Args:
|
|
24
|
+
context: the current message context
|
|
25
|
+
|
|
26
|
+
"""
|
|
27
|
+
...
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import time
|
|
3
|
+
|
|
4
|
+
from ..typedefs import MessageContext
|
|
5
|
+
from .base import AbstractContextProcessor
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class CodebuildProcessor(AbstractContextProcessor):
|
|
9
|
+
"""
|
|
10
|
+
Adds the following keys to the context:
|
|
11
|
+
|
|
12
|
+
* ``build_id``: the CodeBuild build id
|
|
13
|
+
* ``build_project_name``: the CodeBuild project name
|
|
14
|
+
* ``build_status_url``: the URL to the CodeBuild build status page
|
|
15
|
+
* ``account_id``: the AWS account id
|
|
16
|
+
* ``pipeline_url``: the URL to the CodePipeline pipeline status page
|
|
17
|
+
* ``pipeline``: the CodePipeline pipeline name
|
|
18
|
+
* ``status``: the CodePipeline pipeline status
|
|
19
|
+
* ``region``: the AWS region
|
|
20
|
+
* ``build_time``: the elapsed time for the build in minutes and seconds
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
def get_build_log_url(self, context: MessageContext) -> None:
|
|
24
|
+
fields = os.environ["CODEBUILD_BUILD_ARN"].split(":")
|
|
25
|
+
context["account_id"] = fields[4]
|
|
26
|
+
context["build_project_name"] = fields[5].split("/")[1]
|
|
27
|
+
context["build_id"] = fields[6]
|
|
28
|
+
context["build_status_url"] = (
|
|
29
|
+
f"<https://{context['region']}.console.aws.amazon.com/codesuite/codebuild/"
|
|
30
|
+
f"{context['account_id']}/projects/{context['build_project_name']}/build/"
|
|
31
|
+
f"{context['build_project_name']}%3A{context['build_id']}/"
|
|
32
|
+
"log?region=us-west-2|Click here>"
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
def get_pipeline_url(self, context: MessageContext) -> None:
|
|
36
|
+
# TODO: detect region from the environment instead of hardcoding it to us-west-2
|
|
37
|
+
context["pipeline"] = os.environ["CODEBUILD_INITIATOR"].split("/")[1]
|
|
38
|
+
context["pipeline_url"] = (
|
|
39
|
+
f"<https://{context['region']}.console.aws.amazon.com/codesuite/codepipeline/pipelines/{context['pipeline']}/view?region=us-west-2|{context['pipeline']}>"
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
def annotate(self, context: MessageContext) -> None:
|
|
43
|
+
context["status"] = (
|
|
44
|
+
"Success" if "CODEBUILD_BUILD_SUCCEEDING" in os.environ else "Failed"
|
|
45
|
+
)
|
|
46
|
+
context["region"] = os.environ["AWS_DEFAULT_REGION"]
|
|
47
|
+
context["build_id"] = os.environ.get("CODEBUILD_BUILD_ID", None)
|
|
48
|
+
build_seconds = time.time() - float(os.environ["CODEBUILD_START_TIME"]) / 1000
|
|
49
|
+
build_minutes = int(build_seconds // 60)
|
|
50
|
+
build_seconds = int(build_seconds - build_minutes * 60)
|
|
51
|
+
context["build_time"] = f"{build_minutes}m {build_seconds}s"
|
|
52
|
+
self.get_build_log_url(context)
|
|
53
|
+
self.get_pipeline_url(context)
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
from ..typedefs import MessageContext
|
|
2
|
+
from .base import AbstractContextProcessor
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class DeployfishDeployProcessor(AbstractContextProcessor):
|
|
6
|
+
"""
|
|
7
|
+
Adds the following keys to the context:
|
|
8
|
+
|
|
9
|
+
* ``service``: the name of the ECS service being deployed
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
def __init__(self, **kwargs) -> None:
|
|
13
|
+
super().__init__(**kwargs)
|
|
14
|
+
self.service: str = kwargs["service"]
|
|
15
|
+
|
|
16
|
+
def annotate(self, context: MessageContext) -> None:
|
|
17
|
+
context["service"] = self.service
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class DeployfishTasksDeployProcessor(AbstractContextProcessor):
|
|
21
|
+
"""
|
|
22
|
+
Adds the following keys to the context:
|
|
23
|
+
|
|
24
|
+
* ``tasks``: a list of the names of the ECS tasks being deployed
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
def __init__(self, **kwargs) -> None:
|
|
28
|
+
super().__init__(**kwargs)
|
|
29
|
+
self.tasks: list[str] = kwargs["tasks"]
|
|
30
|
+
|
|
31
|
+
def annotate(self, context: MessageContext) -> None:
|
|
32
|
+
context["tasks"] = self.tasks
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
import docker
|
|
4
|
+
|
|
5
|
+
from ..typedefs import MessageContext
|
|
6
|
+
from .base import AbstractContextProcessor
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class DockerImageNameProcessor(AbstractContextProcessor):
|
|
10
|
+
"""
|
|
11
|
+
Adds the key ``short_image`` to the context, which is the basename of
|
|
12
|
+
the Docker image without the repository name.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
def __init__(self, **kwargs) -> None:
|
|
16
|
+
super().__init__(**kwargs)
|
|
17
|
+
self.image: str = kwargs["image"]
|
|
18
|
+
|
|
19
|
+
def annotate(self, context: MessageContext) -> None:
|
|
20
|
+
context["short_image"] = Path(self.image).name
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class DockerProcessor(AbstractContextProcessor):
|
|
24
|
+
"""
|
|
25
|
+
Adds the following keys to the context:
|
|
26
|
+
|
|
27
|
+
* ``image_id``: the short id of the Docker image
|
|
28
|
+
* ``image_size``: the size of the Docker image in MB
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
def __init__(self, **kwargs) -> None:
|
|
32
|
+
super().__init__(**kwargs)
|
|
33
|
+
self.image: str = kwargs["image"]
|
|
34
|
+
|
|
35
|
+
def annotate(self, context: MessageContext) -> None:
|
|
36
|
+
client = docker.from_env()
|
|
37
|
+
image = client.images.get(self.image)
|
|
38
|
+
context["image_id"] = image.short_id.split(":")[1]
|
|
39
|
+
context["image_size"] = image.attrs["Size"] / (1024 * 1024)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
from ..typedefs import MessageContext
|
|
2
|
+
from .base import AbstractContextProcessor
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class GenericProcessor(AbstractContextProcessor):
|
|
6
|
+
"""
|
|
7
|
+
Adds the following keys to the context:
|
|
8
|
+
|
|
9
|
+
* ``label``: a user supplied label we got from the --label command line option
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
def __init__(self, **kwargs) -> None:
|
|
13
|
+
super().__init__(**kwargs)
|
|
14
|
+
self.label: str | None = kwargs["label"]
|
|
15
|
+
|
|
16
|
+
def annotate(self, context: MessageContext) -> None:
|
|
17
|
+
context["label"] = self.label
|