name: Release
on:
workflow_dispatch:
inputs:
release-type:
description: 'Release type'
required: true
default: 'patch'
type: choice
options:
- patch
- minor
- major
- prerelease-alpha
- prerelease-beta
dry-run:
description: 'Dry run (no actual release)'
required: false
default: false
type: boolean
env:
NODE_VERSION: '20.x'
jobs:
release:
name: Create Release
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop'
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Configure Git
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
- name: Run CI checks
run: npm run ci:check
- name: Dry run release
if: inputs.dry-run == true
run: |
case "${{ inputs.release-type }}" in
"patch")
npm run release:dry-run -- --release-as patch
;;
"minor")
npm run release:dry-run -- --release-as minor
;;
"major")
npm run release:dry-run -- --release-as major
;;
"prerelease-alpha")
npm run release:dry-run -- --prerelease alpha
;;
"prerelease-beta")
npm run release:dry-run -- --prerelease beta
;;
esac
- name: Create release
if: inputs.dry-run == false
run: |
case "${{ inputs.release-type }}" in
"patch")
npm run release:patch
;;
"minor")
npm run release:minor
;;
"major")
npm run release:major
;;
"prerelease-alpha")
npm run release:alpha
;;
"prerelease-beta")
npm run release:beta
;;
esac
- name: Push changes
if: inputs.dry-run == false
run: |
git push --follow-tags origin main
- name: Get new version
if: inputs.dry-run == false
id: version
run: |
echo "version=$(node -p "require('./package.json').version")" >> $GITHUB_OUTPUT
echo "tag=v$(node -p "require('./package.json').version")" >> $GITHUB_OUTPUT
- name: Install VSCE
if: inputs.dry-run == false
run: npm install -g @vscode/vsce
- name: Package extension
if: inputs.dry-run == false
run: vsce package
- name: Create GitHub Release
if: inputs.dry-run == false
uses: softprops/action-gh-release@v1
with:
tag_name: ${{ steps.version.outputs.tag }}
name: Release ${{ steps.version.outputs.version }}
body_path: CHANGELOG.md
files: '*.vsix'
draft: false
prerelease: ${{ contains(inputs.release-type, 'prerelease') }}
generate_release_notes: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Publish to VS Code Marketplace
if: inputs.dry-run == false && !contains(inputs.release-type, 'prerelease')
env:
VSCE_PAT: ${{ secrets.VSCE_PAT }}
run: |
if [ -n "$VSCE_PAT" ]; then
vsce publish --pat $VSCE_PAT
else
echo "VSCE_PAT not configured, skipping marketplace publish"
fi
- name: Publish Pre-release to VS Code Marketplace
if: inputs.dry-run == false && contains(inputs.release-type, 'prerelease')
env:
VSCE_PAT: ${{ secrets.VSCE_PAT }}
run: |
if [ -n "$VSCE_PAT" ]; then
vsce publish --pre-release --pat $VSCE_PAT
else
echo "VSCE_PAT not configured, skipping marketplace publish"
fi
notify:
name: Notify Release
runs-on: ubuntu-latest
needs: [release]
if: inputs.dry-run == false && (success() || failure())
steps:
- name: Notify Success
if: needs.release.result == 'success'
run: |
echo "✅ Release ${{ inputs.release-type }} completed successfully!"
echo "New version: v$(node -p "require('./package.json').version")"
- name: Notify Failure
if: needs.release.result == 'failure'
run: |
echo "❌ Release ${{ inputs.release-type }} failed!"
exit 1