Skip to content

Commit 5b30193

Browse files
Copilotwysaid
andauthored
Implement tag-based release workflow with marketplace publishing (#11)
* Initial plan * Implement improved workflow release process with tag validation and marketplace publishing Co-authored-by: wysaid <1430725+wysaid@users.noreply.github.com> * Security improvement: Use environment variable for marketplace token Co-authored-by: wysaid <1430725+wysaid@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: wysaid <1430725+wysaid@users.noreply.github.com>
1 parent 6552991 commit 5b30193

2 files changed

Lines changed: 234 additions & 10 deletions

File tree

.github/workflows/release.yml

Lines changed: 86 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
name: release extension
22

33
on:
4-
push:
5-
tags:
6-
- '*'
4+
push:
5+
tags:
6+
- '*'
77

88
jobs:
99
build:
@@ -12,22 +12,98 @@ jobs:
1212
steps:
1313
- uses: actions/checkout@v4
1414

15+
- name: Extract tag name
16+
id: extract_tag
17+
run: |
18+
TAG=${GITHUB_REF#refs/tags/}
19+
echo "tag=$TAG" >> $GITHUB_OUTPUT
20+
echo "Extracted tag: $TAG"
21+
22+
- name: Validate tag format and determine release type
23+
id: validate_tag
24+
run: |
25+
TAG="${{ steps.extract_tag.outputs.tag }}"
26+
27+
# Check if tag matches stable release pattern (e.g., 1.0.3)
28+
if echo "$TAG" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+$'; then
29+
echo "is_stable_release=true" >> $GITHUB_OUTPUT
30+
echo "is_prerelease=false" >> $GITHUB_OUTPUT
31+
echo "should_publish=true" >> $GITHUB_OUTPUT
32+
echo "Tag is a stable release: $TAG"
33+
# Check if tag matches pre-release pattern (e.g., 1.0.3-alpha, 1.0.3-beta, 1.0.3-rc.1)
34+
elif echo "$TAG" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+-.+$'; then
35+
echo "is_stable_release=false" >> $GITHUB_OUTPUT
36+
echo "is_prerelease=true" >> $GITHUB_OUTPUT
37+
echo "should_publish=true" >> $GITHUB_OUTPUT
38+
echo "Tag is a pre-release: $TAG"
39+
else
40+
echo "is_stable_release=false" >> $GITHUB_OUTPUT
41+
echo "is_prerelease=false" >> $GITHUB_OUTPUT
42+
echo "should_publish=false" >> $GITHUB_OUTPUT
43+
echo "Tag does not match release patterns: $TAG"
44+
echo "Will only run build and test."
45+
fi
46+
47+
- name: Extract version from tag
48+
id: extract_version
49+
if: steps.validate_tag.outputs.should_publish == 'true'
50+
run: |
51+
TAG="${{ steps.extract_tag.outputs.tag }}"
52+
# Extract the version number (e.g., 1.0.3 from 1.0.3 or 1.0.3-alpha)
53+
VERSION=$(echo "$TAG" | grep -oE '^[0-9]+\.[0-9]+\.[0-9]+')
54+
echo "version=$VERSION" >> $GITHUB_OUTPUT
55+
echo "Extracted version: $VERSION"
56+
57+
- name: Check version consistency with package.json
58+
if: steps.validate_tag.outputs.should_publish == 'true'
59+
run: |
60+
TAG_VERSION="${{ steps.extract_version.outputs.version }}"
61+
PACKAGE_VERSION=$(node -p "require('./package.json').version")
62+
63+
echo "Tag version: $TAG_VERSION"
64+
echo "package.json version: $PACKAGE_VERSION"
65+
66+
if [ "$TAG_VERSION" != "$PACKAGE_VERSION" ]; then
67+
echo "Error: Tag version ($TAG_VERSION) does not match package.json version ($PACKAGE_VERSION)"
68+
exit 1
69+
fi
70+
71+
echo "Version check passed: $TAG_VERSION"
72+
1573
- name: Use Node.js
1674
uses: actions/setup-node@v3
1775
with:
1876
node-version: 21.x
1977

78+
- name: Install dependencies
79+
run: npm install
80+
2081
- name: Build
21-
run: |
22-
npm install
23-
npx tsc
82+
run: npx tsc
83+
2484
- name: Install VSCE
25-
run: npm install -g vsce
85+
run: npm install -g @vscode/vsce
86+
2687
- name: Build VSIX
2788
run: vsce package
28-
- name: GitHub Release
89+
90+
- name: Publish to VS Code Marketplace
91+
if: steps.validate_tag.outputs.should_publish == 'true'
92+
env:
93+
VSCE_PAT: ${{ secrets.MS_STORE_TOKEN }}
94+
run: |
95+
if [ "${{ steps.validate_tag.outputs.is_stable_release }}" == "true" ]; then
96+
echo "Publishing as stable release to VS Code Marketplace..."
97+
vsce publish -p $VSCE_PAT
98+
else
99+
echo "Publishing as pre-release to VS Code Marketplace..."
100+
vsce publish --pre-release -p $VSCE_PAT
101+
fi
102+
103+
- name: Create GitHub Release
104+
if: steps.validate_tag.outputs.should_publish == 'true'
29105
uses: softprops/action-gh-release@v2
30-
if: startsWith(github.ref, 'refs/tags/')
31106
with:
32107
files: ./*.vsix
33-
prerelease: true
108+
prerelease: ${{ steps.validate_tag.outputs.is_prerelease }}
109+
generate_release_notes: true

RELEASE_WORKFLOW.md

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
# Release Workflow Documentation
2+
3+
This document describes the automated release workflow for the EGE VSCode Plugin.
4+
5+
## Overview
6+
7+
The release workflow is triggered when you push a git tag to the repository. The behavior depends on the tag format:
8+
9+
### Tag Formats
10+
11+
#### 1. Stable Release Tags
12+
**Pattern:** `X.Y.Z` (e.g., `1.0.3`, `2.1.0`)
13+
- **Regex:** `/^[0-9]+\.[0-9]+\.[0-9]+$/`
14+
- **Behavior:**
15+
- Builds and tests the extension
16+
- Validates tag version matches `package.json` version
17+
- Publishes to VS Code Marketplace as a **stable release**
18+
- Creates a GitHub release (not marked as pre-release)
19+
- Attaches VSIX file to GitHub release
20+
21+
#### 2. Pre-Release Tags
22+
**Pattern:** `X.Y.Z-suffix` (e.g., `1.0.3-alpha`, `1.0.3-beta`, `1.0.3-rc.1`)
23+
- **Regex:** `/^[0-9]+\.[0-9]+\.[0-9]+-.+$/`
24+
- **Supported suffixes:** `-alpha`, `-beta`, `-rc`, `-rc.1`, etc.
25+
- **Behavior:**
26+
- Builds and tests the extension
27+
- Validates tag version (numeric part) matches `package.json` version
28+
- Publishes to VS Code Marketplace as a **pre-release**
29+
- Creates a GitHub release (marked as pre-release)
30+
- Attaches VSIX file to GitHub release
31+
32+
**Important:** The VS Code Marketplace doesn't support version suffixes in the actual extension version. The pre-release suffix is only used in the git tag name. The actual version in `package.json` should be the numeric version only (e.g., `1.0.3`).
33+
34+
#### 3. Non-Release Tags
35+
**Examples:** `v1.0.3`, `latest`, `dev`, `test`
36+
- **Behavior:**
37+
- Builds and tests the extension
38+
- **Does NOT publish** to marketplace
39+
- **Does NOT create** GitHub release
40+
- Useful for testing the build process
41+
42+
## Version Consistency Check
43+
44+
For all release tags (both stable and pre-release), the workflow validates that:
45+
- The numeric version in the tag matches the version in `package.json`
46+
- If they don't match, the workflow fails with an error
47+
48+
**Example:**
49+
- Tag: `1.0.3` → Must match `package.json` version `1.0.3`
50+
- Tag: `1.0.3-alpha` → Must match `package.json` version `1.0.3`
51+
- Tag: `1.0.4` → If `package.json` has `1.0.3`, workflow fails ✗
52+
53+
## How to Create a Release
54+
55+
### Stable Release
56+
57+
1. Update the version in `package.json`:
58+
```bash
59+
# Edit package.json and set "version": "1.0.4"
60+
```
61+
62+
2. Commit the version change:
63+
```bash
64+
git add package.json
65+
git commit -m "Bump version to 1.0.4"
66+
git push
67+
```
68+
69+
3. Create and push a tag:
70+
```bash
71+
git tag 1.0.4
72+
git push origin 1.0.4
73+
```
74+
75+
### Pre-Release
76+
77+
1. Update the version in `package.json` to the base version:
78+
```bash
79+
# Edit package.json and set "version": "1.0.4"
80+
```
81+
82+
2. Commit the version change:
83+
```bash
84+
git add package.json
85+
git commit -m "Bump version to 1.0.4"
86+
git push
87+
```
88+
89+
3. Create and push a pre-release tag:
90+
```bash
91+
git tag 1.0.4-beta
92+
git push origin 1.0.4-beta
93+
```
94+
95+
## Required Secrets
96+
97+
The workflow requires the following GitHub secret:
98+
- `MS_STORE_TOKEN`: Personal Access Token for publishing to VS Code Marketplace
99+
100+
## Workflow Steps
101+
102+
1. **Extract Tag Name** - Gets the tag that triggered the workflow
103+
2. **Validate Tag Format** - Determines if it's stable, pre-release, or non-release
104+
3. **Extract Version** - Extracts numeric version from tag (for release tags only)
105+
4. **Check Version Consistency** - Validates tag version matches package.json
106+
5. **Setup Node.js** - Installs Node.js environment
107+
6. **Install Dependencies** - Runs `npm install`
108+
7. **Build** - Compiles TypeScript to JavaScript
109+
8. **Install VSCE** - Installs VS Code Extension packaging tool
110+
9. **Build VSIX** - Creates the extension package
111+
10. **Publish to Marketplace** - Publishes to VS Code Marketplace (release tags only)
112+
11. **Create GitHub Release** - Creates GitHub release with VSIX file (release tags only)
113+
114+
## Troubleshooting
115+
116+
### Workflow fails with "Version mismatch"
117+
- Ensure the tag version matches the version in `package.json`
118+
- For pre-release tags, only the numeric part needs to match
119+
120+
### Marketplace publish fails
121+
- Check that `MS_STORE_TOKEN` secret is correctly configured
122+
- Verify the token has appropriate permissions
123+
- The workflow will fail if marketplace publishing fails
124+
125+
### Build or test fails
126+
- The workflow runs for all tags, even non-release tags
127+
- Fix build or test issues before creating release tags
128+
129+
## Examples
130+
131+
### Valid Stable Release Tags
132+
- `1.0.3`
133+
- `2.0.0`
134+
- `10.20.30`
135+
136+
### Valid Pre-Release Tags
137+
- `1.0.3-alpha`
138+
- `1.0.3-beta`
139+
- `1.0.3-rc`
140+
- `1.0.3-rc.1`
141+
- `2.0.0-beta.2`
142+
143+
### Non-Release Tags (Build & Test Only)
144+
- `v1.0.3` (has 'v' prefix)
145+
- `latest`
146+
- `dev`
147+
- `test`
148+
- `1.0` (incomplete version)

0 commit comments

Comments
 (0)