- Complete VS Code extension with React-based kanban board UI - MCP integration for real-time Task Master synchronization - Professional CI/CD workflows for marketplace publishing - Comprehensive configuration system with user preferences - ShadCN UI components with VS Code theme integration - Drag-and-drop task management with status transitions - AI-powered task features via MCP protocol - Robust error handling and connection management - Multi-registry publishing (VS Code Marketplace + Open VSX) - Security audit completed with hardcoded paths removed BREAKING CHANGE: Extension requires publisher setup and marketplace keys Publisher and extension naming decisions required: - Update publisher field from placeholder 'DavidMaliglowka' - Choose unique extension name (currently 'taskr-kanban') - Select appropriate extension icon - Configure CI secrets (VSCE_PAT, OVSX_PAT) for publishing See apps/extension/docs/ for detailed setup instructions
240 lines
8.1 KiB
YAML
240 lines
8.1 KiB
YAML
name: Extension Release
|
||
|
||
on:
|
||
push:
|
||
branches:
|
||
- main
|
||
paths:
|
||
- 'apps/extension/**'
|
||
workflow_dispatch:
|
||
inputs:
|
||
force_publish:
|
||
description: 'Force publish even without version changes'
|
||
required: false
|
||
default: false
|
||
type: boolean
|
||
|
||
permissions:
|
||
contents: read
|
||
|
||
concurrency: extension-release-${{ github.ref }}
|
||
|
||
jobs:
|
||
check-version:
|
||
runs-on: ubuntu-latest
|
||
outputs:
|
||
should-publish: ${{ steps.version-check.outputs.should-publish }}
|
||
current-version: ${{ steps.version-check.outputs.current-version }}
|
||
steps:
|
||
- uses: actions/checkout@v4
|
||
with:
|
||
fetch-depth: 0
|
||
|
||
- name: Check version changes
|
||
id: version-check
|
||
run: |
|
||
# Get current version from package.json
|
||
CURRENT_VERSION=$(jq -r '.version' apps/extension/package.json)
|
||
echo "current-version=$CURRENT_VERSION" >> $GITHUB_OUTPUT
|
||
|
||
# Check if this is a force publish
|
||
if [ "${{ github.event.inputs.force_publish }}" = "true" ]; then
|
||
echo "should-publish=true" >> $GITHUB_OUTPUT
|
||
echo "Force publish requested"
|
||
exit 0
|
||
fi
|
||
|
||
# Check if version changed in the last commit
|
||
if git diff HEAD~1 HEAD --name-only | grep -q "apps/extension/package.json\|apps/extension/package.publish.json"; then
|
||
# Check if version field actually changed
|
||
PREV_VERSION=$(git show HEAD~1:apps/extension/package.json | jq -r '.version')
|
||
if [ "$CURRENT_VERSION" != "$PREV_VERSION" ]; then
|
||
echo "should-publish=true" >> $GITHUB_OUTPUT
|
||
echo "Version changed from $PREV_VERSION to $CURRENT_VERSION"
|
||
else
|
||
echo "should-publish=false" >> $GITHUB_OUTPUT
|
||
echo "No version change detected"
|
||
fi
|
||
else
|
||
echo "should-publish=false" >> $GITHUB_OUTPUT
|
||
echo "No package.json changes detected"
|
||
fi
|
||
|
||
build-and-publish:
|
||
needs: check-version
|
||
if: needs.check-version.outputs.should-publish == 'true'
|
||
runs-on: ubuntu-latest
|
||
environment: extension-release
|
||
steps:
|
||
- uses: actions/checkout@v4
|
||
with:
|
||
fetch-depth: 0
|
||
|
||
- uses: actions/setup-node@v4
|
||
with:
|
||
node-version: 20
|
||
|
||
- uses: pnpm/action-setup@v4
|
||
with:
|
||
version: latest
|
||
|
||
- name: Cache pnpm dependencies
|
||
uses: actions/cache@v4
|
||
with:
|
||
path: |
|
||
~/.pnpm-store
|
||
apps/extension/node_modules
|
||
key: ${{ runner.os }}-extension-pnpm-${{ hashFiles('apps/extension/pnpm-lock.yaml') }}
|
||
restore-keys: |
|
||
${{ runner.os }}-extension-pnpm-
|
||
|
||
- name: Install Extension Dependencies
|
||
working-directory: apps/extension
|
||
run: pnpm install --frozen-lockfile
|
||
timeout-minutes: 5
|
||
|
||
- name: Run Tests
|
||
working-directory: apps/extension
|
||
run: xvfb-run -a pnpm run test
|
||
env:
|
||
CI: true
|
||
FORCE_COLOR: 1
|
||
timeout-minutes: 10
|
||
|
||
- name: Lint Extension
|
||
working-directory: apps/extension
|
||
run: pnpm run lint
|
||
env:
|
||
FORCE_COLOR: 1
|
||
|
||
- name: Type Check Extension
|
||
working-directory: apps/extension
|
||
run: pnpm run check-types
|
||
env:
|
||
FORCE_COLOR: 1
|
||
|
||
- name: Build Extension
|
||
working-directory: apps/extension
|
||
run: pnpm run build
|
||
env:
|
||
FORCE_COLOR: 1
|
||
|
||
- name: Package Extension
|
||
working-directory: apps/extension
|
||
run: pnpm run package
|
||
env:
|
||
FORCE_COLOR: 1
|
||
|
||
- name: Verify Package Structure
|
||
working-directory: apps/extension
|
||
run: |
|
||
echo "=== Checking vsix-build structure ==="
|
||
ls -la vsix-build/
|
||
echo "=== Checking dist contents ==="
|
||
ls -la vsix-build/dist/
|
||
echo "=== Verifying required files ==="
|
||
test -f vsix-build/package.json || (echo "Missing package.json" && exit 1)
|
||
test -f vsix-build/dist/extension.js || (echo "Missing extension.js" && exit 1)
|
||
echo "=== Checking package.json content ==="
|
||
cat vsix-build/package.json | jq '.name, .version, .publisher'
|
||
|
||
- name: Create VSIX Package
|
||
working-directory: apps/extension/vsix-build
|
||
run: pnpm exec vsce package --no-dependencies
|
||
env:
|
||
FORCE_COLOR: 1
|
||
|
||
- name: Get VSIX filename
|
||
id: vsix-info
|
||
working-directory: apps/extension/vsix-build
|
||
run: |
|
||
VSIX_FILE=$(ls *.vsix)
|
||
echo "vsix-filename=$VSIX_FILE" >> $GITHUB_OUTPUT
|
||
echo "Found VSIX: $VSIX_FILE"
|
||
|
||
- name: Validate VSIX Package
|
||
working-directory: apps/extension/vsix-build
|
||
run: |
|
||
echo "=== VSIX Package Contents ==="
|
||
unzip -l "${{ steps.vsix-info.outputs.vsix-filename }}"
|
||
|
||
- name: Publish to VS Code Marketplace
|
||
working-directory: apps/extension/vsix-build
|
||
run: pnpm exec vsce publish --packagePath "${{ steps.vsix-info.outputs.vsix-filename }}"
|
||
env:
|
||
VSCE_PAT: ${{ secrets.VSCE_PAT }}
|
||
FORCE_COLOR: 1
|
||
|
||
- name: Install Open VSX CLI
|
||
run: npm install -g ovsx
|
||
|
||
- name: Publish to Open VSX Registry
|
||
working-directory: apps/extension/vsix-build
|
||
run: ovsx publish "${{ steps.vsix-info.outputs.vsix-filename }}"
|
||
env:
|
||
OVSX_PAT: ${{ secrets.OVSX_PAT }}
|
||
FORCE_COLOR: 1
|
||
|
||
- name: Create GitHub Release
|
||
uses: actions/create-release@v1
|
||
env:
|
||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||
with:
|
||
tag_name: extension-v${{ needs.check-version.outputs.current-version }}
|
||
release_name: Extension v${{ needs.check-version.outputs.current-version }}
|
||
body: |
|
||
VS Code Extension Release v${{ needs.check-version.outputs.current-version }}
|
||
|
||
**Changes in this release:**
|
||
- Published to VS Code Marketplace
|
||
- Published to Open VSX Registry
|
||
- Extension package: `${{ steps.vsix-info.outputs.vsix-filename }}`
|
||
|
||
**Installation:**
|
||
- Install from VS Code Marketplace: [Task Master Kanban](https://marketplace.visualstudio.com/items?itemName=[TBD])
|
||
- Install from Open VSX Registry: [Task Master Kanban](https://open-vsx.org/extension/[TBD])
|
||
- Or download the VSIX file below and install manually
|
||
draft: false
|
||
prerelease: false
|
||
|
||
- name: Upload VSIX to Release
|
||
uses: actions/upload-release-asset@v1
|
||
env:
|
||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||
with:
|
||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||
asset_path: apps/extension/vsix-build/${{ steps.vsix-info.outputs.vsix-filename }}
|
||
asset_name: ${{ steps.vsix-info.outputs.vsix-filename }}
|
||
asset_content_type: application/zip
|
||
|
||
- name: Upload Build Artifacts
|
||
uses: actions/upload-artifact@v4
|
||
with:
|
||
name: extension-release-v${{ needs.check-version.outputs.current-version }}
|
||
path: |
|
||
apps/extension/vsix-build/*.vsix
|
||
apps/extension/dist/
|
||
retention-days: 90
|
||
|
||
notify-success:
|
||
needs: [check-version, build-and-publish]
|
||
if: success() && needs.check-version.outputs.should-publish == 'true'
|
||
runs-on: ubuntu-latest
|
||
steps:
|
||
- name: Success Notification
|
||
run: |
|
||
echo "🎉 Extension v${{ needs.check-version.outputs.current-version }} successfully published!"
|
||
echo "📦 Available on VS Code Marketplace"
|
||
echo "🌍 Available on Open VSX Registry"
|
||
echo "🏷️ GitHub release created: extension-v${{ needs.check-version.outputs.current-version }}"
|
||
|
||
notify-skipped:
|
||
needs: check-version
|
||
if: needs.check-version.outputs.should-publish == 'false'
|
||
runs-on: ubuntu-latest
|
||
steps:
|
||
- name: Skip Notification
|
||
run: |
|
||
echo "ℹ️ Extension publish skipped - no version changes detected"
|
||
echo "Current version: ${{ needs.check-version.outputs.current-version }}"
|
||
echo "To force publish, use workflow_dispatch with force_publish=true" |