mirror of
https://github.com/oven-sh/setup-bun.git
synced 2025-07-19 21:18:22 +02:00
feat: support for multiple registries
This commit is contained in:
parent
7c641390eb
commit
c623269aa2
6 changed files with 332 additions and 22 deletions
|
@ -12,7 +12,7 @@ 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 { writeBunfig, Registry } from "./bunfig";
|
||||
import { saveState } from "@actions/core";
|
||||
import { addExtension, retry } from "./utils";
|
||||
|
||||
|
@ -23,8 +23,7 @@ export type Input = {
|
|||
arch?: string;
|
||||
avx2?: boolean;
|
||||
profile?: boolean;
|
||||
scope?: string;
|
||||
registryUrl?: string;
|
||||
registries?: Registry[];
|
||||
noCache?: boolean;
|
||||
};
|
||||
|
||||
|
@ -45,7 +44,7 @@ export type CacheState = {
|
|||
|
||||
export default async (options: Input): Promise<Output> => {
|
||||
const bunfigPath = join(process.cwd(), "bunfig.toml");
|
||||
writeBunfig(bunfigPath, options);
|
||||
writeBunfig(bunfigPath, options.registries);
|
||||
|
||||
const url = getDownloadUrl(options);
|
||||
const cacheEnabled = isCacheEnabled(options);
|
||||
|
|
142
src/bunfig.ts
142
src/bunfig.ts
|
@ -1,21 +1,32 @@
|
|||
import { EOL } from "node:os";
|
||||
import { appendFileSync } from "node:fs";
|
||||
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
||||
import { info } from "@actions/core";
|
||||
|
||||
type BunfigOptions = {
|
||||
registryUrl?: string;
|
||||
scope?: string;
|
||||
export type Registry = {
|
||||
url: string;
|
||||
scope: string;
|
||||
token: string;
|
||||
};
|
||||
|
||||
export function createBunfig(options: BunfigOptions): string | null {
|
||||
const { registryUrl, scope } = options;
|
||||
enum FieldType {
|
||||
GLOBAL_REGISTRY,
|
||||
INSTALL_WITH_SCOPE,
|
||||
}
|
||||
|
||||
type Field = {
|
||||
type: FieldType;
|
||||
value: string;
|
||||
};
|
||||
|
||||
export function createField(registry: Registry): Field {
|
||||
const { url: registryUrl, scope, token } = registry;
|
||||
|
||||
let url: URL | undefined;
|
||||
if (registryUrl) {
|
||||
try {
|
||||
url = new URL(registryUrl);
|
||||
} catch {
|
||||
throw new Error(`Invalid registry-url: ${registryUrl}`);
|
||||
throw new Error(`Invalid registry url ${registryUrl}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,24 +38,131 @@ export function createBunfig(options: BunfigOptions): string | null {
|
|||
}
|
||||
|
||||
if (url && owner) {
|
||||
return `[install.scopes]${EOL}'${owner}' = { token = "$BUN_AUTH_TOKEN", url = "${url}"}${EOL}`;
|
||||
return {
|
||||
type: FieldType.INSTALL_WITH_SCOPE,
|
||||
value: `'${owner}' = { token = "${token}", url = "${url}" }`,
|
||||
};
|
||||
}
|
||||
|
||||
if (url && !owner) {
|
||||
return `[install]${EOL}registry = "${url}"${EOL}`;
|
||||
return {
|
||||
type: FieldType.GLOBAL_REGISTRY,
|
||||
value: `registry = "${url}"`,
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export function writeBunfig(path: string, options: BunfigOptions): void {
|
||||
const bunfig = createBunfig(options);
|
||||
export function createBunfig(registries: Registry[]): Field[] | null {
|
||||
const fields = registries.map(createField).filter((field) => field);
|
||||
if (fields.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (
|
||||
fields.filter((field) => field.type === FieldType.GLOBAL_REGISTRY).length >
|
||||
1
|
||||
) {
|
||||
throw new Error("You can't have more than one global registry.");
|
||||
}
|
||||
|
||||
return fields;
|
||||
}
|
||||
|
||||
export function serializeInstallScopes(
|
||||
fields: Field[],
|
||||
header: boolean = false
|
||||
): string {
|
||||
const installScopes = fields
|
||||
.filter((field) => field.type === FieldType.INSTALL_WITH_SCOPE)
|
||||
.map((field) => field.value)
|
||||
.join(EOL);
|
||||
|
||||
if (!installScopes) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return `${header ? `[install.scopes]${EOL}` : ""}${installScopes}${EOL}`;
|
||||
}
|
||||
|
||||
export function serializeGlobalRegistry(
|
||||
fields: Field[],
|
||||
header: boolean = false
|
||||
): string {
|
||||
const globalRegistry = fields
|
||||
.filter((field) => field.type === FieldType.GLOBAL_REGISTRY)
|
||||
.map((field) => field.value)
|
||||
.join(EOL);
|
||||
|
||||
if (!globalRegistry) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return `${header ? `[install]${EOL}` : ""}${globalRegistry}${EOL}`;
|
||||
}
|
||||
|
||||
export function writeBunfig(path: string, registries: Registry[]): void {
|
||||
const bunfig = createBunfig(registries);
|
||||
if (!bunfig) {
|
||||
return;
|
||||
}
|
||||
|
||||
info(`Writing bunfig.toml to '${path}'.`);
|
||||
appendFileSync(path, bunfig, {
|
||||
|
||||
if (!existsSync(path)) {
|
||||
writeFileSync(
|
||||
path,
|
||||
`${serializeGlobalRegistry(bunfig, true)}${serializeInstallScopes(
|
||||
bunfig,
|
||||
true
|
||||
)}`,
|
||||
{
|
||||
encoding: "utf8",
|
||||
}
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
let newContent = "";
|
||||
const contents = readFileSync(path, {
|
||||
encoding: "utf-8",
|
||||
}).split(EOL);
|
||||
|
||||
contents.forEach((line, index, array) => {
|
||||
if (index > 0 && array[index - 1].includes("[install.scopes]")) {
|
||||
newContent += serializeInstallScopes(bunfig);
|
||||
}
|
||||
|
||||
if (index > 0 && array[index - 1].includes("[install]")) {
|
||||
newContent += serializeGlobalRegistry(bunfig);
|
||||
}
|
||||
|
||||
if (
|
||||
!bunfig.some(
|
||||
(field) =>
|
||||
field.type === FieldType.INSTALL_WITH_SCOPE &&
|
||||
(line.startsWith(field.value.split(" ")[0]) ||
|
||||
((line[0] === "'" || line[0] === '"') &&
|
||||
line
|
||||
.toLowerCase()
|
||||
.startsWith(field.value.split(" ")[0].slice(1).slice(0, -1))))
|
||||
)
|
||||
) {
|
||||
newContent += line + EOL;
|
||||
}
|
||||
});
|
||||
|
||||
if (!contents.includes("[install.scopes]")) {
|
||||
newContent += serializeInstallScopes(bunfig, true);
|
||||
}
|
||||
|
||||
if (!contents.includes("[install]")) {
|
||||
newContent += serializeGlobalRegistry(bunfig, true);
|
||||
}
|
||||
|
||||
writeFileSync(path, newContent, {
|
||||
encoding: "utf8",
|
||||
});
|
||||
}
|
||||
|
|
20
src/index.ts
20
src/index.ts
|
@ -7,14 +7,30 @@ if (!process.env.RUNNER_TEMP) {
|
|||
process.env.RUNNER_TEMP = tmpdir();
|
||||
}
|
||||
|
||||
const registries = JSON.parse(getInput("registries") || "[]");
|
||||
const registryUrl = getInput("registry-url");
|
||||
const scope = getInput("scope");
|
||||
|
||||
if (registries.length > 0 && (registryUrl || scope)) {
|
||||
setFailed("Cannot specify both 'registries' and 'registry-url' or 'scope'.");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (registryUrl) {
|
||||
registries.push({
|
||||
url: registryUrl,
|
||||
scope: scope,
|
||||
token: "$$BUN_AUTH_TOKEN",
|
||||
});
|
||||
}
|
||||
|
||||
runAction({
|
||||
version:
|
||||
getInput("bun-version") ||
|
||||
readVersionFromFile(getInput("bun-version-file")) ||
|
||||
undefined,
|
||||
customUrl: getInput("bun-download-url") || undefined,
|
||||
registryUrl: getInput("registry-url") || undefined,
|
||||
scope: getInput("scope") || undefined,
|
||||
registries: registries.length > 0 ? registries : undefined,
|
||||
noCache: getBooleanInput("no-cache") || false,
|
||||
})
|
||||
.then(({ version, revision, bunPath, url, cacheHit }) => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue