c2cciutils 1.8.0.dev64__py3-none-any.whl → 1.8.0.dev68__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.
Potentially problematic release.
This version of c2cciutils might be problematic. Click here for more details.
- c2cciutils/__init__.py +1 -194
- c2cciutils/applications-versions.yaml +0 -1
- c2cciutils/configuration.py +1 -598
- c2cciutils/schema.json +2 -317
- {c2cciutils-1.8.0.dev64.dist-info → c2cciutils-1.8.0.dev68.dist-info}/METADATA +1 -219
- c2cciutils-1.8.0.dev68.dist-info/RECORD +25 -0
- c2cciutils-1.8.0.dev68.dist-info/entry_points.txt +9 -0
- c2cciutils/lib/docker.py +0 -141
- c2cciutils/lib/oidc.py +0 -188
- c2cciutils/package-lock.json +0 -370
- c2cciutils/package.json +0 -9
- c2cciutils/publish.py +0 -451
- c2cciutils/schema-applications.json +0 -50
- c2cciutils/scripts/clean.py +0 -103
- c2cciutils/scripts/docker_versions_gen.py +0 -33
- c2cciutils/scripts/pin_pipenv.py +0 -54
- c2cciutils/scripts/publish.py +0 -477
- c2cciutils/scripts/trigger_image_update.py +0 -84
- c2cciutils/scripts/version.py +0 -245
- c2cciutils-1.8.0.dev64.dist-info/RECORD +0 -37
- c2cciutils-1.8.0.dev64.dist-info/entry_points.txt +0 -18
- {c2cciutils-1.8.0.dev64.dist-info → c2cciutils-1.8.0.dev68.dist-info}/LICENSE +0 -0
- {c2cciutils-1.8.0.dev64.dist-info → c2cciutils-1.8.0.dev68.dist-info}/WHEEL +0 -0
c2cciutils/scripts/publish.py
DELETED
|
@@ -1,477 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
|
|
3
|
-
"""The publish script."""
|
|
4
|
-
|
|
5
|
-
import argparse
|
|
6
|
-
import os
|
|
7
|
-
import re
|
|
8
|
-
import subprocess # nosec
|
|
9
|
-
import sys
|
|
10
|
-
from re import Match
|
|
11
|
-
from typing import Optional, cast
|
|
12
|
-
|
|
13
|
-
import requests
|
|
14
|
-
import security_md
|
|
15
|
-
import yaml
|
|
16
|
-
|
|
17
|
-
import c2cciutils
|
|
18
|
-
import c2cciutils.configuration
|
|
19
|
-
import c2cciutils.env
|
|
20
|
-
import c2cciutils.lib.docker
|
|
21
|
-
import c2cciutils.lib.oidc
|
|
22
|
-
import c2cciutils.publish
|
|
23
|
-
import c2cciutils.scripts.download_applications
|
|
24
|
-
from c2cciutils.publish import GoogleCalendar
|
|
25
|
-
from c2cciutils.scripts.trigger_image_update import dispatch
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
def match(tpe: str, base_re: str) -> Optional[Match[str]]:
|
|
29
|
-
"""
|
|
30
|
-
Return the match for `GITHUB_REF` basically like: `refs/<tpe>/<base_re>`.
|
|
31
|
-
|
|
32
|
-
Arguments:
|
|
33
|
-
tpe: The type of ref we want to match (heads, tag, ...)
|
|
34
|
-
base_re: The regular expression to match the value
|
|
35
|
-
|
|
36
|
-
"""
|
|
37
|
-
if base_re[0] == "^":
|
|
38
|
-
base_re = base_re[1:]
|
|
39
|
-
if base_re[-1] != "$":
|
|
40
|
-
base_re += "$"
|
|
41
|
-
return re.match(f"^refs/{tpe}/{base_re}", os.environ["GITHUB_REF"])
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
def to_version(full_config: c2cciutils.configuration.Configuration, value: str, kind: str) -> str:
|
|
45
|
-
"""
|
|
46
|
-
Compute publish version from branch name or tag.
|
|
47
|
-
|
|
48
|
-
Arguments:
|
|
49
|
-
full_config: The full configuration
|
|
50
|
-
value: The value to be transformed
|
|
51
|
-
kind: The name of the transformer in the configuration
|
|
52
|
-
|
|
53
|
-
"""
|
|
54
|
-
item_re = c2cciutils.compile_re(
|
|
55
|
-
cast(
|
|
56
|
-
c2cciutils.configuration.VersionTransform, full_config["version"].get(kind + "_to_version_re", [])
|
|
57
|
-
)
|
|
58
|
-
)
|
|
59
|
-
value_match = c2cciutils.match(value, item_re)
|
|
60
|
-
if value_match[0] is not None:
|
|
61
|
-
return c2cciutils.get_value(*value_match)
|
|
62
|
-
return value
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
def main() -> None:
|
|
66
|
-
"""Run the publish."""
|
|
67
|
-
parser = argparse.ArgumentParser(description="Publish the project.")
|
|
68
|
-
parser.add_argument("--group", default="default", help="The publishing group")
|
|
69
|
-
parser.add_argument("--version", help="The version to publish to")
|
|
70
|
-
parser.add_argument(
|
|
71
|
-
"--docker-versions",
|
|
72
|
-
help="The versions to publish on Docker registry, comma separated, ex: 'x,x.y,x.y.z,latest'.",
|
|
73
|
-
)
|
|
74
|
-
parser.add_argument("--snyk-version", help="The version to publish to Snyk")
|
|
75
|
-
parser.add_argument("--branch", help="The branch from which to compute the version")
|
|
76
|
-
parser.add_argument("--tag", help="The tag from which to compute the version")
|
|
77
|
-
parser.add_argument("--dry-run", action="store_true", help="Don't do the publish")
|
|
78
|
-
parser.add_argument(
|
|
79
|
-
"--type",
|
|
80
|
-
help="The type of version, if no argument provided auto-determinate, can be: "
|
|
81
|
-
"rebuild (in case of rebuild), version_tag, version_branch, feature_branch, feature_tag "
|
|
82
|
-
"(for pull request)",
|
|
83
|
-
)
|
|
84
|
-
args = parser.parse_args()
|
|
85
|
-
|
|
86
|
-
config = c2cciutils.get_config()
|
|
87
|
-
c2cciutils.env.print_environment(config)
|
|
88
|
-
|
|
89
|
-
# Describe the kind of release we do: rebuild (specified with --type), version_tag, version_branch,
|
|
90
|
-
# feature_branch, feature_tag (for pull request)
|
|
91
|
-
version: str = ""
|
|
92
|
-
ref = os.environ.get("GITHUB_REF", "refs/heads/fake-local")
|
|
93
|
-
local = "GITHUB_REF" not in os.environ
|
|
94
|
-
|
|
95
|
-
if len([e for e in [args.version, args.branch, args.tag] if e is not None]) > 1:
|
|
96
|
-
print("::error::you specified more than one of the arguments --version, --branch or --tag")
|
|
97
|
-
sys.exit(1)
|
|
98
|
-
|
|
99
|
-
version_type = args.type
|
|
100
|
-
|
|
101
|
-
tag_match = c2cciutils.match(
|
|
102
|
-
ref,
|
|
103
|
-
c2cciutils.compile_re(config["version"].get("tag_to_version_re", []), "refs/tags/"),
|
|
104
|
-
)
|
|
105
|
-
branch_match = c2cciutils.match(
|
|
106
|
-
ref,
|
|
107
|
-
c2cciutils.compile_re(config["version"].get("branch_to_version_re", []), "refs/heads/"),
|
|
108
|
-
)
|
|
109
|
-
ref_match = re.match(r"refs/pull/(.*)/merge", ref)
|
|
110
|
-
|
|
111
|
-
if args.version is not None:
|
|
112
|
-
version = args.version
|
|
113
|
-
elif args.branch is not None:
|
|
114
|
-
version = to_version(config, args.branch, "branch")
|
|
115
|
-
elif args.tag is not None:
|
|
116
|
-
version = to_version(config, args.tag, "tag")
|
|
117
|
-
elif tag_match[0] is not None:
|
|
118
|
-
if version_type is None:
|
|
119
|
-
version_type = "version_tag"
|
|
120
|
-
else:
|
|
121
|
-
print("::warning::you specified the argument --type but not one of --version, --branch or --tag")
|
|
122
|
-
version = c2cciutils.get_value(*tag_match)
|
|
123
|
-
elif branch_match[0] is not None:
|
|
124
|
-
if version_type is None:
|
|
125
|
-
version_type = "version_branch"
|
|
126
|
-
else:
|
|
127
|
-
print("::warning::you specified the argument --type but not one of --version, --branch or --tag")
|
|
128
|
-
version = c2cciutils.get_value(*branch_match)
|
|
129
|
-
elif ref_match is not None:
|
|
130
|
-
version = c2cciutils.get_value(ref_match, {}, ref)
|
|
131
|
-
if version_type is None:
|
|
132
|
-
version_type = "feature_branch"
|
|
133
|
-
elif ref.startswith("refs/heads/"):
|
|
134
|
-
if version_type is None:
|
|
135
|
-
version_type = "feature_branch"
|
|
136
|
-
else:
|
|
137
|
-
print("::warning::you specified the argument --type but not one of --version, --branch or --tag")
|
|
138
|
-
# By the way we replace '/' by '_' because it isn't supported by Docker
|
|
139
|
-
version = "_".join(ref.split("/")[2:])
|
|
140
|
-
elif ref.startswith("refs/tags/"):
|
|
141
|
-
if version_type is None:
|
|
142
|
-
version_type = "feature_tag"
|
|
143
|
-
else:
|
|
144
|
-
print("::warning::you specified the argument --type but not one of --version, --branch or --tag")
|
|
145
|
-
# By the way we replace '/' by '_' because it isn't supported by Docker
|
|
146
|
-
version = "_".join(ref.split("/")[2:])
|
|
147
|
-
else:
|
|
148
|
-
print(
|
|
149
|
-
f"WARNING: {ref} is not supported, only ref starting with 'refs/heads/' or 'refs/tags/' "
|
|
150
|
-
"are supported, ignoring"
|
|
151
|
-
)
|
|
152
|
-
sys.exit(0)
|
|
153
|
-
|
|
154
|
-
if version_type is None:
|
|
155
|
-
print(
|
|
156
|
-
"::error::you specified one of the arguments --version, --branch or --tag but not the --type, GitHub ref is: {ref}"
|
|
157
|
-
)
|
|
158
|
-
sys.exit(1)
|
|
159
|
-
|
|
160
|
-
if version_type is not None:
|
|
161
|
-
if args.dry_run:
|
|
162
|
-
print(f"Create release type {version_type}: {version} (dry run)")
|
|
163
|
-
else:
|
|
164
|
-
print(f"Create release type {version_type}: {version}")
|
|
165
|
-
|
|
166
|
-
success = True
|
|
167
|
-
pypi_config = cast(
|
|
168
|
-
c2cciutils.configuration.PublishPypiConfig,
|
|
169
|
-
config.get("publish", {}).get("pypi", {}) if config.get("publish", {}).get("pypi", False) else {},
|
|
170
|
-
)
|
|
171
|
-
if pypi_config:
|
|
172
|
-
if pypi_config["packages"]:
|
|
173
|
-
c2cciutils.lib.oidc.pypi_login()
|
|
174
|
-
|
|
175
|
-
for package in pypi_config["packages"]:
|
|
176
|
-
if package.get("group", c2cciutils.configuration.PUBLISH_PIP_PACKAGE_GROUP_DEFAULT) == args.group:
|
|
177
|
-
publish = version_type in pypi_config.get("versions", [])
|
|
178
|
-
if args.dry_run:
|
|
179
|
-
print(
|
|
180
|
-
f"{'Publishing' if publish else 'Checking'} "
|
|
181
|
-
f"'{package.get('path')}' to pypi, skipping (dry run)"
|
|
182
|
-
)
|
|
183
|
-
else:
|
|
184
|
-
success &= c2cciutils.publish.pip(package, version, version_type, publish)
|
|
185
|
-
|
|
186
|
-
google_calendar = None
|
|
187
|
-
google_calendar_publish = config.get("publish", {}).get("google_calendar", False) is not False
|
|
188
|
-
google_calendar_config = cast(
|
|
189
|
-
c2cciutils.configuration.PublishGoogleCalendarConfig,
|
|
190
|
-
config.get("publish", {}).get("google_calendar", {}),
|
|
191
|
-
)
|
|
192
|
-
|
|
193
|
-
docker_config = cast(
|
|
194
|
-
c2cciutils.configuration.PublishDockerConfig,
|
|
195
|
-
config.get("publish", {}).get("docker", {}) if config.get("publish", {}).get("docker", False) else {},
|
|
196
|
-
)
|
|
197
|
-
if docker_config:
|
|
198
|
-
full_repo = c2cciutils.get_repository()
|
|
199
|
-
full_repo_split = full_repo.split("/")
|
|
200
|
-
master_branch, _ = c2cciutils.get_master_branch(full_repo_split)
|
|
201
|
-
security_text = ""
|
|
202
|
-
if local:
|
|
203
|
-
with open("SECURITY.md", encoding="utf-8") as security_file:
|
|
204
|
-
security_text = security_file.read()
|
|
205
|
-
else:
|
|
206
|
-
security_response = requests.get(
|
|
207
|
-
f"https://raw.githubusercontent.com/{full_repo}/{master_branch}/SECURITY.md",
|
|
208
|
-
headers=c2cciutils.add_authorization_header({}),
|
|
209
|
-
timeout=int(os.environ.get("C2CCIUTILS_TIMEOUT", "30")),
|
|
210
|
-
)
|
|
211
|
-
c2cciutils.check_response(security_response, False)
|
|
212
|
-
if security_response.ok:
|
|
213
|
-
security_text = security_response.text
|
|
214
|
-
elif security_response.status_code != 404:
|
|
215
|
-
print(f"::error:: {security_response.status_code} {security_response.text}")
|
|
216
|
-
sys.exit(1)
|
|
217
|
-
|
|
218
|
-
security = security_md.Security(security_text)
|
|
219
|
-
version_index = security.version_index
|
|
220
|
-
alternate_tag_index = security.alternate_tag_index
|
|
221
|
-
|
|
222
|
-
row_index = -1
|
|
223
|
-
if version_index >= 0:
|
|
224
|
-
for index, row in enumerate(security.data):
|
|
225
|
-
if row[version_index] == version:
|
|
226
|
-
row_index = index
|
|
227
|
-
break
|
|
228
|
-
|
|
229
|
-
alt_tags = set()
|
|
230
|
-
if alternate_tag_index >= 0 and row_index >= 0:
|
|
231
|
-
alt_tags = {
|
|
232
|
-
t.strip() for t in security.data[row_index][alternate_tag_index].split(",") if t.strip()
|
|
233
|
-
}
|
|
234
|
-
if version_index >= 0 and security.data[-1][version_index] == version:
|
|
235
|
-
add_latest = True
|
|
236
|
-
for data in security.data:
|
|
237
|
-
row_tags = {t.strip() for t in data[alternate_tag_index].split(",") if t.strip()}
|
|
238
|
-
print(row_tags)
|
|
239
|
-
if "latest" in row_tags:
|
|
240
|
-
print("latest found in ", row_tags)
|
|
241
|
-
add_latest = False
|
|
242
|
-
break
|
|
243
|
-
if add_latest:
|
|
244
|
-
alt_tags.add("latest")
|
|
245
|
-
|
|
246
|
-
images_src: set[str] = set()
|
|
247
|
-
images_full: list[str] = []
|
|
248
|
-
images_snyk: set[str] = set()
|
|
249
|
-
versions = args.docker_versions.split(",") if args.docker_versions else [version]
|
|
250
|
-
for image_conf in docker_config.get("images", []):
|
|
251
|
-
if (
|
|
252
|
-
image_conf.get("group", c2cciutils.configuration.PUBLISH_DOCKER_IMAGE_GROUP_DEFAULT)
|
|
253
|
-
== args.group
|
|
254
|
-
):
|
|
255
|
-
for tag_config in image_conf.get(
|
|
256
|
-
"tags", c2cciutils.configuration.PUBLISH_DOCKER_IMAGE_TAGS_DEFAULT
|
|
257
|
-
):
|
|
258
|
-
tag_src = tag_config.format(version="latest")
|
|
259
|
-
image_source = f"{image_conf['name']}:{tag_src}"
|
|
260
|
-
images_src.add(image_source)
|
|
261
|
-
tag_snyk = tag_config.format(version=args.snyk_version or version).lower()
|
|
262
|
-
image_snyk = f"{image_conf['name']}:{tag_snyk}"
|
|
263
|
-
|
|
264
|
-
# Workaround sine we have the business plan
|
|
265
|
-
image_snyk = f"{image_conf['name']}_{tag_snyk}"
|
|
266
|
-
|
|
267
|
-
if not args.dry_run:
|
|
268
|
-
subprocess.run(["docker", "tag", image_source, image_snyk], check=True)
|
|
269
|
-
images_snyk.add(image_snyk)
|
|
270
|
-
if tag_snyk != tag_src and not args.dry_run:
|
|
271
|
-
subprocess.run(
|
|
272
|
-
[
|
|
273
|
-
"docker",
|
|
274
|
-
"tag",
|
|
275
|
-
image_source,
|
|
276
|
-
f"{image_conf['name']}:{tag_snyk}",
|
|
277
|
-
],
|
|
278
|
-
check=True,
|
|
279
|
-
)
|
|
280
|
-
|
|
281
|
-
tags_calendar = []
|
|
282
|
-
for name, conf in {
|
|
283
|
-
**cast(
|
|
284
|
-
dict[str, c2cciutils.configuration.PublishDockerRepository],
|
|
285
|
-
c2cciutils.configuration.DOCKER_REPOSITORY_DEFAULT,
|
|
286
|
-
),
|
|
287
|
-
**docker_config.get("repository", {}),
|
|
288
|
-
}.items():
|
|
289
|
-
for docker_version in versions:
|
|
290
|
-
tag_dst = tag_config.format(version=docker_version)
|
|
291
|
-
if tag_dst not in tags_calendar:
|
|
292
|
-
tags_calendar.append(tag_dst)
|
|
293
|
-
if version_type in conf.get(
|
|
294
|
-
"versions",
|
|
295
|
-
c2cciutils.configuration.PUBLISH_DOCKER_REPOSITORY_VERSIONS_DEFAULT,
|
|
296
|
-
):
|
|
297
|
-
tags = [
|
|
298
|
-
tag_config.format(version=alt_tag)
|
|
299
|
-
for alt_tag in [docker_version, *alt_tags]
|
|
300
|
-
]
|
|
301
|
-
|
|
302
|
-
if args.dry_run:
|
|
303
|
-
for tag in tags:
|
|
304
|
-
print(
|
|
305
|
-
f"Publishing {image_conf['name']}:{tag} to {name}, skipping (dry run)"
|
|
306
|
-
)
|
|
307
|
-
else:
|
|
308
|
-
success &= c2cciutils.publish.docker(
|
|
309
|
-
conf, name, image_conf, tag_src, tags, images_full
|
|
310
|
-
)
|
|
311
|
-
|
|
312
|
-
if google_calendar_publish and version_type in google_calendar_config.get(
|
|
313
|
-
"on", c2cciutils.configuration.PUBLISH_GOOGLE_CALENDAR_ON_DEFAULT
|
|
314
|
-
):
|
|
315
|
-
if not google_calendar:
|
|
316
|
-
google_calendar = GoogleCalendar()
|
|
317
|
-
summary = f"{image_conf['name']}:{', '.join(tags_calendar)}"
|
|
318
|
-
description = "\n".join(
|
|
319
|
-
[
|
|
320
|
-
f"Published the image {image_conf['name']}",
|
|
321
|
-
f"Published on: {', '.join(docker_config['repository'].keys())}",
|
|
322
|
-
f"With tags: {', '.join(tags_calendar)}",
|
|
323
|
-
f"For version type: {version_type}",
|
|
324
|
-
]
|
|
325
|
-
)
|
|
326
|
-
|
|
327
|
-
google_calendar.create_event(summary, description)
|
|
328
|
-
|
|
329
|
-
if args.dry_run:
|
|
330
|
-
sys.exit(0)
|
|
331
|
-
|
|
332
|
-
dispatch_config = docker_config.get("dispatch", {})
|
|
333
|
-
if dispatch_config is not False and images_full:
|
|
334
|
-
dispatch(
|
|
335
|
-
dispatch_config.get(
|
|
336
|
-
"repository", c2cciutils.configuration.DOCKER_DISPATCH_REPOSITORY_DEFAULT
|
|
337
|
-
),
|
|
338
|
-
dispatch_config.get(
|
|
339
|
-
"event-type", c2cciutils.configuration.DOCKER_DISPATCH_EVENT_TYPE_DEFAULT
|
|
340
|
-
),
|
|
341
|
-
images_full,
|
|
342
|
-
)
|
|
343
|
-
|
|
344
|
-
snyk_exec, env = c2cciutils.snyk_exec()
|
|
345
|
-
for image in images_snyk:
|
|
346
|
-
print(f"::group::Snyk check {image}")
|
|
347
|
-
sys.stdout.flush()
|
|
348
|
-
sys.stderr.flush()
|
|
349
|
-
try:
|
|
350
|
-
if version_type in ("version_branch", "version_tag"):
|
|
351
|
-
monitor_args = docker_config.get("snyk", {}).get(
|
|
352
|
-
"monitor_args",
|
|
353
|
-
c2cciutils.configuration.PUBLISH_DOCKER_SNYK_MONITOR_ARGS_DEFAULT,
|
|
354
|
-
)
|
|
355
|
-
if monitor_args is not False:
|
|
356
|
-
subprocess.run( # pylint: disable=subprocess-run-check
|
|
357
|
-
[
|
|
358
|
-
snyk_exec,
|
|
359
|
-
"container",
|
|
360
|
-
"monitor",
|
|
361
|
-
*monitor_args,
|
|
362
|
-
# Available only on the business plan
|
|
363
|
-
# f"--project-tags=tag={image.split(':')[-1]}",
|
|
364
|
-
image,
|
|
365
|
-
],
|
|
366
|
-
env=env,
|
|
367
|
-
)
|
|
368
|
-
test_args = docker_config.get("snyk", {}).get(
|
|
369
|
-
"test_args", c2cciutils.configuration.PUBLISH_DOCKER_SNYK_TEST_ARGS_DEFAULT
|
|
370
|
-
)
|
|
371
|
-
snyk_error = False
|
|
372
|
-
if test_args is not False:
|
|
373
|
-
proc = subprocess.run(
|
|
374
|
-
[snyk_exec, "container", "test", *test_args, image],
|
|
375
|
-
check=False,
|
|
376
|
-
env=env,
|
|
377
|
-
)
|
|
378
|
-
if proc.returncode != 0:
|
|
379
|
-
snyk_error = True
|
|
380
|
-
print("::endgroup::")
|
|
381
|
-
if snyk_error:
|
|
382
|
-
print("::error::Critical vulnerability found by Snyk in the published image.")
|
|
383
|
-
except subprocess.CalledProcessError as exception:
|
|
384
|
-
print(f"Error: {exception}")
|
|
385
|
-
print("::endgroup::")
|
|
386
|
-
print("::error::With error")
|
|
387
|
-
|
|
388
|
-
versions_config, dpkg_config_found = c2cciutils.lib.docker.get_versions_config()
|
|
389
|
-
dpkg_success = True
|
|
390
|
-
for image in images_src:
|
|
391
|
-
dpkg_success &= c2cciutils.lib.docker.check_versions(versions_config.get(image, {}), image)
|
|
392
|
-
|
|
393
|
-
if not dpkg_success:
|
|
394
|
-
current_versions_in_images: dict[str, dict[str, str]] = {}
|
|
395
|
-
if dpkg_config_found:
|
|
396
|
-
with open("ci/dpkg-versions.yaml", encoding="utf-8") as dpkg_versions_file:
|
|
397
|
-
current_versions_in_images = yaml.load(dpkg_versions_file, Loader=yaml.SafeLoader)
|
|
398
|
-
for image in images_src:
|
|
399
|
-
if image in current_versions_in_images:
|
|
400
|
-
current_versions_in_images[image] = dict(current_versions_in_images[image])
|
|
401
|
-
_, versions_image = c2cciutils.lib.docker.get_dpkg_packages_versions(image)
|
|
402
|
-
for dpkg_package, package_version in versions_image.items():
|
|
403
|
-
if dpkg_package not in current_versions_in_images.get(image, {}):
|
|
404
|
-
current_versions_in_images.setdefault(image, {})[dpkg_package] = str(package_version)
|
|
405
|
-
for dpkg_package in list(current_versions_in_images[image].keys()):
|
|
406
|
-
if dpkg_package not in versions_image:
|
|
407
|
-
del current_versions_in_images[image][dpkg_package]
|
|
408
|
-
if dpkg_config_found:
|
|
409
|
-
print(
|
|
410
|
-
"::error::Some packages are have a greater version in the config raster then in the image."
|
|
411
|
-
)
|
|
412
|
-
print("Current versions of the Debian packages in Docker images:")
|
|
413
|
-
print(yaml.dump(current_versions_in_images, Dumper=yaml.SafeDumper, default_flow_style=False))
|
|
414
|
-
if dpkg_config_found:
|
|
415
|
-
with open("ci/dpkg-versions.yaml", "w", encoding="utf-8") as dpkg_versions_file:
|
|
416
|
-
yaml.dump(
|
|
417
|
-
current_versions_in_images,
|
|
418
|
-
dpkg_versions_file,
|
|
419
|
-
Dumper=yaml.SafeDumper,
|
|
420
|
-
default_flow_style=False,
|
|
421
|
-
)
|
|
422
|
-
|
|
423
|
-
if dpkg_config_found:
|
|
424
|
-
success = False
|
|
425
|
-
|
|
426
|
-
helm_config = cast(
|
|
427
|
-
c2cciutils.configuration.PublishHelmConfig,
|
|
428
|
-
config.get("publish", {}).get("helm", {}) if config.get("publish", {}).get("helm", False) else {},
|
|
429
|
-
)
|
|
430
|
-
if helm_config and helm_config["folders"] and version_type in helm_config.get("versions", []):
|
|
431
|
-
c2cciutils.scripts.download_applications.download_c2cciutils_applications("helm/chart-releaser")
|
|
432
|
-
|
|
433
|
-
owner, repo = full_repo_split
|
|
434
|
-
commit_sha = (
|
|
435
|
-
subprocess.run(["git", "rev-parse", "HEAD"], check=True, stdout=subprocess.PIPE)
|
|
436
|
-
.stdout.strip()
|
|
437
|
-
.decode()
|
|
438
|
-
)
|
|
439
|
-
token = (
|
|
440
|
-
os.environ["GITHUB_TOKEN"].strip()
|
|
441
|
-
if "GITHUB_TOKEN" in os.environ
|
|
442
|
-
else c2cciutils.gopass("gs/ci/github/token/gopass")
|
|
443
|
-
)
|
|
444
|
-
assert token is not None
|
|
445
|
-
if version_type == "version_branch":
|
|
446
|
-
last_tag = (
|
|
447
|
-
subprocess.run(
|
|
448
|
-
["git", "describe", "--abbrev=0", "--tags"], check=True, stdout=subprocess.PIPE
|
|
449
|
-
)
|
|
450
|
-
.stdout.strip()
|
|
451
|
-
.decode()
|
|
452
|
-
)
|
|
453
|
-
expression = re.compile(r"^[0-9]+\.[0-9]+\.[0-9]+$")
|
|
454
|
-
while expression.match(last_tag) is None:
|
|
455
|
-
last_tag = (
|
|
456
|
-
subprocess.run(
|
|
457
|
-
["git", "describe", "--abbrev=0", "--tags", f"{last_tag}^"],
|
|
458
|
-
check=True,
|
|
459
|
-
stdout=subprocess.PIPE,
|
|
460
|
-
)
|
|
461
|
-
.stdout.strip()
|
|
462
|
-
.decode()
|
|
463
|
-
)
|
|
464
|
-
|
|
465
|
-
versions = last_tag.split(".")
|
|
466
|
-
versions[-1] = str(int(versions[-1]) + 1)
|
|
467
|
-
version = ".".join(versions)
|
|
468
|
-
|
|
469
|
-
for folder in helm_config["folders"]:
|
|
470
|
-
success &= c2cciutils.publish.helm(folder, version, owner, repo, commit_sha, token)
|
|
471
|
-
|
|
472
|
-
if not success:
|
|
473
|
-
sys.exit(1)
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
if __name__ == "__main__":
|
|
477
|
-
main()
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
|
|
3
|
-
"""Trigger an image update on the argocd repository."""
|
|
4
|
-
|
|
5
|
-
import argparse
|
|
6
|
-
import os.path
|
|
7
|
-
import random
|
|
8
|
-
import subprocess # nosec
|
|
9
|
-
import sys
|
|
10
|
-
|
|
11
|
-
import requests
|
|
12
|
-
import yaml
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
def main() -> None:
|
|
16
|
-
"""
|
|
17
|
-
Trigger an image update on the argocd repository.
|
|
18
|
-
|
|
19
|
-
Only the branch present in the HELM_RELEASE_NAMES environment variable will be considered.
|
|
20
|
-
"""
|
|
21
|
-
parser = argparse.ArgumentParser(
|
|
22
|
-
description="""Trigger an image update on the argocd repository.
|
|
23
|
-
|
|
24
|
-
Only the branch present in the HELM_RELEASE_NAMES environment variable will be considered."""
|
|
25
|
-
)
|
|
26
|
-
parser.add_argument("--version", help="The version to be exported")
|
|
27
|
-
parser.add_argument("--event-type", default="image-update", help="The event name to be triggered")
|
|
28
|
-
parser.add_argument(
|
|
29
|
-
"--repository",
|
|
30
|
-
default="camptocamp/argocd-gs-platform-ch-development-apps",
|
|
31
|
-
help="The repository name to be triggered",
|
|
32
|
-
)
|
|
33
|
-
|
|
34
|
-
args = parser.parse_args()
|
|
35
|
-
|
|
36
|
-
if args.version:
|
|
37
|
-
version = args.version
|
|
38
|
-
else:
|
|
39
|
-
ref = os.environ["GITHUB_REF"].split("/")
|
|
40
|
-
|
|
41
|
-
if ref[1] != "heads":
|
|
42
|
-
print("::error::Not a branch")
|
|
43
|
-
sys.exit(0)
|
|
44
|
-
|
|
45
|
-
version = "/".join(ref[2:])
|
|
46
|
-
|
|
47
|
-
if version not in os.environ.get("HELM_RELEASE_NAMES", "").split(","):
|
|
48
|
-
print("::error::Not a release branch")
|
|
49
|
-
sys.exit(0)
|
|
50
|
-
|
|
51
|
-
images_full = []
|
|
52
|
-
with open("ci/config.yaml", encoding="utf-8") as config_file:
|
|
53
|
-
ci_config = yaml.load(config_file, Loader=yaml.SafeLoader)
|
|
54
|
-
for image_config in ci_config.get("publish", {}).get("docker", {}).get("images", []):
|
|
55
|
-
images_full.append(image_config["name"])
|
|
56
|
-
|
|
57
|
-
dispatch(args.repository, args.event_type, [f"{image}:{version}" for image in images_full])
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
def dispatch(repository: str, event_type: str, images_full: list[str]) -> None:
|
|
61
|
-
"""Trigger an image update on the argocd repository."""
|
|
62
|
-
id_ = random.randint(1, 100000) # noqa: S311 # nosec
|
|
63
|
-
print(f"Triggering {event_type}:{id_} on {repository} with {','.join(images_full)}")
|
|
64
|
-
|
|
65
|
-
response = requests.post(
|
|
66
|
-
f"https://api.github.com/repos/{repository}/dispatches",
|
|
67
|
-
headers={
|
|
68
|
-
"Content-Type": "application/json2",
|
|
69
|
-
"Accept": "application/vnd.github.v3+json",
|
|
70
|
-
"Authorization": "token "
|
|
71
|
-
+ subprocess.run(
|
|
72
|
-
["gopass", "show", "gs/ci/github/token/gopass"], check=True, stdout=subprocess.PIPE
|
|
73
|
-
)
|
|
74
|
-
.stdout.decode()
|
|
75
|
-
.strip(),
|
|
76
|
-
},
|
|
77
|
-
json={"event_type": event_type, "client_payload": {"name": " ".join(images_full), "id": id_}},
|
|
78
|
-
timeout=int(os.environ.get("C2CCIUTILS_TIMEOUT", "30")),
|
|
79
|
-
)
|
|
80
|
-
response.raise_for_status()
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
if __name__ == "__main__":
|
|
84
|
-
main()
|