Skip to content

Commit e2a6487

Browse files
ci(release): add automated VSIX packaging on tag
- Add GitHub Actions release workflow (.github/workflows/release.yml) - Triggers on git tags matching v* pattern - Validates tag version matches package.json version - Builds on Node.js 18.x and 20.x matrix - Packages extension with vsce --no-yarn - Uploads VSIX artifacts with 30-day retention - Optional marketplace publishing (when VSCE_PAT secret exists) - Add release helper script (scripts/release.sh) - Interactive version prompting and validation - Semantic versioning format checking - Automated package.json updates and git tagging - Pre-release testing (lint, compile, build) - Prevents duplicate tags and dirty working directory - Add npm release script (package.json) - `npm run release` for easy access to release script - Add comprehensive release documentation (RELEASE.md) - Quick start guide for automated releases - Manual release process documentation - Version validation examples and troubleshooting - Marketplace publishing setup instructions - Rename readme.md to README.md for consistency Resolves #8
1 parent 7c1df40 commit e2a6487

File tree

5 files changed

+319
-1
lines changed

5 files changed

+319
-1
lines changed

.github/workflows/release.yml

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# Copyright IBM Corp. 2025
2+
# Assisted by CursorAI
3+
4+
name: Release
5+
6+
on:
7+
push:
8+
tags:
9+
- 'v*'
10+
11+
jobs:
12+
release:
13+
runs-on: ubuntu-latest
14+
15+
strategy:
16+
matrix:
17+
node-version: [18.x, 20.x]
18+
19+
steps:
20+
- name: Checkout code
21+
uses: actions/checkout@v4
22+
23+
- name: Setup Node.js ${{ matrix.node-version }}
24+
uses: actions/setup-node@v4
25+
with:
26+
node-version: ${{ matrix.node-version }}
27+
cache: "npm"
28+
29+
- name: Install dependencies
30+
run: npm ci
31+
32+
- name: Validate tag matches package.json version
33+
run: |
34+
PACKAGE_VERSION=$(node -p "require('./package.json').version")
35+
TAG_VERSION=${GITHUB_REF#refs/tags/v}
36+
echo "Package version: $PACKAGE_VERSION"
37+
echo "Tag version: $TAG_VERSION"
38+
if [ "$PACKAGE_VERSION" != "$TAG_VERSION" ]; then
39+
echo "❌ Error: Tag version ($TAG_VERSION) does not match package.json version ($PACKAGE_VERSION)"
40+
exit 1
41+
fi
42+
echo "✅ Version validation passed"
43+
44+
- name: Compile extension
45+
run: npm run compile
46+
47+
- name: Package VSIX
48+
run: npx @vscode/vsce package --no-yarn
49+
50+
- name: Upload VSIX artifact
51+
uses: actions/upload-artifact@v4
52+
with:
53+
name: vscode-stepzen-${{ matrix.node-version }}-${{ github.ref_name }}
54+
path: "*.vsix"
55+
retention-days: 30
56+
57+
# Optional: Uncomment and add VSCE_PAT secret to enable marketplace publishing
58+
# - name: Publish to Marketplace (optional)
59+
# if: ${{ secrets.VSCE_PAT }}
60+
# run: npx @vscode/vsce publish --no-yarn
61+
# env:
62+
# VSCE_PAT: ${{ secrets.VSCE_PAT }}
File renamed without changes.

RELEASE.md

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
<!--
2+
Copyright IBM Corp. 2025
3+
Assisted by CursorAI
4+
-->
5+
6+
# Release Process
7+
8+
This document describes how to create releases for the VSCode StepZen extension.
9+
10+
## Overview
11+
12+
The extension uses automated release workflows that:
13+
14+
- ✅ Validate that git tags match the version in `package.json`
15+
- ✅ Build and package the extension automatically
16+
- ✅ Upload VSIX artifacts for distribution
17+
- ✅ Optionally publish to the VS Code Marketplace
18+
19+
## Quick Release (Recommended)
20+
21+
Use the provided release script for a guided release process:
22+
23+
```bash
24+
# Interactive mode (prompts for version)
25+
npm run release
26+
27+
# Or specify version directly
28+
./scripts/release.sh 0.1.3
29+
```
30+
31+
This script will:
32+
33+
1. Validate the new version format
34+
2. Update `package.json` and `package-lock.json`
35+
3. Run linting and compilation checks
36+
4. Commit the version change
37+
5. Create a git tag
38+
6. Provide instructions for pushing
39+
40+
## Manual Release Process
41+
42+
If you prefer to handle the release manually:
43+
44+
### 1. Update Version
45+
46+
```bash
47+
# Update package.json version (this also updates package-lock.json)
48+
npm version 0.1.3 --no-git-tag-version
49+
```
50+
51+
### 2. Validate and Test
52+
53+
```bash
54+
# Run all checks
55+
npm run ci:lint
56+
npm run compile
57+
58+
# Optional: Test packaging locally
59+
npx @vscode/vsce package --no-yarn
60+
```
61+
62+
### 3. Commit and Tag
63+
64+
```bash
65+
# Commit version changes
66+
git add package.json package-lock.json
67+
git commit -m "chore(release): bump version to 0.1.3"
68+
69+
# Create tag (must match package.json version exactly)
70+
git tag v0.1.3
71+
```
72+
73+
### 4. Push Release
74+
75+
```bash
76+
# Push commits and tags
77+
git push origin main
78+
git push origin v0.1.3
79+
```
80+
81+
## Version Validation
82+
83+
The release workflow automatically validates that:
84+
85+
- The git tag format is `v{version}` (e.g., `v0.1.3`)
86+
- The tag version matches the version in `package.json` exactly
87+
- If validation fails, the workflow stops and no artifacts are created
88+
89+
### Example Validation
90+
91+
```
92+
✅ Tag: v0.1.3, Package: 0.1.3 → Valid
93+
❌ Tag: v0.1.3, Package: 0.1.2 → Invalid (mismatch)
94+
❌ Tag: 0.1.3, Package: 0.1.3 → Invalid (missing 'v' prefix)
95+
❌ Tag: v1.0, Package: 1.0.0 → Invalid (incomplete version)
96+
```
97+
98+
## Automated Workflow
99+
100+
When you push a tag matching `v*`, the GitHub Actions workflow will:
101+
102+
1. **Validate** tag matches package.json version
103+
2. **Build** on Node.js 18.x and 20.x
104+
3. **Package** the extension into VSIX files
105+
4. **Upload** artifacts to GitHub Actions (30-day retention)
106+
5. **Publish** to marketplace (if `VSCE_PAT` secret is configured)
107+
108+
## Marketplace Publishing
109+
110+
To enable automatic marketplace publishing:
111+
112+
1. Generate a Personal Access Token from the [Visual Studio Marketplace](https://marketplace.visualstudio.com/manage)
113+
2. Add it as a repository secret named `VSCE_PAT`
114+
3. Uncomment the publish step in `.github/workflows/release.yml`
115+
116+
## Versioning Guidelines
117+
118+
Follow [Semantic Versioning](https://semver.org/):
119+
120+
- **Patch** (0.1.2 → 0.1.3): Bug fixes, minor improvements
121+
- **Minor** (0.1.3 → 0.2.0): New features, backward compatible
122+
- **Major** (0.2.0 → 1.0.0): Breaking changes
123+
124+
## Troubleshooting
125+
126+
### Version Mismatch Error
127+
128+
If the workflow fails with a version mismatch:
129+
130+
```bash
131+
# Check current versions
132+
git describe --tags --abbrev=0 # Latest tag
133+
node -p "require('./package.json').version" # Package version
134+
135+
# Fix by updating package.json or creating correct tag
136+
npm version 0.1.3 --no-git-tag-version
137+
git add package.json package-lock.json
138+
git commit -m "fix: correct version to match tag"
139+
```
140+
141+
### Failed Build
142+
143+
If compilation fails:
144+
145+
```bash
146+
# Run the same checks locally
147+
npm run ci:lint
148+
npm run compile
149+
150+
# Fix any issues and commit
151+
git add .
152+
git commit -m "fix: resolve build issues"
153+
```
154+
155+
### Artifact Download
156+
157+
To download VSIX files from a release:
158+
159+
1. Go to the [Actions tab](https://github.com/stepzen-dev/vscode-stepzen/actions)
160+
2. Click on the release workflow run
161+
3. Download artifacts from the "Artifacts" section
162+
163+
---
164+
165+
_Portions of the Content may be generated with the assistance of CursorAI_

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,8 @@
128128
"lint:deps": "depcheck",
129129
"lint:all": "npm run lint && npm run lint:prune && npm run lint:deps",
130130
"ci:lint": "npm run lint && npm run lint:prune && npm run lint:deps && npm run check-types",
131-
"test": "vscode-test"
131+
"test": "vscode-test",
132+
"release": "scripts/release.sh"
132133
},
133134
"devDependencies": {
134135
"@types/mocha": "^10.0.10",

scripts/release.sh

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
#!/bin/bash
2+
3+
# Copyright IBM Corp. 2025
4+
# Assisted by CursorAI
5+
6+
# Release helper script for vscode-stepzen extension
7+
# Usage: ./scripts/release.sh [version]
8+
# Example: ./scripts/release.sh 0.1.3
9+
10+
set -e
11+
12+
# Colors for output
13+
RED='\033[0;31m'
14+
GREEN='\033[0;32m'
15+
YELLOW='\033[1;33m'
16+
NC='\033[0m' # No Color
17+
18+
# Function to print colored output
19+
print_info() {
20+
echo -e "${GREEN}ℹ️ $1${NC}"
21+
}
22+
23+
print_warning() {
24+
echo -e "${YELLOW}⚠️ $1${NC}"
25+
}
26+
27+
print_error() {
28+
echo -e "${RED}$1${NC}"
29+
}
30+
31+
# Check if we're in a git repository
32+
if ! git rev-parse --git-dir > /dev/null 2>&1; then
33+
print_error "Not in a git repository"
34+
exit 1
35+
fi
36+
37+
# Check if working directory is clean
38+
if ! git diff-index --quiet HEAD --; then
39+
print_error "Working directory is not clean. Please commit or stash your changes."
40+
exit 1
41+
fi
42+
43+
# Get current version from package.json
44+
CURRENT_VERSION=$(node -p "require('./package.json').version")
45+
print_info "Current version: $CURRENT_VERSION"
46+
47+
# If version is provided as argument, use it; otherwise prompt
48+
if [ $# -eq 1 ]; then
49+
NEW_VERSION=$1
50+
else
51+
echo -n "Enter new version (current: $CURRENT_VERSION): "
52+
read NEW_VERSION
53+
fi
54+
55+
# Validate version format (basic semver check)
56+
if ! [[ $NEW_VERSION =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.-]+)?$ ]]; then
57+
print_error "Invalid version format. Please use semantic versioning (e.g., 1.0.0)"
58+
exit 1
59+
fi
60+
61+
# Check if tag already exists
62+
if git tag -l "v$NEW_VERSION" | grep -q "v$NEW_VERSION"; then
63+
print_error "Tag v$NEW_VERSION already exists"
64+
exit 1
65+
fi
66+
67+
print_info "Updating version to $NEW_VERSION..."
68+
69+
# Update package.json version
70+
npm version $NEW_VERSION --no-git-tag-version
71+
72+
# Run tests and build
73+
print_info "Running tests and build..."
74+
npm run ci:lint
75+
npm run compile
76+
77+
# Commit the version change
78+
git add package.json package-lock.json
79+
git commit -m "chore(release): bump version to $NEW_VERSION"
80+
81+
# Create and push tag
82+
print_info "Creating tag v$NEW_VERSION..."
83+
git tag "v$NEW_VERSION"
84+
85+
print_warning "Ready to push. Run the following commands to complete the release:"
86+
echo ""
87+
echo " git push origin main"
88+
echo " git push origin v$NEW_VERSION"
89+
echo ""
90+
print_info "The GitHub Actions workflow will automatically build and package the extension."

0 commit comments

Comments
 (0)