Skip to content

Commit

Permalink
Merge branch 'feat/multiple-registries'
Browse files Browse the repository at this point in the history
  • Loading branch information
xhyrom committed Dec 12, 2024
2 parents 9bdeab4 + 9a0f1f0 commit d5ff847
Show file tree
Hide file tree
Showing 11 changed files with 512 additions and 57 deletions.
56 changes: 53 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,26 @@ jobs:
env:
GH_TOKEN: ${{ github.token }}
tests:
name: Tests
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Bun
uses: ./

- name: Install dependencies
run: bun install

- name: Run tests
run: bun test --coverage

setup-bun:
runs-on: ${{ matrix.os }}
continue-on-error: true
needs: [remove-cache]
needs: [remove-cache, tests]
strategy:
matrix:
os:
Expand Down Expand Up @@ -73,7 +89,7 @@ jobs:
name: setup-bun from (${{ matrix.os }}, ${{ matrix.file.name }})
runs-on: ${{ matrix.os }}
continue-on-error: true
needs: [remove-cache]
needs: [remove-cache, tests]
strategy:
matrix:
os:
Expand Down Expand Up @@ -134,7 +150,7 @@ jobs:
name: setup-bun from (${{ matrix.os }}, download url)
runs-on: ${{ matrix.os }}
continue-on-error: true
needs: [remove-cache]
needs: [remove-cache, tests]
strategy:
matrix:
os:
Expand All @@ -155,3 +171,37 @@ jobs:
id: run_bun
run: |
bun --version
setup-bun-registry:
name: setup-bun registry (${{ matrix.os }})
runs-on: ${{ matrix.os }}
continue-on-error: true
needs: [remove-cache, tests]
strategy:
matrix:
os:
- ubuntu-latest
- macos-latest
- windows-latest

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Bun
uses: ./
id: setup_bun
with:
registries: |
[
{
"url": "https://username:[email protected]/",
"scope": "@myorg"
}
]
- name: Run Bun
id: run_bun
run: |
bun --version
bun add @myorg/example
3 changes: 3 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ inputs:
scope:
required: false
description: "The scope for authenticating with the package registry."
registries:
required: false
description: "An list of package registries for authenticating with the package registry."
no-cache:
required: false
type: boolean
Expand Down
Binary file modified bun.lockb
Binary file not shown.
64 changes: 32 additions & 32 deletions dist/setup/index.js

Large diffs are not rendered by default.

39 changes: 36 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"@actions/tool-cache": "^2.0.1"
},
"devDependencies": {
"@types/bun": "^1.1.13",
"@types/node": "^20.8.2",
"esbuild": "^0.19.2",
"prettier": "^2.8.4",
Expand Down
10 changes: 5 additions & 5 deletions src/action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ 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";
import { cwd } from "node:process";

export type Input = {
customUrl?: string;
Expand All @@ -23,8 +24,7 @@ export type Input = {
arch?: string;
avx2?: boolean;
profile?: boolean;
scope?: string;
registryUrl?: string;
registries?: Registry[];
noCache?: boolean;
};

Expand All @@ -44,8 +44,8 @@ export type CacheState = {
};

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

const url = getDownloadUrl(options);
const cacheEnabled = isCacheEnabled(options);
Expand Down
145 changes: 133 additions & 12 deletions src/bunfig.ts
Original file line number Diff line number Diff line change
@@ -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}`);
}
}

Expand All @@ -27,24 +38,134 @@ 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}' = { url = "${url}"${
token ? `, token = "${token}"` : ""
} }`,
};
}

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 (
line.startsWith("registry = ") ||
!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",
});
}
Loading

0 comments on commit d5ff847

Please sign in to comment.