Skip to content

Commit e6873a9

Browse files
committed
chore: tag version v0.0.1
1 parent 98b8b60 commit e6873a9

File tree

2 files changed

+29
-29
lines changed

2 files changed

+29
-29
lines changed

.github/workflows/release.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ jobs:
1616
fetch-depth: 0
1717

1818
- name: Setup Deno
19-
uses: denoland/setup-deno@v1
19+
uses: denoland/setup-deno@v2
2020
with:
21-
deno-version: v1.x
21+
deno-version: v2.x
2222

2323
- name: Cache Deno dependencies
2424
uses: actions/cache@v3

docs/prompt-context/building-a-release-pipeline.md

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,26 @@
11
# Automating Release Pipelines for Node, Deno, and Bun Projects
22

3-
Successfully automating releases for diverse Javascript and Typescript projects requires a unified yet flexible approach. We need to **detect each projects runtime and type**, then run the appropriate build and publish steps. Below, we outline how to identify the project type from config files, update configurations if needed, and implement a **GitHub Actions** workflow with accompanying scripts to handle library publishing, CLI distribution, and compiled binary releases for **Node.js**, **Deno**, and **Bun**.
3+
Successfully automating releases for diverse Javascript and Typescript projects requires a unified yet flexible approach. We need to **detect each project's runtime and type**, then run the appropriate build and publish steps. Below, we outline how to identify the project type from config files, update configurations if needed, and implement a **GitHub Actions** workflow with accompanying scripts to handle library publishing, CLI distribution, and compiled binary releases for **Node.js**, **Deno**, and **Bun**.
44

55
## 1. Detecting Runtime and Release Type
66

77
Each project contains manifest files that signal its runtime and intended usage:
88

9-
* **Node.js projects**: Indicated by a `package.json`. We further check if its a CLI tool by looking for a `"bin"` field mapping command names to script files (e.g. `"bin": {"mytool": "src/cli.js"}`). Presence of `"bin"` means the package is a CLI tool (executables on install); absence suggests a library module.
9+
* **Node.js projects**: Indicated by a `package.json`. We further check if it's a CLI tool by looking for a `"bin"` field mapping command names to script files (e.g. `"bin": {"mytool": "src/cli.js"}`). Presence of `"bin"` means the package is a CLI tool (executables on install); absence suggests a library module.
1010
* **Bun projects**: Usually have a `bun.json`/`bunfig.toml` (in addition to or instead of `package.json`). Bun is largely Node-compatible, but a `bun.json` hints the project is optimized for Bun. If Bun config defines an executable entry (or the Node `"bin"` field is present), treat it as a CLI; otherwise a library.
11-
* **Deno projects**: Identified by a `deno.json`/`deno.jsonc`. Deno packages must have a `name`, `version`, and `exports` in this file for publishing. Deno doesnt use a separate `"bin"` field; a Deno CLI vs library is determined by intent:
11+
* **Deno projects**: Identified by a `deno.json`/`deno.jsonc`. Deno packages must have a `name`, `version`, and `exports` in this file for publishing. Deno doesn't use a separate `"bin"` field; a Deno CLI vs library is determined by intent:
1212

13-
* If the codes primary use is to be run (e.g. has a `main.ts` or similar that parses arguments or is referenced in documentation as a command), treat as a CLI tool.
14-
* Otherwise, if its meant to be imported (e.g. provides functions/types), treat as a library.
15-
* **Compiled Binary**: Some CLI projects also require a **compiled binary** release (single-file executables) for convenience (no runtime needed). By default, we will produce binaries for CLI tools in Node and Bun (to run without Node/Bun installed), and optionally for Deno CLIs if needed for users without Deno. If its ambiguous (e.g. a Deno CLI might be fine with just `deno install`), wed confirm with maintainers whether to provide a binary.
13+
* If the code's primary use is to be run (e.g. has a `main.ts` or similar that parses arguments or is referenced in documentation as a command), treat as a CLI tool.
14+
* Otherwise, if it's meant to be imported (e.g. provides functions/types), treat as a library.
15+
* **Compiled Binary**: Some CLI projects also require a **compiled binary** release (single-file executables) for convenience (no runtime needed). By default, we will produce binaries for CLI tools in Node and Bun (to run without Node/Bun installed), and optionally for Deno CLIs if needed for users without Deno. If it's ambiguous (e.g. a Deno CLI might be fine with just `deno install`), we'd confirm with maintainers whether to provide a binary.
1616

