Skip to content

ci: automate helm chart release alongside package release#3439

Merged
nicktrn merged 2 commits intomainfrom
ci/automate-helm-chart-release
Apr 24, 2026
Merged

ci: automate helm chart release alongside package release#3439
nicktrn merged 2 commits intomainfrom
ci/automate-helm-chart-release

Conversation

@nicktrn
Copy link
Copy Markdown
Collaborator

@nicktrn nicktrn commented Apr 23, 2026

Wires up automatic Helm chart releases to ride along with the existing changeset-driven package release flow.

Today Chart.yaml is bumped by hand and release-helm.yml fires only when a human pushes a helm-v* tag. With this, the changeset release PR also carries a Chart.yaml bump so main always matches the published version, and release.yml invokes release-helm.yml via workflow_call after Docker images are published.

helm-v${VERSION} tag is pushed as a marker (same GITHUB_TOKEN trick as v.docker.*). Manual helm-v* tag flow still works. Chart.yaml consistency check in release-helm.yml is the safety net if the bump job ever drifts.

First rollout: the open changeset-release/main PR has stale Chart.yaml. Bump it manually on that branch before merging, otherwise the first automated helm release fails at the consistency check.

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Apr 23, 2026

⚠️ No Changeset found

Latest commit: a2e06d8

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 23, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: f6d39b5a-8f83-4c3d-b65b-7345f844575f

📥 Commits

Reviewing files that changed from the base of the PR and between 3590d97 and a2e06d8.

📒 Files selected for processing (1)
  • .github/workflows/release.yml
