Chart - Release - Pipeline - 1 - Build Dev [8.9] #767
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: "Chart - Release - Pipeline - 1 - Build Dev" | |
| run-name: >- | |
| Chart - Release - Pipeline - 1 - Build Dev${{ inputs.chart-version != '' && format(' [{0}]', inputs.chart-version) || '' }} | |
| # Builds immutable dev packages for all active chart versions. | |
| # These packages are release-ready (transformations applied) and stored in Harbor | |
| # with unique dev tags for testing. They can be promoted to RC/release by retagging. | |
| # | |
| # Tagging scheme: | |
| # Dev: {version}-dev-{sha} (e.g., 13.4.0-dev-abc1234) | |
| # Rolling: {chart-major}-dev-latest (e.g., 13-dev-latest) | |
| # | |
| # Chart.yaml version is the final release version (e.g., 13.4.0) computed via | |
| # release-please dry-run, making the artifact truly release-ready. | |
| # | |
| # Registry: oci://registry.camunda.cloud/team-distribution/camunda-platform | |
| # Note: Harbor is for internal storage/testing. Public releases go to | |
| # GitHub Releases → helm.camunda.io → Artifact Hub | |
| # | |
| on: | |
| push: | |
| branches: | |
| - main | |
| paths: | |
| - .github/workflows/chart-build-dev.yaml | |
| - charts/camunda-platform-*/** | |
| - "!charts/camunda-platform-*/test/**" | |
| workflow_dispatch: | |
| inputs: | |
| chart-version: | |
| description: | | |
| Specific chart version to build (e.g., "8.8"). | |
| Leave empty to build all active versions. | |
| required: false | |
| type: string | |
| orchestration-image-tag: | |
| type: string | |
| required: false | |
| zeebe-image-tag: | |
| type: string | |
| required: false | |
| zeebe-gateway-image-tag: | |
| type: string | |
| required: false | |
| operate-image-tag: | |
| type: string | |
| required: false | |
| tasklist-image-tag: | |
| type: string | |
| required: false | |
| console-image-tag: | |
| type: string | |
| required: false | |
| modeler-image-tag: | |
| type: string | |
| required: false | |
| connectors-image-tag: | |
| type: string | |
| required: false | |
| optimize-image-tag: | |
| type: string | |
| required: false | |
| identity-image-tag: | |
| type: string | |
| required: false | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ inputs.chart-version || 'push' }} | |
| cancel-in-progress: false | |
| env: | |
| CHART_NAME: "camunda-platform" | |
| HARBOR_REGISTRY_HOST: "registry.camunda.cloud" | |
| HARBOR_REGISTRY_PROJECT: "team-distribution" | |
| jobs: | |
| setup: | |
| name: Setup build matrix | |
| runs-on: ubuntu-latest | |
| outputs: | |
| chart-matrix: ${{ steps.matrix.outputs.chart-matrix }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 | |
| with: | |
| fetch-depth: 0 | |
| - name: Configure curl and wget | |
| uses: ./.github/actions/setup-curl | |
| - name: Info - ℹ️ Print workflow inputs ℹ️ | |
| env: | |
| GITHUB_CONTEXT: ${{ toJson(inputs) }} | |
| run: | | |
| if [[ -n "${INITIAL_CLAIM_VALUE}" ]]; then | |
| echo "::add-mask::${INITIAL_CLAIM_VALUE}" | |
| fi | |
| echo "Workflow Inputs:" | |
| echo "${GITHUB_CONTEXT}" | jq '."extra-values" = "<Check below>"' | |
| echo "Workflow Inputs - Extra Values:" | |
| echo "${GITHUB_CONTEXT}" | jq -r '."extra-values"' | |
| - name: Get chart versions | |
| id: chart-versions | |
| uses: ./.github/actions/get-chart-versions | |
| - name: Build chart matrix | |
| id: matrix | |
| run: | | |
| # Use input version if provided, otherwise use all active versions | |
| if [[ -n "${{ inputs.chart-version }}" ]]; then | |
| versions="${{ inputs.chart-version }}" | |
| else | |
| versions="${{ steps.chart-versions.outputs.active }}" | |
| fi | |
| # Build matrix JSON as single line (required for GITHUB_OUTPUT) | |
| matrix="[" | |
| first=true | |
| for version in ${versions}; do | |
| if [[ "${first}" != "true" ]]; then | |
| matrix+="," | |
| fi | |
| first=false | |
| matrix+="{\"name\":\"Helm Chart ${version}\",\"directory\":\"charts/camunda-platform-${version}\",\"version\":\"${version}\"}" | |
| done | |
| matrix+="]" | |
| echo "chart-matrix=${matrix}" >> $GITHUB_OUTPUT | |
| echo "Building charts: ${versions}" | |
| build: | |
| needs: setup | |
| name: Build ${{ matrix.chart.version }} | |
| permissions: | |
| contents: read | |
| id-token: write | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| chart: ${{ fromJson(needs.setup.outputs.chart-matrix) }} | |
| defaults: | |
| run: | |
| shell: bash | |
| working-directory: ${{ matrix.chart.directory }} | |
| env: | |
| CHART_RELEASER_CONFIG_FILE: ".github/config/chart-releaser.yaml" | |
| CHART_DIR: "${{ matrix.chart.directory }}" | |
| CHART_RELEASE_VERSION: "${{ matrix.chart.version }}" | |
| CHART_RELEASE_PACKAGE_FILE: "camunda-platform-${{ matrix.chart.version }}.tgz" | |
| CHART_RELEASE_COSIGN_BUNDLE_FILE: "camunda-platform-${{ matrix.chart.version }}-cosign-bundle.json" | |
| CHART_RELEASE_COSIGN_VERIFY_FILE: "camunda-platform-${{ matrix.chart.version }}-cosign-verify.sh" | |
| CHART_RELEASE_COSIGN_CERTIFICATE_IDENTITY: "https://github.com/${{ github.workflow_ref }}" | |
| CHART_RELEASE_COSIGN_CERTIFICATE_OIDC_ISSUER: "https://token.actions.githubusercontent.com" | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 | |
| with: | |
| fetch-depth: 0 | |
| - name: Import Vault secrets | |
| id: secrets | |
| uses: hashicorp/vault-action@892a26828f195e65540a40b4768ae4571f51ebfc # v4.0.0 | |
| with: | |
| url: ${{ secrets.VAULT_ADDR }} | |
| method: approle | |
| roleId: ${{ secrets.VAULT_ROLE_ID }} | |
| secretId: ${{ secrets.VAULT_SECRET_ID }} | |
| secrets: | | |
| secret/data/products/distribution/ci HARBOR_REGISTRY_USER; | |
| secret/data/products/distribution/ci HARBOR_REGISTRY_PASSWORD; | |
| exportEnv: true | |
| - name: Install tools | |
| uses: ./.github/actions/install-tool-versions | |
| with: | |
| tools: | | |
| git-cliff | |
| golang | |
| gomplate | |
| helm | |
| oras | |
| yq | |
| - name: Install Cosign | |
| uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6 # v4.1.2 | |
| - name: Build values-injector | |
| env: | |
| CONSOLE_IMAGE_TAG: ${{ inputs.console-image-tag }} | |
| CONNECTORS_IMAGE_TAG: ${{ inputs.connectors-image-tag }} | |
| IDENTITY_IMAGE_TAG: ${{ inputs.identity-image-tag }} | |
| WEB_MODELER_IMAGE_TAG: ${{ inputs.modeler-image-tag }} | |
| OPTIMIZE_IMAGE_TAG: ${{ inputs.optimize-image-tag }} | |
| ORCHESTRATION_IMAGE_TAG: ${{ inputs.orchestration-image-tag }} | |
| ZEEBE_IMAGE_TAG: ${{ inputs.zeebe-image-tag }} | |
| ZEEBE_GATEWAY_IMAGE_TAG: ${{ inputs.zeebe-gateway-image-tag }} | |
| OPERATE_IMAGE_TAG: ${{ inputs.operate-image-tag }} | |
| TASKLIST_IMAGE_TAG: ${{ inputs.tasklist-image-tag }} | |
| CHART_VERSION: ${{ matrix.chart.version }} | |
| run: | | |
| cd $(git rev-parse --show-toplevel) | |
| cd scripts/values-injector | |
| go build | |
| cd $(git rev-parse --show-toplevel) | |
| ./scripts/values-injector/values-injector | |
| - name: Login to Harbor registry | |
| run: | | |
| source "${GITHUB_WORKSPACE}/scripts/harbor-retry.sh" | |
| harbor_login | |
| - name: Set version vars | |
| id: vars | |
| run: | | |
| # Version vars will be set after release-please computes the release version | |
| # For now, just set the short SHA and Camunda version | |
| SHORT_SHA="${GITHUB_SHA::7}" | |
| CAMUNDA_VERSION="${{ matrix.chart.version }}" | |
| echo "SHORT_SHA=${SHORT_SHA}" | tee -a $GITHUB_ENV | |
| echo "CAMUNDA_VERSION=${CAMUNDA_VERSION}" | tee -a $GITHUB_ENV | |
| # | |
| # Compute release version using release-please dry-run | |
| # This ensures the packaged Chart.yaml has the correct version and changelog | |
| # annotations that release-please would compute at release time. | |
| # | |
| - name: Install release-please CLI | |
| run: npm install -g release-please | |
| - name: Compute release version (release-please dry-run) | |
| id: release-please | |
| env: | |
| RELEASE_PLEASE_CONFIG: .github/config/release-please/release-please-config.json | |
| RELEASE_PLEASE_MANIFEST: .github/config/release-please/.release-please-manifest.json | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| # Get current version from Chart.yaml to check if it's a prerelease | |
| CURRENT_VERSION=$(yq '.version' Chart.yaml) | |
| echo "Current version: ${CURRENT_VERSION}" | |
| # Check if current version is a prerelease (alpha, beta, rc) | |
| IS_PRERELEASE=false | |
| if [[ "${CURRENT_VERSION}" =~ -(alpha|beta|rc)([0-9]+)$ ]]; then | |
| PRERELEASE_TYPE="${BASH_REMATCH[1]}" | |
| PRERELEASE_NUM="${BASH_REMATCH[2]}" | |
| BASE_VERSION="${CURRENT_VERSION%%-*}" | |
| # Cross-reference chart-versions.yaml to detect alpha-to-stable transition. | |
| # If Chart.yaml has an alpha suffix but the chart is no longer listed under | |
| # alpha in chart-versions.yaml, this is the first stable release: strip the | |
| # prerelease suffix instead of incrementing it. | |
| CHART_VERSIONS_FILE="$(git rev-parse --show-toplevel)/charts/chart-versions.yaml" | |
| IS_STILL_ALPHA=$(yq ".camundaVersions.alpha[] | select(. == \"${{ matrix.chart.version }}\")" "${CHART_VERSIONS_FILE}") | |
| if [[ -n "${IS_STILL_ALPHA}" ]]; then | |
| IS_PRERELEASE=true | |
| NEXT_PRERELEASE_NUM=$((PRERELEASE_NUM + 1)) | |
| RELEASE_VERSION="${BASE_VERSION}-${PRERELEASE_TYPE}${NEXT_PRERELEASE_NUM}" | |
| echo "Prerelease detected: ${PRERELEASE_TYPE}${PRERELEASE_NUM} -> ${PRERELEASE_TYPE}${NEXT_PRERELEASE_NUM}" | |
| else | |
| RELEASE_VERSION="${BASE_VERSION}" | |
| echo "Alpha-to-stable transition detected: ${CURRENT_VERSION} -> ${RELEASE_VERSION}" | |
| fi | |
| echo "RELEASE_VERSION=${RELEASE_VERSION}" | tee -a $GITHUB_ENV | |
| echo "IS_PRERELEASE=${IS_PRERELEASE}" >> $GITHUB_ENV | |
| RELEASE_VERSION_COMPUTED=true | |
| echo "RELEASE_VERSION_COMPUTED=true" >> $GITHUB_ENV | |
| echo "::notice::Computed version: ${RELEASE_VERSION}" | |
| fi | |
| # Run release-please dry-run to get changelog annotations | |
| cd ../.. | |
| release-please release-pr \ | |
| --token="${GITHUB_TOKEN}" \ | |
| --repo-url="${{ github.repository }}" \ | |
| --target-branch="main" \ | |
| --path="${{ matrix.chart.directory }}" \ | |
| --config-file="${RELEASE_PLEASE_CONFIG}" \ | |
| --manifest-file="${RELEASE_PLEASE_MANIFEST}" \ | |
| --dry-run \ | |
| --trace 2>&1 | tee ${{ matrix.chart.directory }}/release-please-trace.log | |
| cd ${{ matrix.chart.directory }} | |
| # For stable releases (not alpha-to-stable transition), extract version from release-please output | |
| if [[ "${IS_PRERELEASE}" != "true" && "${RELEASE_VERSION_COMPUTED}" != "true" ]]; then | |
| RELEASE_VERSION=$(grep -A5 "^+.*version:" release-please-trace.log | head -1 | sed 's/^+.*version:\s*//' || echo "") | |
| if [[ -z "${RELEASE_VERSION}" ]]; then | |
| RELEASE_VERSION=$(grep -oP '"\Q${{ matrix.chart.directory }}\E":\s*"\K[^"]+' release-please-trace.log || echo "") | |
| fi | |
| if [[ -z "${RELEASE_VERSION}" ]]; then | |
| echo "::warning::Could not determine release version from release-please dry-run" | |
| echo "RELEASE_VERSION_COMPUTED=false" >> $GITHUB_ENV | |
| else | |
| echo "RELEASE_VERSION=${RELEASE_VERSION}" | tee -a $GITHUB_ENV | |
| echo "RELEASE_VERSION_COMPUTED=true" >> $GITHUB_ENV | |
| echo "::notice::Computed release version: ${RELEASE_VERSION}" | |
| fi | |
| fi | |
| # Set dev tag version: {release-version}-dev-{sha} | |
| if [[ "${RELEASE_VERSION_COMPUTED}" == "true" || -n "${RELEASE_VERSION}" ]]; then | |
| DEV_TAG="${RELEASE_VERSION}-dev-${SHORT_SHA}" | |
| else | |
| # Fallback to current version if release-please couldn't compute | |
| DEV_TAG="${CURRENT_VERSION}-dev-${SHORT_SHA}" | |
| RELEASE_VERSION="${CURRENT_VERSION}" | |
| echo "RELEASE_VERSION=${RELEASE_VERSION}" | tee -a $GITHUB_ENV | |
| fi | |
| echo "DEV_TAG=${DEV_TAG}" | tee -a $GITHUB_ENV | |
| # Extract chart major version for rolling tag (e.g., 13.4.0 -> 13) | |
| CHART_MAJOR_VERSION="${RELEASE_VERSION%%.*}" | |
| echo "CHART_MAJOR_VERSION=${CHART_MAJOR_VERSION}" | tee -a $GITHUB_ENV | |
| echo "::notice::Dev tag: ${DEV_TAG}, Rolling tag: ${CHART_MAJOR_VERSION}-dev-latest" | |
| - name: Check for image override inputs | |
| id: check-overrides | |
| run: | | |
| # Detect if any image override inputs were provided via workflow_dispatch | |
| # When overrides are present, we must rebuild even if artifact exists | |
| HAS_IMAGE_OVERRIDES=false | |
| OVERRIDES_YAML="" | |
| declare -A OVERRIDE_INPUTS=( | |
| ["orchestration"]="${{ inputs.orchestration-image-tag }}" | |
| ["zeebe"]="${{ inputs.zeebe-image-tag }}" | |
| ["zeebe-gateway"]="${{ inputs.zeebe-gateway-image-tag }}" | |
| ["operate"]="${{ inputs.operate-image-tag }}" | |
| ["tasklist"]="${{ inputs.tasklist-image-tag }}" | |
| ["console"]="${{ inputs.console-image-tag }}" | |
| ["modeler"]="${{ inputs.modeler-image-tag }}" | |
| ["connectors"]="${{ inputs.connectors-image-tag }}" | |
| ["optimize"]="${{ inputs.optimize-image-tag }}" | |
| ["identity"]="${{ inputs.identity-image-tag }}" | |
| ) | |
| for key in "${!OVERRIDE_INPUTS[@]}"; do | |
| value="${OVERRIDE_INPUTS[$key]}" | |
| if [[ -n "${value}" ]]; then | |
| HAS_IMAGE_OVERRIDES=true | |
| OVERRIDES_YAML+="${key}: ${value}\n" | |
| fi | |
| done | |
| echo "HAS_IMAGE_OVERRIDES=${HAS_IMAGE_OVERRIDES}" | tee -a $GITHUB_ENV | |
| if [[ "${HAS_IMAGE_OVERRIDES}" == "true" ]]; then | |
| echo -e "${OVERRIDES_YAML}" > /tmp/image-overrides.yaml | |
| echo "::notice::Image override inputs detected - will force rebuild if artifact exists" | |
| echo "Overrides:" | |
| cat /tmp/image-overrides.yaml | |
| fi | |
| - name: Check if artifact already exists | |
| id: check-artifact | |
| run: | | |
| source "${GITHUB_WORKSPACE}/scripts/harbor-retry.sh" | |
| # Dev packages are immutable - skip if already exists | |
| # Exception: when image overrides are provided, delete and rebuild | |
| OCI_REGISTRY="${HARBOR_REGISTRY_HOST}/${HARBOR_REGISTRY_PROJECT}" | |
| # Retry helm pull with re-auth to avoid misinterpreting transient 401 as "not found" | |
| # harbor_helm_pull returns: 0=found, 1=not-found/other non-auth error, 2=persistent auth failure | |
| PULL_RC=0 | |
| harbor_helm_pull "oci://${OCI_REGISTRY}/${{ env.CHART_NAME }}" \ | |
| --version "${DEV_TAG}" --destination /tmp || PULL_RC=$? | |
| if [[ ${PULL_RC} -eq 2 ]]; then | |
| echo "::error::Harbor auth failure checking artifact existence" | |
| exit 1 | |
| fi | |
| if [[ ${PULL_RC} -eq 0 ]]; then | |
| if [[ "${HAS_IMAGE_OVERRIDES}" == "true" ]]; then | |
| # Image overrides provided - delete existing artifact to allow rebuild | |
| echo "::notice::Dev package ${DEV_TAG} exists but image overrides provided - deleting to rebuild" | |
| harbor_curl \ | |
| -X DELETE "https://${HARBOR_REGISTRY_HOST}/api/v2.0/projects/${HARBOR_REGISTRY_PROJECT}/repositories/${{ env.CHART_NAME }}/artifacts/${DEV_TAG}/tags/${DEV_TAG}" || true | |
| echo "SKIP_BUILD=false" | tee -a $GITHUB_ENV | |
| else | |
| echo "SKIP_BUILD=true" | tee -a $GITHUB_ENV | |
| echo "::notice::Dev package ${DEV_TAG} already exists, skipping build" | |
| fi | |
| else | |
| echo "SKIP_BUILD=false" | tee -a $GITHUB_ENV | |
| fi | |
| - name: Apply Chart.yaml version and changelog from release-please | |
| if: env.SKIP_BUILD == 'false' && env.RELEASE_VERSION_COMPUTED == 'true' | |
| run: | | |
| # Extract the Chart.yaml diff from trace output and apply it | |
| # The trace contains unified diff format for each file | |
| echo "Applying release-please computed changes to Chart.yaml..." | |
| echo "Release version: ${RELEASE_VERSION}" | |
| # Update the version field | |
| yq -i ".version = \"${RELEASE_VERSION}\"" Chart.yaml | |
| # Remove prerelease annotation for stable releases. | |
| # During alpha-to-stable transitions the source Chart.yaml may still | |
| # carry artifacthub.io/prerelease: "true". Strip it so Artifact Hub | |
| # does not label the GA chart as a pre-release. | |
| if [[ "${IS_PRERELEASE}" != "true" ]]; then | |
| yq -i 'del(.annotations."artifacthub.io/prerelease")' Chart.yaml | |
| echo "Removed artifacthub.io/prerelease annotation (stable release)" | |
| fi | |
| # Extract and apply the artifacthub.io/changes annotation from trace | |
| # The trace output contains the full YAML block for the annotation | |
| # Parse the changelog entries from trace output | |
| # Look for lines between artifacthub.io/changes and the next annotation or end of annotations | |
| CHANGELOG_YAML=$(awk ' | |
| /^\+.*artifacthub.io\/changes:/ { capture=1; next } | |
| capture && /^\+/ { | |
| line=$0 | |
| sub(/^\+[ ]*/, "", line) | |
| print line | |
| } | |
| capture && !/^\+/ { capture=0 } | |
| ' release-please-trace.log) | |
| if [[ -n "${CHANGELOG_YAML}" ]]; then | |
| echo "Extracted changelog annotations:" | |
| echo "${CHANGELOG_YAML}" | |
| # Create a temp file with the changelog YAML | |
| echo "${CHANGELOG_YAML}" > /tmp/changelog.yaml | |
| # Update the annotation in Chart.yaml | |
| yq -i '.annotations."artifacthub.io/changes" = load_str("/tmp/changelog.yaml")' Chart.yaml | |
| echo "Applied artifacthub.io/changes annotations" | |
| else | |
| echo "::warning::Could not extract changelog annotations from trace output" | |
| fi | |
| echo "Updated Chart.yaml:" | |
| head -50 Chart.yaml | |
| - name: Add component image versions to Chart.yaml annotations | |
| if: env.SKIP_BUILD == 'false' | |
| run: | | |
| # Extract image tags from values.yaml and add as Chart.yaml annotation | |
| # This makes the artifact self-documenting with exact component versions | |
| get_tag() { | |
| local path=$1 | |
| yq -r "${path} // \"N/A\"" values.yaml | |
| } | |
| # Version-specific components (order matches workflow summary) | |
| CAMUNDA_MINOR=$(echo "${{ env.CAMUNDA_VERSION }}" | sed 's/^8\.//') | |
| if [[ ${CAMUNDA_MINOR} -ge 8 ]]; then | |
| # 8.8+ orchestration architecture | |
| IMAGE_VERSIONS=$(cat << YAML | |
| camunda: $(get_tag '.orchestration.image.tag') | |
| managementIdentity: $(get_tag '.identity.image.tag') | |
| optimize: $(get_tag '.optimize.image.tag') | |
| webModeler: $(get_tag '.webModeler.image.tag') | |
| connectors: $(get_tag '.connectors.image.tag') | |
| console: $(get_tag '.console.image.tag') | |
| YAML | |
| ) | |
| else | |
| # 8.6-8.7 classic architecture | |
| IMAGE_VERSIONS=$(cat << YAML | |
| zeebe: $(get_tag '.zeebe.image.tag') | |
| operate: $(get_tag '.operate.image.tag') | |
| tasklist: $(get_tag '.tasklist.image.tag') | |
| identity: $(get_tag '.identity.image.tag') | |
| optimize: $(get_tag '.optimize.image.tag') | |
| webModeler: $(get_tag '.webModeler.image.tag') | |
| connectors: $(get_tag '.connectors.image.tag') | |
| console: $(get_tag '.console.image.tag') | |
| YAML | |
| ) | |
| fi | |
| # Write to temp file and add annotation | |
| echo "${IMAGE_VERSIONS}" > /tmp/image-versions.yaml | |
| yq -i '.annotations."camunda.io/component-image-versions" = load_str("/tmp/image-versions.yaml")' Chart.yaml | |
| echo "Added camunda.io/component-image-versions annotation:" | |
| yq '.annotations."camunda.io/component-image-versions"' Chart.yaml | |
| - name: Add image overrides annotation to Chart.yaml | |
| if: env.SKIP_BUILD == 'false' && env.HAS_IMAGE_OVERRIDES == 'true' | |
| run: | | |
| # Document which images were manually overridden via workflow_dispatch | |
| # This indicates the artifact cannot be traced to a standard commit's image set | |
| yq -i '.annotations."camunda.io/imageOverrides" = load_str("/tmp/image-overrides.yaml")' Chart.yaml | |
| echo "Added camunda.io/imageOverrides annotation:" | |
| yq '.annotations."camunda.io/imageOverrides"' Chart.yaml | |
| - name: Show computed version info | |
| if: env.SKIP_BUILD == 'false' | |
| run: | | |
| echo "### Version Information" | |
| echo "- Release Version (in Chart.yaml): ${RELEASE_VERSION}" | |
| echo "- Dev Tag: ${DEV_TAG}" | |
| echo "- Rolling Tag: ${CHART_MAJOR_VERSION}-dev-latest" | |
| # | |
| # Apply release transformations (makes artifact release-ready) | |
| # | |
| - name: Remove dev comments | |
| if: env.SKIP_BUILD == 'false' | |
| run: | | |
| target_files=( | |
| values*.yaml | |
| Chart.yaml | |
| ) | |
| for target_file in "${target_files[@]}"; do | |
| if [[ -f "${target_file}" ]]; then | |
| sed -i '/# START DEV COMMENT/,/# END DEV COMMENT/d' "${target_file}" | |
| fi | |
| done | |
| echo "Dev comments removed" | |
| - name: Remove badges from README | |
| if: env.SKIP_BUILD == 'false' | |
| run: | | |
| # Clean up badges from readme to avoid showing them in Artifact Hub | |
| sed -ri '/Badge .+/d' "README.md" | |
| echo "Badges removed from README" | |
| - name: Show transformations | |
| if: env.SKIP_BUILD == 'false' | |
| run: | | |
| echo "Applied release transformations:" | |
| git --no-pager diff --stat | |
| - name: Add Helm repos | |
| if: env.SKIP_BUILD == 'false' | |
| run: | | |
| make -C ../.. helm.repos-add | |
| - name: Helm dependency update | |
| if: env.SKIP_BUILD == 'false' | |
| run: | | |
| make -C ../.. helm.dependency-update \ | |
| chartPath=${{ matrix.chart.directory }} | |
| # | |
| # Generate release notes | |
| # | |
| - name: Generate RELEASE-NOTES.md | |
| if: env.SKIP_BUILD == 'false' | |
| working-directory: ${{ github.workspace }} | |
| run: | | |
| set -euo pipefail | |
| # Generate release notes using the same script as the release process | |
| bash scripts/generate-release-notes.sh --main ${{ matrix.chart.directory }} | |
| bash scripts/generate-release-notes.sh --footer ${{ matrix.chart.directory }} | |
| # Verify release notes contain actual version matrix content | |
| if ! grep -q "Camunda images:" "${{ matrix.chart.directory }}/RELEASE-NOTES.md"; then | |
| echo "::error::RELEASE-NOTES.md is missing version matrix content - generation failed" | |
| cat ${{ matrix.chart.directory }}/RELEASE-NOTES.md | |
| exit 1 | |
| fi | |
| echo "Generated RELEASE-NOTES.md:" | |
| cat ${{ matrix.chart.directory }}/RELEASE-NOTES.md | |
| # | |
| # Package and publish | |
| # | |
| - name: Package Helm chart | |
| if: env.SKIP_BUILD == 'false' | |
| run: | | |
| helm version | |
| # Package WITHOUT --version flag to preserve Chart.yaml version (release version) | |
| # The Chart.yaml already contains the correct release version (e.g., 11.11.3) | |
| helm-cr package ./ --config ../../${{ env.CHART_RELEASER_CONFIG_FILE }} | |
| # The package filename will be based on Chart.yaml version | |
| PACKAGED_FILE=$(ls .cr-release-packages/${{ env.CHART_NAME }}-*.tgz) | |
| echo "Packaged: ${PACKAGED_FILE}" | |
| # Verify Chart.yaml inside has the release version | |
| echo "Verifying packaged Chart.yaml version:" | |
| tar -xzf "${PACKAGED_FILE}" -O ${{ env.CHART_NAME }}/Chart.yaml | grep "^version:" | |
| # Store the package filename for later steps | |
| echo "HELM_PACKAGE=${PACKAGED_FILE}" >> $GITHUB_ENV | |
| - name: Push Helm chart to Harbor | |
| if: env.SKIP_BUILD == 'false' | |
| env: | |
| CR_TOKEN: '${{ secrets.GITHUB_TOKEN }}' | |
| run: | | |
| source "${GITHUB_WORKSPACE}/scripts/harbor-retry.sh" | |
| OCI_REGISTRY="${HARBOR_REGISTRY_HOST}/${HARBOR_REGISTRY_PROJECT}" | |
| # helm push creates OCI tag from Chart.yaml version (the release version) | |
| # We need to retag to our dev tag and add rolling tag | |
| # helm push with retry and re-auth (most common 401 failure point) | |
| harbor_retry "helm push" helm push "${HELM_PACKAGE}" "oci://${OCI_REGISTRY}" | |
| cosign sign-blob -y ${HELM_PACKAGE} \ | |
| --bundle ".cr-release-packages/${{ env.CHART_RELEASE_COSIGN_BUNDLE_FILE }}" | |
| CHART_RELEASE_TAG_NAME="camunda-platform-${{ matrix.chart.version }}-${RELEASE_VERSION}" | |
| echo "CHART_RELEASE_TAG_NAME=camunda-platform-${{ matrix.chart.version }}-${RELEASE_VERSION}" >> $GITHUB_ENV | |
| cat .cr-release-packages/${{ env.CHART_RELEASE_COSIGN_BUNDLE_FILE }} | jq | |
| rekor_log_index="$(cat .cr-release-packages/${{ env.CHART_RELEASE_COSIGN_BUNDLE_FILE }} | jq '.rekorBundle.Payload.logIndex')" | |
| echo "CHART_RELEASE_COSIGN_REKOR_LOG_INDEX=${rekor_log_index}" >> $GITHUB_ENV | |
| cat << EOF > ${{ env.CHART_RELEASE_COSIGN_VERIFY_FILE }} | |
| # Rekor. | |
| echo "Rekor record:" | |
| echo "https://search.sigstore.dev/?logIndex=${rekor_log_index}" | |
| # Cosign. | |
| cosign verify-blob ${HELM_PACKAGE} \\ | |
| --bundle ".cr-release-packages/${{ env.CHART_RELEASE_COSIGN_BUNDLE_FILE }}" \\ | |
| --certificate-identity "${{ env.CHART_RELEASE_COSIGN_CERTIFICATE_IDENTITY }}" \\ | |
| --certificate-oidc-issuer "${{ env.CHART_RELEASE_COSIGN_CERTIFICATE_OIDC_ISSUER }}" | |
| EOF | |
| COSIGN_VERIFIED="$( | |
| cosign verify-blob ${HELM_PACKAGE} \ | |
| --bundle ".cr-release-packages/${{ env.CHART_RELEASE_COSIGN_BUNDLE_FILE }}" \ | |
| --certificate-identity "${{ env.CHART_RELEASE_COSIGN_CERTIFICATE_IDENTITY }}" \ | |
| --certificate-oidc-issuer "${{ env.CHART_RELEASE_COSIGN_CERTIFICATE_OIDC_ISSUER }}" 2>&1 | |
| )" | |
| echo COSIGN_VERIFIED="${COSIGN_VERIFIED}" >> $GITHUB_ENV | |
| COSIGN_METADATA="$(cat .cr-release-packages/${{ env.CHART_RELEASE_COSIGN_BUNDLE_FILE }} | jq .verificationMaterial.certificate.rawBytes | sed 's/"//g' | base64 -d | openssl x509 -noout -text - )" | |
| # funkiness to preserve newlines | |
| { | |
| echo "COSIGN_METADATA<<EOF" | |
| echo "$COSIGN_METADATA" | |
| echo "EOF" | |
| } >> "$GITHUB_ENV" | |
| # oras push with retry and re-auth | |
| harbor_retry "oras push" \ | |
| oras push ${OCI_REGISTRY}/${{ env.CHART_NAME }} .cr-release-packages/${{ env.CHART_RELEASE_COSIGN_BUNDLE_FILE }} | |
| # The helm push created a tag with the release version | |
| PUSHED_TAG="${RELEASE_VERSION}" | |
| echo "Pushed with tag: ${PUSHED_TAG}" | |
| # Get the digest for API operations | |
| DIGEST=$(helm pull "oci://${OCI_REGISTRY}/${{ env.CHART_NAME }}" --version "${PUSHED_TAG}" 2>&1 | grep -oP 'Digest: \K[^\s]+' || \ | |
| harbor_curl "https://${HARBOR_REGISTRY_HOST}/api/v2.0/projects/${HARBOR_REGISTRY_PROJECT}/repositories/${{ env.CHART_NAME }}/artifacts/${PUSHED_TAG}" | jq -r '.digest') | |
| echo "Artifact digest: ${DIGEST}" | |
| # Harbor API base URL for this artifact | |
| HARBOR_API="https://${HARBOR_REGISTRY_HOST}/api/v2.0/projects/${HARBOR_REGISTRY_PROJECT}/repositories/${{ env.CHART_NAME }}/artifacts/${DIGEST}/tags" | |
| # Add dev tag: {version}-dev-{sha} | |
| echo "Adding dev tag: ${DEV_TAG}" | |
| harbor_curl -X POST "${HARBOR_API}" \ | |
| -H "Content-Type: application/json" \ | |
| -d "{\"name\": \"${DEV_TAG}\"}" | |
| # Delete the release version tag (we only want dev tag for now) | |
| echo "Removing release version tag: ${PUSHED_TAG}" | |
| harbor_curl -X DELETE "${HARBOR_API}/${PUSHED_TAG}" | |
| # Add rolling tag: {chart-major}-dev-latest | |
| ROLLING_TAG="${CHART_MAJOR_VERSION}-dev-latest" | |
| echo "Removing existing rolling tag if present: ${ROLLING_TAG}" | |
| harbor_curl \ | |
| -X DELETE "https://${HARBOR_REGISTRY_HOST}/api/v2.0/projects/${HARBOR_REGISTRY_PROJECT}/repositories/${{ env.CHART_NAME }}/artifacts/${ROLLING_TAG}/tags/${ROLLING_TAG}" || true | |
| echo "Adding rolling tag: ${ROLLING_TAG}" | |
| harbor_curl -X POST "${HARBOR_API}" \ | |
| -H "Content-Type: application/json" \ | |
| -d "{\"name\": \"${ROLLING_TAG}\"}" | |
| echo "::notice::Pushed to Harbor with tags: ${DEV_TAG}, ${ROLLING_TAG}" | |
| # | |
| # Summary | |
| # | |
| - name: Add build info to workflow summary | |
| run: | | |
| # Extract key Camunda component versions from values.yaml | |
| # Component structure changed in 8.8: | |
| # - 8.6, 8.7: zeebe, operate, tasklist, identity (separate images) | |
| # - 8.8+: orchestration (single camunda image) + management identity | |
| # Use yq to extract image tags reliably | |
| get_tag() { | |
| local path=$1 | |
| yq -r "${path} // \"N/A\"" values.yaml | |
| } | |
| # Components that exist in all versions | |
| IMAGE_CONSOLE=$(get_tag '.console.image.tag') | |
| IMAGE_CONNECTORS=$(get_tag '.connectors.image.tag') | |
| IMAGE_OPTIMIZE=$(get_tag '.optimize.image.tag') | |
| IMAGE_WEBMODELER=$(get_tag '.webModeler.image.tag') | |
| # Version-specific components | |
| CAMUNDA_MINOR=$(echo "${{ env.CAMUNDA_VERSION }}" | sed 's/^8\.//') | |
| if [[ ${CAMUNDA_MINOR} -ge 8 ]]; then | |
| CHART_ARCHITECTURE="orchestration" | |
| IMAGE_CAMUNDA=$(get_tag '.orchestration.image.tag') | |
| IMAGE_MGMT_IDENTITY=$(get_tag '.identity.image.tag') | |
| else | |
| CHART_ARCHITECTURE="classic" | |
| IMAGE_ZEEBE=$(get_tag '.zeebe.image.tag') | |
| IMAGE_OPERATE=$(get_tag '.operate.image.tag') | |
| IMAGE_TASKLIST=$(get_tag '.tasklist.image.tag') | |
| IMAGE_IDENTITY=$(get_tag '.identity.image.tag') | |
| fi | |
| # Set up registry URL for summary | |
| OCI_REGISTRY="${HARBOR_REGISTRY_HOST}/${HARBOR_REGISTRY_PROJECT}" | |
| ROLLING_TAG="${CHART_MAJOR_VERSION}-dev-latest" | |
| if [[ "${{ env.SKIP_BUILD }}" == "true" ]]; then | |
| cat << EOF >> $GITHUB_STEP_SUMMARY | |
| ## 📦 Chart Build Skipped (Camunda ${{ env.CAMUNDA_VERSION }}) | |
| Dev package already exists for this commit. | |
| - **Dev Tag:** \`${DEV_TAG}\` | |
| - **Camunda Version:** \`${{ env.CAMUNDA_VERSION }}\` | |
| EOF | |
| else | |
| # Build summary based on architecture | |
| if [[ "${CHART_ARCHITECTURE}" == "orchestration" ]]; then | |
| # 8.8+ with orchestration cluster (single camunda image) | |
| cat << EOF >> $GITHUB_STEP_SUMMARY | |
| ## 📦 Dev Package Built ✅ (Camunda ${{ env.CAMUNDA_VERSION }}) | |
| ### Package Info | |
| | Property | Value | | |
| |----------|-------| | |
| | **Registry** | \`oci://${OCI_REGISTRY}\` | | |
| | **Chart** | \`${{ env.CHART_NAME }}\` | | |
| | **Dev Tag** | \`${DEV_TAG}\` | | |
| | **Rolling Tag** | \`${ROLLING_TAG}\` | | |
| | **Release Version (in Chart.yaml)** | \`${RELEASE_VERSION}\` | | |
| | **Camunda Version** | \`${{ env.CAMUNDA_VERSION }}\` | | |
| | **Commit** | [${{ env.SHORT_SHA }}](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}) | | |
| ### 🐳 Image Versions (from values.yaml) | |
| | Component | Version | | |
| |-----------|---------| | |
| | Camunda (Zeebe/Operate/Tasklist/Orch. Identity) | \`${IMAGE_CAMUNDA}\` | | |
| | Management Identity | \`${IMAGE_MGMT_IDENTITY}\` | | |
| | Optimize | \`${IMAGE_OPTIMIZE}\` | | |
| | Web Modeler | \`${IMAGE_WEBMODELER}\` | | |
| | Connectors | \`${IMAGE_CONNECTORS}\` | | |
| | Console | \`${IMAGE_CONSOLE}\` | | |
| > **Note:** Compare these versions with the release train announcement to verify this dev package has the correct versions for release. | |
| ### Install (requires Harbor access) | |
| \`\`\`bash | |
| helm registry login ${HARBOR_REGISTRY_HOST} | |
| helm install my-camunda-dev \\ | |
| oci://${OCI_REGISTRY}/${{ env.CHART_NAME }} \\ | |
| --version ${DEV_TAG} | |
| \`\`\` | |
| ### Cosign verified | |
| Verification status: ${COSIGN_VERIFIED} | |
| <details> | |
| <summary>View Cosign metadata</summary> | |
| \`\`\`bash | |
| $(echo "${COSIGN_METADATA}") | |
| \`\`\` | |
| </details> | |
| EOF | |
| else | |
| # 8.6, 8.7 with separate component images | |
| cat << EOF >> $GITHUB_STEP_SUMMARY | |
| ## 📦 Dev Package Built ✅ (Camunda ${{ env.CAMUNDA_VERSION }}) | |
| ### Package Info | |
| | Property | Value | | |
| |----------|-------| | |
| | **Registry** | \`oci://${OCI_REGISTRY}\` | | |
| | **Chart** | \`${{ env.CHART_NAME }}\` | | |
| | **Dev Tag** | \`${DEV_TAG}\` | | |
| | **Rolling Tag** | \`${ROLLING_TAG}\` | | |
| | **Release Version (in Chart.yaml)** | \`${RELEASE_VERSION}\` | | |
| | **Camunda Version** | \`${{ env.CAMUNDA_VERSION }}\` | | |
| | **Commit** | [${{ env.SHORT_SHA }}](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}) | | |
| ### 🐳 Image Versions (from values.yaml) | |
| | Component | Version | | |
| |-----------|---------| | |
| | Zeebe | \`${IMAGE_ZEEBE}\` | | |
| | Operate | \`${IMAGE_OPERATE}\` | | |
| | Tasklist | \`${IMAGE_TASKLIST}\` | | |
| | Identity | \`${IMAGE_IDENTITY}\` | | |
| | Optimize | \`${IMAGE_OPTIMIZE}\` | | |
| | Web Modeler | \`${IMAGE_WEBMODELER}\` | | |
| | Connectors | \`${IMAGE_CONNECTORS}\` | | |
| | Console | \`${IMAGE_CONSOLE}\` | | |
| > **Note:** Compare these versions with the release train announcement to verify this dev package has the correct versions for release. | |
| ### Install (requires Harbor access) | |
| \`\`\`bash | |
| helm registry login ${HARBOR_REGISTRY_HOST} | |
| helm install my-camunda-dev \\ | |
| oci://${OCI_REGISTRY}/${{ env.CHART_NAME }} \\ | |
| --version ${DEV_TAG} | |
| \`\`\` | |
| ### Cosign verified | |
| Verification status: ${COSIGN_VERIFIED} | |
| <details> | |
| <summary>View Cosign metadata</summary> | |
| \`\`\`bash | |
| $(echo "${COSIGN_METADATA}") | |
| \`\`\` | |
| </details> | |
| EOF | |
| fi | |
| fi | |
| notify-on-failure: | |
| name: Notify on Failure | |
| needs: [setup, build] | |
| if: failure() | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Import Vault secrets | |
| id: secrets | |
| uses: hashicorp/vault-action@892a26828f195e65540a40b4768ae4571f51ebfc # v4.0.0 | |
| with: | |
| url: ${{ secrets.VAULT_ADDR }} | |
| method: approle | |
| roleId: ${{ secrets.VAULT_ROLE_ID }} | |
| secretId: ${{ secrets.VAULT_SECRET_ID }} | |
| secrets: | | |
| secret/data/products/distribution/ci SLACK_DISTRO_BOT_WEBHOOK; | |
| exportEnv: false | |
| - name: Send Slack notification | |
| continue-on-error: true | |
| uses: slackapi/slack-github-action@45a88b9581bfab2566dc881e2cd66d334e621e2c # v3.0.3 | |
| with: | |
| webhook: ${{ steps.secrets.outputs.SLACK_DISTRO_BOT_WEBHOOK }} | |
| webhook-type: incoming-webhook | |
| payload: | | |
| blocks: | |
| - type: header | |
| text: | |
| type: plain_text | |
| text: "Chart Dev Build Failed" | |
| emoji: true | |
| - type: section | |
| text: | |
| type: mrkdwn | |
| text: | | |
| <!subteam^S05K9BK6RTK> :rotating_light: | |
| The *Chart Dev Build* pipeline has failed. | |
| *Chart version:* ${{ inputs.chart-version || 'all active versions' }} | |
| *Trigger:* ${{ github.event_name }} | |
| <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|View failed workflow> |