* chore: update dependencies, Node.js, pnpm, and GitHub Actions * chore: update pnpm/setup to v3.1.2 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs: update pnpm/setup examples to v3.1.2 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
152 lines
5.8 KiB
YAML
152 lines
5.8 KiB
YAML
name: Docker
|
|
|
|
on:
|
|
release:
|
|
types: [published]
|
|
workflow_dispatch:
|
|
inputs:
|
|
version:
|
|
description: "pnpm version to build (without leading v)"
|
|
required: true
|
|
prerelease:
|
|
description: "Treat as prerelease (skips mutable tags)"
|
|
type: boolean
|
|
default: false
|
|
|
|
jobs:
|
|
build:
|
|
name: Build
|
|
if: github.event_name == 'workflow_dispatch' || startsWith(github.event.release.tag_name, 'v')
|
|
runs-on: blacksmith-8vcpu-ubuntu-2404
|
|
environment: release
|
|
permissions:
|
|
contents: read
|
|
packages: write
|
|
id-token: write
|
|
env:
|
|
IMAGE: ghcr.io/${{ github.repository_owner }}/pnpm
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- name: Resolve release metadata
|
|
id: meta
|
|
env:
|
|
EVENT_NAME: ${{ github.event_name }}
|
|
RELEASE_TAG: ${{ github.event.release.tag_name }}
|
|
RELEASE_PRERELEASE: ${{ github.event.release.prerelease }}
|
|
INPUT_VERSION: ${{ inputs.version }}
|
|
INPUT_PRERELEASE: ${{ inputs.prerelease }}
|
|
run: |
|
|
set -eu
|
|
if [ "$EVENT_NAME" = "release" ]; then
|
|
version="${RELEASE_TAG#v}"
|
|
prerelease="$RELEASE_PRERELEASE"
|
|
else
|
|
version="${INPUT_VERSION#v}"
|
|
prerelease="$INPUT_PRERELEASE"
|
|
fi
|
|
case "$version" in
|
|
*[!0-9A-Za-z.+-]*) echo "invalid version: $version" >&2; exit 1 ;;
|
|
[0-9]*.[0-9]*.[0-9]*) ;;
|
|
*) echo "invalid version: $version" >&2; exit 1 ;;
|
|
esac
|
|
echo "version=$version" >> "$GITHUB_OUTPUT"
|
|
echo "prerelease=$prerelease" >> "$GITHUB_OUTPUT"
|
|
|
|
- name: Compute pnpm tarball checksums
|
|
id: checksums
|
|
env:
|
|
VERSION: ${{ steps.meta.outputs.version }}
|
|
GH_TOKEN: ${{ github.token }}
|
|
run: |
|
|
set -euo pipefail
|
|
base="https://github.com/pnpm/pnpm/releases/download/v${VERSION}"
|
|
for pair in amd64:x64 arm64:arm64; do
|
|
key="${pair%:*}"
|
|
name="${pair#*:}"
|
|
sha="$(curl -fsSL --retry 3 --retry-delay 2 "${base}/pnpm-linux-${name}.tar.gz" \
|
|
| sha256sum | awk '{print $1}')"
|
|
echo "sha_${key}=${sha}" >> "$GITHUB_OUTPUT"
|
|
done
|
|
# The Alpine image is built only for release lines that ship musl
|
|
# tarballs for both architectures. Older lines lack the arm64 one.
|
|
assets="$(gh release view "v${VERSION}" --repo "$GITHUB_REPOSITORY" --json assets --jq '.assets[].name')"
|
|
alpine=true
|
|
for name in x64 arm64; do
|
|
printf '%s\n' "$assets" | grep -qxF "pnpm-linux-${name}-musl.tar.gz" || alpine=false
|
|
done
|
|
echo "alpine=${alpine}" >> "$GITHUB_OUTPUT"
|
|
if [ "$alpine" = true ]; then
|
|
for pair in amd64:x64 arm64:arm64; do
|
|
key="${pair%:*}"
|
|
name="${pair#*:}"
|
|
sha="$(curl -fsSL --retry 3 --retry-delay 2 "${base}/pnpm-linux-${name}-musl.tar.gz" \
|
|
| sha256sum | awk '{print $1}')"
|
|
echo "sha_musl_${key}=${sha}" >> "$GITHUB_OUTPUT"
|
|
done
|
|
fi
|
|
|
|
- name: Set up QEMU
|
|
uses: docker/setup-qemu-action@99012661954931238ded8c8b007157a8430204e1 # v4.4.0
|
|
|
|
- name: Set up Docker Buildx
|
|
uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1
|
|
|
|
- name: Login to GHCR
|
|
uses: docker/login-action@81c6f93d4bc991e510b342a00b419b3bb4efc5c6 # v4.7.0
|
|
with:
|
|
registry: ghcr.io
|
|
username: ${{ github.actor }}
|
|
password: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- name: Build and push
|
|
uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0
|
|
with:
|
|
context: ./docker
|
|
platforms: linux/amd64,linux/arm64
|
|
push: true
|
|
tags: ${{ env.IMAGE }}:${{ steps.meta.outputs.version }}
|
|
build-args: |
|
|
PNPM_VERSION=${{ steps.meta.outputs.version }}
|
|
PNPM_SHA256_AMD64=${{ steps.checksums.outputs.sha_amd64 }}
|
|
PNPM_SHA256_ARM64=${{ steps.checksums.outputs.sha_arm64 }}
|
|
provenance: mode=max
|
|
sbom: true
|
|
|
|
- name: Build and push Alpine
|
|
if: steps.checksums.outputs.alpine == 'true'
|
|
uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0
|
|
with:
|
|
context: ./docker
|
|
file: ./docker/Dockerfile.alpine
|
|
platforms: linux/amd64,linux/arm64
|
|
push: true
|
|
tags: ${{ env.IMAGE }}:${{ steps.meta.outputs.version }}-alpine
|
|
build-args: |
|
|
PNPM_VERSION=${{ steps.meta.outputs.version }}
|
|
PNPM_SHA256_AMD64=${{ steps.checksums.outputs.sha_musl_amd64 }}
|
|
PNPM_SHA256_ARM64=${{ steps.checksums.outputs.sha_musl_arm64 }}
|
|
provenance: mode=max
|
|
sbom: true
|
|
|
|
# Runs after the builds so that every release published in the same
|
|
# burst is listed by the time this run decides which tags it may move.
|
|
- name: Move mutable tags
|
|
if: steps.meta.outputs.prerelease != 'true'
|
|
env:
|
|
VERSION: ${{ steps.meta.outputs.version }}
|
|
ALPINE: ${{ steps.checksums.outputs.alpine }}
|
|
GH_TOKEN: ${{ github.token }}
|
|
run: |
|
|
set -euo pipefail
|
|
releases="$(gh api --paginate "repos/${GITHUB_REPOSITORY}/releases?per_page=100" \
|
|
--jq '.[] | select(.draft == false and .prerelease == false) | .tag_name')"
|
|
moves="$(.github/scripts/docker-image-tags.sh "$IMAGE" "$VERSION" "$ALPINE" <<< "$releases")"
|
|
while read -r target source; do
|
|
[ -n "$target" ] || continue
|
|
docker buildx imagetools create --tag "$target" "$source"
|
|
done <<< "$moves"
|