Skip to content

Commit e2bf9e2

Browse files
authored
Merge pull request #142 from adamblake/main
Allow extra options to be passed to docker build
2 parents 46b80fc + 3bed6da commit e2bf9e2

File tree

5 files changed

+125
-8
lines changed

5 files changed

+125
-8
lines changed

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,14 @@ charts:
192192
buildArgs:
193193
MY_STATIC_BUILD_ARG: "hello world"
194194
MY_DYNAMIC_BUILD_ARG: "{TAG}-{LAST_COMMIT}"
195+
# Build options to be passed to the docker build command. Pass a list
196+
# of strings to be appended to the end of the build command. These are
197+
# passed directly to the command line, so prepend each option with "--"
198+
# like in the examples below. TAG and LAST_COMMIT are expandable.
199+
extraBuildCommandOptions:
200+
- --label=maintainer=octocat
201+
- --label=ref={TAG}-{LAST_COMMIT}
202+
- --rm
195203
# contextPath is the path to the directory that is to be considered the
196204
# current working directory during the build process of the Dockerfile.
197205
# This is by default the folder of the Dockerfile. This path should be

chartpress.py

100755100644
Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,23 @@ def _get_image_build_args(image_options, ns):
236236
return build_args
237237

238238

239+
def _get_image_extra_build_command_options(image_options, ns):
240+
"""
241+
Render extraBuildCommandOptions from chartpress.yaml that could be
242+
templates, using the provided namespace that contains keys with dynamic
243+
values such as LAST_COMMIT or TAG.
244+
245+
Args:
246+
image_options (dict):
247+
The dictionary for a given image from chartpress.yaml.
248+
Strings in `image_options['extraBuildCommandOptions']` will be rendered
249+
and returned.
250+
ns (dict): the namespace used when rendering templated arguments
251+
"""
252+
options = image_options.get("extraBuildCommandOptions", [])
253+
return [str(option).format(**ns) for option in options]
254+
255+
239256
def _get_image_build_context_path(name, options):
240257
"""
241258
Return the image's contextPath configuration value, or a default value based
@@ -296,6 +313,7 @@ def build_image(
296313
context_path,
297314
dockerfile_path=None,
298315
build_args=None,
316+
extra_build_command_options=None,
299317
*,
300318
push=False,
301319
builder=Builder.DOCKER_BUILD,
@@ -321,6 +339,9 @@ def build_image(
321339
"<context_path>/Dockerfile".
322340
build_args (dict, optional):
323341
Dictionary of docker build arguments.
342+
extra_build_command_options (list, optional):
343+
List of other docker build options to use. Each item should be a string
344+
that gets appended to the build command (e.g. "--label=version=0.1.0").
324345
push (bool, optional):
325346
Whether to push the image to a registry
326347
builder (str):
@@ -356,6 +377,8 @@ def build_image(
356377
cmd.append("--push")
357378
elif len(platforms) <= 1:
358379
cmd.append("--load")
380+
if extra_build_command_options:
381+
cmd.extend(extra_build_command_options)
359382
_check_call(cmd)
360383

361384
if builder == Builder.DOCKER_BUILD and push:
@@ -592,18 +615,19 @@ def build_images(
592615

593616
# build image and optionally push image
594617
if force_build or _image_needs_building(image_spec, platforms):
618+
expansion_namespace = {
619+
"LAST_COMMIT": _get_latest_commit_tagged_or_modifying_paths(
620+
*all_image_paths, echo=False
621+
),
622+
"TAG": image_tag,
623+
}
595624
build_image(
596625
image_spec,
597626
_get_image_build_context_path(name, options),
598627
dockerfile_path=_get_image_dockerfile_path(name, options),
599-
build_args=_get_image_build_args(
600-
options,
601-
{
602-
"LAST_COMMIT": _get_latest_commit_tagged_or_modifying_paths(
603-
*all_image_paths, echo=False
604-
),
605-
"TAG": image_tag,
606-
},
628+
build_args=_get_image_build_args(options, expansion_namespace),
629+
extra_build_command_options=_get_image_extra_build_command_options(
630+
options, expansion_namespace
607631
),
608632
push=push or force_push,
609633
builder=builder,

tests/test_commands.py

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

5555

56+
@pytest.mark.parametrize("with_opts", [False, True])
57+
def test_build_image_with_options(git_repo, mock_check_call, with_opts):
58+
image_spec = "index.docker.io/library/ubuntu:latest"
59+
context_path = "dir"
60+
dockerfile_path = None
61+
build_args = None
62+
extra_build_command_options = None
63+
64+
if with_opts:
65+
dockerfile_path = "Dockerfile.custom"
66+
extra_build_command_options = [
67+
"--label=maintainer=octocat",
68+
"--label",
69+
"ref=tag-sha",
70+
"--rm",
71+
]
72+
73+
chartpress.build_image(
74+
image_spec,
75+
context_path,
76+
dockerfile_path,
77+
build_args,
78+
extra_build_command_options,
79+
)
80+
81+
assert len(mock_check_call.commands) == 1
82+
if with_opts:
83+
sha = git_repo.commit(git_repo.head).hexsha
84+
assert mock_check_call.commands[0] == (
85+
[
86+
"docker",
87+
"build",
88+
"-t",
89+
image_spec,
90+
context_path,
91+
"-f",
92+
"Dockerfile.custom",
93+
"--label=maintainer=octocat",
94+
"--label",
95+
"ref=tag-sha",
96+
"--rm",
97+
],
98+
{},
99+
)
100+
else:
101+
assert mock_check_call.commands[0] == (
102+
[
103+
"docker",
104+
"build",
105+
"-t",
106+
image_spec,
107+
context_path,
108+
],
109+
{},
110+
)
111+
112+
56113
@pytest.mark.parametrize("push", [False, True])
57114
@pytest.mark.parametrize("tag", [None, "1.2.3"])
58115
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: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from chartpress import _get_git_remote_url
66
from chartpress import _get_identifier_from_parts
77
from chartpress import _get_image_build_args
8+
from chartpress import _get_image_extra_build_command_options
89
from chartpress import _get_latest_commit_tagged_or_modifying_paths
910
from chartpress import _image_needs_pushing
1011
from chartpress import Builder
@@ -156,3 +157,25 @@ def test__get_image_build_args(git_repo):
156157
}
157158
else:
158159
assert build_args == {}
160+
161+
162+
def test__get_image_extra_build_command_options(git_repo):
163+
with open("chartpress.yaml") as f:
164+
config = yaml.load(f)
165+
for chart in config["charts"]:
166+
for name, options in chart["images"].items():
167+
extra_build_command_options = _get_image_extra_build_command_options(
168+
options,
169+
{
170+
"LAST_COMMIT": "sha",
171+
"TAG": "tag",
172+
},
173+
)
174+
assert name in ("testimage", "amd64only")
175+
if name == "testimage":
176+
assert extra_build_command_options == [
177+
"--label=maintainer=octocat",
178+
"--label",
179+
"ref=tag-sha",
180+
"--rm",
181+
]

0 commit comments

Comments
 (0)