-
-
Notifications
You must be signed in to change notification settings - Fork 959
fix(helm): support secrets.existingSecret for core secrets #2860
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
When users set secrets.enabled=false to use an external secret via secrets.existingSecret, the environment variables SESSION_SECRET, MAGIC_LINK_SECRET, ENCRYPTION_KEY, and MANAGED_WORKER_SECRET were not being populated from the secret. The templates only checked `if .Values.secrets.enabled` before setting these env vars. This change updates the condition to also check for `secrets.existingSecret`, so users can reference an existing Kubernetes Secret instead of having the chart create one. Fixes #2859 Co-authored-by: nicktrn <nicktrn@users.noreply.github.com>
⚠️ No Changeset found
Latest commit: 012b943
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
WalkthroughTwo Helm templates were changed to broaden the condition that injects secret-related environment variables: both supervisor.yaml (MANAGED_WORKER_SECRET) and webapp.yaml (SESSION_SECRET and related envs) now include these vars when either Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes 🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
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. Comment |
PR Review: fix(helm): support secrets.existingSecret for core secrets
Summary
This PR fixes a critical bug where users who set secrets.enabled=false and provide an external Kubernetes Secret via secrets.existingSecret were unable to deploy the Helm chart successfully. The fix is minimal, targeted, and correct.
Code Quality and Best Practices
Excellent aspects:
- The fix is minimal and focused - only 2 lines changed across 2 files
- The pattern used (
{{- if or .Values.secrets.enabled .Values.secrets.existingSecret }}) is idiomatic Helm templating - The change is consistent with how other
existingSecretpatterns are handled in the chart (e.g., PostgreSQL, Redis, ClickHouse, S3) - The
trigger-v4.secretsNamehelper (lines 466-475 in_helpers.tpl) already correctly handlesexistingSecret, so the fix properly leverages existing infrastructure
Validation:
secrets.yamlcorrectly creates secrets only whensecrets.enabled=trueANDexistingSecretis not set (line 1)- The helper function
trigger-v4.secretsNameproperly returns either theexistingSecretname or generates one - The fix aligns environment variable injection with the secret name resolution logic
Potential Bugs or Issues
None identified. The logic is sound:
- When
secrets.enabled=true: Environment variables are set (existing behavior preserved) - When
secrets.existingSecretis set: Environment variables are set from the external secret - When both are false/empty: Environment variables are not set (correct - no source available)
One minor documentation consideration: The values.yaml comments (lines 26-30) already document that existingSecret must contain the required keys (SESSION_SECRET, MAGIC_LINK_SECRET, ENCRYPTION_KEY, MANAGED_WORKER_SECRET), which is helpful for users.
Performance Considerations
No performance impact. This is a template-time condition evaluation that doesn't affect runtime behavior.
Security Concerns
None identified. The fix actually improves security posture by enabling users to:
- Use external secret management systems (Vault, External Secrets Operator, Infisical, etc.)
- Avoid hardcoding secrets in Helm values
- Follow Kubernetes secrets management best practices
Test Coverage
Recommendation: While there are no automated Helm template tests visible in the PR, manual testing should verify:
- Deployment with
secrets.enabled=true(regression test) - Deployment with
secrets.enabled=falseandsecrets.existingSecretset (new functionality) - Verification that all four environment variables (
SESSION_SECRET,MAGIC_LINK_SECRET,ENCRYPTION_KEY,MANAGED_WORKER_SECRET) are properly injected in both scenarios
Overall Assessment
Approve - This is a well-implemented bug fix that:
- Solves the reported issue (Self-hosting: using Kubernetes Secrets instead of hardcoded values is not working #2859 )
- Is minimal and low-risk
- Follows existing patterns in the codebase
- Enables a security best practice (external secret management)
The only suggestion would be to consider adding Helm template tests (e.g., using helm-unittest) to prevent similar regressions in the future, but this is outside the scope of this PR.
Review Complete
Your review story is ready!
Comment !reviewfast on this PR to re-generate the story.
nicktrn
commented
Jan 9, 2026
@claude check if we could easily add helm chart prereleases for prs like this one. i want to avoid having to manually trigger releases. desired outcome: pr that touches helm chart files -> helm prerelease. note that semver app version selectors like ~4.0.0 should not match prereleases
|
Claude finished @nicktrn's task in 1m 54s —— View job Helm Chart Prerelease Automation Analysis
SummaryYes, this can be easily implemented. Here's my analysis: Current State
Semver Prerelease Behavior (Good News)Per the semver spec, version constraints like
Users with Recommended ImplementationCreate a new workflow name: 🧭 Helm Chart PR Prerelease on: pull_request: types: [opened, synchronize, reopened] paths: - 'hosting/k8s/helm/**' env: REGISTRY: ghcr.io CHART_NAME: trigger jobs: lint-and-test: runs-on: ubuntu-latest permissions: contents: read steps: - name: Checkout uses: actions/checkout@v4 - name: Set up Helm uses: azure/setup-helm@v4 with: version: "3.18.3" - name: Build dependencies run: helm dependency build ./hosting/k8s/helm/ - name: Extract dependency charts run: | cd ./hosting/k8s/helm/ for file in ./charts/*.tgz; do echo "Extracting $file"; tar -xzf "$file" -C ./charts; done - name: Lint Helm Chart run: helm lint ./hosting/k8s/helm/ - name: Render templates run: | helm template test-release ./hosting/k8s/helm/ \ --values ./hosting/k8s/helm/values.yaml \ --output-dir ./helm-output - name: Validate manifests uses: docker://ghcr.io/yannh/kubeconform:v0.7.0 with: entrypoint: '/kubeconform' args: "-summary -output json ./helm-output" prerelease: needs: lint-and-test runs-on: ubuntu-latest permissions: contents: read packages: write steps: - name: Checkout uses: actions/checkout@v4 - name: Set up Helm uses: azure/setup-helm@v4 with: version: "3.18.3" - name: Build dependencies run: helm dependency build ./hosting/k8s/helm/ - name: Extract dependency charts run: | cd ./hosting/k8s/helm/ for file in ./charts/*.tgz; do echo "Extracting $file"; tar -xzf "$file" -C ./charts; done - name: Log in to Container Registry uses: docker/login-action@v3 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Generate prerelease version id: version run: | BASE_VERSION=$(grep '^version:' ./hosting/k8s/helm/Chart.yaml | awk '{print 2ドル}') PR_NUMBER=${{ github.event.pull_request.number }} RUN_NUMBER=${{ github.run_number }} PRERELEASE_VERSION="${BASE_VERSION}-pr${PR_NUMBER}.${RUN_NUMBER}" echo "version=$PRERELEASE_VERSION" >> $GITHUB_OUTPUT echo "Prerelease version: $PRERELEASE_VERSION" - name: Update Chart.yaml with prerelease version run: | sed -i "s/^version:.*/version: ${{ steps.version.outputs.version }}/" ./hosting/k8s/helm/Chart.yaml - name: Package Helm Chart run: | helm package ./hosting/k8s/helm/ --destination /tmp/ - name: Push Helm Chart to GHCR run: | VERSION="${{ steps.version.outputs.version }}" CHART_PACKAGE="/tmp/${{ env.CHART_NAME }}-${VERSION}.tgz" helm push "$CHART_PACKAGE" "oci://${{ env.REGISTRY }}/${{ github.repository_owner }}/charts" - name: Add PR comment with install instructions uses: actions/github-script@v7 with: script: | const version = '${{ steps.version.outputs.version }}'; const body = `### 🧭 Helm Chart Prerelease Published **Version:** \`${version}\` **Install:** \`\`\`bash helm upgrade --install trigger \\ oci://ghcr.io/${{ github.repository_owner }}/charts/trigger \\ --version "${version}" \`\`\` > ⚠️ This is a prerelease for testing. Do not use in production.`; github.rest.issues.createComment({ issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, body: body }); Key Features
Alternative: Simpler ApproachIf you want to minimize CI complexity, you could instead just add a Helm lint job to Let me know if you'd like me to implement this workflow! |
nicktrn
commented
Jan 9, 2026
@claude looks great, can you add that workflow to this pr to test? also, make sure this is based on our existing helm workflow as we know it works. something we'll have to figure out: when we keep pushing to the same branch / pr we shouldn't keep adding comments each time but instead just update the existing comment. don't create a gh release btw, no need
Claude finished @nicktrn's task in 1m 46s —— View job
Adding Helm Chart Prerelease Workflow
- Read the existing Helm release workflow
- Create the prerelease workflow based on the existing one
- Handle comment updating (not creating new comments each time)
-
(削除) Commit and push the changes (削除ここまで)— blocked by permissions
Summary
I created the workflow file but cannot push it due to GitHub App permissions. The GitHub App does not have workflows permission, which is required to create or modify files in .github/workflows/.
The workflow file is ready at .github/workflows/helm-prerelease.yml. Here's what it does:
Key Features
- Triggers on PRs that touch
hosting/k8s/helm/**files - Based on existing release workflow — uses same lint/test steps, helm version, kubeconform validation
- Updates existing comment instead of creating new ones on each push:
- Uses
peter-evans/find-commentto find existing bot comment - Uses
peter-evans/create-or-update-commentwithedit-mode: replace
- Uses
- No GH release — just pushes to GHCR OCI registry
- Unique version format:
{base_version}-pr{pr_number}.{short_sha}(e.g.,4.0.5-pr2860.abc1234)
To apply this workflow, you have two options:
Option 1: Add the file manually with this content:
Click to expand workflow file
name: 🧭 Helm Chart PR Prerelease on: pull_request: types: [opened, synchronize, reopened] paths: - "hosting/k8s/helm/**" env: REGISTRY: ghcr.io CHART_NAME: trigger jobs: lint-and-test: runs-on: ubuntu-latest permissions: contents: read steps: - name: Checkout uses: actions/checkout@v4 - name: Set up Helm uses: azure/setup-helm@v4 with: version: "3.18.3" - name: Build dependencies run: helm dependency build ./hosting/k8s/helm/ - name: Extract dependency charts run: | cd ./hosting/k8s/helm/ for file in ./charts/*.tgz; do echo "Extracting $file"; tar -xzf "$file" -C ./charts; done - name: Lint Helm Chart run: | helm lint ./hosting/k8s/helm/ - name: Render templates run: | helm template test-release ./hosting/k8s/helm/ \ --values ./hosting/k8s/helm/values.yaml \ --output-dir ./helm-output - name: Validate manifests uses: docker://ghcr.io/yannh/kubeconform:v0.7.0 with: entrypoint: "/kubeconform" args: "-summary -output json ./helm-output" prerelease: needs: lint-and-test runs-on: ubuntu-latest permissions: contents: read packages: write pull-requests: write steps: - name: Checkout uses: actions/checkout@v4 - name: Set up Helm uses: azure/setup-helm@v4 with: version: "3.18.3" - name: Build dependencies run: helm dependency build ./hosting/k8s/helm/ - name: Extract dependency charts run: | cd ./hosting/k8s/helm/ for file in ./charts/*.tgz; do echo "Extracting $file"; tar -xzf "$file" -C ./charts; done - name: Log in to Container Registry uses: docker/login-action@v3 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Generate prerelease version id: version run: | BASE_VERSION=$(grep '^version:' ./hosting/k8s/helm/Chart.yaml | awk '{print 2ドル}') PR_NUMBER=${{ github.event.pull_request.number }} SHORT_SHA=$(echo "${{ github.event.pull_request.head.sha }}" | cut -c1-7) PRERELEASE_VERSION="${BASE_VERSION}-pr${PR_NUMBER}.${SHORT_SHA}" echo "version=$PRERELEASE_VERSION" >> $GITHUB_OUTPUT echo "Prerelease version: $PRERELEASE_VERSION" - name: Update Chart.yaml with prerelease version run: | sed -i "s/^version:.*/version: ${{ steps.version.outputs.version }}/" ./hosting/k8s/helm/Chart.yaml - name: Package Helm Chart run: | helm package ./hosting/k8s/helm/ --destination /tmp/ - name: Push Helm Chart to GHCR run: | VERSION="${{ steps.version.outputs.version }}" CHART_PACKAGE="/tmp/${{ env.CHART_NAME }}-${VERSION}.tgz" # Push to GHCR OCI registry helm push "$CHART_PACKAGE" "oci://${{ env.REGISTRY }}/${{ github.repository_owner }}/charts" - name: Find existing comment uses: peter-evans/find-comment@v3 id: find-comment with: issue-number: ${{ github.event.pull_request.number }} comment-author: "github-actions[bot]" body-includes: "Helm Chart Prerelease Published" - name: Create or update PR comment uses: peter-evans/create-or-update-comment@v4 with: comment-id: ${{ steps.find-comment.outputs.comment-id }} issue-number: ${{ github.event.pull_request.number }} body: | ### 🧭 Helm Chart Prerelease Published **Version:** `${{ steps.version.outputs.version }}` **Install:** ```bash helm upgrade --install trigger \ oci://ghcr.io/${{ github.repository_owner }}/charts/trigger \ --version "${{ steps.version.outputs.version }}" ``` > ⚠️ This is a prerelease for testing. Do not use in production. edit-mode: replace
Option 2: Grant the GitHub App workflows permission and ask me again.
🧭 Helm Chart Prerelease Published
Version: 4.0.5-pr2860.012b943
Install:
helm upgrade --install trigger \
oci://ghcr.io/triggerdotdev/charts/trigger \
--version "4.0.5-pr2860.012b943"
⚠️ This is a prerelease for testing. Do not use in production.
PR Review: fix(helm): support secrets.existingSecret for core secrets
Summary
This PR fixes issue #2859 where users setting secrets.enabled=false with secrets.existingSecret could not properly use external secrets for core environment variables (SESSION_SECRET, MAGIC_LINK_SECRET, ENCRYPTION_KEY, MANAGED_WORKER_SECRET).
✅ Code Quality and Best Practices
The Helm template fix is correct and minimal:
The change from:
{{- if .Values.secrets.enabled }}to:
{{- if or .Values.secrets.enabled .Values.secrets.existingSecret }}is the right approach. The trigger-v4.secretsName helper in _helpers.tpl (lines 469-475) already correctly handles both cases:
- Returns
secrets.existingSecretwhen set - Falls back to generated secret name otherwise
The GitHub workflow follows existing patterns and is consistent with release-helm.yml.
⚠️ Potential Issues
-
Workflow file scope creep: The PR description focuses on fixing
secrets.existingSecretsupport, but it also introduces a new GitHub workflow (helm-pr-prerelease.yml). While useful, this is unrelated to the bug fix and should ideally be a separate PR for cleaner history and easier rollback if needed. -
Workflow hardcodes Helm version: Both the new workflow and the existing release workflow hardcode
version: "3.18.3". Consider extracting this to an env variable or workflow input to simplify updates. -
Missing error handling in workflow: The prerelease workflow's version extraction step:
BASE_VERSION=$(grep '^version:' ./hosting/k8s/helm/Chart.yaml | awk '{print 2ドル}')doesn't validate that
BASE_VERSIONwas successfully extracted. IfChart.yamlhas an unexpected format, this could produce an invalid version string silently.
🔒 Security Considerations
No security concerns identified. The changes correctly reference existing secrets without exposing sensitive values. The workflow uses GITHUB_TOKEN with appropriate permissions (packages: write, pull-requests: write).
⚡ Performance Considerations
No performance concerns. The template changes add a simple or condition which has negligible impact.
🧪 Test Coverage
Positive aspects:
- The new workflow includes lint and validation steps (
helm lint,kubeconform) - Template rendering is validated before packaging
Suggestions:
-
Consider adding a test case that renders templates with
secrets.enabled=falseandsecrets.existingSecret="my-secret"to verify the fix works:helm template test ./hosting/k8s/helm/ \ --set secrets.enabled=false \ --set secrets.existingSecret=my-existing-secretThis would catch regressions.
-
The workflow doesn't test the specific scenario this PR fixes. A values file override testing
existingSecretwould be valuable.
📋 Recommendations
- Consider splitting the workflow addition into a separate PR
- Add a brief comment in
values.yamlclarifying that when usingexistingSecret,enabledcan be eithertrueorfalse(or document thatenabled: falseis the expected pattern) - Validate version extraction in the workflow with a check like:
if [ -z "$BASE_VERSION" ]; then echo "Failed to extract version from Chart.yaml" exit 1 fi
✅ Verdict
The core fix (2 lines changed in Helm templates) is correct and ready to merge. The fix properly enables existingSecret to work as documented.
The workflow addition is a nice enhancement but could be separated for cleaner PR scope.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In @.github/workflows/helm-pr-prerelease.yml:
- Around line 34-37: Remove the whole CI step titled "Extract dependency charts"
that runs the for-loop extracting ./charts/*.tgz; delete that step from the helm
workflow (and the equivalent step in the release workflow) so the pipeline
relies on `helm dependency build` and keeps .tgz files intact for `helm lint`,
`helm template`, and `helm package`; ensure no other steps expect extracted
chart directories and leave the rest of the workflow unchanged.
🧹 Nitpick comments (2)
.github/workflows/helm-pr-prerelease.yml (2)
31-37: Consider extracting common setup steps (optional).The checkout, Helm setup, and dependency build steps are duplicated between both jobs. While this keeps jobs independent, you could optionally refactor common setup into a composite action or use job outputs to reduce duplication.
However, the current approach is straightforward and maintainable, so this is just a suggestion for future improvement.
Also applies to: 71-77
26-29: Consider upgrading to Helm 4.0.4 (the current stable release as of January 2026).Helm 3.18.3 is a valid release, but Helm 4 was released in November 2025, and version 4.0.4 is now the latest stable release. If Kubernetes compatibility with versions 1.30–1.33 is required, Helm 3.18.3 remains suitable; otherwise, evaluate upgrading to the current major version for latest features and support.
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
.github/workflows/helm-pr-prerelease.yml
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: nicktrn
Repo: triggerdotdev/trigger.dev PR: 2195
File: hosting/k8s/helm/values-production-example.yaml:95-102
Timestamp: 2025年06月25日T14:14:11.965Z
Learning: In the Trigger.dev Helm chart production examples, the maintainer prefers to include initial/bootstrap credentials with clear warnings that they should be changed after first login, rather than requiring external secret references that could complicate initial setup. This follows their pattern of providing working examples with explicit security guidance.
Learnt from: nicktrn
Repo: triggerdotdev/trigger.dev PR: 2195
File: hosting/k8s/helm/values.yaml:22-51
Timestamp: 2025年06月25日T13:20:17.174Z
Learning: In the Trigger.dev Helm chart values.yaml, the maintainer prefers to use explicit comprehensive warnings for security-sensitive default values rather than implementing secure-by-default behavior that would fail installation. The project uses deterministic default secrets with clear "TESTING ONLY" warnings and instructions for production deployment.
Learnt from: julienvanbeveren
Repo: triggerdotdev/trigger.dev PR: 2417
File: apps/webapp/app/routes/api.v1.projects.$projectRef.envvars.$slug.import.ts:56-61
Timestamp: 2025年08月19日T09:49:07.011Z
Learning: In the Trigger.dev codebase, environment variables should default to `isSecret: false` when not explicitly marked as secrets in the syncEnvVars functionality. This is the intended behavior for both regular variables and parent variables.
⏰ 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). (24)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (3, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (7, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (4, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (3, 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 (5, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (8, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (2, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (8, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (2, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (7, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (6, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (4, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (5, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (1, 8)
- GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - pnpm)
- GitHub Check: units / packages / 🧪 Unit Tests: Packages (1, 1)
- GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - npm)
- GitHub Check: typecheck / typecheck
- GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - npm)
- GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - pnpm)
- GitHub Check: claude-review
- GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (4)
.github/workflows/helm-pr-prerelease.yml (4)
1-16: LGTM: Workflow configuration is well-structured.The trigger conditions, concurrency control, and environment setup are appropriate for a PR-based Helm prerelease workflow. The path filter ensures the workflow only runs when Helm chart files change, and the concurrency group prevents duplicate runs for the same PR.
86-94: LGTM: Version generation logic is well-designed.The prerelease versioning scheme (
BASE_VERSION-prNUMBER.SHA) is appropriate:
- Follows semver prerelease conventions
- Ensures uniqueness per PR and commit
- Won't match standard semver selectors (as intended per requirements)
112-138: LGTM: PR comment approach correctly implements requirements.The workflow properly:
- Finds existing comments to avoid duplicates when the PR is updated
- Uses
edit-mode: replaceto update rather than append- Provides clear installation instructions with OCI registry syntax
- Includes appropriate warnings about prerelease usage
- Avoids creating GitHub releases (as requested)
This implementation aligns perfectly with the stated requirements.
49-53: No action required — kubeconform:v0.7.0 is the latest stable release as of January 2026.The version specified in the workflow is current.
Likely an incorrect or invalid review comment.
Uh oh!
There was an error while loading. Please reload this page.
When users set
secrets.enabled=falseto use an external secret viasecrets.existingSecret, the environment variablesSESSION_SECRET,MAGIC_LINK_SECRET,ENCRYPTION_KEY, andMANAGED_WORKER_SECRETwere not being populated from the secret.Fixes #2859
Also adds automatic helm prereleases for PRs