mirror of
https://github.com/ModernRelay/omnigraph.git
synced 2026-07-12 03:12:11 +02:00
* feat(ci): publish omnigraph-server container image to GHCR on release Build binaries inside a rust:1-bookworm container (matching the Dockerfile's bookworm-slim runtime glibc) with the aws feature enabled, then build and push ghcr.io/<owner>/omnigraph-server:<tag>. Separate from release.yml so an image failure never blocks the binary release, and a workflow_dispatch backfill of a past tag never re-runs the release matrix or repoints :latest. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * review fixes: validate dispatch tag (existing v* only), document workflow + GHCR image - Guard workflow_dispatch: the free-form tag input must name an EXISTING v* tag (gh api ref check) and checkout is pinned to refs/tags/<tag>, so a branch/SHA can never be published under a release-looking image tag (greptile P1). - docs/dev/ci.md: add the publish-image.yml entry (same-PR docs rule). - docs/user/deployment.md: document pulling the prebuilt GHCR image. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
103 lines
4 KiB
YAML
103 lines
4 KiB
YAML
name: Publish container image
|
|
|
|
# Build and publish the omnigraph-server container image to GHCR so
|
|
# downstream deployments can pull it without building from source.
|
|
#
|
|
# Kept separate from release.yml on purpose: an image-publish failure must
|
|
# not block the binary release / Homebrew chain, and a manual backfill of an
|
|
# old tag must not re-run the four-platform release matrix.
|
|
#
|
|
# Triggers (same dual pattern as release.yml):
|
|
# - push of a v* tag (normal release)
|
|
# - workflow_dispatch with an explicit `tag` (publish an image for a past
|
|
# tag; resolves the same `${{ inputs.tag || github.ref_name }}`)
|
|
#
|
|
# The binaries are compiled inside a rust:1-bookworm container, NOT on the
|
|
# runner host: the Dockerfile's runtime base is debian bookworm-slim
|
|
# (glibc 2.36), and binaries built on ubuntu-latest (glibc 2.39) do not run
|
|
# there. Builder and runtime must share the same distro release.
|
|
|
|
on:
|
|
push:
|
|
tags:
|
|
- "v*"
|
|
workflow_dispatch:
|
|
inputs:
|
|
tag:
|
|
description: "Tag to publish an image for (e.g. v0.8.1). Required for manual dispatches."
|
|
required: true
|
|
type: string
|
|
|
|
jobs:
|
|
publish_image:
|
|
name: Build and push image
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
contents: read
|
|
packages: write
|
|
env:
|
|
RELEASE_TAG: ${{ inputs.tag || github.ref_name }}
|
|
steps:
|
|
# The dispatch `tag` input is free-form; without this guard a dispatcher
|
|
# could pass a branch name or SHA and publish non-release code under a
|
|
# release-looking image tag. Require an existing v* tag ref.
|
|
- name: Validate dispatch tag
|
|
if: github.event_name == 'workflow_dispatch'
|
|
env:
|
|
GH_TOKEN: ${{ github.token }}
|
|
run: |
|
|
[[ "${RELEASE_TAG}" == v* ]] \
|
|
|| { echo "tag must be a v* release tag, got: ${RELEASE_TAG}" >&2; exit 1; }
|
|
gh api "repos/${GITHUB_REPOSITORY}/git/ref/tags/${RELEASE_TAG}" >/dev/null \
|
|
|| { echo "no such tag: ${RELEASE_TAG}" >&2; exit 1; }
|
|
|
|
- name: Checkout source
|
|
uses: actions/checkout@v5.0.1
|
|
with:
|
|
# Fully qualified so a branch of the same name can never shadow the tag.
|
|
ref: refs/tags/${{ env.RELEASE_TAG }}
|
|
|
|
- name: Build release binaries (bookworm builder)
|
|
run: |
|
|
docker run --rm -v "$PWD:/work" -w /work rust:1-bookworm bash -euxc '
|
|
apt-get update
|
|
apt-get install -y --no-install-recommends protobuf-compiler libprotobuf-dev
|
|
# --features omnigraph-server/aws: include the AWS Secrets Manager
|
|
# bearer-token source so one public image serves both token modes.
|
|
cargo build --release --locked -p omnigraph-cli -p omnigraph-server --features omnigraph-server/aws
|
|
'
|
|
|
|
- name: Log in to GHCR
|
|
run: |
|
|
echo "${{ secrets.GITHUB_TOKEN }}" \
|
|
| docker login ghcr.io --username "${{ github.actor }}" --password-stdin
|
|
|
|
- name: Build and push image
|
|
run: |
|
|
owner="${GITHUB_REPOSITORY_OWNER,,}"
|
|
image="ghcr.io/${owner}/omnigraph-server"
|
|
docker build -t "${image}:${RELEASE_TAG}" .
|
|
docker push "${image}:${RELEASE_TAG}"
|
|
|
|
# Move `latest` only on real tag pushes — a dispatch backfill of an
|
|
# old tag must not repoint `latest` at it.
|
|
if [[ "${GITHUB_EVENT_NAME}" == "push" ]]; then
|
|
docker tag "${image}:${RELEASE_TAG}" "${image}:latest"
|
|
docker push "${image}:latest"
|
|
fi
|
|
|
|
- name: Report pinned digest
|
|
run: |
|
|
owner="${GITHUB_REPOSITORY_OWNER,,}"
|
|
image="ghcr.io/${owner}/omnigraph-server"
|
|
digest=$(docker inspect --format='{{index .RepoDigests 0}}' "${image}:${RELEASE_TAG}")
|
|
{
|
|
echo "## Container image published"
|
|
echo
|
|
echo '```'
|
|
echo "${image}:${RELEASE_TAG}"
|
|
echo "${digest}"
|
|
echo '```'
|
|
echo
|
|
echo "Pin deployments to the digest form."
|
|
} >> "$GITHUB_STEP_SUMMARY"
|