diff --git a/.github/workflows/ci-js.yml b/.github/workflows/ci-js.yml deleted file mode 100644 index a55926a8..00000000 --- a/.github/workflows/ci-js.yml +++ /dev/null @@ -1,100 +0,0 @@ -name: 'CI-CD sails-js' - -on: - pull_request: - types: [opened, synchronize, reopened, labeled] - branches: [master] - paths-ignore: - - 'net/**' - - 'Sails.Net.sln' - push: - branches: [master] - paths: - - js/** - workflow_dispatch: - -env: - BINARYEN_VERSION: version_111 - -jobs: - test: - if: github.event_name == 'pull_request' - - runs-on: ubuntu-22.04 - env: - RUSTUP_HOME: /tmp/rustup_home - steps: - - name: Cancel previous workflow runs - uses: styfle/cancel-workflow-action@0.12.1 - with: - access_token: ${{ github.token }} - - - name: Checkout - uses: actions/checkout@v4 - - - name: 'Install: NodeJS 20.x' - uses: actions/setup-node@v4 - with: - node-version: 20.x - - - name: 'Install: dependencies' - run: yarn install - - - name: 'Install: binaryen' - working-directory: /usr - run: | - sudo wget -c https://github.com/WebAssembly/binaryen/releases/download/$BINARYEN_VERSION/binaryen-$BINARYEN_VERSION-x86_64-linux.tar.gz -O - | sudo tar -xz -C . - sudo cp binaryen-$BINARYEN_VERSION/bin/wasm-opt /usr/bin/ - - - name: 'Prepare: build all' - run: yarn build - - - name: 'Prepare: fmt' - run: yarn lint - - - name: 'Prepare: download Gear node' - run: | - wget -O ./gear https://github.com/gear-tech/gear/releases/download/v1.5.0-1/gear - chmod +x gear - - - name: 'Prepare: run Gear node' - run: nohup ./gear --dev --execution=wasm --tmp --unsafe-rpc-external --rpc-methods Unsafe --rpc-cors all & - - - name: 'Prepare: sleep 3 min' - run: sleep 180 - - - name: 'Test: run' - run: yarn test - - publish-to-npm: - if: github.event_name == 'push' - - runs-on: ubuntu-22.04 - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Use node 20.x - uses: actions/setup-node@v4 - with: - node-version: 20.x - - - name: 'Prepare: install dependencies' - run: yarn install - - - name: 'Install: binaryen' - working-directory: /usr - run: | - sudo wget -c https://github.com/WebAssembly/binaryen/releases/download/$BINARYEN_VERSION/binaryen-$BINARYEN_VERSION-x86_64-linux.tar.gz -O - | sudo tar -xz -C . - sudo cp binaryen-$BINARYEN_VERSION/bin/wasm-opt /usr/bin/ - - - name: 'Prepare: build all' - run: yarn build - - - name: Publish - run: | - export token=$(printenv npm_token) - echo "//registry.npmjs.org/:_authToken=$token" > .npmrc - npx lerna publish from-package --yes --no-private - env: - npm_token: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/js-ci.yml b/.github/workflows/js-ci.yml new file mode 100644 index 00000000..6f4da3a2 --- /dev/null +++ b/.github/workflows/js-ci.yml @@ -0,0 +1,49 @@ +name: '[js] CI' + +on: + pull_request: + types: [opened, synchronize, reopened, labeled] + branches: [master] + paths: + - 'js/**' + - 'package.json' + +jobs: + test: + runs-on: ubuntu-22.04 + steps: + - name: Cancel previous workflow runs + uses: styfle/cancel-workflow-action@0.12.1 + with: + access_token: ${{ github.token }} + + - name: Checkout + uses: actions/checkout@v4 + + - name: 'Install: NodeJS 20.x' + uses: actions/setup-node@v4 + with: + node-version: 20.x + + - name: 'Install: dependencies' + run: yarn install + + - name: 'Prepare: build all' + run: yarn build + + - name: 'Prepare: fmt' + run: yarn lint + + - name: 'Prepare: download Gear node' + run: | + wget -O ./gear https://github.com/gear-tech/gear/releases/download/build/gear + chmod +x gear + + - name: 'Prepare: run Gear node' + run: nohup ./gear --dev --execution=wasm --tmp --unsafe-rpc-external --rpc-methods Unsafe --rpc-cors all & + + - name: 'Prepare: sleep 3 min' + run: sleep 180 + + - name: 'Test: run' + run: yarn test diff --git a/.github/workflows/js-release.yml b/.github/workflows/js-release.yml new file mode 100644 index 00000000..30711cac --- /dev/null +++ b/.github/workflows/js-release.yml @@ -0,0 +1,80 @@ +name: '[js] Release' + +on: + push: + branches: + - master + paths: + - package.json + +jobs: + release: + name: Create Release + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: 'Setup NodeJS 20.x' + uses: actions/setup-node@v4 + with: + node-version: 20.x + + - name: 'Get info' + id: info + run: | + VERSION=$(jq -r '.version' package.json) + echo "version=$VERSION" >> $GITHUB_OUTPUT + echo "tag_name=js/v$VERSION" >> $GITHUB_OUTPUT + PREVIOUS_VERSION=$(npm show @js/package version) + echo "prev_version=$PREVIOUS_VERSION" >> $GITHUB_OUTPUT + + - name: 'Compare versions' + id: release + run: | + if [ ${{ steps.info.outputs.version }} == ${{ steps.info.outputs.prev_version }} ]; then + echo "No new version to release" + echo "skip=true" >> $GITHUB_OUTPUT + else + echo "New version to release" + echo "skip=false" >> $GITHUB_OUTPUT + fi + + - name: 'Get release notes' + id: release_notes + if: steps.release.outputs.skip != 'true' + run: | + awk '/## ${{ steps.info.outputs.version }}/{flag=1;next}/---/{flag=0} flag' ./js/CHANGELOG.md >> release_notes.txt + echo "release_notes<> $GITHUB_OUTPUT + cat release_notes.txt >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT + rm release_notes.txt + + - name: 'Prepare: install dependencies and build pkgs' + if: steps.release.outputs.skip != 'true' + run: | + yarn install + yarn build + + - name: 'Create new tag' + if: steps.release.outputs.skip != 'true' + run: | + git tag ${{ steps.info.outputs.tag_name }} + git push origin ${{ steps.info.outputs.tag_name }} + + - name: 'Create Release' + if: steps.release.outputs.skip != 'true' + uses: softprops/action-gh-release@v2 + with: + body: ${{ steps.release_notes.outputs.release_notes }} + tag_name: ${{ steps.info.outputs.tag_name }} + name: 'Sails-JS v${{ steps.info.outputs.version }}' + + - name: 'Publish to npm registry' + if: steps.release.outputs.skip != 'true' + run: | + export token=$(printenv npm_token) + echo "//registry.npmjs.org/:_authToken=$token" > .npmrc + npx lerna publish from-package --yes --no-private + env: + npm_token: ${{ secrets.NPM_TOKEN }} diff --git a/.gitignore b/.gitignore index 6d635378..db3c84d6 100644 --- a/.gitignore +++ b/.gitignore @@ -16,7 +16,6 @@ net/**/*.trx node_modules/ js/**/lib/ js/cli/build/ -js/parser/parser.wasm js/test/demo/ .pnp.* .yarn/* diff --git a/js/CHANGELOG.md b/js/CHANGELOG.md new file mode 100644 index 00000000..1d3c90a6 --- /dev/null +++ b/js/CHANGELOG.md @@ -0,0 +1,9 @@ +# CHANGELOG + +## 0.3.1 (draft) + +### Compatibility +- Sails-RS v0.6.3 + +### Changes +- Setup automated releases in https://github.com/gear-tech/sails/pull/608 diff --git a/js/cli/src/generate/types-gen.ts b/js/cli/src/generate/types-gen.ts index 915d0da5..6d049b2f 100644 --- a/js/cli/src/generate/types-gen.ts +++ b/js/cli/src/generate/types-gen.ts @@ -14,7 +14,7 @@ export class TypesGenerator extends BaseGenerator { } public generate() { - this._out.line('declare global {').increaseIndent(); + this._out.line('declare global {', false).increaseIndent(); for (const { name, def, docs } of this._program.types) { this._out.lines(formatDocs(docs), false); diff --git a/js/config.json b/js/config.json new file mode 100644 index 00000000..e31f62af --- /dev/null +++ b/js/config.json @@ -0,0 +1,3 @@ +{ + "sails-rs": "0.6.3" +} diff --git a/js/parser/rollup.config.js b/js/parser/rollup.config.js index 79d0e3ee..3fe2d225 100644 --- a/js/parser/rollup.config.js +++ b/js/parser/rollup.config.js @@ -1,42 +1,44 @@ -import { writeFileSync, readFileSync, existsSync, rmSync } from 'fs'; -import { execSync } from 'child_process'; +import { writeFileSync, rmSync } from 'fs'; import commonjs from '@rollup/plugin-commonjs'; import typescript from 'rollup-plugin-typescript2'; +import config from '../config.json' assert { type: 'json' }; -function checkParserFile() { - return { - name: 'check-parser-file', - buildStart() { - if (!existsSync('./parser.wasm')) { - throw new Error('parser.wasm file not found'); - } - }, - }; +async function getStreamFromRelease(version, cs) { + const link = `https://github.com/gear-tech/sails/releases/download/rs%2Fv${version}/sails_idl_parser.wasm`; + const res = await fetch(link); + + if (!res.ok) { + throw new Error(`Failed to fetch parser from ${link}`); + } + + return res.body.pipeThrough(cs); } -function compressParser(type) { - return { - name: 'compress-parser', - async closeBundle() { - const buf = readFileSync('./parser.wasm'); +async function getBase64Parser(version) { + const cs = new CompressionStream('gzip'); - const cs = new CompressionStream('gzip'); + const stream = await getStreamFromRelease(version, cs); - const compressedReadableStream = new Response(buf).body.pipeThrough(cs); + const reader = stream.getReader(); - const reader = compressedReadableStream.getReader(); + let resultArr = []; - let resultArr = []; + while (true) { + const read = await reader.read(); - while (true) { - const read = await reader.read(); + if (read.done) break; - if (read.done) break; + resultArr = resultArr.concat(Array.from(read.value)); + } - resultArr = resultArr.concat(Array.from(read.value)); - } + return Buffer.from(Uint8Array.from(resultArr).buffer).toString('base64'); +} - const base64Bytes = Buffer.from(Uint8Array.from(resultArr).buffer).toString('base64'); +function writeCompressedWasmParser(type) { + return { + name: 'write-wasm-parser', + async closeBundle() { + const base64Bytes = await getBase64Parser(config['sails-rs']); if (type === 'cjs') { writeFileSync( @@ -59,16 +61,6 @@ function cleanOldBuild() { }; } -function buildParserWasm() { - return { - name: 'build-parser-wasm', - buildStart() { - execSync('cargo build -p sails-idl-parser --target=wasm32-unknown-unknown --release'); - execSync('wasm-opt -O4 -o ./parser.wasm ../../target/wasm32-unknown-unknown/release/sails_idl_parser.wasm'); - }, - }; -} - export default [ { input: 'src/index.ts', @@ -81,13 +73,11 @@ export default [ }, ], plugins: [ - buildParserWasm(), - checkParserFile(), cleanOldBuild(), typescript({ tsconfig: 'tsconfig.build.json', }), - compressParser('es'), + writeCompressedWasmParser('es'), ], }, { @@ -107,7 +97,7 @@ export default [ tsconfig: 'tsconfig.cjs.json', }), commonjs(), - compressParser('cjs'), + writeCompressedWasmParser('cjs'), ], }, ]; diff --git a/js/scripts/build-parser.sh b/js/scripts/build-parser.sh new file mode 100755 index 00000000..7679281b --- /dev/null +++ b/js/scripts/build-parser.sh @@ -0,0 +1,5 @@ +echo "[*] Building parser wasm" +cargo build -p sails-idl-parser --target=wasm32-unknown-unknown --release +echo "[*] Optimizing parser wasm" +wasm-opt -O4 -o ./js/parser/parser.wasm ./target/wasm32-unknown-unknown/release/sails_idl_parser.wasm +ls -l ./js/parser/parser.wasm diff --git a/js/scripts/bump-versions.sh b/js/scripts/bump-versions.sh new file mode 100755 index 00000000..452d99cf --- /dev/null +++ b/js/scripts/bump-versions.sh @@ -0,0 +1,9 @@ +version=$1 + +echo "Bumping versions to $version" + +pkgs=("package.json" "./js/package.json" "./js/cli/package.json" "./js/parser/package.json" "./js/types/package.json" "./js/util/package.json") + +for pkg in ${pkgs[@]}; do + jq ".version = \"$version\"" $pkg > tmp.$$.json && mv tmp.$$.json $pkg +done diff --git a/js/test/demo.test.ts b/js/test/demo.test.ts index 2f539f8e..2f74ed1a 100644 --- a/js/test/demo.test.ts +++ b/js/test/demo.test.ts @@ -18,7 +18,7 @@ let charlieRaw: HexString; let code: Buffer; let codeId: HexString; -const DEMO_WASM_PATH = '../target/wasm32-unknown-unknown/release/demo.opt.wasm'; +const DEMO_WASM_PATH = 'test/demo/demo.wasm'; beforeAll(async () => { const parser = await SailsIdlParser.new(); diff --git a/js/test/setup.js b/js/test/setup.js index 1207d2da..749f8527 100644 --- a/js/test/setup.js +++ b/js/test/setup.js @@ -1,18 +1,35 @@ import * as fs from 'fs'; import { execSync } from 'child_process'; +import config from '../config.json' assert { type: 'json' }; -export default () => { - // Build demo app - execSync('cargo build -p demo --release'); +const downloadAndWriteFile = async (fileName, writeTo) => { + const link = `https://github.com/gear-tech/sails/releases/download/rs%2Fv${config['sails-rs']}/${fileName}`; - // Remove old generated files - execSync('rm -rf ./test/demo'); + const res = await fetch(link); + if (!res.ok) { + throw new Error(`Failed to fetch parser from ${link}`); + } + + const blob = await res.blob(); + const buf = await blob.arrayBuffer(); + + fs.writeFileSync(writeTo, Buffer.from(buf)); +}; + +export default async () => { + if (!fs.existsSync('test/demo')) { + fs.mkdirSync('test/demo'); + } + + await Promise.all([ + downloadAndWriteFile('demo.wasm', 'test/demo/demo.wasm'), + downloadAndWriteFile('demo.idl', 'test/demo/demo.idl'), + ]); // Generate demo ts client - execSync('node cli/build/app.js generate ../examples/demo/client/demo.idl -o ./test/demo --no-project --yes'); + execSync('node cli/build/app.js generate test/demo/demo.idl -o ./test/demo --no-project --yes'); // Modify client imports - const filesToModify = ['test/demo/lib.ts']; for (const path of filesToModify) { diff --git a/js/tsconfig.json b/js/tsconfig.json index 4969e1ec..97b63793 100644 --- a/js/tsconfig.json +++ b/js/tsconfig.json @@ -7,6 +7,7 @@ "forceConsistentCasingInFileNames": true, "strict": false, "noImplicitAny": false, - "skipLibCheck": true + "skipLibCheck": true, + "resolveJsonModule": true } }