Skip to content
Merged
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
37 changes: 0 additions & 37 deletions .github/workflows/build-image.yaml

This file was deleted.

37 changes: 37 additions & 0 deletions .github/workflows/build-images.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: Build Docker Images

# Builds and publishes the pack's first-party image(s) via the shared reusable
# workflow in nebari-dev/.github. Each image is pushed to GHCR and quay.io with
# `sha-<short>` and `latest` tags. Publishing to quay.io/nebari/* uses the
# org-provided QUAY_TOKEN / QUAY_USERNAME secrets, so this works for official
# packs in the nebari-dev org.
#
# The Chart.yaml path is included in the trigger on purpose: release.yaml pins
# image tags to sha-<release-commit>, so the release commit (a Chart.yaml bump)
# must produce images with that sha. Building here on the bump ensures they
# exist. This runs in parallel with the release workflow.

on:
push:
branches: [main]
paths:
- "examples/auth-fastapi/app/**"
- "examples/auth-fastapi/Dockerfile"
- ".github/workflows/build-images.yaml"
- "examples/auth-fastapi/chart/Chart.yaml"
pull_request:
paths:
- "examples/auth-fastapi/app/**"
- "examples/auth-fastapi/Dockerfile"
workflow_dispatch:

jobs:
auth-fastapi-example:
uses: nebari-dev/.github/.github/workflows/pack-build-image.yaml@v1
with:
image: auth-fastapi-example
context: examples/auth-fastapi
push: ${{ github.event_name != 'pull_request' }}
secrets:
QUAY_TOKEN: ${{ secrets.QUAY_TOKEN }}
QUAY_USERNAME: ${{ secrets.QUAY_USERNAME }}
131 changes: 32 additions & 99 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
@@ -1,105 +1,38 @@
name: Release Chart

# Releases a pack chart via the shared reusable workflow in nebari-dev/.github.
# On a Chart.yaml version bump it pins the chart's image tag(s) to the release
# commit's sha, packages the chart, creates a GitHub Release, and opens a PR in
# nebari-dev/helm-repository (which then publishes to quay.io/nebari/charts).
#
# This pattern only works for official packs in the nebari-dev org: it relies on
# the org-provided NEBARI_HELM_REPO_TOKEN secret and the central
# nebari-dev/helm-repository. Forks outside the org must supply their own
# publishing infrastructure.
#
# To adapt this for your pack, point the inputs at your chart:
# - chart-path: directory containing your Chart.yaml
# - chart-name: chart name (used for the release tag and the destination
# directory in nebari-dev/helm-repository)
# - tag-paths: newline-separated dotted values.yaml keys to pin to the
# release commit's sha (one per first-party image tag)
# and update the paths filter to your chart's Chart.yaml. Make sure your image
# build runs on the same Chart.yaml bump so the pinned sha-<short> tag exists
# (see build-images.yaml).

on:
workflow_dispatch:
inputs:
chart_path:
description: "Path to the chart directory to release"
required: true
default: "examples/basic-nginx/chart"
type: choice
options:
- "examples/basic-nginx/chart"
- "examples/auth-fastapi/chart"
- "examples/wrap-existing-chart/chart"
push:
branches: [main]
paths:
- "examples/auth-fastapi/chart/Chart.yaml"

jobs:
release:
runs-on: ubuntu-latest
permissions:
contents: write
pages: write

steps:
- name: Checkout
uses: actions/checkout@v5
with:
fetch-depth: 0

- name: Configure Git
run: |
git config user.name "$GITHUB_ACTOR"
git config user.email "$GITHUB_ACTOR@users.noreply.github.com"

- name: Set up Helm
uses: azure/setup-helm@v5

- name: Update dependencies
run: helm dependency update ${{ inputs.chart_path }} || true

- name: Get chart version
id: chart
run: |
echo "version=$(grep '^version:' ${{ inputs.chart_path }}/Chart.yaml | awk '{print $2}')" >> $GITHUB_OUTPUT
echo "name=$(grep '^name:' ${{ inputs.chart_path }}/Chart.yaml | awk '{print $2}')" >> $GITHUB_OUTPUT

