Skip to content

Commit b62dcc7

Browse files
authored
Merge branch 'main' into sortable-versions
2 parents f129f43 + d4900b0 commit b62dcc7

File tree

10 files changed

+180
-48
lines changed

10 files changed

+180
-48
lines changed

.github/workflows/publish.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ jobs:
2727
runs-on: ubuntu-20.04
2828
steps:
2929
- uses: actions/checkout@v3
30-
- uses: actions/setup-python@v3
30+
- uses: actions/setup-python@v4
3131
with:
3232
python-version: "3.9"
3333

@@ -43,7 +43,7 @@ jobs:
4343
ls -alh dist
4444
4545
- name: publish to pypi
46-
uses: pypa/[email protected].0
46+
uses: pypa/[email protected].1
4747
if: startsWith(github.ref, 'refs/tags/')
4848
with:
4949
user: __token__

.github/workflows/test.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,9 @@ jobs:
4949
# chartpress requires the full history
5050
fetch-depth: 0
5151

52-
# NOTE: actions/setup-python@v3 make use of a cache within the GitHub base
52+
# NOTE: actions/setup-python@v4 make use of a cache within the GitHub base
5353
# environment and setup in a fraction of a second.
54-
- uses: actions/setup-python@v3
54+
- uses: actions/setup-python@v4
5555
with:
5656
python-version: "${{ matrix.python }}"
5757

@@ -75,7 +75,7 @@ jobs:
7575

7676
# https://github.com/docker/setup-buildx-action
7777
- name: Setup docker buildx
78-
uses: docker/setup-buildx-action@v1
78+
uses: docker/setup-buildx-action@v2
7979
with:
8080
# Allows pushing to registry on localhost:5000
8181
driver-opts: network=host

.pre-commit-config.yaml

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,28 +9,42 @@
99
# - Register git hooks: pre-commit install --install-hooks
1010
#
1111
repos:
12+
# Autoformat: Python code, syntax patterns are modernized
13+
- repo: https://github.com/asottile/pyupgrade
14+
rev: v2.37.3
15+
hooks:
16+
- id: pyupgrade
17+
args:
18+
- --py37-plus
19+
1220
# Autoformat: Python code
1321
- repo: https://github.com/psf/black
14-
rev: 22.1.0
22+
rev: 22.6.0
1523
hooks:
1624
- id: black
17-
args: [--target-version=py36]
25+
args:
26+
- --target-version=py37
27+
- --target-version=py38
28+
- --target-version=py39
29+
- --target-version=py310
1830

19-
# Autoformat: markdown, yaml
20-
- repo: https://github.com/pre-commit/mirrors-prettier
21-
rev: v2.5.1
31+
# Autoformat: Python code
32+
- repo: https://github.com/pycqa/isort
33+
rev: 5.10.1
2234
hooks:
23-
- id: prettier
35+
- id: isort
36+
args:
37+
- --profile=black
2438

25-
# Autoformat: https://github.com/asottile/reorder_python_imports
26-
- repo: https://github.com/asottile/reorder_python_imports
39+
# Autoformat: markdown, yaml
40+
- repo: https://github.com/pre-commit/mirrors-prettier
2741
rev: v2.7.1
2842
hooks:
29-
- id: reorder-python-imports
43+
- id: prettier
3044

3145
# Misc...
3246
- repo: https://github.com/pre-commit/pre-commit-hooks
33-
rev: v4.1.0
47+
rev: v4.3.0
3448
# ref: https://github.com/pre-commit/pre-commit-hooks#hooks-available
3549
hooks:
3650
# Autoformat: Makes sure files end in a newline and only a newline.
@@ -48,6 +62,6 @@ repos:
4862

4963
# Lint: Python code
5064
- repo: https://github.com/PyCQA/flake8
51-
rev: "4.0.1"
65+
rev: "5.0.4"
5266
hooks:
5367
- id: flake8

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,14 @@ charts:
206206
buildArgs:
207207
MY_STATIC_BUILD_ARG: "hello world"
208208
MY_DYNAMIC_BUILD_ARG: "{TAG}-{LAST_COMMIT}"
209+
# Build options to be passed to the docker build command. Pass a list
210+
# of strings to be appended to the end of the build command. These are
211+
# passed directly to the command line, so prepend each option with "--"
212+
# like in the examples below. TAG and LAST_COMMIT are expandable.
213+
extraBuildCommandOptions:
214+
- --label=maintainer=octocat
215+
- --label=ref={TAG}-{LAST_COMMIT}
216+
- --rm
209217
# contextPath is the path to the directory that is to be considered the
210218
# current working directory during the build process of the Dockerfile.
211219
# This is by default the folder of the Dockerfile. This path should be

chartpress.py

