Compare commits

..

31 commits
v1.2.1 ... main

Author SHA1 Message Date
Jozef Steinhübl
22457c87c1
docs: remove unnecessary note
Some checks failed
🧪 Test / setup-bun from (ubuntu-latest, package.json (packageManager bun@1.1.0)) (push) Successful in 57s
🧪 Test / setup-bun from (ubuntu-latest, download url) (push) Successful in 1m0s
🧪 Test / setup-bun from (ubuntu-latest, package.json (packageManager yarn@bun@1.1.0)) (push) Successful in 57s
🧪 Test / test installing deps from custom registries (ubuntu-latest) (push) Failing after 3m15s
🧪 Test / setup-bun from (macos-latest, .tool-versions (bun 1.1.0)) (push) Has been cancelled
🧪 Test / setup-bun from (windows-latest, .tool-versions (bun1.1.0)) (push) Has been cancelled
🧪 Test / setup-bun (1.1.0, macos-latest) (push) Has been cancelled
🧪 Test / setup-bun (1.1.0, windows-latest) (push) Has been cancelled
🧪 Test / setup-bun (canary, macos-latest) (push) Has been cancelled
🧪 Test / setup-bun (canary, windows-latest) (push) Has been cancelled
🧪 Test / setup-bun (latest, macos-latest) (push) Has been cancelled
🧪 Test / setup-bun (latest, windows-latest) (push) Has been cancelled
🧪 Test / setup-bun from (macos-latest, .bumrc (1.1.0)) (push) Has been cancelled
🧪 Test / setup-bun from (windows-latest, .bumrc (1.1.0)) (push) Has been cancelled
🧪 Test / setup-bun from (macos-latest, .bun-version (1.1.0)) (push) Has been cancelled
🧪 Test / setup-bun from (windows-latest, .bun-version (1.1.0)) (push) Has been cancelled
🧪 Test / setup-bun from (macos-latest, .tool-versions (bun 1.1.0)) (push) Has been cancelled
🧪 Test / setup-bun from (windows-latest, .tool-versions (bun 1.1.0)) (push) Has been cancelled
🧪 Test / setup-bun from (windows-latest, .tool-versions (bun 1.1.0)) (push) Has been cancelled
🧪 Test / setup-bun from (macos-latest, .tool-versions (bun1.1.0)) (push) Has been cancelled
🧪 Test / setup-bun from (macos-latest, foo/package.json (packageManager bun@1.1.0)) (push) Has been cancelled
🧪 Test / setup-bun from (windows-latest, foo/package.json (packageManager bun@1.1.0)) (push) Has been cancelled
🧪 Test / setup-bun from (macos-latest, package.json (engines bun@1.1.0)) (push) Has been cancelled
🧪 Test / setup-bun from (windows-latest, package.json (engines bun@1.1.0)) (push) Has been cancelled
🧪 Test / setup-bun from (macos-latest, package.json (packageManager bun@1.1.0)) (push) Has been cancelled
🧪 Test / setup-bun from (windows-latest, package.json (packageManager bun@1.1.0)) (push) Has been cancelled
🧪 Test / setup-bun from (macos-latest, package.json (packageManager yarn@bun@1.1.0)) (push) Has been cancelled
🧪 Test / setup-bun from (windows-latest, package.json (packageManager yarn@bun@1.1.0)) (push) Has been cancelled
🧪 Test / setup-bun from (macos-latest, download url) (push) Has been cancelled
🧪 Test / setup-bun from (windows-latest, download url) (push) Has been cancelled
2025-07-10 21:09:16 +02:00
autofix-ci[bot]
237a6a77d8
[autofix.ci] apply automated fixes 2025-07-10 19:07:39 +00:00
Jozef Steinhübl
53e6487b6e
ci(format): use bun 2025-07-10 21:07:00 +02:00
Jozef Steinhübl
68643ea879
ci: disable tests with version selectors (#133) 2025-07-10 21:02:01 +02:00
Jozef Steinhübl
56169ab7b0
feat: read engines from package json (#132)
* feat: read engines from package.json

closes https://github.com/oven-sh/setup-bun/issues/115

* ci: test for engines package.json

* [autofix.ci] apply automated fixes

* ci: test for engines package.json

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-07-10 20:58:50 +02:00
Jozef Steinhübl
34f777aec1
feat: support for multiple registries (#109)
Some checks failed
🧪 Test / setup-bun from (windows-latest, download url) (push) Has been cancelled
🧪 Test / setup-bun (1, macos-latest) (push) Has been cancelled
🧪 Test / setup-bun (1, windows-latest) (push) Has been cancelled
🧪 Test / setup-bun (1.1.0, macos-latest) (push) Has been cancelled
🧪 Test / setup-bun (1.1.0, windows-latest) (push) Has been cancelled
🧪 Test / setup-bun (1.x, macos-latest) (push) Has been cancelled
🧪 Test / setup-bun (1.x, windows-latest) (push) Has been cancelled
🧪 Test / setup-bun (< 2, macos-latest) (push) Has been cancelled
🧪 Test / setup-bun (< 2, windows-latest) (push) Has been cancelled
🧪 Test / setup-bun (> 1.0.0, macos-latest) (push) Has been cancelled
🧪 Test / setup-bun (> 1.0.0, windows-latest) (push) Has been cancelled
🧪 Test / setup-bun (canary, macos-latest) (push) Has been cancelled
🧪 Test / setup-bun (canary, windows-latest) (push) Has been cancelled
🧪 Test / setup-bun (latest, windows-latest) (push) Has been cancelled
🧪 Test / setup-bun from (macos-latest, .bumrc (1.1.0)) (push) Has been cancelled
🧪 Test / setup-bun from (windows-latest, .bumrc (1.1.0)) (push) Has been cancelled
🧪 Test / setup-bun from (macos-latest, .bun-version (1.1.0)) (push) Has been cancelled
🧪 Test / setup-bun from (windows-latest, .bun-version (1.1.0)) (push) Has been cancelled
🧪 Test / setup-bun from (macos-latest, .tool-versions (bun 1.1.0)) (push) Has been cancelled
🧪 Test / setup-bun from (windows-latest, .tool-versions (bun 1.1.0)) (push) Has been cancelled
🧪 Test / setup-bun from (macos-latest, .tool-versions (bun 1.1.0)) (push) Has been cancelled
🧪 Test / setup-bun from (windows-latest, .tool-versions (bun 1.1.0)) (push) Has been cancelled
🧪 Test / setup-bun from (windows-latest, .tool-versions (bun1.1.0)) (push) Has been cancelled
🧪 Test / setup-bun from (macos-latest, /foo/package.json (bun@1.1.0)) (push) Has been cancelled
🧪 Test / setup-bun from (windows-latest, /foo/package.json (bun@1.1.0)) (push) Has been cancelled
🧪 Test / setup-bun from (macos-latest, package.json (bun@1.1.0)) (push) Has been cancelled
🧪 Test / setup-bun from (windows-latest, package.json (bun@1.1.0)) (push) Has been cancelled
🧪 Test / setup-bun from (macos-latest, package.json (yarn@bun@1.1.0)) (push) Has been cancelled
🧪 Test / setup-bun from (windows-latest, package.json (yarn@bun@1.1.0)) (push) Has been cancelled
🧪 Test / setup-bun from (macos-latest, download url) (push) Has been cancelled
* feat: support for multiple registries

* [autofix.ci] apply automated fixes

* refactor: drop unnecessary check

* fix: pass empty array instead undefined

* [autofix.ci] apply automated fixes

* fix: dont add registry set line

* [autofix.ci] apply automated fixes

* feat: few more tests

* feat: add bun types

* docs: explain registries

* feat: save globally

* [autofix.ci] apply automated fixes

* ci: jsr registry test

* ci: add ,

* ci: test

* ci: test

* ci: test

* ci: test

* [autofix.ci] apply automated fixes

* feat: use @iarna/toml

* [autofix.ci] apply automated fixes

* feat: registry parsing

* [autofix.ci] apply automated fixes

* ci: verbose add

* ci: registry install check

* ci: registry install check

* ci: registry install check

* ci: verify registry usage

* docs: registries

* docs: important block

* docs: show table

* docs: show table

* ci: shell

* ci: registry test on linux

* ci: registry test on linux

* build: text lockfile

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-07-09 12:22:12 +02:00
Okinea Dev
7c641390eb
chore: add settings for vscode (#120)
Some checks failed
🧪 Test / setup-bun (1.1.0, macos-latest) (push) Has been cancelled
🧪 Test / setup-bun (1.1.0, windows-latest) (push) Has been cancelled
🧪 Test / setup-bun (1.x, macos-latest) (push) Has been cancelled
🧪 Test / setup-bun (1.x, windows-latest) (push) Has been cancelled
🧪 Test / setup-bun (< 2, macos-latest) (push) Has been cancelled
🧪 Test / setup-bun (< 2, windows-latest) (push) Has been cancelled
🧪 Test / setup-bun (> 1.0.0, macos-latest) (push) Has been cancelled
🧪 Test / setup-bun (> 1.0.0, windows-latest) (push) Has been cancelled
🧪 Test / setup-bun (canary, macos-latest) (push) Has been cancelled
🧪 Test / setup-bun (canary, windows-latest) (push) Has been cancelled
🧪 Test / setup-bun (latest, macos-latest) (push) Has been cancelled
🧪 Test / setup-bun (latest, windows-latest) (push) Has been cancelled
🧪 Test / setup-bun from (macos-latest, .bumrc (1.1.0)) (push) Has been cancelled
🧪 Test / setup-bun from (windows-latest, .bumrc (1.1.0)) (push) Has been cancelled
🧪 Test / setup-bun from (macos-latest, .bun-version (1.1.0)) (push) Has been cancelled
🧪 Test / setup-bun from (windows-latest, .bun-version (1.1.0)) (push) Has been cancelled
🧪 Test / setup-bun from (macos-latest, .tool-versions (bun 1.1.0)) (push) Has been cancelled
🧪 Test / setup-bun from (windows-latest, .tool-versions (bun 1.1.0)) (push) Has been cancelled
🧪 Test / setup-bun from (macos-latest, .tool-versions (bun 1.1.0)) (push) Has been cancelled
🧪 Test / setup-bun from (windows-latest, .tool-versions (bun 1.1.0)) (push) Has been cancelled
🧪 Test / setup-bun from (macos-latest, .tool-versions (bun1.1.0)) (push) Has been cancelled
🧪 Test / setup-bun from (windows-latest, .tool-versions (bun1.1.0)) (push) Has been cancelled
🧪 Test / setup-bun from (windows-latest, /foo/package.json (bun@1.1.0)) (push) Has been cancelled
🧪 Test / setup-bun from (macos-latest, /foo/package.json (bun@1.1.0)) (push) Has been cancelled
🧪 Test / setup-bun from (macos-latest, package.json (bun@1.1.0)) (push) Has been cancelled
🧪 Test / setup-bun from (windows-latest, package.json (bun@1.1.0)) (push) Has been cancelled
🧪 Test / setup-bun from (macos-latest, package.json (yarn@bun@1.1.0)) (push) Has been cancelled
🧪 Test / setup-bun from (windows-latest, package.json (yarn@bun@1.1.0)) (push) Has been cancelled
🧪 Test / setup-bun from (macos-latest, download url) (push) Has been cancelled
🧪 Test / setup-bun from (windows-latest, download url) (push) Has been cancelled
* chore: update Prettier settings and add settings for vscode

* rollback semi

* fix: exclude `dist` from search and lock changes to some files

* Added `search.exclude` to ignore `dist/**` during searches.
* Configured `files.readonlyInclude` to lock changes to `dist/**`, `bun.lock`, and `package-lock.json`.
2025-07-08 15:29:27 +02:00
autofix-ci[bot]
735343b667
[autofix.ci] apply automated fixes 2025-04-27 13:53:50 +00:00
Jozef Steinhübl
27ecfffdee
ci: update autofix ci 2025-04-27 15:53:25 +02:00
Afonso Jorge Ramos
fcc30ed971
fix(docs): remove wildcard in version (#124)
until https://github.com/oven-sh/setup-bun/issues/37 gets fixed
2025-04-27 15:48:05 +02:00
Jozef Steinhübl
56408e9a3f
release: v2.0.2 2025-04-27 15:47:24 +02:00
Robert Michalak
85cb7f6e7e
build: bump @actions/cache version (#128)
* bump @actions/cache version

* fix runtime error
2025-04-27 15:46:35 +02:00
Okinea Dev
54cb141c5c
ci: remove unnecessary steps & cleanup (#118)
* refactor(ci): refactor GitHub Actions for better readablility

* upd

* remove ""
2025-02-04 18:31:38 +01:00
Okinea Dev
6fb6603cc1
build: use text-based Bun lockfile (#116)
chore: 🔒 use text-based Bun lockfile

Support for the text lockfile format was introduced in version `1.1.40` (https://bun.sh/blog/bun-v1.1.40), it will soon replace the binary lockfile format `.lockb` in the upcoming version `1.2.0`

In addition, cached bun install will become 30% faster thanks to the text-based lockfile format - https://bun.sh/blog/bun-lock-text-lockfile#cached-bun-install-gets-30-faster

Read https://bun.sh/blog/bun-lock-text-lockfile
2025-01-05 12:45:22 +01:00
autofix-ci[bot]
9bdeab4320
[autofix.ci] apply automated fixes 2024-12-09 17:46:42 +00:00
Florian Barbare
f09eb1edd0
fix: make bun resolve to given file path when an absolute path is given (#114)
* Make bun resolve to single file path when an absolute path is given

* Update test not to use the workspace folder
2024-12-09 18:46:15 +01:00
Jozef Steinhübl
8f1bc2eeb3
ci: add setup bun download url (#105)
* ci: add setup bun download url

* ci: change runs-on

* ci: aarch64, not arm64
2024-10-08 15:30:45 +02:00
Jozef Steinhübl
a8913c42f4
fix: use hash instead of url for primary cache key (#102) (#103)
* fix: use hash instead of url for primary cache key (#102)

* Update cache-save.ts

* Update action.ts

* Update cache-save.ts

* build

* format

* [autofix.ci] apply automated fixes

---------

Co-authored-by: Daniil Zotov <142039751+zoto-ff@users.noreply.github.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2024-10-08 15:19:42 +02:00
マルコメ
b9d34de66d
chore(docs): missing version on examples (#96) 2024-08-06 11:21:46 +02:00
Seiya Kokushi
1e54087d4f
fix: allow more spaces for .tool-versions (#94)
* update: allow more spaces for .tool-versions

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2024-07-30 22:30:50 +02:00
Jozef Steinhübl
4bc047ad25
release: v2.0.1 (#91)
* build: bump version

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2024-07-15 21:09:36 +02:00
Araxeus
f43b443c1c
fix: bun-version-file default value (#90)
fix #89
2024-07-15 14:17:41 +02:00
autofix-ci[bot]
339e277e69
[autofix.ci] apply automated fixes 2024-06-24 13:19:56 +00:00
Jozef Steinhübl
e20a54d1da
docs: add bun-path & bun-download-url to outputs table 2024-06-24 15:19:27 +02:00
Jozef Steinhübl
3fcae870de
docs: show correct bun-version-file examples (#86)
* docs: .bun-version

* docs: correct bun-version-file examples
2024-06-24 15:15:35 +02:00
Jozef Steinhübl
123c6c4e2f
docs: use v2 version 2024-06-23 21:56:22 +02:00
Jozef Steinhübl
ef00e4ac8e
release: v2.0 🎉 (#80)
* feat: add input bun-version-file (#76)

* feat: add input for bun-version-file

* docs: update example bun version file

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>

* refactor: reduce read from file code

* [autofix.ci] apply automated fixes

* feat: read from all known files if not specified

* [autofix.ci] apply automated fixes

* fix: just continue if file doesnt exist

* [autofix.ci] apply automated fixes

* fix: return output if found version

* [autofix.ci] apply automated fixes

* fix: make whitespace in .tool-versions optional

* [autofix.ci] apply automated fixes

* log loglog

* [autofix.ci] apply automated fixes

* log log log

* [autofix.ci] apply automated fixes

* better warnings, fix ci failing

* [autofix.ci] apply automated fixes

* feat: log obtained version

* [autofix.ci] apply automated fixes

* build: bump version

* [autofix.ci] apply automated fixes

* fix: add .zip extension if it's not present

Workaround for https://github.com/actions/toolkit/issues/1179

Fixes https://github.com/oven-sh/setup-bun/issues/79

* [autofix.ci] apply automated fixes

* docs: add comment for easier understanding

* ci: more readable version

* ci: match name

* docs: add package.json and .tool-versions to bun-version-file examples

* ci: add cache test

* ci: install another pkg for cache test

* ci: install more pkgs for cache test

* ci: block all trusted deps in cache test

* ci: more deps for cache test

* ci: cache test should cache

* refactor: dont try all files if not defined

* [autofix.ci] apply automated fixes

* ci: remove cache test

* feat: support .bunrc

* [autofix.ci] apply automated fixes

* refactor: .bun-version instead .bunrc

* [autofix.ci] apply automated fixes

* feat: add bun paths and url to output

Fixes https://github.com/oven-sh/setup-bun/issues/81

* [autofix.ci] apply automated fixes

* ci: test for .bun-version

* feat: make .bun-version as default in bun-version-file

* ci: remove cache before test

* ci: remove cache before test

* ci: remove cache before test

* ci: remove cache before test

---------

Co-authored-by: Ade Hery Shopyan <51158020+adeherysh@users.noreply.github.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2024-06-21 21:11:16 +02:00
Jarred Sumner
43b2dc9ae8 Update README.md 2024-06-02 04:02:05 -07:00
Jarred Sumner
45d2c09359 Update README.md 2024-06-02 04:01:49 -07:00
Jarred Sumner
6ef34ab578 Update README.md 2024-06-02 04:00:50 -07:00
Jarred Sumner
f4d14e03ff
Add bun-download-url to actions.yml and rebuild (#83)
* Add download URL

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2024-06-02 03:52:40 -07:00
25 changed files with 1847 additions and 325 deletions

View file

@ -0,0 +1,28 @@
name: ⚖️ Compare Bun Version
description: Compare the version of Bun to a specified version
inputs:
bun-version:
description: The version of Bun to compare against
required: true
default: "1.1.0"
runs:
using: composite
steps:
- name: 🛠️ Get installed Bun version
id: bun
shell: bash
run: |
bun --version
echo "version=$(bun --version)" >> $GITHUB_OUTPUT
- name: ⚖️ Compare versions
shell: bash
run: |
if [[ "${{ steps.bun.outputs.version }}" == "${{ inputs.bun-version }}" ]]; then
echo "Version is ${{ inputs.bun-version }}"
else
echo "Expected version to be ${{ inputs.bun-version }}, got ${{ steps.bun.outputs.version }}"
exit 1
fi

View file

@ -14,17 +14,19 @@ jobs:
format:
runs-on: ubuntu-latest
steps:
- name: Checkout
- name: 📥 Checkout
uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20.x
- name: Install Dependencies
run: npm install
- name: Format
- name: 🛠️ Setup Bun
uses: ./
- name: 📦 Install Dependencies
run: bun install
- name: 🧹 Format
run: |
npm run format
npm run build
- name: Commit
uses: autofix-ci/action@d3e591514b99d0fca6779455ff8338516663f7cc
bun run format
bun run build
- name: 💾 Commit
uses: autofix-ci/action@551dded8c6cc8a1054039c8bc0b8b48c51dfc6ef

View file

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

View file

@ -1,4 +1,4 @@
name: Test
name: 🧪 Test
on:
workflow_dispatch:
@ -8,12 +8,42 @@ on:
- main
permissions:
contents: read
contents: write
jobs:
remove-cache:
runs-on: ubuntu-latest
permissions: write-all
steps:
- name: 📥 Checkout
uses: actions/checkout@v4
- name: 🗑️ Remove cache
run: gh cache delete --all || true
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, tests]
strategy:
matrix:
os:
@ -24,102 +54,169 @@ jobs:
- latest
- canary
- "1.1.0"
- "1.x"
- "1"
- "> 1.0.0"
- "< 2"
# https://github.com/oven-sh/setup-bun/issues/37
# - "1.x"
# - "1"
# - "> 1.0.0"
# - "< 2"
# Disable <sha> support for now. This is because Github Artifacts
# expire after 90 days, and we don't have another source of truth yet.
# - "822a00c4d508b54f650933a73ca5f4a3af9a7983" # 1.0.0 commit
steps:
- name: Checkout
- name: 📥 Checkout
uses: actions/checkout@v4
- name: Setup Bun
- name: 🛠️ Setup Bun
uses: ./
id: setup_bun
with:
bun-version: ${{ matrix.bun-version }}
- name: Run Bun
- name: ▶️ Run Bun
id: run_bun
run: |
bun --version
setup-bun-from-package-json-version:
setup-bun-from-file:
name: setup-bun from (${{ matrix.os }}, ${{ matrix.file.name }})
runs-on: ${{ matrix.os }}
continue-on-error: true
needs: [remove-cache, tests]
strategy:
matrix:
os:
- ubuntu-latest
- macos-latest
- windows-latest
packageManager:
- bun@1.1.0
- yarn@bun@1.1.0
file:
- name: package.json (packageManager bun@1.1.0)
file: package.json
run: |
echo "$(jq '. += {"packageManager": "bun@1.1.0"}' package.json)" > package.json
- name: foo/package.json (packageManager bun@1.1.0)
file: foo/package.json
run: |
mkdir -p foo
echo "$(jq '. += {"packageManager": "bun@1.1.0"}' package.json)" > foo/package.json
- name: package.json (packageManager yarn@bun@1.1.0)
file: package.json
run: |
echo "$(jq '. += {"packageManager": "yarn@bun@1.1.0"}' package.json)" > package.json
- name: package.json (engines bun@1.1.0)
file: package.json
run: |
echo "$(jq '.engines = {"bun": "1.1.0"}' package.json)" > package.json
- name: .tool-versions (bun 1.1.0)
file: .tool-versions
run: echo "bun 1.1.0" > .tool-versions
- name: .tool-versions (bun1.1.0)
file: .tool-versions
run: echo "bun1.1.0" > .tool-versions
- name: .tool-versions (bun 1.1.0)
file: .tool-versions
run: echo "bun 1.1.0" > .tool-versions
- name: .bumrc (1.1.0)
file: .bumrc
run: echo "1.1.0" > .bumrc
- name: .bun-version (1.1.0)
file: .bun-version
run: echo "1.1.0" > .bun-version
steps:
- name: Checkout
- name: 📥 Checkout
uses: actions/checkout@v4
- name: Setup package.json
shell: bash
run: |
echo "$(jq '. += {"packageManager": "${{ matrix.packageManager }}"}' package.json)" > package.json
- name: 📄 Setup file
run: ${{ matrix.file.run }}
- name: Setup Bun
- name: 🛠️ Setup Bun
uses: ./
with:
bun-version-file: ${{ matrix.file.file }}
- name: Run Bun
id: bun
shell: bash
run: |
bun --version
echo "version=$(bun --version)" >> $GITHUB_OUTPUT
- name: ⚖️ Compare versions
uses: ./.github/actions/compare-bun-version
with:
bun-version: "1.1.0"
- 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
setup-bun-from-tool-versions:
setup-bun-download-url:
name: setup-bun from (${{ matrix.os }}, download url)
runs-on: ${{ matrix.os }}
continue-on-error: true
needs: [remove-cache, tests]
strategy:
matrix:
os:
- ubuntu-latest
- macos-latest
- windows-latest
content:
- "bun 1.1.0"
- "bun1.1.0"
steps:
- name: Checkout
- name: 📥 Checkout
uses: actions/checkout@v4
- name: Setup package.json
shell: bash
run: |
echo "bun ${{ matrix.content }}" > .tool-versions
- name: Setup Bun
- name: 🛠️ Setup Bun
uses: ./
id: setup_bun
with:
bun-download-url: "https://github.com/oven-sh/bun/releases/latest/download/bun-${{runner.os == 'macOS' && 'darwin' || runner.os}}-${{ runner.arch == 'X64' && 'x64' || 'aarch64' }}.zip"
- name: Run Bun
id: bun
shell: bash
- name: ▶️ Run Bun
id: run_bun
run: |
bun --version
echo "version=$(bun --version)" >> $GITHUB_OUTPUT
- name: Check version
shell: bash
test-custom-registries:
name: test installing deps from custom registries (${{ matrix.os }})
runs-on: ${{ matrix.os }}
continue-on-error: true
needs: [remove-cache, tests]
strategy:
matrix:
os:
- ubuntu-latest
steps:
- name: 📥 Checkout
uses: actions/checkout@v4
- name: 🛠️ Setup Bun
uses: ./
id: setup_bun
with:
registries: |
https://registry.npmjs.org
@types:https://registry.yarnpkg.com
- name: ▶️ Install from default registry
run: |
if [[ "${{ steps.bun.outputs.version }}" == "1.1.0" ]]; then
echo "Version is 1.1.0"
output=$(bun add is-odd --verbose --force 2>&1)
if echo "$output" | grep -q "HTTP/1.1 GET https://registry.npmjs.org/is-odd"; then
echo "Successfully installed from default registry"
else
echo "Expected version to be 1.1.0, got ${{ steps.bun.outputs.version }}"
echo "Failed to install from default registry"
exit 1
fi
- name: ▶️ Install from @types registry
run: |
output=$(bun add @types/bun --verbose --force 2>&1)
if echo "$output" | grep -q "HTTP/1.1 GET https://registry.yarnpkg.com/@types%2fbun"; then
echo "Successfully installed from @types registry"
else
echo "Failed to install from @types registry"
exit 1
fi

4
.prettierrc Normal file
View file

@ -0,0 +1,4 @@
{
"semi": true,
"quoteProps": "preserve"
}

3
.vscode/extensions.json vendored Normal file
View file

@ -0,0 +1,3 @@
{
"recommendations": ["esbenp.prettier-vscode", "github.vscode-github-actions"]
}

12
.vscode/settings.json vendored Normal file
View file

@ -0,0 +1,12 @@
{
"editor.defaultFormatter": "esbenp.prettier-vscode",
"search.exclude": {
"dist/**": true
},
// Lock changes to these files
"files.readonlyInclude": {
"dist/**": true,
"bun.lock": true,
"package-lock.json": true
},
}

View file

@ -5,46 +5,81 @@ Download, install, and setup [Bun](https://bun.sh) in GitHub Actions.
## Usage
```yaml
- uses: oven-sh/setup-bun@v1
- uses: oven-sh/setup-bun@v2
with:
bun-version: latest
```
### Using a custom NPM registry
## Using version file
```yaml
- uses: oven-sh/setup-bun@v1
- uses: oven-sh/setup-bun@v2
with:
registry-url: "https://npm.pkg.github.com/"
scope: "@foo"
bun-version-file: ".bun-version"
```
If you need to authenticate with a private registry, you can set the `BUN_AUTH_TOKEN` environment variable.
## Using custom registries
You can configure multiple package registries using the `registries` input. This supports both default and scoped registries with various authentication methods.
### Registry configuration
```yaml
- name: Install Dependencies
- uses: oven-sh/setup-bun@v2
with:
registries: |
https://registry.npmjs.org/
@myorg:https://npm.pkg.github.com/|$GITHUB_TOKEN
@internal:https://username:$INTERNAL_PASSWORD@registry.internal.com/
- name: Install dependencies
env:
BUN_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: bun install --frozen-lockfile
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
INTERNAL_PASSWORD: ${{ secrets.INTERNAL_PASSWORD }}
run: bun install
```
### Node.js not needed
#### Registry format options
In most cases, you shouldn't need to use the [setup-node](https://github.com/actions/setup-node) GitHub Action.
| Type | Format |
| ------------------------------------ | --------------------------------------------------------- |
| Default registry | `https://registry.example.com/` |
| Default registry with token | `https://registry.example.com/\|$TOKEN` |
| Scoped registry | `@scope:https://registry.example.com/` |
| Scoped registry with token | `@scope:https://registry.example.com/\|$TOKEN` |
| Scoped registry with URL credentials | `@scope:https://username:$PASSWORD@registry.example.com/` |
> [!IMPORTANT]
> When using authentication, make sure to set the corresponding environment variables in your workflow steps that need access to the registries.
For more information about configuring registries in Bun, see the [official documentation](https://bun.sh/docs/install/registries).
### Override download url
If you need to override the download URL, you can use the `bun-download-url` input.
```yaml
- uses: oven-sh/setup-bun@v2
with:
bun-download-url: "https://github.com/oven-sh/bun/releases/latest/download/bun-linux-x64.zip"
```
## Inputs
| 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` |
| `bun-version-file` | The version of Bun to download and install from file. | `undefined` | `package.json`, `.bun-version`, `.tool-versions` |
| `bun-download-url` | URL to download .zip file for Bun release | | |
| `registry-url` | Registry URL where some private package is stored. | `undefined` | `"https://npm.pkg.github.com/"` |
| `scope` | Scope for private packages. | `undefined` | `"@foo"`, `"@orgname"` |
| `no-cache` | Disable caching of the downloaded executable. | `false` | `true`, `false` |
## Outputs
| Name | Description | Example |
| -------------- | ------------------------------------------ | ---------------- |
| `cache-hit` | If the Bun executable was read from cache. | `true` |
| ------------------ | ------------------------------------------ | ------------------------------------------------------------------ |
| `bun-version` | The output from `bun --version`. | `1.0.0` |
| `bun-revision` | The output from `bun --revision`. | `1.0.0+822a00c4` |
| `bun-path` | The path to the Bun executable. | `/path/to/bun` |
| `bun-download-url` | The URL from which Bun was downloaded. | `https://bun.sh/download/latest/linux/x64?avx2=true&profile=false` |
| `cache-hit` | If the Bun executable was read from cache. | `true` |

View file

@ -1,31 +1,57 @@
name: Setup Bun
description: Download, install, and setup Bun to your path.
author: robobun
branding:
icon: play-circle
color: white
inputs:
bun-version:
description: 'The version of Bun to install. (e.g. "latest", "canary", "1.0.0", "1.0.x", <sha>)'
description: The version of Bun to install. (e.g. "latest", "canary", "1.0.0", "1.0.x", <sha>)
required: false
bun-version-file:
description: The version of Bun to install from file. (e.g. "package.json", ".bun-version", ".tool-versions")
default: null
required: false
bun-download-url:
description: Override the URL to download Bun from. This skips version resolution and verifying AVX2 support.
required: false
registries:
description: |
List of package registries with authentication support. Format:
- Default registry: https://registry.npmjs.org/
- Default with token: https://registry.npmjs.org/|token
- Scoped registry: @scope:https://registry.example.com/
- Scoped with token: @scope:https://registry.example.com/|token
- Scoped with credentials: @scope:https://user:pass@registry.example.com/
required: false
registry-url:
required: false
description: "The URL of the package registry to use for installing Bun. Set the $BUN_AUTH_TOKEN environment variable to authenticate with the registry."
description: The URL of the package registry to use for installing Bun. Set the $BUN_AUTH_TOKEN environment variable to authenticate with the registry.
deprecationMessage: "Use 'registries' input instead."
scope:
required: false
description: "The scope for authenticating with the package registry."
deprecationMessage: "Use 'registries' input instead."
no-cache:
required: false
type: boolean
default: false
description: "Disable caching of bun executable."
description: Disable caching of bun executable.
outputs:
bun-version:
description: The version of Bun that was installed.
bun-revision:
description: The revision of Bun that was installed.
bun-path:
description: The path to the Bun executable.
bun-download-url:
description: The URL from which Bun was downloaded.
cache-hit:
description: If the version of Bun was cached.
runs:
using: "node20"
main: "dist/setup/index.js"

262
bun.lock Normal file
View file

@ -0,0 +1,262 @@
{
"lockfileVersion": 1,
"workspaces": {
"": {
"dependencies": {
"@actions/cache": "^4.0.0",
"@actions/core": "^1.11.0",
"@actions/exec": "^1.1.1",
"@actions/glob": "^0.4.0",
"@actions/io": "^1.1.2",
"@actions/tool-cache": "^2.0.1",
"@iarna/toml": "^2.2.5",
},
"devDependencies": {
"@types/bun": "^1.1.13",
"@types/node": "^20.8.2",
"esbuild": "^0.19.2",
"prettier": "^3.4.2",
"typescript": "^4.9.5",
},
},
},
"packages": {
"@actions/cache": ["@actions/cache@4.0.3", "", { "dependencies": { "@actions/core": "^1.11.1", "@actions/exec": "^1.0.1", "@actions/glob": "^0.1.0", "@actions/http-client": "^2.1.1", "@actions/io": "^1.0.1", "@azure/abort-controller": "^1.1.0", "@azure/ms-rest-js": "^2.6.0", "@azure/storage-blob": "^12.13.0", "@protobuf-ts/plugin": "^2.9.4", "semver": "^6.3.1" } }, "sha512-SvrqFtYJ7I48A/uXNkoJrnukx5weQv1fGquhs3+4nkByZThBH109KTIqj5x/cGV7JGNvb8dLPVywUOqX1fjiXg=="],
"@actions/core": ["@actions/core@1.11.1", "", { "dependencies": { "@actions/exec": "^1.1.1", "@actions/http-client": "^2.0.1" } }, "sha512-hXJCSrkwfA46Vd9Z3q4cpEpHB1rL5NG04+/rbqW9d3+CSvtB1tYe8UTpAlixa1vj0m/ULglfEK2UKxMGxCxv5A=="],
"@actions/exec": ["@actions/exec@1.1.1", "", { "dependencies": { "@actions/io": "^1.0.1" } }, "sha512-+sCcHHbVdk93a0XT19ECtO/gIXoxvdsgQLzb2fE2/5sIZmWQuluYyjPQtrtTHdU1YzTZ7bAPN4sITq2xi1679w=="],
"@actions/glob": ["@actions/glob@0.4.0", "", { "dependencies": { "@actions/core": "^1.9.1", "minimatch": "^3.0.4" } }, "sha512-+eKIGFhsFa4EBwaf/GMyzCdWrXWymGXfFmZU3FHQvYS8mPcHtTtZONbkcqqUMzw9mJ/pImEBFET1JNifhqGsAQ=="],
"@actions/http-client": ["@actions/http-client@2.2.1", "", { "dependencies": { "tunnel": "^0.0.6", "undici": "^5.25.4" } }, "sha512-KhC/cZsq7f8I4LfZSJKgCvEwfkE8o1538VoBeoGzokVLLnbFDEAdFD3UhoMklxo2un9NJVBdANOresx7vTHlHw=="],
"@actions/io": ["@actions/io@1.1.3", "", {}, "sha512-wi9JjgKLYS7U/z8PPbco+PvTb/nRWjeoFlJ1Qer83k/3C5PHQi28hiVdeE2kHXmIL99mQFawx8qt/JPjZilJ8Q=="],
"@actions/tool-cache": ["@actions/tool-cache@2.0.1", "", { "dependencies": { "@actions/core": "^1.2.6", "@actions/exec": "^1.0.0", "@actions/http-client": "^2.0.1", "@actions/io": "^1.1.1", "semver": "^6.1.0", "uuid": "^3.3.2" } }, "sha512-iPU+mNwrbA8jodY8eyo/0S/QqCKDajiR8OxWTnSk/SnYg0sj8Hp4QcUEVC1YFpHWXtrfbQrE13Jz4k4HXJQKcA=="],
"@azure/abort-controller": ["@azure/abort-controller@1.1.0", "", { "dependencies": { "tslib": "^2.2.0" } }, "sha512-TrRLIoSQVzfAJX9H1JeFjzAoDGcoK1IYX1UImfceTZpsyYfWr09Ss1aHW1y5TrrR3iq6RZLBwJ3E24uwPhwahw=="],
"@azure/core-auth": ["@azure/core-auth@1.5.0", "", { "dependencies": { "@azure/abort-controller": "^1.0.0", "@azure/core-util": "^1.1.0", "tslib": "^2.2.0" } }, "sha512-udzoBuYG1VBoHVohDTrvKjyzel34zt77Bhp7dQntVGGD0ehVq48owENbBG8fIgkHRNUBQH5k1r0hpoMu5L8+kw=="],
"@azure/core-http": ["@azure/core-http@3.0.4", "", { "dependencies": { "@azure/abort-controller": "^1.0.0", "@azure/core-auth": "^1.3.0", "@azure/core-tracing": "1.0.0-preview.13", "@azure/core-util": "^1.1.1", "@azure/logger": "^1.0.0", "@types/node-fetch": "^2.5.0", "@types/tunnel": "^0.0.3", "form-data": "^4.0.0", "node-fetch": "^2.6.7", "process": "^0.11.10", "tslib": "^2.2.0", "tunnel": "^0.0.6", "uuid": "^8.3.0", "xml2js": "^0.5.0" } }, "sha512-Fok9VVhMdxAFOtqiiAtg74fL0UJkt0z3D+ouUUxcRLzZNBioPRAMJFVxiWoJljYpXsRi4GDQHzQHDc9AiYaIUQ=="],
"@azure/core-lro": ["@azure/core-lro@2.7.1", "", { "dependencies": { "@azure/abort-controller": "^2.0.0", "@azure/core-util": "^1.2.0", "@azure/logger": "^1.0.0", "tslib": "^2.6.2" } }, "sha512-kXSlrNHOCTVZMxpXNRqzgh9/j4cnNXU5Hf2YjMyjddRhCXFiFRzmNaqwN+XO9rGTsCOIaaG7M67zZdyliXZG9g=="],
"@azure/core-paging": ["@azure/core-paging@1.6.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-3tKIQXSU3mlN+ITz0m2pXLnKK3oQ6/EVcW8ud011Iq+M0rx6Wnm7NUEpoMeOAEedeKlPtemrQzO6YWoDR71O5w=="],
"@azure/core-tracing": ["@azure/core-tracing@1.0.0-preview.13", "", { "dependencies": { "@opentelemetry/api": "^1.0.1", "tslib": "^2.2.0" } }, "sha512-KxDlhXyMlh2Jhj2ykX6vNEU0Vou4nHr025KoSEiz7cS3BNiHNaZcdECk/DmLkEB0as5T7b/TpRcehJ5yV6NeXQ=="],
"@azure/core-util": ["@azure/core-util@1.6.1", "", { "dependencies": { "@azure/abort-controller": "^1.0.0", "tslib": "^2.2.0" } }, "sha512-h5taHeySlsV9qxuK64KZxy4iln1BtMYlNt5jbuEFN3UFSAd1EwKg/Gjl5a6tZ/W8t6li3xPnutOx7zbDyXnPmQ=="],
"@azure/logger": ["@azure/logger@1.1.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-/+4TtokaGgC+MnThdf6HyIH9Wrjp+CnCn3Nx3ggevN7FFjjNyjqg0yLlc2i9S+Z2uAzI8GYOo35Nzb1MhQ89MA=="],
"@azure/ms-rest-js": ["@azure/ms-rest-js@2.7.0", "", { "dependencies": { "@azure/core-auth": "^1.1.4", "abort-controller": "^3.0.0", "form-data": "^2.5.0", "node-fetch": "^2.6.7", "tslib": "^1.10.0", "tunnel": "0.0.6", "uuid": "^8.3.2", "xml2js": "^0.5.0" } }, "sha512-ngbzWbqF+NmztDOpLBVDxYM+XLcUj7nKhxGbSU9WtIsXfRB//cf2ZbAG5HkOrhU9/wd/ORRB6lM/d69RKVjiyA=="],
"@azure/storage-blob": ["@azure/storage-blob@12.17.0", "", { "dependencies": { "@azure/abort-controller": "^1.0.0", "@azure/core-http": "^3.0.0", "@azure/core-lro": "^2.2.0", "@azure/core-paging": "^1.1.1", "@azure/core-tracing": "1.0.0-preview.13", "@azure/logger": "^1.0.0", "events": "^3.0.0", "tslib": "^2.2.0" } }, "sha512-sM4vpsCpcCApagRW5UIjQNlNylo02my2opgp0Emi8x888hZUvJ3dN69Oq20cEGXkMUWnoCrBaB0zyS3yeB87sQ=="],
"@bufbuild/protobuf": ["@bufbuild/protobuf@2.6.0", "", {}, "sha512-6cuonJVNOIL7lTj5zgo/Rc2bKAo4/GvN+rKCrUj7GdEHRzCk8zKOfFwUsL9nAVk5rSIsRmlgcpLzTRysopEeeg=="],
"@bufbuild/protoplugin": ["@bufbuild/protoplugin@2.6.0", "", { "dependencies": { "@bufbuild/protobuf": "2.6.0", "@typescript/vfs": "^1.5.2", "typescript": "5.4.5" } }, "sha512-mfAwI+4GqUtbw/ddfyolEHaAL86ozRIVlOg2A+SVRbjx1CjsMc1YJO+hBSkt/pqfpR+PmWBbZLstHbXP8KGtMQ=="],
"@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.19.12", "", { "os": "aix", "cpu": "ppc64" }, "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA=="],
"@esbuild/android-arm": ["@esbuild/android-arm@0.19.12", "", { "os": "android", "cpu": "arm" }, "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w=="],
"@esbuild/android-arm64": ["@esbuild/android-arm64@0.19.12", "", { "os": "android", "cpu": "arm64" }, "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA=="],
"@esbuild/android-x64": ["@esbuild/android-x64@0.19.12", "", { "os": "android", "cpu": "x64" }, "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew=="],
"@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.19.12", "", { "os": "darwin", "cpu": "arm64" }, "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g=="],
"@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.19.12", "", { "os": "darwin", "cpu": "x64" }, "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A=="],
"@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.19.12", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA=="],
"@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.19.12", "", { "os": "freebsd", "cpu": "x64" }, "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg=="],
"@esbuild/linux-arm": ["@esbuild/linux-arm@0.19.12", "", { "os": "linux", "cpu": "arm" }, "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w=="],
"@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.19.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA=="],
"@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.19.12", "", { "os": "linux", "cpu": "ia32" }, "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA=="],
"@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.19.12", "", { "os": "linux", "cpu": "none" }, "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA=="],
"@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.19.12", "", { "os": "linux", "cpu": "none" }, "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w=="],
"@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.19.12", "", { "os": "linux", "cpu": "ppc64" }, "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg=="],
"@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.19.12", "", { "os": "linux", "cpu": "none" }, "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg=="],
"@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.19.12", "", { "os": "linux", "cpu": "s390x" }, "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg=="],
"@esbuild/linux-x64": ["@esbuild/linux-x64@0.19.12", "", { "os": "linux", "cpu": "x64" }, "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg=="],
"@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.19.12", "", { "os": "none", "cpu": "x64" }, "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA=="],
"@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.19.12", "", { "os": "openbsd", "cpu": "x64" }, "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw=="],
"@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.19.12", "", { "os": "sunos", "cpu": "x64" }, "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA=="],
"@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.19.12", "", { "os": "win32", "cpu": "arm64" }, "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A=="],
"@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.19.12", "", { "os": "win32", "cpu": "ia32" }, "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ=="],
"@esbuild/win32-x64": ["@esbuild/win32-x64@0.19.12", "", { "os": "win32", "cpu": "x64" }, "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA=="],
"@fastify/busboy": ["@fastify/busboy@2.1.1", "", {}, "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA=="],
"@iarna/toml": ["@iarna/toml@2.2.5", "", {}, "sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg=="],
"@opentelemetry/api": ["@opentelemetry/api@1.6.0", "", {}, "sha512-OWlrQAnWn9577PhVgqjUvMr1pg57Bc4jv0iL4w0PRuOSRvq67rvHW9Ie/dZVMvCzhSCB+UxhcY/PmCmFj33Q+g=="],
"@protobuf-ts/plugin": ["@protobuf-ts/plugin@2.11.1", "", { "dependencies": { "@bufbuild/protobuf": "^2.4.0", "@bufbuild/protoplugin": "^2.4.0", "@protobuf-ts/protoc": "^2.11.1", "@protobuf-ts/runtime": "^2.11.1", "@protobuf-ts/runtime-rpc": "^2.11.1", "typescript": "^3.9" }, "bin": { "protoc-gen-ts": "bin/protoc-gen-ts", "protoc-gen-dump": "bin/protoc-gen-dump" } }, "sha512-HyuprDcw0bEEJqkOWe1rnXUP0gwYLij8YhPuZyZk6cJbIgc/Q0IFgoHQxOXNIXAcXM4Sbehh6kjVnCzasElw1A=="],
"@protobuf-ts/protoc": ["@protobuf-ts/protoc@2.11.1", "", { "bin": { "protoc": "protoc.js" } }, "sha512-mUZJaV0daGO6HUX90o/atzQ6A7bbN2RSuHtdwo8SSF2Qoe3zHwa4IHyCN1evftTeHfLmdz+45qo47sL+5P8nyg=="],
"@protobuf-ts/runtime": ["@protobuf-ts/runtime@2.11.1", "", {}, "sha512-KuDaT1IfHkugM2pyz+FwiY80ejWrkH1pAtOBOZFuR6SXEFTsnb/jiQWQ1rCIrcKx2BtyxnxW6BWwsVSA/Ie+WQ=="],
"@protobuf-ts/runtime-rpc": ["@protobuf-ts/runtime-rpc@2.11.1", "", { "dependencies": { "@protobuf-ts/runtime": "^2.11.1" } }, "sha512-4CqqUmNA+/uMz00+d3CYKgElXO9VrEbucjnBFEjqI4GuDrEQ32MaI3q+9qPBvIGOlL4PmHXrzM32vBPWRhQKWQ=="],
"@types/bun": ["@types/bun@1.2.18", "", { "dependencies": { "bun-types": "1.2.18" } }, "sha512-Xf6RaWVheyemaThV0kUfaAUvCNokFr+bH8Jxp+tTZfx7dAPA8z9ePnP9S9+Vspzuxxx9JRAXhnyccRj3GyCMdQ=="],
"@types/node": ["@types/node@20.12.2", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-zQ0NYO87hyN6Xrclcqp7f8ZbXNbRfoGWNcMvHTPQp9UUrwI0mI7XBz+cu7/W6/VClYo2g63B0cjull/srU7LgQ=="],
"@types/node-fetch": ["@types/node-fetch@2.6.11", "", { "dependencies": { "@types/node": "*", "form-data": "^4.0.0" } }, "sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g=="],
"@types/react": ["@types/react@19.1.8", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g=="],
"@types/tunnel": ["@types/tunnel@0.0.3", "", { "dependencies": { "@types/node": "*" } }, "sha512-sOUTGn6h1SfQ+gbgqC364jLFBw2lnFqkgF3q0WovEHRLMrVD1sd5aufqi/aJObLekJO+Aq5z646U4Oxy6shXMA=="],
"@typescript/vfs": ["@typescript/vfs@1.6.1", "", { "dependencies": { "debug": "^4.1.1" }, "peerDependencies": { "typescript": "*" } }, "sha512-JwoxboBh7Oz1v38tPbkrZ62ZXNHAk9bJ7c9x0eI5zBfBnBYGhURdbnh7Z4smN/MV48Y5OCcZb58n972UtbazsA=="],
"abort-controller": ["abort-controller@3.0.0", "", { "dependencies": { "event-target-shim": "^5.0.0" } }, "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg=="],
"asynckit": ["asynckit@0.4.0", "", {}, "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="],
"balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
"brace-expansion": ["brace-expansion@1.1.11", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA=="],
"bun-types": ["bun-types@1.2.18", "", { "dependencies": { "@types/node": "*" }, "peerDependencies": { "@types/react": "^19" } }, "sha512-04+Eha5NP7Z0A9YgDAzMk5PHR16ZuLVa83b26kH5+cp1qZW4F6FmAURngE7INf4tKOvCE69vYvDEwoNl1tGiWw=="],
"combined-stream": ["combined-stream@1.0.8", "", { "dependencies": { "delayed-stream": "~1.0.0" } }, "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg=="],
"concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="],
"csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="],
"debug": ["debug@4.4.1", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ=="],
"delayed-stream": ["delayed-stream@1.0.0", "", {}, "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="],
"esbuild": ["esbuild@0.19.12", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.19.12", "@esbuild/android-arm": "0.19.12", "@esbuild/android-arm64": "0.19.12", "@esbuild/android-x64": "0.19.12", "@esbuild/darwin-arm64": "0.19.12", "@esbuild/darwin-x64": "0.19.12", "@esbuild/freebsd-arm64": "0.19.12", "@esbuild/freebsd-x64": "0.19.12", "@esbuild/linux-arm": "0.19.12", "@esbuild/linux-arm64": "0.19.12", "@esbuild/linux-ia32": "0.19.12", "@esbuild/linux-loong64": "0.19.12", "@esbuild/linux-mips64el": "0.19.12", "@esbuild/linux-ppc64": "0.19.12", "@esbuild/linux-riscv64": "0.19.12", "@esbuild/linux-s390x": "0.19.12", "@esbuild/linux-x64": "0.19.12", "@esbuild/netbsd-x64": "0.19.12", "@esbuild/openbsd-x64": "0.19.12", "@esbuild/sunos-x64": "0.19.12", "@esbuild/win32-arm64": "0.19.12", "@esbuild/win32-ia32": "0.19.12", "@esbuild/win32-x64": "0.19.12" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg=="],
"event-target-shim": ["event-target-shim@5.0.1", "", {}, "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ=="],
"events": ["events@3.3.0", "", {}, "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q=="],
"form-data": ["form-data@2.5.1", "", { "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.6", "mime-types": "^2.1.12" } }, "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA=="],
"mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="],
"mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="],
"minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
"node-fetch": ["node-fetch@2.7.0", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="],
"prettier": ["prettier@3.4.2", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ=="],
"process": ["process@0.11.10", "", {}, "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A=="],
"sax": ["sax@1.3.0", "", {}, "sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA=="],
"semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
"tr46": ["tr46@0.0.3", "", {}, "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="],
"tslib": ["tslib@2.6.2", "", {}, "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="],
"tunnel": ["tunnel@0.0.6", "", {}, "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg=="],
"typescript": ["typescript@4.9.5", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g=="],
"undici": ["undici@5.28.3", "", { "dependencies": { "@fastify/busboy": "^2.0.0" } }, "sha512-3ItfzbrhDlINjaP0duwnNsKpDQk3acHI3gVJ1z4fmwMK31k5G9OVIAMLSIaP6w4FaGkaAkN6zaQO9LUvZ1t7VA=="],
"undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
"uuid": ["uuid@3.4.0", "", { "bin": { "uuid": "./bin/uuid" } }, "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="],
"webidl-conversions": ["webidl-conversions@3.0.1", "", {}, "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="],
"whatwg-url": ["whatwg-url@5.0.0", "", { "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" } }, "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw=="],
"xml2js": ["xml2js@0.5.0", "", { "dependencies": { "sax": ">=0.6.0", "xmlbuilder": "~11.0.0" } }, "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA=="],
"xmlbuilder": ["xmlbuilder@11.0.1", "", {}, "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA=="],
"@actions/cache/@actions/glob": ["@actions/glob@0.1.2", "", { "dependencies": { "@actions/core": "^1.2.6", "minimatch": "^3.0.4" } }, "sha512-SclLR7Ia5sEqjkJTPs7Sd86maMDw43p769YxBOxvPvEWuPEhpAnBsQfENOpXjFYMmhCqd127bmf+YdvJqVqR4A=="],
"@actions/glob/@actions/core": ["@actions/core@1.10.1", "", { "dependencies": { "@actions/http-client": "^2.0.1", "uuid": "^8.3.2" } }, "sha512-3lBR9EDAY+iYIpTnTIXmWcNbX3T2kCkAEQGIQx4NVQ0575nk2k3GRZDTPQG+vVtS2izSLmINlxXf0uLtnrTP+g=="],
"@actions/tool-cache/@actions/core": ["@actions/core@1.10.1", "", { "dependencies": { "@actions/http-client": "^2.0.1", "uuid": "^8.3.2" } }, "sha512-3lBR9EDAY+iYIpTnTIXmWcNbX3T2kCkAEQGIQx4NVQ0575nk2k3GRZDTPQG+vVtS2izSLmINlxXf0uLtnrTP+g=="],
"@actions/tool-cache/@actions/http-client": ["@actions/http-client@2.2.0", "", { "dependencies": { "tunnel": "^0.0.6", "undici": "^5.25.4" } }, "sha512-q+epW0trjVUUHboliPb4UF9g2msf+w61b32tAkFEwL/IwP0DQWgbCMM0Hbe3e3WXSKz5VcUXbzJQgy8Hkra/Lg=="],
"@azure/core-http/@azure/core-auth": ["@azure/core-auth@1.7.1", "", { "dependencies": { "@azure/abort-controller": "^2.0.0", "@azure/core-util": "^1.1.0", "tslib": "^2.6.2" } }, "sha512-dyeQwvgthqs/SlPVQbZQetpslXceHd4i5a7M/7z/lGEAVwnSluabnQOjF2/dk/hhWgMISusv1Ytp4mQ8JNy62A=="],
"@azure/core-http/@azure/core-util": ["@azure/core-util@1.8.1", "", { "dependencies": { "@azure/abort-controller": "^2.0.0", "tslib": "^2.6.2" } }, "sha512-L3voj0StUdJ+YKomvwnTv7gHzguJO+a6h30pmmZdRprJCM+RJlGMPxzuh4R7lhQu1jNmEtaHX5wvTgWLDAmbGQ=="],
"@azure/core-http/form-data": ["form-data@4.0.0", "", { "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "mime-types": "^2.1.12" } }, "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww=="],
"@azure/core-http/uuid": ["uuid@8.3.2", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="],
"@azure/core-lro/@azure/abort-controller": ["@azure/abort-controller@2.1.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-NhzeNm5zu2fPlwGXPUjzsRCRuPx5demaZyNcyNYJDqpa/Sbxzvo/RYt9IwUaAOnDW5+r7J9UOE6f22TQnb9nhQ=="],
"@azure/core-lro/@azure/core-util": ["@azure/core-util@1.8.1", "", { "dependencies": { "@azure/abort-controller": "^2.0.0", "tslib": "^2.6.2" } }, "sha512-L3voj0StUdJ+YKomvwnTv7gHzguJO+a6h30pmmZdRprJCM+RJlGMPxzuh4R7lhQu1jNmEtaHX5wvTgWLDAmbGQ=="],
"@azure/ms-rest-js/tslib": ["tslib@1.14.1", "", {}, "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="],
"@azure/ms-rest-js/uuid": ["uuid@8.3.2", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="],
"@bufbuild/protoplugin/typescript": ["typescript@5.4.5", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ=="],
"@protobuf-ts/plugin/typescript": ["typescript@3.9.10", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q=="],
"@types/node-fetch/form-data": ["form-data@4.0.0", "", { "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "mime-types": "^2.1.12" } }, "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww=="],
"@types/tunnel/@types/node": ["@types/node@20.8.9", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-UzykFsT3FhHb1h7yD4CA4YhBHq545JC0YnEz41xkipN88eKQtL6rSgocL5tbAP6Ola9Izm/Aw4Ora8He4x0BHg=="],
"@actions/cache/@actions/glob/@actions/core": ["@actions/core@1.10.1", "", { "dependencies": { "@actions/http-client": "^2.0.1", "uuid": "^8.3.2" } }, "sha512-3lBR9EDAY+iYIpTnTIXmWcNbX3T2kCkAEQGIQx4NVQ0575nk2k3GRZDTPQG+vVtS2izSLmINlxXf0uLtnrTP+g=="],
"@actions/glob/@actions/core/@actions/http-client": ["@actions/http-client@2.2.0", "", { "dependencies": { "tunnel": "^0.0.6", "undici": "^5.25.4" } }, "sha512-q+epW0trjVUUHboliPb4UF9g2msf+w61b32tAkFEwL/IwP0DQWgbCMM0Hbe3e3WXSKz5VcUXbzJQgy8Hkra/Lg=="],
"@actions/glob/@actions/core/uuid": ["uuid@8.3.2", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="],
"@actions/tool-cache/@actions/core/uuid": ["uuid@8.3.2", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="],
"@actions/tool-cache/@actions/http-client/undici": ["undici@5.26.5", "", { "dependencies": { "@fastify/busboy": "^2.0.0" } }, "sha512-cSb4bPFd5qgR7qr2jYAi0hlX9n5YKK2ONKkLFkxl+v/9BvC0sOpZjBHDBSXc5lWAf5ty9oZdRXytBIHzgUcerw=="],
"@azure/core-http/@azure/core-auth/@azure/abort-controller": ["@azure/abort-controller@2.1.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-NhzeNm5zu2fPlwGXPUjzsRCRuPx5demaZyNcyNYJDqpa/Sbxzvo/RYt9IwUaAOnDW5+r7J9UOE6f22TQnb9nhQ=="],
"@azure/core-http/@azure/core-util/@azure/abort-controller": ["@azure/abort-controller@2.1.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-NhzeNm5zu2fPlwGXPUjzsRCRuPx5demaZyNcyNYJDqpa/Sbxzvo/RYt9IwUaAOnDW5+r7J9UOE6f22TQnb9nhQ=="],
"@actions/cache/@actions/glob/@actions/core/@actions/http-client": ["@actions/http-client@2.2.0", "", { "dependencies": { "tunnel": "^0.0.6", "undici": "^5.25.4" } }, "sha512-q+epW0trjVUUHboliPb4UF9g2msf+w61b32tAkFEwL/IwP0DQWgbCMM0Hbe3e3WXSKz5VcUXbzJQgy8Hkra/Lg=="],
"@actions/cache/@actions/glob/@actions/core/uuid": ["uuid@8.3.2", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="],
"@actions/glob/@actions/core/@actions/http-client/undici": ["undici@5.26.5", "", { "dependencies": { "@fastify/busboy": "^2.0.0" } }, "sha512-cSb4bPFd5qgR7qr2jYAi0hlX9n5YKK2ONKkLFkxl+v/9BvC0sOpZjBHDBSXc5lWAf5ty9oZdRXytBIHzgUcerw=="],
"@actions/tool-cache/@actions/http-client/undici/@fastify/busboy": ["@fastify/busboy@2.0.0", "", {}, "sha512-JUFJad5lv7jxj926GPgymrWQxxjPYuJNiNjNMzqT+HiuP6Vl3dk5xzG+8sTX96np0ZAluvaMzPsjhHZ5rNuNQQ=="],
"@actions/cache/@actions/glob/@actions/core/@actions/http-client/undici": ["undici@5.26.5", "", { "dependencies": { "@fastify/busboy": "^2.0.0" } }, "sha512-cSb4bPFd5qgR7qr2jYAi0hlX9n5YKK2ONKkLFkxl+v/9BvC0sOpZjBHDBSXc5lWAf5ty9oZdRXytBIHzgUcerw=="],
"@actions/glob/@actions/core/@actions/http-client/undici/@fastify/busboy": ["@fastify/busboy@2.0.0", "", {}, "sha512-JUFJad5lv7jxj926GPgymrWQxxjPYuJNiNjNMzqT+HiuP6Vl3dk5xzG+8sTX96np0ZAluvaMzPsjhHZ5rNuNQQ=="],
"@actions/cache/@actions/glob/@actions/core/@actions/http-client/undici/@fastify/busboy": ["@fastify/busboy@2.0.0", "", {}, "sha512-JUFJad5lv7jxj926GPgymrWQxxjPYuJNiNjNMzqT+HiuP6Vl3dk5xzG+8sTX96np0ZAluvaMzPsjhHZ5rNuNQQ=="],
}
}

BIN
bun.lockb

Binary file not shown.

2
bunfig.toml Normal file
View file

@ -0,0 +1,2 @@
[install]
saveTextLockfile = true

211
dist/cache-save/index.js generated vendored

File diff suppressed because one or more lines are too long

290
dist/setup/index.js generated vendored

File diff suppressed because one or more lines are too long

167
package-lock.json generated
View file

@ -1,33 +1,36 @@
{
"name": "setup-bun",
"version": "1.2.1",
"version": "2.0.2",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "setup-bun",
"version": "1.2.1",
"version": "2.0.2",
"license": "MIT",
"dependencies": {
"@actions/cache": "^3.1.4",
"@actions/core": "^1.10.0",
"@actions/cache": "^4.0.0",
"@actions/core": "^1.11.0",
"@actions/exec": "^1.1.1",
"@actions/glob": "^0.4.0",
"@actions/io": "^1.1.2",
"@actions/tool-cache": "^2.0.1"
"@actions/tool-cache": "^2.0.1",
"@iarna/toml": "^2.2.5"
},
"devDependencies": {
"@types/bun": "^1.1.13",
"@types/node": "^20.8.2",
"esbuild": "^0.19.2",
"prettier": "^2.8.4",
"prettier": "^3.4.2",
"typescript": "^4.9.5"
}
},
"node_modules/@actions/cache": {
"version": "3.2.2",
"license": "MIT",
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/@actions/cache/-/cache-4.0.3.tgz",
"integrity": "sha512-SvrqFtYJ7I48A/uXNkoJrnukx5weQv1fGquhs3+4nkByZThBH109KTIqj5x/cGV7JGNvb8dLPVywUOqX1fjiXg==",
"dependencies": {
"@actions/core": "^1.10.0",
"@actions/core": "^1.11.1",
"@actions/exec": "^1.0.1",
"@actions/glob": "^0.1.0",
"@actions/http-client": "^2.1.1",
@ -35,8 +38,8 @@
"@azure/abort-controller": "^1.1.0",
"@azure/ms-rest-js": "^2.6.0",
"@azure/storage-blob": "^12.13.0",
"semver": "^6.1.0",
"uuid": "^3.3.3"
"@protobuf-ts/plugin": "^2.9.4",
"semver": "^6.3.1"
}
},
"node_modules/@actions/cache/node_modules/@actions/glob": {
@ -48,18 +51,12 @@
}
},
"node_modules/@actions/core": {
"version": "1.10.1",
"license": "MIT",
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.11.1.tgz",
"integrity": "sha512-hXJCSrkwfA46Vd9Z3q4cpEpHB1rL5NG04+/rbqW9d3+CSvtB1tYe8UTpAlixa1vj0m/ULglfEK2UKxMGxCxv5A==",
"dependencies": {
"@actions/http-client": "^2.0.1",
"uuid": "^8.3.2"
}
},
"node_modules/@actions/core/node_modules/uuid": {
"version": "8.3.2",
"license": "MIT",
"bin": {
"uuid": "dist/bin/uuid"
"@actions/exec": "^1.1.1",
"@actions/http-client": "^2.0.1"
}
},
"node_modules/@actions/exec": {
@ -276,6 +273,12 @@
"node": ">=12"
}
},
"node_modules/@iarna/toml": {
"version": "2.2.5",
"resolved": "https://registry.npmjs.org/@iarna/toml/-/toml-2.2.5.tgz",
"integrity": "sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==",
"license": "ISC"
},
"node_modules/@opentelemetry/api": {
"version": "1.5.0",
"license": "Apache-2.0",
@ -283,6 +286,86 @@
"node": ">=8.0.0"
}
},
"node_modules/@protobuf-ts/plugin": {
"version": "2.9.6",
"resolved": "https://registry.npmjs.org/@protobuf-ts/plugin/-/plugin-2.9.6.tgz",
"integrity": "sha512-Wpv5rkXeu6E5Y4r0TjWE0bzRGddiTYl/RM+tLgVlS0r8CqOBqNAmlWv+s8ltf/F75rVrahUal0cpyhFwha9GRA==",
"dependencies": {
"@protobuf-ts/plugin-framework": "^2.9.6",
"@protobuf-ts/protoc": "^2.9.6",
"@protobuf-ts/runtime": "^2.9.6",
"@protobuf-ts/runtime-rpc": "^2.9.6",
"typescript": "^3.9"
},
"bin": {
"protoc-gen-dump": "bin/protoc-gen-dump",
"protoc-gen-ts": "bin/protoc-gen-ts"
}
},
"node_modules/@protobuf-ts/plugin-framework": {
"version": "2.9.6",
"resolved": "https://registry.npmjs.org/@protobuf-ts/plugin-framework/-/plugin-framework-2.9.6.tgz",
"integrity": "sha512-w7A1RXrDCiVzcaRE6YJP7FCARuAFe/Vc4SNQnHAi4CF0V6mEtyjAYEIC5BNYgIRaJEqB26zzsBQjIem3R02SCA==",
"dependencies": {
"@protobuf-ts/runtime": "^2.9.6",
"typescript": "^3.9"
}
},
"node_modules/@protobuf-ts/plugin-framework/node_modules/typescript": {
"version": "3.9.10",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz",
"integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==",
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
"node": ">=4.2.0"
}
},
"node_modules/@protobuf-ts/plugin/node_modules/typescript": {
"version": "3.9.10",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz",
"integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==",
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
"node": ">=4.2.0"
}
},
"node_modules/@protobuf-ts/protoc": {
"version": "2.9.6",
"resolved": "https://registry.npmjs.org/@protobuf-ts/protoc/-/protoc-2.9.6.tgz",
"integrity": "sha512-c0XvAPDIBAovH9HxV8gBv8gzOTreQIqibcusrB1+DxvFiSvy+2V1tjbUmG5gJEbjk3aAOaoj0a3+QuE+P28xUw==",
"bin": {
"protoc": "protoc.js"
}
},
"node_modules/@protobuf-ts/runtime": {
"version": "2.9.6",
"resolved": "https://registry.npmjs.org/@protobuf-ts/runtime/-/runtime-2.9.6.tgz",
"integrity": "sha512-C0CfpKx4n4LBbUrajOdRj2BTbd3qBoK0SiKWLq7RgCoU6xiN4wesBMFHUOBp3fFzKeZwgU8Q2KtzaqzIvPLRXg=="
},
"node_modules/@protobuf-ts/runtime-rpc": {
"version": "2.9.6",
"resolved": "https://registry.npmjs.org/@protobuf-ts/runtime-rpc/-/runtime-rpc-2.9.6.tgz",
"integrity": "sha512-0UeqDRzNxgsh08lY5eWzFJNfD3gZ8Xf+WG1HzbIAbVAigzigwjwsYNNhTeas5H3gco1U5owTzCg177aambKOOw==",
"dependencies": {
"@protobuf-ts/runtime": "^2.9.6"
}
},
"node_modules/@types/bun": {
"version": "1.2.18",
"resolved": "https://registry.npmjs.org/@types/bun/-/bun-1.2.18.tgz",
"integrity": "sha512-Xf6RaWVheyemaThV0kUfaAUvCNokFr+bH8Jxp+tTZfx7dAPA8z9ePnP9S9+Vspzuxxx9JRAXhnyccRj3GyCMdQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"bun-types": "1.2.18"
}
},
"node_modules/@types/node": {
"version": "20.9.1",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.9.1.tgz",
@ -311,6 +394,17 @@
"node": ">= 6"
}
},
"node_modules/@types/react": {
"version": "19.1.8",
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.8.tgz",
"integrity": "sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"csstype": "^3.0.2"
}
},
"node_modules/@types/tunnel": {
"version": "0.0.3",
"license": "MIT",
@ -344,6 +438,19 @@
"concat-map": "0.0.1"
}
},
"node_modules/bun-types": {
"version": "1.2.18",
"resolved": "https://registry.npmjs.org/bun-types/-/bun-types-1.2.18.tgz",
"integrity": "sha512-04+Eha5NP7Z0A9YgDAzMk5PHR16ZuLVa83b26kH5+cp1qZW4F6FmAURngE7INf4tKOvCE69vYvDEwoNl1tGiWw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/node": "*"
},
"peerDependencies": {
"@types/react": "^19"
}
},
"node_modules/combined-stream": {
"version": "1.0.8",
"license": "MIT",
@ -358,6 +465,14 @@
"version": "0.0.1",
"license": "MIT"
},
"node_modules/csstype": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
"dev": true,
"license": "MIT",
"peer": true
},
"node_modules/delayed-stream": {
"version": "1.0.0",
"license": "MIT",
@ -473,14 +588,16 @@
}
},
"node_modules/prettier": {
"version": "2.8.8",
"version": "3.4.2",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.2.tgz",
"integrity": "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==",
"dev": true,
"license": "MIT",
"bin": {
"prettier": "bin-prettier.js"
"prettier": "bin/prettier.cjs"
},
"engines": {
"node": ">=10.13.0"
"node": ">=14"
},
"funding": {
"url": "https://github.com/prettier/prettier?sponsor=1"

View file

@ -1,7 +1,7 @@
{
"private": true,
"name": "setup-bun",
"version": "1.2.1",
"version": "2.0.2",
"description": "Setup Bun on GitHub Actions.",
"keywords": [
"bun",
@ -18,24 +18,23 @@
"author": "xHyroM",
"scripts": {
"format": "prettier --write src *.yml *.json *.md",
"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",
"build": "esbuild --target=node20 --outfile=dist/setup/index.js --bundle --keep-names --minify --platform=node --format=cjs src/index.ts && esbuild --target=node20 --outfile=dist/cache-save/index.js --bundle --keep-names --minify --platform=node --format=cjs src/cache-save.ts",
"start": "npm run build && node dist/setup/index.js"
},
"dependencies": {
"@actions/cache": "^3.1.4",
"@actions/core": "^1.10.0",
"@actions/cache": "^4.0.0",
"@actions/core": "^1.11.0",
"@actions/exec": "^1.1.1",
"@actions/glob": "^0.4.0",
"@actions/io": "^1.1.2",
"@actions/tool-cache": "^2.0.1"
"@actions/tool-cache": "^2.0.1",
"@iarna/toml": "^2.2.5"
},
"devDependencies": {
"@types/bun": "^1.1.13",
"@types/node": "^20.8.2",
"esbuild": "^0.19.2",
"prettier": "^2.8.4",
"prettier": "^3.4.2",
"typescript": "^4.9.5"
},
"prettier": {
"quoteProps": "preserve"
}
}

View file

@ -1,3 +1,4 @@
import { createHash } from "node:crypto";
import { homedir } from "node:os";
import { join } from "node:path";
import {
@ -11,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 { retry } from "./utils";
import { addExtension, retry } from "./utils";
import { cwd } from "node:process";
export type Input = {
customUrl?: string;
@ -22,14 +24,15 @@ export type Input = {
arch?: string;
avx2?: boolean;
profile?: boolean;
scope?: string;
registryUrl?: string;
registries?: Registry[];
noCache?: boolean;
};
export type Output = {
version: string;
revision: string;
bunPath: string;
url: string;
cacheHit: boolean;
};
@ -41,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);
@ -71,7 +74,9 @@ export default async (options: Input): Promise<Output> => {
let revision: string | undefined;
let cacheHit = false;
if (cacheEnabled) {
const cacheRestored = await restoreCache([bunPath], url);
const cacheKey = createHash("sha1").update(url).digest("base64");
const cacheRestored = await restoreCache([bunPath], cacheKey);
if (cacheRestored) {
revision = await getRevision(bunPath);
if (revision) {
@ -79,7 +84,7 @@ export default async (options: Input): Promise<Output> => {
info(`Using a cached version of Bun: ${revision}`);
} else {
warning(
`Found a cached version of Bun: ${revision} (but it appears to be corrupted?)`
`Found a cached version of Bun: ${revision} (but it appears to be corrupted?)`,
);
}
}
@ -93,7 +98,7 @@ export default async (options: Input): Promise<Output> => {
if (!revision) {
throw new Error(
"Downloaded a new version of Bun, but failed to check its version? Try again."
"Downloaded a new version of Bun, but failed to check its version? Try again.",
);
}
@ -111,15 +116,18 @@ export default async (options: Input): Promise<Output> => {
return {
version,
revision,
bunPath,
url,
cacheHit,
};
};
async function downloadBun(
url: string,
bunPath: string
bunPath: string,
): Promise<string | undefined> {
const zipPath = await downloadTool(url);
// 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);
try {
@ -160,7 +168,7 @@ function getDownloadUrl(options: Input): string {
const eprofile = encodeURIComponent(profile ?? false);
const { href } = new URL(
`${eversion}/${eos}/${earch}?avx2=${eavx2}&profile=${eprofile}`,
"https://bun.sh/download/"
"https://bun.sh/download/",
);
return href;
}

View file

@ -1,50 +1,81 @@
import { EOL } from "node:os";
import { appendFileSync } from "node:fs";
import { existsSync, readFileSync, writeFileSync } from "node:fs";
import { info } from "@actions/core";
import { parse, stringify } from "@iarna/toml";
import { Registry } from "./registry";
type BunfigOptions = {
registryUrl?: string;
scope?: string;
type BunfigConfig = {
install?: {
registry?: {
url: string;
token?: string;
};
scopes?: Record<string, { url: string; token?: string }>;
};
[key: string]: any;
};
export function createBunfig(options: BunfigOptions): string | null {
const { registryUrl, scope } = options;
let url: URL | undefined;
if (registryUrl) {
try {
url = new URL(registryUrl);
} catch {
throw new Error(`Invalid registry-url: ${registryUrl}`);
}
}
let owner: string | undefined;
if (scope) {
owner = scope.startsWith("@")
? scope.toLocaleLowerCase()
: `@${scope.toLocaleLowerCase()}`;
}
if (url && owner) {
return `[install.scopes]${EOL}'${owner}' = { token = "$BUN_AUTH_TOKEN", url = "${url}"}${EOL}`;
}
if (url && !owner) {
return `[install]${EOL}registry = "${url}"${EOL}`;
}
return null;
}
export function writeBunfig(path: string, options: BunfigOptions): void {
const bunfig = createBunfig(options);
if (!bunfig) {
export function writeBunfig(path: string, registries: Registry[]): void {
if (!registries.length) {
return;
}
info(`Writing bunfig.toml to '${path}'.`);
appendFileSync(path, bunfig, {
encoding: "utf8",
let globalRegistryCount = 0;
registries.forEach((registry) => {
try {
new URL(registry.url);
} catch {
throw new Error(`Invalid registry URL: ${registry.url}`);
}
if (!registry.scope) {
globalRegistryCount++;
}
});
if (globalRegistryCount > 1) {
throw new Error("You can't have more than one global registry.");
}
info(`Writing bunfig.toml to '${path}'.`);
let config: BunfigConfig = {};
if (existsSync(path)) {
try {
const content = readFileSync(path, { encoding: "utf-8" });
config = parse(content) as BunfigConfig;
} catch (error) {
info(`Error reading existing bunfig: ${error.message}`);
config = {};
}
}
config.install = config?.install || {};
config.install.scopes = config?.install.scopes || {};
const globalRegistry = registries.find((r) => !r.scope);
if (globalRegistry) {
config.install.registry = {
url: globalRegistry.url,
...(globalRegistry.token ? { token: globalRegistry.token } : {}),
};
}
for (const registry of registries) {
if (registry.scope) {
const scopeName = registry.scope.startsWith("@")
? registry.scope.toLowerCase()
: `@${registry.scope.toLowerCase()}`;
config.install.scopes[scopeName] = {
url: registry.url,
...(registry.token ? { token: registry.token } : {}),
};
}
}
if (Object.keys(config.install.scopes).length === 0) {
delete config.install.scopes;
}
writeFileSync(path, stringify(config), { encoding: "utf8" });
}

View file

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

View file

@ -1,75 +1,41 @@
import { tmpdir } from "node:os";
import { join } from "node:path";
import { existsSync, readFileSync } from "node:fs";
import {
getInput,
setOutput,
setFailed,
warning,
getBooleanInput,
} from "@actions/core";
import { getInput, setOutput, setFailed, getBooleanInput } from "@actions/core";
import runAction from "./action.js";
import { readVersionFromFile } from "./utils.js";
import { parseRegistries } from "./registry.js";
if (!process.env.RUNNER_TEMP) {
process.env.RUNNER_TEMP = tmpdir();
}
function readVersionFromPackageJson(): string | undefined {
const cwd = process.env.GITHUB_WORKSPACE;
if (!cwd) {
return;
}
const path = join(cwd, "package.json");
try {
if (!existsSync(path)) {
return;
}
const { packageManager } = JSON.parse(readFileSync(path, "utf8"));
if (!packageManager?.includes("bun@")) {
return;
}
const [_, version] = packageManager.split("bun@");
return version;
} catch (error) {
const { message } = error as Error;
warning(`Failed to read package.json: ${message}`);
}
}
const registries = parseRegistries(getInput("registries"));
function readVersionFromToolVersions(): string | undefined {
const cwd = process.env.GITHUB_WORKSPACE;
if (!cwd) {
return;
}
const path = join(cwd, ".tool-versions");
try {
if (!existsSync(path)) {
return;
}
// Backwards compatibility for the `registry-url` and `scope` inputs
const registryUrl = getInput("registry-url");
const scope = getInput("scope");
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}`);
}
if (registryUrl) {
registries.push({
url: registryUrl,
scope: scope,
token: "$BUN_AUTH_TOKEN",
});
}
runAction({
version:
getInput("bun-version") ||
readVersionFromPackageJson() ||
readVersionFromToolVersions() ||
readVersionFromFile(getInput("bun-version-file")) ||
undefined,
customUrl: getInput("bun-download-url") || undefined,
registryUrl: getInput("registry-url") || undefined,
scope: getInput("scope") || undefined,
registries: registries,
noCache: getBooleanInput("no-cache") || false,
})
.then(({ version, revision, cacheHit }) => {
.then(({ version, revision, bunPath, url, cacheHit }) => {
setOutput("bun-version", version);
setOutput("bun-revision", revision);
setOutput("bun-path", bunPath);
setOutput("bun-download-url", url);
setOutput("cache-hit", cacheHit);
process.exit(0);
})

62
src/registry.ts Normal file
View file

@ -0,0 +1,62 @@
export type Registry = {
url: string;
scope: string;
token?: string;
};
/**
* Parse registries from the simplified format:
* - Default registry: https://registry.npmjs.org/
* - Default registry with token: https://registry.npmjs.org/|token123
* - With scope and credentials in URL: @myorg:https://username:password@registry.myorg.com/
* - With scope and separate token: @partner:https://registry.partner.com/|basic_token
*/
export function parseRegistries(input: string): Registry[] {
if (!input?.trim()) return [];
return input
.split("\n")
.map((line) => line.trim())
.filter(Boolean)
.map(parseLine)
.filter(Boolean) as Registry[];
}
function parseLine(line: string): Registry | null {
const scopeMatch = line.match(
/^(@[a-z0-9-_.]+|[a-z0-9-_.]+(?=:[a-z]+:\/\/)):(.+)$/i,
);
if (scopeMatch) {
const scope = scopeMatch[1];
const urlPart = scopeMatch[2].trim();
const [url, token] = urlPart.split("|", 2).map((p) => p?.trim());
try {
new URL(url);
return {
url,
scope,
...(token && { token }),
};
} catch (e) {
throw new Error(`Invalid URL in registry configuration: ${url}`);
}
} else {
const [url, token] = line.split("|", 2).map((p) => p?.trim());
try {
new URL(url);
return {
url,
scope: "",
...(token && { token }),
};
} catch (e) {
throw new Error(`Invalid URL in registry configuration: ${url}`);
}
}
}

View file

@ -1,14 +1,80 @@
import { debug, warning } from "@actions/core";
import { info } from "node:console";
import { existsSync, readFileSync, renameSync } from "node:fs";
import { resolve, basename } from "node:path";
export function retry<T>(
fn: () => Promise<T>,
retries: number,
timeout = 10000
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)
retry(fn, retries - 1, timeout),
);
});
}
export function addExtension(path: string, ext: string): string {
if (!path.endsWith(ext)) {
renameSync(path, path + ext);
return path + ext;
}
return path;
}
const FILE_VERSION_READERS = {
"package.json": (content: string) => {
const pkg = JSON.parse(content);
return pkg.packageManager?.split("bun@")?.[1] ?? pkg.engines?.bun;
},
".tool-versions": (content: string) =>
content.match(/^bun\s*(?<version>.*?)$/m)?.groups?.version,
".bumrc": (content: string) => content, // https://github.com/owenizedd/bum
".bun-version": (content: string) => content,
};
export function readVersionFromFile(file: string): string | undefined {
const cwd = process.env.GITHUB_WORKSPACE;
if (!cwd) {
return;
}
if (!file) {
return;
}
debug(`Reading version from ${file}`);
const path = resolve(cwd, file);
const base = basename(file);
if (!existsSync(path)) {
warning(`File ${path} not found`);
return;
}
const reader = FILE_VERSION_READERS[base] ?? (() => undefined);
let output: string | undefined;
try {
output = reader(readFileSync(path, "utf8"))?.trim();
if (!output) {
warning(`Failed to read version from ${file}`);
return;
}
} catch (error) {
const { message } = error as Error;
warning(`Failed to read ${file}: ${message}`);
} finally {
if (output) {
info(`Obtained version ${output} from ${file}`);
return output;
}
}
}

291
tests/bunfig.spec.ts Normal file
View file

@ -0,0 +1,291 @@
import { afterEach, describe, expect, it } from "bun:test";
import { existsSync, unlinkSync } from "node:fs";
import { writeBunfig } from "../src/bunfig";
import { EOL } from "os";
describe("writeBunfig", () => {
const filePath = "bunfig_test.toml";
async function getFileAndContents() {
const file = Bun.file(filePath);
const contents = (await file.text()).split(EOL);
return { file, contents };
}
afterEach(() => {
if (existsSync(filePath)) unlinkSync(filePath);
console.log(`${filePath} was deleted`);
});
describe("when no bunfig_test.toml file exists", () => {
it("should create a new file with scopes content", async () => {
writeBunfig(filePath, [
{
url: "https://npm.pkg.github.com",
scope: "foo-bar",
token: "$BUN_AUTH_TOKEN",
},
]);
const { file, contents } = await getFileAndContents();
expect(file.exists()).resolves.toBeTrue();
const expectedContents = [
'[install.scopes."@foo-bar"]',
'url = "https://npm.pkg.github.com"',
'token = "$BUN_AUTH_TOKEN"',
"",
];
contents.forEach((content, index) =>
expect(content).toBe(expectedContents[index])
);
expect(contents.length).toBe(expectedContents.length);
});
it("should create a new file with global registry", async () => {
writeBunfig(filePath, [
{
url: "https://npm.pkg.github.com",
scope: "",
},
]);
const { file, contents } = await getFileAndContents();
expect(file.exists()).resolves.toBeTrue();
const expectedContents = [
"[install.registry]",
'url = "https://npm.pkg.github.com"',
"",
];
contents.forEach((content, index) =>
expect(content).toBe(expectedContents[index])
);
expect(contents.length).toBe(expectedContents.length);
});
it("should create a new file with global registry & token", async () => {
writeBunfig(filePath, [
{
url: "https://npm.pkg.github.com",
scope: "",
token: "$BUN_AUTH_TOKEN",
},
]);
const { file, contents } = await getFileAndContents();
expect(file.exists()).resolves.toBeTrue();
const expectedContents = [
"[install.registry]",
'url = "https://npm.pkg.github.com"',
'token = "$BUN_AUTH_TOKEN"',
"",
];
contents.forEach((content, index) =>
expect(content).toBe(expectedContents[index])
);
expect(contents.length).toBe(expectedContents.length);
});
});
describe("when local bunfig_test.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);
writeBunfig(filePath, [
{
url: "https://npm.pkg.github.com",
scope: "foo-bar",
token: "$BUN_AUTH_TOKEN",
},
]);
const { file, contents } = await getFileAndContents();
expect(file.exists()).resolves.toBeTrue();
const expectedContents = [
"[install]",
"optional = true",
"",
" [install.cache]",
" disable = true",
"",
'[install.scopes."@foo-bar"]',
'url = "https://npm.pkg.github.com"',
'token = "$BUN_AUTH_TOKEN"',
"",
];
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);
writeBunfig(filePath, [
{
url: "https://npm.pkg.github.com",
scope: "foo-bar",
token: "$BUN_AUTH_TOKEN",
},
]);
const { file, contents } = await getFileAndContents();
expect(file.exists()).resolves.toBeTrue();
const expectedContents = [
"[install]",
"optional = true",
"",
'[install.scopes."@bla-ble"]',
'token = "$BUN_AUTH_TOKEN"',
'url = "https://npm.pkg.github.com/"',
"",
'[install.scopes."@foo-bar"]',
'url = "https://npm.pkg.github.com"',
'token = "$BUN_AUTH_TOKEN"',
"",
" [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);
writeBunfig(filePath, [
{
url: "https://npm.pkg.github.com",
scope: "foo-bar",
token: "$BUN_AUTH_TOKEN",
},
]);
const { file, contents } = await getFileAndContents();
expect(file.exists()).resolves.toBeTrue();
const expectedContents = [
"[install]",
"optional = true",
"",
'[install.scopes."@foo-bar"]',
'url = "https://npm.pkg.github.com"',
'token = "$BUN_AUTH_TOKEN"',
"",
'[install.scopes."@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] and [install] exists, should concantenate 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);
writeBunfig(filePath, [
{
url: "https://npm.pkg.github.com",
scope: "foo-bar",
token: "$BUN_AUTH_TOKEN",
},
{
url: "https://bun.sh",
scope: "",
token: "$BUN_AUTH_TOKEN",
}, // global registry
]);
const { file, contents } = await getFileAndContents();
expect(file.exists()).resolves.toBeTrue();
const expectedContents = [
"[install]",
"optional = true",
"",
'[install.scopes."@foo-bar"]',
'url = "https://npm.pkg.github.com"',
'token = "$BUN_AUTH_TOKEN"',
"",
'[install.scopes."@bla-ble"]',
'token = "$BUN_AUTH_TOKEN"',
'url = "https://npm.pkg.github.com/"',
"",
" [install.cache]",
" disable = true",
"",
" [install.registry]",
' url = "https://bun.sh"',
' token = "$BUN_AUTH_TOKEN"',
"",
];
contents.forEach((content, index) =>
expect(content).toBe(expectedContents[index])
);
expect(contents.length).toBe(expectedContents.length);
});
});
describe("when multiple global registries are provided", () => {
it("should throw an error", () => {
expect(() => {
writeBunfig(filePath, [
{
url: "https://npm.pkg.github.com",
scope: "",
token: "$BUN_AUTH_TOKEN",
},
{
url: "https://bun.sh",
scope: "",
token: "$BUN_AUTH_TOKEN",
},
]);
}).toThrow("You can't have more than one global registry.");
});
});
});

170
tests/registry.spec.ts Normal file
View file

@ -0,0 +1,170 @@
import { describe, expect, it } from "bun:test";
import { parseRegistries } from "../src/registry";
describe("registry", () => {
describe("parseRegistries", () => {
it("should return an empty array for empty input", () => {
expect(parseRegistries("")).toEqual([]);
expect(parseRegistries(" ")).toEqual([]);
expect(parseRegistries(null as any)).toEqual([]);
expect(parseRegistries(undefined as any)).toEqual([]);
});
it("should parse default registry without token", () => {
const input = "https://registry.npmjs.org/";
const result = parseRegistries(input);
expect(result).toEqual([
{
url: "https://registry.npmjs.org/",
scope: "",
},
]);
});
it("should parse default registry with token", () => {
const input = "https://registry.npmjs.org/|npm_token123";
const result = parseRegistries(input);
expect(result).toEqual([
{
url: "https://registry.npmjs.org/",
scope: "",
token: "npm_token123",
},
]);
});
it("should parse scoped registry with URL credentials", () => {
const input = "@myorg:https://username:password@registry.myorg.com/";
const result = parseRegistries(input);
expect(result).toEqual([
{
url: "https://username:password@registry.myorg.com/",
scope: "@myorg",
},
]);
});
it("should parse scoped registry with separate token", () => {
const input = "@partner:https://registry.partner.com/|token_abc123";
const result = parseRegistries(input);
expect(result).toEqual([
{
url: "https://registry.partner.com/",
scope: "@partner",
token: "token_abc123",
},
]);
});
it("should parse multiple registries", () => {
const input = `
https://registry.npmjs.org/
@myorg:https://username:password@registry.myorg.com/
@partner:https://registry.partner.com/|token_abc123
`;
const result = parseRegistries(input);
expect(result).toEqual([
{
url: "https://registry.npmjs.org/",
scope: "",
},
{
url: "https://username:password@registry.myorg.com/",
scope: "@myorg",
},
{
url: "https://registry.partner.com/",
scope: "@partner",
token: "token_abc123",
},
]);
});
it("should handle scope names without @ prefix", () => {
const input = "myorg:https://registry.myorg.com/|token123";
const result = parseRegistries(input);
expect(result).toEqual([
{
url: "https://registry.myorg.com/",
scope: "myorg",
token: "token123",
},
]);
});
it("should throw error for invalid URLs", () => {
expect(() => {
parseRegistries("@myorg:not-a-valid-url");
}).toThrow("Invalid URL in registry configuration: not-a-valid-url");
expect(() => {
parseRegistries("also-not-a-valid-url");
}).toThrow("Invalid URL in registry configuration: also-not-a-valid-url");
});
it("should handle whitespace and empty lines", () => {
const input = `
https://registry.npmjs.org/
@myorg:https://registry.myorg.com/|token123
`;
const result = parseRegistries(input);
expect(result).toEqual([
{
url: "https://registry.npmjs.org/",
scope: "",
},
{
url: "https://registry.myorg.com/",
scope: "@myorg",
token: "token123",
},
]);
});
it("should handle URLs with paths and query parameters", () => {
const input =
"@myorg:https://registry.myorg.com/npm/registry/?timeout=5000|token123";
const result = parseRegistries(input);
expect(result).toEqual([
{
url: "https://registry.myorg.com/npm/registry/?timeout=5000",
scope: "@myorg",
token: "token123",
},
]);
});
it("should correctly handle scopes with hyphens and underscores", () => {
const input = `
@my-org:https://registry.myorg.com/
@my_org:https://registry.myorg.com/
`;
const result = parseRegistries(input);
expect(result).toEqual([
{
url: "https://registry.myorg.com/",
scope: "@my-org",
},
{
url: "https://registry.myorg.com/",
scope: "@my_org",
},
]);
});
});
});

8
tests/tsconfig.json Normal file
View file

@ -0,0 +1,8 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
"types": [
"bun"
]
}
}