diff --git a/.github/workflows/turborepo-release.yml b/.github/workflows/turborepo-release.yml index 328b2fdc93912..654a8f9d2a741 100644 --- a/.github/workflows/turborepo-release.yml +++ b/.github/workflows/turborepo-release.yml @@ -214,6 +214,15 @@ jobs: git config --global user.name 'Turbobot' git config --global user.email 'turbobot@vercel.com' + - name: Install GoReleaser + uses: goreleaser/goreleaser-action@v6 + with: + distribution: goreleaser-pro + version: v1.18.2 + install-only: true + env: + GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }} + - name: Download Rust artifacts uses: actions/download-artifact@v4 with: @@ -224,13 +233,14 @@ jobs: mv rust-artifacts/turbo-aarch64-apple-darwin cli/dist-darwin-arm64 mv rust-artifacts/turbo-aarch64-unknown-linux-musl cli/dist-linux-arm64 cp -r rust-artifacts/turbo-x86_64-pc-windows-msvc cli/dist-windows-arm64 - mv rust-artifacts/turbo-x86_64-unknown-linux-musl cli/dist-linux-x64 - mv rust-artifacts/turbo-x86_64-apple-darwin cli/dist-darwin-x64 - mv rust-artifacts/turbo-x86_64-pc-windows-msvc cli/dist-windows-x64 + mv rust-artifacts/turbo-x86_64-unknown-linux-musl cli/dist-linux-amd64 + mv rust-artifacts/turbo-x86_64-apple-darwin cli/dist-darwin-amd64 + mv rust-artifacts/turbo-x86_64-pc-windows-msvc cli/dist-windows-amd64 - name: Perform Release run: cd cli && make publish-turbo SKIP_PUBLISH=${{ inputs.dry_run && '--skip-publish' || '' }} env: + GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }} # Upload published artifacts in case they are needed for debugging later diff --git a/cli/Makefile b/cli/Makefile index b5d56caad51d6..77658cbf29ea5 100644 --- a/cli/Makefile +++ b/cli/Makefile @@ -54,7 +54,8 @@ publish-turbo: build npm config set --location=project "//registry.npmjs.org/:_authToken" $(NPM_TOKEN) # Publishes the native npm modules. - turbo release-native -- $(SKIP_PUBLISH) + # TODO: do this without goreleaser. + goreleaser release --rm-dist -f combined-shim.yml $(SKIP_PUBLISH) # Split packing from the publish step so that npm locates the correct .npmrc file. cd $(CLI_DIR)/../packages/turbo && pnpm pack --pack-destination=$(CLI_DIR)/../ diff --git a/cli/combined-shim.yml b/cli/combined-shim.yml new file mode 100644 index 0000000000000..67d9914a3269c --- /dev/null +++ b/cli/combined-shim.yml @@ -0,0 +1,78 @@ +project_name: turbo + +dist: dist + +builds: + - id: turbo + builder: prebuilt + tags: + - rust + - staticbinary + goos: + - linux + - windows + - darwin + goarch: + - amd64 + - arm64 + goamd64: + - v1 + prebuilt: + path: dist-{{ .Os }}-{{ .Arch }}/turbo{{ .Ext }} + hooks: + pre: + - cmd: ./scripts/npm-native-packages/npm-native-packages.js {{ .Os }} {{ .Arch }} {{ .Version }} + binary: bin/turbo +checksum: + name_template: "checksums.txt" +snapshot: + name_template: "{{ incpatch .Version }}" +archives: + - id: github + name_template: "{{ .ProjectName }}-{{ .Version }}-{{ .Os }}-{{ .Arch }}" + wrap_in_directory: true + replacements: + amd64: 64 + format: tar.gz + format_overrides: + - goos: windows + format: zip + files: + - LICENSE + - README.md + - id: npm + name_template: "{{ .ProjectName }}-{{ .Os }}-{{ .Arch }}" + wrap_in_directory: true + replacements: + amd64: 64 + format: tar.gz + files: + - LICENSE + - src: "scripts/npm-native-packages/build/{{ .ProjectName }}-{{ .Os }}-{{ .Arch }}/package.json" + dst: "workaround/.." + strip_parent: true + - src: "scripts/npm-native-packages/build/{{ .ProjectName }}-{{ .Os }}-{{ .Arch }}/README.md" + dst: "workaround/.." + strip_parent: true + - src: "scripts/npm-native-packages/build/{{ .ProjectName }}-{{ .Os }}-{{ .Arch }}/bin/*" + dst: "bin/" + strip_parent: true +changelog: + sort: asc + filters: + exclude: + - "^docs:" + - "^test:" +release: + github: + owner: vercel + name: turborepo + ids: + - github + prerelease: auto + disable: true +publishers: + - name: npm + ids: + - npm + cmd: "npm publish{{ if .Prerelease }} --tag canary{{ end }} {{ abs .ArtifactPath }}" diff --git a/cli/package.json b/cli/package.json index 197d0c130731e..deff9108f9185 100644 --- a/cli/package.json +++ b/cli/package.json @@ -5,10 +5,6 @@ "scripts": { "clean": "cargo clean --package turbo", "build": "cargo build --package turbo", - "build:release": "cargo build --package turbo --profile release-turborepo", - "release-native": "turboreleaser --version-path ../version.txt" - }, - "dependencies": { - "@turbo/releaser": "workspace:*" + "build:release": "cargo build --package turbo --profile release-turborepo" } } diff --git a/cli/scripts/npm-native-packages/.gitignore b/cli/scripts/npm-native-packages/.gitignore new file mode 100644 index 0000000000000..84c048a73cc2e --- /dev/null +++ b/cli/scripts/npm-native-packages/.gitignore @@ -0,0 +1 @@ +/build/ diff --git a/cli/scripts/npm-native-packages/npm-native-packages.js b/cli/scripts/npm-native-packages/npm-native-packages.js new file mode 100755 index 0000000000000..52b7463b40d1b --- /dev/null +++ b/cli/scripts/npm-native-packages/npm-native-packages.js @@ -0,0 +1,51 @@ +#!/usr/bin/env node + +const fs = require("fs"); +const path = require("path"); + +// Map to node os and arch names. +const nodeOsLookup = { + darwin: "darwin", + linux: "linux", + windows: "win32", +}; + +const nodeArchLookup = { + amd64: "x64", + arm64: "arm64", +}; + +const humanizedArchLookup = { + amd64: "64", + arm64: "arm64", +}; + +const template = require("./template/template.package.json"); +const os = process.argv[2]; +const arch = process.argv[3]; +const version = process.argv[4]; + +template.name = `turbo-${os}-${humanizedArchLookup[arch]}`; +template.description = `The ${os}-${humanizedArchLookup[arch]} binary for turbo, a monorepo build system.`; +template.os = [nodeOsLookup[os]]; +template.cpu = [nodeArchLookup[arch]]; +template.version = version; + +const outputPath = path.join(__dirname, "build", template.name); +fs.rmSync(outputPath, { recursive: true, force: true }); +fs.mkdirSync(path.join(outputPath, "bin"), { recursive: true }); + +if (os === "windows") { + fs.copyFileSync( + path.join(__dirname, "template", "bin", "turbo"), + path.join(outputPath, "bin", "turbo") + ); +} +fs.copyFileSync( + path.join(__dirname, "template", "README.md"), + path.join(outputPath, "README.md") +); +fs.writeFileSync( + path.join(outputPath, "package.json"), + JSON.stringify(template, null, 2) +); diff --git a/packages/turbo-releaser/template/README.md b/cli/scripts/npm-native-packages/template/README.md similarity index 100% rename from packages/turbo-releaser/template/README.md rename to cli/scripts/npm-native-packages/template/README.md diff --git a/packages/turbo-releaser/template/bin/turbo b/cli/scripts/npm-native-packages/template/bin/turbo similarity index 100% rename from packages/turbo-releaser/template/bin/turbo rename to cli/scripts/npm-native-packages/template/bin/turbo diff --git a/cli/scripts/npm-native-packages/template/template.package.json b/cli/scripts/npm-native-packages/template/template.package.json new file mode 100644 index 0000000000000..c6f9700b183e7 --- /dev/null +++ b/cli/scripts/npm-native-packages/template/template.package.json @@ -0,0 +1,12 @@ +{ + "name": "turbo-{{Os}}-{{Arch}}", + "version": "{{Version}", + "description": "The {{Os}}-{{Arch}} binary for turbo, a monorepo build system.", + "repository": "https://github.com/vercel/turborepo", + "bugs": "https://github.com/vercel/turborepo/issues", + "homepage": "https://turbo.build/repo", + "license": "MIT", + "os": ["{{Os}}"], + "cpu": ["{{Arch}}"], + "preferUnplugged": true +} diff --git a/cli/turbo.json b/cli/turbo.json index 9e1e5aa12ac4a..92b936b9c0dcc 100644 --- a/cli/turbo.json +++ b/cli/turbo.json @@ -39,10 +39,6 @@ "AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY" ] - }, - "release-native": { - "dependsOn": ["@turbo/releaser#build"], - "cache": false } } } diff --git a/packages/turbo-releaser/.eslintrc.js b/packages/turbo-releaser/.eslintrc.js deleted file mode 100644 index 1ea2c1f97c3c6..0000000000000 --- a/packages/turbo-releaser/.eslintrc.js +++ /dev/null @@ -1,26 +0,0 @@ -module.exports = { - extends: ["@turbo/eslint-config/library"], - overrides: [ - { - files: ["src/*.ts", "cli/index.cjs"], - rules: { - "no-console": "off", - }, - }, - { - files: ["src/native.ts", "src/operations.ts"], - rules: { - "import/no-default-export": "off", - }, - }, - { - files: ["src/*.test.ts"], - rules: { - // https://github.com/nodejs/node/issues/51292 - "@typescript-eslint/no-floating-promises": "off", - "@typescript-eslint/no-unsafe-member-access": "off", - "@typescript-eslint/no-unsafe-argument": "off", - }, - }, - ], -}; diff --git a/packages/turbo-releaser/cli/index.cjs b/packages/turbo-releaser/cli/index.cjs deleted file mode 100755 index d635b1dc6e50c..0000000000000 --- a/packages/turbo-releaser/cli/index.cjs +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env node - -const { spawnSync } = require("node:child_process"); -const path = require("node:path"); - -const PATH_TO_DIST = path.resolve(__dirname, "../dist"); - -// Define the path to the CLI file -const cliPath = path.resolve(__dirname, PATH_TO_DIST, "index.js"); - -try { - const result = spawnSync("node", [cliPath, ...process.argv.slice(2)], { - stdio: "inherit", - }); - - process.exit(result.status); -} catch (error) { - console.error("Error loading turboreleaser CLI, please re-install", error); - process.exit(1); -} diff --git a/packages/turbo-releaser/package.json b/packages/turbo-releaser/package.json deleted file mode 100644 index 6917aaa0b75fd..0000000000000 --- a/packages/turbo-releaser/package.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "name": "@turbo/releaser", - "private": true, - "version": "0.0.1", - "bin": { - "turboreleaser": "cli/index.cjs" - }, - "files": [ - "dist", - "template" - ], - "scripts": { - "build": "tsup", - "check-types": "tsc --noEmit", - "test": "node --import tsx --test src/*.test.ts", - "lint": "eslint src/", - "lint:prettier": "prettier -c . --cache --ignore-path=../../.prettierignore" - }, - "dependencies": { - "commander": "^11.0.0", - "tar": "6.1.13" - }, - "devDependencies": { - "@turbo/eslint-config": "workspace:*", - "@turbo/tsconfig": "workspace:*", - "@types/node": "^20", - "@types/tar": "^6.1.4", - "typescript": "5.5.4", - "tsup": "^6.7.0", - "tsx": "4.19.1" - } -} diff --git a/packages/turbo-releaser/src/index.ts b/packages/turbo-releaser/src/index.ts deleted file mode 100644 index 7b4e01d5c8516..0000000000000 --- a/packages/turbo-releaser/src/index.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { Command } from "commander"; -import { packAndPublish } from "./packager"; -import type { Platform } from "./types"; -import { getVersionInfo } from "./version"; - -const supportedPlatforms: Array = [ - { os: "darwin", arch: "x64" }, - { os: "darwin", arch: "arm64" }, - { os: "linux", arch: "x64" }, - { os: "linux", arch: "arm64" }, - { os: "windows", arch: "x64" }, - { os: "windows", arch: "arm64" }, -]; - -const turboReleaser = new Command(); -turboReleaser - .requiredOption("--version-path ", "Path to the version.txt file") - .option("--skip-publish", "Skip publishing to NPM") - .action(main); - -async function main(options: { skipPublish: boolean; versionPath: string }) { - console.log("Command line options:", options); - console.log("Supported platforms:", supportedPlatforms); - - try { - const { version, npmTag } = await getVersionInfo(options.versionPath); - console.log(`Using version: ${version}, NPM tag: ${npmTag}`); - - await packAndPublish({ - platforms: supportedPlatforms, - version, - skipPublish: options.skipPublish as boolean, - npmTag, - }); - console.log("Packaging and publishing completed successfully"); - } catch (error) { - console.error("Error during packaging and publishing:", error); - process.exit(1); - } -} - -turboReleaser.parseAsync().catch((reason) => { - console.error("Unexpected error. Please report it as a bug:", reason); - process.exit(1); -}); diff --git a/packages/turbo-releaser/src/native.test.ts b/packages/turbo-releaser/src/native.test.ts deleted file mode 100644 index b0a1de655495f..0000000000000 --- a/packages/turbo-releaser/src/native.test.ts +++ /dev/null @@ -1,133 +0,0 @@ -import { describe, it, mock } from "node:test"; -import assert from "node:assert/strict"; -import path from "node:path"; -import fs from "node:fs/promises"; -import native from "./native"; -import type { Platform } from "./types"; - -describe("generateNativePackage", () => { - const outputDir = "/path/to/output"; - - it("should generate package correctly for non-Windows platform", async (t) => { - const mockRm = mock.fn((_path: string) => Promise.resolve()); - const mockMkdir = mock.fn((_path: string) => Promise.resolve()); - const mockCopyFile = mock.fn((_src: string, _dst: string) => - Promise.resolve() - ); - const mockWriteFile = mock.fn((_path: string, _data: string) => - Promise.resolve() - ); - - t.mock.method(fs, "rm", mockRm); - t.mock.method(fs, "mkdir", mockMkdir); - t.mock.method(fs, "copyFile", mockCopyFile); - t.mock.method(fs, "writeFile", mockWriteFile); - - const platform: Platform = { os: "darwin", arch: "x64" }; - const version = "1.0.0"; - await native.generateNativePackage({ platform, version, outputDir }); - - // Assert rm was called correctly - assert.equal(mockRm.mock.calls.length, 1); - assert.equal(mockRm.mock.calls[0].arguments[0], outputDir); - - // Assert mkdir was called correctly - assert.equal(mockMkdir.mock.calls.length, 1); - assert.equal( - mockMkdir.mock.calls[0].arguments[0], - path.join(outputDir, "bin") - ); - - // Assert copyFile was called correctly - assert.equal(mockCopyFile.mock.calls.length, 2); - assert.ok( - mockCopyFile.mock.calls[0].arguments[0].endsWith("template/README.md") - ); - assert.equal( - mockCopyFile.mock.calls[0].arguments[1], - path.join(outputDir, "README.md") - ); - assert.ok( - mockCopyFile.mock.calls[1].arguments[0].endsWith("template/LICENSE") - ); - assert.equal( - mockCopyFile.mock.calls[1].arguments[1], - path.join(outputDir, "LICENSE") - ); - - // Assert writeFile was called correctly - assert.equal(mockWriteFile.mock.calls.length, 1); - const [filePath, content] = mockWriteFile.mock.calls[0].arguments; - assert.equal(filePath, path.join(outputDir, "package.json")); - - const packageJson = JSON.parse(content) as { - name: string; - version: string; - description: string; - os: Array; - cpu: Array; - }; - assert.equal(packageJson.name, `turbo-darwin-${native.archToHuman.x64}`); - assert.equal(packageJson.version, version); - assert.equal( - packageJson.description, - "The darwin-x64 binary for turbo, a monorepo build system." - ); - assert.deepEqual(packageJson.os, ["darwin"]); - assert.deepEqual(packageJson.cpu, ["x64"]); - }); - - it("should handle Windows platform correctly", async (t) => { - const mockRm = mock.fn((_path: string) => Promise.resolve()); - const mockMkdir = mock.fn((_path: string) => Promise.resolve()); - const mockCopyFile = mock.fn((_src: string, _dst: string) => - Promise.resolve() - ); - const mockWriteFile = mock.fn((_path: string, _data: string) => - Promise.resolve() - ); - - t.mock.method(fs, "rm", mockRm); - t.mock.method(fs, "mkdir", mockMkdir); - t.mock.method(fs, "copyFile", mockCopyFile); - t.mock.method(fs, "writeFile", mockWriteFile); - - await native.generateNativePackage({ - platform: { os: "windows", arch: "x64" }, - version: "1.0.0", - outputDir, - }); - - assert.equal(mockCopyFile.mock.calls.length, 3); - assert.ok( - mockCopyFile.mock.calls[0].arguments[0].endsWith("template/bin/turbo") - ); - assert.equal( - mockCopyFile.mock.calls[0].arguments[1], - path.join(outputDir, "bin", "turbo") - ); - }); - - it("should propagate errors", async (t) => { - const mockRm = mock.fn(() => { - throw new Error("Failed to remove directory"); - }); - t.mock.method(fs, "rm", mockRm); - - await assert.rejects( - native.generateNativePackage({ - platform: { os: "linux", arch: "x64" }, - version: "1.2.0", - outputDir, - }), - { message: "Failed to remove directory" } - ); - }); -}); - -describe("archToHuman", () => { - it("should map architectures correctly", () => { - assert.equal(native.archToHuman.x64, "64"); - assert.equal(native.archToHuman.arm64, "arm64"); - }); -}); diff --git a/packages/turbo-releaser/src/native.ts b/packages/turbo-releaser/src/native.ts deleted file mode 100644 index 1ea2924ee0745..0000000000000 --- a/packages/turbo-releaser/src/native.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { rm, mkdir, copyFile, writeFile } from "node:fs/promises"; -import path from "node:path"; -import type { SupportedArch, HumanArch, Platform } from "./types"; - -export const archToHuman: Record = { - x64: "64", - arm64: "arm64", -}; - -const templateDir = path.join(__dirname, "..", "template"); - -async function generateNativePackage({ - platform, - version, - outputDir, -}: { - platform: Platform; - version: string; - outputDir: string; -}) { - const { os, arch } = platform; - console.log(`Generating native package for ${os}-${arch}...`); - - console.log(`Cleaning output directory: ${outputDir}`); - await rm(outputDir, { recursive: true, force: true }); - await mkdir(path.join(outputDir, "bin"), { recursive: true }); - - const copyFromTemplate = async (part: string, ...parts: Array) => { - console.log("Copying ", path.join(part, ...parts)); - await copyFile( - path.join(templateDir, part, ...parts), - path.join(outputDir, part, ...parts) - ); - }; - - if (os === "windows") { - await copyFromTemplate("bin", "turbo"); - } - - await copyFromTemplate("README.md"); - await copyFromTemplate("LICENSE"); - - console.log("Generating package.json..."); - const packageJson = { - name: `turbo-${os}-${archToHuman[arch]}`, - version, - description: `The ${os}-${arch} binary for turbo, a monorepo build system.`, - repository: "https://github.com/vercel/turborepo", - bugs: "https://github.com/vercel/turborepo/issues", - homepage: "https://turbo.build/repo", - license: "MIT", - os: [os], - cpu: [arch], - preferUnplugged: true, - }; - await writeFile( - path.join(outputDir, "package.json"), - JSON.stringify(packageJson, null, 2) - ); - - console.log(`Native package generated successfully in ${outputDir}`); -} - -// Exported asn an object instead of export keyword, so that these functions -// can be mocked in tests. -export default { generateNativePackage, archToHuman }; diff --git a/packages/turbo-releaser/src/operations.test.ts b/packages/turbo-releaser/src/operations.test.ts deleted file mode 100644 index b00602ed415a2..0000000000000 --- a/packages/turbo-releaser/src/operations.test.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { describe, it, mock } from "node:test"; -import fs from "node:fs/promises"; -import assert from "node:assert"; -import path from "node:path"; -import tar from "tar"; -import native from "./native"; -import type { Platform } from "./types"; -import operations from "./operations"; - -describe("packPlatform", () => { - it("should pack a platform correctly", async (t) => { - const mockGenerateNativePackage = mock.fn(); - const mockMkdir = mock.fn(); - const mockCopyFile = mock.fn(); - const mockTarCreate = mock.fn(); - - t.mock.method(native, "generateNativePackage", mockGenerateNativePackage); - t.mock.method(fs, "mkdir", mockMkdir); - t.mock.method(fs, "copyFile", mockCopyFile); - t.mock.method(tar, "create", mockTarCreate); - - const platform: Platform = { os: "darwin", arch: "x64" }; - const version = "1.0.0"; - - const result = await operations.packPlatform(platform, version); - - assert.equal(mockGenerateNativePackage.mock.calls.length, 1); - assert.equal(mockMkdir.mock.calls.length, 1); - assert.equal(mockCopyFile.mock.calls.length, 1); - assert.equal(mockTarCreate.mock.calls.length, 1); - - assert.ok(result.endsWith("darwin-x64-1.0.0.tar.gz")); - assert.ok(path.isAbsolute(result)); - }); - - it("should pack a Windows with .exe", async (t) => { - const mockGenerateNativePackage = mock.fn(); - const mockMkdir = mock.fn(); - const mockCopyFile = mock.fn((_src: string, _dst: string) => - Promise.resolve() - ); - const mockTarCreate = mock.fn(); - - t.mock.method(native, "generateNativePackage", mockGenerateNativePackage); - t.mock.method(fs, "mkdir", mockMkdir); - t.mock.method(fs, "copyFile", mockCopyFile); - t.mock.method(tar, "create", mockTarCreate); - - const platform: Platform = { os: "windows", arch: "x64" }; - const version = "1.0.0"; - - const result = await operations.packPlatform(platform, version); - - assert.ok( - mockCopyFile.mock.calls[0].arguments[0].endsWith("turbo.exe"), - "source ends with .exe" - ); - assert.ok( - mockCopyFile.mock.calls[0].arguments[1].endsWith("turbo.exe"), - "destination ends with .exe" - ); - assert.equal(mockGenerateNativePackage.mock.calls.length, 1); - assert.equal(mockMkdir.mock.calls.length, 1); - assert.equal(mockCopyFile.mock.calls.length, 1); - assert.equal(mockTarCreate.mock.calls.length, 1); - - assert.ok(result.endsWith("windows-x64-1.0.0.tar.gz")); - assert.ok(path.isAbsolute(result)); - }); -}); diff --git a/packages/turbo-releaser/src/operations.ts b/packages/turbo-releaser/src/operations.ts deleted file mode 100644 index 822c37a2d46ed..0000000000000 --- a/packages/turbo-releaser/src/operations.ts +++ /dev/null @@ -1,56 +0,0 @@ -import path from "node:path"; -import fs from "node:fs/promises"; -import { execSync } from "node:child_process"; -import tar from "tar"; -import native from "./native"; -import type { Platform } from "./types"; - -async function packPlatform( - platform: Platform, - version: string -): Promise { - const { os, arch } = platform; - console.log(`Packing platform: ${os}-${arch}`); - const npmDirName = `turbo-${os}-${arch}`; - const tarballDir = path.join("dist", `${os}-${arch}-${version}`); - const scaffoldDir = path.join(tarballDir, npmDirName); - - console.log("Generating native package..."); - await native.generateNativePackage({ - platform, - version, - outputDir: scaffoldDir, - }); - - console.log("Moving prebuilt binary..."); - const binaryName = os === "windows" ? "turbo.exe" : "turbo"; - const sourcePath = path.join(`dist-${os}-${arch}`, binaryName); - const destPath = path.join(scaffoldDir, "bin", binaryName); - await fs.mkdir(path.dirname(destPath), { recursive: true }); - await fs.copyFile(sourcePath, destPath); - - console.log("Creating tar.gz..."); - const tarName = `${os}-${arch}-${version}.tar.gz`; - const tarPath = path.join("dist", tarName); - await tar.create( - { - gzip: true, - file: tarPath, - cwd: tarballDir, - }, - [npmDirName] - ); - - console.log(`Artifact created: ${tarPath}`); - return path.resolve(tarPath); -} - -function publishArtifacts(artifacts: Array, npmTag: string) { - for (const artifact of artifacts) { - const publishCommand = `npm publish "${artifact}" --tag ${npmTag}`; - console.log(`Executing: ${publishCommand}`); - execSync(publishCommand, { stdio: "inherit" }); - } -} - -export default { packPlatform, publishArtifacts }; diff --git a/packages/turbo-releaser/src/packager.test.ts b/packages/turbo-releaser/src/packager.test.ts deleted file mode 100644 index c9568d838e2e3..0000000000000 --- a/packages/turbo-releaser/src/packager.test.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { describe, it, mock } from "node:test"; -import assert from "node:assert/strict"; -import { packAndPublish } from "./packager"; -import type { Platform } from "./types"; -import operations from "./operations"; - -describe("packager", () => { - describe("packAndPublish", () => { - it("should pack and publish for all platforms when skipPublish is false", async (t) => { - const mockPackPlatform = mock.fn(() => - Promise.resolve("/path/to/artifact.tgz") - ); - const mockPublishArtifacts = mock.fn((_paths: Array) => - Promise.resolve() - ); - t.mock.method(operations, "packPlatform", mockPackPlatform); - t.mock.method(operations, "publishArtifacts", mockPublishArtifacts); - - const platforms: Array = [ - { os: "darwin", arch: "x64" }, - { os: "linux", arch: "arm64" }, - ]; - const version = "1.0.0"; - const npmTag = "latest"; - - await packAndPublish({ platforms, version, skipPublish: false, npmTag }); - - assert.equal(mockPackPlatform.mock.calls.length, 2); - assert.equal(mockPublishArtifacts.mock.calls.length, 1); - assert.deepEqual(mockPublishArtifacts.mock.calls[0].arguments, [ - ["/path/to/artifact.tgz", "/path/to/artifact.tgz"], - "latest", - ]); - }); - - it("should pack but not publish when skipPublish is true", async (t) => { - const mockPackPlatform = mock.fn(() => - Promise.resolve("/path/to/artifact.tgz") - ); - const mockPublishArtifacts = mock.fn(); - - t.mock.method(operations, "packPlatform", mockPackPlatform); - t.mock.method(operations, "publishArtifacts", mockPublishArtifacts); - - const platforms: Array = [{ os: "darwin", arch: "x64" }]; - const version = "1.0.0"; - const npmTag = "latest"; - - await packAndPublish({ platforms, version, skipPublish: true, npmTag }); - - assert.equal(mockPackPlatform.mock.calls.length, 1); - assert.equal(mockPublishArtifacts.mock.calls.length, 0); - }); - }); -}); diff --git a/packages/turbo-releaser/src/packager.ts b/packages/turbo-releaser/src/packager.ts deleted file mode 100644 index bc4fa98f5b17d..0000000000000 --- a/packages/turbo-releaser/src/packager.ts +++ /dev/null @@ -1,35 +0,0 @@ -import type { Platform } from "./types"; -import operations from "./operations"; - -interface PackAndPublishOptions { - platforms: Array; - version: string; - skipPublish: boolean; - npmTag: string; -} - -export async function packAndPublish({ - platforms, - version, - skipPublish, - npmTag, -}: PackAndPublishOptions) { - console.log("Starting packAndPublish process..."); - const artifacts: Array = []; - - for (const platform of platforms) { - console.log(`Processing platform: ${platform.os}-${platform.arch}`); - // eslint-disable-next-line no-await-in-loop -- We trade of slightly faster releases with more legible logging - const artifact = await operations.packPlatform(platform, version); - artifacts.push(artifact); - } - - console.log("All platforms processed. Artifacts:", artifacts); - - if (!skipPublish) { - console.log("Publishing artifacts..."); - operations.publishArtifacts(artifacts, npmTag); - } else { - console.log("Skipping publish step."); - } -} diff --git a/packages/turbo-releaser/src/types.ts b/packages/turbo-releaser/src/types.ts deleted file mode 100644 index f75d9bba2c69c..0000000000000 --- a/packages/turbo-releaser/src/types.ts +++ /dev/null @@ -1,8 +0,0 @@ -export type SupportedOS = "darwin" | "linux" | "windows"; -export type SupportedArch = "x64" | "arm64"; -export type HumanArch = "64" | "arm64"; - -export interface Platform { - os: SupportedOS; - arch: SupportedArch; -} diff --git a/packages/turbo-releaser/src/version.test.ts b/packages/turbo-releaser/src/version.test.ts deleted file mode 100644 index 0319c23b2adb1..0000000000000 --- a/packages/turbo-releaser/src/version.test.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { describe, it, mock } from "node:test"; -import assert from "node:assert"; -import fs from "node:fs/promises"; -import { getVersionInfo } from "./version"; - -describe("getVersionInfo", () => { - it("should read version and npm tag from version.txt", async (t) => { - const mockReadFile = mock.fn((_path, _encoding) => { - return Promise.resolve("1.0.0\nbeta\n"); - }); - t.mock.method(fs, "readFile", mockReadFile); - const result = await getVersionInfo("some-path/version.txt"); - assert.deepStrictEqual(result, { version: "1.0.0", npmTag: "beta" }); - assert.equal( - mockReadFile.mock.calls[0].arguments[0], - "some-path/version.txt" - ); - }); - - it("should throw an error if version.txt is not found", async (t) => { - const mockReadFile = mock.fn((_path, _encoding) => { - return Promise.reject(new Error("File not found")); - }); - t.mock.method(fs, "readFile", mockReadFile); - await assert.rejects(() => getVersionInfo("version.txt"), { - message: "File not found", - }); - }); -}); diff --git a/packages/turbo-releaser/src/version.ts b/packages/turbo-releaser/src/version.ts deleted file mode 100644 index a727355f54c2b..0000000000000 --- a/packages/turbo-releaser/src/version.ts +++ /dev/null @@ -1,11 +0,0 @@ -import fs from "node:fs/promises"; - -export async function getVersionInfo(versionPath: string): Promise<{ - version: string; - npmTag: string; -}> { - const versionFile = await fs.readFile(versionPath, "utf-8"); - const [version, npmTag] = versionFile.trim().split("\n"); - console.log(`Version: ${version}, NPM Tag: ${npmTag}`); - return { version, npmTag }; -} diff --git a/packages/turbo-releaser/template/LICENSE b/packages/turbo-releaser/template/LICENSE deleted file mode 100644 index 5c3db8bb6f857..0000000000000 --- a/packages/turbo-releaser/template/LICENSE +++ /dev/null @@ -1,7 +0,0 @@ -Copyright (c) 2024 Vercel, Inc - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turbo-releaser/tsconfig.json b/packages/turbo-releaser/tsconfig.json deleted file mode 100644 index e6f9fc6aa70b6..0000000000000 --- a/packages/turbo-releaser/tsconfig.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": "@turbo/tsconfig/library.json", - "compilerOptions": { - "rootDir": ".", - "module": "ESNext", - "lib": ["ESNext"] - } -} diff --git a/packages/turbo-releaser/tsup.config.ts b/packages/turbo-releaser/tsup.config.ts deleted file mode 100644 index b78e5518aef2a..0000000000000 --- a/packages/turbo-releaser/tsup.config.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { defineConfig, Options } from "tsup"; - -export default defineConfig((options: Options) => ({ - entry: ["src/index.ts"], - format: ["cjs"], - clean: true, - minify: true, - ...options, -})); diff --git a/packages/turbo-releaser/turbo.json b/packages/turbo-releaser/turbo.json deleted file mode 100644 index 07dd354a7722d..0000000000000 --- a/packages/turbo-releaser/turbo.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": ["//"], - "tasks": { - "build": { - "dependsOn": ["^build"], - "outputs": ["dist"] - } - } -} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 92a9dc7791a66..9c6f595b5617c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -46,11 +46,7 @@ importers: specifier: ^0.36.0 version: 0.36.0 - cli: - dependencies: - '@turbo/releaser': - specifier: workspace:* - version: link:../packages/turbo-releaser + cli: {} docs: dependencies: @@ -564,37 +560,6 @@ importers: specifier: 5.5.4 version: 5.5.4 - packages/turbo-releaser: - dependencies: - commander: - specifier: ^11.0.0 - version: 11.0.0 - tar: - specifier: 6.1.13 - version: 6.1.13 - devDependencies: - '@turbo/eslint-config': - specifier: workspace:* - version: link:../eslint-config - '@turbo/tsconfig': - specifier: workspace:* - version: link:../tsconfig - '@types/node': - specifier: ^20 - version: 20.11.30 - '@types/tar': - specifier: ^6.1.4 - version: 6.1.4 - tsup: - specifier: ^6.7.0 - version: 6.7.0(ts-node@10.9.2)(typescript@5.5.4) - tsx: - specifier: 4.19.1 - version: 4.19.1 - typescript: - specifier: 5.5.4 - version: 5.5.4 - packages/turbo-repository: devDependencies: '@napi-rs/cli': @@ -4223,6 +4188,7 @@ packages: /chownr@2.0.0: resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} engines: {node: '>=10'} + dev: true /ci-info@3.8.0: resolution: {integrity: sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==} @@ -6394,6 +6360,7 @@ packages: engines: {node: '>= 8'} dependencies: minipass: 3.3.6 + dev: true /fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} @@ -8926,12 +8893,14 @@ packages: engines: {node: '>=8'} dependencies: yallist: 4.0.0 + dev: true /minipass@4.0.0: resolution: {integrity: sha512-g2Uuh2jEKoht+zvO6vJqXmYpflPqzRBT+Th2h01DKh5z7wbY/AZ2gCQ78cP70YoHPyFdY30YBV5WxgLOEwOykw==} engines: {node: '>=8'} dependencies: yallist: 4.0.0 + dev: true /minipass@7.1.2: resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} @@ -8944,6 +8913,7 @@ packages: dependencies: minipass: 3.3.6 yallist: 4.0.0 + dev: true /mixin-deep@1.3.2: resolution: {integrity: sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==} @@ -8962,7 +8932,7 @@ packages: /mkdirp@1.0.4: resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} engines: {node: '>=10'} - hasBin: true + dev: true /ms@2.0.0: resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} @@ -10750,6 +10720,7 @@ packages: minizlib: 2.1.2 mkdirp: 1.0.4 yallist: 4.0.0 + dev: true /test-exclude@6.0.0: resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} @@ -11169,7 +11140,6 @@ packages: /tsx@4.19.1: resolution: {integrity: sha512-0flMz1lh74BR4wOvBjuh9olbnwqCPc35OOlfyzHba0Dc+QNUeWX/Gq2YTbnwcWPO3BMd8fkzRVrHcsR+a7z7rA==} engines: {node: '>=18.0.0'} - hasBin: true dependencies: esbuild: 0.23.1 get-tsconfig: 4.7.6 @@ -11318,7 +11288,6 @@ packages: /typescript@5.5.4: resolution: {integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==} engines: {node: '>=14.17'} - hasBin: true /uglify-js@3.17.4: resolution: {integrity: sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==}