-
-
Notifications
You must be signed in to change notification settings - Fork 1
274 lines (221 loc) · 9.22 KB
/
Copy pathci.yml
File metadata and controls
274 lines (221 loc) · 9.22 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
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
name: CI
on:
push:
branches:
- main
pull_request:
branches:
- main
permissions: {}
jobs:
build:
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
fail-fast: false
runs-on: ${{ matrix.os }}
permissions:
contents: read
steps:
- name: Configure Git line endings
if: runner.os == 'Windows'
run: git config --global core.autocrlf false
- name: Harden Runner
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit
- name: Checkout
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- name: Setup Node.js
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: '24'
cache: 'npm'
cache-dependency-path: package-lock.json
# Install at root level for npm workspaces
- name: Install dependencies
run: npm ci
- name: Lint
run: npm run lint
working-directory: extensions/git-id-switcher
- name: Compile
run: npm run compile
working-directory: extensions/git-id-switcher
- name: Run tests with coverage
run: npm run test:coverage
working-directory: extensions/git-id-switcher
- name: Upload coverage to Codecov
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
with:
directory: extensions/git-id-switcher/coverage
fail_ci_if_error: false
- name: Package
run: npm run package
working-directory: extensions/git-id-switcher
- name: Verify VSIX created
shell: bash
run: ls -la extensions/git-id-switcher/*.vsix
- name: Verify package.json URLs (anti-impersonation)
shell: bash
run: |
cd extensions/git-id-switcher
REPO_URL=$(node -e "console.log(require('./package.json').repository.url)")
HOMEPAGE=$(node -e "console.log(require('./package.json').homepage)")
EXPECTED_REPO="https://github.com/nullvariant/nullvariant-vscode-extensions"
EXPECTED_HOME_PREFIX="https://github.com/nullvariant/nullvariant-vscode-extensions"
if [ "$REPO_URL" != "$EXPECTED_REPO" ]; then
echo "::error::repository.url mismatch: expected '$EXPECTED_REPO', got '$REPO_URL'"
exit 1
fi
if [[ "$HOMEPAGE" != "$EXPECTED_HOME_PREFIX"* ]]; then
echo "::error::homepage does not start with '$EXPECTED_HOME_PREFIX': got '$HOMEPAGE'"
exit 1
fi
echo "package.json URLs verified"
e2e:
name: E2E Tests (${{ matrix.os }})
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
fail-fast: false
runs-on: ${{ matrix.os }}
permissions:
contents: read
steps:
- name: Configure Git line endings
if: runner.os == 'Windows'
run: git config --global core.autocrlf false
- name: Harden Runner
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit
- name: Checkout
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- name: Setup Node.js
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: '24'
cache: 'npm'
cache-dependency-path: package-lock.json
# Install at root level for npm workspaces
- name: Install dependencies
run: npm ci
- name: Run E2E tests (Linux)
if: runner.os == 'Linux'
run: xvfb-run -a npm run test:e2e
working-directory: extensions/git-id-switcher
- name: Run E2E tests (Windows/macOS)
if: runner.os != 'Linux'
run: npm run test:e2e
working-directory: extensions/git-id-switcher
vex-dependency-review:
name: VEX Dependency Review
runs-on: ubuntu-latest
# Only run on dependency update PRs (Dependabot or Renovate)
if: >
github.event_name == 'pull_request' &&
(github.actor == 'dependabot[bot]' || github.actor == 'renovate[bot]')
permissions:
contents: read
pull-requests: write
steps:
- name: Harden Runner
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit
- name: Checkout repository
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
fetch-depth: 0
- name: Check for production dependency changes
id: check
run: |
BASE_REF="${{ github.event.pull_request.base.sha }}"
HEAD_REF="${{ github.event.pull_request.head.sha }}"
# Get production dependency count from base and head
BASE_DEPS=$(git show "${BASE_REF}:extensions/git-id-switcher/package.json" | jq -r '.dependencies // {} | keys | length')
HEAD_DEPS=$(git show "${HEAD_REF}:extensions/git-id-switcher/package.json" | jq -r '.dependencies // {} | keys | length')
echo "Base production deps: $BASE_DEPS"
echo "Head production deps: $HEAD_DEPS"
if [ "$HEAD_DEPS" != "0" ]; then
echo "has_prod_deps=true" >> "$GITHUB_OUTPUT"
NEW_DEPS=$(git show "${HEAD_REF}:extensions/git-id-switcher/package.json" | jq -r '.dependencies | keys[]')
echo "prod_deps<<DEPSEOF" >> "$GITHUB_OUTPUT"
echo "$NEW_DEPS" >> "$GITHUB_OUTPUT"
echo "DEPSEOF" >> "$GITHUB_OUTPUT"
echo "::error::Production dependencies detected. VEX must be manually reviewed."
else
echo "has_prod_deps=false" >> "$GITHUB_OUTPUT"
fi
- name: Post VEX assessment (devDependencies only)
if: steps.check.outputs.has_prod_deps == 'false'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# Prevent duplicate comments on force-pushed PRs
EXISTING=$(gh pr view "${{ github.event.pull_request.number }}" --json comments \
--jq '.comments[] | select(.body | contains("VEX Assessment")) | .id' | head -1)
if [ -n "$EXISTING" ]; then
echo "VEX assessment comment already exists. Skipping."
exit 0
fi
gh pr comment "${{ github.event.pull_request.number }}" --body "$(cat <<'COMMENTEOF'
### VEX Assessment: `not_affected`
This dependency update modifies **devDependencies only**.
- **Status**: `not_affected`
- **Justification**: `vulnerable_code_not_in_execute_path`
- **Impact**: Zero production dependencies. No third-party code is included in the published VSIX.
Any CVEs in updated devDependencies do not affect end users. The VEX document will be automatically updated by the weekly [VEX Auto-Update](.github/workflows/vex-update.yml) workflow.
🤖 Automated VEX assessment
COMMENTEOF
)"
- name: Warn about production dependencies
if: steps.check.outputs.has_prod_deps == 'true'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# Prevent duplicate comments on force-pushed PRs
EXISTING=$(gh pr view "${{ github.event.pull_request.number }}" --json comments \
--jq '.comments[] | select(.body | contains("VEX Assessment")) | .id' | head -1)
if [ -n "$EXISTING" ]; then
echo "VEX assessment comment already exists. Skipping."
else
DEPS="${{ steps.check.outputs.prod_deps }}"
gh pr comment "${{ github.event.pull_request.number }}" --body "$(cat <<COMMENTEOF
### ⚠️ VEX Assessment: Manual Review Required
This PR adds **production dependencies**:
\`\`\`
$DEPS
\`\`\`
Production dependencies are bundled into the published VSIX and may affect end users.
The current VEX blanket statement (\`not_affected\` for all CVEs) **no longer applies**.
**Action required:**
1. Review whether production dependencies are truly necessary
2. Update \`.vex/vex.json\` to reflect the new risk assessment
3. Consider the impact on supply chain security
🤖 Automated VEX assessment
COMMENTEOF
)"
fi
# Always fail when production dependencies are detected
exit 1
dependency-review:
name: Dependency Review
runs-on: ubuntu-latest
# Only run on pull requests (requires base/head comparison)
if: github.event_name == 'pull_request'
permissions:
contents: read
pull-requests: write
steps:
- name: Harden Runner
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit
- name: Checkout
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- name: Dependency Review
uses: actions/dependency-review-action@a1d282b36b6f3519aa1f3fc636f609c47dddb294 # v5.0.0
with:
config-file: './.github/dependency-review-config.yml'
comment-summary-in-pr: always