Before the first public release, configure npm Trusted Publishing for this repository.
- Create or use the npm account that can publish
@roastcodes/ttdash - Enable 2FA on that npm account
- Ensure you have publish rights in the
roastcodesnpm organization - In npm package settings, add this GitHub repository as a trusted publisher for
@roastcodes/ttdash - Confirm the GitHub Actions release workflow is allowed to request an OIDC token
- Install the
ttdash-releaseGitHub App onroastcodes/ttdash - Add
APP_CLIENT_IDandAPP_PRIVATE_KEYas Actions secrets for this repository or thereleaseenvironment - Add
OP_SERVICE_ACCOUNT_TOKEN_PUBLICas an Actions secret for this repository or thereleaseenvironment - Add
OP_SSH_BASE_URLas an Actions secret for this repository or thereleaseenvironment, point it to the shared 1Password item prefix for the release signer, and make sure it ends with a trailing/(otherwise the workflow fails its format-validation step before it attempts to load secrets) - Add the
ttdash-releaseGitHub App as a bypass actor in themainruleset
The release workflow loads the SSH signing identity from 1Password through the public-repo service account token. OP_SSH_BASE_URL must contain only the common item prefix and must end with /, for example op://vault/item/, while the workflow appends name, comment, public key, and private key?ssh-format=openssh internally. The workflow validates this format before loading secrets and exits early with a format error if the trailing slash is missing. The SSH public key must remain added to the maintainer GitHub account as an SSH signing key, and the signing email used by the workflow must stay valid for both GitHub verification and the roastcodes organization trailer.
Trusted Publishing is preferred because it avoids long-lived npm tokens and enables provenance for public publishes.
If you want npm provenance on the published package, the GitHub repository must be public when the release workflow runs.
Before using the manual release workflow, make sure:
mainis protected and requires theCIstatus check before merges- CodeQL is enabled in the GitHub UI if you want it as a manual release gate
- the
ttdash-releaseGitHub App is allowed to push the version-bump commit and signed tag back tomain - the
roast.codesdomain remains verified for theroastcodesorganization so the workflow-createdon-behalf-of: @roastcodes <github@roast.codes>trailer continues to render correctly on GitHub (check GitHub organization settings under verified domains; if verification lapses, restore or confirm the DNS TXT record and re-verify the domain as documented at https://docs.github.com/en/organizations/managing-organization-settings/verifying-or-approving-a-domain-for-your-organization)
If branch protection or rulesets block the ttdash-release app from writing to main or pushing v* tags, the workflow will fail when it tries to push the release commit or tag.
- Merge the intended release state to
main - Confirm the latest
CIrun onmainsucceeded - Confirm CodeQL is green in the GitHub UI
- Start the
Releaseworkflow manually from GitHub Actions and provide the target version inx.y.zformat
Optional local confidence check before starting the workflow:
npm run verify:fullIf port 3015 is already occupied locally, keep the same one-pass gate and only override the Playwright port:
PLAYWRIGHT_TEST_PORT=3016 npm_config_cache=/tmp/ttdash-npm-cache npm run verify:fullOn a manual workflow_dispatch run against main, the workflow:
-
verifies the requested version is greater than the current
package.jsonversion or resumes a partially completed release when the requested version is already onmain -
verifies the latest
CIrun for the currentmaincommit succeeded -
bumps
package.jsonandpackage-lock.jsonto the requested version -
runs
prettier --check, ESLint, andtsc --noEmit -
runs unit/integration tests with coverage
-
builds the production bundle
-
verifies the packed npm artifact
-
runs the Playwright smoke suite
-
loads the SSH signing identity from 1Password and verifies the signing setup locally in the runner
-
creates and pushes the signed release commit and signed tag, with the release commit carrying
on-behalf-of: @roastcodes <github@roast.codes> -
publishes
@roastcodes/ttdashto npm through Trusted Publishing -
waits for npm registry propagation
-
verifies:
npx --yes @roastcodes/ttdash@<version> --helpbunx @roastcodes/ttdash@<version> --help
-
creates the GitHub release
Note: the workflow reruns the release-critical test suite itself after the version bump. This is necessary because the workflow-created push back to main should not be relied on to trigger the normal CI workflow again.
If a release fails after the version bump was already pushed, rerunning the workflow with the same version resumes that release only when all retry conditions still hold:
mainstill points at the originalvX.Y.Z: Releasecommit- any pre-existing
vX.Y.Ztag is already signed - any pre-existing
vX.Y.Ztag points at that same release commit
If new commits landed on main in the meantime, or an existing tag does not match the release commit, the workflow aborts early and you should cut a new version instead of retrying the old one.
After the workflow succeeds, run a final sanity check:
npm view @roastcodes/ttdash version description bin --json
npx --yes @roastcodes/ttdash@latest --help
bunx @roastcodes/ttdash@latest --helpOptional runtime smoke test:
NO_OPEN_BROWSER=1 PORT=3010 npx --yes @roastcodes/ttdash@latestThen open http://127.0.0.1:3010.