Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,9 @@ Changelog guidance:
Manual fallback (maintainers only):

- On the generated version PR's merged commit: `corepack yarn release:publish`.
- This publishes Viewer with its explicit `alpha` tag, then uses `changeset publish` for the
remaining packages and `changeset tag` for release discovery. A failed registry lookup stops the
- This publishes Viewer with its explicit `alpha` tag, then uses `changeset publish --no-git-tag`
for the remaining packages and one `changeset tag` pass for release discovery. Duplicate tag
announcements make the release action try to create the same GitHub release twice. A failed registry lookup stops the
release; retries do not republish an existing version.

Notes:
Expand All @@ -127,7 +128,9 @@ Notes:
- Scoped packages publish to `latest`, except `@transloadit/viewer`, which is an alpha and uses
`alpha`. Its `publishConfig.tag` alone is insufficient because Changesets passes `--tag latest`.
- Mark the Viewer GitHub release as a prerelease and verify the npm tags after publishing. On first
publication, npm may also assign `latest`; remove that Viewer tag if present.
publication, npm also assigned `latest` and rejected its removal with HTTP 400 (also reported in
[npm/cli#8490](https://github.com/npm/cli/issues/8490)). Do not claim alpha-only registry tagging:
keep the package description, README and GitHub release explicit about alpha stability.
- Viewer prepack uses incremental TypeScript builds, like Utils. Do not recursively clean project
references there: Changesets can pack dependent packages concurrently.
- If this was a pre-release, remember to reset the [npm `latest` tag](https://www.npmjs.com/package/transloadit?activeTab=versions) to the previous version (replace `x.y.z` with previous version):
Expand Down
47 changes: 43 additions & 4 deletions docs/prompts/2026-09-21-viewer-alpha-release.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,11 @@ at least 4.9.0 before publishing. The old private workspace protocol must not es
- [x] Reproduce private-package/registry-dependency metadata failure with a regression test.
- [x] Verify package checks and the packed Next browser fixture (Chromium/WebKit, both cache modes,
and development diagnostics). Run the versioned release dry run in PR CI.
- [ ] Reconcile council review; open and finish the alpha preparation PR.
- [ ] Inspect generated #502 versions, dependency floors, changelogs and exact-head CI.
- [ ] Merge #502, watch trusted publication and verify every expected registry version.
- [ ] Verify Viewer alpha tag and GitHub prerelease; prevent an accidental stable `latest` claim.
- [x] Reconcile council review; open and finish the alpha preparation PR (#503).
- [x] Inspect generated #502 versions, dependency floors, changelogs and exact-head CI.
- [x] Merge #502, watch trusted publication and verify every expected registry version.
- [x] Verify Viewer alpha tag and GitHub prerelease; document npm's retained `latest` tag without
claiming stable API support.
- [ ] Prove a registry-installed consumer, not just a workspace-linked or vendored package.

For a new npm package, trusted-publisher bootstrap may need a maintainer action. Follow the
Expand All @@ -51,6 +52,44 @@ Local `verify:full`, `check`, the 30 image fixture contract tests and the seven
The packed fixture passed both production modes (58 browser cases each), the secretless public-only
builds, and ten development cases. Evidence: `/tmp/viewer-alpha-20260921.gU9s3H/`.

## Publication receipts and follow-up

#503 merged as `78de89e`; #502 merged as `a4db0b2` with green PR and main CI. The bot's force push
was prohibited, so #502 was regenerated with Changesets and updated through normal commits without
weakening repository rules. Its merged tree matches the tested head `fe77d59`.

Viewer 0.0.1 required a maintainer MFA bootstrap because trusted publishing could not create the
new package. The registry accepted it at 19:34 UTC; its package index caught up around 19:39 UTC.
Release run `35643913063`, attempt 3, published the other six packages through trusted publishing:
Utils 4.9.0, Node and legacy CLI 4.13.0, Types and Zod 4.4.1, MCP 0.3.32. All seven versions are
independently available from the registry; the six CI-published versions have provenance.
Viewer's GitHub release is explicitly an alpha/prerelease. npm auto-created `latest` alongside
`alpha`; removing that Viewer-only tag with a fresh MFA code returned HTTP 400, matching
[npm/cli#8490](https://github.com/npm/cli/issues/8490). Do not keep requesting codes for this refusal
or claim that `latest` was removed. Alpha stability remains explicit in the package, README and
GitHub release. Configure its trusted publisher for future releases rather than leaving manual
publishing as the permanent process.

The packages and all seven GitHub releases were created, but the workflow then failed: both
`changeset publish` and `changeset tag` emitted the stable package tags. With this workflow's
GitHub-API commit mode, the action parsed both announcements and tried to create those releases
twice. Do not delete valid releases or publish new versions to hide that failure.

- [x] Reproduce the missing `--no-git-tag` guard with a failing publisher test.
- [x] Disable publication's tag pass and retain one final tag pass, including Viewer.
- [x] Cover failure before tagging so an incomplete publish does not announce unready versions.
- [ ] Review and verify this narrow release-orchestration fix; land it and confirm main's release
workflow succeeds without republishing any existing version.

The follow-up council reported no findings; its Claude leg hit the monthly spending limit again.
The eight publisher tests and `yarn check` pass. No package version or published bytes change in
this orchestration fix.

Content PR #6047 is the registry-installed consumer and records the later backend/Console/CLI and
Storage dogfood gates. The API2 x64 main build at `b553c67b84` is green and uploaded to R2:
`s3://build-artifacts-transloadit/main/api2/api2-gha-ci-35641331297.tar.gz`. ARM64 is still running at
this checkpoint. Deployment remains Kevin's responsibility.

## Before API2 is deployed

Storage Built-ins, native catalog APIs and device login need the matching backend rollout. The
Expand Down
11 changes: 10 additions & 1 deletion scripts/publish-release.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ test('the release publishes Viewer to alpha and leaves stable packages to Change
expect(run.mock.calls.map(([command, args]) => [command, args])).toEqual([
['npm', ['view', `${viewer.name}@${viewer.version}`, 'version', '--json']],
['npm', ['publish', './packages/img', '--access', 'public', '--tag', 'alpha']],
['corepack', ['yarn', 'changeset', 'publish']],
// Only the following tag command may announce tags to changesets/action; duplicate
// announcements make it try to create each stable GitHub release twice.
['corepack', ['yarn', 'changeset', 'publish', '--no-git-tag']],
['corepack', ['yarn', 'changeset', 'tag']],
])
})
Expand Down Expand Up @@ -50,6 +52,13 @@ test('a failed Viewer publish stops before the stable release and tags', async (
expect(run).toHaveBeenCalledTimes(2)
})

test('a failed stable release does not announce tags for unpublished packages', async () => {
run.mockResolvedValueOnce({ exitCode: 0, stdout: JSON.stringify(viewer.version) })
run.mockRejectedValueOnce(new Error('stable publish refused'))
await expect(import('./publish-release.ts')).rejects.toThrow('stable publish refused')
expect(run).toHaveBeenCalledTimes(2)
})

test('Viewer prepack never recursively deletes artifacts used by another publisher', () => {
expect(viewer.scripts.build).not.toContain('--clean')
})
Expand Down
5 changes: 3 additions & 2 deletions scripts/publish-release.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ async function main(): Promise<void> {
throw new Error('Viewer registry lookup failed; refusing to treat a network/auth error as E404')
}

await execa('corepack', ['yarn', 'changeset', 'publish'], options)
// Include the alpha in Changesets' normal tag output so its action creates the release too.
// Emit each tag only once: changesets/action turns every announcement into a GitHub release.
// The separate tag pass also includes Viewer, which was already published with its alpha tag.
await execa('corepack', ['yarn', 'changeset', 'publish', '--no-git-tag'], options)
await execa('corepack', ['yarn', 'changeset', 'tag'], options)
}

Expand Down
Loading