publish-image #1
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 image | |
| on: | |
| repository_dispatch: | |
| types: [publish-image] | |
| workflow_dispatch: | |
| inputs: | |
| digest: | |
| description: "Image digest already in GHCR (sha256:…)" | |
| required: true | |
| version: | |
| description: "Release tag to publish it as (vX.Y.Z)" | |
| required: true | |
| # The image is built in the private source repository. It pushes the layers to | |
| # ghcr.io/nexora-vpn/node under a throwaway build tag and then triggers this | |
| # workflow with the digest; all this does is put the released tags on that | |
| # digest. No layer is uploaded twice — the digest is already in the registry and | |
| # only a manifest is written. | |
| # | |
| # The point of doing it here rather than there is the package's repository link: | |
| # GHCR links a container package to the repository whose workflow pushed it with | |
| # GITHUB_TOKEN. Pushed from the private repository, the package lands on a page | |
| # nobody can open; pushed from here, it lands on this one — which is also what | |
| # names this repository as the source in the organisation's package list. | |
| # | |
| # One-time setup on the package: Manage Actions access must grant this repository | |
| # Write, or the first run is denied. | |
| permissions: | |
| contents: read | |
| packages: write | |
| # Two releases tagging the same package must not interleave. | |
| concurrency: | |
| group: publish-image | |
| cancel-in-progress: false | |
| jobs: | |
| tag: | |
| runs-on: ubuntu-latest | |
| env: | |
| IMAGE: ghcr.io/nexora-vpn/node | |
| DIGEST: ${{ github.event.client_payload.digest || inputs.digest }} | |
| VERSION: ${{ github.event.client_payload.version || inputs.version }} | |
| steps: | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v4 | |
| - name: Login to GHCR | |
| uses: docker/login-action@v4 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.repository_owner }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Put the released tags on the built digest | |
| run: | | |
| set -euo pipefail | |
| case "$DIGEST" in sha256:*) ;; *) echo "not a digest: ${DIGEST}" >&2; exit 1 ;; esac | |
| case "$VERSION" in v[0-9]*) ;; *) echo "not a release tag: ${VERSION}" >&2; exit 1 ;; esac | |
| bare="${VERSION#v}" | |
| tags=("$VERSION" "$bare") | |
| # A prerelease moves neither the major.minor tag nor `latest`: `latest` | |
| # is what the documented compose files pull, and what the panel's node | |
| # installer resolves. | |
| case "$bare" in | |
| *-*) ;; | |
| *) tags+=("${bare%.*}" latest) ;; | |
| esac | |
| args=() | |
| for t in "${tags[@]}"; do args+=(--tag "${IMAGE}:${t}"); done | |
| echo "tagging ${IMAGE}@${DIGEST} as: ${tags[*]}" | |
| docker buildx imagetools create "${args[@]}" "${IMAGE}@${DIGEST}" | |
| docker buildx imagetools inspect "${IMAGE}:${VERSION}" |