vscode-openvsx-extension-publish
VSCode & Open VSX Extension Publish
Workflow for publishing VSCode extensions to both VS Code Marketplace and Open VSX.
Prerequisites
- Extension implementation is mostly complete
- Node.js is installed
- A GitHub repository exists
Workflow Overview
- Account & Token Verification — Check that required accounts and tokens are ready; guide creation if missing
- Pre-publish Preparation — Prepare package.json, README, LICENSE, .vscodeignore, etc.
- Local Testing — Verify the extension works correctly before publishing
- Initial Publish — Publish to both VS Code Marketplace and Open VSX
- GitHub Actions Setup — Create a workflow to automate subsequent publishes
Phase 1: Account & Token Verification
Start by confirming the following with the user. Guide them through creation of anything that is missing.
Checklist
Ask the user to determine their current status:
- Do you have a VS Code Marketplace Publisher?
- Do you have an Azure DevOps Personal Access Token (PAT)?
- Do you have an Open VSX (open-vsx.org) account?
- Do you have an Open VSX Access Token?
1-1: Creating a VS Code Marketplace Publisher
If the user does not have a Publisher:
- Direct them to https://marketplace.visualstudio.com/manage
- Sign in with a Microsoft account (create one if needed)
- Click "Create Publisher" and configure:
- ID: A unique identifier (cannot be changed later; all lowercase, hyphens allowed)
- Name: The name displayed on the marketplace
- Ask for the created Publisher ID
1-2: Creating an Azure DevOps PAT
If the user does not have a PAT:
- Go to https://aex.dev.azure.com (using
dev.azure.commay redirect to the Azure DevOps product page, so use this URL instead) - Sign in with a Microsoft account. If no organization exists, create one with any name
- Once the organization is created, go directly to the PAT creation page:
https://dev.azure.com/<org-name>/_usersSettings/tokens - Click "New Token" and configure:
- Name: Any name (e.g.,
vscode-marketplace) - Organization: Select "All accessible organizations" (this is important — selecting a specific org may cause 403 errors)
- Expiration: Any duration (up to 1 year)
- Scopes: Select "Custom defined" → Click "Show all scopes" → Check Marketplace → Manage
- Name: Any name (e.g.,
- Tell the user to copy and securely save the token (it is only displayed once)
1-3: Creating an Open VSX Account
If the user does not have an account:
- Create an Eclipse account at https://accounts.eclipse.org
- GitHub account linking is required, so verify the GitHub username is correct
- Log in to https://open-vsx.org with GitHub
- Authenticate with the Eclipse account from profile settings
- Review and accept the Publisher Agreement
1-4: Creating an Open VSX Access Token
If the user does not have a token:
- Go to https://open-vsx.org → Settings → Access Tokens
- Click "Generate New Token" to create a token
- Tell the user to copy and securely save the token (it is only displayed once)
1-5: Creating an Open VSX Namespace
Open VSX requires a "Namespace" corresponding to the Publisher ID. Create one with the same name as the user's Publisher ID:
npx ovsx create-namespace <publisher-id> -p <openvsx-token>
Skip this step if the namespace already exists.
Phase 2: Pre-publish Preparation
2-1: Validating and Fixing package.json
Read the package.json and validate the following fields. Suggest fixes for any missing or incorrect values.
Required fields:
| Field | Description | Example |
|---|---|---|
name |
Extension identifier | my-extension |
displayName |
Name displayed on the marketplace | My Extension |
description |
Brief description | A helpful VSCode extension |
version |
SemVer format | 0.1.0 |
publisher |
Publisher ID (confirmed in Phase 1) | my-publisher |
engines.vscode |
Supported VSCode version | ^1.80.0 |
categories |
Categories (array) | ["Other"] |
Recommended fields:
| Field | Description | Example |
|---|---|---|
icon |
Icon image path (PNG, 128x128 or larger) | icon.png |
repository |
GitHub repository URL | {"type": "git", "url": "https://github.com/..."} |
license |
License | MIT |
keywords |
Search keywords (up to 30) | ["vscode", "tool"] |
homepage |
Homepage URL | Can be the same as the repository URL |
bugs |
Issue tracker URL | {"url": "https://github.com/.../issues"} |
About activationEvents:
- Even without
activationEventsinpackage.json, VSCode can automatically infer them from thecontributessection, so explicit declaration is often unnecessary - However, if
*(activate on all events) is used, suggest narrowing it to specific events
About engines.vscode:
- Specify the minimum VSCode API version required by the extension
- If unknown, suggest a relatively recent version like
^1.80.0
2-2: Preparing README.md
The README becomes the body of the extension page on the marketplace. Suggest the following structure:
# Extension Name
Brief description (1-2 sentences)
## Features
- Description of feature 1
- Description of feature 2
(Screenshots or GIFs are recommended)
## Usage
How to use the extension
## Extension Settings
Describe settings if any
## Release Notes
### x.x.x
- Changes
If a README already exists, only suggest additions for missing sections. Do not over-rewrite.
2-3: LICENSE File
If no LICENSE file exists, suggest creating one. Ensure it matches the license field in package.json.
2-4: CHANGELOG.md
If no CHANGELOG exists, create a minimal one:
# Changelog
## [0.1.0]
- Initial release
2-5: Preparing .vscodeignore
If .vscodeignore does not exist, create one. Exclude development files to keep the package size small:
.vscode/**
.vscode-test/**
.github/**
src/**
node_modules/**
.gitignore
.eslintrc*
tsconfig.json
*.ts
!*.d.ts
**/*.map
For TypeScript projects, exclude source files and only include compiled files. Adjust according to the actual project structure.
2-6: Icon Generation
If package.json has "icon": "icon.png" but the file does not exist, or if the icon field is missing entirely, generate an icon.
- Generate an SVG representing the extension's functionality (create a temporary file
_generate-icon.mjs):
// _generate-icon.mjs
import { writeFileSync } from "fs";
const size = 256;
const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 256 256">
<defs>
<linearGradient id="bg" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#1a1a2e"/>
<stop offset="100%" style="stop-color:#16213e"/>
</linearGradient>
</defs>
<rect width="256" height="256" rx="32" fill="url(#bg)"/>
<!-- Design an icon here that represents the extension's functionality -->
</svg>`;
writeFileSync("icon.svg", svg);
- Convert SVG to PNG:
node _generate-icon.mjs
npx sharp-cli -i icon.svg -o icon.png resize 256 256
- Delete temporary files:
rm _generate-icon.mjs icon.svg
- Add
"icon": "icon.png"to package.json if not already present
Note: The icon must be a PNG file of at least 128x128 pixels. 256x256 is recommended. Adjust the SVG content to match the extension's functionality.
2-7: vscode:prepublish Script
For TypeScript projects, check that package.json has a vscode:prepublish script in scripts:
{
"scripts": {
"vscode:prepublish": "npm run compile"
}
}
Adjust the build command to match the project's actual setup (tsc, esbuild, webpack, etc.).
Phase 3: Local Testing
Before publishing, verify that the extension works correctly. Fixing issues here prevents problems after publishing.
3-1: Testing with Extension Development Host
Guide the user through the following:
- Open the project folder in VSCode
- Press
F5(or go to "Run and Debug" → "Run Extension") to launch the Extension Development Host - In the new VSCode window, verify the extension's functionality:
- Do registered commands appear in the Command Palette (
Ctrl+Shift+P/Cmd+Shift+P)? - Does each feature work as expected?
- Are there any errors in the Debug Console?
- Do registered commands appear in the Command Palette (
If .vscode/launch.json does not exist, create it:
{
"version": "0.2.0",
"configurations": [
{
"name": "Run Extension",
"type": "extensionHost",
"request": "launch",
"args": ["--extensionDevelopmentPath=${workspaceFolder}"]
}
]
}
3-2: Testing from .vsix File
Verify the extension works correctly when packaged:
npx @vscode/vsce package
Install the generated .vsix file in VSCode to verify:
code --install-extension <name>-<version>.vsix
After installation, guide the user to restart VSCode and verify the extension works correctly. Once testing is complete, uninstall the test extension:
code --uninstall-extension <publisher>.<name>
Phase 4: Initial Publish
4-1: Package Creation (Dry Run)
First, install vsce and create a package:
npx @vscode/vsce package
Check the output:
- Is the file size reasonable?
- Are any unnecessary files included?
- Are there any warnings or errors?
If there are issues, go back to Phase 2 and fix them.
4-2: Publish to VS Code Marketplace
Confirm with the user before publishing.
npx @vscode/vsce publish
The user will be prompted to enter the PAT — they should paste it in the terminal. Have the user run this command.
On success, share the marketplace URL:
https://marketplace.visualstudio.com/items?itemName=<publisher>.<extension-name>
Note: It may take a few minutes for the extension to appear.
4-3: Publish to Open VSX
Use the same .vsix file created for VS Code Marketplace:
npx ovsx publish <file>.vsix -p <openvsx-token>
Or publish directly from source:
npx ovsx publish -p <openvsx-token>
On success, share the Open VSX URL:
https://open-vsx.org/extension/<namespace>/<extension-name>
4-4: Post-publish Verification
Verify the extension appears on both marketplaces:
# VS Code Marketplace
npx @vscode/vsce show <publisher>.<extension-name>
# Open VSX (check in browser)
# https://open-vsx.org/extension/<namespace>/<extension-name>
4-5: Claiming Open VSX Namespace Ownership
After publishing to Open VSX, the extension page may display a "not a verified publisher" warning banner. To resolve this, you need to claim namespace ownership.
Create an issue in the EclipseFdn/open-vsx.org repository using the gh command:
gh issue create --repo EclipseFdn/open-vsx.org \
--title "Claiming namespace <publisher-id>" \
--label "namespace,operations" \
--body "I am the owner of the GitHub account https://github.com/<github-username> and I would like to claim ownership of the \`<publisher-id>\` namespace on Open VSX. I have already logged in to https://open-vsx.org and published an extension (<extension-name>) under this namespace."
It may take several days for Eclipse Foundation staff to review and approve the request. Once approved, the warning banner will be removed and a verified badge will appear.
Prerequisite: The user must have logged in to https://open-vsx.org at least once.
Phase 5: GitHub Actions Setup
5-1: Configuring Secrets
Guide the user to add secrets to the GitHub repository:
- Go to repository Settings → Secrets and variables → Actions
- Add the following secrets:
VSCE_PAT: Azure DevOps PAT (for VS Code Marketplace)OVSX_PAT: Open VSX Access Token
5-2: Creating the Workflow File
Create .github/workflows/publish.yml:
name: Publish Extension
on:
push:
tags:
- "*"
jobs:
publish:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
- run: npm ci
- name: Publish to VS Code Marketplace
run: npx @vscode/vsce publish -p ${{ secrets.VSCE_PAT }}
- name: Publish to Open VSX
run: npx ovsx publish -p ${{ secrets.OVSX_PAT }}
Adjust according to the project setup:
- Package manager: Change
npm cito match npm / yarn / pnpm - Build step: If
vscode:prepublishis defined,vsce publishruns it automatically, so a separate build step is usually unnecessary - Node.js version: Match the project's requirements
- Do NOT add
npm test: VSCode extension tests (vscode-test) require a display server (X11) which is unavailable on standard CI runners, causingSIGSEGVcrashes. If tests are needed in CI, usexvfb-runor a separate workflow
5-3: Release Flow Explanation
Explain the release process to the user:
# 1. Update the version (automatically creates a commit and tag)
npm version patch # or minor, major
# 2. Push with tags → GitHub Actions automatically publishes
git push --follow-tags
This triggers automatic publishing to both marketplaces whenever a tag is pushed.
Troubleshooting
| Error | Cause | Solution |
|---|---|---|
403 Forbidden (vsce) |
PAT scope is incorrect, or Organization is not set to "All accessible organizations" | Recreate the PAT and verify the Org setting and Marketplace Manage scope |
Extension name already exists |
An extension with the same name already exists | Change the name in package.json |
Missing publisher |
publisher is missing from package.json |
Add the publisher field |
| Namespace mismatch (ovsx) | The Open VSX Namespace does not exist or does not match the publisher | Create it with npx ovsx create-namespace |
| Icon-related errors | Icon is smaller than 128x128 or is not a PNG | Provide a PNG file of at least 128x128 |
More from mrsekut/agent-skills
chrome-store-submit
Automate new Chrome extension submission to Chrome Web Store using playwright-mcp. Reads manifest.json and source code, generates store listing text in any language, creates store images, and fills all required forms via browser automation. Use when submitting a new Chrome extension to Chrome Web Store, publishing a Chrome extension, or filling Chrome Web Store developer dashboard forms.
20cosense-conversation
Cosense(旧Scrapbox)上での会話記法を理解し、Cosense MCPを通じてページに書き込む際にCosense流の書き方で応答する。Cosenseのページに書き込むとき、Cosense上で会話・返答するとき、Cosense MCPを使うときにこのスキルを適用する。
12bun-publish-setup
First-time npm publish for bun libraries and GitHub Actions setup for automated publishing. Validates/fixes package.json, performs initial publish, and configures CI/CD workflow.
11claude-code-copy-markdown
Copy Claude Code's previous response (or a specific part of the conversation output) to the clipboard as clean Markdown. Trigger phrases include "copy this", "copy to clipboard", "markdown copy", "md copy", "I want to copy this", "copy the last output", "paste this somewhere", etc. Do NOT use this skill when the user explicitly asks to write to a file — just write to a file normally in that case. Trigger this skill proactively whenever the user wants to "copy", "paste", "share", or "export" Claude Code output.
9curated-skill-creator
既存のスキルやインターネット上の類似事例をリサーチし、ユーザーの要望と組み合わせて高品質なClaude Codeスキルを作成するスキル。新しいスキルを作りたい、スキルのアイデアがある、こういうワークフローを自動化したい、といった場面で使う。既存のskill-creatorとの違いは、インターネット上の類似スキルやプロンプト、ベストプラクティスをリサーチして取り込むフェーズがあること。スキルを作りたい、ワークフローをスキル化したい、と言われたらこのスキルを使うこと。
2sdd
>
1