Skip to content

Commit 2ea1605

Browse files
committed
Build Docker image and push to GHCR
Up to this point, the project has been set up as a Docker action referencing the Dockerfile. The downside to using the Dockerfile for the action is that the Docker image must be built every time the action is used. This commit will set up the project to build the Docker image and push it to GitHub Container Registry (GHCR). This change will speed up user workflows every time the action is used because the workflows will simply pull the Docker image from GHCR instead of building again. Changes: - Add required metadata to Dockerfile - Build container image with GitHub Actions - Push container image to GHCR Docker actions support pulling in pre-built Docker images. The downside is that there's no way to specify the correct Docker tag because the GitHub Actions `image` and `uses:` keys don't accept any context. For example, if a user's workflow has `uses: pypa/gh-action-pypi-publish@release/v1.8`, then the action should pull in a Docker image built from the `release/v1.8` branch, something like `ghcr.io/pypa/gh-action-pypi-publish:release-v1.8` (Docker tags can't have `/`). The workaround is to switch the top-level `action.yml` to a composite action that then calls the Docker action, substituting the correct image name and tag.
1 parent 3fbcf7c commit 2ea1605

File tree

5 files changed

+126
-17
lines changed

5 files changed

+126
-17
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
---
2+
name: 🏃
3+
inputs:
4+
user:
5+
required: false
6+
password:
7+
required: false
8+
repository-url:
9+
required: false
10+
packages-dir:
11+
required: false
12+
verify-metadata:
13+
required: false
14+
skip-existing:
15+
required: false
16+
verbose:
17+
required: false
18+
print-hash:
19+
required: false
20+
runs:
21+
using: docker
22+
image: {{image}}
23+
args:
24+
- ${{ inputs.user }}
25+
- ${{ inputs.password }}
26+
- ${{ inputs.repository-url }}
27+
- ${{ inputs.packages-dir }}
28+
- ${{ inputs.verify-metadata }}
29+
- ${{ inputs.skip-existing }}
30+
- ${{ inputs.verbose }}
31+
- ${{ inputs.print-hash }}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
---
2+
3+
name: 🏗️
4+
5+
on: # yamllint disable-line rule:truthy
6+
pull_request:
7+
push:
8+
branches: ["release/*", "unstable/*"]
9+
tags: ["*"]
10+
11+
jobs:
12+
build-and-push:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- uses: actions/checkout@v4
16+
- name: Build Docker image
17+
run: |
18+
IMAGE="ghcr.io/$GITHUB_REPOSITORY:${GITHUB_REF_NAME/'/'/'-'}"
19+
echo "IMAGE=$IMAGE" >>"$GITHUB_ENV"
20+
docker build . \
21+
--build-arg BUILDKIT_INLINE_CACHE=1 \
22+
--cache-from $IMAGE \
23+
--tag $IMAGE
24+
- name: Push Docker image to GHCR
25+
if: github.event_name != 'pull_request'
26+
run: |
27+
echo ${{ secrets.GITHUB_TOKEN }} |
28+
docker login ghcr.io -u $GITHUB_ACTOR --password-stdin
29+
docker push $IMAGE

.github/workflows/self-smoke-test-action.yml

+9-6
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
name: 🧪
44

55
on: # yamllint disable-line rule:truthy
6-
push:
76
pull_request:
7+
workflow_run:
8+
workflows: [🏗️]
9+
types: [completed]
810

911
env:
1012
devpi-password: abcd1234
@@ -28,6 +30,9 @@ env:
2830
2931
jobs:
3032
smoke-test:
33+
if: >-
34+
github.event_name == 'pull_request' ||
35+
github.event.workflow_run.conclusion == 'success'
3136
runs-on: ubuntu-latest
3237

3338
services:
@@ -42,13 +47,11 @@ jobs:
4247

4348
steps:
4449
- name: Check out the action locally
45-
uses: actions/checkout@v3
46-
with:
47-
path: test
50+
uses: actions/checkout@v4
4851
- name: Install the packaging-related tools
4952
run: python3 -m pip install build twine
5053
env:
51-
PIP_CONSTRAINT: test/requirements/runtime.txt
54+
PIP_CONSTRAINT: requirements/runtime.txt
5255
- name: Create the stub package importable directory
5356
run: mkdir -pv src/test_package
5457
- name: Populate the stub package `__init__.py`
@@ -83,7 +86,7 @@ jobs:
8386
env.devpi-username
8487
}}/public/
8588
- name: ✅ Smoke-test the locally checked out action
86-
uses: ./test
89+
uses: ./
8790
env:
8891
DEBUG: >-
8992
true