1717
**Note:** If multiple configs exist (e.g. both `package.json` and `deno.json`), the project may target both Node (NPM) and Deno (JSR). In such cases, we can publish to both registries. If the intended release registry is unclear, we should ask the user to specify their preference (NPM vs JSR, or both).
1818

1919
## 2. Configuration Updates for Release Readiness
2020

21-
Before writing the pipeline, ensure each projects config is set up for smooth publishing:
21+
Before writing the pipeline, ensure each project's config is set up for smooth publishing:
2222

23-
* **Node (and Bun) packages**: The `package.json` should have correct `name` (unique in npm), `version` (matching the tag to be released), and if its a library, an appropriate `"main"` or `"exports"` field for module entry. For TypeScript, include `"types"` pointing to the type definitions. If its a CLI, add a `"bin"` field mapping the command name to the compiled output or entry script. Also, set `"files"` or `.npmignore` to include built artifacts (and exclude source if not needed) so that `npm publish` packages the right files. For example, a Node CLI might have:
23+
* **Node (and Bun) packages**: The `package.json` should have correct `name` (unique in npm), `version` (matching the tag to be released), and if it's a library, an appropriate `"main"` or `"exports"` field for module entry. For TypeScript, include `"types"` pointing to the type definitions. If it's a CLI, add a `"bin"` field mapping the command name to the compiled output or entry script. Also, set `"files"` or `.npmignore` to include built artifacts (and exclude source if not needed) so that `npm publish` packages the right files. For example, a Node CLI might have:
2424

