Split package publish from Docker and Helm release - #861
ramantehlan wants to merge 5 commits into
Conversation
Remove the npm-install Dockerfile so Docker and Helm no longer wait for npm, and publish the chart in the same image workflow instead of a bot PR. Signed-off-by: Raman Tehlan <ramantehlan@gmail.com>
|
Rename the package workflow to release-packages.yml, drop the Helm tag-retry job, and start the chart workflow on main with its own Changesets select-mode. Signed-off-by: Raman Tehlan <ramantehlan@gmail.com>
The package workflow now pushes chart/v<version> in parallel with npm and PyPI, and release-chart.yml builds the image and publishes the chart from that tag. Drops the chart-release bot PR and merge gate. Signed-off-by: Raman Tehlan <ramantehlan@gmail.com>
Replay chart metadata onto origin/main with the App token, treat an already-published OCI version as success, and leave the npm-install controller command in values.yaml until that publish rewrites it. Signed-off-by: Raman Tehlan <ramantehlan@gmail.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 755405b. Configure here.
| exit 1 | ||
| fi | ||
| SHORT_SHA="${GITHUB_SHA:0:7}" | ||
| IMAGE_TAG="${APP_VERSION}-${SHORT_SHA}" |
There was a problem hiding this comment.
Image tag uses annotated tag SHA
Medium Severity
The automated chart path creates an annotated chart/v* tag, then tags the image with the first seven characters of GITHUB_SHA. On an annotated-tag push that value is the tag object, not the commit, so {version}-{shortSha} no longer matches the build commit. A later dispatch rebuild of the same commit gets a different image tag, and the reusable build checkout may also receive that tag-object SHA.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 755405b. Configure here.
| drainingSeconds: 35, | ||
| }, | ||
| env: { | ||
| // From-source image; root Dockerfile is the published npm recipe and needs APP_VERSION. |
There was a problem hiding this comment.
Railway still points at deleted Dockerfile
High Severity
Existing Railway services still have RAILWAY_DOCKERFILE_PATH=Dockerfile.dev from the previous IaC apply. This change deletes Dockerfile.dev and only drops that env from railway.ts, which does not update already-applied services. The next git-triggered rebuild looks for a file that is gone and fails until someone re-applies IaC.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 755405b. Configure here.
| # dist/controller-main.js when it publishes a from-source image. | ||
| command: | ||
| - node | ||
| - node_modules/@truefoundry/trueforge/dist/controller-main.js |
There was a problem hiding this comment.
Is this still correct?
from what I understand, it should be
| - node_modules/@truefoundry/trueforge/dist/controller-main.js | |
| - dist/controller-main.js |
There was a problem hiding this comment.
should we just keep the old contents of this as Dockerfile.npm ?
There was a problem hiding this comment.
where is this workflow used? we probably don't have use case for it
we can keep it, but rename to build-image.yml
There was a problem hiding this comment.
let's not change the filename here please, all trusted publishing will break
we can do it as a separate activity
| push: | ||
| tags: | ||
| - 'charts/trueforge@*' | ||
| - 'chart/v[0-9]*' |
There was a problem hiding this comment.
keep it same as before please?
'charts/trueforge@*'
It can be changed as part of new release process PRs
| yq -i '.version = strenv(VERSION)' charts/trueforge/Chart.yaml | ||
| yq -i '.appVersion = strenv(APP_VERSION)' charts/trueforge/Chart.yaml | ||
| yq -i '.image.tag = strenv(IMAGE_TAG)' charts/trueforge/values.yaml | ||
| yq -i '.controller.command = ["node", "dist/controller-main.js"]' charts/trueforge/values.yaml |
There was a problem hiding this comment.
this doesn't need to be here, it can be just part of values directly?
| helm push "$PACKAGE" "oci://$HELM_CHART_REPOSITORY" | ||
| set +e | ||
| PUSH_OUT=$(helm push "$PACKAGE" "oci://$HELM_CHART_REPOSITORY" 2>&1) | ||
| PUSH_RC=$? |
There was a problem hiding this comment.
what does RC in PUSH_RC mean here? 😅


Summary
release-packages.yml(wasrelease.yml) stays packages-only work plus one extra job: after pack and Windows smoke, npm publish, PyPI publish, and Create release tag (chart/v<packages/trueforge version>) run in parallel. The tag is pushed with the GitHub App token becauseGITHUB_TOKENtag pushes do not start other workflows.release-chart.ymlis triggered by thatchart/v*tag (or manual dispatch). It builds the from-source image, packages and pushes the Helm chart to OCI, and commits the chart metadata back tomain. No chart-release bot PR and no merge gate.Dockerfile(the formerDockerfile.dev); the npm-install image is gone. The Helm controller command matches it (node dist/controller-main.js).versionis locked to the same major.minor as@truefoundry/trueforge, so chart, package, and image tag prefix stay aligned (scripts/resolve-chart-version.sh).Release flows
1. Version or publish packages -
release-packages.yml2. Build server image and publish Helm chart -
release-chart.ymlflowchart LR trigger["Trigger<br/>push of chart/v* tag<br/>or manual workflow_dispatch<br/>(optional app_version)"] resolve["Resolve versions<br/>(tag must match package.json)"] build["Build and push server image<br/>{version}-{shortSha}"] publishChart["Publish Helm chart<br/>bump, lint, package, OCI push,<br/>commit chart files to main"] trigger --> resolve resolve --> build resolve --> publishChart build --> publishChartHow they connect
Test plan
release-packages.ymlbefore the first publish (they were bound torelease.yml).chart/v*tag job all start after pack and smoke, in parallel.chart/v*tag push startsrelease-chart.yml(needs the App token, notGITHUB_TOKEN).Dockerfile, tag{version}-{shortSha}) and the chart is pushed to OCI with the same major.minor as the package.main(Chart.yaml,values.yaml).Dockerfile, and the controller starts withnode dist/controller-main.js.gh workflow run release-chart.yml --ref main.Note
High Risk
Changes production release automation, how prod images are built, and CI pushes chart metadata directly to protected
main; misconfiguration can break publishes or ship mismatched chart/image versions.Overview
Decouples npm/PyPI publishing from container and Helm releases, and replaces the npm-install production image with a single from-source root
Dockerfile(formerDockerfile.devis removed).After pack and Windows smoke,
release-packages.yml(renamed fromrelease.yml) now runs npm, PyPI, and a newchart/v<version>tag job in parallel (App token so the tag can trigger downstream workflows). It no longer waits on npm or calls the deletedbuild-and-prepare-chart-release.yml/release-chart/trueforgebot PR flow.release-chart.ymlis driven bychart/v*tags (or manual dispatch): resolve versions frompackages/trueforge/package.json, build and push{version}-{shortSha}from the workspace Dockerfile, lint/package/push the Helm chart (treats registry “already exists” as success), then commitChart.yamlandvalues.yamltomainwith controller commandnode dist/controller-main.js.scripts/resolve-chart-version.shnow pins chart major.minor to the app package so chart, package, and image tag prefix stay aligned. Compose, Railway IaC, dev image workflow, and docs are updated to build the rootDockerfile.Ops note: npm and PyPI trusted publishers must be updated to workflow filename
release-packages.ymlbefore the next publish.Reviewed by Cursor Bugbot for commit 755405b. Bugbot is set up for automated code reviews on this repo. Configure here.