Skip to content

Commit

Permalink
rollback semi
Browse files Browse the repository at this point in the history
  • Loading branch information
okineadev committed Feb 4, 2025
1 parent f6221cd commit 2a182f9
Show file tree
Hide file tree
Showing 6 changed files with 166 additions and 166 deletions.
2 changes: 1 addition & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"semi": false,
"semi": true,
"quoteProps": "preserve"
}
186 changes: 93 additions & 93 deletions src/action.ts
Original file line number Diff line number Diff line change
@@ -1,210 +1,210 @@
import { createHash } from "node:crypto"
import { homedir } from "node:os"
import { join } from "node:path"
import { createHash } from "node:crypto";
import { homedir } from "node:os";
import { join } from "node:path";
import {
mkdirSync,
readdirSync,
symlinkSync,
renameSync,
copyFileSync,
} from "node:fs"
import { addPath, info, warning } from "@actions/core"
import { isFeatureAvailable, restoreCache } from "@actions/cache"
import { downloadTool, extractZip } from "@actions/tool-cache"
import { getExecOutput } from "@actions/exec"
import { writeBunfig } from "./bunfig"
import { saveState } from "@actions/core"
import { addExtension, retry } from "./utils"
} from "node:fs";
import { addPath, info, warning } from "@actions/core";
import { isFeatureAvailable, restoreCache } from "@actions/cache";
import { downloadTool, extractZip } from "@actions/tool-cache";
import { getExecOutput } from "@actions/exec";
import { writeBunfig } from "./bunfig";
import { saveState } from "@actions/core";
import { addExtension, retry } from "./utils";

export type Input = {
customUrl?: string
version?: string
os?: string
arch?: string
avx2?: boolean
profile?: boolean
scope?: string
registryUrl?: string
noCache?: boolean
}
customUrl?: string;
version?: string;
os?: string;
arch?: string;
avx2?: boolean;
profile?: boolean;
scope?: string;
registryUrl?: string;
noCache?: boolean;
};

export type Output = {
version: string
revision: string
bunPath: string
url: string
cacheHit: boolean
}
version: string;
revision: string;
bunPath: string;
url: string;
cacheHit: boolean;
};

export type CacheState = {
cacheEnabled: boolean
cacheHit: boolean
bunPath: string
url: string
}
cacheEnabled: boolean;
cacheHit: boolean;
bunPath: string;
url: string;
};

export default async (options: Input): Promise<Output> => {
const bunfigPath = join(process.cwd(), "bunfig.toml")
writeBunfig(bunfigPath, options)
const bunfigPath = join(process.cwd(), "bunfig.toml");
writeBunfig(bunfigPath, options);

const url = getDownloadUrl(options)
const cacheEnabled = isCacheEnabled(options)
const url = getDownloadUrl(options);
const cacheEnabled = isCacheEnabled(options);

const binPath = join(homedir(), ".bun", "bin")
const binPath = join(homedir(), ".bun", "bin");
try {
mkdirSync(binPath, { recursive: true })
mkdirSync(binPath, { recursive: true });
} catch (error) {
if (error.code !== "EEXIST") {
throw error
throw error;
}
}
addPath(binPath)
addPath(binPath);

const exe = (name: string) =>
process.platform === "win32" ? `${name}.exe` : name
const bunPath = join(binPath, exe("bun"))
process.platform === "win32" ? `${name}.exe` : name;
const bunPath = join(binPath, exe("bun"));
try {
symlinkSync(bunPath, join(binPath, exe("bunx")))
symlinkSync(bunPath, join(binPath, exe("bunx")));
} catch (error) {
if (error.code !== "EEXIST") {
throw error
throw error;
}
}

let revision: string | undefined
let cacheHit = false
let revision: string | undefined;
let cacheHit = false;
if (cacheEnabled) {
const cacheKey = createHash("sha1").update(url).digest("base64")
const cacheKey = createHash("sha1").update(url).digest("base64");

const cacheRestored = await restoreCache([bunPath], cacheKey)
const cacheRestored = await restoreCache([bunPath], cacheKey);
if (cacheRestored) {
revision = await getRevision(bunPath)
revision = await getRevision(bunPath);
if (revision) {
cacheHit = true
info(`Using a cached version of Bun: ${revision}`)
cacheHit = true;
info(`Using a cached version of Bun: ${revision}`);
} else {
warning(
`Found a cached version of Bun: ${revision} (but it appears to be corrupted?)`,
)
);
}
}
}

if (!cacheHit) {
info(`Downloading a new version of Bun: ${url}`)
info(`Downloading a new version of Bun: ${url}`);
// TODO: remove this, temporary fix for https://github.com/oven-sh/setup-bun/issues/73
revision = await retry(async () => await downloadBun(url, bunPath), 3)
revision = await retry(async () => await downloadBun(url, bunPath), 3);
}

if (!revision) {
throw new Error(
"Downloaded a new version of Bun, but failed to check its version? Try again.",
)
);
}

const [version] = revision.split("+")
const [version] = revision.split("+");

const cacheState: CacheState = {
cacheEnabled,
cacheHit,
bunPath,
url,
}
};

saveState("cache", JSON.stringify(cacheState))
saveState("cache", JSON.stringify(cacheState));

return {
version,
revision,
bunPath,
url,
cacheHit,
}
}
};
};

