internal changes only (#11188)

This commit is contained in:
Andras Bacsai
2026-08-11 16:32:46 +02:00
committed by GitHub
8 changed files with 101 additions and 198 deletions
+1 -2
View File
@@ -2,7 +2,7 @@ name: Coolify Helper Image
on:
push:
branches: [ "v4.x", "main" ]
branches: [ "v4.x" ]
paths:
- .github/workflows/coolify-helper.yml
- docker/coolify-helper/Dockerfile
@@ -113,4 +113,3 @@ jobs:
if: always()
with:
webhook: ${{ secrets.DISCORD_WEBHOOK_PROD_RELEASE_CHANNEL }}
+1 -1
View File
@@ -2,7 +2,7 @@ name: Coolify Realtime
on:
push:
branches: [ "v4.x", "main" ]
branches: [ "v4.x" ]
paths:
- .github/workflows/coolify-realtime.yml
- docker/coolify-realtime/**
+1 -1
View File
@@ -1,4 +1,4 @@
name: Release Coolify Fix
name: Release Coolify Stable
on:
workflow_dispatch:
+1 -1
View File
@@ -2,7 +2,7 @@ name: Build Coolify (SHA)
on:
push:
branches: ["v4.x", "main"]
branches: ["v4.x"]
permissions:
contents: read
@@ -4,7 +4,6 @@ on:
push:
branches-ignore:
- v4.x
- main
- v3.x
- '**v5.x**'
paths-ignore:
+1 -1
View File
@@ -2,7 +2,7 @@ name: Generate Changelog
on:
push:
branches: [ v4.x, main ]
branches: [ v4.x ]
paths-ignore:
- .github/workflows/coolify-helper.yml
- .github/workflows/coolify-helper-next.yml
+55 -174
View File
@@ -1,185 +1,66 @@
# Coolify Release Guide
This guide outlines the release process for Coolify, intended for developers and those interested in understanding how Coolify releases are managed and deployed.
## Branches
## Table of Contents
- [Branch Strategy](#branch-strategy)
- [Release Process](#release-process)
- [Version Types](#version-types)
- [Stable](#stable)
- [Nightly](#nightly)
- [Beta](#beta)
- [Version Availability](#version-availability)
- [Self-Hosted](#self-hosted)
- [Cloud](#cloud)
- [Manually Update to Specific Versions](#manually-update-to-specific-versions)
| Branch | Purpose |
| --- | --- |
| `main` | Latest production source |
| `next` | Feature integration and RC releases |
| `feature/*` | New features based on and merged into `next` |
| `hotfix/X.Y.Z` | Production fixes based on `main` |
## Branch Strategy
Release workflows never edit or commit versions. Set the intended version in `config/constants.php` before running a release workflow.
Coolify uses two long-lived branches so production fixes can ship without waiting on unfinished feature work.
## Feature and RC flow
| Branch | Role | Docker image tags | How it ships |
| --- | --- | --- | --- |
| **`v4.x`** | Production / releasable line | Immutable `sha-<commit>` images via **Build Coolify (SHA)** | The manual fix-release workflow rebuilds the selected commit with the stable version and updates `latest` |
| **`next`** | Development line for features and larger changes | Branch tag (for example `next`) via **Staging Build** | Becomes production only after merge into `v4.x` |
### Where to merge
- **Fixes and release-ready patches** → open PRs against **`v4.x`**. This is the fast path for patch releases.
- **Features, refactors, and experimental work** → open PRs against **`next`** (or a feature branch that targets `next`).
- **Shipping features to production** → merge `next` into `v4.x` when the feature set is ready for a stable (or beta) release. Prefer a deliberate merge, not ad-hoc cherry-picks of large feature stacks.
### Keeping the branches in sync
- After each fix lands on `v4.x` (and after each production release), **merge `v4.x` back into `next`** so fixes are not lost and `next` does not reintroduce already-shipped bugs.
- When `next` has unfinished work and you need a hotfix, **open a small PR to `v4.x`** or **cherry-pick the fix commit** onto `v4.x`. Do not merge half-finished feature work from `next` just to ship a fix.
- Treat **database migrations and irreversible data changes** carefully when the branches diverge. Prefer minimal, forward-compatible migrations on the fix path.
### Mental model
```
next ── features, refactors, experiments ──► (when ready) merge into v4.x
│ regularly merge fixes back
v4.x ── fixes / release prep ──► Build Coolify (SHA) ──► Release Coolify ──► CDN
```text
feature/* → next → RC
```
Only commits on **`v4.x`** produce production SHA images and can be tagged for a GitHub release.
1. Merge feature branches into `next`.
2. Set the intended RC version on `next`, such as `4.4-rc.1`.
3. Regular builds publish `sha-<commit>`, `4.4-rc.1.<short-sha>`, and the moving `next` tag.
4. Create a reviewed draft GitHub Release named `v4.4-rc.1` and mark it as a prerelease.
5. Run the RC workflow from `next`. It publishes `4.4-rc.1`, updates `next`, and publishes the draft.
6. Advance `next` to the next intended RC version.
## Release Process
## Stable release flow
1. **Prepare the Release**
- Land the work on **`v4.x`**: merge a fix PR into `v4.x`, or merge ready work from `next` into `v4.x` for a feature release.
- Set the upcoming release version in `config/constants.php`. It must match the planned Git tag without the `v` prefix (for example, `4.3.1` for tag `v4.3.1`). Keep `coolify.v4.version` in `versions.json` on the currently published stable version until the CDN update.
- Verify the changelog and required tests before merging.
- After the release (or after the fix merges), merge `v4.x` back into `next` if those branches have diverged.
2. **Build the Release Commit**
- Merge the release commit into `v4.x` through a pull request.
- The `Build Coolify (SHA)` workflow builds AMD64 and ARM64 images and publishes them to Docker Hub and GHCR using immutable architecture tags.
- After both builds complete, the workflow creates the multi-architecture `sha-<commit-sha>` manifest in both registries.
- The image reports a traceable development version such as `4.3.1-dev.d64cbda3e`.
- This workflow does not update a semantic version tag or `latest`.
3. **Prepare the Draft Release**
- Confirm the complete `Build Coolify (SHA)` workflow, including its `merge-manifest` job, succeeded.
- Create a reviewed draft GitHub release with the planned tag, such as `v4.3.1`, targeting `v4.x`.
- Add the final release notes, leave the release as a draft, and do not mark a fix release as a prerelease.
4. **Run the Fix-Release Workflow**
- Run `Release Coolify Fix` manually from `v4.x` and enter the existing draft tag.
- The workflow validates the draft, its release notes, the version in `config/constants.php`, and the absence of an existing Git tag.
- It pins the draft to the selected commit and rebuilds AMD64 and ARM64 images with the exact stable version.
- After both builds succeed, it publishes the semantic version and `latest` manifests to Docker Hub and GHCR, then publishes the existing draft release.
5. **Verify the Release**
- Confirm the `Release Coolify Fix` workflow succeeded and the reviewed draft is now published.
- Verify the semantic version image and `latest` contain AMD64 and ARM64 manifests in Docker Hub and GHCR.
- Verify Coolify reports the exact stable version without a development SHA suffix.
6. **Update the CDN**
- To make a new version available to self-hosted instances, update the version information on the CDN manually.
- Confirm the new version is available at [https://cdn.coollabs.io/coolify/versions.json](https://cdn.coollabs.io/coolify/versions.json).
> [!NOTE]
> The CDN update may not occur immediately after the GitHub release. It can take hours or even days due to additional testing, stability checks, or potential hotfixes. **The update becomes available only after the CDN is updated. After the CDN is updated, a discord announcement will be made in the Production Release channel.**
## Version Types
<details>
<summary><strong>Stable</strong></summary>
- **Stable**
- The production version suitable for stable, production environments (recommended).
- **Update Frequency:** Every 2 to 4 weeks, with more frequent possible fixes.
- **Release Size:** Larger but less frequent releases. Multiple nightly versions are consolidated into a single stable release.
- **Versioning Scheme:** Follows semantic versioning (e.g., `v4.0.0`, `4.1.0`, etc.).
- **Installation Command:**
```bash
curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bash
```
</details>
<details>
<summary><strong>Nightly</strong></summary>
- **Nightly**
- The latest development version, suitable for testing the latest changes and experimenting with new features.
- **Update Frequency:** Daily or bi-weekly updates.
- **Release Size:** Smaller, more frequent releases.
- **Versioning Scheme:** Follows semantic versioning (e.g., `4.1.0-nightly.1`, `4.1.0-nightly.2`, etc.).
- **Installation Command:**
```bash
curl -fsSL https://cdn.coollabs.io/coolify-nightly/install.sh | bash -s next
```
</details>
<details>
<summary><strong>Beta</strong></summary>
- **Beta**
- Test releases for the upcoming stable version.
- **Purpose:** Allows users to test and provide feedback on new features and changes before they become stable.
- **Update Frequency:** Available if we think beta testing is necessary.
- **Release Size:** Same size as stable release as it will become the next stable release after some time.
- **Versioning Scheme:** Follows semantic versioning (e.g., `4.1.0-beta.1`, `4.1.0-beta.2`, etc.).
- **Installation Command:**
```bash
curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bash
```
</details>
> [!WARNING]
> Do not use nightly/beta builds in production as there is no guarantee of stability.
## Version Availability
When a new version is released and a new GitHub release is created, it doesn't immediately become available for your instance. Here's how version availability works for different instance types.
### Self-Hosted
- **Update Frequency:** More frequent updates, especially on the nightly release channel.
- **Update Availability:** New versions are available once the CDN has been updated.
- **Update Methods:**
1. **Manual Update in Instance Settings:**
- Go to `Settings > Update Check Frequency` and click the `Check Manually` button.
- If an update is available, an upgrade button will appear on the sidebar.
2. **Automatic Update:**
- If enabled, the instance will update automatically at the time set in the settings.
3. **Re-run Installation Script:**
- Run the installation script again to upgrade to the latest version available on the CDN:
```bash
curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bash
```
> [!IMPORTANT]
> If a new release is available on GitHub but your instance hasn't updated yet or no upgrade button is shown in the UI, the CDN might not have been updated yet. This intentional delay ensures stability and allows for hotfixes before official release.
### Cloud
- **Update Frequency:** Less frequent as it's a managed service.
- **Update Availability:** New versions are available once Andras has updated the cloud version manually.
- **Update Method:**
- Updates are managed by Andras, who ensures each cloud version is thoroughly tested and stable before releasing it.
> [!IMPORTANT]
> The cloud version of Coolify may be several versions behind the latest GitHub releases even if the CDN is updated. This is intentional to ensure stability and reliability for cloud users and Andras will manually update the cloud version when the update is ready.
## Manually Update/ Downgrade to Specific Versions
> [!CAUTION]
> Updating to unreleased versions is not recommended and can cause issues.
> [!IMPORTANT]
> Downgrading is supported but not recommended and can cause issues because of database migrations and other changes.
To update your Coolify instance to a specific version, use the following command:
```bash
curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bash -s <version>
```text
next → main → stable release
```
Replace `<version>` with the version you want to update to (for example `4.0.0-beta.332`).
1. Temporarily stop merging features into `next`.
2. Change the version on `next` from the approved RC to the stable version, such as `4.4.0`.
3. Merge `next` into `main`.
4. Create a reviewed draft GitHub Release named `v4.4.0`.
5. Run the stable release workflow from `main`.
6. The workflow rebuilds the exact stable version, publishes `4.4.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.
## Hotfix flow
```text
main → hotfix/X.Y.Z → main → next
```
1. Create `hotfix/X.Y.Z` from `main` and set the intended patch version.
2. Implement and test the fix. SHA images report `X.Y.Z-dev.<short-sha>`.
3. Merge the hotfix into `main`.
4. Create a reviewed draft GitHub Release named `vX.Y.Z`.
5. Run the stable release workflow from `main`.
6. Merge `main` into `next`, resolve the version in favor of the next intended RC, and delete the hotfix branch.
7. Update the CDN only after the release is approved.
## Image tags
| Tag | Meaning |
| --- | --- |
| `latest` | Latest stable release |
| `next` | Latest successful `next` 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.4.0`. Docker image tags do not.
+41 -17
View File
@@ -7,6 +7,8 @@ it('publishes v4 branch builds under the commit sha with a traceable internal ve
expect($workflow)
->toContain('name: Build Coolify (SHA)')
->toContain('branches: ["v4.x"]')
->not->toContain('branches: ["v4.x", "main"]')
->toContain('sha-${{ github.sha }}-${{ matrix.arch }}')
->toContain('sha-${{ github.sha }}')
->toContain('php bootstrap/getVersion.php')
@@ -29,6 +31,7 @@ it('requires a reviewed draft release before building a stable version', functio
$workflow = file_get_contents(dirname(__DIR__, 2).'/.github/workflows/coolify-release.yml');
expect($workflow)
->toContain('name: Release Coolify Stable')
->toContain('workflow_dispatch:')
->toContain('tag:')
->toContain('github.ref_name != \'v4.x\'')
@@ -41,6 +44,33 @@ it('requires a reviewed draft release before building a stable version', functio
->not->toContain('generate-notes');
});
it('runs production support workflows only from v4.x', function (string $workflowFile) {
$workflow = file_get_contents(dirname(__DIR__, 2)."/.github/workflows/{$workflowFile}");
expect($workflow)
->toContain('branches: [ "v4.x" ]')
->not->toContain('"main"');
})->with([
'helper' => 'coolify-helper.yml',
'realtime' => 'coolify-realtime.yml',
]);
it('generates the production changelog only from v4.x', function () {
$workflow = file_get_contents(dirname(__DIR__, 2).'/.github/workflows/generate-changelog.yml');
expect($workflow)
->toContain('branches: [ v4.x ]')
->not->toContain('main');
});
it('excludes only active production branches from staging builds', function () {
$workflow = file_get_contents(dirname(__DIR__, 2).'/.github/workflows/coolify-staging-build.yml');
expect($workflow)
->toContain(' - v4.x')
->not->toContain(' - main');
});
it('rebuilds stable images and publishes the reviewed draft after both architectures succeed', function () {
$workflow = file_get_contents(dirname(__DIR__, 2).'/.github/workflows/coolify-release.yml');
@@ -59,25 +89,19 @@ it('rebuilds stable images and publishes the reviewed draft after both architect
->not->toContain('SOURCE_TAG="sha-${RELEASE_SHA}"');
});
it('documents the sha image release process', function () {
it('documents the production, rc, and hotfix release flows', function () {
$releaseGuide = file_get_contents(dirname(__DIR__, 2).'/RELEASE.md');
expect($releaseGuide)
->toContain('## Branch Strategy')
->toContain('Fixes and release-ready patches')
->toContain('open PRs against **`v4.x`**')
->toContain('open PRs against **`next`**')
->toContain('merge `v4.x` back into `next`')
->toContain('Merge the release commit into `v4.x`')
->toContain('`Build Coolify (SHA)`')
->toContain('`sha-<commit-sha>`')
->toContain('Create a reviewed draft GitHub release')
->toContain('rebuilds AMD64 and ARM64 images with the exact stable version')
->toContain('publishes the existing draft release')
->toContain('Update the CDN')
->toContain('Only commits on **`v4.x`** produce production SHA images')
->toContain('| `main` | Latest production source |')
->toContain('| `next` | Feature integration and RC releases |')
->toContain('| `hotfix/X.Y.Z` | Production fixes based on `main` |')
->toContain('feature/* → next → RC')
->toContain('next → main → stable release')
->toContain('main → hotfix/X.Y.Z → main → next')
->toContain('reviewed draft GitHub Release')
->toContain('workflows never edit or commit versions')
->toContain('Update the CDN only after the release is approved')
->not->toContain('`edge`')
->not->toContain('promotes the existing SHA image')
->not->toContain('Merging to `main`')
->not->toContain('Production Build (v4)');
->not->toContain('promotes the existing SHA image');
});