Skip to content

Commit 8fa0c77

Browse files
authored
feat(release): add docker publishing to the release process (#25)
1 parent 60271c5 commit 8fa0c77

4 files changed

Lines changed: 74 additions & 65 deletions

File tree

hooks/post_gen_project.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,24 @@ def write_context(*, context: dict) -> None:
121121
yaml.dump(context, file)
122122

123123

124+
def notify_dockerhub_secrets() -> None:
125+
"""Notify user about required Docker Hub secrets for releases."""
126+
print("\n" + "=" * 70)
127+
print("IMPORTANT: Docker Hub Publishing Enabled")
128+
print("=" * 70)
129+
print("\nYou have enabled Docker Hub publishing for releases.")
130+
print("Please ensure the following GitHub secrets are configured:")
131+
print("\n • DOCKERHUB_USERNAME - Your Docker Hub username")
132+
print(" • DOCKERHUB_PAT - Your Docker Hub Personal Access Token")
133+
print("\nWithout these secrets, your releases will fail during the")
134+
print("Docker image publishing step.")
135+
print("\nTo add these secrets:")
136+
print("1. Go to your GitHub repository settings")
137+
print("2. Navigate to Settings → Secrets and variables → Actions")
138+
print("3. Add the required secrets")
139+
print("=" * 70 + "\n")
140+
141+
124142
def run_post_gen_hook():
125143
"""Run post generation hook"""
126144
try:
@@ -199,6 +217,10 @@ def run_post_gen_hook():
199217
# Run the initial setup step automatically so pre-commit hooks, etc. are pre-installed. However, if it fails, don't fail the overall repo generation
200218
# (i.e. check=False)
201219
subprocess.run(["task", "init"], check=False, capture_output=True)
220+
221+
# Notify about Docker Hub secrets if Docker Hub publishing is enabled
222+
if cookiecutter_context.get("dockerhub") == "yes":
223+
notify_dockerhub_secrets()
202224
except subprocess.CalledProcessError as error:
203225
stdout = error.stdout.decode("utf-8") if error.stdout else "No stdout"
204226
stderr = error.stderr.decode("utf-8") if error.stderr else "No stderr"

{{cookiecutter.project_name|replace(" ", "")}}/.github/workflows/commit.yml

Lines changed: 0 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -102,42 +102,3 @@ jobs:
102102
name: vulns-${{ "{{ env.SANITIZED_PLATFORM }}" }}
103103
path: vulns.*.json
104104
if-no-files-found: error
105-
{%- if cookiecutter.dockerhub == 'yes' %}
106-
publish:
107-
name: Publish the container(s)
108-
needs: bump-version
109-
runs-on: ubuntu-24.04
110-
strategy:
111-
fail-fast: false
112-
matrix:
113-
platform:
114-
- linux/amd64
115-
- linux/arm64
116-
steps:
117-
- name: Checkout the repository
118-
uses: actions/checkout@v4
119-
with:
120-
fetch-depth: 0
121-
ref: "${{ "{{ needs.bump-version.outputs.tag }}" }}"
122-
persist-credentials: 'false'
123-
- name: Bootstrap repository
124-
uses: ./.github/actions/bootstrap
125-
with:
126-
token: ${{ "{{ secrets.GITHUB_TOKEN }}" }}
127-
python-version: ${{ "{{ env.python_version }}" }}
128-
- name: Set up QEMU for cross-platform emulation
129-
uses: docker/setup-qemu-action@v3
130-
- name: Build the container
131-
run: task -v build
132-
env:
133-
PLATFORM: ${{ "{{ matrix.platform }}" }}
134-
- name: Login to Docker Hub
135-
uses: docker/login-action@v3
136-
with:
137-
username: ${{ "{{ secrets.DOCKERHUB_USERNAME }}" }}
138-
password: ${{ "{{ secrets.DOCKERHUB_PAT }}" }}
139-
- name: Publish the container
140-
run: task -v publish
141-
env:
142-
PLATFORM: ${{ "{{ matrix.platform }}" }}
143-
{%- endif %}

{{cookiecutter.project_name|replace(" ", "")}}/.github/workflows/release.yml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,41 @@ jobs:
4848
TAG=$(git describe --tags --abbrev=0)
4949
echo "tag=${TAG}" | tee -a "${GITHUB_OUTPUT}"
5050
echo "Created release tag: ${TAG}"
51+
{%- if cookiecutter.dockerhub == 'yes' %}
52+
53+
publish-docker:
54+
name: Publish Docker Image
55+
needs: release
56+
runs-on: ubuntu-24.04
57+
steps:
58+
- name: Checkout the repository
59+
uses: actions/checkout@v4
60+
with:
61+
fetch-depth: 0
62+
ref: ${{ "{{ needs.release.outputs.tag }}" }}
63+
persist-credentials: 'false'
64+
65+
- name: Bootstrap repository
66+
uses: ./.github/actions/bootstrap
67+
with:
68+
token: ${{ "{{ secrets.GITHUB_TOKEN }}" }}
69+
python-version: ${{ "{{ env.python_version }}" }}
70+
71+
- name: Set up QEMU for cross-platform emulation
72+
uses: docker/setup-qemu-action@v3
73+
74+
- name: Login to Docker Hub
75+
uses: docker/login-action@v3
76+
with:
77+
username: ${{ "{{ secrets.DOCKERHUB_USERNAME }}" }}
78+
password: ${{ "{{ secrets.DOCKERHUB_PAT }}" }}
79+
80+
- name: Build and publish multiplatform Docker image
81+
run: |
82+
# Extract version from tag (remove 'v' prefix if present)
83+
VERSION="${{ "{{ needs.release.outputs.tag }}" }}"
84+
VERSION="${VERSION#v}"
85+
86+
# Build and push multiplatform image
87+
task -v publish VERSION="${VERSION}" PLATFORM=all
88+
{%- endif %}

{{cookiecutter.project_name|replace(" ", "")}}/Taskfile.yml

Lines changed: 14 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ tasks:
8686
build:
8787
desc: Build the project; docker images, compiled binaries, etc.
8888
vars:
89+
PUBLISH: '{{ '{{.PUBLISH | default "false"}}' }}'
8990
TIMESTAMP:
9091
sh: '{{ '{{.RUN_SCRIPT}}' }} {{ '{{.SCRIPTS_DIR}}' }}/get_rfc3339_timestamp.py'
9192
EPOCH:
@@ -98,12 +99,12 @@ tasks:
9899
OUTPUT_FILE: '{{ '{{.IMAGE_NAME | replace "/" "_"}}' }}_latest_{{ '{{.PLATFORM_SUFFIX}}' }}.tar'
99100
DESCRIPTION: '{{ cookiecutter.project_short_description }}'
100101
cmds:
101-
# First build: load if same platform, output to file if cross-platform
102+
# First build: load if same platform, output to file if cross-platform, or push if PUBLISH is true
102103
- |
103104
docker buildx build \
104105
--platform {{ '{{.BUILD_PLATFORM}}' }} \
105106
--pull \
106-
{{ '{{if eq .PLATFORM .LOCAL_PLATFORM}}' }}--load{{ '{{else}}' }}-o type=oci,dest="{{ '{{.OUTPUT_FILE}}' }}"{{ '{{end}}' }} \
107+
{{ '{{if eq .PUBLISH "true"}}' }}--push{{ "{{else if eq .PLATFORM .LOCAL_PLATFORM}}" }}--load{{ "{{else}}" }}-o type=oci,dest="{{ '{{.OUTPUT_FILE}}' }}"{{ "{{end}}" }} \
107108
{{ '{{if eq .GITHUB_ACTIONS "true"}}' }}--cache-from type=gha --cache-to type=gha,mode=max{{ '{{end}}' }} \
108109
--build-arg NAME="{{ '{{.PROJECT_SLUG}}' }}" \
109110
--build-arg DESCRIPTION="{{ '{{.DESCRIPTION}}' }}" \
@@ -243,29 +244,16 @@ tasks:
243244

244245
publish:
245246
desc: Publish the project artifacts; docker images, compiled binaries, etc.
246-
vars:
247-
INPUT_FILE:
248-
# 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}}' }}'
250-
preconditions:
251-
- sh: which docker
252-
msg: "docker is required for publishing"
247+
requires:
248+
vars:
249+
- VERSION
253250
cmds:
254-
- |
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}}' }}"
260-
docker run --rm \
261-
-v "$(pwd):/src" \
262-
-w /src \
263-
quay.io/skopeo/stable:latest \
264-
copy oci-archive:{{ '{{.INPUT_FILE}}' }} docker://{{ '{{.IMAGE_NAME}}:{{.VERSION}}' }}
265-
docker run --rm \
266-
-v "$(pwd):/src" \
267-
-w /src \
268-
quay.io/skopeo/stable:latest \
269-
copy oci-archive:{{ '{{.INPUT_FILE}}' }} docker://{{ '{{.IMAGE_NAME}}:latest' }}
270-
{{ '{{end}}' }}
251+
- task: build
252+
vars:
253+
PUBLISH: 'true'
254+
VERSION: '{{ '{{.VERSION}}' }}'
255+
PLATFORM: '{{ '{{.PLATFORM | default "all"}}' }}'
256+
DOCKER_BUILDX_CUSTOM_ARGS: '{{ '{{.DOCKER_BUILDX_CUSTOM_ARGS | default ""}}' }}'
257+
DOCKER_BUILDX_CUSTOM_TAGS: '{{ '{{.DOCKER_BUILDX_CUSTOM_TAGS | default ""}}' }}'
258+
DOCKER_BUILDX_CUSTOM_CONTEXT: '{{ '{{.DOCKER_BUILDX_CUSTOM_CONTEXT}}' }}'
271259
{%- endif %}

0 commit comments

Comments
 (0)