Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/release-derun.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ on:
description: "Semver without v prefix (for example: 0.2.0)"
required: true
dry_run:
description: "If true, skip release publication and Homebrew PR creation"
description: "If true, skip release publication and Homebrew tap push"
required: false
default: "true"
type: choice
Expand Down Expand Up @@ -203,7 +203,7 @@ jobs:
- name: Submit Homebrew update
if: env.DRY_RUN != 'true'
env:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
GH_TOKEN: ${{ secrets.HOMEBREW_TAP_GH_TOKEN }}
shell: bash
run: |
set -euo pipefail
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/release-dexdex.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ on:
description: "Semver without v prefix (for example: 0.2.0)"
required: true
dry_run:
description: "If true, skip release publication and Homebrew PR creation"
description: "If true, skip release publication and Homebrew tap push"
required: false
default: "true"
type: choice
Expand Down Expand Up @@ -323,7 +323,7 @@ jobs:
- name: Submit Homebrew updates
if: env.DRY_RUN != 'true'
env:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
GH_TOKEN: ${{ secrets.HOMEBREW_TAP_GH_TOKEN }}
shell: bash
run: |
set -euo pipefail
Expand Down
59 changes: 40 additions & 19 deletions .github/workflows/release-nodeup.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ on:
description: "Semver without v prefix (for example: 0.2.0)"
required: true
dry_run:
description: "If true, skip release publication and Homebrew PR creation"
description: "If true, skip release publication and Homebrew tap push"
required: false
default: "true"
type: choice
Expand Down Expand Up @@ -181,44 +181,65 @@ jobs:
files: dist/*
generate_release_notes: true

- name: Compute source archive checksum
id: source
shell: bash
run: |
set -euo pipefail

source_url="https://github.com/delinoio/oss/archive/refs/tags/${RELEASE_TAG}.tar.gz"
curl -fsSL "$source_url" -o source.tar.gz
source_sha="$(shasum -a 256 source.tar.gz | awk '{print $1}')"

echo "source_url=$source_url" >> "$GITHUB_OUTPUT"
echo "source_sha=$source_sha" >> "$GITHUB_OUTPUT"

- name: Render Homebrew update
if: env.DRY_RUN == 'true'
shell: bash
run: |
set -euo pipefail

chmod +x ./scripts/release/update-homebrew.sh

darwin_amd64_asset="nodeup-darwin-amd64.tar.gz"
darwin_amd64_sha="$(grep " ${darwin_amd64_asset}$" dist/SHA256SUMS | awk '{print $1}')"
darwin_amd64_url="https://github.com/delinoio/oss/releases/download/${RELEASE_TAG}/${darwin_amd64_asset}"

darwin_arm64_asset="nodeup-darwin-arm64.tar.gz"
darwin_arm64_sha="$(grep " ${darwin_arm64_asset}$" dist/SHA256SUMS | awk '{print $1}')"
darwin_arm64_url="https://github.com/delinoio/oss/releases/download/${RELEASE_TAG}/${darwin_arm64_asset}"

linux_amd64_asset="nodeup-linux-amd64.tar.gz"
linux_amd64_sha="$(grep " ${linux_amd64_asset}$" dist/SHA256SUMS | awk '{print $1}')"
linux_amd64_url="https://github.com/delinoio/oss/releases/download/${RELEASE_TAG}/${linux_amd64_asset}"

./scripts/release/update-homebrew.sh \
--project nodeup \
--version "$RELEASE_VERSION" \
--source-url "${{ steps.source.outputs.source_url }}" \
--source-sha256 "${{ steps.source.outputs.source_sha }}" \
--darwin-amd64-url "$darwin_amd64_url" \
--darwin-amd64-sha256 "$darwin_amd64_sha" \
--darwin-arm64-url "$darwin_arm64_url" \
--darwin-arm64-sha256 "$darwin_arm64_sha" \
--linux-amd64-url "$linux_amd64_url" \
--linux-amd64-sha256 "$linux_amd64_sha" \
--dry-run >/dev/null

- name: Submit Homebrew update
if: env.DRY_RUN != 'true'
env:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
GH_TOKEN: ${{ secrets.HOMEBREW_TAP_GH_TOKEN }}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve GH_TOKEN fallback in release workflows

This step overwrites GH_TOKEN with secrets.HOMEBREW_TAP_GH_TOKEN, so if the new secret is not present yet the value becomes empty and update-homebrew.sh aborts in non-dry-run mode (HOMEBREW_TAP_GH_TOKEN (or GH_TOKEN) is required). Because prior releases used secrets.GH_TOKEN and the script still supports that fallback, this change can block nodeup (and the same pattern in derun/dexdex) releases during secret migration. Use a workflow-level fallback so existing GH_TOKEN continues to work until all environments are updated.

Useful? React with 👍 / 👎.

shell: bash
run: |
set -euo pipefail

chmod +x ./scripts/release/update-homebrew.sh

darwin_amd64_asset="nodeup-darwin-amd64.tar.gz"
darwin_amd64_sha="$(grep " ${darwin_amd64_asset}$" dist/SHA256SUMS | awk '{print $1}')"
darwin_amd64_url="https://github.com/delinoio/oss/releases/download/${RELEASE_TAG}/${darwin_amd64_asset}"

darwin_arm64_asset="nodeup-darwin-arm64.tar.gz"
darwin_arm64_sha="$(grep " ${darwin_arm64_asset}$" dist/SHA256SUMS | awk '{print $1}')"
darwin_arm64_url="https://github.com/delinoio/oss/releases/download/${RELEASE_TAG}/${darwin_arm64_asset}"

linux_amd64_asset="nodeup-linux-amd64.tar.gz"
linux_amd64_sha="$(grep " ${linux_amd64_asset}$" dist/SHA256SUMS | awk '{print $1}')"
linux_amd64_url="https://github.com/delinoio/oss/releases/download/${RELEASE_TAG}/${linux_amd64_asset}"

./scripts/release/update-homebrew.sh \
--project nodeup \
--version "$RELEASE_VERSION" \
--source-url "${{ steps.source.outputs.source_url }}" \
--source-sha256 "${{ steps.source.outputs.source_sha }}"
--darwin-amd64-url "$darwin_amd64_url" \
--darwin-amd64-sha256 "$darwin_amd64_sha" \
--darwin-arm64-url "$darwin_arm64_url" \
--darwin-arm64-sha256 "$darwin_arm64_sha" \
--linux-amd64-url "$linux_amd64_url" \
--linux-amd64-sha256 "$linux_amd64_sha"
2 changes: 2 additions & 0 deletions apps/public-docs/nodeup.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ Tag contract:
Package manager:

- macOS/Linux: `brew install delinoio/tap/nodeup`
- Homebrew installs prebuilt archives on macOS Intel, macOS Apple Silicon, and Linux amd64
- Linux arm64 is not yet published for the Homebrew package

Windows direct install:

Expand Down
2 changes: 2 additions & 0 deletions docs/crates-nodeup-foundation.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
- Binary entrypoints must force-link `swc_malloc` allocator policy, while the library target remains allocator-agnostic for downstream consumers.
- Shim dispatch behavior must remain deterministic by executable name (`node`, `npm`, `npx`, `yarn`, `pnpm`).
- Install/update command surfaces must preserve backward-compatible flags and outputs.
- Homebrew installation must consume prebuilt release archives for `darwin/amd64`, `darwin/arm64`, and `linux/amd64`; Linux arm64 must fail with a clear unsupported-platform message.
- `yarn`/`pnpm` delegated execution must honor nearest `package.json` `packageManager` when present.
- `packageManager` parsing contract is strict: `<manager>@<exact-semver>` with manager limited to `yarn|pnpm`.
- `packageManager` manager-command mismatch must fail with `conflict`; malformed values must fail with `invalid-input`.
Expand Down Expand Up @@ -52,6 +53,7 @@
- Workspace baseline: `cargo test --workspace --all-targets`
- Release contract checks should align with `release-nodeup` workflow expectations.
- Release assets must include both standalone prebuilt binaries (`nodeup-<os>-<arch>[.exe]`) and compressed archives (`nodeup-<os>-<arch>.tar.gz|zip`) for the supported release matrix.
- Homebrew release automation must render the prebuilt formula from release asset URLs and push tap updates directly to `delinoio/homebrew-tap` `main` with a dedicated tap-write credential.
- Completion coverage must include successful script generation, invalid shell/scope validation, and JSON-mode raw output behavior.
- Output color coverage must include flag/env precedence, invalid env fallback, stream-aware auto-mode behavior, and JSON/completion ANSI exclusion.
- `packageManager` coverage must include strict parsing, mismatch conflicts, yarn v1 vs v2+ mapping, direct-binary preference, and npm-exec fallback behavior.
Expand Down
1 change: 1 addition & 0 deletions docs/project-nodeup.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Provide a Rust-based Node.js version manager with predictable channel resolution
- Shell completion generation must remain deterministic for supported shells and top-level command scopes.
- Human output styling controls (`--color`, `NODEUP_COLOR`, and `NO_COLOR` precedence) must remain stable across CLI and public documentation.
- Release automation must publish both standalone prebuilt binaries and archive assets for the supported OS/architecture matrix.
- Homebrew installation must use prebuilt `nodeup` release archives for `darwin/amd64`, `darwin/arm64`, and `linux/amd64`, while failing clearly for unsupported Linux arm64 hosts.

## Change Policy
- Update this index and `docs/crates-nodeup-foundation.md` in the same change for behavior or storage contract updates.
Expand Down
2 changes: 1 addition & 1 deletion packaging/homebrew/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This directory contains Homebrew formula/cask templates rendered by `scripts/rel

Supported package identifiers:

- `nodeup`
- `nodeup` (prebuilt formula: `darwin/amd64`, `darwin/arm64`, `linux/amd64`)
- `derun`
- `dexdex-main-server` (prebuilt formula: `darwin/amd64`, `darwin/arm64`, `linux/amd64`)
- `dexdex-worker-server` (prebuilt formula: `darwin/amd64`, `darwin/arm64`, `linux/amd64`)
Expand Down
25 changes: 21 additions & 4 deletions packaging/homebrew/templates/nodeup.rb.tmpl
Original file line number Diff line number Diff line change
@@ -1,17 +1,34 @@
class Nodeup < Formula
desc "Rust-based Node.js version manager"
homepage "https://github.com/delinoio/oss"
url "__SOURCE_URL__"
sha256 "__SOURCE_SHA256__"
version "__VERSION__"
license "MIT"

depends_on "rust" => :build
on_macos do
if Hardware::CPU.intel?
url "__DARWIN_AMD64_URL__"
sha256 "__DARWIN_AMD64_SHA256__"
else
url "__DARWIN_ARM64_URL__"
sha256 "__DARWIN_ARM64_SHA256__"
end
end

on_linux do
if Hardware::CPU.intel?
url "__LINUX_AMD64_URL__"
sha256 "__LINUX_AMD64_SHA256__"
else
odie "nodeup prebuilt distribution currently supports Linux amd64 only"
end
end

def install
system "cargo", "install", "--locked", "--path", "crates/nodeup", "--root", prefix
bin.install "nodeup"
end

test do
assert_predicate bin/"nodeup", :exist?
assert_match version.to_s, shell_output("#{bin}/nodeup --version").strip
end
end
2 changes: 1 addition & 1 deletion scripts/release/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Release Automation Scripts

- `generate-checksums.sh`: produces `SHA256SUMS` and cosign signatures.
- `update-homebrew.sh`: renders and optionally submits Homebrew formula/cask updates (DexDex server formulas consume prebuilt multi-OS release artifacts). In non-dry-run mode, it sets a fixed local commit identity (`github-actions[bot] <github-actions@users.noreply.github.com>`) before creating the tap commit.
- `update-homebrew.sh`: renders and optionally pushes Homebrew formula/cask updates to the tap repository `main` branch (DexDex server formulas and nodeup consume prebuilt multi-OS release artifacts). In non-dry-run mode, it expects `HOMEBREW_TAP_GH_TOKEN` (or `GH_TOKEN`) with write access to the tap repository and sets a fixed local commit identity (`github-actions[bot] <github-actions@users.noreply.github.com>`) before creating the tap commit.

These scripts are designed for use by release workflows:

Expand Down
Loading
Loading