Skip to content

Commit

Permalink
fix(releaser): make sure binary is executable
Browse files Browse the repository at this point in the history
  • Loading branch information
chris-olszewski committed Feb 7, 2025
1 parent 1172ed9 commit 47c89f2
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 10 deletions.
52 changes: 52 additions & 0 deletions packages/turbo-releaser/src/e2e.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import assert from "node:assert/strict";
import { test } from "node:test";
import path from "node:path";
import os from "node:os";
import { mkdir, realpath, rm, writeFile } from "node:fs/promises";
import { execSync } from "node:child_process";
import operations from "./operations";

test("produces installable archive", async () => {
const tempDir = path.join(
await realpath(os.tmpdir()),
"turboreleaser-e2e-test"
);
await rm(tempDir, { recursive: true, force: true });
await mkdir(tempDir, { recursive: true });

// make a fake turbo binary at `dist-darwin-arm64/turbo`
const platformPath = "dist-darwin-arm64";
await mkdir(path.join(tempDir, platformPath));
await writeFile(
path.join(tempDir, platformPath, "turbo"),
"#!/bin/bash\necho Invoked fake turbo!"
);

const tarPath = await operations.packPlatform({
platform: { os: "darwin", arch: "arm64" },
version: "0.1.2",
srcDir: tempDir,
});
assert.ok(path.isAbsolute(tarPath));

// Make a fake repo to install the tarball in
const fakeRepo = path.join(tempDir, "fake-repo");
await mkdir(fakeRepo);
await writeFile(
path.join(fakeRepo, "package.json"),
JSON.stringify({
name: "fake-repo",
scripts: { "test-turbo-install": "turbo" },
})
);
execSync(`npm install ${tarPath}`, { cwd: fakeRepo });
const output = execSync("npm run test-turbo-install", {
stdio: "pipe",
cwd: fakeRepo,
encoding: "utf-8",
});
assert.equal(
output,
"\n> test-turbo-install\n> turbo\n\nInvoked fake turbo!\n"
);
});
17 changes: 15 additions & 2 deletions packages/turbo-releaser/src/operations.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,28 @@ describe("packPlatform", () => {
const mockGenerateNativePackage = mock.fn();
const mockMkdir = mock.fn();
const mockCopyFile = mock.fn();
const mockStat = mock.fn(() => Promise.resolve({ mode: 0 }));
const mockChmod = 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(fs, "stat", mockStat);
t.mock.method(fs, "chmod", mockChmod);
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);
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(mockStat.mock.calls.length, 1);
assert.equal(mockChmod.mock.calls.length, 1);
assert.equal(mockChmod.mock.calls[0].arguments[1], 0o111);
assert.equal(mockTarCreate.mock.calls.length, 1);

assert.ok(result.endsWith("darwin-x64-1.0.0.tar.gz"));
Expand All @@ -39,17 +46,21 @@ describe("packPlatform", () => {
const mockCopyFile = mock.fn((_src: string, _dst: string) =>
Promise.resolve()
);
const mockStat = mock.fn(() => Promise.resolve({ mode: 0 }));
const mockChmod = mock.fn();
const mockTarCreate = mock.fn();

t.mock.method(native, "generateNativePackage", mockGenerateNativePackage);
t.mock.method(fs, "mkdir", mockMkdir);
t.mock.method(fs, "stat", mockStat);
t.mock.method(fs, "chmod", mockChmod);
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);
const result = await operations.packPlatform({ platform, version });

assert.ok(
mockCopyFile.mock.calls[0].arguments[0].endsWith("turbo.exe"),
Expand All @@ -63,6 +74,8 @@ describe("packPlatform", () => {
assert.equal(mockMkdir.mock.calls.length, 1);
assert.equal(mockCopyFile.mock.calls.length, 1);
assert.equal(mockTarCreate.mock.calls.length, 1);
assert.equal(mockChmod.mock.calls.length, 1);
assert.equal(mockChmod.mock.calls[0].arguments[1], 0o111);

assert.ok(result.endsWith("windows-x64-1.0.0.tar.gz"));
assert.ok(path.isAbsolute(result));
Expand Down
29 changes: 22 additions & 7 deletions packages/turbo-releaser/src/operations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,24 @@ import tar from "tar";
import native from "./native";
import type { Platform } from "./types";

async function packPlatform(
platform: Platform,
version: string
): Promise<string> {
export interface PackOptions {
platform: Platform;
version: string;
// Directory where prebuilt `turbo` binaries are located
// It will also be where `dist` is created and tarballs are put.
// Defaults to cwd
srcDir?: string;
}

async function packPlatform({
platform,
version,
srcDir = process.cwd(),
}: PackOptions): Promise<string> {
const { os, arch } = platform;
console.log(`Packing platform: ${os}-${arch}`);
const npmDirName = `turbo-${os}-${arch}`;
const tarballDir = path.join("dist", `${os}-${arch}-${version}`);
const tarballDir = path.join(srcDir, "dist", `${os}-${arch}-${version}`);
const scaffoldDir = path.join(tarballDir, npmDirName);

console.log("Generating native package...");
Expand All @@ -24,14 +34,19 @@ async function packPlatform(

console.log("Moving prebuilt binary...");
const binaryName = os === "windows" ? "turbo.exe" : "turbo";
const sourcePath = path.join(`dist-${os}-${arch}`, binaryName);
const sourcePath = path.join(srcDir, `dist-${os}-${arch}`, binaryName);
const destPath = path.join(scaffoldDir, "bin", binaryName);
await fs.mkdir(path.dirname(destPath), { recursive: true });
await fs.copyFile(sourcePath, destPath);
// Make sure the binary we copied is executable
const stat = await fs.stat(destPath);
const currMode = stat.mode;
// eslint-disable-next-line no-bitwise -- necessary for enabling the executable bits
await fs.chmod(destPath, currMode | 0o111);

console.log("Creating tar.gz...");
const tarName = `${os}-${arch}-${version}.tar.gz`;
const tarPath = path.join("dist", tarName);
const tarPath = path.join(srcDir, "dist", tarName);
await tar.create(
{
gzip: true,
Expand Down
2 changes: 1 addition & 1 deletion packages/turbo-releaser/src/packager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export async function packAndPublish({
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);
const artifact = await operations.packPlatform({ platform, version });
artifacts.push(artifact);
}

Expand Down
Empty file modified packages/turbo-releaser/template/bin/turbo
100644 → 100755
Empty file.

0 comments on commit 47c89f2

Please # to comment.