Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 35 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ jobs:
registry-url: "https://registry.npmjs.org"

- run: npm ci
- run: npm install --include=optional
- run: opam install dune cppo
- run: npm run compile
- run: npm run bundle
Expand Down Expand Up @@ -114,11 +115,20 @@ jobs:
mv rescript-tools.exe ${{matrix.artifact-folder}}
tar -cvf binary.tar ${{matrix.artifact-folder}}

- uses: actions/upload-artifact@v4
- name: Upload binaries
uses: actions/upload-artifact@v4
with:
name: ${{matrix.artifact-folder}}
path: binary.tar

- name: Upload platform bindings
if: always()
uses: actions/upload-artifact@v4
with:
name: bindings-${{matrix.artifact-folder}}
path: node_modules/@oxc-parser/
retention-days: 1

package:
needs:
- build
Expand All @@ -134,6 +144,7 @@ jobs:
registry-url: "https://registry.npmjs.org"

- run: npm ci
- run: npm install --include=optional
- run: npm run compile

- name: Download MacOS binaries
Expand Down Expand Up @@ -180,6 +191,13 @@ jobs:
run: rm binary.tar
working-directory: binaries

- name: Download platform bindings from all platforms
uses: actions/download-artifact@v4
with:
pattern: bindings-*
path: bindings
merge-multiple: true

- name: Move binaries to folders
run: |
declare -a platforms=("darwin" "darwinarm64" "linux" "linuxarm64" "win32")
Expand All @@ -194,6 +212,16 @@ jobs:
mv binaries/"$platform"/rescript-tools.exe tools/binaries/"$platform"
done

- name: Merge platform bindings into node_modules
run: |
mkdir -p node_modules/@oxc-parser
# Copy all bindings from downloaded artifacts
if [ -d "bindings" ]; then
find bindings -type d -name "binding-*" -exec cp -r {} node_modules/@oxc-parser/ \;
fi
# Ensure we have the Linux binding from current platform
npm install --include=optional || true

- name: Store short commit SHA for filename
id: vars
env:
Expand All @@ -215,15 +243,18 @@ jobs:

- name: Package Extension
if: github.ref != 'refs/heads/master'
run: npx vsce package -o rescript-vscode-${{ steps.vars.outputs.sha_short }}.vsix
run: npx vsce package --no-yarn -o rescript-vscode-${{ steps.vars.outputs.sha_short }}.vsix

- name: Package Extension pre-release version
if: github.ref == 'refs/heads/master'
run: npx vsce package -o rescript-vscode-latest-master.vsix ${{ steps.increment_pre_release.outputs.new_version }} --no-git-tag-version
run: npx vsce package --no-yarn -o rescript-vscode-latest-master.vsix ${{ steps.increment_pre_release.outputs.new_version }} --no-git-tag-version

- name: Package Extension release version
if: startsWith(github.ref, 'refs/tags/')
run: npx vsce package -o rescript-vscode-${{ steps.tag_name.outputs.tag }}.vsix ${{ steps.tag_name.outputs.tag }} --no-git-tag-version
run: npx vsce package --no-yarn -o rescript-vscode-${{ steps.tag_name.outputs.tag }}.vsix ${{ steps.tag_name.outputs.tag }} --no-git-tag-version

- name: Verify Package Contents
run: npm run verify-package

- uses: actions/upload-artifact@v4
if: github.ref != 'refs/heads/master'
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@
"scripts": {
"clean": "rm -rf client/out server/out",
"vscode:prepublish": "npm run clean && npm run bundle",
"verify-package": "node scripts/verify-package.mjs",
"compile": "tsc -b",
"watch": "tsc -b -w",
"postinstall": "cd server && npm i && cd ../client && npm i && cd ../tools && npm i && cd ../tools/tests && npm i && cd ../../analysis/tests && npm i && cd ../reanalyze/examples/deadcode && npm i && cd ../termination && npm i",
Expand All @@ -280,7 +281,7 @@
},
"dependencies": {
"magic-string": "^0.30.21",
"oxc-parser": "^0.97.0",
"oxc-parser": "0.97.0",
"oxc-walker": "^0.5.2",
"semver": "^7.7.2"
},
Expand Down
115 changes: 115 additions & 0 deletions scripts/verify-package.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
#!/usr/bin/env node

/**
* Script to verify that platform-specific native bindings and required dependencies
* are included in the packaged .vsix file
*/

import fs from "fs";
import path from "path";
import { fileURLToPath } from "url";
import { execSync } from "child_process";

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const ROOT_DIR = path.join(__dirname, "..");

// Find .vsix file
const vsixFiles = fs
.readdirSync(ROOT_DIR)
.filter((f) => f.endsWith(".vsix"))
.sort((a, b) => {
const statA = fs.statSync(path.join(ROOT_DIR, a));
const statB = fs.statSync(path.join(ROOT_DIR, b));
return statB.mtimeMs - statA.mtimeMs; // Most recent first
});

if (vsixFiles.length === 0) {
console.error('No .vsix file found. Run "npx vsce package" first.');
process.exit(1);
}

const vsixFile = vsixFiles[0];
console.log(`Checking ${vsixFile}...\n`);

// Extract and check contents
const tempDir = path.join(ROOT_DIR, ".vsix-check");
try {
fs.mkdirSync(tempDir, { recursive: true });

// .vsix is just a zip file
execSync(`unzip -q "${path.join(ROOT_DIR, vsixFile)}" -d "${tempDir}"`, {
stdio: "inherit",
});

const extensionDir = path.join(tempDir, "extension");
const oxcParserDir = path.join(extensionDir, "node_modules", "@oxc-parser");

// Platform-specific bindings that should be included
const platformBindings = [
"@oxc-parser/binding-darwin-arm64",
"@oxc-parser/binding-darwin-x64",
"@oxc-parser/binding-linux-x64-gnu",
"@oxc-parser/binding-win32-x64-msvc",
];

const checks = [
{
name: "oxc-parser",
path: path.join(extensionDir, "node_modules", "oxc-parser"),
required: true,
},
...platformBindings.map((binding) => ({
name: binding,
path: path.join(oxcParserDir, binding.replace("@oxc-parser/", "")),
required: true,
})),
];

let allGood = true;
let foundCount = 0;

for (const check of checks) {
const exists = fs.existsSync(check.path);
const status = exists ? "✓" : "✗";
console.log(`${status} ${check.name}: ${exists ? "FOUND" : "MISSING"}`);

if (exists) {
foundCount++;
// Check for key files in bindings
if (check.name.startsWith("@oxc-parser/binding-")) {
// Look for .node files (native bindings) or package.json
const packageJson = path.join(check.path, "package.json");
if (fs.existsSync(packageJson)) {
console.log(` ✓ package.json found`);
} else {
console.log(` ✗ package.json missing`);
allGood = false;
}
}
} else if (check.required) {
allGood = false;
}
}

console.log("");
console.log(`Found ${foundCount}/${checks.length} required packages`);

if (allGood && foundCount === checks.length) {
console.log("✓ All required files are included in the package!");
} else {
console.log("✗ Some required files are missing!");
if (foundCount < platformBindings.length) {
console.log(
` Warning: Only ${foundCount - 1} platform bindings found, expected ${platformBindings.length}`,
);
console.log(" The extension may not work on all platforms.");
}
process.exit(1);
}
} finally {
// Cleanup
if (fs.existsSync(tempDir)) {
fs.rmSync(tempDir, { recursive: true, force: true });
}
}