Skip to content
Closed
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
8 changes: 4 additions & 4 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,19 @@ jobs:
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
node-version: '24'

- name: Install dependencies
run: npm ci

- name: Compile TypeScript
run: npm run compile

- name: Install vsce
run: npm install -g @vscode/vsce
- name: Test dependency and packaging contracts
run: npm run test:dependencies

- name: Package extension
run: vsce package
run: npm run package

- name: Upload VSIX artifact
uses: actions/upload-artifact@v4
Expand Down
2 changes: 2 additions & 0 deletions .vscodeignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@ tsconfig.json
**/*.map
**/*.ts
.gitignore

tests/**
6 changes: 3 additions & 3 deletions package-lock.json

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

7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@
{
"language": "stlcpp",
"scopes": {
"boolean": ["constant.language.boolean"]
"boolean": [
"constant.language.boolean"
]
}
}
]
Expand All @@ -52,7 +54,8 @@
"vscode:prepublish": "npm run compile",
"compile": "tsc -p ./",
"watch": "tsc -watch -p ./",
"package": "vsce package"
"package": "vsce package",
"test:dependencies": "node --test tests/dependencies/*.test.cjs"
},
"devDependencies": {
"@types/node": "^20.0.0",
Expand Down
14 changes: 14 additions & 0 deletions tests/dependencies/brace-expansion.test.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const test = require('node:test');
const assert = require('node:assert/strict');
const expand = require('brace-expansion');
const minimatch = require('minimatch');

test('packaging globs retain nested alternatives, ranges, and escaped literals', () => {
assert.deepEqual(expand('assets/{wasm,{queries,config}}/*'), ['assets/wasm/*', 'assets/queries/*', 'assets/config/*']);
assert.deepEqual(expand('chunk-{01..03}.js'), ['chunk-01.js', 'chunk-02.js', 'chunk-03.js']);
assert.deepEqual(expand('literal\\{name\\}'), ['literal{name}']);
const pattern = '**/*.{ts,map}';
assert.equal(minimatch('src/extension.ts', pattern), true);
assert.equal(minimatch('out/extension.js.map', pattern), true);
assert.equal(minimatch('wasm/tree-sitter-stlcpp.wasm', pattern), false);
});
44 changes: 44 additions & 0 deletions tests/dependencies/packaging.test.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
const test = require('node:test');
const assert = require('node:assert/strict');
const { mkdtempSync, readFileSync, rmSync } = require('node:fs');
const { tmpdir } = require('node:os');
const { join, dirname } = require('node:path');
const { execFileSync } = require('node:child_process');
const vsceManifest = require.resolve('@vscode/vsce/package.json');

function readArchive(file) {
// Python's standard ZIP reader verifies the packaged artifact independently
// of the ZIP implementation used by vsce itself.
const script = `import base64,json,sys,zipfile
with zipfile.ZipFile(sys.argv[1]) as archive:
wanted = {'extension/package.json', 'extension/wasm/tree-sitter-stlcpp.wasm'}
print(json.dumps({name: base64.b64encode(archive.read(name)).decode() if name in wanted else '' for name in archive.namelist()}))`;
const contents = JSON.parse(execFileSync('python3', ['-c', script, file], { encoding: 'utf8', timeout: 30_000 }));
return new Map(Object.entries(contents).map(([name, data]) => [name, Buffer.from(data, 'base64')]));
}

test('the locked vsce packages a loadable extension without source or test files', async () => {
const temporary = mkdtempSync(join(tmpdir(), 'stlcpp-vsix-'));
try {
const output = join(temporary, 'extension.vsix');
execFileSync(process.execPath, [join(dirname(vsceManifest), 'vsce'), 'package', '--out', output], {
cwd: process.cwd(), timeout: 120_000, stdio: 'pipe',
});
const files = await readArchive(output);
const manifest = JSON.parse(files.get('extension/package.json'));
assert.equal(manifest.publisher, 'aalto-opencs');
assert.equal(manifest.contributes.languages[0].id, 'stlcpp');
for (const name of ['out/extension.js', 'language-configuration.json', 'wasm/tree-sitter-stlcpp.wasm',
'node_modules/web-tree-sitter/package.json']) {
assert.ok(files.has(`extension/${name}`), `Missing runtime asset: ${name}`);
}
assert.deepEqual(files.get('extension/wasm/tree-sitter-stlcpp.wasm'), readFileSync('wasm/tree-sitter-stlcpp.wasm'));
assert.ok(files.has('extension/README.md') || files.has('extension/readme.md'));
for (const name of files.keys()) {
assert.doesNotMatch(name, /^extension\/(?:src|tests|\.github)\//);
assert.doesNotMatch(name, /^extension\/node_modules\/@vscode\/vsce\//);
}
} finally {
rmSync(temporary, { recursive: true, force: true });
}
});
Loading