mirror of
https://github.com/coollabsio/coolify.git
synced 2026-11-06 13:10:37 -04:00
docs: rewrite RELEASE.md for the new release process
This commit is contained in:
+134
-65
@@ -1,78 +1,147 @@
|
||||
# Coolify Release Guide
|
||||
# Releases
|
||||
|
||||
## Branches
|
||||
Every release is tagged `v<version>`, such as `v4.6.0-beta.1`, and publishes the image with the tag `4.6.0-beta.1` on ghcr.io and Docker Hub.
|
||||
|
||||
| Branch | Purpose |
|
||||
| --- | --- |
|
||||
| `main` | Latest production source |
|
||||
| `next` | Feature integration and RC releases for the next version |
|
||||
| `feature/*` | New features based on and merged into `next` |
|
||||
| `hotfix/X.Y.Z` | Production fixes based on `main` |
|
||||
> [!IMPORTANT]
|
||||
> A push that changes `release.json` releases the version it sets, unless that version is released already. Run `scripts/version.sh` first to see what a push releases.
|
||||
|
||||
`next` is the only long-lived development branch. Do not create `release/v*` branches.
|
||||
## Rules
|
||||
|
||||
Release workflows never edit or commit versions. Stable versions come from `config/constants.php`; RC versions come from `coolify.nightly.version` in `versions.json` and `other/nightly/versions.json`.
|
||||
| Branch | Takes | Releases |
|
||||
| -------------- | ---------------------------------------------------------- | -------------------------------------- |
|
||||
| `main` | fixes, and `next` or a release branch for a new version | stable versions |
|
||||
| `next` | features | prereleases of the next minor or major |
|
||||
| `release/v4.6` | the minor 4.6, split off `next` so `next` can go on to 4.7 | prereleases of `4.6.0` |
|
||||
| `release/v5.0` | the next major, cut from `next` | prereleases of `5.0.0` |
|
||||
| `v4.x` | backports, once `main` is on v5 | stable `4.x` versions |
|
||||
| `v4.4.x` | backports and hotfixes, cut from the newest tag of v4.4 | stable `4.4.x` versions |
|
||||
|
||||
## Where changes go
|
||||
- `main` takes fixes only. A new minor or major reaches it as a merge of `next` or a release branch
|
||||
- `next` and the release branches publish prereleases only, their stable versions are released on `main`
|
||||
- Name a branch after what it changes: `fix/<topic>`, `feat/<topic>`, and `fix/<topic>-v4.4.8` for a backport, after the version that releases it
|
||||
- Squash merge pull requests from contributors and pull requests with a single change, such as dependency updates
|
||||
- Merge everything else with a merge commit: team pull requests with several commits, backports, `next`, the release branches and `v4.5.x` into `main`
|
||||
- The merge forward workflow merges `main` into `release/v4.6` and `next`, and `release/v4.6` into `next`
|
||||
- While `main` is on 4.5, `v4.3.x` and `v4.4.x` are never merged into another branch
|
||||
- Delete `release/v4.6` once `main` has released `4.6.0`
|
||||
- Delete `v4.5.x` once it is merged into `main`
|
||||
- Delete `v4.3.x` and `v4.4.x` once their release is published, the next backport cuts them again from the newest tag
|
||||
|
||||
- Fixes, security updates, and small improvements target `main`.
|
||||
- New features and larger changes target `next`.
|
||||
- **Sync main to next** merges `main` into `next` every 10 minutes, so every production fix is included in the next release. If the merge conflicts, it opens a `chore: merge main into next` pull request to resolve.
|
||||
- Do not merge `next` into `main` until an RC is approved for a stable release.
|
||||
> [!CAUTION]
|
||||
> Never squash merge `next` or a release branch. Their commits stay unmerged and come back as conflicts in every later merge.
|
||||
|
||||
## Feature and RC flow
|
||||
## Create a release
|
||||
|
||||
```text
|
||||
feature/* → next → RC
|
||||
> [!NOTE]
|
||||
> `next` publishes prereleases only. For its stable version, merge `next` into `main` with a merge commit and create the release on `main`.
|
||||
|
||||
1. Describe the changes under `## [Unreleased]` in `CHANGELOG.md`, they become the release notes
|
||||
2. Check what the branch releases:
|
||||
|
||||
```sh
|
||||
scripts/version.sh
|
||||
```
|
||||
|
||||
3. Select the stage and the version, the script commits them and asks to push:
|
||||
|
||||
```sh
|
||||
scripts/release.sh
|
||||
```
|
||||
|
||||
4. The pushed commit changes `release.json`, so it runs the release workflow, which builds and publishes the release and moves its tags
|
||||
5. After a stable release that moves `latest`, merge the pull request of the stable channel on `coollabsio/coollabs-cdn`, see [CDN](#cdn)
|
||||
|
||||
> [!TIP]
|
||||
> To take the release commit back before the push:
|
||||
>
|
||||
> ```sh
|
||||
> scripts/undo-release.sh
|
||||
> ```
|
||||
|
||||
## Backport a fix
|
||||
|
||||
`main` is on 4.5, and 4.3 and 4.4 still get fixes. A fix reaches each of them through a patch branch and a pull request of its own:
|
||||
|
||||
1. Cut the patch branch from the newest tag of the minor, unless it exists:
|
||||
|
||||
```sh
|
||||
git switch -c v4.4.x v4.4.7 && git push -u origin v4.4.x
|
||||
```
|
||||
|
||||
2. Put the fix on a branch named after the version that releases it, cherry-picked from `main` when it is there already:
|
||||
|
||||
```sh
|
||||
git switch -c fix/<topic>-v4.4.8 origin/v4.4.x && git cherry-pick -x <commit>
|
||||
```
|
||||
|
||||
3. Merge a pull request from `fix/<topic>-v4.4.8` into `v4.4.x` with a merge commit
|
||||
4. Create the release on your checkout of `v4.4.x`:
|
||||
|
||||
```sh
|
||||
git switch v4.4.x && git pull && scripts/release.sh
|
||||
```
|
||||
|
||||
5. Repeat with `v4.3.x` and `fix/<topic>-v4.3.25`. 4.2 gets no backports
|
||||
|
||||
> [!IMPORTANT]
|
||||
> A hotfix for 4.5 while `main` holds unreleased changes goes through `v4.5.x` the same way. Merge `v4.5.x` into `main` with a merge commit afterwards and delete it. `v4.3.x` and `v4.4.x` are never merged, their fixes come from `main`.
|
||||
|
||||
## Release a major version
|
||||
|
||||
1. Cut `release/v5.0` from `next` and create its prereleases there with `scripts/release.sh`:
|
||||
|
||||
```sh
|
||||
git switch -c release/v5.0 origin/next && git push -u origin release/v5.0
|
||||
```
|
||||
|
||||
2. Merge `main` into `release/v5.0`, so v5 has every fix of v4 and the pull request into `main` has no conflicts:
|
||||
|
||||
```sh
|
||||
git switch release/v5.0 && git pull && git merge origin/main && git push
|
||||
```
|
||||
|
||||
3. Keep v4 on a branch of its own:
|
||||
|
||||
```sh
|
||||
git switch -c v4.x origin/main && git push -u origin v4.x
|
||||
```
|
||||
|
||||
4. Merge a pull request from `release/v5.0` into `main` with a merge commit
|
||||
5. Create the release on `main` and select `5.0.0`:
|
||||
|
||||
```sh
|
||||
git switch main && git pull && scripts/release.sh
|
||||
```
|
||||
|
||||
6. Delete `release/v5.0`
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Cut `v4.x` from `main`, or bring an existing one up to date with `main`, before `release/v5.0` is merged into `main`. Afterwards `main` is v5 and v4 lives on `v4.x` alone.
|
||||
|
||||
## CDN
|
||||
|
||||
`scripts/sync-cdn.sh` syncs a channel of `coollabsio/coollabs-cdn` from the commit of the version it syncs: the install and upgrade scripts, the compose files, the environment file, the service templates, the GitHub releases and `versions.json`.
|
||||
|
||||
| Channel | Path | Synced by |
|
||||
| --------- | ------------------- | --------------------------------------------------------- |
|
||||
| `stable` | `/coolify/` | the release workflow when `latest` moves, a pull request |
|
||||
| `preview` | `/coolify/preview/` | the release workflow when `preview` moves, pushed to main |
|
||||
|
||||
- The preview channel takes betas and release candidates, no alphas
|
||||
- `CDN_TOKEN` in the environment `release` is a fine-grained token for `coollabsio/coollabs-cdn` alone, with read and write access to contents and pull requests
|
||||
- `versions.json` of a channel names its Coolify version and the helper, Sentinel and Traefik versions of `upstream.json`
|
||||
- `/coolify/release.json` lists the Coolify version of every channel, each sync sets the version of its channel
|
||||
|
||||
Cloudflare keeps a file of the CDN for up to 10 minutes. To clear the cache sooner, for example once the pull request of the stable channel is merged and deployed, set `CLOUDFLARE_API_TOKEN` and `CLOUDFLARE_ZONE_ID` in `.env` or the environment, with a token that can purge the cache of the zone:
|
||||
|
||||
```sh
|
||||
scripts/sync-cdn.sh --purge
|
||||
```
|
||||
|
||||
1. Merge feature branches into `next`.
|
||||
2. Set `coolify.nightly.version` in both version files to the intended RC, such as `4.5-rc.1`.
|
||||
3. Every push to `next` runs **Build Coolify Next**. It publishes `sha-<short-sha>`, `4.5-rc.1.<short-sha>`, and the moving `next` tag. It never publishes the exact `4.5-rc.1` tag.
|
||||
4. Create a reviewed draft GitHub Release named `v4.5-rc.1` and mark it as a prerelease.
|
||||
5. Run **Release Coolify RC** manually from `next` and enter `v4.5-rc.1`.
|
||||
6. The workflow validates the draft and configured nightly version, builds the exact RC, publishes `4.5-rc.1`, updates the `next` image tag, and publishes the draft prerelease.
|
||||
7. Advance `coolify.nightly.version` to the next intended RC version.
|
||||
## Update the helper, Sentinel or Traefik
|
||||
|
||||
## Stable release flow
|
||||
`upstream.json` pins them. A change of it releases nothing, every Coolify instance reads the versions from the CDN. To ship it before the next release, sync the stable channel on `main`:
|
||||
|
||||
```text
|
||||
next → main → stable release
|
||||
```sh
|
||||
scripts/sync-cdn.sh --stable <latest version>
|
||||
```
|
||||
|
||||
1. Temporarily stop merging features into `next`.
|
||||
2. Change the version on `next` from the approved RC to the stable version, such as `4.5.0`.
|
||||
3. Merge `next` into `main`.
|
||||
4. Create a reviewed draft GitHub Release named `v4.5.0`.
|
||||
5. Run the stable release workflow from `main`.
|
||||
6. The workflow rebuilds the exact stable version, publishes `4.5.0` and `latest`, then publishes the draft.
|
||||
7. Update the CDN only after the release is approved.
|
||||
8. Advance `next` to the next development version, such as `4.6-rc.1`.
|
||||
|
||||
## Hotfix flow
|
||||
|
||||
```text
|
||||
main → hotfix/X.Y.Z → main → next
|
||||
```
|
||||
|
||||
1. Create `hotfix/X.Y.Z` from `main` when a patch needs an integration branch. A single fix may use a normal branch from `main` instead.
|
||||
2. Set the intended patch version.
|
||||
3. Implement and test the fix. SHA images report `X.Y.Z-dev.<short-sha>`.
|
||||
4. Merge the fix into `main`.
|
||||
5. Create a reviewed draft GitHub Release named `vX.Y.Z`.
|
||||
6. Run the stable release workflow from `main`.
|
||||
7. **Sync main to next** merges `main` into `next`. If the version conflicts, resolve it in favor of the next intended RC in the sync pull request. Delete the hotfix branch if one was used.
|
||||
8. Update the CDN only after the release is approved.
|
||||
|
||||
## Image tags
|
||||
|
||||
| Tag | Meaning |
|
||||
| --- | --- |
|
||||
| `latest` | Latest stable release |
|
||||
| `next` | Latest successful `next` build or RC release |
|
||||
| `X.Y-rc.N.<short-sha>` | Exact `next` commit build |
|
||||
| `X.Y.Z` | Exact stable release |
|
||||
| `X.Y-rc.N` | Exact RC release |
|
||||
| `sha-<commit>` | Exact commit build |
|
||||
|
||||
Git tags use the `v` prefix, such as `v4.5.0`. Docker image tags do not.
|
||||
|
||||
Reference in New Issue
Block a user