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
145 changes: 0 additions & 145 deletions .github/scripts/packages-publish-beta.mjs

This file was deleted.

4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ name: CI

on:
push:
branches: [ main, beta, develop, 'feature/**', 'hotfix/**', 'release/**', 'users/**' ]
branches: [ main, develop, 'feature/**', 'hotfix/**', 'release/**', 'users/**' ]
pull_request:
branches: [ main, beta, develop ]
branches: [ main, develop, 'release/**' ]

permissions:
contents: read
Expand Down
19 changes: 6 additions & 13 deletions .github/workflows/cli-semantic-release.yml
Original file line number Diff line number Diff line change
@@ -1,24 +1,17 @@
# Releases @testplanit/cli via semantic-release.
#
# `main` cuts normal releases to the `latest` npm tag. `beta` is configured in
# cli/.releaserc.json as a prerelease branch, so pushes there cut `1.x.y-beta.N`
# under the `beta` npm tag instead — matching the beta channel the packages/*
# workspace publishes through packages-release.yml. Testers opt in with
# `npm i @testplanit/cli@beta`; `@latest` is untouched.
# `main` cuts releases to the `latest` npm tag. Versions are computed by
# semantic-release from conventional commits, NOT set by hand; a push with no
# releasable commits publishes nothing.
#
# Versions are computed by semantic-release from conventional commits, NOT set
# by hand: a `feat` on beta over the 1.3.0 baseline yields 1.4.0-beta.1 (its
# prerelease counter starts at 1). A push with no releasable commits publishes
# nothing.
#
# Both branches release from THIS workflow file on purpose — npm trusted
# publishing (OIDC) authorizes a single workflow filename per package.
# npm trusted publishing (OIDC) authorizes a single workflow filename per
# package — every CLI release must come from THIS workflow file.
name: CLI Semantic Release

on:
workflow_dispatch:
push:
branches: [main, beta]
branches: [main]
paths:
- 'cli/**'
- '.github/workflows/cli-semantic-release.yml'
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/db-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ name: DB Integration Tests
on:
workflow_dispatch:
push:
branches: [main, beta]
branches: [main, 'release/**']
paths:
- "testplanit/__tests__/integration/**"
- "testplanit/lib/**"
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/e2e-smoke.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ name: E2E Smoke
on:
workflow_dispatch:
push:
branches: [main, beta]
branches: [main, 'release/**']
paths:
- "testplanit/app/**"
- "testplanit/components/**"
Expand Down
36 changes: 6 additions & 30 deletions .github/workflows/packages-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,41 +13,24 @@
# 2. Commit and merge to main
# 3. Review and merge the auto-created "Version Packages" PR
#
# Beta pre-releases (the `beta` branch):
# Package changes that depend on the unreleased 1.0 app can't ship to `latest`,
# so `beta` publishes under the `beta` dist-tag instead — testers opt in with
# `npm i @testplanit/mcp-server@beta` while `@latest` stays on the main release.
# Versions track the app's 1.0 beta line: `1.0.0-beta.N`.
# @testplanit/cli lives outside packages/ and is released by
# cli-semantic-release.yml — it is not part of this workflow.
#
# That path is NOT Changesets-managed (Changesets versions from `main` only):
# set an explicit pre-release version on `beta` and push.
#
# # on the beta branch
# # packages/mcp-server/package.json: "version": "1.0.0-beta.1"
# git commit -am 'chore(mcp-server): 1.0.0-beta.1' && git push origin beta
#
# Only packages/* carrying a pre-release version publish from `beta`; see
# .github/scripts/packages-publish-beta.mjs. @testplanit/cli lives outside
# packages/ and is released by cli-semantic-release.yml — it is not part of this
# channel.
#
# Both paths live in THIS file on purpose: npm trusted publishing (OIDC)
# authorizes a single workflow filename per package, and it is this one. A
# separate beta workflow file would fall back to anonymous auth and E404.
# npm trusted publishing (OIDC) authorizes a single workflow filename per
# package, and it is this one: every publish path must live in THIS file, or
# it falls back to anonymous auth and E404.
name: Package Release

