Skip to content
Closed
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
142 changes: 142 additions & 0 deletions .github/workflows/build-binaries.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
name: Build and Release Binaries

on:
push:
tags:
- 'v*'
workflow_dispatch:

jobs:
build:
strategy:
fail-fast: false
matrix:
settings:
- host: macos-latest
target: x86_64-apple-darwin
build: yarn build:rs --target x86_64-apple-darwin
- host: macos-latest
target: aarch64-apple-darwin
build: yarn build:rs --target aarch64-apple-darwin
- host: windows-latest
target: x86_64-pc-windows-msvc
build: yarn build:rs --target x86_64-pc-windows-msvc
- host: windows-latest
target: i686-pc-windows-msvc
build: yarn build:rs --target i686-pc-windows-msvc
- host: ubuntu-latest
target: x86_64-unknown-linux-gnu
build: yarn build:rs --target x86_64-unknown-linux-gnu
- host: ubuntu-latest
target: x86_64-unknown-linux-musl
build: |
sudo apt-get update
sudo apt-get install musl-tools
yarn build:rs --target x86_64-unknown-linux-musl
- host: ubuntu-latest
target: aarch64-unknown-linux-gnu
build: |
sudo apt-get update
sudo apt-get install gcc-aarch64-linux-gnu
yarn build:rs --target aarch64-unknown-linux-gnu
- host: ubuntu-latest
target: i686-unknown-linux-gnu
build: |
sudo apt-get update
sudo apt-get install gcc-multilib
yarn build:rs --target i686-unknown-linux-gnu
- host: ubuntu-latest
target: armv7-unknown-linux-gnueabihf
build: |
sudo apt-get update
sudo apt-get install gcc-arm-linux-gnueabihf
yarn build:rs --target armv7-unknown-linux-gnueabihf
- host: ubuntu-latest
target: x86_64-unknown-freebsd
build: yarn build:rs --target x86_64-unknown-freebsd

name: Build ${{ matrix.settings.target }}
runs-on: ${{ matrix.settings.host }}

steps:
- uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'yarn'

- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.settings.target }}

- name: Cache cargo
uses: actions/cache@v4
with:
path: |
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
.cargo-cache
target/
key: ${{ matrix.settings.target }}-cargo-${{ hashFiles('**/Cargo.lock') }}

- name: Install dependencies
run: yarn install --frozen-lockfile

- name: Build binary
run: ${{ matrix.settings.build }}

- name: Upload binary
uses: actions/upload-artifact@v4
with:
name: binaries-${{ matrix.settings.target }}
path: |
*.node
cjs/*.node
esm/*.node

release:
name: Create Release
runs-on: ubuntu-latest
needs: build
if: startsWith(github.ref, 'refs/tags/')

steps:
- uses: actions/checkout@v4

- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts

- name: Create Release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: Release ${{ github.ref }}
draft: false
prerelease: false

- name: Upload Release Assets
run: |
for dir in artifacts/binaries-*; do
target=$(basename "$dir" | sed 's/binaries-//')
for file in "$dir"/*.node; do
if [ -f "$file" ]; then
asset_name="idea-parser-${target}.node"
echo "Uploading $file as $asset_name"
curl \
-X POST \
-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
-H "Content-Type: application/octet-stream" \
--data-binary @"$file" \
"https://uploads.github.com/repos/${{ github.repository }}/releases/${{ steps.create_release.outputs.id }}/assets?name=$asset_name"
fi
done
done
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -149,4 +149,9 @@ packages/idea-language/server/package-lock.json
packages/idea-transformer/tests/out
.DS_Store

.clinerules
.clinerules
old/

#rust
target/
**/*.rs.bk
161 changes: 161 additions & 0 deletions docs/parser/Binaries.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
# Binary Distribution Strategy

This document explains how the Rust binaries are built and distributed for the `@stackpress/idea-parser` npm package.

## Overview

The package uses a hybrid approach for binary distribution:

1. **GitHub Actions** builds pre-compiled binaries for multiple platforms
2. **Postinstall script** downloads the appropriate binary for the user's platform
3. **Fallback to source compilation** if no pre-built binary is available

## Supported Platforms

The following platforms are supported with pre-built binaries:

- **macOS**:
- x86_64 (Intel)
- aarch64 (Apple Silicon)
- **Windows**:
- x86_64 (64-bit)
- i686 (32-bit)
- **Linux**:
- x86_64 (GNU)
- x86_64 (musl)
- aarch64 (ARM64)
- i686 (32-bit)
- armv7 (ARM)
- **FreeBSD**:
- x86_64

## How It Works

### 1. GitHub Actions Workflow

The `.github/workflows/build-binaries.yml` workflow:

