From 021e27304a5209340ff64eedc783b004ee05a928 Mon Sep 17 00:00:00 2001 From: michaelstingl Date: Fri, 23 May 2025 17:34:18 +0200 Subject: [PATCH 1/5] Add release process documentation to CONTRIBUTING.md Fixes #48 - Define who can create releases (maintainers only) - Add simple release process checklist - Document version guidelines for 0.x.x phase - Clarify breaking changes vs features vs fixes This provides the minimal governance structure requested while keeping the process lightweight and community-friendly. --- CONTRIBUTING.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 24cf390e..219c771f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -41,6 +41,30 @@ When making changes, please ensure you: - Ensure your PR has a clear description of the changes - At least one reviewer must approve before a maintainer can merge +## Release Process + +### Creating a Release + +Only maintainers can create releases. The process is: + +1. **Update versions**: Update the version in all Chart.yaml files +2. **Update documentation**: Add release notes to CHANGELOG.md (if exists) +3. **Create PR**: Submit a PR with the version changes +4. **Tag after merge**: After the PR is merged, create and push a tag: + ```bash + git tag -a v0.x.x -m "Release v0.x.x" + git push origin v0.x.x + ``` + +### Version Guidelines (0.x.x phase) + +During the initial development phase (0.x.x), we follow these conventions: +- `0.x.0` - Breaking changes (incompatible API/values changes) +- `0.x.y` - New features (backwards compatible) +- `0.x.y-z` - Bug fixes only + +Note: As per [SemVer 2.0](https://semver.org/spec/v2.0.0.html#spec-item-4), the 0.x.x range indicates the API is not stable and breaking changes may occur. + ## Code of Conduct This project follows the [Contributor Covenant Code of Conduct](https://www.contributor-covenant.org/version/2/1/code_of_conduct/). From eec4394fee4e2e1f332c34a7e0ca8d6c2a76af22 Mon Sep 17 00:00:00 2001 From: michaelstingl Date: Fri, 23 May 2025 20:55:30 +0200 Subject: [PATCH 2/5] Add version consistency checks to publish workflow - Validate semver format for all chart versions - Check and warn about version mismatches with git tags - Show which versions will be overwritten during tag releases - Helps prevent accidental version inconsistencies This addresses concerns raised in #48 about version governance --- .github/workflows/publish-helm-charts.yml | 38 +++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/.github/workflows/publish-helm-charts.yml b/.github/workflows/publish-helm-charts.yml index 47739308..ca9f6fee 100644 --- a/.github/workflows/publish-helm-charts.yml +++ b/.github/workflows/publish-helm-charts.yml @@ -22,6 +22,44 @@ jobs: with: fetch-depth: 0 + - name: Check chart versions + run: | + echo "## Checking Chart Versions" + + # Get versions + PROD_VERSION=$(grep "^version:" charts/opencloud/Chart.yaml | awk '{print $2}') + DEV_VERSION=$(grep "^version:" charts/opencloud-dev/Chart.yaml | awk '{print $2}') + + echo "- opencloud: $PROD_VERSION" + echo "- opencloud-dev: $DEV_VERSION" + + # Basic semver check (x.y.z format) + for version in "$PROD_VERSION" "$DEV_VERSION"; do + if ! [[ "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "❌ ERROR: Version '$version' is not valid semver" + exit 1 + fi + done + + # Check tag consistency if this is a tag push + if [[ "$GITHUB_REF" == refs/tags/v* ]]; then + TAG_VERSION="${GITHUB_REF#refs/tags/v}" + echo "" + echo "## Publishing for tag: v$TAG_VERSION" + + # Check if tag matches chart versions + if [ "$PROD_VERSION" != "$TAG_VERSION" ] && [ "$DEV_VERSION" != "$TAG_VERSION" ]; then + echo "⚠️ WARNING: Tag doesn't match any chart version" + echo " Both charts will be updated from their current versions to $TAG_VERSION" + elif [ "$PROD_VERSION" = "$TAG_VERSION" ] && [ "$DEV_VERSION" != "$TAG_VERSION" ]; then + echo "⚠️ Dev chart will be updated from $DEV_VERSION to $TAG_VERSION" + elif [ "$DEV_VERSION" = "$TAG_VERSION" ] && [ "$PROD_VERSION" != "$TAG_VERSION" ]; then + echo "⚠️ Production chart will be updated from $PROD_VERSION to $TAG_VERSION" + else + echo "✅ Both charts already at version $TAG_VERSION" + fi + fi + - name: Set up Helm uses: azure/setup-helm@v3 with: From fcc1c7e99ce08020397fb19cb37d4afd84dfa416 Mon Sep 17 00:00:00 2001 From: michaelstingl Date: Fri, 23 May 2025 23:48:51 +0200 Subject: [PATCH 3/5] fix: only publish helm charts on tag push, not on every main commit This change prevents the workflow from overwriting the same chart version multiple times by restricting publishing to tag pushes only. Changes: - Remove 'branches: [main]' trigger from publish workflow - Add strict version validation that requires at least one chart to match the tag - Fail the workflow if no chart matches the tag version (prevents accidental overwrites) This ensures Helm chart versions remain immutable once published, following best practices for package management. --- .github/workflows/publish-helm-charts.yml | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/.github/workflows/publish-helm-charts.yml b/.github/workflows/publish-helm-charts.yml index ca9f6fee..295998c8 100644 --- a/.github/workflows/publish-helm-charts.yml +++ b/.github/workflows/publish-helm-charts.yml @@ -2,9 +2,7 @@ name: Publish Helm charts to OCI Registry on: push: - branches: - - main - # Publish when a new tag is pushed + # Publish ONLY when a new tag is pushed (not on every main push) tags: - 'v*' # Allow manual trigger @@ -47,10 +45,15 @@ jobs: echo "" echo "## Publishing for tag: v$TAG_VERSION" - # Check if tag matches chart versions + # Strict version check - at least one chart must match the tag if [ "$PROD_VERSION" != "$TAG_VERSION" ] && [ "$DEV_VERSION" != "$TAG_VERSION" ]; then - echo "⚠️ WARNING: Tag doesn't match any chart version" - echo " Both charts will be updated from their current versions to $TAG_VERSION" + echo "❌ ERROR: Neither chart version matches the tag version" + echo " - opencloud chart: $PROD_VERSION" + echo " - opencloud-dev chart: $DEV_VERSION" + echo " - Git tag: v$TAG_VERSION" + echo "" + echo "Please update Chart.yaml files to match the tag version before creating the release." + exit 1 elif [ "$PROD_VERSION" = "$TAG_VERSION" ] && [ "$DEV_VERSION" != "$TAG_VERSION" ]; then echo "⚠️ Dev chart will be updated from $DEV_VERSION to $TAG_VERSION" elif [ "$DEV_VERSION" = "$TAG_VERSION" ] && [ "$PROD_VERSION" != "$TAG_VERSION" ]; then From 45a8ad156c04341320fa90626d898c8167f0c379 Mon Sep 17 00:00:00 2001 From: michaelstingl Date: Fri, 23 May 2025 23:50:59 +0200 Subject: [PATCH 4/5] fix: allow pre-release versions in semver validation As pointed out by @butonic, the version check should support versions like 0.1.2-1 for bug fix releases as documented in CONTRIBUTING.md --- .github/workflows/publish-helm-charts.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish-helm-charts.yml b/.github/workflows/publish-helm-charts.yml index 295998c8..1f054655 100644 --- a/.github/workflows/publish-helm-charts.yml +++ b/.github/workflows/publish-helm-charts.yml @@ -31,9 +31,9 @@ jobs: echo "- opencloud: $PROD_VERSION" echo "- opencloud-dev: $DEV_VERSION" - # Basic semver check (x.y.z format) + # Basic semver check (x.y.z or x.y.z-prerelease format) for version in "$PROD_VERSION" "$DEV_VERSION"; do - if ! [[ "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + if ! [[ "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z-]+)?$ ]]; then echo "❌ ERROR: Version '$version' is not valid semver" exit 1 fi From cf1e9aafd054211a64d966f192aa83f8395283f7 Mon Sep 17 00:00:00 2001 From: michaelstingl Date: Sat, 24 May 2025 00:02:23 +0200 Subject: [PATCH 5/5] feat: add test build support with separate registry namespace - Add workflow_dispatch input for version suffix (default: test) - Manual triggers now build to helm-charts-test/ namespace - Test builds use timestamp-based versions: {version}-{suffix}.{timestamp} - Ensures clear separation between official releases and test builds - Official releases remain in helm-charts/ namespace (tag pushes only) --- .github/workflows/publish-helm-charts.yml | 50 +++++++++++++++++------ 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/.github/workflows/publish-helm-charts.yml b/.github/workflows/publish-helm-charts.yml index 1f054655..1e66ffcb 100644 --- a/.github/workflows/publish-helm-charts.yml +++ b/.github/workflows/publish-helm-charts.yml @@ -5,8 +5,14 @@ on: # Publish ONLY when a new tag is pushed (not on every main push) tags: - 'v*' - # Allow manual trigger + # Allow manual trigger with test suffix workflow_dispatch: + inputs: + version_suffix: + description: 'Version suffix for test builds (default: test)' + required: false + default: 'test' + type: string jobs: publish: @@ -84,47 +90,65 @@ jobs: run: | echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV echo "RELEASE_TAG=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV - # Default version for non-tag builds - if [[ "${{ github.ref }}" == "refs/heads/main" ]]; then - echo "CHARTS_VERSION=0.0.0-${GITHUB_SHA::8}" >> $GITHUB_ENV - elif [[ "${{ github.ref }}" == refs/tags/v* ]]; then + + # Version handling based on trigger type + if [[ "${{ github.ref }}" == refs/tags/v* ]]; then + # Tag push: use tag version for official releases echo "CHARTS_VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_ENV + echo "REGISTRY_NAMESPACE=helm-charts" >> $GITHUB_ENV + elif [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then + # Manual trigger: use test version with separate namespace + CHART_VERSION=$(grep "^version:" charts/opencloud/Chart.yaml | awk '{print $2}') + TIMESTAMP=$(date +%Y%m%d%H%M%S) + echo "CHARTS_VERSION=${CHART_VERSION}-${{ inputs.version_suffix }}.${TIMESTAMP}" >> $GITHUB_ENV + echo "REGISTRY_NAMESPACE=helm-charts-test" >> $GITHUB_ENV + echo "⚠️ Manual build: Creating test version ${CHART_VERSION}-${{ inputs.version_suffix }}.${TIMESTAMP}" else + # Fallback (should not happen with current triggers) echo "CHARTS_VERSION=0.0.0-dev" >> $GITHUB_ENV + echo "REGISTRY_NAMESPACE=helm-charts-test" >> $GITHUB_ENV fi - name: Package and push OpenCloud chart run: | - # Update Chart.yaml version if we have a tag + # Update Chart.yaml version based on trigger type if [[ "${{ github.ref }}" == refs/tags/v* ]]; then echo "Updating chart version to ${{ env.CHARTS_VERSION }}" sed -i "s/^version:.*/version: ${{ env.CHARTS_VERSION }}/" charts/opencloud/Chart.yaml + elif [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then + echo "Updating chart version to ${{ env.CHARTS_VERSION }} for test build" + sed -i "s/^version:.*/version: ${{ env.CHARTS_VERSION }}/" charts/opencloud/Chart.yaml fi # Package Helm chart helm package charts/opencloud - # Push to GHCR - helm push opencloud-*.tgz oci://ghcr.io/${{ github.repository_owner }}/helm-charts/ + # Push to GHCR with appropriate namespace + echo "Pushing to oci://ghcr.io/${{ github.repository_owner }}/${{ env.REGISTRY_NAMESPACE }}/" + helm push opencloud-*.tgz oci://ghcr.io/${{ github.repository_owner }}/${{ env.REGISTRY_NAMESPACE }}/ # Verify the pushed chart echo "Verifying the pushed chart..." - helm pull oci://ghcr.io/${{ github.repository_owner }}/helm-charts/opencloud --version $(helm show chart charts/opencloud | grep version | awk '{print $2}') + helm pull oci://ghcr.io/${{ github.repository_owner }}/${{ env.REGISTRY_NAMESPACE }}/opencloud --version $(helm show chart charts/opencloud | grep version | awk '{print $2}') - name: Package and push OpenCloud Dev chart run: | - # Update Chart.yaml version if we have a tag + # Update Chart.yaml version based on trigger type if [[ "${{ github.ref }}" == refs/tags/v* ]]; then echo "Updating chart version to ${{ env.CHARTS_VERSION }}" sed -i "s/^version:.*/version: ${{ env.CHARTS_VERSION }}/" charts/opencloud-dev/Chart.yaml + elif [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then + echo "Updating chart version to ${{ env.CHARTS_VERSION }} for test build" + sed -i "s/^version:.*/version: ${{ env.CHARTS_VERSION }}/" charts/opencloud-dev/Chart.yaml fi # Package Helm chart helm package charts/opencloud-dev - # Push to GHCR - helm push opencloud-dev-*.tgz oci://ghcr.io/${{ github.repository_owner }}/helm-charts/ + # Push to GHCR with appropriate namespace + echo "Pushing to oci://ghcr.io/${{ github.repository_owner }}/${{ env.REGISTRY_NAMESPACE }}/" + helm push opencloud-dev-*.tgz oci://ghcr.io/${{ github.repository_owner }}/${{ env.REGISTRY_NAMESPACE }}/ # Verify the pushed chart echo "Verifying the pushed chart..." - helm pull oci://ghcr.io/${{ github.repository_owner }}/helm-charts/opencloud-dev --version $(helm show chart charts/opencloud-dev | grep version | awk '{print $2}') \ No newline at end of file + helm pull oci://ghcr.io/${{ github.repository_owner }}/${{ env.REGISTRY_NAMESPACE }}/opencloud-dev --version $(helm show chart charts/opencloud-dev | grep version | awk '{print $2}') \ No newline at end of file