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
8 changes: 4 additions & 4 deletions .releaserc.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
{
"branches": [
{
"name": "release-v14",
"name": "master",
"channel": "latest"
},
{
"name": "master",
"prerelease": "rc",
"channel": "rc"
"name": "release-v14",
"channel": "v14",
"range": "14.x"
}
],
"plugins": [
Expand Down
4 changes: 2 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Agents should prioritize API stability and high test coverage when changing code

Stream's React Chat SDK — React components, hooks and contexts for building chat UIs on the Stream Chat API. The published package (`stream-chat-react`) lives at the repo root; `examples/*` are private Yarn workspaces consuming it via `workspace:^`.

This is the **v15** line, developed on `master` and published as release candidates (npm `rc`). The stable v14 line lives on `release-v14` (npm `latest`). It is built on `stream-chat` v10 (the "LLC"), which owns message, thread and composer state; this package renders it.
This is the **v15** line, developed on `master` and published under npm `latest`. The v14 maintenance line lives on `release-v14` (npm `release-v14`). It is built on `stream-chat` v10 (the "LLC"), which owns message, thread and composer state; this package renders it.

## Tech & toolchain

Expand Down Expand Up @@ -443,7 +443,7 @@ Implement MediaRecorder API integration with MP3 encoding.
Closes #123
```

- v15 is a major release line: a change that breaks the v14 API is marked with `!` and a `BREAKING CHANGE:` footer, and gets an entry in `ai-docs/ai-migration-v14-v15.md`.
- `master` publishes v15 under `latest`, so a commit marked with `!` or a `BREAKING CHANGE:` footer releases 16.0.0. Mark a commit as breaking only when the next major is planned (see `developers/BRANCHES.md`).
- Never commit directly to `master` or `release-v14`; always create a feature branch (see `developers/BRANCHES.md`). v15 work targets `master`; v14 fixes target `release-v14`.
- Never commit unless explicitly requested.

Expand Down
20 changes: 12 additions & 8 deletions developers/BRANCHES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,25 @@

We have two base branches:

- `master` — the v15 line. Releases from it are published as release candidates (`15.0.0-rc.N`) under the npm `rc` tag.
- `release-v14` — the stable v14 line. Releases from it are published under the npm `latest` tag.
- `master` — the v15 line. Releases from it are published under the npm `latest` tag.
- `release-v14` — the v14 maintenance line. Releases from it are published under the npm `release-v14` tag (`npm install stream-chat-react@release-v14`).

Older lines (`release-v13`, `release-v12`, …) are maintenance branches as well, published under the npm `release-v13`, `release-v12`, … tags.

If you want to implement a solution, create a branch from the base branch it belongs to: `master` for v15 work, `release-v14` for a v14 fix. A base branch should receive updates only through squash-merging feature branches - each of these squashed commits should be up to date with its base branch and should be passing CI requirements.

A fix that applies to both lines is merged into `release-v14` and ported to `master`.

`release-v14` must not receive breaking changes (`!` or a `BREAKING CHANGE:` footer). It is the release branch in `.releaserc.json`, which semantic-release cannot limit to `14.x`, so a breaking change there would publish v15 under `latest`.
`release-v14` accepts only 14.x releases and must not receive breaking changes. It is a maintenance branch in `.releaserc.json` (`"range": "14.x"`), so semantic-release refuses a release that would leave 14.x: a `fix:` or `feat:` commit with a `BREAKING CHANGE:` footer makes the release fail with `EINVALIDNEXTVERSION` instead of publishing v15. Its commit analyzer uses the `angular` preset, which does not read `!` in a header, so a `fix!:` commit on `release-v14` releases nothing.

A breaking change on `master` releases the next major (16.0.0) under `latest`. Mark a commit on `master` as breaking only when the next major is planned.

The branch architecture in this repository is as follows:

```shell
NPM (rc) <--- master <--- branch_solution_x
<--- branch_solution_y
...
NPM (latest) <--- release-v14 <--- branch_fix_x
...
NPM (latest) <--- master <--- branch_solution_x
<--- branch_solution_y
...
NPM (release-v14) <--- release-v14 <--- branch_fix_x
...
```
26 changes: 21 additions & 5 deletions developers/RELEASE.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,39 @@ The `stream-chat-react` package follows semantic versioning and the release is t

In order to get the above generated outputs, each contributor should follow [Angular's Commit Message Format rules](https://github.com/angular/angular/blob/master/CONTRIBUTING.md#-commit-message-format).

## Branches and npm dist-tags

The Release workflow runs `semantic-release` on the branch you pick, so that branch's own `.releaserc.json` decides where its releases go. `master` and `release-v14` keep the same `branches` list:

| Branch | Entry in `branches` | Versions | npm dist-tag |
| ------------- | -------------------------------------------------------------- | -------- | ------------- |
| `master` | `{ "name": "master", "channel": "latest" }` | 15.x | `latest` |
| `release-v14` | `{ "name": "release-v14", "channel": "v14", "range": "14.x" }` | 14.x | `release-v14` |

`@semantic-release/npm` publishes a release under its channel as the dist-tag, and prefixes a channel that reads as a version range with `release-`: the `v14` channel publishes under `release-v14`. Older maintenance branches work the same way (`release-v13` publishes under `release-v13`).

A maintenance branch only publishes versions inside its `range`. If its commits call for a version outside it, for example 15.0.0 from a breaking change on `release-v14`, the release fails with `EINVALIDNEXTVERSION` and nothing is published.

## Major version release preparations

We need to:
While the next major is in prerelease, `master` is a prerelease branch, for example `{ "name": "master", "prerelease": "rc", "channel": "rc" }`, and the previous line's branch (for example `release-v14`) is the release branch on `latest`. When the major goes GA:

1. Convert the current latest branch to a version branch by creating a PR with adjusted `.releaserc.json`. Example PR: https://github.com/GetStream/stream-chat-react/pull/2507
1. Make the previous line a maintenance branch. On that branch, set the `branches` list in `.releaserc.json` to `master` on `latest` plus the branch with its own channel and range, as in the table above. Merge this first: once it is in, a release from that branch can no longer move `latest`. Example PR: https://github.com/GetStream/stream-chat-react/pull/3122
2. On `master`, replace the prerelease entry with `{ "name": "master", "channel": "latest" }` and list the maintenance branch next to it, the same list as in step 1. Example PR: https://github.com/GetStream/stream-chat-react/pull/3121
3. Run the Release workflow on `master`, with a dry run first. A release branch ignores the `-rc.N` tags, so `semantic-release` compares `master` with its last stable tag. The breaking commits since then make the release `X.0.0`, published under `latest`. No extra commit is needed.
4. Run the Release workflow on the maintenance branch once, at any time after step 1. With no new fixes it only adds the branch's last version to the branch's dist-tag (for example `14.16.1` to `release-v14`), so `npm install stream-chat-react@release-v14` works before the first maintenance release. The workflow publishes through npm trusted publishing (OIDC). If this step fails with `E401` on `npm dist-tag`, the package's trusted publisher settings on npmjs.com do not allow `npm dist-tag`: allow it, or add the tag by hand with `npm dist-tag add stream-chat-react@14.16.1 release-v14`. A re-run does not retry the step.

2. Configure the `master` branch back from `prerelease` to `latest` and add a config for the next version branch also designated as `latest`. Example PR: https://github.com/GetStream/stream-chat-react/pull/2506.
If step 3 runs before step 1, the next release from the previous line's branch publishes under `latest` and replaces the new major there.

## Required steps

At the moment these manual actions have to be taken to achieve a successful release:

1. make sure that all the new required features and bug fixes in peer dependency repositories `@stream-io/stream-chat-css` and `stream-chat-js` are released
2. make sure that the peer dependencies `@stream-io/stream-chat-css` and `stream-chat-js` are installed at their latest version (see `package.json`, `yarn.lock`) (if applicable)
3. squash-merge required pull requests to `master` branch with appropriate message name, for example: `fix(scope): new feature`, if this feature is breaking, make sure to include `BREAKING CHANGE: <reason>` in the message footer
3. squash-merge required pull requests to their base branch (`master` or `release-v14`) with appropriate message name, for example: `fix(scope): new feature`. A breaking change (`!` or a `BREAKING CHANGE: <reason>` footer) releases a new major from `master`, so merge one only when the next major is planned (see `developers/BRANCHES.md`)
4. navigate to ["Actions"](https://github.com/GetStream/stream-chat-react/actions) and in the left bar select the "Release" workflow
5. click "Run workflow" and select the branch you want to release from then adjust the prompt options and click "Run workflow", note that allowed branches are branch names starting with `release`, `rc` and `master` (a dry run can use any branch), extend the workflow condition and `.releaserc.json` as needed. The `master` branch is the release-candidate branch.
5. click "Run workflow" and select the branch you want to release from then adjust the prompt options and click "Run workflow", note that allowed branches are branch names starting with `release`, `rc` and `master` (a dry run can use any branch), extend the workflow condition and `.releaserc.json` as needed. Releases from `master` go to `latest`, releases from `release-v14` to `release-v14` (see [Branches and npm dist-tags](#branches-and-npm-dist-tags)).

## Available release prompt options

Expand Down
2 changes: 1 addition & 1 deletion examples/ai-chatbot/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"next": "^16.2.4",
"react": "^19.2.6",
"react-dom": "^19.2.6",
"stream-chat": "10.0.0-rc.34",
"stream-chat": "^10.0.0",
"stream-chat-react": "workspace:^"
},
"devDependencies": {
Expand Down
2 changes: 1 addition & 1 deletion examples/cookbook/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"react": "^19.2.6",
"react-dom": "^19.2.6",
"react-leaflet": "^5.0.0",
"stream-chat": "10.0.0-rc.34",
"stream-chat": "^10.0.0",
"stream-chat-react": "workspace:^"
},
"devDependencies": {
Expand Down
2 changes: 1 addition & 1 deletion examples/tutorial/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"emoji-mart": "^5.6.0",
"react": "^19.2.6",
"react-dom": "^19.2.6",
"stream-chat": "10.0.0-rc.34",
"stream-chat": "^10.0.0",
"stream-chat-react": "workspace:^"
},
"devDependencies": {
Expand Down
2 changes: 1 addition & 1 deletion examples/vite/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"modern-normalize": "^3.0.1",
"react": "^19.2.6",
"react-dom": "^19.2.6",
"stream-chat": "10.0.0-rc.34",
"stream-chat": "^10.0.0",
"stream-chat-react": "workspace:^"
},
"devDependencies": {
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@
"modern-normalize": "^3.0.1",
"react": "^19.0.0 || ^18.0.0 || ^17.0.0",
"react-dom": "^19.0.0 || ^18.0.0 || ^17.0.0",
"stream-chat": "^10.0.0-rc.34"
"stream-chat": "^10.0.0"
},
"peerDependenciesMeta": {
"@a2ui/react": {
Expand Down Expand Up @@ -246,7 +246,7 @@
"react-dom": "^19.2.6",
"sass": "^1.100.0",
"semantic-release": "^25.0.3",
"stream-chat": "10.0.0-rc.34",
"stream-chat": "^10.0.0",
"typescript": "^6.0.3",
"typescript-eslint": "^8.59.4",
"vite": "^8.1.3",
Expand Down
20 changes: 10 additions & 10 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3288,7 +3288,7 @@ __metadata:
react: "npm:^19.2.6"
react-dom: "npm:^19.2.6"
sass: "npm:^1.100.0"
stream-chat: "npm:10.0.0-rc.34"
stream-chat: "npm:^10.0.0"
stream-chat-react: "workspace:^"
typescript: "npm:^6.0.3"
languageName: unknown
Expand Down Expand Up @@ -3332,7 +3332,7 @@ __metadata:
react: "npm:^19.2.6"
react-dom: "npm:^19.2.6"
react-leaflet: "npm:^5.0.0"
stream-chat: "npm:10.0.0-rc.34"
stream-chat: "npm:^10.0.0"
stream-chat-react: "workspace:^"
typescript: "npm:^6.0.3"
vite: "npm:^8.1.3"
Expand All @@ -3350,7 +3350,7 @@ __metadata:
emoji-mart: "npm:^5.6.0"
react: "npm:^19.2.6"
react-dom: "npm:^19.2.6"
stream-chat: "npm:10.0.0-rc.34"
stream-chat: "npm:^10.0.0"
stream-chat-react: "workspace:^"
typescript: "npm:^6.0.3"
vite: "npm:^8.1.3"
Expand Down Expand Up @@ -3378,7 +3378,7 @@ __metadata:
react: "npm:^19.2.6"
react-dom: "npm:^19.2.6"
sass: "npm:^1.100.0"
stream-chat: "npm:10.0.0-rc.34"
stream-chat: "npm:^10.0.0"
stream-chat-react: "workspace:^"
typescript: "npm:^6.0.3"
vite: "npm:^8.1.3"
Expand Down Expand Up @@ -12058,7 +12058,7 @@ __metadata:
remark-parse: "npm:^11.0.0"
sass: "npm:^1.100.0"
semantic-release: "npm:^25.0.3"
stream-chat: "npm:10.0.0-rc.34"
stream-chat: "npm:^10.0.0"
typescript: "npm:^6.0.3"
typescript-eslint: "npm:^8.59.4"
unified: "npm:^11.0.5"
Expand All @@ -12081,7 +12081,7 @@ __metadata:
modern-normalize: ^3.0.1
react: ^19.0.0 || ^18.0.0 || ^17.0.0
react-dom: ^19.0.0 || ^18.0.0 || ^17.0.0
stream-chat: ^10.0.0-rc.34
stream-chat: ^10.0.0
dependenciesMeta:
"@parcel/watcher":
built: true
Expand Down Expand Up @@ -12111,9 +12111,9 @@ __metadata:
languageName: unknown
linkType: soft

"stream-chat@npm:10.0.0-rc.34":
version: 10.0.0-rc.34
resolution: "stream-chat@npm:10.0.0-rc.34"
"stream-chat@npm:^10.0.0":
version: 10.0.0
resolution: "stream-chat@npm:10.0.0"
dependencies:
"@stream-io/logger": "npm:^2.1.0"
"@stream-io/state-store": "npm:^1.2.0"
Expand All @@ -12124,7 +12124,7 @@ __metadata:
built: true
husky:
built: true
checksum: 10c0/ab420864180b851b849e9abf69577d136cb341af302694cf7436dc81eee54cbbf51181cffff4a353f3417bd312a1d5c244f514c489f600e5fd3e01ef001957f9
checksum: 10c0/d44d6ddc3c417844f0d43b10ccf30dd483291fb7e7843173f00129759aa20020f05167e6037f6e8fbefc25f65c19a0c967058fa559bb4b23a4d8b255180a5b4c
languageName: node
linkType: hard

Expand Down
Loading