This document describes the automated release process for the Nebari Operator.
The release process is fully automated via GitHub Actions and is triggered when you create a GitHub Release. The workflow will:
- Run all tests to ensure code quality
- Generate and update CRDs and RBAC manifests
- Build and push multi-architecture Docker images to Quay.io
- Build Go binaries for multiple platforms using GoReleaser
- Package and publish the Helm chart
- Generate a consolidated
install.yamlwith all Kubernetes manifests - Attach all artifacts to the GitHub Release
Before creating a release, ensure you have:
-
Quay.io Credentials: Add the following secrets to your GitHub repository:
QUAY_USERNAME: Your Quay.io usernameQUAY_PASSWORD: Your Quay.io password or robot token
To add secrets:
Settings → Secrets and variables → Actions → New repository secret -
Completed Development Work:
- All tests pass locally (
make test) - Linter passes (
make lint) - Manifests are up to date (
make manifests) - Documentation is updated
- All tests pass locally (
-
Version Tagging Strategy: Follow semantic versioning (e.g.,
v1.0.0,v1.2.3)
-
Update documentation if needed (especially if new configuration options were added)
-
Update any version references in code or documentation
-
Commit and push all changes:
git add . git commit -m "chore: prepare for vX.Y.Z release" git push origin main
Create and push a version tag:
# Create a tag (e.g., v1.0.0)
git tag -a v1.0.0 -m "Release v1.0.0"
# Push the tag
git push origin v1.0.0There are two ways to create a GitHub Release:
- Go to your repository on GitHub
- Click on "Releases" (right sidebar)
- Click "Draft a new release"
- Select the tag you just created (e.g.,
v1.0.0) - Set the release title (e.g., "v1.0.0")
- Write release notes describing:
- New features
- Bug fixes
- Breaking changes
- Upgrade instructions
- Click "Publish release"
gh release create v1.0.0 \
--title "v1.0.0" \
--notes "Release notes here..."- Go to the "Actions" tab in your GitHub repository
- Find the "Release" workflow run
- Monitor the progress of all jobs:
- tests: Runs unit tests and linter
- build-manifests: Generates and uploads install.yaml
- docker-build-push: Builds Docker images for each architecture
- merge-manifest: Creates multi-arch manifest and pushes to registry
- goreleaser: Builds Go binaries for multiple platforms
- publish-helm-chart: Packages and uploads Helm chart to release
- sync-helm-repository: Syncs chart to helm-repository (if enabled)
The workflow typically takes 5-10 minutes to complete.
After the workflow completes successfully, the following artifacts will be available:
Multi-architecture images will be pushed to:
quay.io/nebari/nebari-operator:<version>
quay.io/nebari/nebari-operator:latest
Supported architectures:
linux/amd64linux/arm64
Platform-specific binaries will be attached to the GitHub Release:
nebari-operator_<version>_Linux_x86_64.tar.gznebari-operator_<version>_Linux_arm64.tar.gznebari-operator_<version>_Darwin_x86_64.tar.gznebari-operator_<version>_Darwin_arm64.tar.gznebari-operator_<version>_Windows_x86_64.zip
A consolidated installation file:
install.yaml- Contains all CRDs, RBAC, and deployment manifests
The Helm chart package:
nebari-operator-<version>.tgz- Helm chart for deploying the operator
checksums.txt- SHA256 checksums for all binaries
Install the operator using the Helm chart from the OCI registry:
helm install nebari-operator oci://quay.io/nebari/charts/nebari-operator \
--version 1.0.0 \
--create-namespace \
--namespace nebari-operator-systemOr install directly from the GitHub release artifact:
helm install nebari-operator \
https://github.com/nebari-dev/nebari-operator/releases/download/v1.0.0/nebari-operator-1.0.0.tgz \
--create-namespace \
--namespace nebari-operator-systemInstall the operator using kubectl:
kubectl apply -f https://github.com/nebari-dev/nebari-operator/releases/download/v1.0.0/install.yamlDownload and run the binary for your platform:
# Linux (amd64)
curl -LO https://github.com/nebari-dev/nebari-operator/releases/download/v1.0.0/nebari-operator_1.0.0_Linux_x86_64.tar.gz
tar -xzf nebari-operator_1.0.0_Linux_x86_64.tar.gz
./manager
# macOS (arm64)
curl -LO https://github.com/nebari-dev/nebari-operator/releases/download/v1.0.0/nebari-operator_1.0.0_Darwin_arm64.tar.gz
tar -xzf nebari-operator_1.0.0_Darwin_arm64.tar.gz
./managerFollow Semantic Versioning:
- MAJOR version (
vX.0.0): Incompatible API changes - MINOR version (
v1.X.0): Backward-compatible functionality additions - PATCH version (
v1.0.X): Backward-compatible bug fixes
v1.0.0- Initial stable releasev1.1.0- Added new features, backward compatiblev1.1.1- Bug fixes, no new featuresv2.0.0- Breaking changes, requires migration
You can also create pre-releases for testing:
v1.0.0-alpha.1- Alpha releasev1.0.0-beta.1- Beta releasev1.0.0-rc.1- Release candidate
To mark a release as a pre-release in GitHub, check the "This is a pre-release" checkbox.
When introducing breaking changes to the CRD API:
- Create a new API version (e.g.,
v2) - Maintain the old version for backward compatibility
- Provide migration documentation
- Announce deprecation of the old version
Example structure:
api/
v1/ # Existing stable API
v2/ # New API version
- Tests fail: Fix the failing tests and create a new release
- Docker push fails: Check that
QUAY_USERNAMEandQUAY_PASSWORDsecrets are set correctly - GoReleaser fails: Check the GoReleaser configuration in
.goreleaser.yml
If the Docker push fails with authentication errors:
-
Verify secrets are set in GitHub:
Settings → Secrets and variables → Actions -
For Quay.io robot accounts:
- Go to Quay.io → Account Settings → Robot Accounts
- Create a robot account with write permissions to the repository
- Use the robot account credentials as secrets
-
Test locally:
echo $QUAY_PASSWORD | docker login quay.io -u $QUAY_USERNAME --password-stdin docker pull quay.io/nebari/nebari-operator:latest
If artifacts are missing from the release:
- Check the workflow logs in the Actions tab
- Ensure all jobs completed successfully
- Re-run failed jobs if needed
If you need to rollback a release:
- Delete the GitHub Release (optional)
- Delete the tag:
git tag -d v1.0.0 git push origin :refs/tags/v1.0.0
- Revert problematic commits
- Create a new release with a patch version
If the automated workflow fails and you need to release manually:
export VERSION=v1.0.0
export IMG=quay.io/nebari/nebari-operator:${VERSION}
# Login to Quay.io
docker login quay.io
# Build multi-arch image
make docker-buildx IMG=${IMG}
# Also tag as latest
docker tag ${IMG} quay.io/nebari/nebari-operator:latest
docker push quay.io/nebari/nebari-operator:latestexport VERSION=v1.0.0
export IMG=quay.io/nebari/nebari-operator:${VERSION}
# Generate install.yaml with correct image tag
make build-installer IMG=${IMG}export VERSION=1.0.0 # Note: no 'v' prefix for Helm chart version
# Generate and package chart
make helm-chart
make helm-chart-version VERSION=${VERSION} APP_VERSION=v${VERSION}
make helm-package# Requires Go and goreleaser installed
goreleaser release --cleanManually upload the files to the GitHub Release:
- Go binaries from
dist/ dist/install.yamldist/nebari-operator-<version>.tgzchecksums.txt
- Test Before Release: Always run tests locally before creating a release
- Write Good Release Notes: Clearly document what changed
- Follow Semantic Versioning: Be consistent with version numbers
- Announce Breaking Changes: Clearly communicate incompatible changes
- Maintain Changelog: Keep CHANGELOG.md updated
- Tag Appropriately: Use annotated tags with descriptions
- Monitor Releases: Watch the workflow execution
- Validate Release: Test the released artifacts before announcing
Consider establishing a release schedule:
- Major releases: Once or twice a year
- Minor releases: Every 1-3 months
- Patch releases: As needed for critical bugs
After a successful release:
- Update project documentation
- Announce on relevant channels (Slack, mailing list, etc.)
- Update examples and tutorials
- Notify users of breaking changes
- Celebrate! 🎉