Dockerfile

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ FROM python:3.12-slim
33
LABEL "maintainer" "Sviatoslav Sydorenko <[email protected]>"
44
LABEL "repository" "https://github.com/pypa/gh-action-pypi-publish"
55
LABEL "homepage" "https://github.com/pypa/gh-action-pypi-publish"
6+
LABEL "org.opencontainers.image.source" "https://github.com/pypa/gh-action-pypi-publish"
67

78
ENV PYTHONDONTWRITEBYTECODE 1
89
ENV PYTHONUNBUFFERED 1

action.yml

+56-11
Original file line numberDiff line numberDiff line change
@@ -84,14 +84,59 @@ branding:
8484
color: yellow
8585
icon: upload-cloud
8686
runs:
87-
using: docker
88-
image: Dockerfile
89-
args:
90-
- ${{ inputs.user }}
91-
- ${{ inputs.password }}
92-
- ${{ inputs.repository-url }}
93-
- ${{ inputs.packages-dir }}
94-
- ${{ inputs.verify-metadata }}
95-
- ${{ inputs.skip-existing }}
96-
- ${{ inputs.verbose }}
97-
- ${{ inputs.print-hash }}
87+
using: composite
88+
steps:
89+
- name: Reset path if needed
90+
run: |
91+
# Reset path if needed
92+
# https://github.com/pypa/gh-action-pypi-publish/issues/112
93+
if [[ $PATH != *"/usr/bin"* ]]; then
94+
echo "\$PATH=$PATH. Resetting \$PATH for GitHub Actions."
95+
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
96+
echo "PATH=$PATH" >>"$GITHUB_ENV"
97+
echo "$PATH" >>"$GITHUB_PATH"
98+
echo "\$PATH reset. \$PATH=$PATH"
99+
fi
100+
shell: bash
101+
- name: Set repo and ref from which to run Docker container action
102+
id: set-repo-and-ref
103+
run: |
104+
# Set repo and ref from which to run Docker container action
105+
# to handle cases in which `github.action_` context is not set
106+
# https://github.com/actions/runner/issues/2473
107+
REF=${{ env.ACTION_REF || github.ref_name }}
108+
REPO=${{ env.ACTION_REPO || github.repository }}
109+
echo "ref=$REF" >>"$GITHUB_OUTPUT"
110+
echo "repo=$REPO" >>"$GITHUB_OUTPUT"
111+
shell: bash
112+
env:
113+
ACTION_REF: ${{ github.action_ref }}
114+
ACTION_REPO: ${{ github.action_repository }}
115+
- name: Set Docker image name and tag
116+
run: |
117+
# Set Docker image name and tag
118+
# if action run was triggered by a pull request to this repo,
119+
# build image from Dockerfile because it has not been pushed to GHCR,
120+
# else pull image from GHCR
121+
if [[ $GITHUB_EVENT_NAME == "pull_request" ]] &&
122+
[[ $GITHUB_REPOSITORY == "pypa/gh-action-pypi-publish" ]]; then
123+
IMAGE="../../../Dockerfile"
124+
else
125+
REF=${{ steps.set-repo-and-ref.outputs.ref }}
126+
REPO=${{ steps.set-repo-and-ref.outputs.repo }}
127+
IMAGE="docker://ghcr.io/$REPO:${REF/'/'/'-'}"
128+
fi
129+
FILE=".github/actions/run-docker-container/action.yml"
130+
sed -i -e "s|{{image}}|$IMAGE|g" "$FILE"
131+
shell: bash
132+
- name: Run Docker container
133+
uses: ./.github/actions/run-docker-container
134+
with:
135+
user: ${{ inputs.user }}
136+
password: ${{ inputs.password }}
137+
repository-url: ${{ inputs.repository-url || inputs.repository_url }}
138+
packages-dir: ${{ inputs.packages-dir || inputs.packages_dir }}
139+
verify-metadata: ${{ inputs.verify-metadata || inputs.verify_metadata }}
140+
skip-existing: ${{ inputs.skip-existing || inputs.skip_existing }}
141+
verbose: ${{ inputs.verbose }}
142+
print-hash: ${{ inputs.print-hash || inputs.print_hash }}

0 commit comments

Comments
 (0)