diff --git a/.github/WORKFLOWS.md b/.github/WORKFLOWS.md index d2f57d11..82e6298c 100644 --- a/.github/WORKFLOWS.md +++ b/.github/WORKFLOWS.md @@ -50,6 +50,17 @@ This document describes all the GitHub Actions workflows configured for the Obje - Reminds contributors to add changesets - Comments on PRs with changelog preview +### 📦 [publish-vscode-extension.yml](workflows/publish-vscode-extension.yml) ✨ NEW +**Purpose:** Publish VSCode extension to marketplace +**Triggers:** Manual dispatch, Git tags (`vscode-v*.*.*`) +**What it does:** +- Builds the ObjectQL VSCode extension +- Packages the extension as `.vsix` file +- Publishes to VSCode Marketplace (requires VSCE_PAT secret) +- Creates GitHub Release with VSIX artifact +- Supports dry-run mode for testing +- See [PUBLISHING.md](../packages/tools/vscode-objectql/PUBLISHING.md) for detailed instructions + ## Code Quality & Security ### 🔒 [codeql.yml](workflows/codeql.yml) diff --git a/.github/workflows/publish-vscode-extension.yml b/.github/workflows/publish-vscode-extension.yml new file mode 100644 index 00000000..1bf43b86 --- /dev/null +++ b/.github/workflows/publish-vscode-extension.yml @@ -0,0 +1,133 @@ +name: Publish VSCode Extension + +on: + workflow_dispatch: + inputs: + version: + description: 'Version to publish (leave empty to use version from package.json)' + required: false + type: string + dry_run: + description: 'Dry run (package only, do not publish)' + required: false + type: boolean + default: false + push: + tags: + - 'vscode-v*.*.*' + +permissions: + contents: write + issues: write + pull-requests: write + +jobs: + publish: + name: Package and Publish VSCode Extension + runs-on: ubuntu-latest + timeout-minutes: 15 + + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + + - name: Install pnpm + uses: pnpm/action-setup@v3 + with: + version: 10 + run_install: false + + - name: Get pnpm store directory + shell: bash + run: | + echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV + + - name: Setup pnpm cache + uses: actions/cache@v4 + with: + path: ${{ env.STORE_PATH }} + key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: | + ${{ runner.os }}-pnpm-store- + + - name: Install Dependencies + run: pnpm install + timeout-minutes: 3 + + - name: Build Monorepo + run: pnpm run build + timeout-minutes: 5 + + - name: Build VSCode Extension + working-directory: packages/tools/vscode-objectql + run: pnpm run compile + + - name: Update Version (if specified) + if: inputs.version != '' + working-directory: packages/tools/vscode-objectql + run: | + echo "Updating version to ${{ inputs.version }}" + npm version ${{ inputs.version }} --no-git-tag-version + + - name: Package Extension + working-directory: packages/tools/vscode-objectql + run: | + npx @vscode/vsce package --no-yarn + echo "VSIX_FILE=$(ls *.vsix)" >> $GITHUB_ENV + + - name: Upload VSIX as Artifact + uses: actions/upload-artifact@v4 + with: + name: vscode-objectql-extension + path: packages/tools/vscode-objectql/*.vsix + retention-days: 30 + + - name: Publish to VSCode Marketplace + if: inputs.dry_run != true + working-directory: packages/tools/vscode-objectql + env: + VSCE_PAT: ${{ secrets.VSCE_PAT }} + run: | + if [ -z "$VSCE_PAT" ]; then + echo "::error::VSCE_PAT secret is not set. Cannot publish to marketplace." + exit 1 + fi + npx @vscode/vsce publish --no-yarn --pat "$VSCE_PAT" + + - name: Create GitHub Release + if: inputs.dry_run != true && startsWith(github.ref, 'refs/tags/') + uses: softprops/action-gh-release@v1 + with: + files: packages/tools/vscode-objectql/*.vsix + generate_release_notes: true + draft: false + prerelease: false + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Summary + run: | + echo "## 🎉 VSCode Extension Build Complete" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "### Package Details" >> $GITHUB_STEP_SUMMARY + echo "- **VSIX File:** \`${{ env.VSIX_FILE }}\`" >> $GITHUB_STEP_SUMMARY + echo "- **Dry Run:** ${{ inputs.dry_run }}" >> $GITHUB_STEP_SUMMARY + if [ "${{ inputs.dry_run }}" == "true" ]; then + echo "- **Status:** ✅ Packaged (not published)" >> $GITHUB_STEP_SUMMARY + else + echo "- **Status:** ✅ Published to VSCode Marketplace" >> $GITHUB_STEP_SUMMARY + fi + echo "" >> $GITHUB_STEP_SUMMARY + echo "### Next Steps" >> $GITHUB_STEP_SUMMARY + if [ "${{ inputs.dry_run }}" == "true" ]; then + echo "- Download the VSIX artifact to test locally" >> $GITHUB_STEP_SUMMARY + echo "- Install in VSCode: Extensions → Install from VSIX" >> $GITHUB_STEP_SUMMARY + else + echo "- Extension is now available in VSCode Marketplace" >> $GITHUB_STEP_SUMMARY + echo "- Search for 'ObjectQL' in VSCode Extensions" >> $GITHUB_STEP_SUMMARY + fi diff --git a/packages/tools/vscode-objectql/.vscodeignore b/packages/tools/vscode-objectql/.vscodeignore index 1334f997..969a9fc9 100644 --- a/packages/tools/vscode-objectql/.vscodeignore +++ b/packages/tools/vscode-objectql/.vscodeignore @@ -4,6 +4,9 @@ src/** .gitignore .vscodeignore tsconfig.json +tsconfig.tsbuildinfo test-workspace/** node_modules/** *.vsix +CONTRIBUTING.md +IMPLEMENTATION-SUMMARY.md diff --git a/packages/tools/vscode-objectql/LICENSE b/packages/tools/vscode-objectql/LICENSE new file mode 100644 index 00000000..c4a3ad12 --- /dev/null +++ b/packages/tools/vscode-objectql/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 ObjectQL Contributors (https://github.com/objectql) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/tools/vscode-objectql/PUBLISHING.md b/packages/tools/vscode-objectql/PUBLISHING.md new file mode 100644 index 00000000..b35069df --- /dev/null +++ b/packages/tools/vscode-objectql/PUBLISHING.md @@ -0,0 +1,258 @@ +# Publishing the VSCode Extension + +This guide explains how to publish the ObjectQL VSCode extension to the Visual Studio Code Marketplace using the automated GitHub Actions workflow. + +## Prerequisites + +### 1. Visual Studio Code Publisher Account + +You need a publisher account to publish extensions: + +1. Visit [Visual Studio Marketplace](https://marketplace.visualstudio.com/manage) +2. Sign in with your Azure DevOps account (or create one) +3. Create a publisher if you don't have one +4. Note your publisher ID (must match the `publisher` field in `package.json`) + +### 2. Personal Access Token (PAT) + +Create a PAT for publishing: + +1. Go to [Azure DevOps](https://dev.azure.com/) +2. Click on User Settings → Personal Access Tokens +3. Create a new token with: + - **Organization:** All accessible organizations + - **Expiration:** Set appropriate expiration date + - **Scopes:** Select `Marketplace` → `Manage` +4. Copy the token (you won't be able to see it again) + +### 3. Configure GitHub Secret + +Add the PAT as a GitHub repository secret: + +1. Go to your repository on GitHub +2. Navigate to Settings → Secrets and variables → Actions +3. Click "New repository secret" +4. Name: `VSCE_PAT` +5. Value: Paste your Personal Access Token +6. Click "Add secret" + +## Publishing Methods + +### Method 1: Manual Workflow Dispatch (Recommended) + +This method allows you to publish on-demand through the GitHub Actions UI: + +1. Go to the repository on GitHub +2. Click on "Actions" tab +3. Select "Publish VSCode Extension" workflow +4. Click "Run workflow" button +5. Configure options: + - **Version:** Leave empty to use current version, or specify a version (e.g., `2.0.1`) + - **Dry run:** Check to only package (test build) without publishing +6. Click "Run workflow" + +**Use Cases:** +- **Test Build:** Enable "Dry run" to package and download the VSIX for local testing +- **Regular Release:** Leave defaults to publish the current version +- **Version Bump:** Specify a new version to update and publish + +### Method 2: Git Tag-based Release + +Automatically publish when you create a version tag: + +```bash +# Create and push a tag for the VSCode extension +git tag vscode-v2.0.1 +git push origin vscode-v2.0.1 +``` + +This will: +- Automatically build and publish the extension +- Create a GitHub Release with the VSIX file attached +- Make the extension available on the VSCode Marketplace + +## Workflow Steps + +The automated workflow performs the following steps: + +1. **Environment Setup** + - Checkout repository + - Setup Node.js 20 + - Install pnpm + - Cache dependencies + +2. **Build** + - Install all monorepo dependencies + - Build the entire monorepo + - Compile the VSCode extension TypeScript code + +3. **Package** + - Run `vsce package` to create the `.vsix` file + - Upload VSIX as GitHub Actions artifact (available for 30 days) + +4. **Publish** (skipped if dry run) + - Authenticate with VSCE_PAT + - Publish to VSCode Marketplace using `vsce publish` + +5. **Release** (for git tags only) + - Create GitHub Release + - Attach VSIX file to the release + - Generate release notes + +## Version Management + +The extension version is managed in `packages/tools/vscode-objectql/package.json`: + +```json +{ + "name": "vscode-objectql", + "version": "2.0.0", + ... +} +``` + +### Updating the Version + +**Option 1: Manual (before triggering workflow)** +```bash +cd packages/tools/vscode-objectql +npm version patch # 2.0.0 → 2.0.1 +npm version minor # 2.0.0 → 2.1.0 +npm version major # 2.0.0 → 3.0.0 +git add package.json +git commit -m "chore(vscode): bump version to X.Y.Z" +git push +``` + +**Option 2: Automatic (via workflow input)** + +When running the workflow manually, you can specify the version in the input field, and the workflow will update `package.json` before publishing. + +## Testing Before Publishing + +Always test the extension locally before publishing: + +### 1. Build Locally + +```bash +# From repository root +pnpm install +pnpm run build + +# Navigate to extension directory +cd packages/tools/vscode-objectql + +# Compile TypeScript +pnpm run compile + +# Package the extension +pnpm run package +``` + +This creates a `.vsix` file in the `packages/tools/vscode-objectql` directory. + +### 2. Install in VSCode + +1. Open VSCode +2. Go to Extensions view (Ctrl+Shift+X / Cmd+Shift+X) +3. Click the "..." menu → "Install from VSIX..." +4. Select the generated `.vsix` file +5. Test all features + +### 3. Dry Run with Workflow + +Use the workflow with "Dry run" enabled to test the CI/CD build: + +1. Run workflow with dry run option checked +2. Download the VSIX artifact from the workflow run +3. Install and test in VSCode + +## Troubleshooting + +### "VSCE_PAT secret is not set" + +**Problem:** The workflow cannot find the authentication token. + +**Solution:** +1. Verify the secret is named exactly `VSCE_PAT` +2. Check it exists in Settings → Secrets and variables → Actions +3. Ensure it has not expired + +### "Error: Failed request: Unauthorized (401)" + +**Problem:** The PAT is invalid or has expired. + +**Solution:** +1. Generate a new PAT in Azure DevOps +2. Update the `VSCE_PAT` secret in GitHub +3. Ensure the PAT has `Marketplace: Manage` scope + +### "Error: Publisher name does not match" + +**Problem:** The publisher in `package.json` doesn't match your VSCode Marketplace publisher. + +**Solution:** +1. Check your publisher ID at https://marketplace.visualstudio.com/manage +2. Update the `publisher` field in `packages/tools/vscode-objectql/package.json` +3. Commit and push the change + +### "Extension already exists with version X.Y.Z" + +**Problem:** You're trying to publish a version that already exists. + +**Solution:** +1. Increment the version number in `package.json` +2. Or specify a new version when running the workflow + +## Best Practices + +1. **Version Strategy** + - Use semantic versioning (MAJOR.MINOR.PATCH) + - Increment PATCH for bug fixes + - Increment MINOR for new features + - Increment MAJOR for breaking changes + +2. **Pre-release Testing** + - Always test locally before publishing + - Use dry run to validate the CI build + - Review the packaged VSIX contents + +3. **Changelog** + - Update `CHANGELOG.md` before publishing + - Document all changes since last release + - Follow Keep a Changelog format + +4. **Security** + - Rotate PAT tokens regularly + - Use repository secrets, never commit tokens + - Set appropriate token expiration dates + +5. **Release Notes** + - Use git tags for automatic release notes + - Write descriptive commit messages + - Link to issues/PRs in commits + +## Monitoring + +After publishing: + +1. **VSCode Marketplace** + - Check https://marketplace.visualstudio.com/items?itemName=objectstack-ai.vscode-objectql + - Verify the new version appears + - Test installation via VSCode + +2. **GitHub Release** + - Check the Releases page for the new version + - Verify VSIX file is attached + - Review auto-generated release notes + +3. **User Feedback** + - Monitor marketplace reviews + - Watch GitHub issues for bug reports + - Check analytics for install/update metrics + +## Related Documentation + +- [VSCode Extension Publishing](https://code.visualstudio.com/api/working-with-extensions/publishing-extension) +- [vsce CLI Reference](https://github.com/microsoft/vscode-vsce) +- [GitHub Actions Documentation](https://docs.github.com/en/actions) diff --git a/packages/tools/vscode-objectql/README.md b/packages/tools/vscode-objectql/README.md index e776e6c0..2cc6169e 100644 --- a/packages/tools/vscode-objectql/README.md +++ b/packages/tools/vscode-objectql/README.md @@ -1,6 +1,6 @@ # ObjectQL - Visual Studio Code Extension -![ObjectQL Logo](images/icon.svg) +![ObjectQL Logo](images/icon.png) **The Standard Protocol for AI Software Generation** @@ -281,6 +281,15 @@ indexes: Contributions are welcome! Please see the main repository for contribution guidelines. +### For Maintainers: Publishing + +This extension is automatically published to the VSCode Marketplace using GitHub Actions. See [PUBLISHING.md](PUBLISHING.md) for detailed instructions on: + +- Configuring VSCode Marketplace credentials +- Publishing via GitHub Actions workflow +- Version management +- Testing before publishing + --- ## 📄 License diff --git a/packages/tools/vscode-objectql/images/icon-generation.md b/packages/tools/vscode-objectql/images/icon-generation.md deleted file mode 100644 index b64db926..00000000 --- a/packages/tools/vscode-objectql/images/icon-generation.md +++ /dev/null @@ -1,29 +0,0 @@ -# Icon Generation Guide - -The extension icon needs to be in PNG format (128x128 pixels). - -## Using Online Converters - -1. Go to https://cloudconvert.com/svg-to-png -2. Upload `images/icon.svg` -3. Set dimensions to 128x128 -4. Download and save as `images/icon.png` - -## Using ImageMagick (if available) - -```bash -convert -background none -resize 128x128 images/icon.svg images/icon.png -``` - -## Using Node.js sharp library - -```bash -npm install sharp -node -e "require('sharp')('images/icon.svg').resize(128,128).toFile('images/icon.png')" -``` - -## Temporary Workaround - -For now, we've included the SVG. To complete the extension: -1. Convert icon.svg to icon.png using one of the methods above -2. Update package.json if needed diff --git a/packages/tools/vscode-objectql/images/icon.png b/packages/tools/vscode-objectql/images/icon.png new file mode 100644 index 00000000..089b58d9 Binary files /dev/null and b/packages/tools/vscode-objectql/images/icon.png differ diff --git a/packages/tools/vscode-objectql/images/icon.png.placeholder b/packages/tools/vscode-objectql/images/icon.png.placeholder deleted file mode 100644 index 16a56a29..00000000 --- a/packages/tools/vscode-objectql/images/icon.png.placeholder +++ /dev/null @@ -1,3 +0,0 @@ -# This is a placeholder. The actual PNG icon should be generated from icon.svg -# You can use an online SVG to PNG converter or ImageMagick: -# convert -background none -resize 128x128 images/icon.svg images/icon.png diff --git a/packages/tools/vscode-objectql/package.json b/packages/tools/vscode-objectql/package.json index a93827eb..d97fdfad 100644 --- a/packages/tools/vscode-objectql/package.json +++ b/packages/tools/vscode-objectql/package.json @@ -11,6 +11,7 @@ "engines": { "vscode": "^1.85.0" }, + "icon": "images/icon.png", "categories": [ "Programming Languages", "Snippets",