Skip to content

Commit

Permalink
Be able to publish the image on an alternative tag
Browse files Browse the repository at this point in the history
  • Loading branch information
sbrunner committed Sep 8, 2023
1 parent ca978e5 commit f1ff990
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 27 deletions.
34 changes: 21 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,21 @@
The main goals of C2C CI utils is to offer the commands and the workflows to have the following project structure:

Have stabilization branches named by default `<major>.<minor>`.
Have the release named by default `<major>.<minor>-<patch>`.
Have the release named by default `<major>.<minor>.<patch>`.

With C2C CI utils you can publish a python package and a Docker image from the same repository.

The default publishing are:

- Push on the `<major>.<minor>` branch will publish Docker images (the version in the last line of the
`SECURITY.md` of the `master` branch will be published also using the `latest` tag).
- Push on the `<major>.<minor>` branch will publish Docker images.
- Create the tag `<major>.<minor>.<patch>` will publish the Docker images, and the Python package.
- Push on a feature branch (whatever other name) will publish the Docker images.
- Delete a feature branch will delete the Docker images.
- Push on the `master` branch will publish the Docker images with the master tag (Publishing a python package is also possible).
- The version at the last line of the `SECURITY.md` of the `master` branch will be also published using the `latest` tag,
this will respect the `tags` present in the configuration
- In the `SECURITY.md` file of the `master` branch we can also add a column `Alternate Tag` to publish the Docker images with another tag,
this will respect the `tags` present in the configuration (only for Docker).

The Docker images are published on Docker Hub and GitHub Container Registry.

Expand Down Expand Up @@ -278,18 +281,23 @@ The config is like this:
```yaml
latest: True
images:
- name: # The base name of the image we want to publish
- # The base name of the image we want to publish
name:
repository:
<internal_name>:
'server': # The fqdn name of the server if not Docker hub
'version':# List of kinds of versions you want to publish, that can be: rebuild (specified using --type),
# version_tag, version_branch, feature_branch, feature_tag (for pull request)
'tags':# List of tags we want to publish interpreted with `template(version=version)`
# e.g. if you use `{version}-lite` when you publish the version `1.2.3` the source tag
# (that should be built by the application build) is `latest-lite`, and it will be published
# with the tag `1.2.3-lite`.
'group':# If your images are published by different jobs you can separate them in different groups
# and publish them with `c2cciutils-publish --group=<group>`
# The fqdn name of the server if not Docker hub
server:
# List of kinds of versions you want to publish, that can be: rebuild (specified using --type),
# version_tag, version_branch, feature_branch, feature_tag (for pull request)
version:
# List of tags we want to publish interpreted with `template(version=version)`
# e.g. if you use `{version}-lite` when you publish the version `1.2.3` the source tag
# (that should be built by the application build) is `latest-lite`, and it will be published
# with the tag `1.2.3-lite`.
tags:
# If your images are published by different jobs you can separate them in different groups
# and publish them with `c2cciutils-publish --group=<group>`
group:
```
By default, the last line of the `SECURITY.md` file will be published (`docker`) with the tag
Expand Down
24 changes: 24 additions & 0 deletions c2cciutils/publish.py
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,7 @@ def docker(
tag_src: str,
tag_dst: str,
latest: bool,
alt_tags: list[str],
images_full: list[str],
) -> bool:
"""
Expand All @@ -356,6 +357,7 @@ def docker(
tag_src: The source tag (usually latest)
tag_dst: The tag used for publication
latest: Publish also the tag latest
alt_tags: Publish also to the provided tags
images_full: The list of published images (with tag), used to build the dispatch event
"""

