I'm thinking this may be a simple error, but nothi...
# general
b
I'm thinking this may be a simple error, but nothing I've tried has worked. I'm trying to get my CI workflow on Github working, but I'm having trouble with passing in my build arguments. My
docker_image
target is very simple:
Copy code
docker_image(
    name="app",
    image_tags=["{build_args.GIT_COMMIT}", "latest"],
    registries=["{build_args.REGISTRY}"],
)
then I have Github run it using
./pants --docker-build-args="[GIT_COMMIT=${GITHUB_SHA::7}, REGISTRY=${{ steps.login-ecr.outputs.registry }}]" package src/services/app/Dockerfile
. The error is in the 🧵, my guess is I have the syntax wrong in my package statement but I can't figure it out.
âś… 1
Copy code
Exception message: Error computing value for --build-args in scope 'docker' (may also be from PANTS_* environment variables).
39
Caused by:
40
The value cannot be evaluated as a literal expression: SyntaxError('invalid syntax', ('<string>', 1, 12, '[GIT_COMMIT=f716139, REGISTRY=***.<http://dkr.ecr.us-west-2.amazonaws.com|dkr.ecr.us-west-2.amazonaws.com>]'))
41
Given raw value:
42
1: [GIT_COMMIT=f716139, REGISTRY=***.<http://dkr.ecr.us-west-2.amazonaws.com|dkr.ecr.us-west-2.amazonaws.com>]
45
w
list values are parsed as python
list
literals
so you probably want something shaped closer to:
Copy code
./pants --docker-build-args='["GIT_COMMIT=${GITHUB_SHA::7}", "REGISTRY=${{ steps.login-ecr.outputs.registry }}"]' package src/services/app/Dockerfile
…but you’ll need to do a bit of escaping there =/
…maybe
Copy code
"[\"GIT_COMMIT=${GITHUB_SHA::7}\", \"REGISTRY=${{ steps.login-ecr.outputs.registry }}\"]"
?
oh, alternatively, if you don’t use a list literal, you can append the option multiple times:
Copy code
./pants --docker-build-args="GIT_COMMIT=${GITHUB_SHA::7}" --docker-build-args="REGISTRY=${{ steps.login-ecr.outputs.registry }}" package src/services/app/Dockerfile
… which looks much cleaner in this case i think
b
Having REGISTRY= in quotes or out of quotes is giving two different errors. If I don't have it in quotes, the error is as I wrote above (can't parse the list). If I DO have it in quotes however, I get errors that look like
Copy code
ProcessExecutionFailure: Process 'Building docker image {build_args.REGISTRY}/dandelion:2bf4e5e +1 additional tag.' failed with exit code 125.

stdout:

stderr:

invalid argument "{build_args.REGISTRY}/dandelion:2bf4e5e" for "-t, --tag" flag: invalid reference format

See 'docker build --help'.
So either it passes in the variable correctly but can't parse the build_args, or it parses it correctly but doesn't pass it in.
(@witty-crayon-22786 this is with any of your solutions, the last of which I agree is the cleanest)
w
cc @curved-television-6568 any ideas?
đź‘€ 1
c
Uhm… the
registries
field does not support string interpolation as the
image_tags
field does. It’s not super clear, but mentioned in the docs: https://www.pantsbuild.org/v2.12/docs/reference-docker_image#codeimage_tagscode
tag may use placeholders in curly braces to be interpolated. The placeholders are derived from various sources, such as the Dockerfile instructions and build args.
That snippet about placeholders is missing for the registries field, indicating it does not support it. Sorry for the confusion.
âś… 2
b
So is there any way to define a registry dynamically like this?
c
Yes, you can setup registries dynamically.. hmm, the trickier part may be how to apply them to your docker image targets, if they shouldn’t be applied to all of them.. ?
What does your docker image targets look like? will they all be using the same dynamic registry?
b
Well they can all use them like this, defined at Github action time. So I can have one "dynamic" definition for everything
Yes, I can define it once
c
Great, so just dynamically declare one default registry, and removing the registry field of each target will have them use the default one
b
Set it in the
pants.toml
you mean? Something like this:
Copy code
[docker.registries.company-ecr]
address = {build_args.REGISTRY}
Do the curly braces work there?
(I think so, I see
{build_args.ARG_NAME}: Each defined Docker build arg is available for interpolation under the build_args. prefix.
in the docs)
c
No, they do not. Would it be ok to setup the default registry from the cmd line each time?
Copy code
╰─❯ ./pants --docker-registries='{"default":{"address":"foo.bar"}}' package testprojects/src/python/docker:test-example
â ¤ 7.76s Building docker image foo.bar/test-example:1.2.5
🙏 1
b
yeah no reason that can't work, let me give it a shot...
đź‘Ť 1
I think that got it, thank you very much!
🙌 2
b
Just found this, trying to do the same thing getting frustrated. Specifically, this would make my life easier:
Copy code
[docker]
build_args = ["namebase", "aws_account", "aws_region"]

[docker.registries.legacy-prod]
address = "{build_args.aws_account}.dkr.ecr.{build_args.aws_region}.<http://amazonaws.com|amazonaws.com>"
repository = "{build_args.namebase}"
I can work around it with a wrapper script but it'd be nice not to have to!
p
Hi, I was reading up about this and started wondering if this new official blog post would be useful to you https://www.pantsbuild.org/blog/2024/04/27/simple-versioning-with-git-tags
I mean, apparently one could set up at bootstrap time that value for registries and then use
env(...)
b
Interesting, I didn't know about
.pants.bootstrap
and it may help for other things 🙂 in this case we have args passed in from terraform. I think in this specific case we still run into the problem that the registry address doesn't interpolate curly-brace values.
The downside to my current approach (passing
--docker-registries=...
on the command line) is my configuration is now split across two places: pants.toml and my CI script
đź‘– 1