100755100644
Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@
1313
import sys
1414
from collections.abc import MutableMapping
1515
from enum import Enum
16-
from functools import lru_cache
17-
from functools import partial
16+
from functools import lru_cache, partial
1817
from tempfile import TemporaryDirectory
1918

2019
import docker
@@ -246,6 +245,23 @@ def _get_image_build_args(image_options, ns):
246245
return build_args
247246

248247

248+
def _get_image_extra_build_command_options(image_options, ns):
249+
"""
250+
Render extraBuildCommandOptions from chartpress.yaml that could be
251+
templates, using the provided namespace that contains keys with dynamic
252+
values such as LAST_COMMIT or TAG.
253+
254+
Args:
255+
image_options (dict):
256+
The dictionary for a given image from chartpress.yaml.
257+
Strings in `image_options['extraBuildCommandOptions']` will be rendered
258+
and returned.
259+
ns (dict): the namespace used when rendering templated arguments
260+
"""
261+
options = image_options.get("extraBuildCommandOptions", [])
262+
return [str(option).format(**ns) for option in options]
263+
264+
249265
def _get_image_build_context_path(name, options):
250266
"""
251267
Return the image's contextPath configuration value, or a default value based
@@ -306,6 +322,7 @@ def build_image(
306322
context_path,
307323
dockerfile_path=None,
308324
build_args=None,
325+
extra_build_command_options=None,
309326
*,
310327
push=False,
311328
builder=Builder.DOCKER_BUILD,
@@ -331,6 +348,9 @@ def build_image(
331348
"<context_path>/Dockerfile".
332349
build_args (dict, optional):
333350
Dictionary of docker build arguments.
351+
extra_build_command_options (list, optional):
352+
List of other docker build options to use. Each item should be a string
353+
that gets appended to the build command (e.g. "--label=version=0.1.0").
334354
push (bool, optional):
335355
Whether to push the image to a registry
336356
builder (str):
@@ -366,6 +386,8 @@ def build_image(
366386
cmd.append("--push")
367387
elif len(platforms) <= 1:
368388
cmd.append("--load")
389+
if extra_build_command_options:
390+
cmd.extend(extra_build_command_options)
369391
_check_call(cmd)
370392

371393
if builder == Builder.DOCKER_BUILD and push:
@@ -626,18 +648,19 @@ def build_images(
626648

627649
# build image and optionally push image
628650
if force_build or _image_needs_building(image_spec, platforms):
651+
expansion_namespace = {
652+
"LAST_COMMIT": _get_latest_commit_tagged_or_modifying_paths(
653+
*all_image_paths, echo=False
654+
),
655+
"TAG": image_tag,
656+
}
629657
build_image(
630658
image_spec,
631659
_get_image_build_context_path(name, options),
632660
dockerfile_path=_get_image_dockerfile_path(name, options),
633-
build_args=_get_image_build_args(
634-
options,
635-
{
636-
"LAST_COMMIT": _get_latest_commit_tagged_or_modifying_paths(
637-
*all_image_paths, echo=False
638-
),
639-
"TAG": image_tag,
640-
},
661+
build_args=_get_image_build_args(options, expansion_namespace),
662+
extra_build_command_options=_get_image_extra_build_command_options(
663+
options, expansion_namespace
641664
),
642665
push=push or force_push,
643666
builder=builder,
@@ -897,9 +920,11 @@ def publish_pages(
897920
if os.path.isfile(os.path.join(checkout_dir, "index.yaml")):
898921
with open(os.path.join(checkout_dir, "index.yaml")) as f:
899922
chart_repo_index = yaml.load(f)
900-
published_charts = chart_repo_index["entries"].get(chart_name)
923+
published_charts = chart_repo_index["entries"].get(chart_name, [])
901924

902-
if any(c["version"] == chart_version for c in published_charts):
925+
if published_charts and any(
926+
c["version"] == chart_version for c in published_charts
927+
):
903928
if force:
904929
_log(
905930
f"Chart of version {chart_version} already exists, overwriting it."

tests/test_chartpress.py

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
import json
22
import sys
3-
from subprocess import PIPE
4-
from subprocess import run
5-
from urllib.request import Request
6-
from urllib.request import urlopen
3+
from subprocess import PIPE, run
4+
from urllib.request import Request, urlopen
75
from uuid import uuid4
86

97
import pytest
@@ -15,8 +13,7 @@ def test_list_images(git_repo):
1513
p = run(
1614
[sys.executable, "-m", "chartpress", "--list-images"],
1715
check=True,
18-
stdout=PIPE,
19-
stderr=PIPE,
16+
capture_output=True,
2017
)
2118
stdout = p.stdout.decode("utf8").strip()
2219
# echo stdout/stderr for debugging
@@ -32,8 +29,7 @@ def test_list_images(git_repo):
3229
p = run(
3330
["git", "status", "--porcelain"],
3431
check=True,
35-
stdout=PIPE,
36-
stderr=PIPE,
32+
capture_output=True,
3733
)
3834
assert not p.stdout, "--list-images should not make changes!"
3935

@@ -88,6 +84,7 @@ def test_buildx(git_repo, capfd):
8884
tag,
8985
],
9086
check=True,
87+
capture_output=True,
9188
)
9289
stdout, stderr = capfd.readouterr()
9390
# stdout = p.stdout.decode("utf8").strip()

tests/test_commands.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,63 @@ def test_build_image(mock_check_call, with_args):
5454
)
5555

5656

57+
@pytest.mark.parametrize("with_opts", [False, True])
58+
def test_build_image_with_options(git_repo, mock_check_call, with_opts):
59+
image_spec = "index.docker.io/library/ubuntu:latest"
60+
context_path = "dir"
61+
dockerfile_path = None
62+
build_args = None
63+
extra_build_command_options = None
64+
65+
if with_opts:
66+
dockerfile_path = "Dockerfile.custom"
67+
extra_build_command_options = [
68+
"--label=maintainer=octocat",
69+
"--label",
70+
"ref=tag-sha",
71+
"--rm",
72+
]
73+
74+
chartpress.build_image(
75+
image_spec,
76+
context_path,
77+
dockerfile_path,
78+
build_args,
79+
extra_build_command_options,
80+
)
81+
82+
assert len(mock_check_call.commands) == 1
83+
if with_opts:
84+
sha = git_repo.commit(git_repo.head).hexsha
85+
assert mock_check_call.commands[0] == (
86+
[
87+
"docker",
88+
"build",
89+
"-t",
90+
image_spec,
91+
context_path,
92+
"-f",
93+
"Dockerfile.custom",
94+
"--label=maintainer=octocat",
95+
"--label",
96+
"ref=tag-sha",
97+
"--rm",
98+
],
99+
{},
100+
)
101+
else:
102+
assert mock_check_call.commands[0] == (
103+
[
104+
"docker",
105+
"build",
106+
"-t",
107+
image_spec,
108+
context_path,
109+
],
110+
{},
111+
)
112+
113+
57114
@pytest.mark.parametrize("push", [False, True])
58115
@pytest.mark.parametrize("tag", [None, "1.2.3"])
59116
def test_build_images(git_repo, mock_check_call, push, tag):

tests/test_helm_chart/chartpress.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ charts:
1313
buildArgs:
1414
TEST_STATIC_BUILD_ARG: "test"
1515
TEST_DYNAMIC_BUILD_ARG: "{TAG}-{LAST_COMMIT}"
16+
extraBuildCommandOptions:
17+
- --label=maintainer=octocat
18+
- --label
19+
- ref={TAG}-{LAST_COMMIT}
20+
- --rm
1621
contextPath: image
1722
dockerfilePath: image/Dockerfile
1823
valuesPath:

tests/test_helpers.py

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
import pytest
22

3-
from chartpress import _check_call
4-
from chartpress import _fix_chart_version
5-
from chartpress import _get_git_remote_url
6-
from chartpress import _get_identifier_from_parts
7-
from chartpress import _get_image_build_args
8-
from chartpress import _get_latest_commit_tagged_or_modifying_paths
9-
from chartpress import _image_needs_pushing
10-
from chartpress import GITHUB_ACTOR_KEY
11-
from chartpress import GITHUB_TOKEN_KEY
12-
from chartpress import yaml
3+
from chartpress import (
4+
GITHUB_ACTOR_KEY,
5+
GITHUB_TOKEN_KEY,
6+
Builder,
7+
yaml,
8+
_check_call,
9+
_fix_chart_version,
10+
_get_git_remote_url,
11+
_get_identifier_from_parts,
12+
_get_image_build_args,
13+
_get_image_extra_build_command_options,
14+
_get_latest_commit_tagged_or_modifying_paths,
15+
_image_needs_pushing,
16+
)
1317

1418

1519
@pytest.mark.parametrize(
@@ -131,3 +135,25 @@ def test__get_image_build_args(git_repo):
131135
}
132136
else:
133137
assert build_args == {}
138+
139+
140+
def test__get_image_extra_build_command_options(git_repo):
141+
with open("chartpress.yaml") as f:
142+
config = yaml.load(f)
143+
for chart in config["charts"]:
144+
for name, options in chart["images"].items():
145+
extra_build_command_options = _get_image_extra_build_command_options(
146+
options,
147+
{
148+
"LAST_COMMIT": "sha",
149+
"TAG": "tag",
150+
},
151+
)
152+
assert name in ("testimage", "amd64only")
153+
if name == "testimage":
154+
assert extra_build_command_options == [
155+
"--label=maintainer=octocat",
156+
"--label",
157+
"ref=tag-sha",
158+
"--rm",
159+
]

0 commit comments

Comments
 (0)