semantic-release plugin to package and publish VS Code extensions.
Step | Description |
---|---|
verify |
Verify the package.json and the validity of the personal access tokens against Visual Studio Marketplace and/or Open VSX Registry when publish is enabled |
prepare |
Generate the .vsix file using vsce (can be be controlled by the packageVsix config option |
publish |
Publish the extension to Visual Studio Marketplace and/or Open VSX Registry (learn more here) |
npm install --save-dev semantic-release-vsce
or
yarn add --dev semantic-release-vsce
The plugin can be configured in the semantic-release configuration file:
{
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
[
"semantic-release-vsce",
{
"packageVsix": true
}
],
[
"@semantic-release/github",
{
"assets": [
{
"path": "*.vsix"
}
]
}
]
]
}
Whether to package or not the extension into a .vsix
file, or where to place it. This controls if vsce package
gets called or not, and what value will be used for vsce package --out
.
Value | Description |
---|---|
"auto" (default) |
behave as true in case publish is disabled or the OVSX_PAT environment variable is present |
true |
package the extension .vsix , and place it at the current working directory |
false |
disables packaging the extension .vsix entirely |
a string |
package the extension .vsix and place it at the specified path |
Whether to publish or not the extension to Visual Studio Marketplace and/or to Open VSX Registry. This controls if vsce publish
or ovsx publish
gets called or not. Learn more here.
Value | Description |
---|---|
true (default) |
publishes the extension to Visual Studio Marketplace and/or to Open VSX Registry |
false |
disables publishing the extension to Visual Studio Marketplace and/or to Open VSX Registry |
Which .vsix
file (or files) to publish. This controls what value will be used for vsce publish --packagePath
.
Value | Description |
---|---|
"auto" (default) |
uses the .vsix packaged during the prepare step (if packaged), or behave as false otherwise |
false |
do not use a .vsix file to publish, which causes vsce to package the extension as part of the publish process |
a string |
publish the specified .vsix file(s). This can be a glob pattern, or a comma-separated list of files |
The directory of the extension relative to the current working directory. Defaults to cwd
.
The following environment variables are supported by this plugin:
Variable | Description |
---|---|
OVSX_PAT |
Optional. The personal access token to push to Open VSX Registry |
VSCE_PAT |
Optional. The personal access token to publish to Visual Studio Marketplace. Note: Cannot be set at the same time as VSCE_AZURE_CREDENTIAL . |
VSCE_AZURE_CREDENTIAL |
Optional. When set to true or 1 , vsce will use the --azure-credential flag to authenticate. Note: Cannot be set at the same time as VSCE_PAT . |
VSCE_TARGET |
Optional. The target to use when packaging or publishing the extension (used as vsce package --target ${VSCE_TARGET} ). When set to universal , behave as if VSCE_TARGET was not set (i.e. build the universal/generic vsix ). See the platform-specific example |
You can set vsce
options in the package.json
, like:
{
"vsce": {
"baseImagesUrl": "https://my.custom/base/images/url",
"dependencies": true,
"yarn": false
}
}
For more information, check the vsce
docs.
This plugin can publish extensions to Visual Studio Marketplace and/or Open VSX Registry.
You can enable or disable publishing with the publish
config option.
When publish is enabled (default), the plugin will publish to Visual Studio Marketplace if the VSCE_PAT
environment variable is present, and/or to Open VSX Registry if the OVSX_PAT
environment variable is present.
For example, you may want to disable publishing if you only want to publish the .vsix
file as a GitHub release asset.
Publishing extensions to Visual Studio Marketplace using this plugin is easy:
-
Create your personal access token for Visual Studio Marketplace. Learn more here.
-
Configure the
VSCE_PAT
environment variable in your CI with the token that you created. -
Enjoy! The plugin will automatically detect the environment variable and it will publish to Visual Studio Marketplace, no additional configuration is needed.
Publishing extensions to Open VSX Registry using this plugin is easy:
-
Create your personal access token for Open VSX Registry. Learn more here.
-
Configure the
OVSX_PAT
environment variable in your CI with the token that you created. -
Enjoy! The plugin will automatically detect the environment variable and it will publish to Open VSX Registry, no additional configuration is needed.
name: release
on:
push:
branches:
- master
permissions:
contents: read # for checkout
jobs:
release:
runs-on: ubuntu-latest
permissions:
contents: write # to be able to publish a GitHub release
issues: write # to be able to comment on released issues
pull-requests: write # to be able to comment on released pull requests
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
- run: npm ci
- run: npm audit signatures
- run: npx semantic-release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# In case you want to publish to Visual Studio Marketplace
VSCE_PAT: ${{ secrets.VSCE_PAT }}
# In case you want to publish to Open VSX Registry
OVSX_PAT: ${{ secrets.OVSX_PAT }}
-
Install
semantic-release-stop-before-publish
npm install --save-dev semantic-release-stop-before-publish
We will use it to make
semantic-release
stop before publishing anything, so that we can usesemantic-release
to build each.vsix
in a matrix. -
Separate your
semantic-release
configuration into two, one for packaging and another for publishing.The one for packaging has
semantic-release-stop-before-publish
so thatsemantic-release
does not publish anything (which includes the git tag).// package.release.config.js /** * @type {import('semantic-release').GlobalConfig} */ export default { plugins: [ '@semantic-release/commit-analyzer', '@semantic-release/release-notes-generator', [ 'semantic-release-vsce', { packageVsix: true, publish: false, }, ], 'semantic-release-stop-before-publish', ], };
The one for publishing does not package the
.vsix
, but publishes all the*.vsix
files.// publish.release.config.js /** * @type {import('semantic-release').GlobalConfig} */ export default { plugins: [ '@semantic-release/commit-analyzer', '@semantic-release/release-notes-generator', [ 'semantic-release-vsce', { packageVsix: false, publishPackagePath: '*.vsix', }, ], [ '@semantic-release/github', { assets: '*.vsix', }, ], ], };
Note: do not forget to remove your existing
semantic-release
configuration. -
Create a workflow file like below:
# .github/workflows/ci.yaml
name: ci
on:
push:
branches:
- master
permissions:
contents: read # for checkout
jobs:
build:
strategy:
matrix:
include:
- os: windows-latest
target: win32-x64
npm_config_arch: x64
- os: windows-latest
target: win32-arm64
npm_config_arch: arm64
- os: ubuntu-latest
target: linux-x64
npm_config_arch: x64
- os: ubuntu-latest
target: linux-arm64
npm_config_arch: arm64
- os: ubuntu-latest
target: linux-armhf
npm_config_arch: arm
- os: ubuntu-latest
target: alpine-x64
npm_config_arch: x64
- os: ubuntu-latest
target: alpine-arm64
npm_config_arch: arm64
- os: macos-latest
target: darwin-x64
npm_config_arch: x64
- os: macos-latest
target: darwin-arm64
npm_config_arch: arm64
- os: ubuntu-latest
target: universal
runs-on: ${{ matrix.os }}
# Even though semantic-release will not publish anything, it still needs to
# validate the GITHUB_TOKEN
permissions:
contents: write # to be able to publish a GitHub release
issues: write # to be able to comment on released issues
pull-requests: write # to be able to comment on released pull requests
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
- if: matrix.target != 'universal'
name: Install dependencies (with binaries)
run: npm ci
env:
npm_config_arch: ${{ matrix.npm_config_arch }}
- if: matrix.target == 'universal'
name: Install dependencies (without binaries)
run: npm ci
- run: npx semantic-release --extends ./package.release.config.js
env:
VSCE_TARGET: ${{ matrix.target }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/upload-artifact@v4
with:
name: ${{ matrix.target }}
path: '*.vsix'
# vsce updates the version in package.json and package-lock.json during
# package step, so we need to save them for the publish step
- if: matrix.target == 'universal'
uses: actions/upload-artifact@v4
with:
name: package-json
path: |
package.json
package-lock.json
release:
runs-on: ubuntu-latest
needs: build
permissions:
contents: write # to be able to publish a GitHub release
issues: write # to be able to comment on released issues
pull-requests: write # to be able to comment on released pull requests
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v4
with:
merge-multiple: true
- uses: actions/setup-node@v4
with:
node-version: 22
- run: npm ci
- run: npm audit signatures
- run: npx semantic-release --extends ./publish.release.config.js
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# In case you want to publish to Visual Studio Marketplace
VSCE_PAT: ${{ secrets.VSCE_PAT }}
# In case you want to publish to Open VSX Registry
OVSX_PAT: ${{ secrets.OVSX_PAT }}
name: release
on:
push:
branches:
- master
permissions:
contents: read # for checkout
jobs:
release:
runs-on: ubuntu-latest
permissions:
contents: write # to be able to publish a GitHub release
issues: write # to be able to comment on released issues
pull-requests: write # to be able to comment on released pull requests
steps:
- uses: actions/checkout@v4
- uses: azure/login@v2
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- uses: actions/setup-node@v4
with:
node-version: 22
- run: npm ci
- run: npm audit signatures
- run: npx semantic-release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
VSCE_AZURE_CREDENTIAL: 'true'
A reference implementation can also be found in the VS Code ShellCheck extension.