- name: Check if release exists
id: check
run: |
if gh release view "${{ steps.chart.outputs.name }}-${{ steps.chart.outputs.version }}" &>/dev/null; then
echo "exists=true" >> $GITHUB_OUTPUT
else
echo "exists=false" >> $GITHUB_OUTPUT
fi
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Package chart
if: steps.check.outputs.exists == 'false'
run: helm package ${{ inputs.chart_path }}

- name: Create GitHub release
if: steps.check.outputs.exists == 'false'
run: |
gh release create "${{ steps.chart.outputs.name }}-${{ steps.chart.outputs.version }}" \
--title "${{ steps.chart.outputs.name }}-${{ steps.chart.outputs.version }}" \
--generate-notes \
*.tgz
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Update Helm repo index
if: steps.check.outputs.exists == 'false'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -euo pipefail
GH_PAGES_URL="https://x-access-token:${GH_TOKEN}@github.com/${{ github.repository }}.git"
REPO_URL="https://github.com/${{ github.repository }}/releases/download/${{ steps.chart.outputs.name }}-${{ steps.chart.outputs.version }}"

# Preserve any existing gh-pages history (and index) so prior chart
# releases are not lost. Bootstrap the branch on first release.
if git ls-remote --exit-code --heads "${GH_PAGES_URL}" gh-pages >/dev/null 2>&1; then
git clone --depth 1 --branch gh-pages "${GH_PAGES_URL}" gh-pages
else
mkdir -p gh-pages
git -C gh-pages init -b gh-pages
git -C gh-pages remote add origin "${GH_PAGES_URL}"
fi

cp *.tgz gh-pages/
cd gh-pages

# Merge with the existing index when present so old chart versions
# remain installable from the Helm repo.
if [ -f index.yaml ]; then
helm repo index . --url "${REPO_URL}" --merge index.yaml
else
helm repo index . --url "${REPO_URL}"
fi

git config user.name "$GITHUB_ACTOR"
git config user.email "$GITHUB_ACTOR@users.noreply.github.com"
git add .
git commit -m "Release ${{ steps.chart.outputs.name }}-${{ steps.chart.outputs.version }}"
git push origin gh-pages
uses: nebari-dev/.github/.github/workflows/pack-release.yaml@v1
with:
chart-path: examples/auth-fastapi/chart
chart-name: my-pack
tag-paths: |
image.tag
secrets:
NEBARI_HELM_REPO_TOKEN: ${{ secrets.NEBARI_HELM_REPO_TOKEN }}
4 changes: 2 additions & 2 deletions .github/workflows/test-integration.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,10 @@ jobs:
# ============================================================
- name: Build and load auth-fastapi image
run: |
docker build -t ghcr.io/nebari-dev/nebari-software-pack-template/auth-fastapi-example:latest \
docker build -t ghcr.io/nebari-dev/software-pack-template/auth-fastapi-example:latest \
examples/auth-fastapi/
kind load docker-image \
ghcr.io/nebari-dev/nebari-software-pack-template/auth-fastapi-example:latest \
ghcr.io/nebari-dev/software-pack-template/auth-fastapi-example:latest \
--name pack-integration

# ============================================================
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ jobs:
# Test auth-fastapi Helm example
- name: Build and load auth-fastapi image
run: |
docker build -t ghcr.io/nebari-dev/nebari-software-pack-template/auth-fastapi-example:latest examples/auth-fastapi/
kind load docker-image ghcr.io/nebari-dev/nebari-software-pack-template/auth-fastapi-example:latest --name pack-test
docker build -t ghcr.io/nebari-dev/software-pack-template/auth-fastapi-example:latest examples/auth-fastapi/
kind load docker-image ghcr.io/nebari-dev/software-pack-template/auth-fastapi-example:latest --name pack-test

- name: Install auth-fastapi chart
run: |
Expand Down
52 changes: 36 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Nebari Software Pack Template