Expand Down Expand Up @@ -387,6 +389,17 @@ def docker(
check=True,
)
new_images_full.append(f"{config['server']}/{image_config['name']}:{tag_src}")
for alt_tag in alt_tags:
subprocess.run(
[
"docker",
"tag",
f"{image_config['name']}:{tag_src}",
f"{config['server']}/{image_config['name']}:{alt_tag}",
],
check=True,
)
new_images_full.append(f"{config['server']}/{image_config['name']}:{alt_tag}")
else:
if tag_src != tag_dst:
subprocess.run(
Expand All @@ -401,6 +414,17 @@ def docker(
new_images_full.append(f"{image_config['name']}:{tag_dst}")
if latest and tag_src != tag_dst:
new_images_full.append(f"{image_config['name']}:{tag_src}")
for alt_tag in alt_tags:
subprocess.run(
[
"docker",
"tag",
f"{image_config['name']}:{tag_src}",
f"{image_config['name']}:{alt_tag}",
],
check=True,
)
new_images_full.append(f"{image_config['name']}:{alt_tag}")

for image in new_images_full:
subprocess.run(["docker", "push", image], check=True)
Expand Down
2 changes: 1 addition & 1 deletion c2cciutils/scripts/clean.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ def main() -> None:
)
for image in docker_config.get("images", []):
for tag in image.get("tags", []):
clean(image["name"], tag.format(version=ref), token)
clean(image, tag.format(version=ref), token)


if __name__ == "__main__":
Expand Down
60 changes: 47 additions & 13 deletions c2cciutils/scripts/publish.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ def main() -> None:
# feature_branch, feature_tag (for pull request)
version: str = ""
ref = os.environ.get("GITHUB_REF", "refs/heads/fake-local")
local = "GITHUB_REF" not in os.environ

if len([e for e in [args.version, args.branch, args.tag] if e is not None]) > 1:
print("::error::you specified more than one of the arguments --version, --branch or --tag")
Expand Down Expand Up @@ -196,18 +197,38 @@ def main() -> None:
full_repo = c2cciutils.get_repository()
full_repo_split = full_repo.split("/")
master_branch, _ = c2cciutils.get_master_branch(full_repo_split)
security_response = requests.get(
f"https://raw.githubusercontent.com/{full_repo}/{master_branch}/SECURITY.md",
headers=c2cciutils.add_authorization_header({}),
timeout=int(os.environ.get("C2CCIUTILS_TIMEOUT", "30")),
)
if (
security_response.ok
and docker_config.get("latest", c2cciutils.configuration.PUBLISH_DOCKER_LATEST_DEFAULT) is True
):
security = c2cciutils.security.Security(security_response.text)
version_index = security.headers.index("Version")
latest = security.data[-1][version_index] == version
security_text = ""
if local:
with open("SECURITY.md", encoding="utf-8") as security_file:
security_text = security_file.read()
else:
security_response = requests.get(
f"https://raw.githubusercontent.com/{full_repo}/{master_branch}/SECURITY.md",
headers=c2cciutils.add_authorization_header({}),
timeout=int(os.environ.get("C2CCIUTILS_TIMEOUT", "30")),
)
if (
security_response.ok
and docker_config.get("latest", c2cciutils.configuration.PUBLISH_DOCKER_LATEST_DEFAULT)
is True
):
security_text = security_response.text

security = c2cciutils.security.Security(security_text)
version_index = security.headers.index("Version")
latest = security.data[-1][version_index] == version

row_index = -1
for index, row in enumerate(security.data):
if row[version_index] == version:
row_index = index
break

alt_tags = []
if "Alternate Tag" in security.headers:
tag_index = security.headers.index("Alternate Tag")
if tag_index != -1:
alt_tags = security.data[row_index][tag_index].split(",")

images_src: set[str] = set()
images_full: list[str] = []
Expand Down Expand Up @@ -261,13 +282,26 @@ def main() -> None:
"versions",
c2cciutils.configuration.PUBLISH_DOCKER_REPOSITORY_VERSIONS_DEFAULT,
):
current_alt_tag = [tag_config.format(version=alt_tag) for alt_tag in alt_tags]

if args.dry_run:
print(f"Publishing {image_dst} to {name}, skipping (dry run)")
if latest:
print(f"Publishing {image_source} to {name}, skipping (dry run)")
for alt_tag in current_alt_tag:
print(
f"Publishing {image_conf['name']}:{alt_tag} to {name}, skipping (dry run)"
)
else:
success &= c2cciutils.publish.docker(
conf, name, image_conf, tag_src, tag_dst, latest, images_full
conf,
name,
image_conf,
tag_src,
tag_dst,
latest,
current_alt_tag,
images_full,
)

if google_calendar_publish:
Expand Down

0 comments on commit f1ff990

Please sign in to comment.