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 (#340)
* 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>
This commit is contained in:
parent
b92be13bc6
commit
d2f9b5c5fb
3 changed files with 112 additions and 1 deletions
103
.github/workflows/publish-image.yml
vendored
Normal file
103
.github/workflows/publish-image.yml
vendored
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
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"
|
||||
|
|
@ -12,3 +12,4 @@
|
|||
- **release-edge.yml**: on every push to main, retags `edge`, builds Linux x86_64 / Linux arm64 / macOS arm64 archives and Windows x86_64 zip + sha256, publishes a rolling prerelease, then smoke-tests the Windows PowerShell installer against `edge`.
|
||||
- **release.yml**: on `v*` tags, builds the Linux x86_64 / Linux arm64 / macOS arm64 archives and Windows x86_64 zip release matrix, updates the Homebrew tap (`scripts/update-homebrew-formula.sh`) by pushing the regenerated formula to `ModernRelay/homebrew-tap`, and smoke-tests the Windows PowerShell installer against the tag.
|
||||
- **package.yml**: manual ECR image build; emits two image tags per commit (`<sha>`, `<sha>-aws`) via CodeBuild.
|
||||
- **publish-image.yml**: builds and pushes the public `omnigraph-server` container image to GHCR (`ghcr.io/modernrelay/omnigraph-server:<tag>`) on `v*` tag pushes, plus manual `workflow_dispatch` with an explicit existing `v*` tag to backfill an image for a past release. Compiles the binaries inside a `rust:1-bookworm` builder container to match the Dockerfile's bookworm-slim runtime glibc (host-built ubuntu binaries do not run there), builds with `--features omnigraph-server/aws`, and moves `latest` only on real tag pushes — never on backfill dispatches. Separate from release.yml so an image-publish failure cannot block the binary release / Homebrew chain.
|
||||
|
|
|
|||
|
|
@ -172,7 +172,14 @@ endpoint and credentials. CI exercises this path against containerized RustFS.
|
|||
|
||||
## Container Deployment
|
||||
|
||||
Build the image:
|
||||
Pull the prebuilt public image (published to GHCR for every `v*` release by
|
||||
`publish-image.yml`; built with the `aws` feature, linux/amd64):
|
||||
|
||||
```bash
|
||||
docker pull ghcr.io/modernrelay/omnigraph-server:v0.8.1
|
||||
```
|
||||
|
||||
Or build it yourself:
|
||||
|
||||
```bash
|
||||
docker build -t omnigraph-server:local .
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue