Skip to content

Commit 9403ce0

Browse files
mhuisiclaude
andauthored
chore: publish to marketplaces independently and handle partial failures (#758)
Previously, `vsce publish` and `ovsx publish` ran sequentially in the same step of `build-and-test`, so a failure in one would skip the other and also skip the GitHub release creation. This PR restructures `.github/workflows/on-push.yml` so partial failures are recoverable and obvious. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent d069af1 commit 9403ce0

File tree

1 file changed

+148
-58
lines changed

1 file changed

+148
-58
lines changed

.github/workflows/on-push.yml

Lines changed: 148 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -25,24 +25,9 @@ permissions:
2525
id-token: write
2626

2727
jobs:
28-
build-and-test:
28+
package:
2929
if: github.event_name != 'workflow_dispatch'
30-
strategy:
31-
fail-fast: false
32-
matrix:
33-
include:
34-
- name: Linux
35-
os: ubuntu-latest
36-
artifact: build-Linux release
37-
# - name: macOS
38-
# os: macos-latest
39-
# artifact: build-macOS
40-
- name: Windows
41-
os: windows-latest
42-
artifact: build-Windows
43-
name: ${{ matrix.name }}
44-
runs-on: ${{ matrix.os }}
45-
30+
runs-on: ubuntu-latest
4631
steps:
4732
- name: Checkout
4833
uses: actions/checkout@v2
@@ -61,25 +46,25 @@ jobs:
6146
npm run build
6247
6348
- name: Try publishing infoview-api
64-
if: ${{ startsWith(github.ref, 'refs/tags/v') && !endsWith(github.ref, '-pre') && matrix.os == 'ubuntu-latest' }}
49+
if: ${{ startsWith(github.ref, 'refs/tags/v') && !endsWith(github.ref, '-pre') }}
6550
continue-on-error: true
6651
run: |
6752
npm publish --workspace=lean4-infoview-api --access=public
6853
6954
- name: Try publishing infoview
70-
if: ${{ startsWith(github.ref, 'refs/tags/v') && !endsWith(github.ref, '-pre') && matrix.os == 'ubuntu-latest' }}
55+
if: ${{ startsWith(github.ref, 'refs/tags/v') && !endsWith(github.ref, '-pre') }}
7156
continue-on-error: true
7257
run: |
7358
npm publish --workspace=lean4-infoview --access=public
7459
7560
- name: Try publishing unicode-input
76-
if: ${{ startsWith(github.ref, 'refs/tags/v') && !endsWith(github.ref, '-pre') && matrix.os == 'ubuntu-latest' }}
61+
if: ${{ startsWith(github.ref, 'refs/tags/v') && !endsWith(github.ref, '-pre') }}
7762
continue-on-error: true
7863
run: |
7964
npm publish --workspace=lean4-unicode-input --access=public
8065
8166
- name: Try publishing unicode-input-component
82-
if: ${{ startsWith(github.ref, 'refs/tags/v') && !endsWith(github.ref, '-pre') && matrix.os == 'ubuntu-latest' }}
67+
if: ${{ startsWith(github.ref, 'refs/tags/v') && !endsWith(github.ref, '-pre') }}
8368
continue-on-error: true
8469
run: |
8570
npm publish --workspace=lean4-unicode-input-component --access=public
@@ -94,33 +79,141 @@ jobs:
9479

9580
- name: Upload artifact
9681
uses: actions/upload-artifact@v4
97-
if: matrix.os == 'ubuntu-latest'
9882
with:
9983
name: vscode-lean4
10084
path: 'vscode-lean4/lean4-*.vsix'
10185

102-
- name: Publish packaged extension
103-
if: ${{ startsWith(github.ref, 'refs/tags/v') && !endsWith(github.ref, '-pre') && matrix.os == 'ubuntu-latest' }}
86+
build-and-test:
87+
if: github.event_name != 'workflow_dispatch'
88+
strategy:
89+
fail-fast: false
90+
matrix:
91+
include:
92+
- name: Linux
93+
os: ubuntu-latest
94+
artifact: build-Linux release
95+
# - name: macOS
96+
# os: macos-latest
97+
# artifact: build-macOS
98+
- name: Windows
99+
os: windows-latest
100+
artifact: build-Windows
101+
name: ${{ matrix.name }}
102+
runs-on: ${{ matrix.os }}
103+
104+
steps:
105+
- name: Checkout
106+
uses: actions/checkout@v2
107+
with:
108+
fetch-depth: 0
109+
110+
- name: Setup Node.js
111+
uses: actions/setup-node@v4
112+
with:
113+
node-version: '24'
114+
registry-url: 'https://registry.npmjs.org'
115+
116+
- name: Build
117+
run: |
118+
npm ci
119+
npm run build
120+
121+
- name: Lint
122+
run: npm run lint
123+
124+
- name: Install Brew Packages
125+
run: |
126+
brew install ccache tree zstd coreutils
127+
if: matrix.os == 'macos-latest'
128+
129+
- name: Set path to elan on Linux or macOS
130+
if: matrix.os == 'ubuntu-latest' || matrix.os == 'macos-latest'
131+
run: |
132+
echo "$HOME/.elan/bin" >> $GITHUB_PATH
133+
134+
- name: Set path to elan on Windows
135+
shell: pwsh
136+
if: matrix.os == 'windows-latest'
137+
run: |
138+
echo "$HOME\.elan\bin" >> $env:GITHUB_PATH
139+
140+
- name: Run tests
141+
uses: GabrielBB/xvfb-action@v1.0
142+
with:
143+
run: npm run test
144+
145+
publish-vsce:
146+
needs: package
147+
if: startsWith(github.ref, 'refs/tags/v')
148+
runs-on: ubuntu-latest
149+
steps:
150+
- name: Setup Node.js
151+
uses: actions/setup-node@v4
152+
with:
153+
node-version: '24'
154+
155+
- name: Download packaged extension
156+
uses: actions/download-artifact@v4
157+
with:
158+
name: vscode-lean4
159+
path: vscode-lean4
160+
161+
- name: Publish to VS Code Marketplace
104162
run: |
105163
cd vscode-lean4
106-
npx @vscode/vsce publish -i lean4-*.vsix
107-
npx ovsx publish lean4-*.vsix
164+
npx @vscode/vsce publish $PRE_RELEASE_FLAG -i lean4-*.vsix
108165
env:
109-
OVSX_PAT: ${{ secrets.OVSX_PAT }}
110166
VSCE_PAT: ${{ secrets.VSCE_PAT }}
167+
PRE_RELEASE_FLAG: ${{ endsWith(github.ref, '-pre') && '--pre-release' || '' }}
111168

112-
- name: Publish packaged pre-release extension
113-
if: ${{ startsWith(github.ref, 'refs/tags/v') && endsWith(github.ref, '-pre') && matrix.os == 'ubuntu-latest' }}
169+
publish-ovsx:
170+
needs: package
171+
if: startsWith(github.ref, 'refs/tags/v')
172+
runs-on: ubuntu-latest
173+
steps:
174+
- name: Setup Node.js
175+
uses: actions/setup-node@v4
176+
with:
177+
node-version: '24'
178+
179+
- name: Download packaged extension
180+
uses: actions/download-artifact@v4
181+
with:
182+
name: vscode-lean4
183+
path: vscode-lean4
184+
185+
- name: Publish to Open VSX
114186
run: |
115187
cd vscode-lean4
116-
npx @vscode/vsce publish --pre-release -i lean4-*.vsix
117-
npx ovsx publish --pre-release lean4-*.vsix
188+
npx ovsx publish $PRE_RELEASE_FLAG lean4-*.vsix
118189
env:
119190
OVSX_PAT: ${{ secrets.OVSX_PAT }}
120-
VSCE_PAT: ${{ secrets.VSCE_PAT }}
191+
PRE_RELEASE_FLAG: ${{ endsWith(github.ref, '-pre') && '--pre-release' || '' }}
192+
193+
github-release:
194+
needs: [package, publish-vsce, publish-ovsx]
195+
# Run even if one of the publish jobs failed, so a GitHub Release with notes
196+
# is always created on a tag build. Tests are intentionally not a dependency:
197+
# releases ship in parallel with the build-and-test matrix, matching the
198+
# previous single-job behavior where publish ran before tests.
199+
if: |
200+
!cancelled() &&
201+
needs.package.result == 'success' &&
202+
startsWith(github.ref, 'refs/tags/v')
203+
runs-on: ubuntu-latest
204+
steps:
205+
- name: Checkout
206+
uses: actions/checkout@v2
207+
with:
208+
fetch-depth: 0
209+
210+
- name: Download packaged extension
211+
uses: actions/download-artifact@v4
212+
with:
213+
name: vscode-lean4
214+
path: vscode-lean4
121215

122216
- name: Generate release notes
123-
if: startsWith(github.ref, 'refs/tags/v') && matrix.os == 'ubuntu-latest'
124217
run: |
125218
current_tag="${GITHUB_REF#refs/tags/}"
126219
is_pre="${{ endsWith(github.ref, '-pre') }}"
@@ -140,6 +233,28 @@ jobs:
140233
write_users="$(gh api "/repos/${{ github.repository }}/collaborators" --paginate --jq '.[] | select(.permissions.push) | .login' 2>/dev/null || true)"
141234
142235
{
236+
# If either marketplace publish failed, prepend a prominent warning so
237+
# the partial failure is obvious on the Release page itself (in addition
238+
# to the red CI status). Note: this banner is NOT updated automatically
239+
# after a successful "Re-run failed jobs" — edit the release body by
240+
# hand after a retry if you want the banner gone.
241+
vsce_result="${{ needs.publish-vsce.result }}"
242+
ovsx_result="${{ needs.publish-ovsx.result }}"
243+
failed=()
244+
if [ "$vsce_result" != "success" ]; then failed+=("VS Code Marketplace"); fi
245+
if [ "$ovsx_result" != "success" ]; then failed+=("Open VSX"); fi
246+
if [ ${#failed[@]} -gt 0 ]; then
247+
if [ ${#failed[@]} -eq 2 ]; then
248+
joined="${failed[0]} and ${failed[1]}"
249+
else
250+
joined="${failed[0]}"
251+
fi
252+
echo "> [!WARNING]"
253+
echo "> This release could not be published to **$joined** from CI."
254+
echo "> See [the CI run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) and use *Re-run failed jobs* once the upstream issue is resolved."
255+
echo ""
256+
fi
257+
143258
git log "$prev_tag".."$current_tag"^ --pretty=tformat:"%H %s" | while read -r hash msg; do
144259
# Skip release commits
145260
case "$msg" in
@@ -167,7 +282,6 @@ jobs:
167282
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
168283

169284
- name: Upload extension as release
170-
if: startsWith(github.ref, 'refs/tags/v') && matrix.os == 'ubuntu-latest'
171285
uses: softprops/action-gh-release@v1
172286
with:
173287
files: 'vscode-lean4/lean4-*.vsix'
@@ -177,30 +291,6 @@ jobs:
177291
env:
178292
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
179293

180-
- name: Lint
181-
run: npm run lint
182-
183-
- name: Install Brew Packages
184-
run: |
185-
brew install ccache tree zstd coreutils
186-
if: matrix.os == 'macos-latest'
187-
188-
- name: Set path to elan on Linux or macOS
189-
if: matrix.os == 'ubuntu-latest' || matrix.os == 'macos-latest'
190-
run: |
191-
echo "$HOME/.elan/bin" >> $GITHUB_PATH
192-
193-
- name: Set path to elan on Windows
194-
shell: pwsh
195-
if: matrix.os == 'windows-latest'
196-
run: |
197-
echo "$HOME\.elan\bin" >> $env:GITHUB_PATH
198-
199-
- name: Run tests
200-
uses: GabrielBB/xvfb-action@v1.0
201-
with:
202-
run: npm run test
203-
204294
publish-packages:
205295
if: github.event_name == 'workflow_dispatch' && inputs.action == 'publish-packages'
206296
runs-on: ubuntu-latest

0 commit comments

Comments
 (0)