From 8d2563739447a3e43b63c33fd7d2ff4642e972f6 Mon Sep 17 00:00:00 2001 From: Amir Keshavarz Date: Fri, 3 Jul 2026 14:14:32 +0200 Subject: [PATCH] ci(sandbox): publish @bunny.net/sandbox in release workflow --- .github/workflows/release.yml | 39 ++++++++++++++++++++++++++++ AGENTS.md | 9 +++++++ bun.lock | 4 +++ packages/sandbox/package.json | 17 +++++++++--- packages/sandbox/tsconfig.build.json | 11 ++++++++ tsconfig.json | 5 ++-- 6 files changed, 80 insertions(+), 5 deletions(-) create mode 100644 packages/sandbox/tsconfig.build.json diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4d07be1c..0d3ca3e1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -39,6 +39,7 @@ jobs: cli-version: ${{ steps.check-cli.outputs.version }} database-shell-version: ${{ steps.check-database-shell.outputs.version }} openapi-client-version: ${{ steps.check-openapi-client.outputs.version }} + sandbox-version: ${{ steps.check-sandbox.outputs.version }} scriptable-dns-types-version: ${{ steps.check-scriptable-dns-types.outputs.version }} steps: - uses: actions/checkout@v5 @@ -53,6 +54,17 @@ jobs: else echo "No version change: $VERSION" fi + - name: Check sandbox version + id: check-sandbox + run: | + VERSION=$(node -p "require('./packages/sandbox/package.json').version") + PUBLISHED=$(npm view @bunny.net/sandbox version 2>/dev/null || echo "0.0.0") + if [ "$VERSION" != "$PUBLISHED" ]; then + echo "version=$VERSION" >> $GITHUB_OUTPUT + echo "New version detected: $VERSION (published: $PUBLISHED)" + else + echo "No version change: $VERSION" + fi - name: Check scriptable-dns-types version id: check-scriptable-dns-types run: | @@ -428,6 +440,33 @@ jobs: env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + publish-sandbox: + name: Publish sandbox + runs-on: ubuntu-latest + needs: version + if: needs.version.outputs.sandbox-version + steps: + - uses: actions/checkout@v5 + - uses: oven-sh/setup-bun@v2 + with: + bun-version: "1.3.11" + - run: bun install + + # Sandbox's build type-checks against openapi-client's package exports (dist/), so build it first. + - name: Build openapi-client + run: bun run --filter @bunny.net/openapi-client build + + - name: Build package + run: bun run --filter @bunny.net/sandbox build + + # bun publish (not npm) rewrites the workspace:* dependency on @bunny.net/openapi-client to a real version. + - name: Publish @bunny.net/sandbox + run: | + cd packages/sandbox + bun publish --access public + env: + NPM_CONFIG_TOKEN: ${{ secrets.NPM_TOKEN }} + publish-scriptable-dns-types: name: Publish scriptable-dns-types runs-on: ubuntu-latest diff --git a/AGENTS.md b/AGENTS.md index f742b47c..d897a0c8 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -867,6 +867,15 @@ Its `package.json` `exports`/`main`/`types` point at `dist/`, so npm consumers g - `scripts/build.ts` drives the TypeScript compiler API (using `tsconfig.build.json`) to emit JS + declarations, then copies the generated `.d.ts` files into `dist/generated/` (tsc never emits its inputs, and those files back the `./generated/*` subpath export). `rewriteRelativeImportExtensions` rewrites `./x.ts` → `./x.js` in the emitted **JS**; TypeScript has no equivalent for declaration emit, so an `afterDeclarations` transformer rewrites the `.ts`/`.d.ts` specifiers in the emitted **`.d.ts`** files on the AST. - The `publish-openapi-client` job in `release.yml` (gated on a version bump detected via `npm view`) builds, then runs `cd packages/openapi-client && npm publish` (`files` ships `dist` + `README.md`). The package versions independently of the CLI — it is not part of any `fixed` group in `.changeset/config.json`. +### Publishing `@bunny.net/sandbox` + +`@bunny.net/sandbox` follows the same compiled-library pattern as `@bunny.net/openapi-client`: `exports`/`main`/`types` point at `dist/`, in-repo tooling resolves it from source via the root `tsconfig.json` `paths` mapping, and `scripts/build.ts` (via `tsconfig.build.json`) emits JS + declarations with the same `.ts` → `.js` specifier rewriting. + +Two differences from openapi-client: + +- Sandbox depends on `@bunny.net/openapi-client` with `workspace:*`, so the `publish-sandbox` job in `release.yml` uses `bun publish` (not `npm publish`) — bun rewrites `workspace:*` to the local package version in the published tarball; npm would ship the unresolvable `workspace:*` spec verbatim. `bun publish` authenticates via the `NPM_CONFIG_TOKEN` env var. +- Its `tsconfig.build.json` overrides `paths` to `{}` so openapi-client resolves via its package `exports` (`dist/`) instead of source — otherwise openapi-client's sources would enter the program and violate `rootDir`. The publish job therefore builds openapi-client before building sandbox. + ### CI Tests and type-checking run on every pull request via `.github/workflows/ci.yml` (`bun run typecheck` and `bun test`). diff --git a/bun.lock b/bun.lock index b979a69e..9a3c8f32 100644 --- a/bun.lock +++ b/bun.lock @@ -1,5 +1,6 @@ { "lockfileVersion": 1, + "configVersion": 0, "workspaces": { "": { "name": "bun-ny-cli", @@ -191,6 +192,9 @@ "@types/ssh2": "^1.15.0", "ssh2": "^1.16.0", }, + "devDependencies": { + "typescript": "^5", + }, }, "packages/scriptable-dns-types": { "name": "@bunny.net/scriptable-dns-types", diff --git a/packages/sandbox/package.json b/packages/sandbox/package.json index e2faf8df..f2fdb7a7 100644 --- a/packages/sandbox/package.json +++ b/packages/sandbox/package.json @@ -2,12 +2,20 @@ "name": "@bunny.net/sandbox", "version": "0.2.1", "type": "module", - "module": "src/index.ts", + "main": "./dist/index.js", + "module": "./dist/index.js", + "types": "./dist/index.d.ts", + "scripts": { + "build": "rm -rf dist && tsc -p tsconfig.build.json" + }, "exports": { - ".": "./src/index.ts" + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js" + } }, "files": [ - "src", + "dist", "README.md" ], "dependencies": { @@ -15,6 +23,9 @@ "@types/ssh2": "^1.15.0", "ssh2": "^1.16.0" }, + "devDependencies": { + "typescript": "^5" + }, "publishConfig": { "access": "public" } diff --git a/packages/sandbox/tsconfig.build.json b/packages/sandbox/tsconfig.build.json new file mode 100644 index 00000000..d432dd3d --- /dev/null +++ b/packages/sandbox/tsconfig.build.json @@ -0,0 +1,11 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "noEmit": false, + "declaration": true, + "rewriteRelativeImportExtensions": true, + "outDir": "dist", + "rootDir": "src" + }, + "exclude": ["src/**/*.test.ts"] +} diff --git a/tsconfig.json b/tsconfig.json index 32dc4bdc..e48ca6a2 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -14,12 +14,13 @@ "verbatimModuleSyntax": true, "noEmit": true, - // Resolve @bunny.net/openapi-client from source in-repo (no prebuild); npm consumers use its package exports. See AGENTS.md "Publishing". + // Resolve @bunny.net/openapi-client and @bunny.net/sandbox from source in-repo (no prebuild); npm consumers use their package exports. See AGENTS.md "Publishing". "paths": { "@bunny.net/openapi-client": ["./packages/openapi-client/src/index.ts"], "@bunny.net/openapi-client/generated/*": [ "./packages/openapi-client/src/generated/*" - ] + ], + "@bunny.net/sandbox": ["./packages/sandbox/src/index.ts"] }, // Best practices