async function downloadBun(
url: string,
bunPath: string,
): Promise<string | undefined> {
// Workaround for https://github.com/oven-sh/setup-bun/issues/79 and https://github.com/actions/toolkit/issues/1179
const zipPath = addExtension(await downloadTool(url), ".zip")
const extractedZipPath = await extractZip(zipPath)
const extractedBunPath = await extractBun(extractedZipPath)
const zipPath = addExtension(await downloadTool(url), ".zip");
const extractedZipPath = await extractZip(zipPath);
const extractedBunPath = await extractBun(extractedZipPath);
try {
renameSync(extractedBunPath, bunPath)
renameSync(extractedBunPath, bunPath);
} catch {
// If mv does not work, try to copy the file instead.
// For example: EXDEV: cross-device link not permitted
copyFileSync(extractedBunPath, bunPath)
copyFileSync(extractedBunPath, bunPath);
}

return await getRevision(bunPath)
return await getRevision(bunPath);
}

function isCacheEnabled(options: Input): boolean {
const { customUrl, version, noCache } = options
const { customUrl, version, noCache } = options;
if (noCache) {
return false
return false;
}
if (customUrl) {
return false
return false;
}
if (!version || /latest|canary|action/i.test(version)) {
return false
return false;
}
return isFeatureAvailable()
return isFeatureAvailable();
}

function getDownloadUrl(options: Input): string {
const { customUrl } = options
const { customUrl } = options;
if (customUrl) {
return customUrl
return customUrl;
}
const { version, os, arch, avx2, profile } = options
const eversion = encodeURIComponent(version ?? "latest")
const eos = encodeURIComponent(os ?? process.platform)
const earch = encodeURIComponent(arch ?? process.arch)
const eavx2 = encodeURIComponent(avx2 ?? true)
const eprofile = encodeURIComponent(profile ?? false)
const { version, os, arch, avx2, profile } = options;
const eversion = encodeURIComponent(version ?? "latest");
const eos = encodeURIComponent(os ?? process.platform);
const earch = encodeURIComponent(arch ?? process.arch);
const eavx2 = encodeURIComponent(avx2 ?? true);
const eprofile = encodeURIComponent(profile ?? false);
const { href } = new URL(
`${eversion}/${eos}/${earch}?avx2=${eavx2}&profile=${eprofile}`,
"https://bun.sh/download/",
)
return href
);
return href;
}

async function extractBun(path: string): Promise<string> {
for (const entry of readdirSync(path, { withFileTypes: true })) {
const { name } = entry
const entryPath = join(path, name)
const { name } = entry;
const entryPath = join(path, name);
if (entry.isFile()) {
if (name === "bun" || name === "bun.exe") {
return entryPath
return entryPath;
}
if (/^bun.*\.zip/.test(name)) {
const extractedPath = await extractZip(entryPath)
return extractBun(extractedPath)
const extractedPath = await extractZip(entryPath);
return extractBun(extractedPath);
}
}
if (/^bun/.test(name) && entry.isDirectory()) {
return extractBun(entryPath)
return extractBun(entryPath);
}
}
throw new Error("Could not find executable: bun")
throw new Error("Could not find executable: bun");
}

async function getRevision(exe: string): Promise<string | undefined> {
const revision = await getExecOutput(exe, ["--revision"], {
ignoreReturnCode: true,
})
});
if (revision.exitCode === 0 && /^\d+\.\d+\.\d+/.test(revision.stdout)) {
return revision.stdout.trim()
return revision.stdout.trim();
}
const version = await getExecOutput(exe, ["--version"], {
ignoreReturnCode: true,
})
});
if (version.exitCode === 0 && /^\d+\.\d+\.\d+/.test(version.stdout)) {
return version.stdout.trim()
return version.stdout.trim();
}
return undefined
return undefined;
}
38 changes: 19 additions & 19 deletions src/bunfig.ts
Original file line number Diff line number Diff line change
@@ -1,50 +1,50 @@
import { EOL } from "node:os"
import { appendFileSync } from "node:fs"
import { info } from "@actions/core"
import { EOL } from "node:os";
import { appendFileSync } from "node:fs";
import { info } from "@actions/core";

type BunfigOptions = {
registryUrl?: string
scope?: string
}
registryUrl?: string;
scope?: string;
};

export function createBunfig(options: BunfigOptions): string | null {
const { registryUrl, scope } = options
const { registryUrl, scope } = options;

let url: URL | undefined
let url: URL | undefined;
if (registryUrl) {
try {
url = new URL(registryUrl)
url = new URL(registryUrl);
} catch {
throw new Error(`Invalid registry-url: ${registryUrl}`)
throw new Error(`Invalid registry-url: ${registryUrl}`);
}
}

let owner: string | undefined
let owner: string | undefined;
if (scope) {
owner = scope.startsWith("@")
? scope.toLocaleLowerCase()
: `@${scope.toLocaleLowerCase()}`
: `@${scope.toLocaleLowerCase()}`;
}

if (url && owner) {
return `[install.scopes]${EOL}'${owner}' = { token = "$BUN_AUTH_TOKEN", url = "${url}"}${EOL}`
return `[install.scopes]${EOL}'${owner}' = { token = "$BUN_AUTH_TOKEN", url = "${url}"}${EOL}`;
}

if (url && !owner) {
return `[install]${EOL}registry = "${url}"${EOL}`
return `[install]${EOL}registry = "${url}"${EOL}`;
}

return null
return null;
}

export function writeBunfig(path: string, options: BunfigOptions): void {
const bunfig = createBunfig(options)
const bunfig = createBunfig(options);
if (!bunfig) {
return
return;
}

info(`Writing bunfig.toml to '${path}'.`)
info(`Writing bunfig.toml to '${path}'.`);
appendFileSync(path, bunfig, {
encoding: "utf8",
})
});
}
Loading

0 comments on commit 2a182f9

Please sign in to comment.