diff --git a/.github/workflows/test-windows-pack.yml b/.github/workflows/test-windows-pack.yml new file mode 100644 index 000000000..be896c6f2 --- /dev/null +++ b/.github/workflows/test-windows-pack.yml @@ -0,0 +1,49 @@ +name: Build Windows installer (test artifact) + +# Manual/PR-triggered build to validate the Windows installer without cutting a release. +# Builds on ubuntu-latest (same as the official release) and uploads the .exe +# files as downloadable workflow artifacts. + +on: + workflow_dispatch: + pull_request: + paths: + - 'scripts/pretarball.js' + - 'package.json' + - '.github/workflows/test-windows-pack.yml' + +jobs: + build-windows: + name: Build Windows installer + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v6 + with: + node-version: '24' + + - name: Install NSIS and 7zip + run: sudo apt-get update && sudo apt-get install -y p7zip-full nsis + + # npm cli 10 has a caching bug that can break the pack step + - name: Install latest npm + run: npm install -g npm@latest + + - name: Install dependencies + run: npm ci + + - name: Build project + run: npm run build + + - name: Pack Windows installer + run: npm run pack:windows + + - name: Upload installer artifacts + uses: actions/upload-artifact@v4 + with: + name: asyncapi-windows-installers + path: dist/win32/*.exe + if-no-files-found: error diff --git a/package.json b/package.json index 2050ca04b..707c5781d 100644 --- a/package.json +++ b/package.json @@ -178,6 +178,7 @@ "pack:tarballs:alpine": "oclif pack tarballs -t linux-x64 && npm run pack:rename alpine", "pack:windows": "oclif pack win && npm run pack:rename", "pack:rename": "node scripts/releasePackagesRename.js", + "pretarball": "node ./scripts/pretarball.js", "publish:trusted": "echo \"Working around changesets action not supporting OIDC yet. Need to pass successful release output for triggering github release\";VERSION=$(node -p \"require('./package.json').version\"); PACKAGE_NAME=$(node -p \"require('./package.json').name\"); if npm view $PACKAGE_NAME@$VERSION > /dev/null 2>&1; then echo \"Version $VERSION of package $PACKAGE_NAME already published to NPM. Skipping GitHub release.\"; else git tag v$VERSION -m v$VERSION; echo \"New tag: $PACKAGE_NAME@$VERSION.\"; fi", "prepublishOnly": "npm run build", "pretest": "npm run build", diff --git a/scripts/pretarball.js b/scripts/pretarball.js new file mode 100644 index 000000000..aa61e29f9 --- /dev/null +++ b/scripts/pretarball.js @@ -0,0 +1,42 @@ +/* eslint-disable no-console */ +/* + * scripts/pretarball.js + * + * Run by oclif (`npm run pretarball`) inside the packing workspace, + * AFTER `npm install --production` and BEFORE the installer/tarball is built + * (see oclif's tarballs build step). The current working directory is the + * oclif workspace root. + * + * It removes the Next.js `output: 'standalone'` build that is shipped inside + * the published `@asyncapi/studio` package. The CLI launches Studio/Preview + * via the programmatic Next server with `distDir: 'build'` + * (see src/domains/models/Studio.ts and src/domains/models/Preview.ts), which + * reads from `build/` as described by `build/required-server-files.json` and + * never uses `build/standalone`. + * + * That standalone folder contains a deeply-nested, pnpm-structured + * `node_modules/.pnpm/next@.../...` tree with paths exceeding the Windows + * 260-character MAX_PATH limit, which breaks the NSIS Windows installer with + * "Error opening file for writing". Pruning it here keeps those paths out of + * every packed artifact (win/macos/linux) without affecting runtime behaviour. + * + * See: https://github.com/asyncapi/cli/issues/2239 + */ + +const fs = require('fs'); +const path = require('path'); + +// Paths are relative to the oclif workspace root (process.cwd()). +const targets = [ + path.join('node_modules', '@asyncapi', 'studio', 'build', 'standalone'), +]; + +for (const rel of targets) { + const abs = path.resolve(process.cwd(), rel); + if (fs.existsSync(abs)) { + fs.rmSync(abs, { recursive: true, force: true }); + console.log(`[pretarball] removed ${rel}`); + } else { + console.log(`[pretarball] skip (not found) ${rel}`); + } +}