Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 45 additions & 30 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@ permissions: {}
env:
CARGO_TERM_COLOR: always
NIGHTLY_RUSTFMT: nightly-2026-03-28
AI_ROLLUP_IMAGE_NAME: ghcr.io/praxis-proxy/grid-ai-rollup
AI_ROLLUP_SOURCE_SHA: c68149502d991d51daaff8d6bf96c18704aeb38d
OFFICIAL_AI_IMAGE_NAME: ghcr.io/praxis-proxy/ai
OFFICIAL_AI_IMAGE_TAG: 0.3.0
OFFICIAL_AI_IMAGE_DIGEST: sha256:ccd46f8772eebcbde2f41ad35c3234d23463b8314a5865083e32baf31eddd1a8
OFFICIAL_AI_SOURCE_SHA: b44360afb4100c5543b1180ac8df16e482978fc8
OPERATOR_IMAGE_NAME: ghcr.io/praxis-proxy/grid-operator
MOCK_PROVIDERS_IMAGE_NAME: ghcr.io/praxis-proxy/grid-mock-providers
OVERLAY_SYNC_IMAGE_NAME: ghcr.io/praxis-proxy/grid-overlay-sync
Expand Down Expand Up @@ -138,7 +140,7 @@ jobs:
operator_digest: ${{ steps.operator.outputs.digest }}
mock_providers_digest: ${{ steps.mock_providers.outputs.digest }}
overlay_sync_digest: ${{ steps.overlay_sync.outputs.digest }}
ai_rollup_digest: ${{ steps.ai_rollup.outputs.digest }}
official_ai_digest: ${{ steps.official_ai.outputs.digest }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
Expand All @@ -155,32 +157,33 @@ jobs:
username: ${{ github.actor }}
password: ${{ github.token }}

- name: Verify official Grid AI rollup
id: ai_rollup
env:
TAG: ${{ needs.validate.outputs.tag }}
- name: Verify official Praxis AI image
id: official_ai
run: |
set -euo pipefail
RELEASE_REF="${AI_ROLLUP_IMAGE_NAME}:${TAG}"
SOURCE_REF="${AI_ROLLUP_IMAGE_NAME}:sha-${AI_ROLLUP_SOURCE_SHA}"
RELEASE_DIGEST=$(docker buildx imagetools inspect "${RELEASE_REF}" \
--format '{{.Manifest.Digest}}')
SOURCE_DIGEST=$(docker buildx imagetools inspect "${SOURCE_REF}" \
--format '{{.Manifest.Digest}}')
if [[ ! "${RELEASE_DIGEST}" =~ ^sha256:[0-9a-f]{64}$ || \
! "${SOURCE_DIGEST}" =~ ^sha256:[0-9a-f]{64}$ ]]; then
echo "::error::Could not resolve official AI rollup digests"
IMAGE_REF="${OFFICIAL_AI_IMAGE_NAME}:${OFFICIAL_AI_IMAGE_TAG}"
DIGEST=$(docker buildx imagetools inspect "${IMAGE_REF}" | awk '$1 == "Digest:" { print $2; exit }')
if [[ ! "${DIGEST}" =~ ^sha256:[0-9a-f]{64}$ ]]; then
echo "::error::Could not resolve official AI image digest"
exit 1
fi
if [[ "${DIGEST}" != "${OFFICIAL_AI_IMAGE_DIGEST}" ]]; then
echo "::error::Official AI tag no longer resolves to the pinned digest"
exit 1
fi
if [[ "${RELEASE_DIGEST}" != "${SOURCE_DIGEST}" ]]; then
echo "::error::Official AI rollup tags resolve to different digests"
echo "::error::${RELEASE_REF}: ${RELEASE_DIGEST}"
echo "::error::${SOURCE_REF}: ${SOURCE_DIGEST}"
IMMUTABLE_REF="${OFFICIAL_AI_IMAGE_NAME}@${DIGEST}"
docker pull "${IMMUTABLE_REF}"
SOURCE=$(docker image inspect "${IMMUTABLE_REF}" --format '{{index .Config.Labels "org.opencontainers.image.source"}}')
REVISION=$(docker image inspect "${IMMUTABLE_REF}" --format '{{index .Config.Labels "org.opencontainers.image.revision"}}')
VERSION=$(docker image inspect "${IMMUTABLE_REF}" --format '{{index .Config.Labels "org.opencontainers.image.version"}}')
if [[ "${SOURCE}" != "https://github.com/praxis-proxy/ai" || \
"${REVISION}" != "${OFFICIAL_AI_SOURCE_SHA}" || \
"${VERSION}" != "${OFFICIAL_AI_IMAGE_TAG}" ]]; then
echo "::error::Official AI image provenance does not match the pinned release"
exit 1
fi
echo "digest=${RELEASE_DIGEST}" >> "${GITHUB_OUTPUT}"
echo "Verified ${RELEASE_REF}@${RELEASE_DIGEST}"
echo "Verified ${SOURCE_REF}@${SOURCE_DIGEST}"
echo "digest=${DIGEST}" >> "${GITHUB_OUTPUT}"
echo "Verified ${IMAGE_REF}@${DIGEST} (${REVISION})"

- name: Build and push operator
id: operator
Expand Down Expand Up @@ -275,8 +278,12 @@ jobs:
echo "::error::${chart} version ($CHART_VERSION) != tag version ($VERSION)"
exit 1
fi
if [ "$CHART_APP_VERSION" != "$TAG" ]; then
echo "::error::${chart} appVersion ($CHART_APP_VERSION) != release tag ($TAG)"
EXPECTED_APP_VERSION="$TAG"
if [ "$chart" = praxis-gateway ]; then
EXPECTED_APP_VERSION="$OFFICIAL_AI_IMAGE_TAG"
fi
if [ "$CHART_APP_VERSION" != "$EXPECTED_APP_VERSION" ]; then
echo "::error::${chart} appVersion ($CHART_APP_VERSION) != expected application version ($EXPECTED_APP_VERSION)"
exit 1
fi
done
Expand Down Expand Up @@ -345,7 +352,7 @@ jobs:
OPERATOR_DIGEST: ${{ needs.container.outputs.operator_digest }}
MOCK_PROVIDERS_DIGEST: ${{ needs.container.outputs.mock_providers_digest }}
OVERLAY_SYNC_DIGEST: ${{ needs.container.outputs.overlay_sync_digest }}
AI_ROLLUP_DIGEST: ${{ needs.container.outputs.ai_rollup_digest }}
OFFICIAL_AI_DIGEST: ${{ needs.container.outputs.official_ai_digest }}
CHART_DIGEST: ${{ needs.chart.outputs.chart_digest }}
SOURCE_SHA: ${{ needs.validate.outputs.source_sha }}
VERSION: ${{ needs.validate.outputs.version }}
Expand All @@ -354,7 +361,7 @@ jobs:
## Container Images

\`\`\`text
${AI_ROLLUP_IMAGE_NAME}:${VERSION}@${AI_ROLLUP_DIGEST}
${OFFICIAL_AI_IMAGE_NAME}:${OFFICIAL_AI_IMAGE_TAG}@${OFFICIAL_AI_DIGEST}
${OPERATOR_IMAGE_NAME}@${OPERATOR_DIGEST}
${MOCK_PROVIDERS_IMAGE_NAME}@${MOCK_PROVIDERS_DIGEST}
${OVERLAY_SYNC_IMAGE_NAME}@${OVERLAY_SYNC_DIGEST}
Expand All @@ -380,10 +387,18 @@ jobs:
\`\`\`

The Grid images were built from \`${SOURCE_SHA}\`. The Praxis AI
rollup was built from
\`praxis-proxy/ai@${AI_ROLLUP_SOURCE_SHA}\` and
\`praxis-proxy/praxis@0d3347c634ab4e09d882c02bf01767a1667c82db\`.
image was verified from the organization-owned image above at
\`praxis-proxy/ai@${OFFICIAL_AI_SOURCE_SHA}\`.
Every reference above is immutable.

## Distributed token quota image requirement

Grid publishes the routing topology and qualification for distributed
token quotas, but the standard Praxis AI ${OFFICIAL_AI_IMAGE_TAG}
container does not include the optional \`token-rate-limit-filter\`
and \`praxis-filter/basic-auth-filter\` features. Deployments using the
quota example must supply a Praxis AI image built with both features.
Grid does not publish a replacement AI rollup.
EOF

- name: Create GitHub release
Expand Down
18 changes: 9 additions & 9 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ members = [
]

[workspace.package]
version = "0.1.3"
version = "0.1.4"
edition = "2024"
rust-version = "1.96"
license = "MIT"
Expand Down
4 changes: 2 additions & 2 deletions charts/grid-mock-providers/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ apiVersion: v2
name: grid-mock-providers
description: Mock inference providers for Grid development and testing
type: application
version: 0.1.3
appVersion: "v0.1.3"
version: 0.1.4
appVersion: "v0.1.4"
kubeVersion: ">=1.26.0-0"
home: https://github.com/praxis-proxy/grid
sources:
Expand Down
4 changes: 2 additions & 2 deletions charts/grid-operator/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ apiVersion: v2
name: grid-operator
description: Grid operator for multi-site AI inference routing with Praxis
type: application
version: 0.1.3
appVersion: "v0.1.3"
version: 0.1.4
appVersion: "v0.1.4"
kubeVersion: ">=1.26.0-0"
home: https://github.com/praxis-proxy/grid
sources:
Expand Down
4 changes: 2 additions & 2 deletions charts/grid-site/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ apiVersion: v2
name: grid-site
description: Grid site topology resources (GridNetwork, GridSite, InferenceProvider)
type: application
version: 0.1.3
appVersion: "v0.1.3"
version: 0.1.4
appVersion: "v0.1.4"
kubeVersion: ">=1.26.0-0"
home: https://github.com/praxis-proxy/grid
sources:
Expand Down
4 changes: 2 additions & 2 deletions charts/praxis-gateway/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ description: >-
Deploys the Praxis process directly — not an operator. Long-term ownership
moves to the future Praxis/Gateway Operator repository.
type: application
version: 0.1.3
appVersion: "v0.1.3"
version: 0.1.4
appVersion: "0.3.0"
kubeVersion: ">=1.26.0-0"
home: https://github.com/praxis-proxy/grid
sources:
Expand Down
15 changes: 11 additions & 4 deletions charts/praxis-gateway/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ release ownership exist. Do not treat this as a permanent Grid responsibility.
- Kubernetes >= 1.26
- Helm >= 3.12
- A Praxis configuration ConfigMap already created in the target namespace
- A compatible Grid AI gateway image (default: Grid v0.1.3 rollup)
- A compatible Praxis AI gateway image (default: Praxis AI 0.3.0)

## Install

Expand All @@ -34,10 +34,17 @@ helm install edge-gateway charts/praxis-gateway \
--set config.existingConfigMap=edge-gateway-config
```

The default image is the Grid v0.1.3 AI gateway rollup. Override
The default image is the official Praxis AI 0.3.0 gateway. Override
`image.repository`, `image.tag`, or `image.digest` to install another compatible
gateway image. Prefer a digest when reproducing a validated deployment.

The standard Praxis AI 0.3.0 image supports Grid provider selection and load
balancing. It does not include the optional `token-rate-limit-filter` and
`praxis-filter/basic-auth-filter` features required by the distributed token
quota qualification. That qualification requires an explicitly supplied Praxis
AI image built with both features; Grid does not publish a replacement AI
rollup.

The chart uses [Semantic Versioning](https://semver.org/). Its `version`
identifies the chart package, while `appVersion` identifies the default Praxis
AI image; these values may advance independently.
Expand All @@ -47,8 +54,8 @@ AI image; these values may advance independently.
| Key | Type | Default | Description |
|-----|------|---------|-------------|
| `replicaCount` | int | `1` | Gateway replicas. |
| `image.repository` | string | `ghcr.io/praxis-proxy/grid-ai-rollup` | Image repository. |
| `image.tag` | string | `""` | Image tag. Defaults to chart `appVersion` (`v0.1.3`). |
| `image.repository` | string | `ghcr.io/praxis-proxy/ai` | Image repository. |
| `image.tag` | string | `0.3.0` | Image tag. |
| `image.digest` | string | `""` | Immutable digest (sha256:…). When set, tag is ignored. |
| `image.pullPolicy` | string | `IfNotPresent` | Image pull policy. |
| `imagePullSecrets` | list | `[]` | Pull secrets for private registries. |
Expand Down
4 changes: 2 additions & 2 deletions charts/praxis-gateway/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ replicaCount: 1
# -- Gateway container image settings.
image:
# -- Image repository.
repository: ghcr.io/praxis-proxy/grid-ai-rollup
repository: ghcr.io/praxis-proxy/ai
# -- Image tag. Used when digest is empty.
tag: "v0.1.3"
tag: "0.3.0"
# -- Immutable image digest (sha256:<64 hex>). When set, tag is ignored.
digest: ""
# -- Image pull policy.
Expand Down
2 changes: 2 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ image preparation, execution, evidence, and cleanup.

## Development

- [Release Process](release.md) - versioning, validation, artifact publication,
and release workflow.
- [Development](development.md) — build, test, format, lint, and coverage.
- [Conventions](conventions.md) — coding style, testing requirements,
documentation rules, and commit attribution.
Expand Down
Loading
Loading