From 08627795a5f8b141b5144078d2ef5ce0d6e166ba Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Wed, 12 Aug 2026 13:12:55 +0200 Subject: [PATCH] ci(release): standardize production workflows on main Route production builds, releases, and changelog generation through `main`, update contribution guidance for main/next branch targets, and cover the branch policy in workflow tests. --- .github/ISSUE_TEMPLATE/01_BUG_REPORT.yml | 2 + .github/ISSUE_TEMPLATE/config.yml | 6 +-- .github/workflows/coolify-helper.yml | 2 +- .github/workflows/coolify-realtime.yml | 2 +- .github/workflows/coolify-release.yml | 4 +- .github/workflows/coolify-sha-build.yml | 2 +- .github/workflows/coolify-staging-build.yml | 1 - .github/workflows/generate-changelog.yml | 2 +- AGENTS.md | 2 +- CONTRIBUTING.md | 19 ++++++--- RELEASE.md | 22 +++++++--- tests/Unit/ProductionImageWorkflowTest.php | 47 +++++++++++++++++---- 12 files changed, 79 insertions(+), 32 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/01_BUG_REPORT.yml b/.github/ISSUE_TEMPLATE/01_BUG_REPORT.yml index d5106ab75..1159bfb2b 100644 --- a/.github/ISSUE_TEMPLATE/01_BUG_REPORT.yml +++ b/.github/ISSUE_TEMPLATE/01_BUG_REPORT.yml @@ -8,6 +8,8 @@ body: value: | > [!IMPORTANT] > **Please ensure you are using the latest version of Coolify before submitting an issue, as the bug may have already been fixed in a recent update.** (Of course, if you're experiencing an issue on the latest version that wasn't present in a previous version, please let us know.) + > + > If you plan to submit a fix, branch from `main` and target `main` with your pull request. - type: textarea attributes: diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 92c48e2d6..847969358 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -7,12 +7,12 @@ contact_links: - name: 💡 Feature Request url: https://github.com/coollabsio/coolify/discussions/categories/feature-requests - about: Suggest a new feature for Coolify. + about: Suggest a new feature for Coolify. Feature code should branch from `next` and target `next`. - name: ⚙️ Service Request url: https://github.com/coollabsio/coolify/discussions/categories/service-requests - about: Request a new service integration for Coolify. + about: Request a new service integration for Coolify. Service code should branch from `next` and target `next`. - name: 🔧 Improvements url: https://github.com/coollabsio/coolify/discussions/categories/improvements - about: Suggest improvements to existing features for Coolify. + about: Suggest improvements to existing features. Small fixes should target `main`; larger changes should target `next`. diff --git a/.github/workflows/coolify-helper.yml b/.github/workflows/coolify-helper.yml index 06c5f9eb3..cf9eb4243 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", "main" ] + branches: [ "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 cfcf8f200..538f5c992 100644 --- a/.github/workflows/coolify-realtime.yml +++ b/.github/workflows/coolify-realtime.yml @@ -2,7 +2,7 @@ name: Coolify Realtime on: push: - branches: [ "v4.x", "main" ] + branches: [ "main" ] paths: - .github/workflows/coolify-realtime.yml - docker/coolify-realtime/** diff --git a/.github/workflows/coolify-release.yml b/.github/workflows/coolify-release.yml index 315802bb3..4f735ab15 100644 --- a/.github/workflows/coolify-release.yml +++ b/.github/workflows/coolify-release.yml @@ -30,9 +30,9 @@ jobs: version: ${{ steps.version.outputs.version }} steps: - name: Reject releases outside the production branch - if: ${{ ! contains(fromJSON('["v4.x", "main"]'), github.ref_name) }} + if: ${{ github.ref_name != 'main' }} run: | - echo "Stable releases must run from v4.x or main, not ${{ github.ref_name }}." + echo "Stable releases must run from main, not ${{ github.ref_name }}." exit 1 - uses: actions/checkout@v5 diff --git a/.github/workflows/coolify-sha-build.yml b/.github/workflows/coolify-sha-build.yml index 5b4e43002..7ae7d7e68 100644 --- a/.github/workflows/coolify-sha-build.yml +++ b/.github/workflows/coolify-sha-build.yml @@ -2,7 +2,7 @@ name: Build Coolify (SHA) on: push: - branches: ["v4.x", "main"] + branches: ["main"] permissions: contents: read diff --git a/.github/workflows/coolify-staging-build.yml b/.github/workflows/coolify-staging-build.yml index df0508c98..ccbd14129 100644 --- a/.github/workflows/coolify-staging-build.yml +++ b/.github/workflows/coolify-staging-build.yml @@ -3,7 +3,6 @@ name: Staging Build on: push: branches-ignore: - - v4.x - main - v3.x - '**v5.x**' diff --git a/.github/workflows/generate-changelog.yml b/.github/workflows/generate-changelog.yml index 1a16ec1e2..6e88c0d60 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, main ] + branches: [ main ] paths-ignore: - .github/workflows/coolify-helper.yml - .github/workflows/coolify-helper-next.yml diff --git a/AGENTS.md b/AGENTS.md index ebd2e7138..e35c5d74f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -146,7 +146,7 @@ function loginAsRoot(): mixed ## Git Workflow -- Production branch: `main` (`v4.x` during the branch rename) +- Production branch: `main` - Development branch: `next` - Fix PRs should target the current production branch; feature PRs should target `next` diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 53ba6c6a1..73b048f4b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -32,9 +32,7 @@ Coolify is currently at v4. While v4 is stable, it has some limitations, includi - A more complex user experience - Other smaller issues that need refinement -These limitations will be addressed in Coolify v5, which is in the planning stage. Because of this, major features, architectural changes, or significant UI changes will not be accepted for v4 at this stage. - -We welcome contributions that help stabilize v4 for a bug free experience. +These limitations will be addressed over time. Fixes and small improvements are accepted on the production line. New features and larger changes require prior discussion and must go through the development line. ## What Makes a Strong Contribution @@ -188,8 +186,19 @@ If maintainers cannot reproduce working behavior, the PR will be closed without - GitHub will auto-populate the PR template - The contributor agreement in PR description must remain intact - Pull requests without the contributor agreement will be closed -- All pull requests must target the `next` branch -- PRs targeting other branches will be closed without review + +Choose the branch based on the type of change: + +| Change | Start from | Pull request target | +| --- | --- | --- | +| Fixes and small improvements | `main` | `main` | +| Security fixes | `main` | `main` | +| New features and larger changes | `next` | `next` | + +- For a fix, branch from `main` and target `main`. +- For a feature, branch from `next` and target `next`. +- If a fix is discovered while developing a feature, submit it separately to `main`. Maintainers will merge `main` into `next` so the fix is included there too. +- Pull requests targeting the wrong branch may be closed or asked to retarget. ## FAQ diff --git a/RELEASE.md b/RELEASE.md index 493c690f1..d278d7690 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -11,6 +11,13 @@ Release workflows never edit or commit versions. Set the intended version in `config/constants.php` before running a release workflow. +## Where changes go + +- Fixes, security updates, and small improvements target `main`. +- New features and larger changes target `next`. +- Merge `main` into `next` regularly so every production fix is included in the next release. +- Do not merge `next` into `main` until an RC is approved for a stable release. + ## Feature and RC flow ```text @@ -45,13 +52,14 @@ next → main → stable release 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.`. -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. +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.`. +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. Merge `main` into `next`, resolve the version in favor of the next intended RC, and delete the hotfix branch if one was used. +8. Update the CDN only after the release is approved. ## Image tags diff --git a/tests/Unit/ProductionImageWorkflowTest.php b/tests/Unit/ProductionImageWorkflowTest.php index ec6f735c7..54fb13bb3 100644 --- a/tests/Unit/ProductionImageWorkflowTest.php +++ b/tests/Unit/ProductionImageWorkflowTest.php @@ -7,7 +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", "main"]') + ->toContain('branches: ["main"]') + ->not->toContain('v4.x') ->toContain('sha-${{ github.sha }}-${{ matrix.arch }}') ->toContain('sha-${{ github.sha }}') ->toContain('php bootstrap/getVersion.php') @@ -33,7 +34,7 @@ it('requires a reviewed draft release before building a stable version', functio ->toContain('name: Release Coolify Stable') ->toContain('workflow_dispatch:') ->toContain('tag:') - ->toContain('contains(fromJSON(\'["v4.x", "main"]\'), github.ref_name)') + ->toContain("github.ref_name != 'main'") ->toContain('github.paginate(github.rest.repos.listReleases') ->toContain('release.draft') ->toContain('release.prerelease') @@ -46,27 +47,31 @@ it('requires a reviewed draft release before building a stable version', functio ->not->toContain('generate-notes'); }); -it('keeps support image workflows ready for the production branch rename', function (string $workflowFile) { +it('runs support image workflows from main', function (string $workflowFile) { $workflow = file_get_contents(dirname(__DIR__, 2)."/.github/workflows/{$workflowFile}"); - expect($workflow)->toContain('branches: [ "v4.x", "main" ]'); + expect($workflow) + ->toContain('branches: [ "main" ]') + ->not->toContain('v4.x'); })->with([ 'helper' => 'coolify-helper.yml', 'realtime' => 'coolify-realtime.yml', ]); -it('generates the production changelog from either production branch during the rename', function () { +it('generates the production changelog from main', function () { $workflow = file_get_contents(dirname(__DIR__, 2).'/.github/workflows/generate-changelog.yml'); - expect($workflow)->toContain('branches: [ v4.x, main ]'); + expect($workflow) + ->toContain('branches: [ main ]') + ->not->toContain('v4.x'); }); -it('excludes both production branch names from staging builds during the rename', function () { +it('excludes main from staging builds', function () { $workflow = file_get_contents(dirname(__DIR__, 2).'/.github/workflows/coolify-staging-build.yml'); expect($workflow) - ->toContain(' - v4.x') - ->toContain(' - main'); + ->toContain(' - main') + ->not->toContain(' - v4.x'); }); it('rebuilds stable images and publishes the reviewed draft after both architectures succeed', function () { @@ -103,3 +108,27 @@ it('documents the production, rc, and hotfix release flows', function () { ->not->toContain('`edge`') ->not->toContain('promotes the existing SHA image'); }); + +it('documents pull request targets for fixes and features', function () { + $contributingGuide = file_get_contents(dirname(__DIR__, 2).'/CONTRIBUTING.md'); + + expect($contributingGuide) + ->toContain('Fixes and small improvements') + ->toContain('target `main`') + ->toContain('New features and larger changes') + ->toContain('target `next`') + ->toContain('branch from `main`') + ->toContain('branch from `next`') + ->not->toContain('All pull requests must target the `next` branch'); +}); + +it('guides issue authors to the correct contribution branch', function () { + $bugReport = file_get_contents(dirname(__DIR__, 2).'/.github/ISSUE_TEMPLATE/01_BUG_REPORT.yml'); + $issueConfig = file_get_contents(dirname(__DIR__, 2).'/.github/ISSUE_TEMPLATE/config.yml'); + + expect($bugReport) + ->toContain('branch from `main` and target `main`') + ->and($issueConfig) + ->toContain('Feature code should branch from `next` and target `next`') + ->toContain('Small fixes should target `main`; larger changes should target `next`'); +});