10 Commits

Author SHA1 Message Date
Jozef Steinhübl
8f24390df0 fix: close immediately (#75)
* fix

* add test for outputs

* ci: use correct outputs from setup bun

* dist update

* feat: add timeout

* c

* increase

* [autofix.ci] apply automated fixes

* refactor: remove unnecesary loging, decrease retries

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2024-04-03 14:01:25 +02:00
Jozef Steinhübl
932c3b236c fix: retry installing three times, add windows for testing (#72)
* ci: test windows

* ci: specify shell

* ci: we don't have >1.1.0

* fix: retry installing version three times

* [autofix.ci] apply automated fixes

* build: bump version to 1.2.1

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2024-04-02 11:24:51 +02:00
Jozef Steinhübl
9e6479509b feat: support .tool-versions (#68)
* feat: support .tool-versions

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2024-04-02 10:26:15 +02:00
Jozef Steinhübl
194c60efc3 build: bump ci actions (#66)
* ci: update checkout

* ci: update checkout
2024-03-07 11:39:32 +01:00
Max Schwenk
d3603274ac Add no-cache option (#58) 2024-02-23 11:09:38 -08:00
Andy Palmer
0f37bd8169 Move cache save to runs.post and exit early (#60) 2024-02-16 14:14:07 -08:00
Filip Czaplicki
12944059f7 Fix typo in README.md (#57) 2024-02-09 18:03:04 +01:00
Ben Limmer
8642d99a51 docs: add --frozen-lockfile to README (#52)
Many folks will copy/paste the sample code from the README directly. In CI, most people will want to enforce a frozen lockfile.
2024-02-01 17:30:42 -08:00
Jacob Hummer
40646b1808 Add GitHub action to auto-update the v1 tag (#53)
Create release.yml
2024-02-01 17:29:22 -08:00
Paul Razvan Berg
94177e527c docs: add explanatory note about setup-node (#47) 2024-01-03 11:33:26 +01:00
13 changed files with 315 additions and 77 deletions

25
.github/workflows/release.yml vendored Normal file
View File

@@ -0,0 +1,25 @@
name: Release new action version
on:
release:
types: [released]
workflow_dispatch:
inputs:
TAG_NAME:
description: 'Tag name that the major tag will point to'
required: true
env:
TAG_NAME: ${{ github.event.inputs.TAG_NAME || github.event.release.tag_name }}
jobs:
update_tag:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- uses: actions/publish-action@v0.3.0
with:
source-tag: ${{ env.TAG_NAME }}

View File

@@ -16,18 +16,14 @@ jobs:
continue-on-error: true continue-on-error: true
strategy: strategy:
matrix: matrix:
include:
- os: windows-latest
bun-version: canary
os: os:
- ubuntu-latest - ubuntu-latest
- macos-latest - macos-latest
- windows-latest
bun-version: bun-version:
- latest - latest
- canary - canary
- "0.8.1" # last version before 1.0 - "1.1.0"
- "0.x"
- "1.0.0"
- "1.x" - "1.x"
- "1" - "1"
- "> 1.0.0" - "> 1.0.0"
@@ -38,13 +34,18 @@ jobs:
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Setup Bun - name: Setup Bun
uses: ./ uses: ./
id: setup_bun
with: with:
bun-version: ${{ matrix.bun-version }} bun-version: ${{ matrix.bun-version }}
- name: Run Bun - name: Run Bun
id: run_bun
run: | run: |
bun --version bun --version
setup-bun-from-package-json-version: setup-bun-from-package-json-version:
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
strategy: strategy:
@@ -52,27 +53,73 @@ jobs:
os: os:
- ubuntu-latest - ubuntu-latest
- macos-latest - macos-latest
- windows-latest
packageManager: packageManager:
- bun@1.0.0 - bun@1.1.0
- yarn@bun@1.0.0 - yarn@bun@1.1.0
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v3 uses: actions/checkout@v4
- name: Setup package.json - name: Setup package.json
shell: bash
run: | run: |
echo "$(jq '. += {"packageManager": "${{ matrix.packageManager }}"}' package.json)" > package.json echo "$(jq '. += {"packageManager": "${{ matrix.packageManager }}"}' package.json)" > package.json
- name: Setup Bun - name: Setup Bun
uses: ./ uses: ./
- name: Run Bun - name: Run Bun
id: bun id: bun
shell: bash
run: | run: |
bun --version bun --version
echo "version=$(bun --version)" >> $GITHUB_OUTPUT echo "version=$(bun --version)" >> $GITHUB_OUTPUT
- name: Check version - name: Check version
shell: bash
run: | run: |
if [[ "${{ steps.bun.outputs.version }}" == "1.0.0" ]]; then if [[ "${{ steps.bun.outputs.version }}" == "1.1.0" ]]; then
echo "Version is 1.0.0" echo "Version is 1.1.0"
else else
echo "Expected version to be 1.0.0, got ${{ steps.bun.outputs.version }}" echo "Expected version to be 1.1.0, got ${{ steps.bun.outputs.version }}"
exit 1 exit 1
fi fi
setup-bun-from-tool-versions:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os:
- ubuntu-latest
- macos-latest
- windows-latest
content:
- "bun 1.1.0"
- "bun1.1.0"
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup package.json
shell: bash
run: |
echo "bun ${{ matrix.content }}" > .tool-versions
- name: Setup Bun
uses: ./
- name: Run Bun
id: bun
shell: bash
run: |
bun --version
echo "version=$(bun --version)" >> $GITHUB_OUTPUT
- name: Check version
shell: bash
run: |
if [[ "${{ steps.bun.outputs.version }}" == "1.1.0" ]]; then
echo "Version is 1.1.0"
else
echo "Expected version to be 1.1.0, got ${{ steps.bun.outputs.version }}"
exit 1
fi

View File

@@ -25,16 +25,21 @@ If you need to authenticate with a private registry, you can set the `BUN_AUTH_T
- name: Install Dependencies - name: Install Dependencies
env: env:
BUN_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} BUN_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: bun install run: bun install --frozen-lockfile
``` ```
### Node.js not needed
In most cases, you shouldn't need to use the [setup-node](https://github.com/actions/setup-node) GitHub Action.
## Inputs ## Inputs
| Name | Description | Default | Examples | | Name | Description | Default | Examples |
| -------------- | -------------------------------------------------- | ----------- | ------------------------------- | | -------------- | -------------------------------------------------- | ----------- | ------------------------------- |
| `bun-version` | The version of Bun to download and install. | `latest` | `canary`, `1.0.0`, `1.0.x` | | `bun-version` | The version of Bun to download and install. | `latest` | `canary`, `1.0.0`, `1.0.x` |
| `registry-url` | Registry URL where some private package is stored. | `undefined` | `"https://npm.pkg.github.com/"` | | `registry-url` | Registry URL where some private package is stored. | `undefined` | `"https://npm.pkg.github.com/"` |
| `scope` | Scope for private pacakages. | `undefined` | `"@foo"`, `"@orgname"` | | `scope` | Scope for private packages. | `undefined` | `"@foo"`, `"@orgname"` |
| `no-cache` | Disable caching of the downloaded executable. | `false` | `true`, `false` |
## Outputs ## Outputs

View File

@@ -14,6 +14,11 @@ inputs:
scope: scope:
required: false required: false
description: "The scope for authenticating with the package registry." description: "The scope for authenticating with the package registry."
no-cache:
required: false
type: boolean
default: false
description: "Disable caching of bun executable."
outputs: outputs:
bun-version: bun-version:
description: The version of Bun that was installed. description: The version of Bun that was installed.
@@ -22,5 +27,7 @@ outputs:
cache-hit: cache-hit:
description: If the version of Bun was cached. description: If the version of Bun was cached.
runs: runs:
using: node20 using: "node20"
main: dist/index.js main: "dist/setup/index.js"
post: "dist/cache-save/index.js"
post-if: success()

BIN
bun.lockb

Binary file not shown.

68
dist/cache-save/index.js generated vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{ {
"name": "setup-bun", "name": "setup-bun",
"version": "1.1.1", "version": "1.2.1",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "setup-bun", "name": "setup-bun",
"version": "1.1.1", "version": "1.2.1",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@actions/cache": "^3.1.4", "@actions/cache": "^3.1.4",

View File

@@ -1,7 +1,7 @@
{ {
"private": true, "private": true,
"name": "setup-bun", "name": "setup-bun",
"version": "1.1.1", "version": "1.2.1",
"description": "Setup Bun on GitHub Actions.", "description": "Setup Bun on GitHub Actions.",
"keywords": [ "keywords": [
"bun", "bun",
@@ -18,8 +18,8 @@
"author": "xHyroM", "author": "xHyroM",
"scripts": { "scripts": {
"format": "prettier --write src *.yml *.json *.md", "format": "prettier --write src *.yml *.json *.md",
"build": "esbuild --target=node20 --outdir=dist --bundle --minify --platform=node --format=cjs src/index.ts", "build": "esbuild --target=node20 --outfile=dist/setup/index.js --bundle --minify --platform=node --format=cjs src/index.ts && esbuild --target=node20 --outfile=dist/cache-save/index.js --bundle --minify --platform=node --format=cjs src/cache-save.ts",
"start": "npm run build && node dist/index.js" "start": "npm run build && node dist/setup/index.js"
}, },
"dependencies": { "dependencies": {
"@actions/cache": "^3.1.4", "@actions/cache": "^3.1.4",

View File

@@ -8,10 +8,12 @@ import {
copyFileSync, copyFileSync,
} from "node:fs"; } from "node:fs";
import { addPath, info, warning } from "@actions/core"; import { addPath, info, warning } from "@actions/core";
import { isFeatureAvailable, restoreCache, saveCache } from "@actions/cache"; import { isFeatureAvailable, restoreCache } from "@actions/cache";
import { downloadTool, extractZip } from "@actions/tool-cache"; import { downloadTool, extractZip } from "@actions/tool-cache";
import { getExecOutput } from "@actions/exec"; import { getExecOutput } from "@actions/exec";
import { writeBunfig } from "./bunfig"; import { writeBunfig } from "./bunfig";
import { saveState } from "@actions/core";
import { retry } from "./utils";
export type Input = { export type Input = {
customUrl?: string; customUrl?: string;
@@ -22,6 +24,7 @@ export type Input = {
profile?: boolean; profile?: boolean;
scope?: string; scope?: string;
registryUrl?: string; registryUrl?: string;
noCache?: boolean;
}; };
export type Output = { export type Output = {
@@ -30,6 +33,13 @@ export type Output = {
cacheHit: boolean; cacheHit: boolean;
}; };
export type CacheState = {
cacheEnabled: boolean;
cacheHit: boolean;
bunPath: string;
url: string;
};
export default async (options: Input): Promise<Output> => { export default async (options: Input): Promise<Output> => {
const bunfigPath = join(process.cwd(), "bunfig.toml"); const bunfigPath = join(process.cwd(), "bunfig.toml");
writeBunfig(bunfigPath, options); writeBunfig(bunfigPath, options);
@@ -77,17 +87,8 @@ export default async (options: Input): Promise<Output> => {
if (!cacheHit) { if (!cacheHit) {
info(`Downloading a new version of Bun: ${url}`); info(`Downloading a new version of Bun: ${url}`);
const zipPath = await downloadTool(url); // TODO: remove this, temporary fix for https://github.com/oven-sh/setup-bun/issues/73
const extractedZipPath = await extractZip(zipPath); revision = await retry(async () => await downloadBun(url, bunPath), 3);
const extractedBunPath = await extractBun(extractedZipPath);
try {
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);
}
revision = await getRevision(bunPath);
} }
if (!revision) { if (!revision) {
@@ -96,15 +97,17 @@ export default async (options: Input): Promise<Output> => {
); );
} }
if (cacheEnabled && !cacheHit) {
try {
await saveCache([bunPath], url);
} catch (error) {
warning("Failed to save Bun to cache.");
}
}
const [version] = revision.split("+"); const [version] = revision.split("+");
const cacheState: CacheState = {
cacheEnabled,
cacheHit,
bunPath,
url,
};
saveState("cache", JSON.stringify(cacheState));
return { return {
version, version,
revision, revision,
@@ -112,8 +115,29 @@ export default async (options: Input): Promise<Output> => {
}; };
}; };
async function downloadBun(
url: string,
bunPath: string
): Promise<string | undefined> {
const zipPath = await downloadTool(url);
const extractedZipPath = await extractZip(zipPath);
const extractedBunPath = await extractBun(extractedZipPath);
try {
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);
}
return await getRevision(bunPath);
}
function isCacheEnabled(options: Input): boolean { function isCacheEnabled(options: Input): boolean {
const { customUrl, version } = options; const { customUrl, version, noCache } = options;
if (noCache) {
return false;
}
if (customUrl) { if (customUrl) {
return false; return false;
} }

15
src/cache-save.ts Normal file
View File

@@ -0,0 +1,15 @@
import { saveCache } from "@actions/cache";
import { getState, warning } from "@actions/core";
import { CacheState } from "./action";
(async () => {
const state: CacheState = JSON.parse(getState("cache"));
if (state.cacheEnabled && !state.cacheHit) {
try {
await saveCache([state.bunPath], state.url);
process.exit(0);
} catch (error) {
warning("Failed to save Bun to cache.");
}
}
})();

View File

@@ -1,7 +1,13 @@
import { tmpdir } from "node:os"; import { tmpdir } from "node:os";
import { join } from "node:path"; import { join } from "node:path";
import { existsSync, readFileSync } from "node:fs"; import { existsSync, readFileSync } from "node:fs";
import { getInput, setOutput, setFailed, warning } from "@actions/core"; import {
getInput,
setOutput,
setFailed,
warning,
getBooleanInput,
} from "@actions/core";
import runAction from "./action.js"; import runAction from "./action.js";
if (!process.env.RUNNER_TEMP) { if (!process.env.RUNNER_TEMP) {
@@ -30,17 +36,44 @@ function readVersionFromPackageJson(): string | undefined {
} }
} }
function readVersionFromToolVersions(): string | undefined {
const cwd = process.env.GITHUB_WORKSPACE;
if (!cwd) {
return;
}
const path = join(cwd, ".tool-versions");
try {
if (!existsSync(path)) {
return;
}
const match = readFileSync(path, "utf8").match(/^bun\s(?<version>.*?)$/m);
return match?.groups?.version;
} catch (error) {
const { message } = error as Error;
warning(`Failed to read .tool-versions: ${message}`);
}
}
runAction({ runAction({
version: getInput("bun-version") || readVersionFromPackageJson() || undefined, version:
getInput("bun-version") ||
readVersionFromPackageJson() ||
readVersionFromToolVersions() ||
undefined,
customUrl: getInput("bun-download-url") || undefined, customUrl: getInput("bun-download-url") || undefined,
registryUrl: getInput("registry-url") || undefined, registryUrl: getInput("registry-url") || undefined,
scope: getInput("scope") || undefined, scope: getInput("scope") || undefined,
noCache: getBooleanInput("no-cache") || false,
}) })
.then(({ version, revision, cacheHit }) => { .then(({ version, revision, cacheHit }) => {
setOutput("bun-version", version); setOutput("bun-version", version);
setOutput("bun-revision", revision); setOutput("bun-revision", revision);
setOutput("cache-hit", cacheHit); setOutput("cache-hit", cacheHit);
process.exit(0);
}) })
.catch((error) => { .catch((error) => {
setFailed(error); setFailed(error);
process.exit(1);
}); });

14
src/utils.ts Normal file
View File

@@ -0,0 +1,14 @@
export function retry<T>(
fn: () => Promise<T>,
retries: number,
timeout = 10000
): Promise<T> {
return fn().catch((err) => {
if (retries <= 0) {
throw err;
}
return new Promise((resolve) => setTimeout(resolve, timeout)).then(() =>
retry(fn, retries - 1, timeout)
);
});
}