📜 Recent review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (30)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (6, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (7, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (8, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (7, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (5, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (1, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (8, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (2, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (4, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (1, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (3, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (5, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (6, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (2, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (4, 8)
  • GitHub Check: sdk-compat / Node.js 22.12 (ubuntu-latest)
  • GitHub Check: units / packages / 🧪 Unit Tests: Packages (1, 1)
  • GitHub Check: sdk-compat / Node.js 20.20 (ubuntu-latest)
  • GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - pnpm)
  • GitHub Check: typecheck / typecheck
  • GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - pnpm)
  • GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - npm)
  • GitHub Check: sdk-compat / Cloudflare Workers
  • GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - npm)
  • GitHub Check: sdk-compat / Bun Runtime
  • GitHub Check: sdk-compat / Deno Runtime
  • GitHub Check: audit
  • GitHub Check: Analyze (python)
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: Analyze (actions)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: nicktrn
Repo: triggerdotdev/trigger.dev PR: 2195
File: hosting/k8s/helm/Chart.yaml:1-18
Timestamp: 2025-06-25T13:18:44.103Z
Learning: For the Trigger.dev Helm chart, the chart name should be "trigger" (not "trigger-v4") since this is the first official chart release. Helper templates should use the actual chart name from .Chart.Name rather than hardcoded prefixes.
Learnt from: nicktrn
Repo: triggerdotdev/trigger.dev PR: 2195
File: .github/workflows/release-helm.yml:42-46
Timestamp: 2025-06-25T13:24:23.836Z
Learning: In .github/workflows/release-helm.yml, the user nicktrn confirmed that using 'entrypoint' with 'docker://' steps works fine, contrary to previous analysis suggesting it's unsupported.
🔇 Additional comments (2)
.github/workflows/release.yml (2)

145-150: LGTM — mirrors the existing Docker tag pattern.

The helm-v${VERSION} tag creation is symmetric with the v.docker.* tag step above, uses set -e for fail-fast, and relies on the same GITHUB_TOKEN flow. As noted in the PR description, this tag is just a marker (the actual release is driven via workflow_call), and the manual helm-v* trigger path in release-helm.yml remains intact.


163-176: LGTM — publish-helm is well-ordered and minimally permissioned.

  • Gating on needs: [release, publish-docker] with if: needs.release.outputs.published == 'true' correctly defers the chart release until after images are published and implicitly skips it when publish-docker fails (default needs behavior), which matches the stated intent of never shipping a chart that references nonexistent images.
  • chart_version maps to the workflow_call input declared in release-helm.yml (required string), and the consistency check in that workflow acts as a safety net against drift between Chart.yaml and the CLI package version bumped by changesets-pr.yml.
  • Permissions scoped to contents: write + packages: write align with the recent commit narrowing scope and are sufficient for tagging/release creation and OCI chart push via GITHUB_TOKEN (no id-token: write needed here).

One operational reminder from the PR description worth keeping visible: before the first automated rollout, hosting/k8s/helm/Chart.yaml must be bumped manually on the existing changeset-release/main PR, otherwise release-helm.yml's consistency check will fail this job on its first run.


Walkthrough

Adds automated Helm chart release steps across three workflows. .github/workflows/changesets-pr.yml gains a bump-chart-version job that reads the target version from packages/cli-v3/package.json, updates hosting/k8s/helm/Chart.yaml (version and appVersion), and commits/pushes to changeset-release/main only if the file changed. .github/workflows/release-helm.yml is converted to a reusable workflow (workflow_call) with a required chart_version input, prefers that input when extracting the version, and normalizes the release tag to helm-v{version}. .github/workflows/release.yml now creates a helm-v{version} git tag and conditionally invokes the reusable release-helm.yml via a new publish-helm job after successful package publishing.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Description check ❓ Inconclusive The description covers the key changes and context, but is missing several required template sections (Checklist, Testing, Changelog, Screenshots). Add the missing required sections from the template: complete the Checklist, describe Testing steps, add a Changelog entry, and include Screenshots if applicable.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: automating Helm chart release as part of the package release workflow.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ci/automate-helm-chart-release

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 5 additional findings.

Open in Devin Review

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
.github/workflows/release-helm.yml (1)

94-102: Harden against script injection by passing inputs via env.

${{ inputs.chart_version }} and ${{ github.ref_name }} are expanded directly into the shell script, which is the classic GitHub Actions script injection pattern. Practical risk is low here (workflow_dispatch requires write access and tag pushes require similar), but the mitigation is trivial and matches GitHub's security guidance.

🔒 Proposed hardening
       - name: Extract version from tag or input
         id: version
+        env:
+          CHART_VERSION_INPUT: ${{ inputs.chart_version }}
+          REF_NAME: ${{ github.ref_name }}
         run: |
-          if [ -n "${{ inputs.chart_version }}" ]; then
-            VERSION="${{ inputs.chart_version }}"
+          if [ -n "$CHART_VERSION_INPUT" ]; then
+            VERSION="$CHART_VERSION_INPUT"
           else
-            VERSION="${{ github.ref_name }}"
+            VERSION="$REF_NAME"
             VERSION="${VERSION#helm-v}"
           fi
           echo "version=$VERSION" >> $GITHUB_OUTPUT
           echo "Releasing version: $VERSION"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/release-helm.yml around lines 94 - 102, The script
currently expands `${{ inputs.chart_version }}` and `${{ github.ref_name }}`
directly into the shell which risks command injection; change the job step to
pass these values via environment variables (e.g., set CHART_VERSION and
REF_NAME in env) and reference those env vars inside the run block when setting
VERSION and writing to GITHUB_OUTPUT; update occurrences of VERSION, `${{
inputs.chart_version }}` and `${{ github.ref_name }}` in the step so the run
script uses safe shell variables like `$CHART_VERSION` / `$REF_NAME` instead of
interpolated GitHub expressions.
.github/workflows/changesets-pr.yml (1)

137-142: Consider using yq for YAML edits.

The sed approach works given current Chart.yaml formatting, but it's brittle to formatting changes (e.g., inline comments like version: 1.0.0 # ..., quoted values, or a stray trailing space after version:), which would silently be clobbered by the .* match. yq would preserve structure and be explicit about the fields being mutated.

♻️ Optional refactor using mikefarah/yq (pre-installed on ubuntu-latest runners)
       - name: Bump Chart.yaml
         run: |
           set -e
           VERSION=$(jq -r '.version' packages/cli-v3/package.json)
-          sed -i "s/^version:.*/version: ${VERSION}/" ./hosting/k8s/helm/Chart.yaml
-          sed -i "s/^appVersion:.*/appVersion: v${VERSION}/" ./hosting/k8s/helm/Chart.yaml
+          yq eval -i ".version = \"${VERSION}\"" ./hosting/k8s/helm/Chart.yaml
+          yq eval -i ".appVersion = \"v${VERSION}\"" ./hosting/k8s/helm/Chart.yaml

Note: pin yq via mikefarah/yq action if reproducibility matters.

Is mikefarah yq pre-installed on GitHub Actions ubuntu-latest runners in 2026?
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/changesets-pr.yml around lines 137 - 142, The current
"Bump Chart.yaml" step uses brittle sed replacements for Chart.yaml; replace the
two sed -i lines that update version and appVersion with mikefarah/yq
invocations that set .version and .appVersion explicitly from the VERSION
environment variable (ensuring appVersion is prefixed with "v"), and export
VERSION from packages/cli-v3/package.json as before; optionally pin/install
mikefarah/yq via the official action to guarantee availability and
reproducibility.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In @.github/workflows/changesets-pr.yml:
- Around line 137-142: The current "Bump Chart.yaml" step uses brittle sed
replacements for Chart.yaml; replace the two sed -i lines that update version
and appVersion with mikefarah/yq invocations that set .version and .appVersion
explicitly from the VERSION environment variable (ensuring appVersion is
prefixed with "v"), and export VERSION from packages/cli-v3/package.json as
before; optionally pin/install mikefarah/yq via the official action to guarantee
availability and reproducibility.

In @.github/workflows/release-helm.yml:
- Around line 94-102: The script currently expands `${{ inputs.chart_version }}`
and `${{ github.ref_name }}` directly into the shell which risks command
injection; change the job step to pass these values via environment variables
(e.g., set CHART_VERSION and REF_NAME in env) and reference those env vars
inside the run block when setting VERSION and writing to GITHUB_OUTPUT; update
occurrences of VERSION, `${{ inputs.chart_version }}` and `${{ github.ref_name
}}` in the step so the run script uses safe shell variables like
`$CHART_VERSION` / `$REF_NAME` instead of interpolated GitHub expressions.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 2bf7b606-4e4b-4081-a39a-63a1fc9bb5d0

📥 Commits

Reviewing files that changed from the base of the PR and between ca39956 and 3590d97.

📒 Files selected for processing (3)
  • .github/workflows/changesets-pr.yml
  • .github/workflows/release-helm.yml
  • .github/workflows/release.yml
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (31)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (7, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (6, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (1, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (3, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (8, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (4, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (7, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (5, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (8, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (5, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (6, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (4, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (1, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (3, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (2, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (2, 8)
  • GitHub Check: units / packages / 🧪 Unit Tests: Packages (1, 1)
  • GitHub Check: sdk-compat / Node.js 20.20 (ubuntu-latest)
  • GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - npm)
  • GitHub Check: sdk-compat / Node.js 22.12 (ubuntu-latest)
  • GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - npm)
  • GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - pnpm)
  • GitHub Check: sdk-compat / Deno Runtime
  • GitHub Check: sdk-compat / Bun Runtime
  • GitHub Check: typecheck / typecheck
  • GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - pnpm)
  • GitHub Check: sdk-compat / Cloudflare Workers
  • GitHub Check: audit
  • GitHub Check: Analyze (python)
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: Analyze (actions)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: nicktrn
Repo: triggerdotdev/trigger.dev PR: 2195
File: hosting/k8s/helm/Chart.yaml:1-18
Timestamp: 2025-06-25T13:18:44.103Z
Learning: For the Trigger.dev Helm chart, the chart name should be "trigger" (not "trigger-v4") since this is the first official chart release. Helper templates should use the actual chart name from .Chart.Name rather than hardcoded prefixes.
📚 Learning: 2026-04-15T15:39:06.868Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-15T15:39:06.868Z
Learning: When modifying any public package (`packages/*` or `integrations/*`), add a changeset using `pnpm run changeset:add`.

Applied to files:

  • .github/workflows/changesets-pr.yml
🔇 Additional comments (3)
.github/workflows/release.yml (2)

145-150: LGTM — mirrors the existing Docker tag pattern.

Tag-push with default GITHUB_TOKEN won't retrigger release-helm.yml's push: tags: helm-v* trigger, which is the intended behavior per the PR description (Helm runs via workflow_call, tag serves as a marker).


163-173: LGTM — dependency chain and gating look correct.

needs: [release, publish-docker] ensures the chart is only published after its referenced Docker images exist, and secrets: inherit propagates GITHUB_TOKEN for both the GHCR OCI push and the softprops/action-gh-release step in release-helm.yml.

.github/workflows/release-helm.yml (1)

132-132: LGTM — tag format now consistent across all invocation paths.

helm-v{version} matches both the push: tags: helm-v* trigger and the tag pushed from release.yml, so the draft release attaches to the expected tag regardless of how this workflow is invoked.

@nicktrn nicktrn added the ready label Apr 24, 2026
@nicktrn
Copy link
Copy Markdown
Collaborator Author

nicktrn commented Apr 24, 2026

ready

@nicktrn nicktrn merged commit 3446be7 into main Apr 24, 2026
59 of 68 checks passed
@nicktrn nicktrn deleted the ci/automate-helm-chart-release branch April 24, 2026 06:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants