diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index 95d9da9..8b5363b 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -159,7 +159,7 @@ jobs: if: startsWith(github.ref, 'refs/tags/v') runs-on: ubuntu-latest permissions: - contents: read + contents: write # create the GitHub Release for the tag packages: write steps: - name: Checkout code @@ -169,6 +169,24 @@ jobs: id: version run: echo "version=${GITHUB_REF_NAME#v}" >> $GITHUB_OUTPUT + # Authoritative release gate: the chart is packaged with --version/--app-version + # derived from the tag, so if Chart.yaml disagrees we'd ship a chart whose + # source tree lies about its own version. Fail here, before publishing, so a + # mistagged release never reaches the registry (this is the only step that + # runs on the tag AND gates the publish). + - name: Assert Chart.yaml matches the release tag + run: | + set -eu + CHART=deployment/openfilter-pipelines-controller/Chart.yaml + TAG="${{ steps.version.outputs.version }}" + VERSION=$(awk '/^version:/ {print $2}' "$CHART" | tr -d '"') + APPVERSION=$(awk '/^appVersion:/ {print $2}' "$CHART" | tr -d '"') + echo "tag=$TAG Chart.yaml version=$VERSION appVersion=$APPVERSION" + if [ "$VERSION" != "$TAG" ] || [ "$APPVERSION" != "$TAG" ]; then + echo "::error file=$CHART::Chart.yaml version/appVersion ($VERSION/$APPVERSION) does not match release tag $GITHUB_REF_NAME (expected $TAG). Bump Chart.yaml to $TAG and re-tag." + exit 1 + fi + - name: Set up Helm uses: azure/setup-helm@v5 @@ -196,6 +214,22 @@ jobs: helm push openfilter-pipelines-controller-${{ steps.version.outputs.version }}.tgz \ oci://ghcr.io/plainsightai/charts + # Publishing to GHCR alone leaves the GitHub Releases page frozen at the + # last chart-releaser release (0.5.1). Recreate a Release per tag so the + # tag is discoverable and the packaged chart is attached as an asset. + - name: Create GitHub Release with chart artifact + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + CHART_TGZ=openfilter-pipelines-controller-${{ steps.version.outputs.version }}.tgz + if gh release view "$GITHUB_REF_NAME" >/dev/null 2>&1; then + gh release upload "$GITHUB_REF_NAME" "$CHART_TGZ" --clobber + else + gh release create "$GITHUB_REF_NAME" "$CHART_TGZ" \ + --title "$GITHUB_REF_NAME" \ + --generate-notes + fi + deploy: needs: merge if: github.ref == 'refs/heads/main' diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index ca14b64..acdce9d 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -46,7 +46,12 @@ jobs: echo "::error file=$CHART::could not parse version/appVersion from $CHART" exit 1 fi + # version==appVersion is checked here (pre-merge, on PRs) for fast + # developer feedback. The stricter "Chart.yaml must equal the release + # tag" gate lives in the publish-chart job (docker-publish.yml), which + # is the only place the tag exists AND the only place we publish — so a + # mistagged release fails to publish rather than just flagging a check. if [ "$VERSION" != "$APPVERSION" ]; then - echo "::error file=$CHART::version ($VERSION) and appVersion ($APPVERSION) drifted. The auto-bump workflow keeps these in lockstep on tag-driven releases (.github/workflows/update-helm-version.yml); manual edits must do the same. See PR #48 for the slip this catches." + echo "::error file=$CHART::version ($VERSION) and appVersion ($APPVERSION) drifted. Bump both together in the same commit. See PR #48 for the slip this catches." exit 1 fi diff --git a/README.md b/README.md index 92cc89f..aa0f7af 100644 --- a/README.md +++ b/README.md @@ -96,13 +96,13 @@ kubectl apply -f https://raw.githubusercontent.com//openfilter-pipelines-co ### Using the Helm Chart -The Helm chart lives in this repository under `deployment/openfilter-pipelines-controller`. Clone the repo and install from the local chart: +The chart is published as an OCI artifact to GitHub Container Registry (GHCR). +Helm 3.8+ supports OCI directly — no `helm repo add` is needed: ```sh -git clone https://github.com/PlainsightAI/openfilter-pipelines-controller -cd openfilter-pipelines-controller - -helm install openfilter-pipelines-controller deployment/openfilter-pipelines-controller \ +helm install openfilter-pipelines-controller \ + oci://ghcr.io/plainsightai/charts/openfilter-pipelines-controller \ + --version 0.6.1 \ --namespace pipelines-system \ --create-namespace ``` @@ -110,7 +110,9 @@ helm install openfilter-pipelines-controller deployment/openfilter-pipelines-con Install with the bundled Valkey subchart enabled (optional): ```sh -helm install openfilter-pipelines-controller deployment/openfilter-pipelines-controller \ +helm install openfilter-pipelines-controller \ + oci://ghcr.io/plainsightai/charts/openfilter-pipelines-controller \ + --version 0.6.1 \ --namespace pipelines-system \ --create-namespace \ --set valkey.enabled=true @@ -119,10 +121,18 @@ helm install openfilter-pipelines-controller deployment/openfilter-pipelines-con To upgrade an existing installation: ```sh -helm upgrade openfilter-pipelines-controller deployment/openfilter-pipelines-controller \ +helm upgrade openfilter-pipelines-controller \ + oci://ghcr.io/plainsightai/charts/openfilter-pipelines-controller \ + --version 0.6.1 \ --namespace pipelines-system ``` +Published chart versions track the git tags on this repository +(`vX.Y.Z` → chart `X.Y.Z`); see the [Releases](https://github.com/PlainsightAI/openfilter-pipelines-controller/releases) +page. Contributors hacking on the chart can also install from the local copy +under `deployment/openfilter-pipelines-controller` — see the +[chart README](deployment/openfilter-pipelines-controller/README.md). + For more configuration options, see the [chart values](deployment/openfilter-pipelines-controller/values.yaml) and the [chart README](deployment/openfilter-pipelines-controller/README.md). ## Contributing diff --git a/deployment/openfilter-pipelines-controller/README.md b/deployment/openfilter-pipelines-controller/README.md index 79ad715..357b0e3 100644 --- a/deployment/openfilter-pipelines-controller/README.md +++ b/deployment/openfilter-pipelines-controller/README.md @@ -25,8 +25,11 @@ Docker Hub has a flat namespace, so the chart (whose OCI repository name is derived from the chart name) would share a repository with the controller image and overwrite the image manifest at each release tag. -Replace `` with the desired release (e.g. `0.5.2`); the published -tags match the git tags on this repository (`vX.Y.Z` → chart `X.Y.Z`). +Replace `` with the desired release (e.g. `0.6.1`); the published +tags match the git tags on this repository (`vX.Y.Z` → chart `X.Y.Z`) and are +listed on the +[Releases](https://github.com/PlainsightAI/openfilter-pipelines-controller/releases) +page. Container images: [`plainsightai/openfilter-pipelines-controller`](https://hub.docker.com/r/plainsightai/openfilter-pipelines-controller) @@ -229,6 +232,28 @@ helm install openfilter-pipelines-controller deployment/openfilter-pipelines-con --dry-run --debug ``` +## Releasing + +Releases are driven entirely by git tags. To cut version `X.Y.Z`: + +1. Bump `version` **and** `appVersion` in `Chart.yaml` to `X.Y.Z` in the same + commit and merge it via PR. The `chart-version-parity` check in + `.github/workflows/lint.yml` runs on the PR and keeps `version` and + `appVersion` in lockstep (it does **not** see the tag). +2. Tag the merged commit `vX.Y.Z` and push the tag. + +On the tag push, `.github/workflows/docker-publish.yml`: + +- builds and pushes the controller + claimer images to Docker Hub, +- in the `publish-chart` job, the **`Assert Chart.yaml matches the release tag`** + step verifies `version == appVersion == X.Y.Z` and exits non-zero on a + mismatch **before** the chart is packaged or pushed — so a stale `Chart.yaml` + fails the publish rather than shipping a chart whose source tree disagrees with + the version it was published under, +- packages the chart (with `--version`/`--app-version` derived from the tag) + and pushes it to `oci://ghcr.io/plainsightai/charts`, and +- creates a GitHub Release for the tag with the packaged chart `.tgz` attached. + ## License See the [LICENSE](../../LICENSE) file for details.