diff --git a/.cirrus.yml b/.cirrus.yml index 843b7d0c..9e417e12 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -4,70 +4,184 @@ env: BUILD_TEST_TASK_TEMPLATE: &BUILD_TEST_TASK_TEMPLATE arch_check_script: - uname -am - test_script: + prebuild_script: + - node --version + - chmod +x script/**/* && chmod +x script/** + - script/download-libs.sh + - npm ci --ignore-scripts + - npx prebuildify --napi + - tar -czf prebuilds.tar.gz prebuilds + - ls + - rm -rf ffi build + test_20_script: + - ls + - node --version + - script/ci/build-and-test.sh + - ls + - npm run clean + - rm -rf node_modules + - ls + test_18_script: + - . $NVM_DIR/nvm.sh + - nvm install 18 + - nvm use 18 - node --version - script/ci/build-and-test.sh + - ls + - npm run clean + - rm -rf node_modules + - ls + test_16_script: + - . $NVM_DIR/nvm.sh + - nvm install 18 + - nvm use 18 + - node --version + - script/ci/build-and-test.sh + - ls + - npm run clean + - rm -rf node_modules + - ls linux_arm64_task: env: - matrix: - - IMAGE: node:16-slim - - IMAGE: node:18-slim - - IMAGE: node:20-slim + NVM_DIR: /usr/local/nvm arm_container: - image: $IMAGE + image: node:20-slim install_script: - apt update --yes && apt install --yes curl python3 make build-essential g++ unzip zip + - curl --silent -o- https://raw.githubusercontent.com/creationix/nvm/v0.31.2/install.sh | bash << : *BUILD_TEST_TASK_TEMPLATE + artifacts: + path: "prebuilds.tar.gz" linux_amd64_task: env: - matrix: - - IMAGE: node:16-slim - - IMAGE: node:18-slim - - IMAGE: node:20-slim + NVM_DIR: /usr/local/nvm container: - image: $IMAGE + image: node:20-slim install_script: - - apt update --yes && apt install --yes curl python3 make build-essential g++ unzip zip + - apt update --yes && apt install --yes curl python3 make build-essential g++ unzip zip + - curl --silent -o- https://raw.githubusercontent.com/creationix/nvm/v0.31.2/install.sh | bash << : *BUILD_TEST_TASK_TEMPLATE + artifacts: + path: "prebuilds.tar.gz" -mac_arm64_task: +macos_arm_prebuilder_task: macos_instance: image: ghcr.io/cirruslabs/macos-ventura-base:latest env: PACT_BROKER_FEATURES: publish_pacts_using_old_api - NVS_HOME: ${HOME}/.nvs - PATH: ${NVS_HOME}:${PATH} - matrix: - - NODE_VERSION: 16 - - NODE_VERSION: 18 - - NODE_VERSION: 20 - install_script: + NVM_DIR: ${HOME}/.nvm + PATH: ${NVM_DIR}:${PATH} + install_node_script: - brew install nvm - - source $(brew --prefix nvm)/nvm.sh - - nvm install $NODE_VERSION - - nvm use $NODE_VERSION - << : *BUILD_TEST_TASK_TEMPLATE + - . $(brew --prefix nvm)/nvm.sh + - nvm install 20 + - nvm install 18 + - nvm install 16 + prebuild_script: + - . $(brew --prefix nvm)/nvm.sh + - nvm use 20 + - node --version + - chmod +x script/**/* && chmod +x script/** + - script/download-libs.sh + - npm ci --ignore-scripts + - npx prebuildify --napi + - tar -czf prebuilds.tar.gz prebuilds + - ls + - rm -rf ffi build + test_20_script: + - . $(brew --prefix nvm)/nvm.sh + - nvm use 20 + - node --version + - script/ci/build-and-test.sh + - ls + - npm run clean + - rm -rf node_modules + - ls + test_18_script: + - . $(brew --prefix nvm)/nvm.sh + - nvm use 18 + - node --version + - script/ci/build-and-test.sh + - ls + - npm run clean + - rm -rf node_modules + - ls + test_16_script: + - . $(brew --prefix nvm)/nvm.sh + - nvm use 16 + - node --version + - script/ci/build-and-test.sh + - ls + - npm run clean + - rm -rf node_modules + - ls + artifacts: + path: "prebuilds.tar.gz" -mac_rosetta_task: +macos_x64_prebuilder_task: macos_instance: image: ghcr.io/cirruslabs/macos-ventura-base:latest env: + PACT_BROKER_FEATURES: publish_pacts_using_old_api NVS_HOME: ${HOME}/.nvs PATH: ${NVS_HOME}:${PATH} - matrix: - - NODE_VERSION: 16 - - NODE_VERSION: 18 - - NODE_VERSION: 20 - install nvs_script: | + install_nvs_script: | git clone https://github.com/jasongin/nvs "$NVS_HOME" . "$NVS_HOME/nvs.sh" install install_rosetta_script: softwareupdate --install-rosetta --agree-to-license - install_x64_script: | + install_node_x64_script: | . "$NVS_HOME/nvs.sh" - nvs add $NODE_VERSION/x64 - nvs use $NODE_VERSION/x64 + nvs add 20/x64 + nvs add 18/x64 + nvs add 16/x64 + nvs use 20/x64 file $(which node) | grep -e 'x64' node --version - << : *BUILD_TEST_TASK_TEMPLATE + prebuild_script: + - ls + - . "$NVS_HOME/nvs.sh" + - nvs use 20/x64 + - file $(which node) | grep -e 'x64' + - node --version + - chmod +x script/**/* && chmod +x script/** + - script/download-libs.sh + - npm ci --ignore-scripts + - npx prebuildify --napi + - tar -czf prebuilds.tar.gz prebuilds + - ls + - rm -rf ffi build + test_20_script: + - . "$NVS_HOME/nvs.sh" + - nvs use 20/x64 + - file $(which node) | grep -e 'x64' + - node --version + - ls + - script/ci/build-and-test.sh + - ls + - npm run clean + - rm -rf node_modules + - ls + test_18_script: + - . "$NVS_HOME/nvs.sh" + - nvs use 18/x64 + - file $(which node) | grep -e 'x64' + - node --version + - script/ci/build-and-test.sh + - ls + - npm run clean + - rm -rf node_modules + - ls + test_16_script: + - . "$NVS_HOME/nvs.sh" + - nvs use 16/x64 + - file $(which node) | grep -e 'x64' + - node --version + - script/ci/build-and-test.sh + - ls + - npm run clean + - rm -rf node_modules + - ls + artifacts: + path: "prebuilds.tar.gz" \ No newline at end of file diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index 6110a456..2ca05a68 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -7,8 +7,45 @@ on: workflow_dispatch: jobs: - build-and-test-osx: + build: runs-on: ${{ matrix.os }} + defaults: + run: + shell: bash + strategy: + fail-fast: false + matrix: + node-version: [20] + os: [macos-latest,ubuntu-latest,windows-latest] + + steps: + - uses: actions/checkout@v3 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }} + - name: download-libs + if: runner.os != 'Windows' + run: script/download-libs.sh + - name: download-libs + if: runner.os == 'Windows' + run: script/download-libs.sh + env: + ONLY_DOWNLOAD_PACT_FOR_WINDOWS: true + - name: generate prebuild + run: | + npm ci --ignore-scripts + npx prebuildify --napi + tar -czf prebuilds-${{ runner.os }}.tar.gz prebuilds + ls + - name: Upload standalone packages + uses: actions/upload-artifact@v3 + with: + name: prebuilds-${{ runner.os }}.tar.gz + path: prebuilds-${{ runner.os }}.tar.gz + test: + runs-on: ${{ matrix.os }} + needs: [build] defaults: run: shell: bash @@ -20,10 +57,24 @@ jobs: steps: - uses: actions/checkout@v3 + - name: Download all workflow run artifacts + uses: actions/download-artifact@v3 + with: + name: prebuilds-${{ runner.os }}.tar.gz + - name: process packaged artifact + run: tar xvf prebuilds-${{ runner.os }}.tar.gz - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-version }} + - name: download-libs + if: runner.os != 'Windows' + run: script/download-libs.sh + - name: download-libs + if: runner.os == 'Windows' + run: script/download-libs.sh + env: + ONLY_DOWNLOAD_PACT_FOR_WINDOWS: true - run: script/ci/build-and-test.sh if: runner.os != 'Windows' env: diff --git a/.gitignore b/.gitignore index 1b5ddb5d..a3f4e552 100644 --- a/.gitignore +++ b/.gitignore @@ -58,7 +58,9 @@ standalone/* !standalone/*.ts standalone/*.d.ts ffi/* +!src/ffi !ffi/README.md +prebuilds # Folders created during testing log diff --git a/.npmignore b/.npmignore index b65f4840..a6eb2a54 100644 --- a/.npmignore +++ b/.npmignore @@ -79,3 +79,7 @@ test # release scripts script + +# FFI binaries +ffi +!prebuilds \ No newline at end of file diff --git a/binding.gyp b/binding.gyp index 80b6ad26..bb0c7998 100644 --- a/binding.gyp +++ b/binding.gyp @@ -28,7 +28,11 @@ "VCCLCompilerTool": { "ExceptionHandling": 1 } - } + }, + "copies":[{ + "files": [ "<(module_root_dir)/ffi/pact_ffi.dll"], + "destination": "<(PRODUCT_DIR)" + }], } ], [ @@ -47,7 +51,11 @@ "-L<(module_root_dir)/ffi", "-Wl,-rpath,@loader_path" ] - } + }, + "copies":[{ + "files": [ "<(module_root_dir)/ffi/libpact_ffi.dylib"], + "destination": "<(PRODUCT_DIR)" + }], } ], [ @@ -63,10 +71,14 @@ "link_settings": { "libraries": [ "-lpact_ffi", - "-L<(module_root_dir)/ffi/osxaarch64", - "-Wl,-rpath,@loader_path/osxaarch64" + "-L<(module_root_dir)/ffi", + "-Wl,-rpath,@loader_path" ] - } + }, + "copies":[{ + "files": [ "<(module_root_dir)/ffi/osxaarch64/libpact_ffi.dylib"], + "destination": "<(PRODUCT_DIR)" + }], } ], [ @@ -78,7 +90,11 @@ "-L<(module_root_dir)/ffi", "-Wl,-rpath,'$$ORIGIN'" ] - } + }, + "copies":[{ + "files": [ "<(module_root_dir)/ffi/libpact_ffi.so"], + "destination": "<(PRODUCT_DIR)" + }], } ], [ @@ -88,9 +104,13 @@ "libraries": [ "-lpact_ffi", "-L<(module_root_dir)/ffi/linuxaarch64", - "-Wl,-rpath,'$$ORIGIN'/linuxaarch64" + "-Wl,-rpath,'$$ORIGIN'" ] - } + }, + "copies":[{ + "files": [ "<(module_root_dir)/ffi/linuxaarch64/libpact_ffi.so"], + "destination": "<(PRODUCT_DIR)" + }], } ] ], @@ -105,39 +125,10 @@ "NAPI_CPP_EXCEPTIONS" ] }, - # Copy the shared libraries into the build/Release folder for distribution - { - "target_name": "copy_release_artifacts", - "dependencies": ["pact"], - "type": "none", - "copies": [ - { - # must use module_root_dir here, because it uses proper windows paths - "files": [ - "<(module_root_dir)/ffi/libpact_ffi.dylib", - "<(module_root_dir)/ffi/libpact_ffi.so", - "<(module_root_dir)/ffi/pact_ffi.dll", - ], - "destination": "<(PRODUCT_DIR)" - }, - { - "files": [ - "<(module_root_dir)/ffi/osxaarch64/libpact_ffi.dylib", - ], - "destination": "<(PRODUCT_DIR)/osxaarch64" - }, - { - "files": [ - "<(module_root_dir)/ffi/linuxaarch64/libpact_ffi.so", - ], - "destination": "<(PRODUCT_DIR)/linuxaarch64" - } - ] - }, # Need to set the library install name to enable the rpath settings to work on OSX { "target_name": "set_osx_install_name", - "dependencies": ["pact", "copy_release_artifacts"], + "dependencies": ["pact"], "type": "none", "target_conditions":[ [ diff --git a/package-lock.json b/package-lock.json index 36a79f45..11a70423 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,7 +26,8 @@ "cross-spawn": "7.0.3", "mkdirp": "1.0.0", "needle": "^3.2.0", - "node-addon-api": "^4.2.0", + "node-addon-api": "^6.1.0", + "node-gyp-build": "^4.6.0", "pino": "^8.7.0", "pino-pretty": "^9.1.1", "promise-timeout": "1.3.0", @@ -5616,9 +5617,19 @@ } }, "node_modules/node-addon-api": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", - "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==" + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz", + "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==" + }, + "node_modules/node-gyp-build": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz", + "integrity": "sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } }, "node_modules/nodemon": { "version": "2.0.20", @@ -11866,9 +11877,14 @@ } }, "node-addon-api": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", - "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==" + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz", + "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==" + }, + "node-gyp-build": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz", + "integrity": "sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==" }, "nodemon": { "version": "2.0.20", diff --git a/package.json b/package.json index a0161b33..d5f59e64 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,8 @@ "cross-spawn": "7.0.3", "mkdirp": "1.0.0", "needle": "^3.2.0", - "node-addon-api": "^4.2.0", + "node-addon-api": "^6.1.0", + "node-gyp-build": "^4.6.0", "pino": "^8.7.0", "pino-pretty": "^9.1.1", "promise-timeout": "1.3.0", @@ -126,7 +127,8 @@ "clean": "rimraf '{src,test,bin,standalone}/**/*.{js,map,d.ts}' 'package.zip' '.tmp' 'tmp'", "lint": "eslint . --ext .ts --config .eslintrc", "lint:fix": "npm run lint -- --fix", - "prebuild": "npm run clean && bash script/download-libs.sh", + "prebuild": "npm run clean", + "download:libs": "npm run clean && bash script/download-libs.sh", "build": "tsc --project tsconfig.build.json", "prerelease": "npm run snyk-protect", "release": "commit-and-tag-version", @@ -135,8 +137,7 @@ "format:base": "prettier --parser typescript", "format:check": "npm run format:base -- --list-different \"{src,standalone,bin,test}/**/*.{ts,tsx}\"", "format:fix": "npm run format:base -- --write \"{src,standalone,bin,test}/**/*.{ts,tsx}\"", - "postinstall": "npm run native", - "native": "node-gyp rebuild -v" + "install": "node-gyp-build" }, "prettier": "@pact-foundation/pact-js-prettier-config", "commit-and-tag-version": { diff --git a/script/ci/build-and-test.sh b/script/ci/build-and-test.sh index 7d5e330c..704c0b7f 100755 --- a/script/ci/build-and-test.sh +++ b/script/ci/build-and-test.sh @@ -5,8 +5,7 @@ set -u SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")"; pwd)" # Figure out where the script is running . "$SCRIPT_DIR"/../lib/robust-bash.sh -bash script/download-libs.sh -npm ci +npm ci --ignore-scripts npm run format:check npm run lint diff --git a/src/ffi/index.ts b/src/ffi/index.ts index 82074441..8c629ae6 100644 --- a/src/ffi/index.ts +++ b/src/ffi/index.ts @@ -1,9 +1,10 @@ -import bindings = require('bindings'); +import path from 'path'; import logger, { DEFAULT_LOG_LEVEL } from '../logger'; import { LogLevel } from '../logger/types'; import { Ffi } from './types'; -const ffiLib: Ffi = bindings('pact.node'); +// eslint-disable-next-line @typescript-eslint/no-var-requires +const ffiLib: Ffi = require('node-gyp-build')(path.join(__dirname, '..', '..')); export const PACT_FFI_VERSION = '0.4.0';