mirror of
https://github.com/oven-sh/setup-bun.git
synced 2025-07-18 04:28:28 +02:00
feat: merge local bunfig with action scope/registry config
This commit is contained in:
parent
830e319e28
commit
8c0b797097
8 changed files with 201 additions and 14 deletions
20
.github/workflows/action.yml
vendored
20
.github/workflows/action.yml
vendored
|
@ -7,6 +7,7 @@ on:
|
|||
branches:
|
||||
- main
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
setup-bun:
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
@ -25,17 +26,21 @@ jobs:
|
|||
- id: checkout
|
||||
name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- id: setup-bun
|
||||
name: Setup Bun
|
||||
uses: ./
|
||||
with:
|
||||
bun-version: ${{ matrix.bun-version }}
|
||||
|
||||
- id: verify-bun
|
||||
name: Verify Bun
|
||||
run: |
|
||||
bun --version
|
||||
|
||||
setup-bun-from-package-json-version:
|
||||
runs-on: ${{ matrix.os }}
|
||||
needs: setup-bun
|
||||
strategy:
|
||||
matrix:
|
||||
os:
|
||||
|
@ -44,11 +49,26 @@ jobs:
|
|||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Setup package.json
|
||||
run: |
|
||||
echo "$(jq '. += {"packageManager": "bun@1.0.0"}' package.json)" > package.json
|
||||
|
||||
- name: Setup Bun
|
||||
uses: ./
|
||||
|
||||
- name: Verify Bun
|
||||
run: |
|
||||
bun --version
|
||||
|
||||
tests:
|
||||
name: Run tests
|
||||
needs: setup-bun
|
||||
runs-on: 'ubuntu-latest'
|
||||
|
||||
steps:
|
||||
- name: Setup Bun
|
||||
uses: ./
|
||||
|
||||
- name: Run tests
|
||||
run: bun test --coverage
|
||||
|
|
|
@ -5,15 +5,19 @@ Download, install, and setup [Bun](https://bun.sh) in GitHub Actions.
|
|||
## Usage
|
||||
|
||||
```yaml
|
||||
- uses: oven-sh/setup-bun@v1
|
||||
- uses: oven-sh/setup-bun@v1.1.1
|
||||
with:
|
||||
bun-version: latest
|
||||
```
|
||||
|
||||
### Setup custom registry-url and scope (for private packages)
|
||||
|
||||
For better DX and not having to expose the Github Token locally and inside repo commits, it would be wise to remove any `[install.scopes]` from a local `bunfig.toml` and move it to a global config file, that way each developer will have it's own file, it's not exposed to the repo and it also makes sure that each developer can manage the expiration date.
|
||||
|
||||
[About global config](https://bun.sh/docs/runtime/bunfig#global-vs-local)
|
||||
|
||||
```yaml
|
||||
- uses: oven-sh/setup-bun@v1
|
||||
- uses: oven-sh/setup-bun@main # Or release version greater than v1
|
||||
with:
|
||||
registry-url: "https://npm.pkg.github.com/"
|
||||
scope: "@foo-bar"
|
||||
|
|
BIN
bun.lockb
BIN
bun.lockb
Binary file not shown.
17
dist/action.js
generated
vendored
17
dist/action.js
generated
vendored
|
@ -78395,18 +78395,27 @@ function writeRegistryToConfigFile({
|
|||
scope = scope.toLocaleLowerCase();
|
||||
}
|
||||
core.info(`Setting auth in ${fileLocation}`);
|
||||
const bunRegistryString = `'${scope}' = { token = "$BUN_AUTH_TOKEN", url = "${registryUrl}" }`;
|
||||
let newContents = "";
|
||||
if ((0, import_node_fs.existsSync)(fileLocation)) {
|
||||
const curContents = (0, import_node_fs.readFileSync)(fileLocation, "utf8");
|
||||
curContents.split(import_node_os.EOL).forEach((line) => {
|
||||
if (!line.toLowerCase().startsWith(scope)) {
|
||||
const contents = curContents.split(import_node_os.EOL);
|
||||
contents.forEach((line, index, array) => {
|
||||
if (index > 0 && array[index - 1].includes("[install.scopes]")) {
|
||||
newContents += bunRegistryString + import_node_os.EOL;
|
||||
}
|
||||
if (!line.toLowerCase().includes(scope)) {
|
||||
newContents += line + import_node_os.EOL;
|
||||
}
|
||||
});
|
||||
if (!contents.includes("[install.scopes]")) {
|
||||
newContents += `[install.scopes]${import_node_os.EOL}${import_node_os.EOL}${bunRegistryString}${import_node_os.EOL}`;
|
||||
}
|
||||
newContents += import_node_os.EOL;
|
||||
}
|
||||
const bunRegistryString = `'${scope}' = { token = "$BUN_AUTH_TOKEN", url = "${registryUrl}"}`;
|
||||
newContents += `[install.scopes]${import_node_os.EOL}${import_node_os.EOL}${bunRegistryString}${import_node_os.EOL}`;
|
||||
if (!(0, import_node_fs.existsSync)(fileLocation)) {
|
||||
newContents += `[install.scopes]${import_node_os.EOL}${import_node_os.EOL}${bunRegistryString}${import_node_os.EOL}`;
|
||||
}
|
||||
(0, import_node_fs.writeFileSync)("./bunfig.toml", newContents);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"private": true,
|
||||
"name": "setup-bun",
|
||||
"version": "1.0.0",
|
||||
"version": "1.1.1",
|
||||
"description": "Setup Bun on GitHub Actions.",
|
||||
"keywords": [
|
||||
"bun",
|
||||
|
@ -31,6 +31,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.8.2",
|
||||
"bun-types": "latest",
|
||||
"esbuild": "^0.19.2",
|
||||
"prettier": "^2.8.4",
|
||||
"typescript": "^4.9.5"
|
||||
|
|
139
src/auth.spec.ts
Normal file
139
src/auth.spec.ts
Normal file
|
@ -0,0 +1,139 @@
|
|||
import { afterEach, describe, expect, it } from "bun:test";
|
||||
import { unlink } from "fs";
|
||||
import { configureAuthentication } from "./auth";
|
||||
import { EOL } from "os";
|
||||
|
||||
describe("#configureAuthentication", () => {
|
||||
const filePath = "bunfig.toml";
|
||||
|
||||
async function getFileAndContents() {
|
||||
const file = Bun.file(filePath);
|
||||
const contents = (await file.text()).split(EOL);
|
||||
|
||||
return { file, contents };
|
||||
}
|
||||
|
||||
afterEach(() => {
|
||||
unlink(filePath, () => console.log(`${filePath} was deleted`));
|
||||
});
|
||||
|
||||
describe("when no bunfig.toml file exists", () => {
|
||||
it("should create a new file with scopes content", async () => {
|
||||
configureAuthentication("https://npm.pkg.github.com", "foo-bar");
|
||||
|
||||
const { file, contents } = await getFileAndContents();
|
||||
|
||||
expect(file.exists()).resolves.toBeTrue();
|
||||
|
||||
const expectedContents = [
|
||||
"[install.scopes]",
|
||||
"",
|
||||
'\'@foo-bar\' = { token = "$BUN_AUTH_TOKEN", url = "https://npm.pkg.github.com/" }',
|
||||
"",
|
||||
];
|
||||
|
||||
contents.forEach((content, index) =>
|
||||
expect(content).toBe(expectedContents[index])
|
||||
);
|
||||
|
||||
expect(contents.length).toBe(expectedContents.length);
|
||||
});
|
||||
});
|
||||
|
||||
describe("when local bunfig.toml file exists", () => {
|
||||
it("and no [install.scopes] exists, should concatenate file correctly", async () => {
|
||||
const bunfig = `[install]${EOL}optional = true${EOL}${EOL}[install.cache]${EOL}disable = true`;
|
||||
|
||||
await Bun.write(filePath, bunfig);
|
||||
|
||||
configureAuthentication("https://npm.pkg.github.com/", "foo-bar");
|
||||
|
||||
const { file, contents } = await getFileAndContents();
|
||||
|
||||
expect(file.exists()).resolves.toBeTrue();
|
||||
|
||||
const expectedContents = [
|
||||
"[install]",
|
||||
"optional = true",
|
||||
"",
|
||||
"[install.cache]",
|
||||
"disable = true",
|
||||
"[install.scopes]",
|
||||
"",
|
||||
'\'@foo-bar\' = { token = "$BUN_AUTH_TOKEN", url = "https://npm.pkg.github.com/" }',
|
||||
"",
|
||||
"",
|
||||
];
|
||||
|
||||
contents.forEach((content, index) =>
|
||||
expect(content).toBe(expectedContents[index])
|
||||
);
|
||||
|
||||
expect(contents.length).toBe(expectedContents.length);
|
||||
});
|
||||
|
||||
it("and [install.scopes] exists and it's not the same registry, should concatenate file correctly", async () => {
|
||||
const bunfig = `[install]${EOL}optional = true${EOL}${EOL}[install.scopes]${EOL}'@bla-ble' = { token = "$BUN_AUTH_TOKEN", url = "https://npm.pkg.github.com/" }${EOL}${EOL}[install.cache]${EOL}disable = true`;
|
||||
|
||||
await Bun.write(filePath, bunfig);
|
||||
|
||||
configureAuthentication("https://npm.pkg.github.com/", "foo-bar");
|
||||
|
||||
const { file, contents } = await getFileAndContents();
|
||||
|
||||
expect(file.exists()).resolves.toBeTrue();
|
||||
|
||||
const expectedContents = [
|
||||
"[install]",
|
||||
"optional = true",
|
||||
"",
|
||||
"[install.scopes]",
|
||||
'\'@foo-bar\' = { token = "$BUN_AUTH_TOKEN", url = "https://npm.pkg.github.com/" }',
|
||||
'\'@bla-ble\' = { token = "$BUN_AUTH_TOKEN", url = "https://npm.pkg.github.com/" }',
|
||||
"",
|
||||
"[install.cache]",
|
||||
"disable = true",
|
||||
"",
|
||||
"",
|
||||
];
|
||||
|
||||
contents.forEach((content, index) =>
|
||||
expect(content).toBe(expectedContents[index])
|
||||
);
|
||||
|
||||
expect(contents.length).toBe(expectedContents.length);
|
||||
});
|
||||
|
||||
it("and [install.scopes] exists and it's the same registry, should concatenate file correctly", async () => {
|
||||
const bunfig = `[install]${EOL}optional = true${EOL}${EOL}[install.scopes]${EOL}'@foo-bar' = { token = "$BUN_AUTH_TOKEN", url = "https://npm.pkg.github.com/" }${EOL}'@bla-ble' = { token = "$BUN_AUTH_TOKEN", url = "https://npm.pkg.github.com/" }${EOL}${EOL}[install.cache]${EOL}disable = true`;
|
||||
|
||||
await Bun.write(filePath, bunfig);
|
||||
|
||||
configureAuthentication("https://npm.pkg.github.com/", "foo-bar");
|
||||
|
||||
const { file, contents } = await getFileAndContents();
|
||||
|
||||
expect(file.exists()).resolves.toBeTrue();
|
||||
|
||||
const expectedContents = [
|
||||
"[install]",
|
||||
"optional = true",
|
||||
"",
|
||||
"[install.scopes]",
|
||||
'\'@foo-bar\' = { token = "$BUN_AUTH_TOKEN", url = "https://npm.pkg.github.com/" }',
|
||||
'\'@bla-ble\' = { token = "$BUN_AUTH_TOKEN", url = "https://npm.pkg.github.com/" }',
|
||||
"",
|
||||
"[install.cache]",
|
||||
"disable = true",
|
||||
"",
|
||||
"",
|
||||
];
|
||||
|
||||
contents.forEach((content, index) =>
|
||||
expect(content).toBe(expectedContents[index])
|
||||
);
|
||||
|
||||
expect(contents.length).toBe(expectedContents.length);
|
||||
});
|
||||
});
|
||||
});
|
25
src/auth.ts
25
src/auth.ts
|
@ -34,24 +34,37 @@ function writeRegistryToConfigFile({
|
|||
|
||||
core.info(`Setting auth in ${fileLocation}`);
|
||||
|
||||
const bunRegistryString = `'${scope}' = { token = "$BUN_AUTH_TOKEN", url = "${registryUrl}" }`;
|
||||
let newContents = "";
|
||||
|
||||
if (existsSync(fileLocation)) {
|
||||
const curContents = readFileSync(fileLocation, "utf8");
|
||||
|
||||
curContents.split(EOL).forEach((line: string) => {
|
||||
// Add current contents unless they are setting the registry
|
||||
if (!line.toLowerCase().startsWith(scope)) {
|
||||
const contents = curContents.split(EOL);
|
||||
|
||||
contents.forEach((line, index, array) => {
|
||||
// If last item is [install.scopes], than it should add the action scope + registry
|
||||
if (index > 0 && array[index - 1].includes('[install.scopes]')) {
|
||||
newContents += bunRegistryString + EOL;
|
||||
}
|
||||
|
||||
// Only add the line if scope does not exists
|
||||
if (!line.toLowerCase().includes(scope)) {
|
||||
newContents += line + EOL;
|
||||
}
|
||||
});
|
||||
|
||||
// In case bunfig.toml has other properties and does not have [install.scopes]
|
||||
if (!contents.includes('[install.scopes]')) {
|
||||
newContents += `[install.scopes]${EOL}${EOL}${bunRegistryString}${EOL}`
|
||||
}
|
||||
|
||||
newContents += EOL;
|
||||
}
|
||||
|
||||
const bunRegistryString = `'${scope}' = { token = "$BUN_AUTH_TOKEN", url = "${registryUrl}"}`;
|
||||
|
||||
newContents += `[install.scopes]${EOL}${EOL}${bunRegistryString}${EOL}`;
|
||||
if (!existsSync(fileLocation)) {
|
||||
newContents += `[install.scopes]${EOL}${EOL}${bunRegistryString}${EOL}`
|
||||
}
|
||||
|
||||
writeFileSync("./bunfig.toml", newContents);
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
"module": "ES2020",
|
||||
"target": "ES2020",
|
||||
"moduleResolution": "node",
|
||||
"skipLibCheck": true
|
||||
"skipLibCheck": true,
|
||||
"types": ["bun-types"]
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue