diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dacb95d0..2590b7c8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -206,7 +206,7 @@ jobs: - name: Create vsix package run: | - yarn package --target ${{ matrix.target }} + yarn run package --target ${{ matrix.target }} --yarn - name: Upload package uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index bdeb4f64..1c3a62ec 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -164,7 +164,7 @@ jobs: - name: Create vsix package run: | - yarn package --target ${{ matrix.target }} + yarn run package --target ${{ matrix.target }} --yarn - name: Upload package uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index 30b020eb..26738126 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -58,6 +58,24 @@ Supported ``s are: > yarn package [--target ] ``` +## Release versioning + +This repository follows the VS Code Marketplace pre-release recommendation: + +- **Odd** minor versions (`x.1.z`, `x.3.z`, ...) are pre-releases. +- **Even** minor versions (`x.0.z`, `x.2.z`, ...) are full releases. + +To enforce this consistently, both packaging and publishing use `scripts/vsce-release.js`, which: + +- checks the current `package.json` version minor value. +- automatically adds `--pre-release` to `vsce package` for odd minor versions. + +Use the following commands: + +```sh +> yarn run package [--target ] +``` + ## Developing 1. If you are developing and debugging this extension, we recommend you run the following command diff --git a/package.json b/package.json index 2ee1254f..2d04c736 100644 --- a/package.json +++ b/package.json @@ -403,7 +403,7 @@ "lint": "eslint .", "test": "jest --reporters=default --reporters=./node_modules/jest-html-reporter", "all": "yarn && yarn download-tools && yarn test", - "package": "vsce package --yarn", + "package": "node ./scripts/vsce-release.js --yarn", "tpip:report": "tsx scripts/tpip-reporter --header docs/tpip-header.md docs/third-party-licenses.json TPIP.md", "lint:md": "markdownlint **/*.md -c ./.github/markdownlint.jsonc -i ./node_modules -i ./dist -i ./coverage -i ./tools", "check:links": "tsx scripts/check-links.ts -i ./node_modules/** -i ./.github/** -c ./.github/markdown-link-check.jsonc", diff --git a/scripts/vsce-release.js b/scripts/vsce-release.js new file mode 100644 index 00000000..4c341fdf --- /dev/null +++ b/scripts/vsce-release.js @@ -0,0 +1,84 @@ +#!/usr/bin/env node + +/** + * Copyright 2026 Arm Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// generated with AI + +/** + * CLI usage: + * - Preferred: npm run package + * - With extra vsce flags: npm run package -- + * - Direct invocation: node ./scripts/vsce-release.js [package] [vsce-args] + * + * Notes: + * - This helper only supports the `package` command. + * - `--pre-release` is appended automatically for odd minor versions. + */ + +import fs from 'node:fs'; +import path from 'node:path'; +import { spawnSync } from 'node:child_process'; +import { fileURLToPath } from 'node:url'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const rootPath = path.resolve(__dirname, '..'); +const packageJsonPath = path.join(rootPath, 'package.json'); + +const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); +const version = packageJson.version; + +const match = /^(\d+)\.(\d+)\.(\d+)(?:[-+].*)?$/.exec(version); +if (!match) { + console.error(`Unsupported package.json version format: ${version}`); + process.exit(1); +} + +const minor = Number(match[2]); +const isPreReleaseChannel = minor % 2 === 1; + +const allowedCommands = new Set(['package']); +const firstArg = process.argv[2]; +const command = firstArg && !firstArg.startsWith('-') ? firstArg : 'package'; + +if (!allowedCommands.has(command)) { + console.error(`Unsupported vsce command: ${command}`); + console.error('Supported commands: package'); + process.exit(1); +} + +const passthroughArgs = command === firstArg ? process.argv.slice(3) : process.argv.slice(2); +const args = [command, ...passthroughArgs]; + +if (isPreReleaseChannel) { + args.push('--pre-release'); +} + +console.log(`Running: vsce ${args.join(' ')}`); + +const result = spawnSync('vsce', args, { + cwd: rootPath, + stdio: 'inherit', + shell: process.platform === 'win32' +}); + +if (result.error) { + console.error(result.error.message); + process.exit(1); +} + +process.exit(result.status ?? 1);