├── .dockerignore ├── versions.json ├── .github ├── dependabot.yml └── workflows │ ├── docker-image.yml │ ├── docker-manual-publish.yml │ └── docker-publish.yml ├── LICENSE ├── Dockerfile ├── README.md ├── version-check └── versions.py └── CHANGELOG.md /.dockerignore: -------------------------------------------------------------------------------- 1 | * 2 | !Dockerfile 3 | -------------------------------------------------------------------------------- /versions.json: -------------------------------------------------------------------------------- 1 | { 2 | "curl": "8.14.1", 3 | "gh": "2.83.2", 4 | "git": "2.47.3", 5 | "gpg": "2.4.7", 6 | "python": "3.14.2" 7 | } -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "docker" 9 | directory: "/" 10 | target-branch: "master" 11 | schedule: 12 | interval: "daily" 13 | - package-ecosystem: "github-actions" 14 | directory: "/" 15 | target-branch: "master" 16 | schedule: 17 | interval: "daily" 18 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Vincent A. Cicirello 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /.github/workflows/docker-image.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | schedule: 9 | - cron: '42 8 * * *' 10 | workflow_dispatch: 11 | 12 | jobs: 13 | 14 | build: 15 | 16 | runs-on: ubuntu-latest 17 | 18 | steps: 19 | - uses: actions/checkout@v6 20 | 21 | - name: Build the Docker image 22 | run: docker build -t pyactioncheck . 23 | 24 | - name: Use image to run Python program and check app versions to verify installation 25 | run: | 26 | pwd 27 | docker run --rm --name versioncheck -v /home/runner/work/pyaction/pyaction:/pyaction -w /pyaction pyactioncheck python version-check/versions.py 28 | 29 | - name: Create Pull Request 30 | if: ${{ github.event_name != 'pull_request' }} 31 | uses: peter-evans/create-pull-request@v8.0.0 32 | with: 33 | title: "Automated update" 34 | commit-message: "Updated versions.json and changelog.md" 35 | author: Vincent A. Cicirello 36 | committer: Vincent A. Cicirello 37 | delete-branch: true 38 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2020-2025 Vincent A. Cicirello 2 | # https://www.cicirello.org 3 | # Source repository: https://github.com/cicirello/pyaction 4 | # Source licensed under the MIT License: https://github.com/cicirello/pyaction/blob/master/LICENSE 5 | 6 | # Base image is a Python 3 Slim image 7 | FROM python:3.14.2-slim 8 | 9 | LABEL maintainer="development@cicirello.org" \ 10 | org.opencontainers.image.description="A Docker image with Python, git, and the GitHub CLI" \ 11 | org.opencontainers.image.authors="Vincent A Cicirello, development@cicirello.org, https://www.cicirello.org/" \ 12 | org.opencontainers.image.source="https://github.com/cicirello/pyaction" \ 13 | org.opencontainers.image.title="pyaction" 14 | 15 | # Install git and the GitHub CLI (gh), and their dependencies. 16 | # Note that curl and gpg are installed here because they are 17 | # required for the installation of gh. 18 | RUN true \ 19 | && apt-get update && apt-get install -y \ 20 | curl \ 21 | gpg \ 22 | git \ 23 | && curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg \ 24 | && echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | tee /etc/apt/sources.list.d/github-cli.list > /dev/null \ 25 | && apt-get update && apt-get install -y gh \ 26 | && rm -rf /var/lib/apt/lists/* \ 27 | && true 28 | 29 | ## BELOW VERSION WILL DOWNLOAD GH FROM RELEASES 30 | ## && t="/tmp/gh-$$.deb" && curl -sSLo "$t" "https://github.com$(curl -sSL "https://github.com/cli/cli/releases/latest" | grep -Po "(?<=href=\")/cli/cli/releases/download/[^\"]*$(dpkg --print-architecture)[.]deb(?=\")")" && apt-get install -y "$t" && rm "$t" \ 31 | ## END RELEASES VERSION 32 | -------------------------------------------------------------------------------- /.github/workflows/docker-manual-publish.yml: -------------------------------------------------------------------------------- 1 | name: Docker Manual Publish 2 | 3 | on: 4 | workflow_dispatch: 5 | 6 | jobs: 7 | build-push: 8 | runs-on: ubuntu-latest 9 | 10 | steps: 11 | - name: Checkout 12 | uses: actions/checkout@v6 13 | with: 14 | fetch-depth: 0 15 | 16 | - name: Prepare 17 | id: prep 18 | run: | 19 | DOCKERHUB_IMAGE=cicirello/pyaction 20 | GHCR_IMAGE=ghcr.io/${{ github.repository_owner }}/pyaction 21 | LATESTTAG=$(git describe --abbrev=0 --tags) 22 | VERSION=${LATESTTAG#v} 23 | MINOR=${VERSION%.*} 24 | MAJOR=${VERSION%%.*} 25 | TAGS="${DOCKERHUB_IMAGE}:${MAJOR},${DOCKERHUB_IMAGE}:${MINOR}" 26 | TAGS="${TAGS},${DOCKERHUB_IMAGE}:${VERSION},${DOCKERHUB_IMAGE}:latest" 27 | TAGS="${TAGS},${GHCR_IMAGE}:${MAJOR},${GHCR_IMAGE}:${MINOR}" 28 | TAGS="${TAGS},${GHCR_IMAGE}:${VERSION},${GHCR_IMAGE}:latest" 29 | echo "tags=${TAGS}" >> $GITHUB_OUTPUT 30 | echo "version=${VERSION}" >> $GITHUB_OUTPUT 31 | echo "dockerhub_image=${DOCKERHUB_IMAGE}" >> $GITHUB_OUTPUT 32 | echo "ghcr_image=${GHCR_IMAGE}" >> $GITHUB_OUTPUT 33 | 34 | - name: Set up QEMU 35 | uses: docker/setup-qemu-action@v3 36 | with: 37 | platforms: all 38 | 39 | - name: Set up Docker Buildx 40 | id: buildx 41 | uses: docker/setup-buildx-action@v3 42 | 43 | - name: Login to DockerHub 44 | uses: docker/login-action@v3 45 | with: 46 | username: ${{ secrets.DOCKER_USERNAME }} 47 | password: ${{ secrets.DOCKER_PASSWORD }} 48 | 49 | - name: Login to Github Container Registry 50 | uses: docker/login-action@v3 51 | with: 52 | registry: ghcr.io 53 | username: ${{ github.repository_owner }} 54 | password: ${{ secrets.GITHUB_TOKEN }} 55 | 56 | - name: Build and push 57 | uses: docker/build-push-action@v6 58 | with: 59 | builder: ${{ steps.buildx.outputs.name }} 60 | context: . 61 | file: ./Dockerfile 62 | platforms: linux/amd64,linux/arm64,linux/386,linux/arm/v7,linux/arm/v6 63 | push: true 64 | tags: ${{ steps.prep.outputs.tags }} 65 | labels: org.opencontainers.image.version=${{ steps.prep.outputs.version }} 66 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # pyaction 2 | 3 | [![pyaction - A Docker container with Python, git, and the GitHub CLI](https://actions.cicirello.org/images/pyaction640.png)](#pyaction) 4 | 5 | Website for our GitHub Actions and tools for developing them: https://actions.cicirello.org/ 6 | 7 | ## Summary 8 | 9 | | __Docker Hub__ | [![Docker Image Version (latest by date)](https://img.shields.io/docker/v/cicirello/pyaction?label=Docker%20Hub&logo=docker)](https://hub.docker.com/r/cicirello/pyaction) [![Docker Pulls](https://img.shields.io/docker/pulls/cicirello/pyaction?logo=docker)](https://hub.docker.com/r/cicirello/pyaction) | 10 | | :--- | :--- | 11 | | __GitHub__ | [![GitHub Container Registry (latest by date)](https://img.shields.io/docker/v/cicirello/pyaction?label=ghcr.io&logo=GitHub)](https://github.com/cicirello/pyaction/pkgs/container/pyaction) | 12 | | __Image Stats__ | [![Docker Image Size (latest by date)](https://img.shields.io/docker/image-size/cicirello/pyaction?logo=docker)](https://hub.docker.com/r/cicirello/pyaction) | 13 | | __Build Status__ | [![build](https://github.com/cicirello/pyaction/workflows/build/badge.svg)](https://github.com/cicirello/pyaction/actions/workflows/docker-image.yml) | 14 | | __License__ | [![License](https://img.shields.io/github/license/cicirello/pyaction)](LICENSE) | 15 | | __Support__ | [![GitHub Sponsors](https://img.shields.io/badge/sponsor-30363D?logo=GitHub-Sponsors&logoColor=#EA4AAA)](https://github.com/sponsors/cicirello) [![Liberapay](https://img.shields.io/badge/Liberapay-F6C915?logo=liberapay&logoColor=black)](https://liberapay.com/cicirello) [![Ko-Fi](https://img.shields.io/badge/Ko--fi-F16061?logo=ko-fi&logoColor=white)](https://ko-fi.com/cicirello) | 16 | 17 | This Docker image is designed to support implementing Github Actions 18 | with Python. It starts with the [official python docker image](https://hub.docker.com/_/python) 19 | as the base, which is a Debian OS. It specifically uses python:3-slim to keep the image size 20 | down for faster loading of Github Actions that use pyaction. On top of the 21 | base, we've installed [curl](https://curl.se/), 22 | [gpg](https://gnupg.org/), [git](https://git-scm.com/), and the 23 | [GitHub CLI](https://cli.github.com/). We added curl and gpg because they 24 | are needed to install the GitHub CLI, and they may come in handy anyway 25 | (especially curl) when implementing a GitHub Action. 26 | 27 | __Blog Posts:__ See a [list of blog posts about pyaction](#blog-posts) later in this README. 28 | 29 | ## Multiplatform Image 30 | 31 | pyaction supports the following platforms: 32 | * linux/386 33 | * linux/amd64 34 | * linux/arm64 35 | * linux/arm/v7 36 | * linux/arm/v6 37 | 38 | ## Source Repository and Builds 39 | 40 | The [source repository](https://github.com/cicirello/pyaction) is 41 | maintained on GitHub. The images are built on Github and pushed 42 | to [Docker Hub](https://hub.docker.com/r/cicirello/pyaction), as 43 | well as the 44 | [Github Container Registry](https://github.com/cicirello?ecosystem=container&tab=packages) 45 | using Github Actions. 46 | 47 | Our daily automated CI/CD processes monitor for updates to the Python slim Docker image, the GitHub 48 | CLI, etc. Upon detecting such updates, we release an update of pyaction sometimes as 49 | early as same day, but possibly a few days later. 50 | 51 | See [versions.json](https://github.com/cicirello/pyaction/blob/master/versions.json) for details of 52 | versions of Python, GitHub CLI, git, etc included in the latest build. 53 | 54 | 55 | ## Docker Tags and Versioning Scheme 56 | 57 | For the current version of Python (e.g., 3.13.5) and current version 58 | of GitHub CLI (e.g., 2.75.0), all of the following tags are available and equivalent: 59 | `latest`, `3.13.5`, `3.13`, `3.13.5-gh-2.75.0`, `3.13.5-gh-2.75`, `3.13.5-gh-2`, 60 | `3.13-gh-2.75.0`, `3.13-gh-2.75`, `3.13-gh-2`. 61 | 62 | For prior versions of Python (e.g., 3.12) and current version of 63 | GitHub CLI (2.75.0), all of the following tags are available and equivalent: 64 | `3.12`, `3.12-gh-2.75.0`, `3.12-gh-2.75`, `3.12-gh-2`. Note that we only build 65 | new images for Python versions that are still supported, and not for any that 66 | have reached end-of-life. See the official [Status of Python Versions](https://devguide.python.org/versions/). 67 | 68 | This tag scheme began with version 2.75.0 of the GitHub CLI. We don't support pyaction 69 | images with earlier versions of the GitHub CLI. 70 | 71 | This tag scheme began with Python 3.13.5. Python patch level tags are not available for 72 | pyaction prior to Python 3.13.5. 73 | 74 | 75 | ## Installation and Usage 76 | 77 | The pre-built image is hosted on both Docker Hub and the Github 78 | Container Registry. You can use it in the following ways. 79 | 80 | ### Docker Pull Command 81 | 82 | Pull the latest image from Docker Hub with the following (replace `latest` with 83 | a specific version number if you prefer): 84 | 85 | ```Shell 86 | docker pull cicirello/pyaction:latest 87 | ``` 88 | 89 | Pull from the Github Container Registry with: 90 | 91 | ```Shell 92 | docker pull ghcr.io/cicirello/pyaction:latest 93 | ``` 94 | 95 | 96 | ### Use as a base image in a Dockerfile 97 | 98 | Use as a base image in a Dockerfile (replace `latest` with 99 | a specific version number if you prefer): 100 | 101 | ```Dockerfile 102 | FROM cicirello/pyaction:latest 103 | 104 | # The rest of your Dockerfile would go here. 105 | ``` 106 | 107 | Or you can use as a base image (via the Github Container Registry) with: 108 | 109 | ```Dockerfile 110 | FROM ghcr.io/cicirello/pyaction:latest 111 | 112 | # The rest of your Dockerfile would go here. 113 | ``` 114 | 115 | ## Blog Posts 116 | 117 | Here are a few blog posts about the pyaction container listed in reverse chronological order: 118 | * [pyaction: Python and the GitHub CLI in a Docker Container](https://dev.to/cicirello/pyaction-python-and-the-github-cli-in-a-docker-container-3682), posted on August 14, 2025. 119 | * [pyaction pulled 4 million times and counting from the GitHub Container Registry](https://dev.to/cicirello/pyaction-pulled-4-million-times-and-counting-from-the-github-container-registry-47i3), posted on May 31, 2024. 120 | * [Celebrating over 2 million pulls of pyaction from the GitHub Container Registry](https://dev.to/cicirello/celebrating-over-2-million-pulls-of-pyaction-from-the-github-container-registry-20hb), posted on September 2, 2023. 121 | * [pyaction: Over 1 million pulls from the GitHub Container Registry](https://dev.to/cicirello/pyaction-over-1-million-pulls-from-the-github-container-registry-29ag), posted on February 16, 2023. 122 | * [pyaction: A Docker container with Python, git, and the GitHub CLI](https://dev.to/cicirello/pyaction-a-docker-container-with-python-git-and-the-github-cli-930), posted on December 28, 2022. 123 | 124 | ## License 125 | 126 | ### Source Code License 127 | The source code, including the Dockerfile and anything 128 | else within the [Github repository for pyaction](https://github.com/cicirello/pyaction), 129 | is licensed under the 130 | [MIT License](https://github.com/cicirello/pyaction/blob/master/LICENSE). 131 | 132 | ### Image Licenses 133 | As with all pre-built Docker images, the image itself (once built, or obtained from 134 | Docker Hub or the Github Container Registry) contains software that is covered by a 135 | variety of licenses. See the license information for the 136 | [python docker image](https://hub.docker.com/_/python), 137 | the [license for git](https://git-scm.com/), 138 | the [GitHub CLI](https://github.com/cli/cli/blob/trunk/LICENSE), 139 | and the [license for Python](https://docs.python.org/3/license.html). 140 | 141 | If you build and distribute an image containing your software, 142 | using pyaction as the base image, it 143 | is your responsibility to follow the licenses of all of the 144 | software contained within the image. 145 | -------------------------------------------------------------------------------- /version-check/versions.py: -------------------------------------------------------------------------------- 1 | # 2 | # Test for the pyaction docker image, validating versions of installed apps. 3 | # 4 | # Copyright (c) 2022 Vincent A Cicirello 5 | # https://www.cicirello.org/ 6 | # 7 | # MIT License 8 | # 9 | # Permission is hereby granted, free of charge, to any person obtaining a copy 10 | # of this software and associated documentation files (the "Software"), to deal 11 | # in the Software without restriction, including without limitation the rights 12 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | # copies of the Software, and to permit persons to whom the Software is 14 | # furnished to do so, subject to the following conditions: 15 | # 16 | # The above copyright notice and this permission notice shall be included in all 17 | # copies or substantial portions of the Software. 18 | # 19 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | # SOFTWARE. 26 | # 27 | 28 | import json 29 | import subprocess 30 | import platform 31 | from datetime import datetime 32 | 33 | def executeCommand(arguments) : 34 | """Execute a subprocess and return result and exit code. 35 | 36 | Keyword arguments: 37 | arguments - The arguments for the command. 38 | """ 39 | result = subprocess.run( 40 | arguments, 41 | stdout=subprocess.PIPE, 42 | universal_newlines=True 43 | ) 44 | return result.stdout.strip(), result.returncode 45 | 46 | def parse_gh_version(gh) : 47 | """Parses the version number for gh. 48 | 49 | Keyword arguments: 50 | gh - The result of querying the version from gh. 51 | """ 52 | return gh.split()[2] 53 | 54 | def parse_git_version(git) : 55 | """Parses the version number for git. 56 | 57 | Keyword arguments: 58 | git - The result of querying the version from git. 59 | """ 60 | return git.split()[2] 61 | 62 | def parse_curl_version(curl) : 63 | """Parses the version number for curl. 64 | 65 | Keyword arguments: 66 | curl - The result of querying the version from curl. 67 | """ 68 | return curl.split()[1] 69 | 70 | def parse_gpg_version(gpg) : 71 | """Parses the version number for gpg. 72 | 73 | Keyword arguments: 74 | gpg - The result of querying the version from gpg. 75 | """ 76 | return gpg.split()[2] 77 | 78 | def updateChangelogIfNecessary(versions) : 79 | """Compares current versions to old, and if any changed 80 | updates the Changelog. Returns whether or not any versions 81 | have changed. 82 | 83 | Keyword arguments: 84 | versions - Python map containing the versions extracted from 85 | the Docker image. 86 | """ 87 | with open("versions.json", "r") as f : 88 | priorVersions = json.load(f) 89 | changed = versions != priorVersions 90 | if changed : 91 | updateChangelog(priorVersions, versions) 92 | return changed 93 | 94 | def updateVersionsJSON(versions) : 95 | """Updates versions.json as necessary. 96 | 97 | Keyword arguments: 98 | versions - Python map containing the versions extracted from 99 | the Docker image. 100 | """ 101 | with open("versions.json", "w") as f : 102 | json.dump(versions, f, sort_keys=True, indent=2) 103 | 104 | def updateChangelog(priorVersions, versions) : 105 | """Updates the Unreleased section of the Changelog as necessary. 106 | 107 | Keyword arguments: 108 | priorVersions - Python map containing the versions as listed 109 | currently in the existing versions.json. 110 | versions - Python map containing the versions extracted from 111 | the Docker image. 112 | """ 113 | with open("CHANGELOG.md", "r+") as f : 114 | contents = f.readlines() 115 | for i in range(len(contents)) : 116 | line = contents[i] 117 | if line.strip().startswith("## [Unreleased]") : 118 | unreleasedLineNumber = i 119 | break 120 | for i in range(unreleasedLineNumber + 1, len(contents)) : 121 | line = contents[i] 122 | if line.strip().startswith("### Changed") : 123 | changedStartsAt = i + 1 124 | break 125 | for i in range(changedStartsAt + 1, len(contents)) : 126 | line = contents[i] 127 | if line.strip().startswith("###") : 128 | changedEndsAt = i - 1 129 | break 130 | contents[unreleasedLineNumber] = "## [Unreleased] - {0}\n".format(datetime.today().strftime('%Y-%m-%d')) 131 | changedContents = findChanges(priorVersions, versions) 132 | updatedLogLines = set() 133 | for i in range(changedStartsAt, changedEndsAt) : 134 | if contents[i].startswith("* Bumped") : 135 | j = contents[i].find(" to ") 136 | if j > 0 : 137 | checkThis = contents[i][:j+3] 138 | for k, toolLine in enumerate(changedContents) : 139 | if toolLine.startswith(checkThis) : 140 | contents[i] = toolLine 141 | updatedLogLines.add(k) 142 | break 143 | changedContents = [ toolLine for k, toolLine in enumerate(changedContents) if k not in updatedLogLines] 144 | if len(changedContents) > 0 : 145 | contents[changedStartsAt:changedStartsAt] = changedContents 146 | f.seek(0) 147 | f.truncate() 148 | f.writelines(contents) 149 | 150 | def findChanges(priorVersions, versions) : 151 | """Determines which tools have new versions. 152 | 153 | Keyword arguments: 154 | priorVersions - Python map containing the versions as listed 155 | currently in the existing versions.json. 156 | versions - Python map containing the versions extracted from 157 | the Docker image. 158 | """ 159 | template = "* Bumped {0} to {1}.\n" 160 | changes = [] 161 | if priorVersions["python"] != versions["python"] : 162 | changes.append(template.format("Python", versions["python"])) 163 | if priorVersions["gh"] != versions["gh"] : 164 | changes.append(template.format("GitHub CLI", versions["gh"])) 165 | if priorVersions["git"] != versions["git"] : 166 | changes.append(template.format("git", versions["git"])) 167 | if priorVersions["curl"] != versions["curl"] : 168 | changes.append(template.format("curl", versions["curl"])) 169 | if priorVersions["gpg"] != versions["gpg"] : 170 | changes.append(template.format("gpg", versions["gpg"])) 171 | return changes 172 | 173 | if __name__ == "__main__" : 174 | gh, code = executeCommand(["gh", "--version"]) 175 | gh = parse_gh_version(gh) 176 | git, code = executeCommand(["git", "--version"]) 177 | git = parse_git_version(git) 178 | curl, code = executeCommand(["curl", "-V"]) 179 | curl = parse_curl_version(curl) 180 | gpg, code = executeCommand(["gpg", "--version"]) 181 | gpg = parse_gpg_version(gpg) 182 | print("gh version:", gh) 183 | print("git version:", git) 184 | print("curl version:", curl) 185 | print("gpg version:", gpg) 186 | print("python version", platform.python_version()) 187 | versions = { 188 | "gh" : gh, 189 | "git" : git, 190 | "curl" : curl, 191 | "gpg" : gpg, 192 | "python" : platform.python_version() 193 | } 194 | if updateChangelogIfNecessary(versions) : 195 | updateVersionsJSON(versions) 196 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | All notable changes to this project will be documented in this file. 3 | 4 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 5 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 6 | 7 | ## [Unreleased] - 2025-12-17 8 | 9 | ### Added 10 | 11 | ### Changed 12 | * Bumped git to 2.47.3. 13 | * Bumped curl to 8.14.1. 14 | * Bumped gpg to 2.4.7. 15 | * Bumped Python to 3.14.2. 16 | * Bumped GitHub CLI to 2.83.2. 17 | 18 | ### Deprecated 19 | 20 | ### Removed 21 | 22 | ### Fixed 23 | 24 | ### CI/CD 25 | 26 | 27 | ## [5.0.0] - 2025-07-10 28 | 29 | **We'll continue to update the Unreleased section of the Changelog with versions planned 30 | for next image build, but we will otherwise no longer be updating the Changelog, 31 | as its structure doesn't coincide very well with our new tagging scheme.** 32 | 33 | ### Added 34 | * New Docker tag scheme based on versions of Python the GitHub CLI contained in the image. 35 | 36 | ### Changed 37 | * Bumped Python to 3.13.5. 38 | * Bumped GitHub CLI to 2.75.0. 39 | 40 | 41 | ## [4.33.0] - 2025-05-18 42 | 43 | ### Changed 44 | * Bumped Python to 3.13.3. 45 | * Bumped GitHub CLI to 2.72.0. 46 | 47 | 48 | ## [4.32.0] - 2024-09-25 49 | 50 | ### Changed 51 | * Bumped git to 2.39.5. 52 | * Bumped GitHub CLI to 2.57.0. 53 | * Bumped Python to 3.12.6. 54 | 55 | 56 | ## [4.31.0] - 2024-06-08 57 | 58 | ### Changed 59 | * Bumped GitHub CLI to 2.50.0. 60 | 61 | 62 | ## [4.30.0] - 2024-05-17 63 | 64 | ### Changed 65 | * Bumped Python to 3.12.3. 66 | * Bumped GitHub CLI to 2.49.2. 67 | 68 | 69 | ## [4.29.0] - 2024-03-05 70 | 71 | ### Changed 72 | * Bumped GitHub CLI to 2.45.0. 73 | 74 | 75 | ## [4.28.0] - 2024-02-16 76 | 77 | ### Changed 78 | * Bumped GitHub CLI to 2.44.1. 79 | * Bumped Python to 3.12.2. 80 | 81 | 82 | ## [4.27.0] - 2023-12-08 83 | 84 | ### Changed 85 | * Bumped GitHub CLI to 2.40.0. 86 | 87 | 88 | ## [4.26.0] - 2023-11-03 89 | 90 | ### Changed 91 | * Bumped GitHub CLI to 2.38.0. 92 | 93 | 94 | ## [4.25.0] - 2023-10-04 95 | 96 | ### Changed 97 | * Bumped GitHub CLI to 2.36.0. 98 | * Bumped Python to 3.12.0. 99 | 100 | 101 | ## [4.24.0] - 2023-09-21 102 | 103 | ### Changed 104 | * Bumped GitHub CLI to 2.35.0. 105 | 106 | 107 | ## [4.23.0] - 2023-09-07 108 | 109 | ### Changed 110 | * Bumped GitHub CLI to 2.34.0. 111 | 112 | 113 | ## [4.22.0] - 2023-08-28 114 | 115 | ### Changed 116 | * Bumped Python to 3.11.5. 117 | * Bumped GitHub CLI to 2.33.0. 118 | 119 | 120 | ## [4.21.0] - 2023-06-15 121 | 122 | ### Changed 123 | * Bumped git to 2.39.2. 124 | * Bumped curl to 7.88.1. 125 | * Bumped gpg to 2.2.40. 126 | * Bumped Python to 3.11.4. 127 | 128 | 129 | ## [4.20.0] - 2023-05-31 130 | 131 | ### Changed 132 | * Bumped GitHub CLI to 2.30.0. 133 | 134 | 135 | ## [4.19.0] - 2023-05-12 136 | 137 | ### Changed 138 | * Bumped GitHub CLI to 2.29.0. 139 | 140 | 141 | ## [4.18.0] - 2023-04-07 142 | 143 | ### Changed 144 | * Bumped Python to 3.11.3. 145 | * Bumped GitHub CLI to 2.26.1. 146 | 147 | 148 | ## [4.17.0] - 2023-03-09 149 | 150 | ### Changed 151 | * Bumped GitHub CLI to 2.24.3. 152 | 153 | 154 | ## [4.16.0] - 2023-02-09 155 | 156 | ### Changed 157 | * Bumped Python to 3.11.2. 158 | * Bumped GitHub CLI to 2.23.0. 159 | 160 | 161 | ## [4.15.0] - 2023-01-26 162 | 163 | ### Changed 164 | * Bumped GitHub CLI to 2.22.0. 165 | 166 | 167 | ## [4.14.1] - 2023-01-04 168 | 169 | ### Changed 170 | * Bumped GitHub CLI to 2.21.2. 171 | 172 | 173 | ## [4.14.0] - 2022-12-28 174 | 175 | ### Changed 176 | * Bumped GitHub CLI to 2.21.1. 177 | 178 | 179 | ## [4.13.1] - 2022-12-10 180 | 181 | ### Changed 182 | * Bumped Python to 3.11.1. 183 | * Bumped GitHub CLI to 2.20.2. 184 | 185 | 186 | ## [4.13.0] - 2022-11-09 187 | 188 | ### Changed 189 | * Bumped GitHub CLI to 2.20.0. 190 | 191 | 192 | ## [4.12.0] - 2022-10-25 193 | 194 | ### Changed 195 | * Bumped Python to 3.11.0. 196 | 197 | 198 | ## [4.11.1] - 2022-10-21 199 | 200 | ### Changed 201 | * Bumped GitHub CLI to 2.18.1. 202 | 203 | 204 | ## [4.11.0] - 2022-10-19 205 | 206 | ### Changed 207 | * Bumped GitHub CLI to 2.18.0. 208 | 209 | 210 | ## [4.10.0] - 2022-10-05 211 | 212 | ### Changed 213 | * Bumped GitHub CLI to 2.17.0. 214 | 215 | 216 | ## [4.9.0] - 2022-09-22 217 | 218 | ### Changed 219 | * Bumped GitHub CLI to 2.16.0. 220 | 221 | 222 | ## [4.8.1] - 2022-09-08 223 | 224 | ### Changed 225 | * Bumped Python to 3.10.7. 226 | 227 | 228 | ## [4.8.0] - 2022-09-07 229 | 230 | ### Changed 231 | * Bumped GitHub CLI to 2.15.0. 232 | 233 | 234 | ## [4.7.1] - 2022-08-15 235 | 236 | ### Changed 237 | * Bumped Python to 3.10.6. 238 | * Bumped GitHub CLI to 2.14.4. 239 | 240 | 241 | ## [4.7.0] - 2022-07-24 242 | 243 | ### Changed 244 | * Bumped GitHub CLI to 2.14.2. 245 | 246 | 247 | ## [4.6.0] - 2022-06-23 248 | 249 | ### Changed 250 | * Bumped GitHub CLI to 2.13.0. 251 | 252 | 253 | ## [4.5.0] - 2022-06-09 254 | 255 | ### Changed 256 | * Bumped Python to 3.10.5. 257 | * Bumped GitHub CLI to 2.12.1. 258 | 259 | 260 | ## [4.4.0] - 2022-05-06 261 | 262 | ### Changed 263 | * Bumped GitHub CLI to 2.9.0. 264 | 265 | 266 | ## [4.3.1] - 2022-03-29 267 | 268 | ### Changed 269 | * Bumped Python to 3.10.4. 270 | 271 | 272 | ## [4.3.0] - 2022-03-17 273 | 274 | ### Changed 275 | * Bumped Python to 3.10.3. 276 | * Bumped GitHub CLI to 2.6.0. 277 | 278 | 279 | ## [4.2.0] - 2022-02-20 280 | 281 | ### Changed 282 | * Bumped GitHub CLI to 2.5.1. 283 | 284 | 285 | ## [4.1.0] - 2022-01-24 286 | 287 | Note that 4.1.0 is the same as 4.0.0 in what is included in the image. The purpose 288 | of this release includes changing the tag used for the base docker image to specify 289 | a specific release of python, in this case `3.10.2-slim`, whereas previously it was 290 | specified more generally as `3-slim`. We have also changed our CI/CD related workflows 291 | to include a script that monitors daily for available updates to the GitHub CLI, git, curl, and 292 | gpg. From this point onward, we are taking a more deliberative approach to pushing new 293 | images, such as when one or more of these have new versions available, and we will bump 294 | the version number of pyaction when this occurs. 295 | 296 | The versions included in pyaction 4.1.0 are as follows: 297 | * Python 3.10.2 (a python 3.10.2-slim base docker image) 298 | * GitHub CLI 2.4.0 299 | * git 2.30.2 300 | * curl 7.74.0 301 | * gpg 2.2.27 302 | 303 | ### Changed 304 | * Base Docker image is still a Python 3 Slim, but it is now fixed to 305 | a specific version, in this case 3.10.2-slim. 306 | * Eliminated the twice-monthly automated builds to current tags to enable 307 | a more deliberative approach to maintaining versions of packages in the 308 | image. 309 | * New release policy is to release a new image when the versions of one or more 310 | of python, git, gh, curl, or gpg are bumped. 311 | 312 | ### CI/CD 313 | * Now performs daily builds, which includes using the image to run a simple Python program 314 | to validate the various package installations. This test program simply outputs the versions 315 | of git, gh, curl, gpg, and python. It also generates a json file with this data within the 316 | repo to enable detecting updated versions of these packages. Dependabot handles updating python 317 | version, but not able to detect what versions the base image's package manager will install. 318 | If any versions change, this workflow will generate a PR for this new versions.json file, 319 | alerting us to the newly available versions. 320 | 321 | 322 | ## [4.0.0] - 2021-07-03 323 | 324 | ### Upgrading 325 | * Potentially breaking changes are included in this release. 326 | * Read notes below carefully, and test your application before 327 | upgrading. 328 | 329 | ### Added 330 | * Added the GitHub CLI (gh). 331 | * Added curl (necessary to install gh). 332 | * Added gpg (necessary to install gh). 333 | 334 | ### Changed 335 | * BREAKING CHANGE: Base image is now python:3-slim rather than alpine. 336 | * This new base image was necessary in order to be able to install gh. 337 | * This new base image is based on Debian. 338 | * CI/CD process now performs twice monthly automated builds/pushes to ensure 339 | picking up any non-breaking bug fixes / security updates from base OS 340 | distro, Python, etc. This is accomplished by using the python:3-slim 341 | tag when pulling the base image, rather than a more specific version of 342 | Python. 343 | * Version numbering scheme changed. 344 | * It is still SemVer, but no longer based on SemVer of base image. 345 | 346 | ### Removed 347 | * No longer supports the following architectures: linux/ppc64le, linux/s390x, linux/arm/v6. 348 | * These architectures are not supported by gh. 349 | 350 | 351 | ## [3.14.0] - 2021-06-16 352 | 353 | ### Added 354 | * This ChangeLog. Note that versions prior to this one that the pyaction 355 | version corresponds to the Alpine version. 356 | 357 | ### Changed 358 | * Bumped base docker image to Alpine 3.14.0. 359 | -------------------------------------------------------------------------------- /.github/workflows/docker-publish.yml: -------------------------------------------------------------------------------- 1 | name: Docker Publish 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | PYTHON: 7 | description: FULL Version Number of Python 8 | required: true 9 | GHCLI: 10 | description: Version of GitHub CLI 11 | required: true 12 | 13 | jobs: 14 | build-push: 15 | needs: python-3-13 16 | runs-on: ubuntu-latest 17 | 18 | steps: 19 | - name: Checkout 20 | uses: actions/checkout@v6 21 | 22 | - name: Prepare 23 | id: prep 24 | run: | 25 | PYTHON_VERSION=${{ github.event.inputs.PYTHON }} 26 | PYTHON_MINOR=${PYTHON_VERSION%.*} 27 | DOCKERHUB_IMAGE=cicirello/pyaction 28 | GHCR_IMAGE=ghcr.io/cicirello/pyaction 29 | VERSION=${{ github.event.inputs.GHCLI }} 30 | MINOR=${VERSION%.*} 31 | MAJOR=${VERSION%%.*} 32 | TAGS="${DOCKERHUB_IMAGE}:${PYTHON_MINOR}-gh-${MAJOR},${DOCKERHUB_IMAGE}:${PYTHON_MINOR}-gh-${MINOR}" 33 | TAGS="${TAGS},${DOCKERHUB_IMAGE}:${PYTHON_MINOR}-gh-${VERSION}" 34 | TAGS="${TAGS},${DOCKERHUB_IMAGE}:${PYTHON_VERSION}-gh-${MAJOR},${DOCKERHUB_IMAGE}:${PYTHON_VERSION}-gh-${MINOR}" 35 | TAGS="${TAGS},${DOCKERHUB_IMAGE}:${PYTHON_VERSION}-gh-${VERSION}" 36 | TAGS="${TAGS},${DOCKERHUB_IMAGE}:${PYTHON_MINOR}" 37 | TAGS="${TAGS},${DOCKERHUB_IMAGE}:${PYTHON_VERSION},${DOCKERHUB_IMAGE}:latest" 38 | TAGS="${TAGS},${GHCR_IMAGE}:${PYTHON_MINOR}-gh-${MAJOR},${GHCR_IMAGE}:${PYTHON_MINOR}-gh-${MINOR}" 39 | TAGS="${TAGS},${GHCR_IMAGE}:${PYTHON_MINOR}-gh-${VERSION}" 40 | TAGS="${TAGS},${GHCR_IMAGE}:${PYTHON_VERSION}-gh-${MAJOR},${GHCR_IMAGE}:${PYTHON_VERSION}-gh-${MINOR}" 41 | TAGS="${TAGS},${GHCR_IMAGE}:${PYTHON_VERSION}-gh-${VERSION}" 42 | TAGS="${TAGS},${GHCR_IMAGE}:${PYTHON_MINOR}" 43 | TAGS="${TAGS},${GHCR_IMAGE}:${PYTHON_VERSION},${GHCR_IMAGE}:latest" 44 | echo "tags=${TAGS}" >> $GITHUB_OUTPUT 45 | echo "version=${VERSION}" >> $GITHUB_OUTPUT 46 | echo "dockerhub_image=${DOCKERHUB_IMAGE}" >> $GITHUB_OUTPUT 47 | echo "ghcr_image=${GHCR_IMAGE}" >> $GITHUB_OUTPUT 48 | 49 | - name: Set up QEMU 50 | uses: docker/setup-qemu-action@v3 51 | with: 52 | platforms: all 53 | 54 | - name: Set up Docker Buildx 55 | id: buildx 56 | uses: docker/setup-buildx-action@v3 57 | 58 | - name: Login to DockerHub 59 | uses: docker/login-action@v3 60 | with: 61 | username: ${{ secrets.DOCKER_USERNAME }} 62 | password: ${{ secrets.DOCKER_PASSWORD }} 63 | 64 | - name: Login to Github Container Registry 65 | uses: docker/login-action@v3 66 | with: 67 | registry: ghcr.io 68 | username: ${{ github.repository_owner }} 69 | password: ${{ secrets.GITHUB_TOKEN }} 70 | 71 | - name: Build and push 72 | uses: docker/build-push-action@v6 73 | with: 74 | builder: ${{ steps.buildx.outputs.name }} 75 | context: . 76 | file: ./Dockerfile 77 | platforms: linux/amd64,linux/arm64,linux/386,linux/arm/v7,linux/arm/v6 78 | push: true 79 | tags: ${{ steps.prep.outputs.tags }} 80 | labels: org.opencontainers.image.version=${{ steps.prep.outputs.version }} 81 | 82 | python-3-13: 83 | needs: python-3-12 84 | runs-on: ubuntu-latest 85 | 86 | steps: 87 | - name: Checkout 88 | uses: actions/checkout@v6 89 | with: 90 | ref: "3.13" 91 | 92 | - name: Prepare 93 | id: prep 94 | run: | 95 | PYTHON_VERSION=3.13 96 | DOCKERHUB_IMAGE=cicirello/pyaction 97 | GHCR_IMAGE=ghcr.io/cicirello/pyaction 98 | VERSION=${{ github.event.inputs.GHCLI }} 99 | MINOR=${VERSION%.*} 100 | MAJOR=${VERSION%%.*} 101 | TAGS="${DOCKERHUB_IMAGE}:${PYTHON_VERSION},${DOCKERHUB_IMAGE}:${PYTHON_VERSION}-gh-${MAJOR}" 102 | TAGS="${TAGS},${DOCKERHUB_IMAGE}:${PYTHON_VERSION}-gh-${MINOR}" 103 | TAGS="${TAGS},${DOCKERHUB_IMAGE}:${PYTHON_VERSION}-gh-${VERSION}" 104 | TAGS="${TAGS},${GHCR_IMAGE}:${PYTHON_VERSION},${GHCR_IMAGE}:${PYTHON_VERSION}-gh-${MAJOR}" 105 | TAGS="${TAGS},${GHCR_IMAGE}:${PYTHON_VERSION}-gh-${MINOR}" 106 | TAGS="${TAGS},${GHCR_IMAGE}:${PYTHON_VERSION}-gh-${VERSION}" 107 | echo "tags=${TAGS}" >> $GITHUB_OUTPUT 108 | echo "version=${VERSION}" >> $GITHUB_OUTPUT 109 | echo "dockerhub_image=${DOCKERHUB_IMAGE}" >> $GITHUB_OUTPUT 110 | echo "ghcr_image=${GHCR_IMAGE}" >> $GITHUB_OUTPUT 111 | 112 | - name: Set up QEMU 113 | uses: docker/setup-qemu-action@v3 114 | with: 115 | platforms: all 116 | 117 | - name: Set up Docker Buildx 118 | id: buildx 119 | uses: docker/setup-buildx-action@v3 120 | 121 | - name: Login to DockerHub 122 | uses: docker/login-action@v3 123 | with: 124 | username: ${{ secrets.DOCKER_USERNAME }} 125 | password: ${{ secrets.DOCKER_PASSWORD }} 126 | 127 | - name: Login to Github Container Registry 128 | uses: docker/login-action@v3 129 | with: 130 | registry: ghcr.io 131 | username: ${{ github.repository_owner }} 132 | password: ${{ secrets.GITHUB_TOKEN }} 133 | 134 | - name: Build and push 135 | uses: docker/build-push-action@v6 136 | with: 137 | builder: ${{ steps.buildx.outputs.name }} 138 | context: . 139 | file: ./Dockerfile 140 | platforms: linux/amd64,linux/arm64,linux/386,linux/arm/v7,linux/arm/v6 141 | push: true 142 | tags: ${{ steps.prep.outputs.tags }} 143 | labels: org.opencontainers.image.version=${{ steps.prep.outputs.version }} 144 | 145 | python-3-12: 146 | needs: python-3-11 147 | runs-on: ubuntu-latest 148 | 149 | steps: 150 | - name: Checkout 151 | uses: actions/checkout@v6 152 | with: 153 | ref: "3.12" 154 | 155 | - name: Prepare 156 | id: prep 157 | run: | 158 | PYTHON_VERSION=3.12 159 | DOCKERHUB_IMAGE=cicirello/pyaction 160 | GHCR_IMAGE=ghcr.io/cicirello/pyaction 161 | VERSION=${{ github.event.inputs.GHCLI }} 162 | MINOR=${VERSION%.*} 163 | MAJOR=${VERSION%%.*} 164 | TAGS="${DOCKERHUB_IMAGE}:${PYTHON_VERSION},${DOCKERHUB_IMAGE}:${PYTHON_VERSION}-gh-${MAJOR}" 165 | TAGS="${TAGS},${DOCKERHUB_IMAGE}:${PYTHON_VERSION}-gh-${MINOR}" 166 | TAGS="${TAGS},${DOCKERHUB_IMAGE}:${PYTHON_VERSION}-gh-${VERSION}" 167 | TAGS="${TAGS},${GHCR_IMAGE}:${PYTHON_VERSION},${GHCR_IMAGE}:${PYTHON_VERSION}-gh-${MAJOR}" 168 | TAGS="${TAGS},${GHCR_IMAGE}:${PYTHON_VERSION}-gh-${MINOR}" 169 | TAGS="${TAGS},${GHCR_IMAGE}:${PYTHON_VERSION}-gh-${VERSION}" 170 | echo "tags=${TAGS}" >> $GITHUB_OUTPUT 171 | echo "version=${VERSION}" >> $GITHUB_OUTPUT 172 | echo "dockerhub_image=${DOCKERHUB_IMAGE}" >> $GITHUB_OUTPUT 173 | echo "ghcr_image=${GHCR_IMAGE}" >> $GITHUB_OUTPUT 174 | 175 | - name: Set up QEMU 176 | uses: docker/setup-qemu-action@v3 177 | with: 178 | platforms: all 179 | 180 | - name: Set up Docker Buildx 181 | id: buildx 182 | uses: docker/setup-buildx-action@v3 183 | 184 | - name: Login to DockerHub 185 | uses: docker/login-action@v3 186 | with: 187 | username: ${{ secrets.DOCKER_USERNAME }} 188 | password: ${{ secrets.DOCKER_PASSWORD }} 189 | 190 | - name: Login to Github Container Registry 191 | uses: docker/login-action@v3 192 | with: 193 | registry: ghcr.io 194 | username: ${{ github.repository_owner }} 195 | password: ${{ secrets.GITHUB_TOKEN }} 196 | 197 | - name: Build and push 198 | uses: docker/build-push-action@v6 199 | with: 200 | builder: ${{ steps.buildx.outputs.name }} 201 | context: . 202 | file: ./Dockerfile 203 | platforms: linux/amd64,linux/arm64,linux/386,linux/arm/v7,linux/arm/v6 204 | push: true 205 | tags: ${{ steps.prep.outputs.tags }} 206 | labels: org.opencontainers.image.version=${{ steps.prep.outputs.version }} 207 | 208 | python-3-11: 209 | needs: python-3-10 210 | runs-on: ubuntu-latest 211 | 212 | steps: 213 | - name: Checkout 214 | uses: actions/checkout@v6 215 | with: 216 | ref: "3.11" 217 | 218 | - name: Prepare 219 | id: prep 220 | run: | 221 | PYTHON_VERSION=3.11 222 | DOCKERHUB_IMAGE=cicirello/pyaction 223 | GHCR_IMAGE=ghcr.io/cicirello/pyaction 224 | VERSION=${{ github.event.inputs.GHCLI }} 225 | MINOR=${VERSION%.*} 226 | MAJOR=${VERSION%%.*} 227 | TAGS="${DOCKERHUB_IMAGE}:${PYTHON_VERSION},${DOCKERHUB_IMAGE}:${PYTHON_VERSION}-gh-${MAJOR}" 228 | TAGS="${TAGS},${DOCKERHUB_IMAGE}:${PYTHON_VERSION}-gh-${MINOR}" 229 | TAGS="${TAGS},${DOCKERHUB_IMAGE}:${PYTHON_VERSION}-gh-${VERSION}" 230 | TAGS="${TAGS},${GHCR_IMAGE}:${PYTHON_VERSION},${GHCR_IMAGE}:${PYTHON_VERSION}-gh-${MAJOR}" 231 | TAGS="${TAGS},${GHCR_IMAGE}:${PYTHON_VERSION}-gh-${MINOR}" 232 | TAGS="${TAGS},${GHCR_IMAGE}:${PYTHON_VERSION}-gh-${VERSION}" 233 | echo "tags=${TAGS}" >> $GITHUB_OUTPUT 234 | echo "version=${VERSION}" >> $GITHUB_OUTPUT 235 | echo "dockerhub_image=${DOCKERHUB_IMAGE}" >> $GITHUB_OUTPUT 236 | echo "ghcr_image=${GHCR_IMAGE}" >> $GITHUB_OUTPUT 237 | 238 | - name: Set up QEMU 239 | uses: docker/setup-qemu-action@v3 240 | with: 241 | platforms: all 242 | 243 | - name: Set up Docker Buildx 244 | id: buildx 245 | uses: docker/setup-buildx-action@v3 246 | 247 | - name: Login to DockerHub 248 | uses: docker/login-action@v3 249 | with: 250 | username: ${{ secrets.DOCKER_USERNAME }} 251 | password: ${{ secrets.DOCKER_PASSWORD }} 252 | 253 | - name: Login to Github Container Registry 254 | uses: docker/login-action@v3 255 | with: 256 | registry: ghcr.io 257 | username: ${{ github.repository_owner }} 258 | password: ${{ secrets.GITHUB_TOKEN }} 259 | 260 | - name: Build and push 261 | uses: docker/build-push-action@v6 262 | with: 263 | builder: ${{ steps.buildx.outputs.name }} 264 | context: . 265 | file: ./Dockerfile 266 | platforms: linux/amd64,linux/arm64,linux/386,linux/arm/v7,linux/arm/v6 267 | push: true 268 | tags: ${{ steps.prep.outputs.tags }} 269 | labels: org.opencontainers.image.version=${{ steps.prep.outputs.version }} 270 | 271 | python-3-10: 272 | runs-on: ubuntu-latest 273 | 274 | steps: 275 | - name: Checkout 276 | uses: actions/checkout@v6 277 | with: 278 | ref: "3.10" 279 | 280 | - name: Prepare 281 | id: prep 282 | run: | 283 | PYTHON_VERSION=3.10 284 | DOCKERHUB_IMAGE=cicirello/pyaction 285 | GHCR_IMAGE=ghcr.io/cicirello/pyaction 286 | VERSION=${{ github.event.inputs.GHCLI }} 287 | MINOR=${VERSION%.*} 288 | MAJOR=${VERSION%%.*} 289 | TAGS="${DOCKERHUB_IMAGE}:${PYTHON_VERSION},${DOCKERHUB_IMAGE}:${PYTHON_VERSION}-gh-${MAJOR}" 290 | TAGS="${TAGS},${DOCKERHUB_IMAGE}:${PYTHON_VERSION}-gh-${MINOR}" 291 | TAGS="${TAGS},${DOCKERHUB_IMAGE}:${PYTHON_VERSION}-gh-${VERSION}" 292 | TAGS="${TAGS},${GHCR_IMAGE}:${PYTHON_VERSION},${GHCR_IMAGE}:${PYTHON_VERSION}-gh-${MAJOR}" 293 | TAGS="${TAGS},${GHCR_IMAGE}:${PYTHON_VERSION}-gh-${MINOR}" 294 | TAGS="${TAGS},${GHCR_IMAGE}:${PYTHON_VERSION}-gh-${VERSION}" 295 | echo "tags=${TAGS}" >> $GITHUB_OUTPUT 296 | echo "version=${VERSION}" >> $GITHUB_OUTPUT 297 | echo "dockerhub_image=${DOCKERHUB_IMAGE}" >> $GITHUB_OUTPUT 298 | echo "ghcr_image=${GHCR_IMAGE}" >> $GITHUB_OUTPUT 299 | 300 | - name: Set up QEMU 301 | uses: docker/setup-qemu-action@v3 302 | with: 303 | platforms: all 304 | 305 | - name: Set up Docker Buildx 306 | id: buildx 307 | uses: docker/setup-buildx-action@v3 308 | 309 | - name: Login to DockerHub 310 | uses: docker/login-action@v3 311 | with: 312 | username: ${{ secrets.DOCKER_USERNAME }} 313 | password: ${{ secrets.DOCKER_PASSWORD }} 314 | 315 | - name: Login to Github Container Registry 316 | uses: docker/login-action@v3 317 | with: 318 | registry: ghcr.io 319 | username: ${{ github.repository_owner }} 320 | password: ${{ secrets.GITHUB_TOKEN }} 321 | 322 | - name: Build and push 323 | uses: docker/build-push-action@v6 324 | with: 325 | builder: ${{ steps.buildx.outputs.name }} 326 | context: . 327 | file: ./Dockerfile 328 | platforms: linux/amd64,linux/arm64,linux/386,linux/arm/v7,linux/arm/v6 329 | push: true 330 | tags: ${{ steps.prep.outputs.tags }} 331 | labels: org.opencontainers.image.version=${{ steps.prep.outputs.version }} 332 | --------------------------------------------------------------------------------