Skip to content

Commit

Permalink
Build Docker image and push to GHCR
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
br3ndonland committed Apr 19, 2024
1 parent 3fbcf7c commit 2ea1605
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 17 deletions.
31 changes: 31 additions & 0 deletions .github/actions/run-docker-container/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
name: 🏃
inputs:
user:
required: false
password:
required: false
repository-url:
required: false
packages-dir:
required: false
verify-metadata:
required: false
skip-existing:
required: false
verbose:
required: false
print-hash:
required: false
runs:
using: docker
image: {{image}}
args:
- ${{ inputs.user }}
- ${{ inputs.password }}
- ${{ inputs.repository-url }}
- ${{ inputs.packages-dir }}
- ${{ inputs.verify-metadata }}
- ${{ inputs.skip-existing }}
- ${{ inputs.verbose }}
- ${{ inputs.print-hash }}
29 changes: 29 additions & 0 deletions .github/workflows/build-and-push-docker-image.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---

name: 🏗️

on: # yamllint disable-line rule:truthy
pull_request:
push:
branches: ["release/*", "unstable/*"]
tags: ["*"]

jobs:
build-and-push:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build Docker image
run: |
IMAGE="ghcr.io/$GITHUB_REPOSITORY:${GITHUB_REF_NAME/'/'/'-'}"
echo "IMAGE=$IMAGE" >>"$GITHUB_ENV"
docker build . \
--build-arg BUILDKIT_INLINE_CACHE=1 \
--cache-from $IMAGE \
--tag $IMAGE
- name: Push Docker image to GHCR
if: github.event_name != 'pull_request'
run: |
echo ${{ secrets.GITHUB_TOKEN }} |
docker login ghcr.io -u $GITHUB_ACTOR --password-stdin
docker push $IMAGE
15 changes: 9 additions & 6 deletions .github/workflows/self-smoke-test-action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
name: 🧪

on: # yamllint disable-line rule:truthy
push:
pull_request:
workflow_run:
workflows: [🏗️]
types: [completed]

env:
devpi-password: abcd1234
Expand All @@ -28,6 +30,9 @@ env:
jobs:
smoke-test:
if: >-
github.event_name == 'pull_request' ||
github.event.workflow_run.conclusion == 'success'
runs-on: ubuntu-latest

services:
Expand All @@ -42,13 +47,11 @@ jobs:

steps:
- name: Check out the action locally
uses: actions/checkout@v3
with:
path: test
uses: actions/checkout@v4
- name: Install the packaging-related tools
run: python3 -m pip install build twine
env:
PIP_CONSTRAINT: test/requirements/runtime.txt
PIP_CONSTRAINT: requirements/runtime.txt
- name: Create the stub package importable directory
run: mkdir -pv src/test_package
- name: Populate the stub package `__init__.py`
Expand Down Expand Up @@ -83,7 +86,7 @@ jobs:
env.devpi-username
}}/public/
- name: ✅ Smoke-test the locally checked out action
uses: ./test
uses: ./
env:
DEBUG: >-
true
Expand Down
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ FROM python:3.12-slim
LABEL "maintainer" "Sviatoslav Sydorenko <wk+pypa@sydorenko.org.ua>"
LABEL "repository" "https://github.com/pypa/gh-action-pypi-publish"
LABEL "homepage" "https://github.com/pypa/gh-action-pypi-publish"
LABEL "org.opencontainers.image.source" "https://github.com/pypa/gh-action-pypi-publish"

ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
Expand Down
67 changes: 56 additions & 11 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,14 +84,59 @@ branding:
color: yellow
icon: upload-cloud
runs:
using: docker
image: Dockerfile
args:
- ${{ inputs.user }}
- ${{ inputs.password }}
- ${{ inputs.repository-url }}
- ${{ inputs.packages-dir }}
- ${{ inputs.verify-metadata }}
- ${{ inputs.skip-existing }}
- ${{ inputs.verbose }}
- ${{ inputs.print-hash }}
using: composite
steps:
- name: Reset path if needed
run: |
# Reset path if needed
# https://github.com/pypa/gh-action-pypi-publish/issues/112
if [[ $PATH != *"/usr/bin"* ]]; then
echo "\$PATH=$PATH. Resetting \$PATH for GitHub Actions."
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
echo "PATH=$PATH" >>"$GITHUB_ENV"
echo "$PATH" >>"$GITHUB_PATH"
echo "\$PATH reset. \$PATH=$PATH"
fi
shell: bash
- name: Set repo and ref from which to run Docker container action
id: set-repo-and-ref
run: |
# Set repo and ref from which to run Docker container action
# to handle cases in which `github.action_` context is not set
# https://github.com/actions/runner/issues/2473
REF=${{ env.ACTION_REF || github.ref_name }}
REPO=${{ env.ACTION_REPO || github.repository }}
echo "ref=$REF" >>"$GITHUB_OUTPUT"
echo "repo=$REPO" >>"$GITHUB_OUTPUT"
shell: bash
env:
ACTION_REF: ${{ github.action_ref }}
ACTION_REPO: ${{ github.action_repository }}
- name: Set Docker image name and tag
run: |
# Set Docker image name and tag
# if action run was triggered by a pull request to this repo,
# build image from Dockerfile because it has not been pushed to GHCR,
# else pull image from GHCR
if [[ $GITHUB_EVENT_NAME == "pull_request" ]] &&
[[ $GITHUB_REPOSITORY == "pypa/gh-action-pypi-publish" ]]; then
IMAGE="../../../Dockerfile"
else
REF=${{ steps.set-repo-and-ref.outputs.ref }}
REPO=${{ steps.set-repo-and-ref.outputs.repo }}
IMAGE="docker://ghcr.io/$REPO:${REF/'/'/'-'}"
fi
FILE=".github/actions/run-docker-container/action.yml"
sed -i -e "s|{{image}}|$IMAGE|g" "$FILE"
shell: bash
- name: Run Docker container
uses: ./.github/actions/run-docker-container
with:
user: ${{ inputs.user }}
password: ${{ inputs.password }}
repository-url: ${{ inputs.repository-url || inputs.repository_url }}
packages-dir: ${{ inputs.packages-dir || inputs.packages_dir }}
verify-metadata: ${{ inputs.verify-metadata || inputs.verify_metadata }}
skip-existing: ${{ inputs.skip-existing || inputs.skip_existing }}
verbose: ${{ inputs.verbose }}
print-hash: ${{ inputs.print-hash || inputs.print_hash }}

0 comments on commit 2ea1605

Please sign in to comment.