diff --git a/.github/workflows/release-promote.yml b/.github/workflows/release-promote.yml index da88a8238f..51dcd5a30c 100644 --- a/.github/workflows/release-promote.yml +++ b/.github/workflows/release-promote.yml @@ -92,6 +92,9 @@ jobs: fi NIGHTLY_COMMAND="node scripts/get-release-version.js --type=promote-nightly" STABLE_JSON=$(${STABLE_COMMAND}) + STABLE_VERSION=$(echo "${STABLE_JSON}" | jq -r .releaseVersion) + PREVIEW_COMMAND+=" --stable-base-version=${STABLE_VERSION}" + NIGHTLY_COMMAND+=" --stable-base-version=${STABLE_VERSION}" PREVIEW_JSON=$(${PREVIEW_COMMAND}) NIGHTLY_JSON=$(${NIGHTLY_COMMAND}) echo "STABLE_JSON_COMMAND=${STABLE_COMMAND}" @@ -100,14 +103,14 @@ jobs: echo "STABLE_JSON: ${STABLE_JSON}" echo "PREVIEW_JSON: ${PREVIEW_JSON}" echo "NIGHTLY_JSON: ${NIGHTLY_JSON}" - echo "STABLE_VERSION=$(echo "${STABLE_JSON}" | jq -r .releaseVersion)" >> "${GITHUB_OUTPUT}" + echo "STABLE_VERSION=${STABLE_VERSION}" >> "${GITHUB_OUTPUT}" # shellcheck disable=SC1083 echo "STABLE_SHA=$(git rev-parse "$(echo "${PREVIEW_JSON}" | jq -r .previousReleaseTag)"^{commit})" >> "${GITHUB_OUTPUT}" echo "PREVIOUS_STABLE_TAG=$(echo "${STABLE_JSON}" | jq -r .previousReleaseTag)" >> "${GITHUB_OUTPUT}" echo "PREVIEW_VERSION=$(echo "${PREVIEW_JSON}" | jq -r .releaseVersion)" >> "${GITHUB_OUTPUT}" # shellcheck disable=SC1083 REF="${REF_INPUT}" - SHA=$(git ls-remote origin "$REF" | awk '{print $1}') + SHA=$(git ls-remote origin "$REF" | awk -v ref="$REF" '$2 == "refs/heads/"ref || $2 == "refs/tags/"ref || $2 == ref {print $1}' | head -n 1) if [ -z "$SHA" ]; then if [[ "$REF" =~ ^[0-9a-f]{7,40}$ ]]; then SHA="$REF" diff --git a/scripts/get-release-version.js b/scripts/get-release-version.js index 442eb4444d..1a29539516 100644 --- a/scripts/get-release-version.js +++ b/scripts/get-release-version.js @@ -47,6 +47,10 @@ function getArgs() { description: 'Override the calculated preview version.', string: true, }) + .option('stable-base-version', { + description: 'Base version to use for calculating next preview/nightly.', + string: true, + }) .help(false) .version(false) .parse(); @@ -255,22 +259,35 @@ function getAndVerifyTags({ npmDistTag, args } = {}) { }; } +function getStableBaseVersion(args) { + let latestStableVersion = args['stable-base-version']; + if (!latestStableVersion) { + const { latestVersion } = getAndVerifyTags({ + npmDistTag: TAG_LATEST, + args, + }); + latestStableVersion = latestVersion; + } + return latestStableVersion; +} + function promoteNightlyVersion({ args } = {}) { - const { latestVersion, latestTag } = getAndVerifyTags({ + const latestStableVersion = getStableBaseVersion(args); + + const { latestTag: previousNightlyTag } = getAndVerifyTags({ npmDistTag: TAG_NIGHTLY, args, }); - const baseVersion = latestVersion.split('-')[0]; - const versionParts = baseVersion.split('.'); - const major = versionParts[0]; - const minor = versionParts[1] ? parseInt(versionParts[1]) : 0; - const nextMinor = minor + 1; + + const major = semver.major(latestStableVersion); + const minor = semver.minor(latestStableVersion); + const nextMinor = minor + 2; const date = new Date().toISOString().slice(0, 10).replace(/-/g, ''); const gitShortHash = execSync('git rev-parse --short HEAD').toString().trim(); return { releaseVersion: `${major}.${nextMinor}.0-nightly.${date}.${gitShortHash}`, npmTag: TAG_NIGHTLY, - previousReleaseTag: latestTag, + previousReleaseTag: previousNightlyTag, }; } @@ -329,10 +346,8 @@ function getStableVersion(args) { } function getPreviewVersion(args) { - const { latestVersion: latestNightlyVersion } = getAndVerifyTags({ - npmDistTag: TAG_NIGHTLY, - args, - }); + const latestStableVersion = getStableBaseVersion(args); + let releaseVersion; if (args['preview_version_override']) { const overrideVersion = args['preview_version_override'].replace(/^v/, ''); @@ -343,8 +358,10 @@ function getPreviewVersion(args) { ); releaseVersion = overrideVersion; } else { - releaseVersion = - latestNightlyVersion.replace(/-nightly.*/, '') + '-preview.0'; + const major = semver.major(latestStableVersion); + const minor = semver.minor(latestStableVersion); + const nextMinor = minor + 1; + releaseVersion = `${major}.${nextMinor}.0-preview.0`; } const { latestTag: previousPreviewTag } = getAndVerifyTags({ diff --git a/scripts/tests/get-release-version.test.js b/scripts/tests/get-release-version.test.js index 38030bb67b..78eb32337c 100644 --- a/scripts/tests/get-release-version.test.js +++ b/scripts/tests/get-release-version.test.js @@ -80,7 +80,10 @@ describe('getVersion', () => { it('should calculate the next preview version from the latest nightly', () => { vi.mocked(execSync).mockImplementation(mockExecSync); - const result = getVersion({ type: 'preview' }); + const result = getVersion({ + type: 'preview', + 'stable-base-version': '0.7.0', + }); expect(result.releaseVersion).toBe('0.8.0-preview.0'); expect(result.npmTag).toBe('preview'); expect(result.previousReleaseTag).toBe('v0.7.0-preview.1'); @@ -136,7 +139,10 @@ describe('getVersion', () => { }; vi.mocked(execSync).mockImplementation(mockWithDeprecated); - const result = getVersion({ type: 'preview' }); + const result = getVersion({ + type: 'preview', + 'stable-base-version': '0.7.0', + }); // It should base the preview off 0.8.0, not the deprecated 0.9.0 expect(result.releaseVersion).toBe('0.8.0-preview.0'); }); @@ -178,7 +184,10 @@ describe('getVersion', () => { }; vi.mocked(execSync).mockImplementation(mockWithConflict); - const result = getVersion({ type: 'preview' }); + const result = getVersion({ + type: 'preview', + 'stable-base-version': '0.7.0', + }); // Should have skipped preview.0 and landed on preview.1 expect(result.releaseVersion).toBe('0.8.0-preview.1'); });