- Triggers on version tags (`v*`) or manual dispatch
- Builds binaries for all supported platforms using a matrix strategy
- Uploads binaries as artifacts
- Creates a GitHub Release with all binaries attached

### 2. Postinstall Script

The `scripts/install.cjs` script:

- Detects the user's platform and architecture
- Maps it to the corresponding Rust target triple
- Attempts to download the pre-built binary from GitHub Releases
- Falls back to building from source if download fails
- Places the binary in the correct locations for both CJS and ESM builds

### 3. Platform Detection

The script maps Node.js platform/architecture to Rust target triples:

```javascript
const platformMap = {
'darwin': {
'x64': 'x86_64-apple-darwin',
'arm64': 'aarch64-apple-darwin'
},
'win32': {
'x64': 'x86_64-pc-windows-msvc',
'ia32': 'i686-pc-windows-msvc'
},
'linux': {
'x64': 'x86_64-unknown-linux-gnu',
'arm64': 'aarch64-unknown-linux-gnu',
'ia32': 'i686-unknown-linux-gnu',
'arm': 'armv7-unknown-linux-gnueabihf'
},
'freebsd': {
'x64': 'x86_64-unknown-freebsd'
}
};
```

## Release Process

To create a new release with binaries:

1. Update the version in `package.json`
2. Create and push a git tag:
```bash
git tag v0.6.3
git push origin v0.6.3
```
3. The GitHub Actions workflow will automatically:
- Build binaries for all platforms
- Create a GitHub Release
- Upload all binaries to the release

## Binary Naming Convention

Binaries are named using the pattern:
```
idea-parser-{target-triple}.node
```

Examples:
- `idea-parser-aarch64-apple-darwin.node`
- `idea-parser-x86_64-pc-windows-msvc.node`
- `idea-parser-x86_64-unknown-linux-gnu.node`

## Fallback Behavior

If a pre-built binary is not available for the user's platform:

1. The script will attempt to build from source using `yarn build:rs`
2. This requires the user to have:
- Rust toolchain installed
- Appropriate build tools for their platform
3. The build process uses the existing `napi` configuration

## Testing

To test the installation process:

```bash
# Test the postinstall script directly
node scripts/install.cjs

# Test with npm install (in a clean environment)
npm install
```

## Troubleshooting

### Binary Download Fails

If the binary download fails, check:
1. Internet connectivity
2. GitHub Releases page for the version
3. Binary exists for your platform

### Build from Source Fails

If building from source fails, ensure:
1. Rust is installed (`rustup` recommended)
2. Build tools are available:
- **Windows**: Visual Studio Build Tools
- **macOS**: Xcode Command Line Tools
- **Linux**: `build-essential` package

### Platform Not Supported

If your platform is not supported:
1. Check if it's in the platform map in `scripts/install.cjs`
2. Add support by updating the GitHub Actions workflow
3. Update the platform map in the install script

## Benefits

This approach provides:

- **Fast installation** for supported platforms (no compilation needed)
- **Broad compatibility** with fallback to source compilation
- **Automatic updates** when new versions are released
- **Reduced package size** (binaries hosted separately)
- **CI/CD integration** for consistent builds across platforms
19 changes: 8 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,15 @@
"example"
],
"scripts": {
"build": "yarn build:parser && yarn build:transformer && yarn build:idea && yarn build:example",
"build:parser": "yarn --cwd packages/idea-parser build",
"build:language": "yarn --cwd packages/idea-language build",
"build:transformer": "yarn --cwd packages/idea-transformer build",
"build:idea": "yarn --cwd packages/idea build",
"build:example": "yarn --cwd example build",
"report": "yarn report:env nyc yarn test && nyc report -r lcov",
"report:env": "NODE_OPTIONS=\"--disable-warning=ExperimentalWarning --experimental-loader @istanbuljs/esm-loader-hook\"",
"idea": "yarn --cwd packages/idea",
"parser": "yarn --cwd packages/idea-parser",
"transformer": "yarn --cwd packages/idea-transformer",
"example": "yarn --cwd example",
"build": "yarn parser build && yarn transformer build && yarn idea build && yarn example build",
"transform": "yarn --cwd example transform",
"test": "yarn test:parser && yarn test:transformer",
"test:parser": "yarn --cwd packages/idea-parser test",
"test:transformer": "yarn --cwd packages/idea-transformer test"
"test": "yarn parser test && yarn transformer test",
"report": "yarn report:env nyc yarn test && nyc report -r lcov",
"report:env": "NODE_OPTIONS=\"--disable-warning=ExperimentalWarning --experimental-loader @istanbuljs/esm-loader-hook\""
},
"devDependencies": {
"@istanbuljs/esm-loader-hook": "0.3.0",
Expand Down
Loading
Loading