@@ -14,15 +14,15 @@ vars:
1414 PYTHON_VERSION : {{ cookiecutter.python_version }}
1515 SUPPORTED_PLATFORMS : ' linux/amd64,linux/arm64'
1616 VERSION :
17- sh : uv run python -c 'from src.{{ "{{" }} .PROJECT_SLUG{{ "}}" }} import __version__; print(__version__)'
17+ sh : uv run python -c 'from src.{{ '{{ .PROJECT_SLUG}}' }} import __version__; print(__version__)'
1818 RUN_SCRIPT : ' uv run --frozen'
1919 SCRIPTS_DIR : ' scripts'
2020 LOCAL_PLATFORM :
21- sh : " {{ " {{" }} .RUN_SCRIPT{{ "}}" }} {{ "{{" }} .SCRIPTS_DIR{{ "}}" }}/get_platform.sh"
21+ sh : " {{ '{{ .RUN_SCRIPT}}' }} {{ '{{ .SCRIPTS_DIR}}' }}/get_platform.sh"
2222 # Use PLATFORM if specified, otherwise use LOCAL_PLATFORM
23- PLATFORM : ' {{ "{{" }} if .PLATFORM{{ "}}" }}{{ "{{" }} .PLATFORM{{ "}}" }}{{ "{{" }} else{{ "}}" }}{{ "{{" }} .LOCAL_PLATFORM{{ "}}" }}{{ "{{" }} end{{ "}}" }}'
23+ PLATFORM : ' {{ ' {{ if .PLATFORM}}' }}{{ '{{ .PLATFORM}}' }}{{ '{{ else}}' }}{{ '{{ .LOCAL_PLATFORM}}' }}{{ '{{ end}}' }}'
2424 # Output redirect based on CI environment
25- OUTPUT_REDIRECT : ' {{ "{{" }} if eq .GITHUB_ACTIONS "true"{{ "}}" }}| tee{{ "{{" }} else{{ "}}" }}>{{ "{{" }} end{{ "}}" }}'
25+ OUTPUT_REDIRECT : ' {{ ' {{ if eq .GITHUB_ACTIONS "true"}}' }}| tee{{ '{{ else}}' }}>{{ '{{ end}}' }}'
2626
2727silent : true
2828
5353 cmds :
5454 - uv tool install pre-commit
5555 # Don't run this in pipelines
56- - ' {{ "{{" }} if ne .GITHUB_ACTIONS "true"{{ " }}{{.RUN_SCRIPT}} pre-commit install{{else}}echo \ "Detected a github actions pipeline; skipping the pre-commit install\ "{{end}}" }}'
56+ - ' {{ ' {{ if ne .GITHUB_ACTIONS "true"}}{{.RUN_SCRIPT}} pre-commit install{{else}}echo "Detected a github actions pipeline; skipping the pre-commit install"{{end}}' }}'
5757
5858 init-docker-multiplatform :
5959 desc : Setup docker for multiplatform builds
6262 # This fixes an "ERROR: Multiple platforms feature is currently not supported for docker driver" pipeline error
6363 # Only create our multiplatform builder if it doesn't already exist; otherwise list information about the one that exists
6464 # It suppresses the inspect output when it's not running in a GitHub Action
65- - docker buildx inspect multiplatform {{ "{{" }} if ne .GITHUB_ACTIONS "true"{{ "}}" }}>/dev/null{{ " {{end}}" }} || docker buildx create --name multiplatform --driver docker-container --use
65+ - docker buildx inspect multiplatform {{ '{{ if ne .GITHUB_ACTIONS "true"}}' }}>/dev/null{{ ' {{end}}' }} || docker buildx create --name multiplatform --driver docker-container --use
6666
6767 init :
6868 desc : Initialize the repo for local use; intended to be run after git clone
@@ -74,66 +74,66 @@ tasks:
7474 lint :
7575 desc : Run the linter(s)
7676 cmds :
77- - ' {{ " {{.RUN_SCRIPT}}" }} pre-commit run --all-files'
77+ - ' {{ ' {{.RUN_SCRIPT}}' }} pre-commit run --all-files'
7878
7979 validate :
8080 desc : Validate the pre-commit config and hooks files
8181 cmds :
82- - ' {{ " {{.RUN_SCRIPT}}" }} pre-commit validate-config'
83- - ' {{ " {{.RUN_SCRIPT}}" }} pre-commit validate-manifest'
84- - ' {{ " {{.RUN_SCRIPT}}" }} python scripts/validate_service_definition.py'
82+ - ' {{ ' {{.RUN_SCRIPT}}' }} pre-commit validate-config'
83+ - ' {{ ' {{.RUN_SCRIPT}}' }} pre-commit validate-manifest'
84+ - ' {{ ' {{.RUN_SCRIPT}}' }} python scripts/validate_service_definition.py'
8585
8686 build :
8787 desc : Build the project; docker images, compiled binaries, etc.
8888 vars :
8989 TIMESTAMP :
90- sh : ' {{ "{{" }} .RUN_SCRIPT{{ "}}" }} {{ "{{" }} .SCRIPTS_DIR{{ "}}" }}/get_rfc3339_timestamp.py'
90+ sh : ' {{ ' {{ .RUN_SCRIPT}}' }} {{ '{{ .SCRIPTS_DIR}}' }}/get_rfc3339_timestamp.py'
9191 EPOCH :
92- sh : ' {{ "{{" }} .RUN_SCRIPT{{ "}}" }} {{ "{{" }} .SCRIPTS_DIR{{ "}}" }}/get_epoch.sh'
92+ sh : ' {{ ' {{ .RUN_SCRIPT}}' }} {{ '{{ .SCRIPTS_DIR}}' }}/get_epoch.sh'
9393 COMMIT_HASH :
9494 sh : git rev-parse HEAD
95- BUILD_PLATFORM : ' {{ "{{" }} if eq .PLATFORM "all"{{ "}}" }}{{ "{{" }} .SUPPORTED_PLATFORMS{{ "}}" }}{{ "{{" }} else if .PLATFORM{{ "}}" }}{{ "{{" }} .PLATFORM{{ "}}" }}{{ "{{" }} else{{ "}}" }}{{ "{{" }} .LOCAL_PLATFORM{{ "}}" }}{{ "{{" }} end{{ "}}" }}'
96- PLATFORM_SUFFIX : ' {{ "{{" }} if eq .PLATFORM "all"{{ "}}" }}all{{ "{{" }} else if .PLATFORM{{ "}}" }}{{ "{{" }} .PLATFORM | replace "/" "_"{{ "}}" }}{{ "{{" }} else{{ "}}" }}{{ "{{" }} .LOCAL_PLATFORM | replace "/" "_"{{ "}}" }}{{ "{{" }} end{{ "}}" }}'
95+ BUILD_PLATFORM : ' {{ ' {{ if eq .PLATFORM "all"}}' }}{{ '{{ .SUPPORTED_PLATFORMS}}' }}{{ '{{ else if .PLATFORM}}' }}{{ '{{ .PLATFORM}}' }}{{ '{{ else}}' }}{{ '{{ .LOCAL_PLATFORM}}' }}{{ '{{ end}}' }}'
96+ PLATFORM_SUFFIX : ' {{ ' {{ if eq .PLATFORM "all"}}' }}all{{ '{{ else if .PLATFORM}}' }}{{ '{{ .PLATFORM | replace "/" "_"}}' }}{{ '{{ else}}' }}{{ '{{ .LOCAL_PLATFORM | replace "/" "_"}}' }}{{ '{{ end}}' }}'
9797 # We always output to "latest", since we're also overwriting latest
98- OUTPUT_FILE : ' {{ "{{" }} .IMAGE_NAME | replace "/" "_"{{ "}}" }}_latest_{{ "{{" }} .PLATFORM_SUFFIX{{ "}}" }}.tar'
98+ OUTPUT_FILE : ' {{ ' {{ .IMAGE_NAME | replace "/" "_"}}' }}_latest_{{ '{{ .PLATFORM_SUFFIX}}' }}.tar'
9999 DESCRIPTION : ' {{ cookiecutter.project_short_description }}'
100100 cmds :
101101 # First build: load if same platform, output to file if cross-platform
102102 - |
103103 docker buildx build \
104- --platform {{ "{{" }} .BUILD_PLATFORM{{ "}}" }} \
104+ --platform {{ '{{ .BUILD_PLATFORM}}' }} \
105105 --pull \
106- {{ "{{" }} if eq .PLATFORM .LOCAL_PLATFORM{{ "}}" }}--load{{ "{{" }} else{{ "}}" }}-o type=oci,dest="{{ "{{" }} .OUTPUT_FILE{{ "}}" }}"{{ "{{" }} end{{ "}}" }} \
107- {{ "{{" }} if eq .GITHUB_ACTIONS "true"{{ "}}" }}--cache-from type=gha --cache-to type=gha,mode=max{{ "{{" }} end{{ "}}" }} \
108- --build-arg NAME="{{ "{{" }} .PROJECT_SLUG{{ "}}" }}" \
109- --build-arg DESCRIPTION="{{ "{{" }} .DESCRIPTION{{ "}}" }}" \
110- --build-arg TIMESTAMP="{{ "{{" }} .TIMESTAMP{{ "}}" }}" \
111- --build-arg COMMIT_HASH="{{ "{{" }} .COMMIT_HASH{{ "}}" }}" \
112- -t {{ " {{.IMAGE_NAME}}:{{.VERSION}}" }} \
113- -t {{ " {{.IMAGE_NAME}}:latest" }} \
114- -t {{ " {{.IMAGE_NAME}}:{{.EPOCH}}" }} \
106+ {{ '{{ if eq .PLATFORM .LOCAL_PLATFORM}}' }}--load{{ '{{ else}}' }}-o type=oci,dest="{{ '{{ .OUTPUT_FILE}}' }}"{{ '{{ end}}' }} \
107+ {{ '{{ if eq .GITHUB_ACTIONS "true"}}' }}--cache-from type=gha --cache-to type=gha,mode=max{{ '{{ end}}' }} \
108+ --build-arg NAME="{{ '{{ .PROJECT_SLUG}}' }}" \
109+ --build-arg DESCRIPTION="{{ '{{ .DESCRIPTION}}' }}" \
110+ --build-arg TIMESTAMP="{{ '{{ .TIMESTAMP}}' }}" \
111+ --build-arg COMMIT_HASH="{{ '{{ .COMMIT_HASH}}' }}" \
112+ -t {{ ' {{.IMAGE_NAME}}:{{.VERSION}}' }} \
113+ -t {{ ' {{.IMAGE_NAME}}:latest' }} \
114+ -t {{ ' {{.IMAGE_NAME}}:{{.EPOCH}}' }} \
115115 .
116116 # Second build: only for same platform to also output to file
117117 - |
118- {{ "{{" }} if eq .PLATFORM .LOCAL_PLATFORM{{ "}}" }}
118+ {{ '{{ if eq .PLATFORM .LOCAL_PLATFORM}}' }}
119119 docker buildx build \
120- --platform {{ "{{" }} .BUILD_PLATFORM{{ "}}" }} \
121- -o type=oci,dest="{{ "{{" }} .OUTPUT_FILE{{ "}}" }}" \
122- {{ "{{" }} if eq .GITHUB_ACTIONS "true"{{ "}}" }}--cache-from type=gha{{ "{{" }} end{{ "}}" }} \
123- --build-arg NAME="{{ "{{" }} .PROJECT_SLUG{{ "}}" }}" \
124- --build-arg DESCRIPTION="{{ "{{" }} .DESCRIPTION{{ "}}" }}" \
125- --build-arg TIMESTAMP="{{ "{{" }} .TIMESTAMP{{ "}}" }}" \
126- --build-arg COMMIT_HASH="{{ "{{" }} .COMMIT_HASH{{ "}}" }}" \
127- -t {{ " {{.IMAGE_NAME}}:{{.VERSION}}" }} \
128- -t {{ " {{.IMAGE_NAME}}:latest" }} \
129- -t {{ " {{.IMAGE_NAME}}:{{.EPOCH}}" }} \
120+ --platform {{ '{{ .BUILD_PLATFORM}}' }} \
121+ -o type=oci,dest="{{ '{{ .OUTPUT_FILE}}' }}" \
122+ {{ '{{ if eq .GITHUB_ACTIONS "true"}}' }}--cache-from type=gha{{ '{{ end}}' }} \
123+ --build-arg NAME="{{ '{{ .PROJECT_SLUG}}' }}" \
124+ --build-arg DESCRIPTION="{{ '{{ .DESCRIPTION}}' }}" \
125+ --build-arg TIMESTAMP="{{ '{{ .TIMESTAMP}}' }}" \
126+ --build-arg COMMIT_HASH="{{ '{{ .COMMIT_HASH}}' }}" \
127+ -t {{ ' {{.IMAGE_NAME}}:{{.VERSION}}' }} \
128+ -t {{ ' {{.IMAGE_NAME}}:latest' }} \
129+ -t {{ ' {{.IMAGE_NAME}}:{{.EPOCH}}' }} \
130130 .
131- {{ "{{" }} end{{ "}}" }}
131+ {{ '{{ end}}' }}
132132 - |
133- {{ "{{" }} if and (ne .PLATFORM .LOCAL_PLATFORM) (ne .PLATFORM "all"){{ "}}" }}
134- echo >&2 "WARNING: Avoided loading {{ "{{" }} .IMAGE_NAME{{ "}}" }}:latest and {{ "{{" }} .IMAGE_NAME{{ "}}" }}:{{ "{{" }} .EPOCH{{ "}}" }} into your Docker daemon because you built a cross-platform image of {{ "{{" }} .PLATFORM{{ "}}" }}.
135- See {{ "{{" }} .OUTPUT_FILE{{ "}}" }} for the OCI artifact."
136- {{ "{{" }} end{{ "}}" }}
133+ {{ '{{ if and (ne .PLATFORM .LOCAL_PLATFORM) (ne .PLATFORM "all")}}' }}
134+ echo >&2 "WARNING: Avoided loading {{ '{{ .IMAGE_NAME}}' }}:latest and {{ '{{ .IMAGE_NAME}}' }}:{{ '{{ .EPOCH}}' }} into your Docker daemon because you built a cross-platform image of {{ '{{ .PLATFORM}}' }}.
135+ See {{ '{{ .OUTPUT_FILE}}' }} for the OCI artifact."
136+ {{ '{{ end}}' }}
137137
138138 test :
139139 desc : Run the project tests
@@ -148,33 +148,33 @@ tasks:
148148 run : once
149149 cmds :
150150 # Ensure we don't aggregate coverage from prior runs
151- - ' {{ " {{.RUN_SCRIPT}}" }} coverage erase'
151+ - ' {{ ' {{.RUN_SCRIPT}}' }} coverage erase'
152152
153153 unit-test :
154154 desc : Run the project unit tests
155155 deps : ["coverage-erase"]
156156 cmds :
157- - ' {{ " {{.RUN_SCRIPT}}" }} pytest -m unit tests/'
157+ - ' {{ ' {{.RUN_SCRIPT}}' }} pytest -m unit tests/'
158158
159159 integration-test :
160160 desc : Run the project integration tests
161161 deps : ["coverage-erase"]
162162 status :
163163 # Only run integration tests when the PLATFORM is set to all or the same platform as we're running on
164- - ' {{ "{{" }} if or (eq .PLATFORM "all") (eq .PLATFORM .LOCAL_PLATFORM) (not .PLATFORM){{ "}}" }}exit 1{{ "{{" }} else{{ "}}" }}exit 0{{ "{{" }} end{{ "}}" }}'
164+ - ' {{ ' {{ if or (eq .PLATFORM "all") (eq .PLATFORM .LOCAL_PLATFORM) (not .PLATFORM)}}' }}exit 1{{ '{{ else}}' }}exit 0{{ '{{ end}}' }}'
165165 cmds :
166- - ' {{ " {{.RUN_SCRIPT}}" }} pytest -m integration tests/'
166+ - ' {{ ' {{.RUN_SCRIPT}}' }} pytest -m integration tests/'
167167
168168 update :
169169 desc : Update the project dev and runtime dependencies
170170 cmds :
171171 # This currently assumes uv was installed via uv (locally); we will want to make it more flexible in the future
172- - ' {{ "{{" }} if ne .GITHUB_ACTIONS "true"{{ "}}" }}brew upgrade uv{{ "{{" }} end{{ "}}" }}'
172+ - ' {{ ' {{ if ne .GITHUB_ACTIONS "true"}}' }}brew upgrade uv{{ '{{ end}}' }}'
173173 - uv tool upgrade --all
174174 - pre-commit autoupdate --freeze --jobs 4
175175 - uv lock --upgrade
176176 # This can take a while but it's required for the following step to update BuildKit in the docker driver
177- - ' {{ "{{" }} if eq .CLI_ARGS "all"{{ "}}" }}docker buildx rm multiplatform || true{{ "{{" }} end{{ "}}" }}'
177+ - ' {{ ' {{ if eq .CLI_ARGS "all"}}' }}docker buildx rm multiplatform || true{{ '{{ end}}' }}'
178178 # If we just destroyed the "multiplatform" builder instance, this will configure a new one. The next time the host runs a `docker buildx build` it will
179179 # rebuild the builder instance, updating its BuildKit. There's no harm in running this even if we didn't do the `docker buildx rm` previously
180180 - task : init-docker-multiplatform
@@ -207,37 +207,37 @@ tasks:
207207 fi
208208 cmds :
209209 # Phase 1: Update version in files without any VCS operations
210- - ' {{ " {{.RUN_SCRIPT}}" }} semantic-release version --no-changelog --skip-build --no-commit --no-tag --no-push --no-vcs-release'
210+ - ' {{ ' {{.RUN_SCRIPT}}' }} semantic-release version --no-changelog --skip-build --no-commit --no-tag --no-push --no-vcs-release'
211211 # Re-lock dependencies to update version in uv.lock
212212 - uv lock
213213 # Stage the updated lock file
214214 - git add uv.lock
215215 # Phase 2: Run full release with commits, tags, and push; this will include the updated uv.lock
216- - ' {{ " {{.RUN_SCRIPT}}" }} semantic-release version --no-changelog --skip-build {{ " {{.CLI_ARGS}}" }}'
216+ - ' {{ ' {{.RUN_SCRIPT}}' }} semantic-release version --no-changelog --skip-build {{ ' {{.CLI_ARGS}}' }}'
217217
218218 sbom :
219219 desc : Generate project SBOMs
220220 cmds :
221221 - |
222- {{ " {{.RUN_SCRIPT}}" }} {{ " {{.SCRIPTS_DIR}}" }}/scan_image.py sbom \
223- --platform "{{ " {{.PLATFORM}}" }}" \
224- --image-name "{{ " {{.IMAGE_NAME}}" }}"
222+ {{ ' {{.RUN_SCRIPT}}' }} {{ ' {{.SCRIPTS_DIR}}' }}/scan_image.py sbom \
223+ --platform "{{ ' {{.PLATFORM}}' }}" \
224+ --image-name "{{ ' {{.IMAGE_NAME}}' }}"
225225
226226 vulnscan :
227227 desc : Vuln scan the SBOM
228228 cmds :
229229 - |
230- {{ " {{.RUN_SCRIPT}}" }} {{ " {{.SCRIPTS_DIR}}" }}/scan_image.py vulnscan \
231- --platform "{{ " {{.PLATFORM}}" }}" \
232- --image-name "{{ " {{.IMAGE_NAME}}" }}"
230+ {{ ' {{.RUN_SCRIPT}}' }} {{ ' {{.SCRIPTS_DIR}}' }}/scan_image.py vulnscan \
231+ --platform "{{ ' {{.PLATFORM}}' }}" \
232+ --image-name "{{ ' {{.IMAGE_NAME}}' }}"
233233
234234 license-check :
235235 desc : Check license compliance using grant
236236 cmds :
237237 - |
238- {{ " {{.RUN_SCRIPT}}" }} {{ " {{.SCRIPTS_DIR}}" }}/scan_image.py license-check \
239- --platform "{{ " {{.PLATFORM}}" }}" \
240- --image-name "{{ " {{.IMAGE_NAME}}" }}"
238+ {{ ' {{.RUN_SCRIPT}}' }} {{ ' {{.SCRIPTS_DIR}}' }}/scan_image.py license-check \
239+ --platform "{{ ' {{.PLATFORM}}' }}" \
240+ --image-name "{{ ' {{.IMAGE_NAME}}' }}"
241241
242242{%- if cookiecutter.dockerhub == 'yes' %}
243243
@@ -246,26 +246,26 @@ tasks:
246246 vars :
247247 INPUT_FILE :
248248 # Find the latest tar file for cross-platform builds
249- sh : ' {{ "{{" }} if and (ne .LOCAL_PLATFORM .PLATFORM) (ne .PLATFORM "all"){{ "}}}" }}ls {{ "{{" }} .IMAGE_NAME | replace "/" "_"{{ "}}" }}_*_{{ "{{" }} .PLATFORM | replace "/" "_" | replace "," "_"{{ "}}" }}.tar 2>/dev/null | sort -r | head -1{{ "{{" }} end{{ "}}" }}'
249+ sh : ' {{ ' {{ if and (ne .LOCAL_PLATFORM .PLATFORM) (ne .PLATFORM "all")}}' }}ls {{ '{{ .IMAGE_NAME | replace "/" "_"}}' }}_*_{{ '{{ .PLATFORM | replace "/" "_" | replace "," "_"}}' }}.tar 2>/dev/null | sort -r | head -1{{ '{{ end}}' }}'
250250 preconditions :
251251 - sh : which docker
252252 msg : " docker is required for publishing"
253253 cmds :
254254 - |
255- {{ "{{" }} if or (eq .LOCAL_PLATFORM .PLATFORM) (eq .PLATFORM "all"){{ "}}" }}
256- docker push {{ " {{.IMAGE_NAME}}:{{.VERSION}}" }}
257- docker push {{ " {{.IMAGE_NAME}}:latest" }}
258- {{ "{{" }} else{{ "}}" }}
259- echo "Publishing cross-platform image from {{ "{{" }} .INPUT_FILE{{ "}}" }}"
255+ {{ '{{ if or (eq .LOCAL_PLATFORM .PLATFORM) (eq .PLATFORM "all")}}' }}
256+ docker push {{ ' {{.IMAGE_NAME}}:{{.VERSION}}' }}
257+ docker push {{ ' {{.IMAGE_NAME}}:latest' }}
258+ {{ '{{ else}}' }}
259+ echo "Publishing cross-platform image from {{ '{{ .INPUT_FILE}}' }}"
260260 docker run --rm \
261261 -v "$(pwd):/src" \
262262 -w /src \
263263 quay.io/skopeo/stable:latest \
264- copy oci-archive:{{ "{{" }} .INPUT_FILE{{ "}}" }} docker://{{ " {{.IMAGE_NAME}}:{{.VERSION}}" }}
264+ copy oci-archive:{{ '{{ .INPUT_FILE}}' }} docker://{{ ' {{.IMAGE_NAME}}:{{.VERSION}}' }}
265265 docker run --rm \
266266 -v "$(pwd):/src" \
267267 -w /src \
268268 quay.io/skopeo/stable:latest \
269- copy oci-archive:{{ "{{" }} .INPUT_FILE{{ "}}" }} docker://{{ " {{.IMAGE_NAME}}:latest" }}
270- {{ "{{" }} end{{ "}}" }}
269+ copy oci-archive:{{ '{{ .INPUT_FILE}}' }} docker://{{ ' {{.IMAGE_NAME}}:latest' }}
270+ {{ '{{ end}}' }}
271271{%- endif %}
0 commit comments