diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index eace380..63a0b74 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -18,6 +18,78 @@ jobs: release: name: Package and publish Helm chart runs-on: ubuntu-latest + permissions: + contents: write + env: + CHART_VERSION: ${{ inputs.draft && format('{0}-draft', inputs.version) || inputs.version }} + APP_VERSION: ${{ inputs.version }} steps: - - name: Placeholder - run: echo "This is a scaffold. The full implementation is in PR #23." + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Helm + uses: azure/setup-helm@v4 + with: + version: v3.14.4 + + - name: Set chart version and appVersion + run: | + set -euo pipefail + sed -i "s/^version:.*/version: $CHART_VERSION/" chart/Chart.yaml + sed -i "s/^appVersion:.*/appVersion: \"$APP_VERSION\"/" chart/Chart.yaml + sed -i 's/^ version: .*/ version: "'"$APP_VERSION"'"/' chart/values.yaml + echo "### Chart.yaml" >> $GITHUB_STEP_SUMMARY + echo '```yaml' >> $GITHUB_STEP_SUMMARY + cat chart/Chart.yaml >> $GITHUB_STEP_SUMMARY + echo '```' >> $GITHUB_STEP_SUMMARY + + - name: Lint chart + run: helm lint chart + + - name: Package chart + run: | + set -euo pipefail + pkg_output=$(helm package chart --version "$CHART_VERSION" --app-version "$APP_VERSION") + echo "$pkg_output" + chart_package=$(printf '%s\n' "$pkg_output" | awk '/Successfully packaged chart and saved it to:/ {print $NF}') + echo "CHART_PACKAGE=$chart_package" >> "$GITHUB_ENV" + + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-access-key-id: ${{ secrets.ECR_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.ECR_SECRET_ACCESS_KEY }} + aws-region: ${{ vars.ECR_PUBLIC_REGION }} + + - name: Push chart to public ECR + run: | + set -euo pipefail + aws ecr-public get-login-password --region ${{ vars.ECR_PUBLIC_REGION }} \ + | helm registry login --username AWS --password-stdin public.ecr.aws + helm push "$CHART_PACKAGE" oci://public.ecr.aws/openops/helm + echo "- ✅ Pushed \`oci://public.ecr.aws/openops/helm/openops:${CHART_VERSION}\`" >> $GITHUB_STEP_SUMMARY + + - name: Create GitHub release + uses: softprops/action-gh-release@v2 + with: + target_commitish: ${{ github.sha }} + tag_name: ${{ env.CHART_VERSION }} + name: openops-${{ env.CHART_VERSION }} + generate_release_notes: true + draft: ${{ inputs.draft }} + files: ${{ env.CHART_PACKAGE }} + + - name: Write summary + run: | + echo "### Helm Chart Release" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "| Field | Value |" >> $GITHUB_STEP_SUMMARY + echo "|-------|-------|" >> $GITHUB_STEP_SUMMARY + echo "| Chart version | \`$CHART_VERSION\` |" >> $GITHUB_STEP_SUMMARY + echo "| App version | \`$APP_VERSION\` |" >> $GITHUB_STEP_SUMMARY + echo "| Draft | \`${{ inputs.draft }}\` |" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "Install with:" >> $GITHUB_STEP_SUMMARY + echo '```bash' >> $GITHUB_STEP_SUMMARY + echo "helm install openops oci://public.ecr.aws/openops/helm/openops --version $CHART_VERSION" >> $GITHUB_STEP_SUMMARY + echo '```' >> $GITHUB_STEP_SUMMARY diff --git a/AGENTS.md b/AGENTS.md index 76e0526..1e59fe0 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -34,6 +34,24 @@ - **Helm tests**: Post-installation connectivity tests to validate deployment health. - **Validation helpers**: Runtime validation of required secrets (OPS_ENCRYPTION_KEY, OPS_JWT_SECRET, etc.) with helpful error messages at render time. +## Release workflow +- **`.github/workflows/release.yml`**: Packages the Helm chart and pushes it as an OCI artifact to `public.ecr.aws/openops/helm/openops`. +- Triggered via `workflow_dispatch` with two inputs: + - `version` (required): The release version (e.g., `0.6.15`). Sets both `Chart.yaml` version/appVersion and `global.version` (image tags). + - `draft` (boolean, default `true`): When true, appends `-draft` to the chart version (e.g., `0.6.15-draft`). Draft versions are overwritable on ECR; final versions are immutable. +- Also triggered cross-repo by `openops-cloud/openops` release workflow. +- Creates a GitHub release (draft or published) with the packaged `.tgz` as an asset. +- **Do not bump versions in `Chart.yaml` or `values.yaml` manually**—the release workflow sets them at build time. The repo defaults are `version: 0.0.1-dev` and `appVersion: 0.0.1-dev`. +- Required secrets: `ECR_ACCESS_KEY_ID`, `ECR_SECRET_ACCESS_KEY`; required vars: `ECR_PUBLIC_REGION`. + +## Versioning strategy +- All *release* versions are unified: chart version = appVersion = `global.version` (image tags) = OpenOps release version. The in-repo development defaults (`0.0.1-dev`) are normalized by the release workflow. +- Exception: draft releases use `{version}-draft` for the chart version only; `appVersion` and image tags use the clean version. +- The chart is published to `oci://public.ecr.aws/openops/helm/openops`. Users install with: + ``` + helm install openops oci://public.ecr.aws/openops/helm/openops --version + ``` + ## PR lint rules The `.github/prlint.json` ruleset runs on every pull request. To avoid CI failures: 1. **Title requirements** diff --git a/README.md b/README.md index 1d4887e..62096f8 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,18 @@ This repository contains the Helm chart that deploys the OpenOps application sta - **redis**: Redis cache. ## Quick start + +### Install from OCI registry (recommended) + +```bash +helm install openops oci://public.ecr.aws/openops/helm/openops \ + --version \ + -n openops --create-namespace \ + -f values.overrides.yaml +``` + +### Install from source + 1. Copy the sample overrides file and adjust it to match your environment: ```bash cp chart/values.overrides-example.yaml chart/values.overrides.yaml diff --git a/chart/Chart.yaml b/chart/Chart.yaml index 7e4709d..8e773bd 100644 --- a/chart/Chart.yaml +++ b/chart/Chart.yaml @@ -1,7 +1,7 @@ -apiVersion: v2 -name: openops -description: A Helm chart for the OpenOps platform -type: application -version: 0.4.0 -appVersion: "0.6.14" -icon: https://openops.com/favicon.ico +apiVersion: v2 +name: openops +description: A Helm chart for the OpenOps platform +type: application +version: 0.0.1-dev +appVersion: "0.0.1-dev" +icon: https://openops.com/favicon.ico diff --git a/chart/templates/NOTES.txt b/chart/templates/NOTES.txt index 46cd106..03312f6 100644 --- a/chart/templates/NOTES.txt +++ b/chart/templates/NOTES.txt @@ -118,7 +118,7 @@ Useful commands: helm test {{ .Release.Name }} -n {{ .Release.Namespace }} # Upgrade deployment - helm upgrade {{ .Release.Name }} ./chart -f values.production.yaml + helm upgrade {{ .Release.Name }} oci://public.ecr.aws/openops/helm/{{ .Chart.Name }} --version {{ .Chart.Version }} -n {{ .Release.Namespace }} -f values.overrides.yaml # Uninstall helm uninstall {{ .Release.Name }} -n {{ .Release.Namespace }} diff --git a/chart/values.ci.yaml b/chart/values.ci.yaml index bc54c41..6ef1cd6 100644 --- a/chart/values.ci.yaml +++ b/chart/values.ci.yaml @@ -3,6 +3,9 @@ # Includes test secrets - NOT FOR PRODUCTION global: + # Use latest published images for CI (repo default 0.0.1-dev does not exist in ECR) + version: "latest" + # Allow single replica for CI allowSingleReplica: true diff --git a/chart/values.schema.json b/chart/values.schema.json index 1c64e18..fa7f547 100644 --- a/chart/values.schema.json +++ b/chart/values.schema.json @@ -11,8 +11,8 @@ "properties": { "version": { "type": "string", - "description": "Immutable version tag for app and engine images (semver or 8-char git hash)", - "pattern": "^([0-9]+\\.[0-9]+\\.[0-9]+(-[a-zA-Z0-9.-]+)?|[0-9a-fA-F]{8})$" + "description": "Immutable version tag for app and engine images (semver, 8-char git hash, or 'latest')", + "pattern": "^([0-9]+\\.[0-9]+\\.[0-9]+(-[a-zA-Z0-9.-]+)?|[0-9a-fA-F]{8}|latest)$" } } }, diff --git a/chart/values.yaml b/chart/values.yaml index af5cbb7..c68b191 100644 --- a/chart/values.yaml +++ b/chart/values.yaml @@ -1,5 +1,5 @@ global: - version: "0.6.14" + version: "0.0.1-dev" # Public URL - single source of truth for domain configuration # This is used to derive ingress host and all *_PUBLIC_URL environment variables