Compare commits

...

20 Commits

Author SHA1 Message Date
Sviatoslav Sydorenko (Святослав Сидоренко) 61da13deb5
Merge pull request #230 from br3ndonland/ghcr
Build Docker image and push to GHCR
2024-11-05 20:58:36 +01:00
Brendon Smith 36965cb24a
Run smoke tests before Docker builds
https://github.com/pypa/gh-action-pypi-publish/pull/230#discussion_r1787027821
2024-11-04 16:35:15 -05:00
Brendon Smith da554410b0
Move smoke test to reusable workflow 2024-11-04 16:35:14 -05:00
Brendon Smith 80b1d50e0d
Make `workflow_dispatch` Docker tag input required
https://github.com/pypa/gh-action-pypi-publish/pull/230#discussion_r1759496153
2024-11-04 16:35:14 -05:00
pre-commit-ci[bot] 1b9f21a741
[pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2024-11-04 16:35:14 -05:00
Brendon Smith cfb9d93a26
Add Docker tags for major and minor versions 2024-11-04 16:35:14 -05:00
Brendon Smith 153ccde9bc
Verify fail-fast in unsupported environments 2024-11-04 16:35:14 -05:00
Brendon Smith d03addb8e6
Drop args from create-docker-action.py
Co-authored-by: Sviatoslav Sydorenko (Святослав Сидоренко) <wk.cvs.github@sydorenko.org.ua>
2024-11-04 16:35:14 -05:00
Brendon Smith bacb62682c
Fail-fast in unsupported environments
https://github.com/pypa/gh-action-pypi-publish/pull/230#discussion_r1632406604

Co-authored-by: Sviatoslav Sydorenko (Святослав Сидоренко) <wk.cvs.github@sydorenko.org.ua>
2024-11-04 16:35:14 -05:00
Brendon Smith 7ea8313fc2
Check repo ID instead of repo owner ID 2024-11-04 16:35:14 -05:00
Brendon Smith f51682fb52
Check repo owner ID instead of repo name 2024-11-04 16:35:14 -05:00
Brendon Smith a360fcb184
Dump action as JSON 2024-11-04 16:35:14 -05:00
Brendon Smith a869dd36b2
Checkout `github.head_ref` and repo for PRs
https://github.com/actions/checkout/issues/27#issuecomment-535897113
https://github.com/actions/checkout/issues/1108
2024-11-04 16:35:14 -05:00
Brendon Smith 5ded5310e7
Add `workflow_dispatch` trigger for Docker builds 2024-11-04 16:35:13 -05:00
Brendon Smith cf5ce177da
Use YAML block strip syntax (`>-`) where possible 2024-11-04 16:35:13 -05:00
Brendon Smith f1f014b445
Reset pre-commit `files:` regex 2024-11-04 16:35:13 -05:00
Brendon Smith aed6c4b1b0
Generate Docker container action with Python 2024-11-04 16:35:13 -05:00
Brendon Smith 0d8d5059c8
Separate `docker login` and `docker push`
https://github.com/pypa/gh-action-pypi-publish/pull/230#discussion_r1578694138
2024-11-04 16:35:13 -05:00
Brendon Smith e453f8c630
Fix pre-commit errors 2024-11-04 16:35:13 -05:00
Brendon Smith 783267be69
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.
2024-11-04 16:35:13 -05:00
4 changed files with 224 additions and 15 deletions

View File

@ -0,0 +1,54 @@
---
name: 🏗️
on: # yamllint disable-line rule:truthy
pull_request:
push:
branches: ["release/*", "unstable/*"]
workflow_dispatch:
inputs:
tag:
description: Docker image tag
required: true
type: string
jobs:
smoke-test:
uses: ./.github/workflows/reusable-smoke-test.yml
build-and-push:
if: github.event_name != 'pull_request'
runs-on: ubuntu-latest
needs:
- smoke-test
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- name: Build Docker image
run: |
DOCKER_TAG="${DOCKER_TAG/'/'/'-'}"
DOCKER_TAG_MAJOR=$(echo "$DOCKER_TAG" | cut -d '.' -f 1)
DOCKER_TAG_MAJOR_MINOR=$(echo "$DOCKER_TAG" | cut -d '.' -f 1-2)
IMAGE="ghcr.io/$GITHUB_REPOSITORY:${DOCKER_TAG}"
IMAGE_MAJOR="ghcr.io/$GITHUB_REPOSITORY:${DOCKER_TAG_MAJOR}"
IMAGE_MAJOR_MINOR="ghcr.io/$GITHUB_REPOSITORY:${DOCKER_TAG_MAJOR_MINOR}"
echo "IMAGE=$IMAGE" >>"$GITHUB_ENV"
echo "IMAGE_MAJOR=$IMAGE_MAJOR" >>"$GITHUB_ENV"
echo "IMAGE_MAJOR_MINOR=$IMAGE_MAJOR_MINOR" >>"$GITHUB_ENV"
docker build . \
--build-arg BUILDKIT_INLINE_CACHE=1 \
--cache-from $IMAGE \
--tag $IMAGE
docker tag $IMAGE $IMAGE_MAJOR
docker tag $IMAGE $IMAGE_MAJOR_MINOR
env:
DOCKER_TAG: ${{ inputs.tag || github.ref_name }}
- name: Log in to GHCR
run: >-
echo ${{ secrets.GITHUB_TOKEN }} |
docker login ghcr.io -u $GITHUB_ACTOR --password-stdin
- name: Push Docker image to GHCR
run: |
docker push $IMAGE
docker push $IMAGE_MAJOR
docker push $IMAGE_MAJOR_MINOR

View File

@ -1,10 +1,9 @@
---
name: 🧪
name: ♻️ 🧪
on: # yamllint disable-line rule:truthy
push:
pull_request:
workflow_call:
env:
devpi-password: abcd1234
@ -27,7 +26,33 @@ env:
PYTEST_THEME_MODE
jobs:
fail-fast:
strategy:
matrix:
os: [macos-latest, windows-latest]
runs-on: ${{ matrix.os }}
timeout-minutes: 2
steps:
- name: Check out the action locally
uses: actions/checkout@v4
with:
path: test
- name: Fail-fast in unsupported environments
continue-on-error: true
id: fail-fast
uses: ./test
- name: Error if action did not fail-fast in unsupported environments
if: steps.fail-fast.outcome == 'success'
run: |
>&2 echo This action should fail-fast in unsupported environments.
exit 1
smoke-test:
runs-on: ubuntu-latest
services:

View File

@ -91,15 +91,70 @@ 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 }}
- ${{ inputs.attestations }}
using: composite
steps:
- name: Fail-fast in unsupported environments
if: runner.os != 'Linux'
run: |
>&2 echo This action is only able to run under GNU/Linux environments
exit 1
shell: bash -eEuo pipefail {0}
- 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 || env.PR_REF || github.ref_name }}
REPO=${{ env.ACTION_REPO || env.PR_REPO || github.repository }}
REPO_ID=${{ env.PR_REPO_ID || github.repository_id }}
echo "ref=$REF" >>"$GITHUB_OUTPUT"
echo "repo=$REPO" >>"$GITHUB_OUTPUT"
echo "repo-id=$REPO_ID" >>"$GITHUB_OUTPUT"
shell: bash
env:
ACTION_REF: ${{ github.action_ref }}
ACTION_REPO: ${{ github.action_repository }}
PR_REF: ${{ github.event.pull_request.head.ref }}
PR_REPO: ${{ github.event.pull_request.head.repo.full_name }}
PR_REPO_ID: ${{ github.event.pull_request.base.repo.id }}
- name: Check out action repo
uses: actions/checkout@v4
with:
path: action-repo
ref: ${{ steps.set-repo-and-ref.outputs.ref }}
repository: ${{ steps.set-repo-and-ref.outputs.repo }}
- name: Create Docker container action
run: |
# Create Docker container action
python create-docker-action.py
env:
REF: ${{ steps.set-repo-and-ref.outputs.ref }}
REPO: ${{ steps.set-repo-and-ref.outputs.repo }}
REPO_ID: ${{ steps.set-repo-and-ref.outputs.repo-id }}
shell: bash
working-directory: action-repo
- name: Run Docker container
uses: ./action-repo/.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 }}
attestations: ${{ inputs.attestations }}

