v2.0.0b3 — Full IPv6 support #4
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Publish Docker Image | |
| # Triggers: | |
| # | |
| # - release: published | |
| # Full tag set (:VERSION, :major.minor, :major, :latest) - the | |
| # canonical "ship a new version" path. Same trigger as | |
| # python-publish.yml, so one release ships PyPI + Docker together. | |
| # | |
| # - workflow_dispatch | |
| # Manual trigger. Two modes depending on inputs: | |
| # | |
| # - With `version` input (e.g. `--field version=2.0.0b2`): | |
| # Publishes the full tag set (:VERSION, :major.minor, :major, | |
| # :latest) using the supplied version string. Builds whatever | |
| # code is at the dispatched ref. Use this for retroactive | |
| # publishes when the release event didn't fire docker-publish | |
| # (e.g. workflow file added after the release was created), | |
| # or to force-republish a specific version. | |
| # | |
| # - Without `version` input: | |
| # Publishes :manual-<timestamp> only. Useful for smoke-testing | |
| # the workflow on master HEAD without affecting any version tags. | |
| on: | |
| release: | |
| types: [published] | |
| workflow_dispatch: | |
| inputs: | |
| version: | |
| description: "Version to publish (e.g. 2.0.0b2). Leave empty for a smoke-test build tagged :manual-<timestamp>." | |
| required: false | |
| default: "" | |
| jobs: | |
| publish: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| packages: write # required to push to ghcr.io | |
| steps: | |
| - name: Check out source | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| # ref omitted: uses GITHUB_REF, which for both `release` events | |
| # and `workflow_dispatch` is the ref that triggered the workflow. | |
| # Multi-arch builds need QEMU for cross-compilation under buildx. | |
| - name: Set up QEMU | |
| uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4.0.0 | |
| # Buildx is the modern docker builder; supports multi-platform output. | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0 | |
| # Docker Hub login. Token must be a Hub access token (NOT a password) | |
| # scoped to the proxybroker2 repository for least-privilege. | |
| - name: Log in to Docker Hub | |
| uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0 | |
| with: | |
| username: ${{ secrets.DOCKERHUB_USERNAME }} | |
| password: ${{ secrets.DOCKERHUB_TOKEN }} | |
| # GHCR login + push are temporarily disabled. Tracking #206. | |
| # Reason: the GHCR package `ghcr.io/bluet/proxybroker2` doesn't | |
| # exist yet, and `permissions: packages: write` + the OCI source | |
| # label (added in PR #205) aren't sufficient to bootstrap a | |
| # brand-new package from a workflow's GITHUB_TOKEN - the first | |
| # push gets 403 Forbidden. Pre-creating the package once via the | |
| # GHCR web UI (or pushing once with a maintainer PAT scoped to | |
| # write:packages) unblocks subsequent workflow pushes. | |
| # Re-enable by uncommenting the two GHCR-related blocks below | |
| # AND restoring `ghcr.io/bluet/proxybroker2` in the `images:` | |
| # list of the metadata-action step. | |
| # | |
| # - name: Log in to GitHub Container Registry | |
| # uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0 | |
| # with: | |
| # registry: ghcr.io | |
| # username: ${{ github.actor }} | |
| # password: ${{ secrets.GITHUB_TOKEN }} | |
| # Compute version components for manual workflow_dispatch with version input. | |
| # Strips any leading 'v', then derives major / major.minor by removing | |
| # PEP 440 prerelease/post suffixes (a / b / rc / .dev / .post). Only runs | |
| # when version input is non-empty. | |
| - name: Compute version components (manual dispatch) | |
| id: ver | |
| if: github.event_name == 'workflow_dispatch' && inputs.version != '' | |
| env: | |
| INPUT_VERSION: ${{ inputs.version }} | |
| run: | | |
| set -euo pipefail | |
| version="${INPUT_VERSION#v}" | |
| # Strip prerelease/post suffix to get bare M.N.P | |
| base=$(echo "$version" | sed -E 's/(a|b|rc|\.dev|\.post)[0-9]+.*$//') | |
| major="${base%%.*}" | |
| major_minor=$(echo "$base" | cut -d. -f1-2) | |
| { | |
| echo "version=$version" | |
| echo "major=$major" | |
| echo "major_minor=$major_minor" | |
| } >> "$GITHUB_OUTPUT" | |
| # Tag strategy: | |
| # | |
| # `:VERSION` (e.g. `:2.0.0b2`) - exact version pin. | |
| # Uses type=pep440 (NOT type=semver) because this project | |
| # versions in PEP 440 form (`2.0.0b2`), not SemVer | |
| # (`2.0.0-beta.2`). PyPI mandates PEP 440 - we follow. | |
| # | |
| # `:major.minor` / `:major` / `:latest` - floating aliases. | |
| # Advanced on every release event AND on workflow_dispatch | |
| # with version input. Type=match is used for release events | |
| # (regex on git tag) because metadata-action's pep440/semver | |
| # parsers deliberately hold floating aliases back for | |
| # prereleases - we want them to advance for prereleases too: | |
| # this project has been in beta for a year, and locking | |
| # floating tags to stable releases would freeze them on | |
| # `v2.0.0b1` (May 2025) until 2.0.0 ships. | |
| # | |
| # `:manual-<timestamp>` - per-build tag for workflow_dispatch | |
| # without a version input. Smoke-test builds. | |
| # | |
| # `flavor: latest=false` disables metadata-action's automatic | |
| # `:latest` for the highest stable version. We control `:latest` | |
| # explicitly above so it only fires when we explicitly say so. | |
| # | |
| # Acknowledged side-effect: if a future patch is released for an | |
| # OLDER version line (e.g. 1.5.1 after 2.0.0), floating tags would | |
| # advance backward. Not maintaining old version lines today; | |
| # restore `flavor: latest=auto` if that ever changes. | |
| - name: Extract image metadata (tags, labels) | |
| id: meta | |
| uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # v6.0.0 | |
| with: | |
| images: | | |
| bluet/proxybroker2 | |
| flavor: | | |
| latest=false | |
| tags: | | |
| type=pep440,pattern={{version}},enable=${{ github.event_name == 'release' }} | |
| type=match,pattern=v(\d+\.\d+),group=1,enable=${{ github.event_name == 'release' }} | |
| type=match,pattern=v(\d+),group=1,enable=${{ github.event_name == 'release' }} | |
| type=raw,value=latest,enable=${{ github.event_name == 'release' }} | |
| type=raw,value=${{ steps.ver.outputs.version }},enable=${{ steps.ver.outputs.version != '' }} | |
| type=raw,value=${{ steps.ver.outputs.major_minor }},enable=${{ steps.ver.outputs.major_minor != '' }} | |
| type=raw,value=${{ steps.ver.outputs.major }},enable=${{ steps.ver.outputs.major != '' }} | |
| type=raw,value=latest,enable=${{ github.event_name == 'workflow_dispatch' && inputs.version != '' }} | |
| type=raw,value=manual-{{date 'YYYYMMDDHHmmss'}},enable=${{ github.event_name == 'workflow_dispatch' && inputs.version == '' }} | |
| # Build once, push to both registries. cache-from/to use the GitHub | |
| # Actions cache backend so a second run on the same code reuses | |
| # layers and finishes in seconds instead of minutes. | |
| - name: Build and push | |
| uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0 | |
| with: | |
| context: . | |
| platforms: linux/amd64,linux/arm64 | |
| push: true | |
| tags: ${{ steps.meta.outputs.tags }} | |
| labels: ${{ steps.meta.outputs.labels }} | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max |