[![Lint](https://github.com/nebari-dev/nebari-software-pack-template/actions/workflows/lint.yaml/badge.svg)](https://github.com/nebari-dev/nebari-software-pack-template/actions/workflows/lint.yaml)
[![Test](https://github.com/nebari-dev/nebari-software-pack-template/actions/workflows/test.yaml/badge.svg)](https://github.com/nebari-dev/nebari-software-pack-template/actions/workflows/test.yaml)
[![Integration Test](https://github.com/nebari-dev/nebari-software-pack-template/actions/workflows/test-integration.yaml/badge.svg)](https://github.com/nebari-dev/nebari-software-pack-template/actions/workflows/test-integration.yaml)
[![Lint](https://github.com/nebari-dev/software-pack-template/actions/workflows/lint.yaml/badge.svg)](https://github.com/nebari-dev/software-pack-template/actions/workflows/lint.yaml)
[![Test](https://github.com/nebari-dev/software-pack-template/actions/workflows/test.yaml/badge.svg)](https://github.com/nebari-dev/software-pack-template/actions/workflows/test.yaml)
[![Integration Test](https://github.com/nebari-dev/software-pack-template/actions/workflows/test-integration.yaml/badge.svg)](https://github.com/nebari-dev/software-pack-template/actions/workflows/test-integration.yaml)

A template repository for building **Nebari Software Packs** - Kubernetes
applications that deploy on the [Nebari](https://nebari.dev) platform with
Expand Down Expand Up @@ -115,13 +115,13 @@ For local development (optional):
## Repository Structure

```
nebari-software-pack-template/
software-pack-template/
.github/workflows/
build-image.yaml # Build + publish auth-fastapi image to GHCR
build-images.yaml # Build + publish images via reusable pack-build-image
lint.yaml # Manifest validation (all examples)
test.yaml # Integration tests on kind cluster
test-integration.yaml # NebariApp integration tests (full stack)
release.yaml # Helm package + GitHub release + gh-pages index
release.yaml # Release chart via reusable pack-release workflow
examples/
vanilla-yaml/ # Example 1: Plain Kubernetes manifests
deployment.yaml # nginx Deployment
Expand Down Expand Up @@ -383,7 +383,7 @@ def get_id_token(request: Request) -> str | None:

```bash
# Run locally (shows "Not Authenticated" - no IdToken cookie without Envoy Gateway)
docker run -p 8000:8000 ghcr.io/nebari-dev/nebari-software-pack-template/auth-fastapi-example:latest
docker run -p 8000:8000 ghcr.io/nebari-dev/software-pack-template/auth-fastapi-example:latest

# Deploy on Nebari with auth
helm install my-pack examples/auth-fastapi/chart/ \
Expand Down Expand Up @@ -539,11 +539,26 @@ Runs on every push and PR. Validates all examples:
- `kubectl kustomize` for each Kustomize overlay
- `helm lint` and `helm template` for each Helm chart (both NebariApp enabled and disabled)

### Build Image (`build-image.yaml`)

Runs on pushes to main that modify `examples/auth-fastapi/app/` or the
`Dockerfile`, plus manual dispatch. Builds and publishes the auth-fastapi
example image to `ghcr.io/nebari-dev/nebari-software-pack-template/auth-fastapi-example`.
### Build Images (`build-images.yaml`)

Calls the shared reusable workflow
`nebari-dev/.github/.github/workflows/pack-build-image.yaml@v1` to build and
publish the auth-fastapi example image to GHCR
(`ghcr.io/nebari-dev/software-pack-template/auth-fastapi-example`) and quay.io,
tagged `sha-<short>` and `latest`. Runs on pushes to main that modify the
example's `app/`, `Dockerfile`, or its chart `Chart.yaml` (so the release commit
produces the sha-pinned image the release workflow references), on pull requests
(build only, no push), and on manual dispatch.

> **Manual prerequisite (official packs).** The shared workflow does **not**
> create Quay repositories. Before the first push, a maintainer must create the
> image's Quay repository under the `nebari` org and grant the CI robot account
> write access (make it public if the pack is public). For this example that is
> `quay.io/nebari/software-pack-template-auth-fastapi-example`; in general it is
> `quay.io/nebari/<repo-name>-<image>`. GHCR repositories are created
> automatically on first push, so only Quay needs this step. The `QUAY_TOKEN`,
> `QUAY_USERNAME`, and `NEBARI_HELM_REPO_TOKEN` secrets are provided
> organizationally to public nebari-dev repos.

### Test (`test.yaml`)

Expand Down Expand Up @@ -572,11 +587,16 @@ setup that the standalone test cannot detect.

### Release (`release.yaml`)

Manual dispatch. Packages and releases a Helm chart:
Calls the shared reusable workflow
`nebari-dev/.github/.github/workflows/pack-release.yaml@v1` when the auth-fastapi
example's `Chart.yaml` version changes on main. The reusable workflow pins the
chart's image tag to the release commit's sha, packages the chart, creates a
GitHub Release, and opens a PR in `nebari-dev/helm-repository` (which publishes
to `quay.io/nebari/charts`).

- Packages the selected chart as a `.tgz`
- Creates a GitHub release with the package
- Updates the `gh-pages` branch with a Helm repo index
This flow works only for official packs in the nebari-dev org: it relies on the
org's `NEBARI_HELM_REPO_TOKEN` secret and the central `nebari-dev/helm-repository`.
Forks outside the org must supply their own publishing infrastructure.

## Deploying to a Nebari Cluster

Expand Down
2 changes: 1 addition & 1 deletion docs/release-readiness-checklist.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ If "product owner" has not been named for a pack, the tech lead acts as product
- `[B]` `appVersion` in `Chart.yaml` matches the upstream application version being wrapped
- `[GA]` Chart version is set to `1.0.0` and follows the [version tagging convention](#version-tagging-convention)
- `[GA]` Custom container images (if any) are published and accessible
- `[GA]` Helm repo index updates correctly after release
- `[GA]` Chart syncs to `nebari-dev/helm-repository` and publishes to `quay.io/nebari/charts` after release
- `[GA]` Upgrade smoke test in CI: `helm install` + `helm upgrade` succeeds without errors

### Pre-sales Verification
Expand Down
2 changes: 1 addition & 1 deletion docs/site/src/content/docs/build-your-own.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ If your app already runs on Kubernetes - via Helm, Kustomize, or plain YAML - ad

## Start from the template

The easiest way to create a pack is the [Software Pack template](https://github.com/nebari-dev/nebari-software-pack-template).
The easiest way to create a pack is the [Software Pack template](https://github.com/nebari-dev/software-pack-template).

1. Click **Use this template** on the template repository.
2. Clone your new repo.
Expand Down
2 changes: 1 addition & 1 deletion docs/site/src/content/docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ A software pack is a Kubernetes application bundled with a `NebariApp` custom re

## Pack template

Use the [nebari-software-pack-template](https://github.com/nebari-dev/nebari-software-pack-template) as your starting point. It includes five examples spanning plain YAML, Kustomize, basic Helm, auth-aware apps, and wrapping an existing upstream chart.
Use the [software-pack-template](https://github.com/nebari-dev/software-pack-template) as your starting point. It includes five examples spanning plain YAML, Kustomize, basic Helm, auth-aware apps, and wrapping an existing upstream chart.
2 changes: 1 addition & 1 deletion docs/site/src/content/docs/release-readiness.md
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ promotion purposes, but this should be resolved before the next promotion attemp
- `[B]` `appVersion` in `Chart.yaml` matches the upstream application version being wrapped
- `[GA]` Chart version is set to `1.0.0` and follows the version tagging convention
- `[GA]` Custom container images (if any) are published and accessible
- `[GA]` Helm repo index updates correctly after release
- `[GA]` Chart syncs to `nebari-dev/helm-repository` and publishes to `quay.io/nebari/charts` after release
- `[GA]` Upgrade smoke test in CI: `helm install` + `helm upgrade` succeeds without errors

### Pre-sales Verification
Expand Down
Loading
Loading