75
create-docker-action.py Normal file
View File

@ -0,0 +1,75 @@
import json
import os
import pathlib
DESCRIPTION = 'description'
REQUIRED = 'required'
REF = os.environ['REF']
REPO = os.environ['REPO']
REPO_ID = os.environ['REPO_ID']
REPO_ID_GH_ACTION = '178055147'
def set_image(ref: str, repo: str, repo_id: str) -> str:
if repo_id == REPO_ID_GH_ACTION:
return '../../../Dockerfile'
docker_ref = ref.replace('/', '-')
return f'docker://ghcr.io/{repo}:{docker_ref}'
image = set_image(REF, REPO, REPO_ID)
action = {
'name': '🏃',
DESCRIPTION: (
'Run Docker container to upload Python distribution packages to PyPI'
),
'inputs': {
'user': {DESCRIPTION: 'PyPI user', REQUIRED: False},
'password': {
DESCRIPTION: 'Password for your PyPI user or an access token',
REQUIRED: False,
},
'repository-url': {
DESCRIPTION: 'The repository URL to use',
REQUIRED: False,
},
'packages-dir': {
DESCRIPTION: 'The target directory for distribution',
REQUIRED: False,
},
'verify-metadata': {
DESCRIPTION: 'Check metadata before uploading',
REQUIRED: False,
},
'skip-existing': {
DESCRIPTION: (
'Do not fail if a Python package distribution'
' exists in the target package index'
),
REQUIRED: False,
},
'verbose': {DESCRIPTION: 'Show verbose output.', REQUIRED: False},
'print-hash': {
DESCRIPTION: 'Show hash values of files to be uploaded',
REQUIRED: False,
},
'attestations': {
DESCRIPTION: (
'[EXPERIMENTAL]'
' Enable experimental support for PEP 740 attestations.'
' Only works with PyPI and TestPyPI via Trusted Publishing.'
),
REQUIRED: False,
},
},
'runs': {
'using': 'docker',
'image': image,
},
}
action_path = pathlib.Path('.github/actions/run-docker-container/action.yml')
action_path.parent.mkdir(parents=True, exist_ok=True)
action_path.write_text(json.dumps(action, ensure_ascii=False), encoding='utf-8')