diff --git a/.github/workflows/codesee-arch-diagram.yml b/.github/workflows/codesee-arch-diagram.yml index 0b75778..fe56ca3 100644 --- a/.github/workflows/codesee-arch-diagram.yml +++ b/.github/workflows/codesee-arch-diagram.yml @@ -54,13 +54,19 @@ jobs: with: ruby-version: '3.0' - # CodeSee Maps Rust support uses a static binary so there's no setup step required. + # We need the rust toolchain because it uses rustc and cargo to inspect the package + - name: Configure Rust 1.x stable + uses: actions-rs/toolchain@v1 + if: ${{ fromJSON(steps.detect-languages.outputs.languages).rust }} + with: + toolchain: stable - name: Generate Map id: generate-map uses: Codesee-io/codesee-map-action@latest with: step: map + api_token: ${{ secrets.CODESEE_ARCH_DIAG_API_TOKEN }} github_ref: ${{ github.ref }} languages: ${{ steps.detect-languages.outputs.languages }} @@ -71,7 +77,7 @@ jobs: step: mapUpload api_token: ${{ secrets.CODESEE_ARCH_DIAG_API_TOKEN }} github_ref: ${{ github.ref }} - + - name: Insights id: insights uses: Codesee-io/codesee-map-action@latest diff --git a/.gitignore b/.gitignore index ef0d174..84856b0 100644 --- a/.gitignore +++ b/.gitignore @@ -2,8 +2,13 @@ /dist .env* !.env.example +# nix /result* /builds +# node-gyp +/build +# prebuildify +/prebuilds # Logs logs diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 2a33158..75bbe2f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,51 +1,269 @@ +workflow: + rules: + # Disable merge request pipelines + - if: $CI_MERGE_REQUEST_ID + when: never + - when: always + default: interruptible: true variables: GIT_SUBMODULE_STRATEGY: recursive + # Cache .npm + NPM_CONFIG_CACHE: "${CI_PROJECT_DIR}/tmp/npm" + # Prefer offline node module installation + NPM_CONFIG_PREFER_OFFLINE: "true" + # `ts-node` has its own cache + TS_CACHED_TRANSPILE_CACHE: "${CI_PROJECT_DIR}/tmp/ts-node-cache" + TS_CACHED_TRANSPILE_PORTABLE: "true" + # Homebrew cache only used by macos runner + HOMEBREW_CACHE: "${CI_PROJECT_DIR}/tmp/Homebrew" + +# Cached directories shared between jobs & pipelines per-branch per-runner +cache: + key: $CI_COMMIT_REF_SLUG + paths: + - ./tmp/npm/ + - ./tmp/ts-node-cache/ + # Homebrew cache is only used by the macos runner + - ./tmp/Homebrew + # `jest` cache is configured in jest.config.js + - ./tmp/jest/ stages: - - check - - build - - quality - - release + - check # Linting, unit tests + - build # Cross-platform library compilation, unit tests + - integration # Cross-platform application bundling, integration tests, and pre-release + - release # Cross-platform distribution and deployment + +image: registry.gitlab.com/matrixai/engineering/maintenance/gitlab-runner -lint: +check:lint: stage: check - image: registry.gitlab.com/matrixai/engineering/maintenance/gitlab-runner + needs: [] script: - > - nix-shell -I nixpkgs=./pkgs.nix --packages nodejs --run ' - npm install; + nix-shell --run ' npm run lint; ' + rules: + # Runs on feature and staging commits and ignores version commits + - if: $CI_COMMIT_BRANCH =~ /^(?:feature.*|staging)$/ && $CI_COMMIT_TITLE !~ /^[0-9]+\.[0-9]+\.[0-9]+(?:-.*[0-9]+)?$/ + # Runs on tag pipeline where the tag is a prerelease or release version + - if: $CI_COMMIT_TAG =~ /^v[0-9]+\.[0-9]+\.[0-9]+(?:-.*[0-9]+)?$/ + # Manually run on commits other than master and ignore version commits + - if: $CI_COMMIT_BRANCH && $CI_COMMIT_BRANCH != 'master' && $CI_COMMIT_TITLE !~ /^[0-9]+\.[0-9]+\.[0-9]+(?:-.*[0-9]+)?$/ + when: manual -test: +check:nix-dry: stage: check - image: registry.gitlab.com/matrixai/engineering/maintenance/gitlab-runner + needs: [] + script: + - nix-build -v -v --dry-run ./release.nix + rules: + # Runs on feature and staging commits and ignores version commits + - if: $CI_COMMIT_BRANCH =~ /^(?:feature.*|staging)$/ && $CI_COMMIT_TITLE !~ /^[0-9]+\.[0-9]+\.[0-9]+(?:-.*[0-9]+)?$/ + # Runs on tag pipeline where the tag is a prerelease or release version + - if: $CI_COMMIT_TAG =~ /^v[0-9]+\.[0-9]+\.[0-9]+(?:-.*[0-9]+)?$/ + # Manually run on commits other than master and ignore version commits + - if: $CI_COMMIT_BRANCH && $CI_COMMIT_BRANCH != 'master' && $CI_COMMIT_TITLE !~ /^[0-9]+\.[0-9]+\.[0-9]+(?:-.*[0-9]+)?$/ + when: manual + +check:test: + stage: check + needs: [] script: - > - nix-shell -I nixpkgs=./pkgs.nix --packages nodejs --run ' - npm install; - npm run test; + nix-shell --run ' + npm run build --verbose; + npm test -- --ci; ' + artifacts: + when: always + reports: + junit: + - ./tmp/junit.xml + rules: + # Runs on staging commits and ignores version commits + - if: $CI_COMMIT_BRANCH =~ /^feature.*$/ && $CI_COMMIT_TITLE !~ /^[0-9]+\.[0-9]+\.[0-9]+(?:-.*[0-9]+)?$/ + # Manually run on commits other than master and staging and ignore version commits + - if: $CI_COMMIT_BRANCH && $CI_COMMIT_BRANCH !~ /^(?:master|staging)$/ && $CI_COMMIT_TITLE !~ /^[0-9]+\.[0-9]+\.[0-9]+(?:-.*[0-9]+)?$/ + when: manual -nix-dry: - stage: check - image: registry.gitlab.com/matrixai/engineering/maintenance/gitlab-runner +build:merge: + stage: build + needs: [] + # Don't interrupt publishing job + interruptible: false + allow_failure: true + script: + - > + nix-shell -I nixpkgs=./pkgs.nix --packages git gitAndTools.gh --run ' + if [ ! gh pr view staging --repo MatrixAI/TypeScript-Demo-Lib-Native >/dev/null 2>/dev/null ]; then + gh pr create \ + --head staging \ + --base master \ + --title 'Merge staging to master' \ + --fill \ + --assignee '@me' \ + --no-maintainer-edit \ + --repo MatrixAI/TypeScript-Demo-Lib-Native; + fi; + gh pr merge staging \ + --auto \ + --repo MatrixAI/TypeScript-Demo-Lib-Native; + ' + rules: + # Runs on staging commits + - if: $CI_COMMIT_BRANCH == 'staging' + +build:linux: + stage: build + needs: + - job: check:lint + optional: true + script: + - > + nix-shell --run ' + npm run build --verbose; + npm test -- --ci; + ' + artifacts: + when: always + reports: + junit: + - ./tmp/junit.xml + paths: + - ./prebuilds/ + # Only the build:linux preserves the dist + - ./dist + rules: + # Runs on staging commits and ignores version commits + - if: $CI_COMMIT_BRANCH == 'staging' && $CI_COMMIT_TITLE !~ /^[0-9]+\.[0-9]+\.[0-9]+(?:-.*[0-9]+)?$/ + # Runs on tag pipeline where the tag is a prerelease or release version + - if: $CI_COMMIT_TAG =~ /^v[0-9]+\.[0-9]+\.[0-9]+(?:-.*[0-9]+)?$/ + +build:windows: + stage: build + needs: + - job: check:lint + optional: true + tags: + - windows + before_script: + - choco install nodejs --version=16.14.2 -y + - choco install python --version=3.9.12 -y + - refreshenv + script: + - npm config set msvs_version 2019 + - npm install --ignore-scripts + - $env:Path = "$(npm bin);" + $env:Path + - npm run build --verbose + - npm test -- --ci + artifacts: + when: always + reports: + junit: + - ./tmp/junit.xml + paths: + - ./prebuilds/ + rules: + # Runs on staging commits and ignores version commits + - if: $CI_COMMIT_BRANCH == 'staging' && $CI_COMMIT_TITLE !~ /^[0-9]+\.[0-9]+\.[0-9]+(?:-.*[0-9]+)?$/ + # Runs on tag pipeline where the tag is a prerelease or release version + - if: $CI_COMMIT_TAG =~ /^v[0-9]+\.[0-9]+\.[0-9]+(?:-.*[0-9]+)?$/ + +build:macos: + stage: build + needs: + - job: check:lint + optional: true + tags: + - shared-macos-amd64 + image: macos-11-xcode-12 + variables: + HOMEBREW_NO_INSTALL_UPGRADE: "true" + HOMEBREW_NO_INSTALL_CLEANUP: "true" + before_script: + - brew install node@16 + - brew link --overwrite node@16 + - brew install python@3.9 + - brew link --overwrite python@3.9 + - hash -r script: - - nix-build -v -v --dry-run ./release.nix --attr application - - nix-build -v -v --dry-run ./release.nix --attr docker - - nix-build -v -v --dry-run ./release.nix --attr package.linux.x64.elf - - nix-build -v -v --dry-run ./release.nix --attr package.windows.x64.exe - - nix-build -v -v --dry-run ./release.nix --attr package.macos.x64.macho + - npm install --ignore-scripts + - export PATH="$(npm bin):$PATH" + - export PREBUILD_ARCH=x64+arm64 + - npm run build --verbose + - npm test -- --ci + artifacts: + when: always + reports: + junit: + - ./tmp/junit.xml + paths: + - ./prebuilds/ + rules: + # Runs on staging commits and ignores version commits + - if: $CI_COMMIT_BRANCH == 'staging' && $CI_COMMIT_TITLE !~ /^[0-9]+\.[0-9]+\.[0-9]+(?:-.*[0-9]+)?$/ + # Runs on tag pipeline where the tag is a prerelease or release version + - if: $CI_COMMIT_TAG =~ /^v[0-9]+\.[0-9]+\.[0-9]+(?:-.*[0-9]+)?$/ -nix: +build:prerelease: stage: build - image: registry.gitlab.com/matrixai/engineering/maintenance/gitlab-runner + needs: + - build:linux + - build:windows + - build:macos + # Don't interrupt publishing job + interruptible: false + allow_failure: true + before_script: + - echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > ./.npmrc + script: + - echo 'Publishing library prerelease' + - > + nix-shell --run ' + npm publish --tag prerelease --access public; + ' + - > + for d in prebuilds/*; do + tar \ + --create \ + --verbose \ + --file="prebuilds/$(basename $d).tar" \ + --directory=prebuilds \ + "$(basename $d)"; + done + - > + nix-shell -I nixpkgs=./pkgs.nix --packages git gitAndTools.gh --run ' + gh release \ + create "$CI_COMMIT_TAG" \ + prebuilds/*.tar \ + --title "Build-$(date -u +"%Y-%m-%dT%H:%M:%SZ")" \ + --notes '' \ + --prerelease \ + --target staging \ + --repo MatrixAI/TypeScript-Demo-Lib-Native; + ' + after_script: + - rm -f ./.npmrc + rules: + # Only runs on tag pipeline where the tag is a prerelease version + # This requires dependencies to also run on tag pipeline + # However version tag comes with a version commit + # Dependencies must not run on the version commit + - if: $CI_COMMIT_TAG =~ /^v[0-9]+\.[0-9]+\.[0-9]+-.*[0-9]+$/ + +integration:builds: + stage: integration + needs: + - build:linux + - build:windows + - build:macos script: - mkdir -p ./builds - # nix-specific application target - > build_application="$(nix-build \ --max-jobs "$(nproc)" --cores "$(nproc)" \ @@ -64,19 +282,38 @@ nix: --attr docker \ --attr package.linux.x64.elf \ --attr package.windows.x64.exe \ - --attr package.macos.x64.macho)" + --attr package.macos.x64.macho \ + --attr package.macos.arm64.macho)" - cp -r $builds ./builds/ - only: - - master artifacts: paths: - ./builds/ + rules: + # Runs on staging commits and ignores version commits + - if: $CI_COMMIT_BRANCH == 'staging' && $CI_COMMIT_TITLE !~ /^[0-9]+\.[0-9]+\.[0-9]+(?:-.*[0-9]+)?$/ + # Runs on tag pipeline where the tag is a prerelease or release version + - if: $CI_COMMIT_TAG =~ /^v[0-9]+\.[0-9]+\.[0-9]+(?:-.*[0-9]+)?$/ -application run: - stage: quality - image: registry.gitlab.com/matrixai/engineering/maintenance/gitlab-runner - dependencies: - - nix +integration:deployment: + stage: integration + needs: + - integration:builds + # Don't interrupt deploying job + interruptible: false + script: + - echo 'Perform service deployment for integration testing' + rules: + # Runs on staging commits and ignores version commits + - if: $CI_COMMIT_BRANCH == 'staging' && $CI_COMMIT_TITLE !~ /^[0-9]+\.[0-9]+\.[0-9]+(?:-.*[0-9]+)?$/ + # Runs on tag pipeline where the tag is a prerelease or release version + - if: $CI_COMMIT_TAG =~ /^v[0-9]+\.[0-9]+\.[0-9]+(?:-.*[0-9]+)?$/ + +integration:nix: + stage: integration + needs: + - integration:builds + - job: integration:deployment + optional: true script: - > build_application="$( \ @@ -85,14 +322,19 @@ application run: tail -1 \ )" - $build_application/bin/typescript-demo-lib - only: - - master + rules: + # Runs on staging commits and ignores version commits + - if: $CI_COMMIT_BRANCH == 'staging' && $CI_COMMIT_TITLE !~ /^[0-9]+\.[0-9]+\.[0-9]+(?:-.*[0-9]+)?$/ + # Runs on tag pipeline where the tag is a prerelease or release version + - if: $CI_COMMIT_TAG =~ /^v[0-9]+\.[0-9]+\.[0-9]+(?:-.*[0-9]+)?$/ -docker run: - stage: quality +integration:docker: + stage: integration + needs: + - integration:builds + - job: integration:deployment + optional: true image: docker:20.10.11 - dependencies: - - nix services: - docker:20.10.11-dind variables: @@ -102,61 +344,191 @@ docker run: script: - image="$(docker load --input ./builds/*docker* | cut -d' ' -f3)" - docker run "$image" - only: - - master + rules: + # Runs on staging commits and ignores version commits + - if: $CI_COMMIT_BRANCH == 'staging' && $CI_COMMIT_TITLE !~ /^[0-9]+\.[0-9]+\.[0-9]+(?:-.*[0-9]+)?$/ + # Runs on tag pipeline where the tag is a prerelease or release version + - if: $CI_COMMIT_TAG =~ /^v[0-9]+\.[0-9]+\.[0-9]+(?:-.*[0-9]+)?$/ -linux run: - stage: quality +integration:linux: + stage: integration + needs: + - integration:builds + - job: integration:deployment + optional: true image: ubuntu:latest - dependencies: - - nix script: - for f in ./builds/*-linux-*; do "$f"; done - only: - - master + rules: + # Runs on staging commits and ignores version commits + - if: $CI_COMMIT_BRANCH == 'staging' && $CI_COMMIT_TITLE !~ /^[0-9]+\.[0-9]+\.[0-9]+(?:-.*[0-9]+)?$/ + # Runs on tag pipeline where the tag is a prerelease or release version + - if: $CI_COMMIT_TAG =~ /^v[0-9]+\.[0-9]+\.[0-9]+(?:-.*[0-9]+)?$/ -windows run: - stage: quality - dependencies: - - nix - script: - - Get-ChildItem -File ./builds/*-win32-* | ForEach {& $_.FullName} +integration:windows: + stage: integration + needs: + - integration:builds + - job: integration:deployment + optional: true tags: - windows - only: - - master - -macos run: - stage: quality - image: macos-11-xcode-12 - dependencies: - - nix script: - - for f in ./builds/*-macos-*; do "$f"; done - only: - - master + - Get-ChildItem -File ./builds/*-win-* | ForEach {& $_.FullName} + rules: + # Runs on staging commits and ignores version commits + - if: $CI_COMMIT_BRANCH == 'staging' && $CI_COMMIT_TITLE !~ /^[0-9]+\.[0-9]+\.[0-9]+(?:-.*[0-9]+)?$/ + # Runs on tag pipeline where the tag is a prerelease or release version + - if: $CI_COMMIT_TAG =~ /^v[0-9]+\.[0-9]+\.[0-9]+(?:-.*[0-9]+)?$/ + +integration:macos: + stage: integration + needs: + - integration:builds + - job: integration:deployment + optional: true tags: - shared-macos-amd64 + image: macos-11-xcode-12 + script: + - for f in ./builds/*-macos-x64*; do "$f"; done + rules: + # Runs on staging commits and ignores version commits + - if: $CI_COMMIT_BRANCH == 'staging' && $CI_COMMIT_TITLE !~ /^[0-9]+\.[0-9]+\.[0-9]+(?:-.*[0-9]+)?$/ + # Runs on tag pipeline where the tag is a prerelease or release version + - if: $CI_COMMIT_TAG =~ /^v[0-9]+\.[0-9]+\.[0-9]+(?:-.*[0-9]+)?$/ + +integration:prerelease: + stage: integration + needs: + - integration:builds + - job: integration:nix + optional: true + - job: integration:docker + optional: true + - job: integration:linux + optional: true + - job: integration:windows + optional: true + - job: integration:macos + optional: true + # Don't interrupt publishing job + interruptible: false + allow_failure: true + script: + - echo 'Publishing application prerelease' + - > + nix-shell -I nixpkgs=./pkgs.nix --packages git gitAndTools.gh --run ' + if [ gh release view "$CI_COMMIT_TAG" >/dev/null 2>&1 ]; then + gh release \ + upload "$CI_COMMIT_TAG" \ + builds/*.closure.gz \ + builds/*-docker-* \ + builds/*-linux-* \ + builds/*-win-* \ + builds/*-macos-* \ + --clobber \ + --repo MatrixAI/TypeScript-Demo-Lib-Native; + else + gh release \ + create "$CI_COMMIT_TAG" \ + builds/*.closure.gz \ + builds/*-docker-* \ + builds/*-linux-* \ + builds/*-win-* \ + builds/*-macos-* \ + --title "Build-$(date -u +"%Y-%m-%dT%H:%M:%SZ")" \ + --notes '' \ + --prerelease \ + --target staging \ + --repo MatrixAI/TypeScript-Demo-Lib-Native; + fi; + ' + rules: + # Only runs on tag pipeline where the tag is a release version + # This requires dependencies to also run on tag pipeline + # However version tag comes with a version commit + # Dependencies must not run on the version commit + - if: $CI_COMMIT_TAG =~ /^v[0-9]+\.[0-9]+\.[0-9]+-.*[0-9]+$/ -packages: +release:deployment: stage: release - image: registry.gitlab.com/matrixai/engineering/maintenance/gitlab-runner - dependencies: - - nix + needs: + - project: $CI_PROJECT_PATH + job: integration:builds + ref: staging + artifacts: true + # Don't interrupt deploying job + interruptible: false script: + - echo 'Perform service deployment for production' + rules: + # Runs on master commits and ignores version commits + - if: $CI_COMMIT_BRANCH == 'master' && $CI_COMMIT_TITLE !~ /^[0-9]+\.[0-9]+\.[0-9]+(?:-.*[0-9]+)?$/ + # Runs on tag pipeline where the tag is a release version + - if: $CI_COMMIT_TAG =~ /^v[0-9]+\.[0-9]+\.[0-9]+$/ + +release:distribution: + stage: release + needs: + - project: $CI_PROJECT_PATH + job: build:linux + ref: staging + artifacts: true + - project: $CI_PROJECT_PATH + job: build:windows + ref: staging + artifacts: true + - project: $CI_PROJECT_PATH + job: build:macos + ref: staging + artifacts: true + - project: $CI_PROJECT_PATH + job: integration:builds + ref: staging + artifacts: true + - job: release:deployment + optional: true + # Don't interrupt publishing job + interruptible: false + allow_failure: true + before_script: + - echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > ./.npmrc + script: + - echo 'Publishing library & application release' + - > + nix-shell --run ' + npm publish --access public; + ' + - > + for d in prebuilds/*; do + tar \ + --create \ + --verbose \ + --file="prebuilds/$(basename $d).tar" \ + --directory=prebuilds \ + "$(basename $d)"; + done - > nix-shell -I nixpkgs=./pkgs.nix --packages git gitAndTools.gh --run ' - commit="$(git rev-parse --short HEAD)"; gh release \ - create "$commit" \ + create "$CI_COMMIT_TAG" \ + prebuilds/*.tar \ builds/*.closure.gz \ + builds/*-docker-* \ builds/*-linux-* \ - builds/*-win32-* \ + builds/*-win-* \ builds/*-macos-* \ --title "Build-$(date -u +"%Y-%m-%dT%H:%M:%SZ")" \ - --prerelease \ - --notes "" \ - --repo MatrixAI/TypeScript-Demo-Lib; + --notes '' \ + --target master \ + --repo MatrixAI/TypeScript-Demo-Lib-Native; ' - only: - - master + after_script: + - rm -f ./.npmrc + rules: + # Only runs on tag pipeline where the tag is a release version + # This requires dependencies to also run on tag pipeline + # However version tag comes with a version commit + # Dependencies must not run on the version commit + - if: $CI_COMMIT_TAG =~ /^v[0-9]+\.[0-9]+\.[0-9]+$/ diff --git a/.npmignore b/.npmignore index 6c68156..6e59877 100644 --- a/.npmignore +++ b/.npmignore @@ -1,16 +1,15 @@ .* +/*.nix /nix -/pkgs.nix -/default.nix -/shell.nix -/release.nix /tsconfig.json /tsconfig.build.json /jest.config.js +/scripts /src /tests /tmp /docs /benches +/build /builds /dist/tsbuildinfo diff --git a/README.md b/README.md index a742fc4..982bbcf 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# TypeScript-Demo-Lib +# TypeScript-Demo-Lib-Native -[![pipeline status](https://gitlab.com/MatrixAI/open-source/TypeScript-Demo-Lib/badges/master/pipeline.svg)](https://gitlab.com/MatrixAI/open-source/TypeScript-Demo-Lib/commits/master) +[![pipeline status](https://gitlab.com/MatrixAI/open-source/TypeScript-Demo-Lib-Native/badges/master/pipeline.svg)](https://gitlab.com/MatrixAI/open-source/TypeScript-Demo-Lib-Native/commits/master) ## Installation @@ -174,7 +174,7 @@ This has to be done to both `node2nixProd` and `node2nixDev`. npm run docs ``` -See the docs at: https://matrixai.github.io/TypeScript-Demo-Lib/ +See the docs at: https://matrixai.github.io/TypeScript-Demo-Lib-Native/ ### Publishing diff --git a/binding.gyp b/binding.gyp new file mode 100644 index 0000000..60bca6c --- /dev/null +++ b/binding.gyp @@ -0,0 +1,42 @@ +{ + 'targets': [{ + 'target_name': 'native', + 'include_dirs': [ + "
Generated using TypeDoc
Generated using TypeDoc
npm run docs
-See the docs at: https://matrixai.github.io/TypeScript-Demo-Lib/
+See the docs at: https://matrixai.github.io/TypeScript-Demo-Lib-Native/
Generated using TypeDoc
Generated using TypeDoc