diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 67bcab16..640af06c 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -107,14 +107,51 @@ jobs: name: bindings-${{ env.PLATFORM_NAME }} path: packages/*/*.${{ env.PLATFORM_NAME }}.node + build_musl: + if: "!contains(github.event.head_commit.message, 'skip ci')" + name: stable - linux-musl - node@12 + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - name: Login to registry + run: | + docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD $DOCKER_REGISTRY_URL + env: + DOCKER_REGISTRY_URL: docker.pkg.github.com + DOCKER_USERNAME: ${{ github.actor }} + DOCKER_PASSWORD: ${{ secrets.GITHUB_TOKEN }} + + - name: Pull docker image + run: | + docker pull docker.pkg.github.com/napi-rs/napi-rs/rust-nodejs-alpine:lts + docker tag docker.pkg.github.com/napi-rs/napi-rs/rust-nodejs-alpine:lts builder + + - name: 'Install dependencies' + run: yarn install --frozen-lockfile --registry https://registry.npmjs.org + + - name: 'Build' + run: | + docker run --rm -v $(pwd)/.cargo:/root/.cargo -v $(pwd):/node-rs -w /node-rs builder sh -c "cargo build --release" + docker run --rm -v $(pwd)/.cargo:/root/.cargo -v $(pwd):/node-rs -w /node-rs builder sh -c "./node_modules/.bin/lerna run build --stream -- --musl" + + - name: Upload artifact + uses: actions/upload-artifact@v2 + with: + name: bindings-musl + path: packages/*/*.musl.node + test_binding: name: Test bindings on ${{ matrix.os }} - node@${{ matrix.node }} - needs: lint_and_build + needs: + - lint_and_build + - build_musl strategy: fail-fast: false matrix: os: [ubuntu-latest, macos-latest, windows-latest] - node: ['10', '12', '13', '14'] + node: ['10', '12', '14'] runs-on: ${{ matrix.os }} steps: @@ -158,6 +195,45 @@ jobs: - name: Run benchmark run: yarn bench + test_musl_binding: + name: Test bindings on alpine - node@${{ matrix.node }} + needs: + - lint_and_build + - build_musl + strategy: + fail-fast: false + matrix: + node: ['10', '12', '14'] + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - name: Download artifacts + uses: actions/download-artifact@v2 + with: + name: bindings-musl + path: artifacts + + - name: Move artifacts + run: node scripts/mv-artifacts.js + shell: bash + env: + MOVE_TARGET: musl + + - name: List packages + run: ls -R packages + shell: bash + + - name: 'Install dependencies' + run: yarn install --frozen-lockfile --ignore-scripts --registry https://registry.npmjs.org + + - name: Build TypeScript + run: yarn build:ts + + - name: Run simple tests + run: docker run --rm -v $(pwd)/.cargo:/root/.cargo -v $(pwd):/node-rs -w /node-rs node:${{ matrix.node }}-alpine sh -c "./node_modules/.bin/lerna run test:simple --stream" + publish: name: Publish if: "startsWith(github.event.head_commit.message, 'chore(release): publish')" diff --git a/Cargo.toml b/Cargo.toml index 5e69e2d9..93fd9ed8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,3 +4,7 @@ members = [ "./packages/crc32", "./packages/jieba" ] + +[profile.release] +opt-level = 3 +lto = true diff --git a/README.md b/README.md index 86c30b51..e2e354c4 100644 --- a/README.md +++ b/README.md @@ -8,11 +8,11 @@ Make rust crates binding to NodeJS use [napi-rs](https://github.com/Brooooooklyn # Support matrix -| | node 10 | node12 | node13 | node14 | -| ----------------- | ------- | ------ | ------ | ------ | -| Windows 64 latest | ✅ | ✅ | ✅ | ✅ | -| macOS latest | ✅ | ✅ | ✅ | ✅ | -| Linux | ✅ | ✅ | ✅ | ✅ | +| | node 10 | node12 | node14 | +| ----------------- | ------- | ------ | ------ | +| Windows 64 latest | ✅ | ✅ | ✅ | +| macOS latest | ✅ | ✅ | ✅ | +| Linux | ✅ | ✅ | ✅ | # Packages diff --git a/package.json b/package.json index b3c6515f..dc88cd04 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "husky": "^4.2.5", "lerna": "^3.20.2", "lint-staged": "^10.1.7", - "napi-rs": "^0.2.3", + "napi-rs": "^0.2.4", "npm-run-all": "^4.1.5", "nyc": "^15.0.1", "prettier": "^2.0.5", diff --git a/packages/bcrypt/Cargo.toml b/packages/bcrypt/Cargo.toml index 5231ef9c..6f2d2aa4 100644 --- a/packages/bcrypt/Cargo.toml +++ b/packages/bcrypt/Cargo.toml @@ -16,7 +16,7 @@ napi-rs-derive = { version = "0.2" } rand = "0.7" phf = { version = "0.8", features = ["macros"] } -[target.'cfg(unix)'.dependencies] +[target.'cfg(all(unix, not(target_env = "musl")))'.dependencies] jemallocator = { version = "0.3", features = ["disable_initial_exec_tls"] } [dev-dependencies] diff --git a/packages/bcrypt/README.md b/packages/bcrypt/README.md index 9aeb7419..adc9b51b 100644 --- a/packages/bcrypt/README.md +++ b/packages/bcrypt/README.md @@ -6,11 +6,11 @@ ## Support matrix -| | node 10 | node12 | node13 | node14 | -| ----------------- | ------- | ------ | ------ | ------ | -| Windows 64 latest | ✓ | ✓ | ✓ | ✓ | -| macOS latest | ✓ | ✓ | ✓ | ✓ | -| Linux | ✓ | ✓ | ✓ | ✓ | +| | node 10 | node12 | node14 | +| ----------------- | ------- | ------ | ------ | +| Windows 64 latest | ✓ | ✓ | ✓ | +| macOS latest | ✓ | ✓ | ✓ | +| Linux | ✓ | ✓ | ✓ | ## Usage diff --git a/packages/bcrypt/index.js b/packages/bcrypt/index.js index e67d9098..817d2c01 100644 --- a/packages/bcrypt/index.js +++ b/packages/bcrypt/index.js @@ -1,6 +1,6 @@ -const { locateBinding } = require('@node-rs/helper') +const { loadBinding } = require('@node-rs/helper') -const binding = require(locateBinding(__dirname, 'bcrypt')) +const binding = loadBinding(__dirname, 'bcrypt') const DEFAULT_COST = 12 diff --git a/packages/bcrypt/package.json b/packages/bcrypt/package.json index 96c6c40f..60e78de2 100644 --- a/packages/bcrypt/package.json +++ b/packages/bcrypt/package.json @@ -24,7 +24,8 @@ "scripts": { "bench": "cross-env NODE_ENV=production node benchmark/bcrypt.js", "build": "napi --release ./bcrypt", - "build:debug": "napi ./bcrypt.debug" + "build:debug": "napi ./bcrypt.debug", + "test:simple": "node ./simple-test.js" }, "bugs": { "url": "https://github.com/Brooooooklyn/node-rs/issues" diff --git a/packages/bcrypt/simple-test.js b/packages/bcrypt/simple-test.js new file mode 100644 index 00000000..323b72cc --- /dev/null +++ b/packages/bcrypt/simple-test.js @@ -0,0 +1,3 @@ +const { verifySync } = require('./index') + +console.assert(verifySync('hello', '$2b$12$k4V9p7YpSYHY05bORujyyeesfPaWNQfPkjVzETFGfozAN/fH0LtdG')) diff --git a/packages/bcrypt/src/lib.rs b/packages/bcrypt/src/lib.rs index 01e3e6d1..1ad8fc56 100644 --- a/packages/bcrypt/src/lib.rs +++ b/packages/bcrypt/src/lib.rs @@ -15,7 +15,7 @@ use verify_task::VerifyTask; mod hash_task; mod verify_task; -#[cfg(unix)] +#[cfg(all(unix, not(target_env = "musl")))] #[global_allocator] static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc; diff --git a/packages/crc32/Cargo.toml b/packages/crc32/Cargo.toml index bb502ae5..45837e75 100644 --- a/packages/crc32/Cargo.toml +++ b/packages/crc32/Cargo.toml @@ -12,7 +12,7 @@ napi-rs = { version = "0.3" } napi-rs-derive = { version = "0.2" } crc32fast = "1.2" -[target.'cfg(unix)'.dependencies] +[target.'cfg(all(unix, not(target_env = "musl")))'.dependencies] jemallocator = { version = "0.3", features = ["disable_initial_exec_tls"] } [build-dependencies] diff --git a/packages/crc32/README.md b/packages/crc32/README.md index 7bf0d84d..ea188721 100644 --- a/packages/crc32/README.md +++ b/packages/crc32/README.md @@ -41,11 +41,11 @@ js_crc32 for inputs 16931844B, avg 2066B x 22.12 ops/sec ±5.20% (40 runs sample ## Support matrix -| | node 10 | node12 | node13 | node14 | -| ----------------- | ------- | ------ | ------ | ------ | -| Windows 64 latest | ✓ | ✓ | ✓ | ✓ | -| macOS latest | ✓ | ✓ | ✓ | ✓ | -| Linux | ✓ | ✓ | ✓ | ✓ | +| | node 10 | node12 | node14 | +| ----------------- | ------- | ------ | ------ | +| Windows 64 latest | ✓ | ✓ | ✓ | +| macOS latest | ✓ | ✓ | ✓ | +| Linux | ✓ | ✓ | ✓ | ## API diff --git a/packages/crc32/index.js b/packages/crc32/index.js index 1f7b714b..66c8f254 100644 --- a/packages/crc32/index.js +++ b/packages/crc32/index.js @@ -1,6 +1,6 @@ -const { locateBinding } = require('@node-rs/helper') +const { loadBinding } = require('@node-rs/helper') -const binding = require(locateBinding(__dirname, 'crc32')) +const binding = loadBinding(__dirname, 'crc32') module.exports = { crc32: function crc32(input, crc) { diff --git a/packages/crc32/package.json b/packages/crc32/package.json index eb30c23a..b1baf9a4 100644 --- a/packages/crc32/package.json +++ b/packages/crc32/package.json @@ -24,7 +24,8 @@ "scripts": { "bench": "cross-env NODE_ENV=production node benchmark/crc32.js", "build": "napi --release ./crc32", - "build:debug": "napi ./index" + "build:debug": "napi ./index", + "test:simple": "node ./simple-test.js" }, "bugs": { "url": "https://github.com/Brooooooklyn/node-rs/issues" diff --git a/packages/crc32/simple-test.js b/packages/crc32/simple-test.js new file mode 100644 index 00000000..6768bad8 --- /dev/null +++ b/packages/crc32/simple-test.js @@ -0,0 +1,3 @@ +const { crc32 } = require('./index') + +console.assert(crc32('hello') === '907060870') diff --git a/packages/crc32/src/lib.rs b/packages/crc32/src/lib.rs index 98d40d1a..ec9bfa4d 100644 --- a/packages/crc32/src/lib.rs +++ b/packages/crc32/src/lib.rs @@ -8,7 +8,7 @@ use crc32fast::Hasher; use napi::{Buffer, CallContext, Env, Number, Object, Result, Value}; use std::convert::TryInto; -#[cfg(unix)] +#[cfg(all(unix, not(target_env = "musl")))] #[global_allocator] static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc; diff --git a/packages/helper/src/index.ts b/packages/helper/src/index.ts index f86c68b9..5875f615 100644 --- a/packages/helper/src/index.ts +++ b/packages/helper/src/index.ts @@ -1 +1 @@ -export { locateBinding } from './loader' +export { loadBinding } from './loader' diff --git a/packages/helper/src/loader.ts b/packages/helper/src/loader.ts index 0edfd213..f8d26e6b 100644 --- a/packages/helper/src/loader.ts +++ b/packages/helper/src/loader.ts @@ -4,7 +4,7 @@ import { join } from 'path' const SupportedPlatforms = new Set(['darwin', 'win32', 'linux']) -export function locateBinding(dirname: string, filename = 'index') { +export function loadBinding(dirname: string, filename = 'index') { const platformName = platform() if (!SupportedPlatforms.has(platformName)) { throw new TypeError( @@ -14,9 +14,17 @@ export function locateBinding(dirname: string, filename = 'index') { const bindingFilePath = join(dirname, `${filename}.${platformName}.node`) + if (platformName === 'linux') { + try { + return require(bindingFilePath) + } catch { + return require(join(dirname, `${filename}.musl.node`)) + } + } + if (!existsSync(bindingFilePath)) { throw new TypeError(`Could not find binding file on path ${bindingFilePath}`) } - return bindingFilePath + return require(bindingFilePath) } diff --git a/packages/jieba/Cargo.toml b/packages/jieba/Cargo.toml index 4687c25d..ce54cd8a 100644 --- a/packages/jieba/Cargo.toml +++ b/packages/jieba/Cargo.toml @@ -13,7 +13,7 @@ napi-rs = { version = "0.3" } napi-rs-derive = { version = "0.2" } once_cell = "1.3" -[target.'cfg(unix)'.dependencies] +[target.'cfg(all(unix, not(target_env = "musl")))'.dependencies] jemallocator = { version = "0.3", features = ["disable_initial_exec_tls"] } [build-dependencies] diff --git a/packages/jieba/README.md b/packages/jieba/README.md index 5a52cdca..1dc0ad63 100644 --- a/packages/jieba/README.md +++ b/packages/jieba/README.md @@ -32,11 +32,11 @@ Tag 246568 words bench suite: Fastest is @node-rs/jieba ## Support matrix -| | node 10 | node12 | node13 | node14 | -| ----------------- | ------- | ------ | ------ | ------ | -| Windows 64 latest | ✓ | ✓ | ✓ | ✓ | -| macOS latest | ✓ | ✓ | ✓ | ✓ | -| Linux | ✓ | ✓ | ✓ | ✓ | +| | node 10 | node12 | node14 | +| ----------------- | ------- | ------ | ------ | +| Windows 64 latest | ✓ | ✓ | ✓ | +| macOS latest | ✓ | ✓ | ✓ | +| Linux | ✓ | ✓ | ✓ | ## Usage diff --git a/packages/jieba/index.js b/packages/jieba/index.js index 0000a766..bd74c88c 100644 --- a/packages/jieba/index.js +++ b/packages/jieba/index.js @@ -1,6 +1,6 @@ -const { locateBinding } = require('@node-rs/helper') +const { loadBinding } = require('@node-rs/helper') -const native = require(locateBinding(__dirname, 'jieba')) +const native = loadBinding(__dirname, 'jieba') module.exports = { ...native, diff --git a/packages/jieba/package.json b/packages/jieba/package.json index af895123..2862e813 100644 --- a/packages/jieba/package.json +++ b/packages/jieba/package.json @@ -24,7 +24,8 @@ "scripts": { "bench": "cross-env NODE_ENV=production node benchmark/jieba.js", "build": "napi --release ./jieba", - "build:debug": "napi ./jieba" + "build:debug": "napi ./jieba", + "test:simple": "node ./simple-test.js" }, "bugs": { "url": "https://github.com/Brooooooklyn/node-rs/issues" diff --git a/packages/jieba/simple-test.js b/packages/jieba/simple-test.js new file mode 100644 index 00000000..80747ede --- /dev/null +++ b/packages/jieba/simple-test.js @@ -0,0 +1,6 @@ +const { cut } = require('./index') + +const [first, second] = cut('武汉市长江大桥') + +console.assert(first === '武汉市') +console.assert(second === '长江大桥') diff --git a/packages/jieba/src/lib.rs b/packages/jieba/src/lib.rs index 3223774b..5225be42 100644 --- a/packages/jieba/src/lib.rs +++ b/packages/jieba/src/lib.rs @@ -12,7 +12,7 @@ use once_cell::sync::OnceCell; use std::convert::TryInto; use std::str; -#[cfg(unix)] +#[cfg(all(unix, not(target_env = "musl")))] #[global_allocator] static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc; diff --git a/scripts/mv-artifacts.js b/scripts/mv-artifacts.js index e2b018a1..c566d3a9 100644 --- a/scripts/mv-artifacts.js +++ b/scripts/mv-artifacts.js @@ -8,7 +8,7 @@ const supporttedPlatforms = require('./platforms') const MOVE_ALL = process.env.MOVE_TARGET === 'all' -const platforms = MOVE_ALL ? supporttedPlatforms : [platform()] +const platforms = MOVE_ALL ? supporttedPlatforms : [process.env.MOVE_TARGET || platform()] /** * @param {string[]} _platforms platforms diff --git a/scripts/platforms.js b/scripts/platforms.js index 46347d51..a9a4c362 100644 --- a/scripts/platforms.js +++ b/scripts/platforms.js @@ -1 +1 @@ -module.exports = ['linux', 'darwin', 'win32'] +module.exports = ['linux', 'musl', 'darwin', 'win32'] diff --git a/yarn.lock b/yarn.lock index 1fcd9ef3..4b476234 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5215,10 +5215,10 @@ nanomatch@^1.2.9: snapdragon "^0.8.1" to-regex "^3.0.1" -napi-rs@^0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/napi-rs/-/napi-rs-0.2.3.tgz#808e14fd4ff39f91b619d5ca42cc4ae7d762d73d" - integrity sha512-F+VNgo7uxUyB2DyCtMAPZT0r06jipFD89nnn1mkEvVsaC5p05Pwz78sd9Jz/NN2tC2FT7PlsY5Ep6EB0VY6C5Q== +napi-rs@^0.2.4: + version "0.2.4" + resolved "https://registry.yarnpkg.com/napi-rs/-/napi-rs-0.2.4.tgz#81efcbb04ccc43e4e2713bfb9d1bad79b4ee8a7e" + integrity sha512-xJtETX+08wI0eQdvZRqumOxYlW5dyALCrK12N5h2UaiNMrVXlNDGTmpq274SotP8WZFVc/FB/uewtwGv58oa7Q== dependencies: minimist "^1.2.5" toml "^3.0.0" @@ -7349,7 +7349,7 @@ to-regex@^3.0.1, to-regex@^3.0.2: toml@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz#342160f1af1904ec9d204d03a5d61222d762c5ee" + resolved "https://registry.yarnpkg.com/toml/-/toml-3.0.0.tgz#342160f1af1904ec9d204d03a5d61222d762c5ee" integrity sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w== tough-cookie@~2.5.0: