Skip to content

container-image

container-image #57

name: Container Image
on:
# Release commits skip the ordinary main build. Tagged releases arrive through
# repository_dispatch while exact-SHA public CI is verified after publication.
push:
branches:
- main
repository_dispatch:
types:
- container-image
workflow_dispatch:
inputs:
push_ghcr:
description: "Publish to GHCR with GHCR_TOKEN or github.token"
type: boolean
default: true
push_dockerhub:
description: "Publish the Docker Hub mirrors when credentials are configured"
type: boolean
default: true
env:
GHCR_IMAGE: ghcr.io/corgicorner/bisibility
GHCR_WORKER_IMAGE: ghcr.io/corgicorner/bisibility-worker
DOCKERHUB_IMAGE: docker.io/corgicorner/bisibility
DOCKERHUB_WORKER_IMAGE: docker.io/corgicorner/bisibility-worker
jobs:
prepare:
name: Prepare image metadata
if: github.repository == 'CorgiCorner/bisibility' && (github.event_name != 'push' || !startsWith(github.event.head_commit.message, 'chore(release):'))
runs-on: ${{ github.repository != 'CorgiCorner/bisibility' && vars.CI_USE_DEPOT == 'true' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
timeout-minutes: 10
permissions:
actions: read
contents: read
packages: write
outputs:
ghcr_enabled: ${{ steps.registries.outputs.ghcr_enabled }}
dockerhub_enabled: ${{ steps.registries.outputs.dockerhub_enabled }}
version: ${{ steps.version.outputs.version }}
source_sha: ${{ steps.version.outputs.source_sha }}
web_labels: ${{ steps.web-meta.outputs.labels }}
worker_labels: ${{ steps.worker-meta.outputs.labels }}
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
ref: ${{ github.event_name == 'repository_dispatch' && github.event.client_payload.public_sha || github.sha }}
- name: Resolve image version
id: version
env:
DISPATCH_VERSION: ${{ github.event.client_payload.version }}
DISPATCH_MINOR: ${{ github.event.client_payload.minor }}
DISPATCH_MAJOR: ${{ github.event.client_payload.major }}
DISPATCH_ORIGIN_SHA: ${{ github.event.client_payload.origin_sha }}
DISPATCH_PUBLIC_SHA: ${{ github.event.client_payload.public_sha }}
run: |
package_version="$(node -p "require('./package.json').version")"
version="${DISPATCH_VERSION:-$package_version}"
source_sha="${DISPATCH_PUBLIC_SHA:-$GITHUB_SHA}"
if [ "${GITHUB_EVENT_NAME}" = "repository_dispatch" ] && [ -z "${DISPATCH_PUBLIC_SHA}" ]; then
echo "::error::repository_dispatch requires client_payload.public_sha."
exit 1
fi
if [ "${GITHUB_EVENT_NAME}" = "repository_dispatch" ] && [ -z "${DISPATCH_ORIGIN_SHA}" ]; then
echo "::error::repository_dispatch requires client_payload.origin_sha."
exit 1
fi
if [ "${GITHUB_EVENT_NAME}" = "repository_dispatch" ] \
&& ! [[ "${DISPATCH_ORIGIN_SHA}" =~ ^[0-9a-f]{40}$ ]]; then
echo "::error::Origin commit is not a full Git SHA: ${DISPATCH_ORIGIN_SHA}"
exit 1
fi
if ! [[ "$source_sha" =~ ^[0-9a-f]{40}$ ]]; then
echo "::error::Source commit is not a full Git SHA: $source_sha"
exit 1
fi
if [ "$(git rev-parse HEAD)" != "$source_sha" ]; then
echo "::error::Checkout does not match source commit $source_sha."
exit 1
fi
if [ "${GITHUB_EVENT_NAME}" = "repository_dispatch" ] && [ "$version" != "$package_version" ]; then
echo "::error::Dispatched version $version does not match package.json $package_version."
exit 1
fi
if ! [[ "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+([+-][0-9A-Za-z.-]+)?$ ]]; then
echo "::error::Image version is not valid SemVer: $version"
exit 1
fi
expected_minor="${version%.*}"
expected_major="${version%%.*}"
if [ "${GITHUB_EVENT_NAME}" = "repository_dispatch" ] \
&& { [ "${DISPATCH_MINOR}" != "$expected_minor" ] || [ "${DISPATCH_MAJOR}" != "$expected_major" ]; }; then
echo "::error::Dispatched major/minor tags do not match version $version."
exit 1
fi
echo "version=$version" >> "$GITHUB_OUTPUT"
echo "source_sha=$source_sha" >> "$GITHUB_OUTPUT"
- name: Verify published public release source
if: github.event_name == 'repository_dispatch'
env:
GITHUB_TOKEN: ${{ github.token }}
ORIGIN_SHA: ${{ github.event.client_payload.origin_sha }}
PUBLIC_SHA: ${{ steps.version.outputs.source_sha }}
RELEASE_TAG: v${{ steps.version.outputs.version }}
run: >-
node scripts/ci/verify-public-release-source.mjs
--repo "$GITHUB_REPOSITORY"
--sha "$PUBLIC_SHA"
--tag "$RELEASE_TAG"
--origin-sha "$ORIGIN_SHA"
--source-only
- name: Select registries
id: registries
env:
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
PUSH_GHCR_INPUT: ${{ inputs.push_ghcr }}
PUSH_DOCKERHUB_INPUT: ${{ inputs.push_dockerhub }}
run: |
set -euo pipefail
if [ "${GITHUB_EVENT_NAME}" = "workflow_dispatch" ] && [ "${PUSH_GHCR_INPUT}" = "false" ] \
&& [ "${PUSH_DOCKERHUB_INPUT}" = "false" ]; then
echo "::error::No container registry is enabled for this run."
exit 1
fi
if [ "${GITHUB_EVENT_NAME}" != "workflow_dispatch" ] || [ "${PUSH_GHCR_INPUT}" != "false" ]; then
echo "ghcr_enabled=true" >> "$GITHUB_OUTPUT"
else
echo "ghcr_enabled=false" >> "$GITHUB_OUTPUT"
fi
if { [ "${GITHUB_EVENT_NAME}" != "workflow_dispatch" ] || [ "${PUSH_DOCKERHUB_INPUT}" != "false" ]; } \
&& [ -n "${DOCKERHUB_USERNAME}" ] && [ -n "${DOCKERHUB_TOKEN}" ]; then
echo "dockerhub_enabled=true" >> "$GITHUB_OUTPUT"
elif [ "${GITHUB_EVENT_NAME}" != "workflow_dispatch" ] || [ "${PUSH_DOCKERHUB_INPUT}" != "false" ]; then
if [ "${GITHUB_EVENT_NAME}" = "repository_dispatch" ]; then
echo "::error::Docker Hub credentials are required for release publication."
exit 1
fi
echo "::notice::Skipping Docker Hub because DOCKERHUB_USERNAME or DOCKERHUB_TOKEN is not configured."
echo "dockerhub_enabled=false" >> "$GITHUB_OUTPUT"
else
echo "dockerhub_enabled=false" >> "$GITHUB_OUTPUT"
fi
- name: Extract web metadata
id: web-meta
uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6
with:
images: ${{ env.GHCR_IMAGE }}
labels: |
org.opencontainers.image.title=bisibility
org.opencontainers.image.description=Open-source search visibility platform
org.opencontainers.image.licenses=AGPL-3.0-only
org.opencontainers.image.url=https://bisibility.com
org.opencontainers.image.source=https://github.com/CorgiCorner/bisibility
org.opencontainers.image.documentation=https://bisibility.com/docs/self-hosting
org.opencontainers.image.version=${{ steps.version.outputs.version }}
org.opencontainers.image.revision=${{ steps.version.outputs.source_sha }}
- name: Extract worker metadata
id: worker-meta
uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6
with:
images: ${{ env.GHCR_WORKER_IMAGE }}
labels: |
org.opencontainers.image.title=bisibility worker
org.opencontainers.image.description=Temporal worker for bisibility
org.opencontainers.image.licenses=AGPL-3.0-only
org.opencontainers.image.url=https://bisibility.com
org.opencontainers.image.source=https://github.com/CorgiCorner/bisibility
org.opencontainers.image.documentation=https://bisibility.com/docs/self-hosting
org.opencontainers.image.version=${{ steps.version.outputs.version }}
org.opencontainers.image.revision=${{ steps.version.outputs.source_sha }}
build:
name: Build ${{ matrix.image.registry }} ${{ matrix.image.runtime }} ${{ matrix.platform.arch }}
if: github.repository == 'CorgiCorner/bisibility'
needs: prepare
strategy:
fail-fast: false
matrix:
image:
- registry: ghcr
host: ghcr.io
runtime: web
image: ghcr.io/corgicorner/bisibility
package: bisibility
dockerfile: Dockerfile
- registry: ghcr
host: ghcr.io
runtime: worker
image: ghcr.io/corgicorner/bisibility-worker
package: bisibility-worker
dockerfile: Dockerfile.worker
- registry: dockerhub
host: docker.io
runtime: web
image: docker.io/corgicorner/bisibility
package: bisibility
dockerfile: Dockerfile
- registry: dockerhub
host: docker.io
runtime: worker
image: docker.io/corgicorner/bisibility-worker
package: bisibility-worker
dockerfile: Dockerfile.worker
platform:
- arch: amd64
value: linux/amd64
runner: ${{ github.repository != 'CorgiCorner/bisibility' && vars.CI_USE_DEPOT == 'true' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
- arch: arm64
value: linux/arm64
runner: ${{ github.repository != 'CorgiCorner/bisibility' && vars.CI_USE_DEPOT == 'true' && 'depot-ubuntu-24.04-arm' || 'ubuntu-24.04-arm' }}
runs-on: ${{ matrix.platform.runner }}
timeout-minutes: 90
permissions:
contents: read
packages: write
steps:
- name: Checkout
if: (matrix.image.registry == 'ghcr' && needs.prepare.outputs.ghcr_enabled == 'true') || (matrix.image.registry == 'dockerhub' && needs.prepare.outputs.dockerhub_enabled == 'true')
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
ref: ${{ needs.prepare.outputs.source_sha }}
- name: Set up Docker Buildx
if: (matrix.image.registry == 'ghcr' && needs.prepare.outputs.ghcr_enabled == 'true') || (matrix.image.registry == 'dockerhub' && needs.prepare.outputs.dockerhub_enabled == 'true')
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4
- name: Log in to registry
if: (matrix.image.registry == 'ghcr' && needs.prepare.outputs.ghcr_enabled == 'true') || (matrix.image.registry == 'dockerhub' && needs.prepare.outputs.dockerhub_enabled == 'true')
uses: docker/login-action@abd2ef45e78c5afb21d64d4ca52ee8550d9572c7 # v4
with:
registry: ${{ matrix.image.host }}
username: ${{ matrix.image.registry == 'ghcr' && (secrets.GHCR_USERNAME || github.actor) || secrets.DOCKERHUB_USERNAME }}
password: ${{ matrix.image.registry == 'ghcr' && (secrets.GHCR_TOKEN || github.token) || secrets.DOCKERHUB_TOKEN }}
- name: Build and push image digest
if: (matrix.image.registry == 'ghcr' && needs.prepare.outputs.ghcr_enabled == 'true') || (matrix.image.registry == 'dockerhub' && needs.prepare.outputs.dockerhub_enabled == 'true')
id: build
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7
with:
context: .
file: ${{ matrix.image.dockerfile }}
platforms: ${{ matrix.platform.value }}
build-args: |
APP_VERSION=${{ needs.prepare.outputs.source_sha }}
APP_REVISION=${{ needs.prepare.outputs.source_sha }}
labels: ${{ matrix.image.runtime == 'web' && needs.prepare.outputs.web_labels || needs.prepare.outputs.worker_labels }}
outputs: type=image,name=${{ matrix.image.image }},push-by-digest=true,name-canonical=true,push=true
cache-from: type=gha,scope=public-${{ matrix.image.runtime }}-${{ matrix.platform.arch }}
cache-to: type=gha,mode=max,scope=public-${{ matrix.image.runtime }}-${{ matrix.platform.arch }}
- name: Export digest
if: (matrix.image.registry == 'ghcr' && needs.prepare.outputs.ghcr_enabled == 'true') || (matrix.image.registry == 'dockerhub' && needs.prepare.outputs.dockerhub_enabled == 'true')
run: |
mkdir -p "$RUNNER_TEMP/digests"
digest="${{ steps.build.outputs.digest }}"
touch "$RUNNER_TEMP/digests/${digest#sha256:}"
- name: Upload digest
if: (matrix.image.registry == 'ghcr' && needs.prepare.outputs.ghcr_enabled == 'true') || (matrix.image.registry == 'dockerhub' && needs.prepare.outputs.dockerhub_enabled == 'true')
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: digests-${{ matrix.image.registry }}-${{ matrix.image.runtime }}-${{ matrix.platform.arch }}
path: ${{ runner.temp }}/digests/*
if-no-files-found: error
retention-days: 1
merge:
name: Publish ${{ matrix.image.registry }} ${{ matrix.image.runtime }} manifest
if: github.repository == 'CorgiCorner/bisibility'
needs:
- prepare
- build
strategy:
fail-fast: false
matrix:
image:
- registry: ghcr
host: ghcr.io
runtime: web
image: ghcr.io/corgicorner/bisibility
package: bisibility
- registry: ghcr
host: ghcr.io
runtime: worker
image: ghcr.io/corgicorner/bisibility-worker
package: bisibility-worker
- registry: dockerhub
host: docker.io
runtime: web
image: docker.io/corgicorner/bisibility
package: bisibility
- registry: dockerhub
host: docker.io
runtime: worker
image: docker.io/corgicorner/bisibility-worker
package: bisibility-worker
runs-on: ${{ github.repository != 'CorgiCorner/bisibility' && vars.CI_USE_DEPOT == 'true' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
timeout-minutes: 20
permissions:
contents: read
packages: write
steps:
- name: Set up Docker Buildx
if: (matrix.image.registry == 'ghcr' && needs.prepare.outputs.ghcr_enabled == 'true') || (matrix.image.registry == 'dockerhub' && needs.prepare.outputs.dockerhub_enabled == 'true')
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4
- name: Log in to registry
if: (matrix.image.registry == 'ghcr' && needs.prepare.outputs.ghcr_enabled == 'true') || (matrix.image.registry == 'dockerhub' && needs.prepare.outputs.dockerhub_enabled == 'true')
uses: docker/login-action@abd2ef45e78c5afb21d64d4ca52ee8550d9572c7 # v4
with:
registry: ${{ matrix.image.host }}
username: ${{ matrix.image.registry == 'ghcr' && (secrets.GHCR_USERNAME || github.actor) || secrets.DOCKERHUB_USERNAME }}
password: ${{ matrix.image.registry == 'ghcr' && (secrets.GHCR_TOKEN || github.token) || secrets.DOCKERHUB_TOKEN }}
- name: Download digests
if: (matrix.image.registry == 'ghcr' && needs.prepare.outputs.ghcr_enabled == 'true') || (matrix.image.registry == 'dockerhub' && needs.prepare.outputs.dockerhub_enabled == 'true')
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
path: ${{ runner.temp }}/digests
pattern: digests-${{ matrix.image.registry }}-${{ matrix.image.runtime }}-*
merge-multiple: true
- name: Create and push multi-arch manifest
if: (matrix.image.registry == 'ghcr' && needs.prepare.outputs.ghcr_enabled == 'true') || (matrix.image.registry == 'dockerhub' && needs.prepare.outputs.dockerhub_enabled == 'true')
working-directory: ${{ runner.temp }}/digests
env:
IMAGE_NAME: ${{ matrix.image.image }}
RELEASE_VERSION: ${{ github.event.client_payload.version }}
RELEASE_MINOR: ${{ github.event.client_payload.minor }}
RELEASE_MAJOR: ${{ github.event.client_payload.major }}
SOURCE_SHA: ${{ needs.prepare.outputs.source_sha }}
run: |
tag_names=()
if [ "${GITHUB_EVENT_NAME}" = "repository_dispatch" ]; then
tag_names+=("${RELEASE_VERSION}" "${RELEASE_MINOR}" "${RELEASE_MAJOR}" "latest" "edge")
elif [ "${GITHUB_REF}" = "refs/heads/main" ]; then
tag_names+=("edge")
fi
tag_names+=("sha-${SOURCE_SHA::7}")
tag_args=()
for tag in "${tag_names[@]}"; do
tag_args+=("-t" "${IMAGE_NAME}:${tag}")
done
source_args=()
for digest in *; do
source_args+=("${IMAGE_NAME}@sha256:${digest}")
done
docker buildx imagetools create "${tag_args[@]}" "${source_args[@]}"
- name: Make GHCR package public
if: matrix.image.registry == 'ghcr' && needs.prepare.outputs.ghcr_enabled == 'true'
env:
GH_TOKEN: ${{ secrets.GHCR_TOKEN || github.token }}
PACKAGE_NAME: ${{ matrix.image.package }}
run: |
if ! gh api --method PATCH \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"/orgs/corgicorner/packages/container/${PACKAGE_NAME}/visibility" \
-f visibility=public; then
echo "::notice::GHCR visibility update was unavailable; anonymous pull verification remains authoritative."
fi
- name: Verify anonymous pull access
if: (matrix.image.registry == 'ghcr' && needs.prepare.outputs.ghcr_enabled == 'true') || (matrix.image.registry == 'dockerhub' && needs.prepare.outputs.dockerhub_enabled == 'true')
env:
IMAGE_NAME: ${{ matrix.image.image }}
SOURCE_SHA: ${{ needs.prepare.outputs.source_sha }}
run: |
docker logout "${{ matrix.image.host }}"
for ((attempt = 1; attempt <= 5; attempt++)); do
if docker buildx imagetools inspect "${IMAGE_NAME}:sha-${SOURCE_SHA::7}" >/dev/null; then
exit 0
fi
sleep 5
done
echo "::error::Published image is not anonymously pullable: ${IMAGE_NAME}:sha-${SOURCE_SHA::7}"
exit 1
verify-release:
name: Verify release distribution
if: >-
github.repository == 'CorgiCorner/bisibility' &&
github.event_name == 'repository_dispatch' &&
needs.prepare.result == 'success' &&
needs.build.result == 'success' &&
needs.merge.result == 'success'
needs:
- prepare
- build
- merge
runs-on: ${{ github.repository != 'CorgiCorner/bisibility' && vars.CI_USE_DEPOT == 'true' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
timeout-minutes: 10
permissions:
contents: read
steps:
- name: Checkout public release
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
ref: ${{ needs.prepare.outputs.source_sha }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4
- name: Verify manifest against published images
run: |
mkdir -p "$RUNNER_TEMP/release-assets"
cp compose.yaml "$RUNNER_TEMP/release-assets/"
cp compose.worker.yaml "$RUNNER_TEMP/release-assets/"
cp compose.temporal.yaml "$RUNNER_TEMP/release-assets/"
cp docker-compose.self-host.yml "$RUNNER_TEMP/release-assets/"
cp .env.example "$RUNNER_TEMP/release-assets/bisibility.env.example"
cp scripts/self-host/generate-env.mjs "$RUNNER_TEMP/release-assets/generate-self-host-env.mjs"
cp upgrade.sh "$RUNNER_TEMP/release-assets/"
node scripts/distribution/verify.mjs \
--manifest distribution-manifest.json \
--artifacts-dir "$RUNNER_TEMP/release-assets" \
--revision "${{ needs.prepare.outputs.source_sha }}"
publish-release:
name: Publish immutable release assets
if: >-
github.repository == 'CorgiCorner/bisibility' &&
github.event_name == 'repository_dispatch' &&
needs.verify-release.result == 'success'
needs:
- prepare
- verify-release
runs-on: ${{ github.repository != 'CorgiCorner/bisibility' && vars.CI_USE_DEPOT == 'true' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
timeout-minutes: 10
permissions:
contents: write
steps:
- name: Checkout public release
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
ref: ${{ needs.prepare.outputs.source_sha }}
- name: Stage immutable release assets
run: |
mkdir -p "$RUNNER_TEMP/release-assets"
cp compose.yaml "$RUNNER_TEMP/release-assets/"
cp compose.worker.yaml "$RUNNER_TEMP/release-assets/"
cp compose.temporal.yaml "$RUNNER_TEMP/release-assets/"
cp docker-compose.self-host.yml "$RUNNER_TEMP/release-assets/"
cp .env.example "$RUNNER_TEMP/release-assets/bisibility.env.example"
cp scripts/self-host/generate-env.mjs "$RUNNER_TEMP/release-assets/generate-self-host-env.mjs"
cp upgrade.sh "$RUNNER_TEMP/release-assets/"
cp distribution-manifest.json "$RUNNER_TEMP/release-assets/"
- name: Publish immutable release assets
env:
GH_TOKEN: ${{ github.token }}
RELEASE_TAG: v${{ github.event.client_payload.version }}
run: |
set -euo pipefail
assets=(
compose.yaml
compose.worker.yaml
compose.temporal.yaml
docker-compose.self-host.yml
bisibility.env.example
generate-self-host-env.mjs
upgrade.sh
distribution-manifest.json
)
if gh release view "$RELEASE_TAG" >/dev/null 2>&1; then
mkdir -p "$RUNNER_TEMP/published-assets"
for asset in "${assets[@]}"; do
gh release download "$RELEASE_TAG" \
--pattern "$asset" \
--dir "$RUNNER_TEMP/published-assets"
cmp "$RUNNER_TEMP/release-assets/$asset" "$RUNNER_TEMP/published-assets/$asset"
done
echo "Release assets already exist and match byte-for-byte."
exit 0
fi
gh release create "$RELEASE_TAG" \
"$RUNNER_TEMP/release-assets/compose.yaml" \
"$RUNNER_TEMP/release-assets/compose.worker.yaml" \
"$RUNNER_TEMP/release-assets/compose.temporal.yaml" \
"$RUNNER_TEMP/release-assets/docker-compose.self-host.yml" \
"$RUNNER_TEMP/release-assets/bisibility.env.example" \
"$RUNNER_TEMP/release-assets/generate-self-host-env.mjs" \
"$RUNNER_TEMP/release-assets/upgrade.sh" \
"$RUNNER_TEMP/release-assets/distribution-manifest.json" \
--verify-tag \
--generate-notes \
--title "$RELEASE_TAG"
sync-dockerhub-descriptions:
name: Sync Docker Hub descriptions
if: >-
github.repository == 'CorgiCorner/bisibility' &&
github.event_name == 'repository_dispatch' &&
needs.prepare.outputs.dockerhub_enabled == 'true' &&
needs.publish-release.result == 'success'
needs:
- prepare
- publish-release
concurrency:
group: dockerhub-description-sync
cancel-in-progress: false
runs-on: ${{ github.repository != 'CorgiCorner/bisibility' && vars.CI_USE_DEPOT == 'true' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
timeout-minutes: 10
permissions:
contents: read
steps:
- name: Checkout dispatched public release
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
ref: ${{ needs.prepare.outputs.source_sha }}
- name: Set up Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v6
with:
node-version-file: .nvmrc
- name: Update and verify Docker Hub descriptions
env:
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
GITHUB_TOKEN: ${{ github.token }}
RELEASE_TAG: v${{ github.event.client_payload.version }}
run: node .github/scripts/sync-dockerhub-descriptions.mjs --version "$RELEASE_TAG"