diff --git a/.github/workflows/release-canary.yml b/.github/workflows/publish-prerelease.yml similarity index 57% rename from .github/workflows/release-canary.yml rename to .github/workflows/publish-prerelease.yml index 0f4d9ca27..c34600786 100644 --- a/.github/workflows/release-canary.yml +++ b/.github/workflows/publish-prerelease.yml @@ -1,4 +1,4 @@ -name: release-canary +name: publish-prerelease on: workflow_dispatch: @@ -11,7 +11,7 @@ env: jobs: release: - name: release-canary-${{ github.ref_name }}-${{ github.sha }} + name: publish-prerelease-${{ github.ref_name }}-${{ github.sha }} permissions: id-token: write runs-on: ubuntu-24.04 @@ -27,8 +27,19 @@ jobs: run: echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> ~/.npmrc env: NPM_TOKEN: ${{ secrets.NPM_TOKEN }} - - name: Canary release script - run: pnpm release:canary + + - name: Determine release type + id: determine_release_type + # Use 'canary' for main branch, 'internal' for others + run: | + if [[ ${{ github.ref_name }} == "main" ]]; then + echo "::set-output name=release_type::canary" + else + echo "::set-output name=release_type::internal" + fi + + - name: Release + run: pnpm publish-prerelease --tag ${{ steps.determine_release_type.outputs.release_type }} env: NPM_TOKEN: ${{ secrets.NPM_TOKEN }} NPM_CONFIG_PROVENANCE: true diff --git a/package.json b/package.json index 28040407d..8504b5495 100644 --- a/package.json +++ b/package.json @@ -81,10 +81,9 @@ "prepare": "husky", "prepare-run-test-against-prod": "pnpm bf && rm -rf test/packed && rm -rf test/node_modules && rm -rf app && rm -f test/pnpm-lock.yaml && pnpm run script:pack --all --no-build --dest test/packed && pnpm runts test/setupProd.ts && cd test && pnpm i --ignore-workspace && cd ..", "prepare-run-test-against-prod:ci": "rm -rf test/node_modules && rm -rf app && rm -f test/pnpm-lock.yaml && pnpm run script:pack --all --no-build --dest test/packed && pnpm runts test/setupProd.ts && cd test && pnpm i --ignore-workspace && cd ..", + "publish-prerelease": "pnpm --filter releaser publish-prerelease", "reinstall": "pnpm clean:all && pnpm install", "release": "pnpm --filter releaser release --tag latest", - "release:beta": "pnpm runts ./scripts/release.ts --bump prerelease --tag beta", - "release:canary": "pnpm --filter releaser release:canary", "runts": "cross-env NODE_OPTIONS=--no-deprecation node --no-deprecation --import @swc-node/register/esm-register", "script:build-template-with-local-pkgs": "pnpm --filter scripts build-template-with-local-pkgs", "script:gen-templates": "pnpm --filter scripts gen-templates", diff --git a/tools/releaser/package.json b/tools/releaser/package.json index 918b3e429..bc9c3927b 100644 --- a/tools/releaser/package.json +++ b/tools/releaser/package.json @@ -29,8 +29,8 @@ "lint": "eslint .", "lint:fix": "eslint . --fix", "list-published": "tsx src/lib/getPackageRegistryVersions.ts", + "publish-prerelease": "tsx src/publish-prerelease.ts", "release": "tsx src/release.ts", - "release:canary": "tsx src/publish-canary.ts", "test": "echo \"Error: no test specified\" && exit 1" }, "dependencies": { diff --git a/tools/releaser/src/lib/getWorkspace.ts b/tools/releaser/src/lib/getWorkspace.ts index 05eed84a9..0596dbc25 100644 --- a/tools/releaser/src/lib/getWorkspace.ts +++ b/tools/releaser/src/lib/getWorkspace.ts @@ -27,7 +27,7 @@ type PackageDetails = { version: string } -type PackageReleaseType = 'canary' | ReleaseType +type PackageReleaseType = 'canary' | 'internal' | ReleaseType type PublishResult = { name: string @@ -140,11 +140,42 @@ export const getWorkspace = async () => { const { version: monorepoVersion, packages: packageDetails } = await getCurrentPackageState() let nextReleaseVersion - if (bumpType === 'canary') { + if (bumpType === 'internal') { const hash = execSync('git rev-parse --short HEAD', { encoding: 'utf8' }).trim().slice(0, 7) - nextReleaseVersion = semver.inc(monorepoVersion, 'minor') + `-canary.${hash}` + nextReleaseVersion = semver.inc(monorepoVersion, 'minor') + `-internal.${hash}` + } else if (bumpType === 'canary') { + const minorCandidateBaseVersion = semver.inc(monorepoVersion, 'minor') + + if (!minorCandidateBaseVersion) { + throw new Error(`Could not determine minor candidate version from ${monorepoVersion}`) + } + + // Get latest canary version from registry + const json = await fetch(`https://registry.npmjs.org/payload`).then((res) => res.json()) + const { canary: latestCanaryVersion } = (json['dist-tags'] ?? {}) as { + canary?: string | undefined + } + + console.log(`Latest canary version: ${latestCanaryVersion}`) + + if ( + latestCanaryVersion?.startsWith(minorCandidateBaseVersion) && + latestCanaryVersion.includes('-canary.') + ) { + const canaryIteration = Number(latestCanaryVersion.split('-canary.')[1]) + if (isNaN(canaryIteration)) { + console.log(`Latest canary version is not a valid canary version, starting from 0`) + nextReleaseVersion = semver.inc(monorepoVersion, 'minor') + '-canary.0' + } else { + console.log(`Incrementing canary version from ${latestCanaryVersion}`) + nextReleaseVersion = `${minorCandidateBaseVersion}-canary.${canaryIteration + 1}` + } + } else { + console.log(`Latest canary does not match minor candidate, incrementing minor`) + nextReleaseVersion = semver.inc(monorepoVersion, 'minor') + '-canary.0' + } } else { - nextReleaseVersion = semver.inc(monorepoVersion, bumpType) + throw new Error(`Invalid bump type: ${bumpType}. Only 'internal' and 'canary' are supported.`) } if (!nextReleaseVersion) { diff --git a/tools/releaser/src/publish-canary.ts b/tools/releaser/src/publish-prerelease.ts similarity index 54% rename from tools/releaser/src/publish-canary.ts rename to tools/releaser/src/publish-prerelease.ts index 108b4809a..3a97d1ed4 100755 --- a/tools/releaser/src/publish-canary.ts +++ b/tools/releaser/src/publish-prerelease.ts @@ -1,12 +1,25 @@ import chalk from 'chalk' +import minimist from 'minimist' import { getWorkspace } from './lib/getWorkspace.js' async function main() { + const args = minimist(process.argv.slice(2)) + + const { bump = 'minor', 'dry-run': dryRun, tag } = args + + if (!tag || !['canary', 'internal'].includes(tag)) { + abort('Tag is required. Use --tag ') + } + + console.log(`\n Bump: ${bump}`) + console.log(` Tag: ${tag}`) + console.log(` Dry Run: ${dryRun ? 'Enabled' : 'Disabled'}`) + const workspace = await getWorkspace() - await workspace.bumpVersion('canary') + await workspace.bumpVersion(tag) await workspace.build() - await workspace.publishSync({ dryRun: false, tag: 'canary' }) + await workspace.publishSync({ dryRun: dryRun ?? false, tag }) header('🎉 Done!') }