-
Notifications
You must be signed in to change notification settings - Fork 0
175 lines (157 loc) · 6.62 KB
/
publish.yml
File metadata and controls
175 lines (157 loc) · 6.62 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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
name: Publish
# Fired by `git tag v0.1.0 && git push --tags`. The job verifies the
# tag matches package.json#version (so a stray tag can't ship the
# wrong build), packages the extension, publishes to both the
# VS Code Marketplace and Open VSX, then attaches the .vsix to a
# GitHub release.
#
# Tag-naming convention:
# - `v0.1.0` (stable) → stable marketplace channel.
# - `v0.1.0-rc.1` (pre-release) → pre-release marketplace channel,
# GitHub release marked `prerelease`.
# Detection is by the presence of a `-` after the semver core; see
# the "Detect pre-release tag" step below.
#
# Required repo secrets:
# - VSCE_PAT — Azure DevOps Personal Access Token, scope
# `Marketplace > Acquire and Manage`. Bound to the
# `greylag-ci` publisher on marketplace.visualstudio.com.
# - OVSX_PAT — Open VSX access token from open-vsx.org user
# settings. Bound to the `greylag-ci` namespace
# after the Eclipse Contributor Agreement is signed.
on:
push:
tags:
- 'v*'
workflow_dispatch:
inputs:
tag:
description: 'Tag to (re)publish'
required: true
type: string
# Workflow default is read-only; the publish job widens to
# `contents: write` for the GitHub release step. GitHub Actions doesn't
# support step-level permissions, so this is the tightest scope
# available without splitting into two jobs.
permissions:
contents: read
jobs:
publish:
runs-on: ubuntu-latest
# Gate the job on the `production` GitHub Environment so VSCE_PAT
# and OVSX_PAT are only readable from a run that has cleared
# whatever reviewers/branch rules the environment imposes. Anyone
# with push access can still fire workflow_dispatch, but the
# publish steps will block on the environment gate.
environment: production
permissions:
contents: write # needed by the "Create GitHub release" step
steps:
- uses: actions/checkout@v6
with:
ref: ${{ inputs.tag || github.ref }}
fetch-depth: 0 # needed for the merge-base check below
- uses: actions/setup-node@v6
with:
node-version: '20'
cache: 'npm'
- run: npm ci
- name: Verify tag matches package.json version
env:
# On tag push GITHUB_REF_NAME is the tag; on workflow_dispatch
# it's the dispatching branch, so prefer the explicit input.
REF_NAME: ${{ inputs.tag || github.ref_name }}
run: |
set -euo pipefail
tag="${REF_NAME#v}"
pkg=$(node -p "require('./package.json').version")
if [ "$tag" != "$pkg" ]; then
echo "::error::Tag v$tag does not match package.json version $pkg"
exit 1
fi
echo "Tag and package.json agree on version $pkg"
- name: Verify tag is reachable from main
env:
REF_NAME: ${{ inputs.tag || github.ref_name }}
run: |
set -euo pipefail
git fetch origin main
if ! git merge-base --is-ancestor "$REF_NAME" origin/main; then
echo "::error::Tag $REF_NAME is not reachable from origin/main — refusing to publish"
exit 1
fi
echo "Tag $REF_NAME is on main"
- name: Verify CHANGELOG has a section for this version
# publish.yml already enforces tag/version parity. This step
# closes the matching changelog-fold gap: if the "Unreleased"
# entries haven't been moved into a "## [X.Y.Z]" section, the
# release-notes extraction below would ship the wrong content.
run: |
set -euo pipefail
version=$(node -p "require('./package.json').version")
if ! grep -E "^## \[${version}\]" CHANGELOG.md > /dev/null; then
echo "::error::CHANGELOG.md is missing a '## [${version}]' section — fold the Unreleased entries before tagging"
exit 1
fi
echo "CHANGELOG section found for ${version}"
- name: Lint
run: npm run lint
- name: TypeScript compile
run: npm run compile
- name: Unit tests
run: npm test
- name: Bundle smoke
run: npm run smoke
- name: Detect pre-release tag
# A tag like `v0.2.0-rc.1` (anything with a `-` after the
# semver core) ships to the marketplace's pre-release channel
# and the GitHub release is marked prerelease. Stable tags
# (`v0.2.0`) ship to the stable channel. Detection is purely
# by the version string — keeps the convention discoverable
# via `git tag`.
run: |
set -euo pipefail
version=$(node -p "require('./package.json').version")
if [[ "$version" == *-* ]]; then
echo "Pre-release tag detected: $version"
echo "PRERELEASE_FLAG=--pre-release" >> "$GITHUB_ENV"
echo "GH_PRERELEASE=--prerelease" >> "$GITHUB_ENV"
else
echo "Stable tag: $version"
echo "PRERELEASE_FLAG=" >> "$GITHUB_ENV"
echo "GH_PRERELEASE=" >> "$GITHUB_ENV"
fi
- name: Package vsix
# vsce and ovsx are pinned devDependencies in package.json, so
# `npm ci` above installed the exact versions and Dependabot
# bumps them via the standard npm config. `npx` here resolves
# the local binary — no fresh fetch with PATs in env.
run: |
version=$(node -p "require('./package.json').version")
npx vsce package $PRERELEASE_FLAG --out "pipeline-check-${version}.vsix"
ls -lh "pipeline-check-${version}.vsix"
echo "VSIX_PATH=pipeline-check-${version}.vsix" >> $GITHUB_ENV
- name: Publish to VS Code Marketplace
env:
VSCE_PAT: ${{ secrets.VSCE_PAT }}
run: |
npx vsce publish $PRERELEASE_FLAG \
--packagePath "$VSIX_PATH" \
--pat "$VSCE_PAT"
- name: Publish to Open VSX
env:
OVSX_PAT: ${{ secrets.OVSX_PAT }}
run: |
# Open VSX (ovsx >= 0.10) honours --pre-release the same
# way vsce does. Older versions ignore the flag silently,
# so this stays safe across minor bumps.
npx ovsx publish $PRERELEASE_FLAG "$VSIX_PATH" \
--pat "$OVSX_PAT"
- name: Create GitHub release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
version=$(node -p "require('./package.json').version")
gh release create "v${version}" "$VSIX_PATH" $GH_PRERELEASE \
--title "v${version}" \
--notes-file <(awk '/^## \[/{n++} n==2{exit} n==1{print}' CHANGELOG.md)