Release #4
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # VS Code Extension Release Workflow | |
| # This workflow builds, tests, packages, and publishes VS Code extensions | |
| # Triggers on GitHub releases and supports both stable and pre-releases | |
| name: Release VS Code Extension | |
| on: | |
| release: | |
| types: [published, prereleased] | |
| workflow_dispatch: | |
| inputs: | |
| release_type: | |
| description: "Release type" | |
| required: true | |
| default: "patch" | |
| type: choice | |
| options: | |
| - patch | |
| - minor | |
| - major | |
| - prerelease | |
| marketplace_publish: | |
| description: "Publish to VS Code Marketplace" | |
| required: false | |
| default: true | |
| type: boolean | |
| openvsx_publish: | |
| description: "Publish to Open VSX Registry" | |
| required: false | |
| default: true | |
| type: boolean | |
| # Set permissions for the workflow | |
| permissions: | |
| contents: read | |
| id-token: write | |
| actions: read | |
| security-events: write | |
| jobs: | |
| release: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 # Fetch all history for proper versioning | |
| - name: Setup pnpm | |
| uses: pnpm/action-setup@v4 | |
| with: | |
| version: 9 | |
| run_install: false # We'll handle installation manually for better caching | |
| - 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: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: "20" | |
| cache: "pnpm" | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Install vsce and ovsx | |
| run: | | |
| pnpm add -D @vscode/vsce | |
| pnpm add -D ovsx | |
| # Run tests if they exist | |
| - name: Run tests | |
| run: | | |
| if [ -f "package.json" ] && grep -q '"test"' package.json; then | |
| pnpm test | |
| else | |
| echo "No tests found, skipping test step" | |
| fi | |
| continue-on-error: false | |
| # Build/compile if build script exists | |
| - name: Build extension | |
| run: | | |
| if [ -f "package.json" ] && grep -q '"build"' package.json; then | |
| pnpm run build | |
| elif [ -f "package.json" ] && grep -q '"compile"' package.json; then | |
| pnpm run compile | |
| else | |
| echo "No build/compile script found, skipping build step" | |
| fi | |
| # Package the extension | |
| - name: Package extension | |
| id: package | |
| run: | | |
| if [ -f "package.json" ] && grep -q '"package"' package.json; then | |
| pnpm run package | |
| else | |
| # Use vsce directly if no package script | |
| npx vsce package --no-dependencies | |
| fi | |
| # Get the generated VSIX filename | |
| VSIX_FILE=$(ls *.vsix | head -1) | |
| echo "vsix_file=$VSIX_FILE" >> $GITHUB_OUTPUT | |
| echo "Generated VSIX: $VSIX_FILE" | |
| # Validate the package | |
| - name: Validate package | |
| run: | | |
| VSIX_FILE="${{ steps.package.outputs.vsix_file }}" | |
| if [ ! -f "$VSIX_FILE" ]; then | |
| echo "ERROR: VSIX file not found: $VSIX_FILE" | |
| exit 1 | |
| fi | |
| # Check file size (should be reasonable) | |
| FILE_SIZE=$(stat -c%s "$VSIX_FILE") | |
| if [ $FILE_SIZE -lt 1000 ]; then | |
| echo "ERROR: VSIX file seems too small: $FILE_SIZE bytes" | |
| exit 1 | |
| fi | |
| echo "VSIX validation passed. File size: $FILE_SIZE bytes" | |
| # Determine if this is a pre-release | |
| - name: Check if pre-release | |
| id: prerelease | |
| run: | | |
| if [[ "${{ github.event.release.prerelease }}" == "true" ]]; then | |
| echo "is_prerelease=true" >> $GITHUB_OUTPUT | |
| echo "This is a pre-release" | |
| else | |
| echo "is_prerelease=false" >> $GITHUB_OUTPUT | |
| echo "This is a stable release" | |
| fi | |
| # Publish to VS Code Marketplace | |
| - name: Publish to VS Code Marketplace | |
| if: | | |
| (github.event_name == 'release' || | |
| (github.event_name == 'workflow_dispatch' && inputs.marketplace_publish)) && | |
| env.VSCE_PAT != '' | |
| env: | |
| VSCE_PAT: ${{ secrets.VSCE_PAT }} | |
| run: | | |
| VSIX_FILE="${{ steps.package.outputs.vsix_file }}" | |
| if [[ "${{ steps.prerelease.outputs.is_prerelease }}" == "true" ]]; then | |
| echo "Publishing pre-release to VS Code Marketplace..." | |
| npx vsce publish --packagePath "$VSIX_FILE" --pre-release | |
| else | |
| echo "Publishing stable release to VS Code Marketplace..." | |
| npx vsce publish --packagePath "$VSIX_FILE" | |
| fi | |
| # Publish to Open VSX Registry | |
| - name: Publish to Open VSX Registry | |
| if: | | |
| (github.event_name == 'release' || | |
| (github.event_name == 'workflow_dispatch' && inputs.openvsx_publish)) && | |
| env.OVSX_PAT != '' | |
| env: | |
| OVSX_PAT: ${{ secrets.OVSX_PAT }} | |
| run: | | |
| VSIX_FILE="${{ steps.package.outputs.vsix_file }}" | |
| echo "Publishing to Open VSX Registry..." | |
| npx ovsx publish "$VSIX_FILE" --pat $OVSX_PAT | |
| # Upload VSIX to GitHub Release | |
| - name: Upload VSIX to GitHub Release | |
| if: github.event_name == 'release' | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| files: ${{ steps.package.outputs.vsix_file }} | |
| fail_on_unmatched_files: true | |
| generate_release_notes: true | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| # Upload as workflow artifact (for manual runs) | |
| - name: Upload VSIX as artifact | |
| if: github.event_name == 'workflow_dispatch' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: vscode-extension-${{ github.run_number }} | |
| path: ${{ steps.package.outputs.vsix_file }} | |
| retention-days: 30 | |
| # Summary | |
| - name: Release Summary | |
| run: | | |
| echo "## Release Summary" >> $GITHUB_STEP_SUMMARY | |
| echo "- **Extension package**: ${{ steps.package.outputs.vsix_file }}" >> $GITHUB_STEP_SUMMARY | |
| echo "- **Pre-release**: ${{ steps.prerelease.outputs.is_prerelease }}" >> $GITHUB_STEP_SUMMARY | |
| echo "- **VS Code Marketplace**: ${{ env.VSCE_PAT != '' && 'Published' || 'Skipped (no PAT)' }}" >> $GITHUB_STEP_SUMMARY | |
| echo "- **Open VSX Registry**: ${{ env.OVSX_PAT != '' && 'Published' || 'Skipped (no PAT)' }}" >> $GITHUB_STEP_SUMMARY | |
| env: | |
| VSCE_PAT: ${{ secrets.VSCE_PAT }} | |
| OVSX_PAT: ${{ secrets.OVSX_PAT }} |