-
Notifications
You must be signed in to change notification settings - Fork 23
153 lines (137 loc) · 6.33 KB
/
release-vscode.yml
File metadata and controls
153 lines (137 loc) · 6.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# Release VS Code Extension
# Stable: tag `vscode-vX.Y.Z` -> extension `vicperdana.psdocs-vscode`
# Preview: tag `vscode-preview-vX.Y.Z` -> extension `vicperdana.psdocs-vscode-preview` (separate Marketplace listing)
#
# VS Code Marketplace does not accept SemVer prerelease suffixes (e.g. -preview.1) in
# the package version, so the channel is encoded in the tag prefix and routed to the
# build pipeline via -Channel. Both channels use plain X.Y.Z versions in package.json.
name: Release VS Code Extension
on:
push:
tags:
- 'vscode-v*'
- 'vscode-preview-v*'
workflow_dispatch:
inputs:
tag:
description: 'Tag to simulate (e.g. vscode-v0.4.0 or vscode-preview-v0.4.0)'
required: true
type: string
dry_run:
description: 'Skip vsce publish and gh release create (validate + build only).'
required: false
type: boolean
default: true
permissions:
contents: write
jobs:
release:
name: Release
runs-on: ubuntu-latest
environment: release
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Setup Node.js
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: '20.x'
cache: 'npm'
cache-dependency-path: packages/vscode-extension/package-lock.json
- name: Setup PowerShell modules
shell: pwsh
run: |
Set-PSRepository -Name PSGallery -InstallationPolicy Trusted
Install-Module -Name InvokeBuild -MinimumVersion 5.4.0 -Scope CurrentUser -Force
- name: Parse tag and detect channel
id: version
shell: pwsh
run: |
$tag = if ('${{ github.event_name }}' -eq 'workflow_dispatch') { '${{ inputs.tag }}' } else { '${{ github.ref_name }}' }
if ($tag -match '^vscode-preview-v(.+)$') {
$version = $Matches[1]
$channel = 'preview'
$isPrerelease = $true
} elseif ($tag -match '^vscode-v(.+)$') {
$version = $Matches[1]
$channel = 'stable'
$isPrerelease = $false
} else {
Write-Error "Tag '$tag' does not match expected pattern vscode-v* or vscode-preview-v*"
exit 1
}
if ($version -notmatch '^\d+\.\d+\.\d+$') {
Write-Error "Version '$version' must be plain SemVer (X.Y.Z) — VS Code Marketplace does not accept prerelease suffixes."
exit 1
}
"tag=$tag" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
"version=$version" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
"channel=$channel" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
"is_prerelease=$($isPrerelease.ToString().ToLower())" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
Write-Host "Tag: $tag -> version=$version channel=$channel"
- name: Validate version matches package.json
shell: pwsh
run: |
$pkg = Get-Content ./packages/vscode-extension/package.json -Raw | ConvertFrom-Json
$expected = '${{ steps.version.outputs.version }}'
if ($pkg.version -ne $expected) {
Write-Error "package.json version '$($pkg.version)' does not match tag version '$expected'. Update packages/vscode-extension/package.json before tagging."
exit 1
}
Write-Host "package.json version '$($pkg.version)' matches tag '$expected'."
- name: Extract release notes
shell: pwsh
run: |
./scripts/extract-release-notes.ps1 `
-ChangelogPath ./packages/vscode-extension/CHANGELOG.md `
-Version '${{ steps.version.outputs.version }}' `
-OutputPath ./release-notes.md
- name: Install dependencies
working-directory: packages/vscode-extension
run: npm ci
- name: Build (${{ steps.version.outputs.channel }})
shell: pwsh
working-directory: packages/vscode-extension
run: |
Invoke-Build Build -Channel '${{ steps.version.outputs.channel }}' -Build '${{ steps.version.outputs.version }}'
- name: Find VSIX file
id: vsix
working-directory: packages/vscode-extension/out/package
run: |
VSIX_FILE=$(ls *.vsix 2>/dev/null | head -1)
if [ -z "$VSIX_FILE" ]; then
echo "::error::No VSIX file found in out/package/"
exit 1
fi
echo "file=$VSIX_FILE" >> $GITHUB_OUTPUT
echo "path=packages/vscode-extension/out/package/$VSIX_FILE" >> $GITHUB_OUTPUT
echo "Found VSIX: $VSIX_FILE"
- name: Publish to VS Marketplace
if: ${{ github.event_name != 'workflow_dispatch' || inputs.dry_run != true }}
working-directory: packages/vscode-extension/out/package
env:
VSCE_PAT: ${{ secrets.VSCE_PAT }}
PRE_RELEASE_FLAG: ${{ steps.version.outputs.is_prerelease == 'true' && '--pre-release' || '' }}
run: |
npx @vscode/vsce publish --packagePath "${{ steps.vsix.outputs.file }}" --pat "$VSCE_PAT" $PRE_RELEASE_FLAG
- name: Create GitHub Release
if: ${{ github.event_name != 'workflow_dispatch' || inputs.dry_run != true }}
env:
GH_TOKEN: ${{ github.token }}
PRERELEASE_FLAG: ${{ steps.version.outputs.is_prerelease == 'true' && '--prerelease' || '' }}
TITLE_SUFFIX: ${{ steps.version.outputs.is_prerelease == 'true' && ' (Preview)' || '' }}
run: |
gh release create "${{ steps.version.outputs.tag }}" \
--title "VS Code Extension v${{ steps.version.outputs.version }}$TITLE_SUFFIX" \
--notes-file ./release-notes.md \
$PRERELEASE_FLAG \
"${{ steps.vsix.outputs.path }}"
- name: Dry-run summary
if: ${{ github.event_name == 'workflow_dispatch' && inputs.dry_run == true }}
shell: pwsh
run: |
Write-Host '=== DRY RUN ==='
Write-Host "Would publish VS Code extension v${{ steps.version.outputs.version }} (channel=${{ steps.version.outputs.channel }}) to VS Marketplace."
Write-Host "Would create GitHub Release for tag ${{ steps.version.outputs.tag }} with VSIX ${{ steps.vsix.outputs.file }}."
Write-Host '--- release notes ---'
Get-Content ./release-notes.md