2525
```json
2626
{
@@ -46,7 +46,7 @@ Before writing the pipeline, ensure each project’s config is set up for smooth
4646

4747
(The `"entry"` above is not official; the important field is `"exports"` for JSR).
4848

49-
* **Bun projects**: Bun uses `package.json` for publishing (via `bun publish` to NPM), so ensure thats updated. If a `bunfig.toml` or `bun.json` exists, verify it doesnt conflict with package.json for name/version. For binaries, Bun will automatically append .exe on Windows builds, so our naming conventions should account for that.
49+
* **Bun projects**: Bun uses `package.json` for publishing (via `bun publish` to NPM), so ensure that's updated. If a `bunfig.toml` or `bun.json` exists, verify it doesn't conflict with package.json for name/version. For binaries, Bun will automatically append ".exe" on Windows builds, so our naming conventions should account for that.
5050

5151
With configs in place, we can proceed to automation.
5252

@@ -55,31 +55,31 @@ With configs in place, we can proceed to automation.
5555
We create a single workflow `.github/workflows/release.yml` that triggers on pushing a version tag. It will detect the project type and run the appropriate jobs:
5656

5757
* **Trigger**: Only on new tags that look like version (e.g. `v*`) pushed to the main or master branch.
58-
* **Environment Matrix**: We may use a job matrix for building binaries on multiple OS, or use cross-compilation tools. Here well demonstrate cross-compiling where possible to keep a single job, but note that Nodes official SEA feature might require per-OS jobs. Well use **Vercel pkg** for Node to allow cross-builds from one job, since Nodes Single Executable Application is experimental and multi-step.
58+
* **Environment Matrix**: We may use a job matrix for building binaries on multiple OS, or use cross-compilation tools. Here we'll demonstrate cross-compiling where possible to keep a single job, but note that Node's official SEA feature might require per-OS jobs. We'll use **Vercel pkg** for Node to allow cross-builds from one job, since Node's Single Executable Application is experimental and multi-step.
5959
* **Steps**:
6060

6161
1. **Checkout code**.
6262
2. **Set up languages** (Node, Deno, or Bun) depending on project:
6363

6464
* For Node: use `actions/setup-node@v3` to install appropriate Node version (and prepare npm auth).
6565
* For Bun: use `oven-sh/setup-bun@v2`.
66-
* For Deno: use `denoland/setup-deno@v1` to get Deno on runner.
66+
* For Deno: use `denoland/setup-deno@v2` to get Deno on runner.
6767
3. **Install Dependencies & Build**:
6868

6969
* If Node or Bun and TypeScript, run `npm ci`/`bun install`, then a build script (e.g. `npm run build`) to produce JS in `dist/`.
7070
* If Deno, installation is not needed (Deno fetches deps on the fly), but we might run `deno check` or tests.
7171
4. **Publish to Registry** (if library or CLI package):
7272

73-
* For Node/Bun: use `npm publish` (or `bun publish`). We configure `NPM_TOKEN` for auth. (Buns publish packs and pushes to npm just like npm publish).
74-
* For Deno: run `deno publish --token=${{ secrets.JSR_TOKEN }}` to publish to JSR (assuming weve created the package on JSR beforehand).
73+
* For Node/Bun: use `npm publish` (or `bun publish`). We configure `NPM_TOKEN` for auth. (Bun's publish packs and pushes to npm just like npm publish).
74+
* For Deno: run `deno publish --token=${{ secrets.JSR_TOKEN }}` to publish to JSR (assuming we've created the package on JSR beforehand).
7575
5. **Compile Binaries** (if CLI needs standalone binaries):
7676

77-
* **Node CLI**: Use `npx pkg` to compile for Linux, Windows, macOS in one go. For example, `pkg -t node18-linux-x64,node18-win-x64,node18-macos-x64 .` will output executables for each target. (We choose a Node runtime target matching our projects requirements, e.g., Node 18 or `latest` for latest LTS).
77+
* **Node CLI**: Use `npx pkg` to compile for Linux, Windows, macOS in one go. For example, `pkg -t node18-linux-x64,node18-win-x64,node18-macos-x64 .` will output executables for each target. (We choose a Node runtime target matching our project's requirements, e.g., Node 18 or `latest` for latest LTS).
7878
* **Deno CLI**: Use `deno compile`. We can cross-compile for all supported targets with `--target` flag (e.g., `deno compile -A --output mytool-linux --target x86_64-unknown-linux-gnu main.ts` and similarly for `*-windows-msvc` and `*-apple-darwin`). Deno will download the appropriate `denort` runtime for each target automatically.
7979
* **Bun CLI**: Use `bun build --compile` with `--target` for each platform. For example: `bun build --compile src/cli.ts --target=bun-linux-x64 --outfile mytool-linux` (and likewise `bun-windows-x64`, `bun-darwin-x64`, etc.). Bun supports cross-compiling via the `--target` option.
8080
6. **Prepare Release Assets**:
8181

82-
* Rename the binaries with a clear convention: e.g. `mytool-linux`, `mytool-macos`, `mytool-windows.exe` (include `.exe` for Windows) for clarity. We might archive them (e.g. zip/tar) or attach raw; to keep it simple well attach raw binaries and ensure the install script accounts for platform naming.
82+
* Rename the binaries with a clear convention: e.g. `mytool-linux`, `mytool-macos`, `mytool-windows.exe` (include `.exe` for Windows) for clarity. We might archive them (e.g. zip/tar) or attach raw; to keep it simple we'll attach raw binaries and ensure the install script accounts for platform naming.
8383
* Generate or update the **`install.sh`** script in the repository root. This script will let users install the latest release easily: it will detect OS and arch, fetch the appropriate binary from GitHub Releases, install it to `/usr/local/bin` (or another prefix), and print usage instructions. We write this script once (committed to the repo) and it always pulls the **latest** release by default. Optionally, allow specifying a version: if user passes an argument (version tag), the script uses that instead of latest.
8484
7. **Create GitHub Release**:
8585

@@ -114,7 +114,7 @@ jobs:
114114
runs-on: ubuntu-latest
115115
env:
116116
NODE_VERSION: "18" # Node version for Node/Bun projects
117-
DENO_VERSION: "1.x" # Deno version (if needed specific)
117+
DENO_VERSION: "2.x" # Deno version (if needed specific)
118118
steps:
119119
- name: Checkout
120120
uses: actions/checkout@v4
@@ -181,7 +181,7 @@ jobs:
181181

182182
- name: Setup Deno (if Deno)
183183
if: env.RUNTIME == 'deno'
184-
uses: denoland/setup-deno@v1
184+
uses: denoland/setup-deno@v2
185185
with:
186186
deno-version: ${{ env.DENO_VERSION }}
187187

@@ -307,7 +307,7 @@ fi
307307
**Notes:**
308308

309309
* For **npm** publishing, we use `npm publish`. The `actions/setup-node` step in the workflow already created an `.npmrc` with the token, so `npm publish` will succeed. We include `--access public` for scoped packages.
310-
* For **JSR (Deno)**, we use `deno publish`. If `JSR_TOKEN` is provided, we pass it (to avoid interactive login). Denos OIDC flow (tokenless from GitHub Actions using Sigstore) could be enabled by setting `permissions:id-token: write` and omitting the token, but using a token is straightforward.
310+
* For **JSR (Deno)**, we use `deno publish`. If `JSR_TOKEN` is provided, we pass it (to avoid interactive login). Deno's OIDC flow (tokenless from GitHub Actions using Sigstore) could be enabled by setting `permissions:id-token: write` and omitting the token, but using a token is straightforward.
311311
* For **Bun**, `bun publish` will pack and publish to the npm registry using the same credentials as npm (it respects `.npmrc` or environment).
312312

313313
### `bin/release.sh` – Building Binaries and Preparing Assets
@@ -411,14 +411,14 @@ fi
411411
A few points about `bin/release.sh`:
412412

413413
* It finds a base `NAME` for the binaries, typically the package name without scope (e.g. `"@org/mytool"` -> `mytool`). This name will be used in the filenames.
414-
* **Node**: We install or use `pkg` to create binaries for all three platforms in one command. The script picks the entry point from package.json (`bin` or `main`). We rename outputs to a consistent scheme. (Using Nodes official SEA would involve a more complex process including `--experimental-sea-config` and `postject` injection – for simplicity and automation, we use `pkg` here.)
414+
* **Node**: We install or use `pkg` to create binaries for all three platforms in one command. The script picks the entry point from package.json (`bin` or `main`). We rename outputs to a consistent scheme. (Using Node's official SEA would involve a more complex process including `--experimental-sea-config` and `postject` injection – for simplicity and automation, we use `pkg` here.)
415415
* **Deno**: We compile 4 binaries: linux x64, macOS x64, macOS arm64, and Windows x64. This covers common platforms. (We could also build Linux arm64 if needed by adding `aarch64-unknown-linux-gnu`.)
416-
* **Bun**: We compile for Linux x64, Windows x64, and macOS x64. (Bun can also produce macOS arm64 if run on an ARM host or in cross-mode, but here we assume x64 build. We note that Buns `--target` has baseline vs modern variants; using default ensures broad compatibility.)
417-
* The script creates an `install.sh` if one doesnt exist. In practice, youd create this script once manually with the correct `REPO` placeholder. We show it being generated for completeness. The script:
416+
* **Bun**: We compile for Linux x64, Windows x64, and macOS x64. (Bun can also produce macOS arm64 if run on an ARM host or in cross-mode, but here we assume x64 build. We note that Bun's `--target` has baseline vs modern variants; using default ensures broad compatibility.)
417+
* The script creates an `install.sh` if one doesn't exist. In practice, you'd create this script once manually with the correct `REPO` placeholder. We show it being generated for completeness. The script:
418418

419-
* Fetches the latest release tag via GitHubs API (unless a version argument is given).
419+
* Fetches the latest release tag via GitHub's API (unless a version argument is given).
420420
* Detects OS and sets the expected asset name (this simple version lumps all Linux under one and all macOS under one, assuming x64 works on ARM via Rosetta – one could refine to pick an ARM binary if available).
421-
* Downloads the asset and installs it to `/usr/local/bin` (using `~/.local/bin` if the former isnt accessible).
421+
* Downloads the asset and installs it to `/usr/local/bin` (using `~/.local/bin` if the former isn't accessible).
422422
* Makes the binary executable and prints a success message.
423423
* For Windows, since this is a Bash script, it would typically be run in WSL or Git Bash. Windows users not using a UNIX shell can manually download the `.exe` or use a PowerShell equivalent script (not included here).
424424

@@ -433,7 +433,7 @@ This will install the latest version of **mytool** on their system.
433433

434434
## 4. Summary of Benefits and Maintenance
435435

436-
By following this template, each projects CI/CD pipeline will automatically:
436+
By following this template, each project's CI/CD pipeline will automatically:
437437

438438
* **Detect the runtime and project type** (Node library, Node CLI, Deno lib/CLI, Bun project, etc.) and run the correct build and release steps.
439439
* **Publish libraries** to the appropriate registry:
@@ -445,8 +445,8 @@ By following this template, each project’s CI/CD pipeline will automatically:
445445
* **npm/JSR** for package installation (e.g. `npm -g` or `deno add`), and/or
446446
* **GitHub Releases** with pre-built binaries for macOS, Linux, and Windows, plus an easy installer script (`curl | sh`).
447447
* **Trigger on tagged releases** ensuring that new versions are released only when you push a version tag (e.g. `v1.2.3`) to the main branch, aligning with Git flow.
448-
* **Isolate build logic** in version-controlled scripts (`/bin`) and configuration in `.github/workflows`, making it easy to update across many projects. Theres no magic – just standard tools as documented by Node, Deno, and Bun.
449-
* **Support all platforms**: We produced platform-specific binaries using each runtimes official capability (Nodes packagers, Denos native compiler, Buns compiler) so users on Windows, Linux, or macOS are all covered. For example, Denos compiler can target all supported OSes from a single machine, and Buns `--target` can cross-compile executables as well. Nodes `pkg` can bundle for multiple platforms in one go.
450-
* **Minimal intervention**: once this is set up, maintainers only need to update version numbers and push tags. The workflow and scripts handle the rest automatically. If a projects intent is unclear (e.g. a Deno project that could be both a library and an app), the detection logic can be refined or a one-time manual tweak can be made to the script for that repository.
448+
* **Isolate build logic** in version-controlled scripts (`/bin`) and configuration in `.github/workflows`, making it easy to update across many projects. There's no magic – just standard tools as documented by Node, Deno, and Bun.
449+
* **Support all platforms**: We produced platform-specific binaries using each runtime's official capability (Node's packagers, Deno's native compiler, Bun's compiler) so users on Windows, Linux, or macOS are all covered. For example, Deno's compiler can target all supported OSes from a single machine, and Bun's `--target` can cross-compile executables as well. Node's `pkg` can bundle for multiple platforms in one go.
450+
* **Minimal intervention**: once this is set up, maintainers only need to update version numbers and push tags. The workflow and scripts handle the rest automatically. If a project's intent is unclear (e.g. a Deno project that could be both a library and an app), the detection logic can be refined or a one-time manual tweak can be made to the script for that repository.
451451

452452
By leveraging official tools and documentation from each ecosystem – Node (npm, pkg, or SEA), Deno (JSR and `deno compile`), and Bun (bun build/publish) – this solution provides a **consistent release process** across all projects. It ensures that libraries reach the right package registries and that CLI applications are easily installable in any environment, all through automated GitHub Actions workflows.

0 commit comments

Comments
 (0)