diff --git a/.editorconfig b/.editorconfig index 1da225e99b..5f5de03f0e 100644 --- a/.editorconfig +++ b/.editorconfig @@ -17,6 +17,9 @@ indent_size = 2 [docker-compose.yml] indent_size = 4 +[{release.json,upstream.json}] +indent_style = tab + [scripts/{clean-manifests,sync-cdn}.sh] indent_style = tab binary_next_line = true diff --git a/.github/workflows/coolify-next-build.yml b/.github/workflows/coolify-next-build.yml index db0f762653..be85ce51a7 100644 --- a/.github/workflows/coolify-next-build.yml +++ b/.github/workflows/coolify-next-build.yml @@ -40,7 +40,7 @@ jobs: - name: Resolve next version id: version run: | - RC_VERSION=$(jq -r '.coolify.nightly.version' versions.json) + RC_VERSION=$(jq -r '.coolify.nightly.version' other/nightly/versions.json) if [[ ! "${RC_VERSION}" =~ ^[0-9]+\.[0-9]+-rc\.[0-9]+$ ]]; then echo "Invalid next RC version: ${RC_VERSION}" exit 1 diff --git a/.github/workflows/coolify-rc-release.yml b/.github/workflows/coolify-rc-release.yml index d7f4dc830f..c5f3cb1e0a 100644 --- a/.github/workflows/coolify-rc-release.yml +++ b/.github/workflows/coolify-rc-release.yml @@ -51,7 +51,7 @@ jobs: fi VERSION="${TAG_NAME#v}" - CONFIG_VERSION=$(jq -r '.coolify.nightly.version' versions.json) + CONFIG_VERSION=$(jq -r '.coolify.nightly.version' other/nightly/versions.json) if [[ "${CONFIG_VERSION}" != "${VERSION}" ]]; then echo "RC tag ${VERSION} does not match nightly version ${CONFIG_VERSION}." exit 1 diff --git a/config/constants.php b/config/constants.php index f4728c24c8..38c7ee287a 100644 --- a/config/constants.php +++ b/config/constants.php @@ -1,12 +1,15 @@ [ - 'version' => env('COOLIFY_VERSION') ?: '4.5.4', - 'helper_version' => '1.0.19', + 'version' => env('COOLIFY_VERSION') ?: $release['stable']['coolify'], + 'helper_version' => $upstream['helper']['version'], 'railpack_version' => '0.43.0', 'self_hosted' => env('SELF_HOSTED', true), 'autoupdate' => env('AUTOUPDATE'), diff --git a/docker/production/Dockerfile b/docker/production/Dockerfile index 476b35b704..0ab9774927 100644 --- a/docker/production/Dockerfile +++ b/docker/production/Dockerfile @@ -197,8 +197,9 @@ COPY --chown=www-data:www-data resources/views ./resources/views COPY --chown=www-data:www-data artisan artisan COPY --chown=www-data:www-data openapi.yaml ./openapi.yaml COPY --chown=www-data:www-data changelogs/ ./changelogs/ -# Version data for Traefik, Sentinel, and helper checks until CheckForUpdatesJob refreshes it -COPY --chown=www-data:www-data versions.json ./versions.json +COPY --chown=www-data:www-data release.json upstream.json ./ +RUN jq --arg version "$COOLIFY_VERSION" '{coolify: ({v4: {$version}} + del(.traefik)), traefik}' upstream.json > versions.json \ + && chown www-data:www-data versions.json RUN composer dump-autoload diff --git a/release.json b/release.json new file mode 100644 index 0000000000..e2c962aef4 --- /dev/null +++ b/release.json @@ -0,0 +1,8 @@ +{ + "stable": { + "coolify": "4.5.3" + }, + "preview": { + "coolify": "4.5.3" + } +} diff --git a/scripts/install.sh b/scripts/install.sh index c9801fbc0b..eab94dbeae 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -519,8 +519,8 @@ fi # Fetch versions.json once and parse all values from it VERSIONS_JSON=$(curl -L --silent $CDN/versions.json) -LATEST_VERSION=$(echo "$VERSIONS_JSON" | grep -i version | xargs | awk '{print $2}' | tr -d ',') -LATEST_HELPER_VERSION=$(echo "$VERSIONS_JSON" | grep -i version | xargs | awk '{print $6}' | tr -d ',') +LATEST_VERSION=$(echo "$VERSIONS_JSON" | sed -n '/"v4"/,/}/s/.*"version": *"\([^"]*\)".*/\1/p' | head -n 1) +LATEST_HELPER_VERSION=$(echo "$VERSIONS_JSON" | sed -n '/"helper"/,/}/s/.*"version": *"\([^"]*\)".*/\1/p' | head -n 1) if [ -z "$LATEST_HELPER_VERSION" ]; then LATEST_HELPER_VERSION=latest diff --git a/scripts/sync-cdn.sh b/scripts/sync-cdn.sh index 23635ba5a0..1ac3c1cf7f 100755 --- a/scripts/sync-cdn.sh +++ b/scripts/sync-cdn.sh @@ -51,8 +51,8 @@ select_channel() { } write_versions() { - jq --indent 4 --arg version "$VERSION" '.coolify.v4.version = $version' versions.json > "$WORK_DIR/versions.json" - ok "versions.json names Coolify $VERSION and the helper, Sentinel and Traefik versions of this commit" + jq --indent 4 --arg version "$VERSION" '{coolify: ({v4: {$version}} + del(.traefik)), traefik}' upstream.json > "$WORK_DIR/versions.json" + ok "versions.json names Coolify $VERSION and the helper, Sentinel and Traefik versions of upstream.json" } fetch_releases() { diff --git a/tests/Feature/Jobs/CheckTraefikVersionJobTest.php b/tests/Feature/Jobs/CheckTraefikVersionJobTest.php index 66b40a717b..71ab87cfb9 100644 --- a/tests/Feature/Jobs/CheckTraefikVersionJobTest.php +++ b/tests/Feature/Jobs/CheckTraefikVersionJobTest.php @@ -55,8 +55,8 @@ it('notification settings have traefik_outdated fields', function () { expect($team->webhookNotificationSettings)->toHaveKey('traefik_outdated_webhook_notifications'); }); -it('versions.json contains traefik branches with patch versions', function () { - $versionsPath = base_path('versions.json'); +it('upstream.json contains traefik branches with patch versions', function () { + $versionsPath = base_path('upstream.json'); expect(File::exists($versionsPath))->toBeTrue(); $versions = json_decode(File::get($versionsPath), true); diff --git a/tests/Feature/ReverbAndTerminalPackagingTest.php b/tests/Feature/ReverbAndTerminalPackagingTest.php index df1932ad49..c0d64513c9 100644 --- a/tests/Feature/ReverbAndTerminalPackagingTest.php +++ b/tests/Feature/ReverbAndTerminalPackagingTest.php @@ -257,7 +257,7 @@ it('stops publishing or preserving the obsolete realtime image', function () { ->not->toContain('realtime_image') ->and(file_get_contents(app_path('Actions/Server/CleanupDocker.php'))) ->not->toContain('realtimeImage') - ->and(file_get_contents(base_path('versions.json'))) + ->and(file_get_contents(base_path('upstream.json'))) ->not->toContain('"realtime"') ->and(is_dir(base_path('docker/coolify-realtime')))->toBeFalse() ->and(file_exists(base_path('.github/workflows/coolify-realtime.yml')))->toBeFalse() diff --git a/tests/Unit/ProductionImageWorkflowTest.php b/tests/Unit/ProductionImageWorkflowTest.php index 686ef33986..de42d2f5c0 100644 --- a/tests/Unit/ProductionImageWorkflowTest.php +++ b/tests/Unit/ProductionImageWorkflowTest.php @@ -1,11 +1,18 @@ toBe("4.6.0-beta.1 {$helper}"); +}); + it('publishes main builds under rolling and commit sha tags with a traceable internal version', function () { $workflow = file_get_contents(dirname(__DIR__, 2).'/.github/workflows/coolify-main-build.yml'); $dockerfile = file_get_contents(dirname(__DIR__, 2).'/docker/production/Dockerfile'); $constants = file_get_contents(dirname(__DIR__, 2).'/config/constants.php'); - $versions = json_decode(file_get_contents(dirname(__DIR__, 2).'/versions.json'), true, flags: JSON_THROW_ON_ERROR); - $nightlyVersions = json_decode(file_get_contents(dirname(__DIR__, 2).'/other/nightly/versions.json'), true, flags: JSON_THROW_ON_ERROR); expect($workflow) ->toContain('name: Build Coolify Main') @@ -30,10 +37,7 @@ it('publishes main builds under rolling and commit sha tags with a traceable int ->toContain('ARG COOLIFY_VERSION') ->toContain('ENV COOLIFY_VERSION=${COOLIFY_VERSION}') ->and($constants) - ->toContain("'version' => env('COOLIFY_VERSION') ?: '{$versions['coolify']['v4']['version']}'") - ->and($versions['coolify']['nightly']['version'])->toMatch('/^\d+\.\d+-rc\.\d+$/') - ->and(version_compare($versions['coolify']['v4']['version'], $versions['coolify']['nightly']['version'], '<'))->toBeTrue() - ->and($nightlyVersions)->toBe($versions); + ->toContain("'version' => env('COOLIFY_VERSION') ?: \$release['stable']['coolify']"); }); it('orders a maintenance development build before its stable release', function () { @@ -119,7 +123,7 @@ it('publishes traceable rolling builds from next without creating an exact rc ta ->toContain('name: Build Coolify Next') ->toContain('branches: [next]') ->toContain('group: coolify-next-build') - ->toContain("jq -r '.coolify.nightly.version' versions.json") + ->toContain("jq -r '.coolify.nightly.version' other/nightly/versions.json") ->toContain('VERSION="${RC_VERSION}.${SHORT_SHA}"') ->toContain('COOLIFY_VERSION=${{ needs.prepare.outputs.version }}') ->toContain('--tag "${IMAGE}:sha-${SHA}"') @@ -140,7 +144,7 @@ it('requires a reviewed draft prerelease before publishing an exact rc', functio ->toContain("github.ref != 'refs/heads/next'") ->toContain('group: coolify-rc-release') ->toContain('^v[0-9]+\\.[0-9]+-rc\\.[0-9]+$') - ->toContain("jq -r '.coolify.nightly.version' versions.json") + ->toContain("jq -r '.coolify.nightly.version' other/nightly/versions.json") ->toContain('release.draft') ->toContain('!release.prerelease') ->toContain('release.body?.trim()') @@ -215,12 +219,13 @@ it('guides issue authors to the correct contribution branch', function () { ->toContain('Small fixes should target `main`; larger changes should target `next`'); }); -it('ships versions.json in the production image so version checks work right after an upgrade', function () { +it('writes versions.json in the production image from upstream.json so version checks work right after an upgrade', function () { $dockerfile = file_get_contents(dirname(__DIR__, 2).'/docker/production/Dockerfile'); $dockerignore = file_get_contents(dirname(__DIR__, 2).'/.dockerignore'); expect($dockerfile) - ->toContain('COPY --chown=www-data:www-data versions.json ./versions.json') + ->toContain('COPY --chown=www-data:www-data release.json upstream.json ./') + ->toContain('upstream.json > versions.json') ->and($dockerignore) - ->not->toMatch('/^\/?versions\.json$/m'); + ->not->toMatch('/^\/?(release|upstream)\.json$/m'); }); diff --git a/upstream.json b/upstream.json new file mode 100644 index 0000000000..7a51650b5a --- /dev/null +++ b/upstream.json @@ -0,0 +1,23 @@ +{ + "helper": { + "version": "1.0.19" + }, + "sentinel": { + "version": "1.1.3" + }, + "sentinel-host": { + "version": "1.1.3", + "digest": "sha256:bca77d22355c9005185b438dad406747b4b776018215a0a4a75c88618d681ff7" + }, + "traefik": { + "v3.7": "3.7.16", + "v3.6": "3.6.25", + "v3.5": "3.5.6", + "v3.4": "3.4.5", + "v3.3": "3.3.7", + "v3.2": "3.2.5", + "v3.1": "3.1.7", + "v3.0": "3.0.4", + "v2.11": "2.11.60" + } +} diff --git a/versions.json b/versions.json deleted file mode 100644 index c7b80ac79f..0000000000 --- a/versions.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "coolify": { - "v4": { - "version": "4.5.4" - }, - "nightly": { - "version": "4.6-rc.1" - }, - "helper": { - "version": "1.0.19" - }, - "sentinel": { - "version": "1.1.3" - }, - "sentinel-host": { - "version": "1.1.3", - "digest": "sha256:bca77d22355c9005185b438dad406747b4b776018215a0a4a75c88618d681ff7" - } - }, - "traefik": { - "v3.7": "3.7.16", - "v3.6": "3.6.25", - "v3.5": "3.5.6", - "v3.4": "3.4.5", - "v3.3": "3.3.7", - "v3.2": "3.2.5", - "v3.1": "3.1.7", - "v3.0": "3.0.4", - "v2.11": "2.11.60" - } -} \ No newline at end of file