Release VS Code Extension #9
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 - Final Fixed Version | |
| 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: Setup Bun | |
| uses: oven-sh/setup-bun@v1 | |
| with: | |
| bun-version: latest | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Install vsce and ovsx | |
| run: | | |
| pnpm add -D @vscode/vsce | |
| pnpm add -D ovsx | |
| # Setup headless environment for VS Code tests | |
| - name: Setup headless environment | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y xvfb libasound2-dev libgtk-3-dev libnss3-dev | |
| # Run tests with xvfb for headless mode | |
| - name: Run tests | |
| run: | | |
| export DISPLAY=:99.0 | |
| export XDG_RUNTIME_DIR=/run/user/$(id -u) | |
| export DBUS_SESSION_BUS_ADDRESS=unix:path=$XDG_RUNTIME_DIR/bus | |
| # Start D-Bus session | |
| mkdir -p $XDG_RUNTIME_DIR | |
| dbus-daemon --session --address=$DBUS_SESSION_BUS_ADDRESS --nofork --nopidfile --syslog-only & | |
| # Start Xvfb with proper configuration | |
| Xvfb :99 -screen 0 1024x768x24 -ac +extension GLX +render -noreset > /dev/null 2>&1 & | |
| # Wait for Xvfb to start | |
| sleep 3 | |
| # Create VS Code config to disable hardware acceleration | |
| mkdir -p ~/.vscode | |
| echo '{ "disable-hardware-acceleration": true }' > ~/.vscode/argv.json | |
| # Run tests | |
| if [ -f "package.json" ] && grep -q '"test"' package.json; then | |
| xvfb-run -a --server-args="-screen 0 1024x768x24 -ac +extension GLX +render -noreset" 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 with dependency fix | |
| - name: Package extension | |
| id: package | |
| run: | | |
| # Clean up any problematic dependencies first | |
| npm ls --production --parseable --depth=99999 --loglevel=error || true | |
| if [ -f "package.json" ] && grep -q '"package"' package.json; then | |
| pnpm run package --no-dependencies | |
| else | |
| # Use vsce directly if no package script with production dependencies flag | |
| 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 }} |