on:
push:
branches:
- main
- beta
paths:
- 'packages/**'
- '.changeset/**'
- '.github/workflows/packages-release.yml'
# The publish commands live here; a fix to one must be able to trigger a run.
# The publish command lives here; a fix to it must be able to trigger a run.
- '.github/scripts/packages-publish.mjs'
- '.github/scripts/packages-publish-beta.mjs'
workflow_dispatch:

concurrency: ${{ github.workflow }}-${{ github.ref }}
Expand Down Expand Up @@ -127,13 +110,6 @@ jobs:
# No NPM_TOKEN — publishing authenticates via OIDC trusted publishing
# (id-token: write above + the trusted publisher configured on npm).

# Beta has no "Version Packages" PR step: versions are set by hand on the
# branch, and only pre-release versions are eligible. Writes its own job
# summary.
- name: Publish beta pre-releases
if: github.ref_name == 'beta'
run: node .github/scripts/packages-publish-beta.mjs

- name: Summary
if: steps.changesets.outputs.published == 'true'
run: |
Expand Down
2 changes: 1 addition & 1 deletion cli/.releaserc.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"branches": ["main", { "name": "beta", "prerelease": true }],
"branches": ["main"],
"tagFormat": "cli-v${version}",
"plugins": [
[
Expand Down
49 changes: 7 additions & 42 deletions packages/RELEASING.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,50 +74,16 @@ When you're ready to release, merge the "Version Packages" PR. This will:
2. Publish packages to npm
3. Create GitHub releases with release notes

## Beta Pre-releases (the `beta` branch)

Package changes that depend on the unreleased 1.0 app cannot ship to `latest` — a
user on the released app would install them and hit endpoints that do not exist
yet. They publish from the `beta` branch under the `beta` npm dist-tag instead,
so the default install is unaffected and testers opt in explicitly:

```bash
npm install @testplanit/mcp-server@beta
```

Beta versions track the app's 1.0 line: `1.0.0-beta.N`.

This path is **not** Changesets-managed — Changesets versions from `main` only,
which is why `packages/*` versions on `beta` trail npm. Cutting a beta is a
deliberate manual step:

1. On the `beta` branch, set the package's `version` to the next pre-release
(e.g. `1.0.0-beta.1`) in its `package.json`.
2. Commit and push to `beta`.

`packages-release.yml` then publishes it via
`.github/scripts/packages-publish-beta.mjs`. Two rules govern what goes out:

- **Only pre-release versions publish.** A package whose version has no `-`
suffix is skipped, so the packages you did not bump can never be republished.
- **Already-published versions are skipped**, so pushing to `beta` without a
version bump is a no-op.

Packages publish dependencies-first, so `@testplanit/api` reaches the registry
before the reporters that declare it as `workspace:^`.

Keep writing changesets for beta work as normal. They are consumed on `main` when
the change lands there, and produce the real changelog entry then; the beta
version number is deliberately outside that flow.

`@testplanit/cli` is separate: it lives outside `packages/` and is released by
`cli-semantic-release.yml`, where `beta` is configured as a semantic-release
prerelease branch. Its version is computed from conventional commits rather than
set by hand, and a push with no releasable commits publishes nothing.
`cli-semantic-release.yml`. Its version is computed from conventional commits
rather than set by hand, and a push with no releasable commits publishes nothing.

> Both branches release from their existing workflow file on purpose. npm trusted
> publishing (OIDC) authorizes a single workflow filename per package, so adding a
> separate beta workflow would fall back to anonymous auth and fail with E404.
> Each package releases from its existing workflow file on purpose. npm trusted
> publishing (OIDC) authorizes a single workflow filename per package, so a
> publish from any other workflow falls back to anonymous auth and fails with E404.

## Version Bump Guidelines

Expand Down Expand Up @@ -153,9 +119,8 @@ pnpm --filter "@testplanit/*" test

The release process is automated via GitHub Actions:

- **Trigger**: Push to `main` (Changesets release) or `beta` (pre-release) with
changes in `packages/` or `.changeset/`
- **Workflow**: `.github/workflows/packages-release.yml` for both branches
- **Trigger**: Push to `main` with changes in `packages/` or `.changeset/`
- **Workflow**: `.github/workflows/packages-release.yml`
- **Authentication**: npm trusted publishing (OIDC) — the job's `id-token: write`
permission plus the trusted publisher configured on npm. There is no
`NPM_TOKEN` secret, and the trusted publisher is bound to this one workflow
Expand Down
Loading