diff --git a/.github/workflows/coolify-helper.yml b/.github/workflows/coolify-helper.yml index ed6fc3bcb..c89e11d7b 100644 --- a/.github/workflows/coolify-helper.yml +++ b/.github/workflows/coolify-helper.yml @@ -2,7 +2,7 @@ name: Coolify Helper Image on: push: - branches: [ "v4.x" ] + branches: [ "v4.x", "main" ] paths: - .github/workflows/coolify-helper.yml - docker/coolify-helper/Dockerfile diff --git a/.github/workflows/coolify-realtime.yml b/.github/workflows/coolify-realtime.yml index d8784dd50..cfcf8f200 100644 --- a/.github/workflows/coolify-realtime.yml +++ b/.github/workflows/coolify-realtime.yml @@ -2,14 +2,10 @@ name: Coolify Realtime on: push: - branches: [ "v4.x" ] + branches: [ "v4.x", "main" ] paths: - .github/workflows/coolify-realtime.yml - - docker/coolify-realtime/Dockerfile - - docker/coolify-realtime/terminal-server.js - - docker/coolify-realtime/package.json - - docker/coolify-realtime/package-lock.json - - docker/coolify-realtime/soketi-entrypoint.sh + - docker/coolify-realtime/** permissions: contents: read diff --git a/.github/workflows/coolify-production-build.yml b/.github/workflows/coolify-sha-build.yml similarity index 98% rename from .github/workflows/coolify-production-build.yml rename to .github/workflows/coolify-sha-build.yml index a5fe461f5..0a5315a49 100644 --- a/.github/workflows/coolify-production-build.yml +++ b/.github/workflows/coolify-sha-build.yml @@ -1,8 +1,8 @@ -name: Production Build (v4) +name: Build Coolify (SHA) on: push: - branches: ["v4.x"] + branches: ["v4.x", "main"] permissions: contents: read diff --git a/.github/workflows/coolify-staging-build.yml b/.github/workflows/coolify-staging-build.yml index c5b70ca92..df0508c98 100644 --- a/.github/workflows/coolify-staging-build.yml +++ b/.github/workflows/coolify-staging-build.yml @@ -4,6 +4,7 @@ on: push: branches-ignore: - v4.x + - main - v3.x - '**v5.x**' paths-ignore: diff --git a/.github/workflows/generate-changelog.yml b/.github/workflows/generate-changelog.yml index c02c13848..1a16ec1e2 100644 --- a/.github/workflows/generate-changelog.yml +++ b/.github/workflows/generate-changelog.yml @@ -2,7 +2,7 @@ name: Generate Changelog on: push: - branches: [ v4.x ] + branches: [ v4.x, main ] paths-ignore: - .github/workflows/coolify-helper.yml - .github/workflows/coolify-helper-next.yml @@ -39,4 +39,4 @@ jobs: git config user.email 'github-actions[bot]@users.noreply.github.com' git add CHANGELOG.md git commit -m "docs: update changelog" - git push https://${{ secrets.GITHUB_TOKEN }}@github.com/${GITHUB_REPOSITORY}.git v4.x + git push https://${{ secrets.GITHUB_TOKEN }}@github.com/${GITHUB_REPOSITORY}.git HEAD:${GITHUB_REF_NAME} diff --git a/RELEASE.md b/RELEASE.md index 1df585fc5..0f956ebfd 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -3,6 +3,7 @@ # 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. ## Table of Contents +- [Branch Strategy](#branch-strategy) - [Release Process](#release-process) - [Version Types](#version-types) - [Stable](#stable) @@ -13,21 +14,55 @@ ## Table of Contents - [Cloud](#cloud) - [Manually Update to Specific Versions](#manually-update-to-specific-versions) +## Branch Strategy + +Coolify uses two long-lived branches so production fixes can ship without waiting on unfinished feature work. + +| Branch | Role | Docker image tags | How it ships | +| --- | --- | --- | --- | +| **`v4.x`** | Production / releasable line | `sha-` via **Build Coolify (SHA)** | GitHub release promotes the SHA image to a semantic version (and `latest` for stable releases) | +| **`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 +``` + +Only commits on **`v4.x`** produce production SHA images and can be tagged for a GitHub release. + ## Release Process 1. **Prepare the Release** - - Develop changes on `next` or feature branches. - - Set the release version in `config/constants.php` and `versions.json`. Both values must match the planned Git tag without the `v` prefix (for example, `4.2.0` for tag `v4.2.0`). + - 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 release version in `config/constants.php` and `versions.json` on the commit you will tag. Both values must match the planned Git tag without the `v` prefix (for example, `4.2.0` for tag `v4.2.0`). - 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 `Production Build (v4)` workflow builds AMD64 and ARM64 images and publishes them to Docker Hub and GHCR using immutable architecture tags. + - 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-` manifest in both registries. - This workflow does not update a semantic version tag or `latest`. 3. **Wait for the SHA Image** - - Confirm the complete `Production Build (v4)` workflow, including its `merge-manifest` job, succeeded. + - Confirm the complete `Build Coolify (SHA)` workflow, including its `merge-manifest` job, succeeded. - Do not publish the release before the multi-architecture SHA image exists in both registries. 4. **Create and Publish the GitHub Release** @@ -87,7 +122,7 @@ ## Version Types - 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 stabe release after some time. + - **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 @@ -130,7 +165,7 @@ ### Cloud - 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 manully update the cloud version when the update is ready. +> 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 diff --git a/tests/Unit/ProductionImageWorkflowTest.php b/tests/Unit/ProductionImageWorkflowTest.php index 557e86b64..895ad0693 100644 --- a/tests/Unit/ProductionImageWorkflowTest.php +++ b/tests/Unit/ProductionImageWorkflowTest.php @@ -1,9 +1,10 @@ toContain('name: Build Coolify (SHA)') ->toContain('sha-${{ github.sha }}-${{ matrix.arch }}') ->toContain('sha-${{ github.sha }}') ->not->toContain('bootstrap/getVersion.php') @@ -37,10 +38,18 @@ $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-`') ->toContain('targeting the exact commit that produced the SHA image') ->toContain('promotes the existing SHA image without rebuilding it') ->toContain('Update the CDN') - ->not->toContain('Merging to `main`'); + ->toContain('Only commits on **`v4.x`** produce production SHA images') + ->not->toContain('Merging to `main`') + ->not->toContain('Production Build (v4)'); });