browser-commander 0.16.0 → 0.16.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.16.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 542bf75: Fix CI/CD false positives, false negatives and warnings across all workflows
|
|
8
|
+
- Repair `if:` conditions that started with `!`, which a YAML plain scalar cannot do
|
|
9
|
+
- Replace `always()` with `!cancelled()` so cancelled runs stop propagating
|
|
10
|
+
- Gate `instant-release` and `changeset-pr` on lint and test, so a manual release can no longer publish unvalidated code
|
|
11
|
+
- Make the changelog fragment checks fail instead of only warning
|
|
12
|
+
- Pass `github.base_ref` and free-form `workflow_dispatch` inputs through environment variables instead of interpolating them into shell bodies
|
|
13
|
+
- Update `actions/setup-python` to v6, `codecov/codecov-action` to v7 and `peter-evans/create-pull-request` to v8
|
|
14
|
+
- Extend `scripts/check-ci-workflows.mjs` so each of the above becomes a permanent policy check
|
|
15
|
+
- Add repository-wide secrets scanning and a 1500-line file limit gate
|
|
16
|
+
|
|
3
17
|
## 0.16.0
|
|
4
18
|
|
|
5
19
|
### Minor Changes
|
package/package.json
CHANGED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import { describe, it } from 'node:test';
|
|
3
|
+
|
|
4
|
+
import { findManualVersionChanges } from '../../../../scripts/check-version-modification.mjs';
|
|
5
|
+
|
|
6
|
+
// The real implementation shells out to git; injecting the diff keeps these
|
|
7
|
+
// cases independent of the branch the suite happens to run on.
|
|
8
|
+
function stubDiff(diffsByPath) {
|
|
9
|
+
return (_baseRef, path) => diffsByPath[path] ?? '';
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
describe('check-version-modification', () => {
|
|
13
|
+
it('reports nothing when no manifest changed', () => {
|
|
14
|
+
assert.deepEqual(findManualVersionChanges('main', stubDiff({})), []);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('detects a hand-edited package.json version', () => {
|
|
18
|
+
const diff = stubDiff({
|
|
19
|
+
'js/package.json': [
|
|
20
|
+
'--- a/js/package.json',
|
|
21
|
+
'+++ b/js/package.json',
|
|
22
|
+
'- "version": "0.16.0",',
|
|
23
|
+
'+ "version": "0.17.0",',
|
|
24
|
+
].join('\n'),
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
assert.deepEqual(findManualVersionChanges('main', diff), [
|
|
28
|
+
'js/package.json',
|
|
29
|
+
]);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('detects hand-edited pyproject and Cargo versions together', () => {
|
|
33
|
+
const diff = stubDiff({
|
|
34
|
+
'python/pyproject.toml': '+version = "0.5.4"',
|
|
35
|
+
'rust/Cargo.toml': '+version = "0.9.1"',
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
assert.deepEqual(findManualVersionChanges('main', diff), [
|
|
39
|
+
'python/pyproject.toml',
|
|
40
|
+
'rust/Cargo.toml',
|
|
41
|
+
]);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('ignores a non-numeric version key', () => {
|
|
45
|
+
// pyproject declares `version = "literal: pyproject.toml: project.version"`
|
|
46
|
+
// for its release tooling; that is not a version bump.
|
|
47
|
+
const diff = stubDiff({
|
|
48
|
+
'python/pyproject.toml':
|
|
49
|
+
'+version = "literal: pyproject.toml: project.version"',
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
assert.deepEqual(findManualVersionChanges('main', diff), []);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it('ignores an unrelated edit to a manifest', () => {
|
|
56
|
+
const diff = stubDiff({
|
|
57
|
+
'js/package.json': '+ "description": "A new description",',
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
assert.deepEqual(findManualVersionChanges('main', diff), []);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it('ignores a removed version line', () => {
|
|
64
|
+
const diff = stubDiff({
|
|
65
|
+
'js/package.json': '- "version": "0.16.0",',
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
assert.deepEqual(findManualVersionChanges('main', diff), []);
|
|
69
|
+
});
|
|
70
|
+
});
|
|
@@ -70,4 +70,157 @@ jobs:
|
|
|
70
70
|
console.error = originalError;
|
|
71
71
|
}
|
|
72
72
|
});
|
|
73
|
+
|
|
74
|
+
it('rejects untrusted expressions interpolated into run bodies', () => {
|
|
75
|
+
const workflow = `name: Test
|
|
76
|
+
on:
|
|
77
|
+
workflow_dispatch:
|
|
78
|
+
inputs:
|
|
79
|
+
bump_type:
|
|
80
|
+
type: choice
|
|
81
|
+
options:
|
|
82
|
+
- patch
|
|
83
|
+
description:
|
|
84
|
+
type: string
|
|
85
|
+
env:
|
|
86
|
+
GIT_CONFIG_KEY_0: init.defaultBranch
|
|
87
|
+
jobs:
|
|
88
|
+
release:
|
|
89
|
+
runs-on: ubuntu-latest
|
|
90
|
+
timeout-minutes: 5
|
|
91
|
+
concurrency:
|
|
92
|
+
group: \${{ github.workflow }}-\${{ github.ref }}-release
|
|
93
|
+
cancel-in-progress: true
|
|
94
|
+
steps:
|
|
95
|
+
- uses: actions/checkout@v6
|
|
96
|
+
- run: echo "\${{ github.base_ref }}"
|
|
97
|
+
- run: bump "\${{ github.event.inputs.bump_type }}" "\${{ github.event.inputs.description }}"
|
|
98
|
+
- uses: peter-evans/create-pull-request@v7
|
|
99
|
+
with:
|
|
100
|
+
title: 'release \${{ github.event.inputs.description }}'
|
|
101
|
+
`;
|
|
102
|
+
const originalError = console.error;
|
|
103
|
+
console.error = () => {};
|
|
104
|
+
|
|
105
|
+
try {
|
|
106
|
+
withWorkflow(workflow, (filePath) => {
|
|
107
|
+
// One github.base_ref interpolation, one free-form input inside a run
|
|
108
|
+
// body (bump_type is a choice input, and the create-pull-request title
|
|
109
|
+
// is an action input rather than a shell body), one outdated action.
|
|
110
|
+
assert.equal(checkWorkflow(filePath), 3);
|
|
111
|
+
});
|
|
112
|
+
} finally {
|
|
113
|
+
console.error = originalError;
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
it('rejects a condition that starts with the YAML tag indicator', () => {
|
|
118
|
+
const workflow = `name: Test
|
|
119
|
+
on: push
|
|
120
|
+
env:
|
|
121
|
+
GIT_CONFIG_KEY_0: init.defaultBranch
|
|
122
|
+
jobs:
|
|
123
|
+
test:
|
|
124
|
+
runs-on: ubuntu-latest
|
|
125
|
+
timeout-minutes: 5
|
|
126
|
+
concurrency:
|
|
127
|
+
group: \${{ github.workflow }}-\${{ github.ref }}-test
|
|
128
|
+
cancel-in-progress: true
|
|
129
|
+
if: !cancelled() && github.event_name == 'push'
|
|
130
|
+
steps:
|
|
131
|
+
- uses: actions/checkout@v6
|
|
132
|
+
`;
|
|
133
|
+
const originalError = console.error;
|
|
134
|
+
console.error = () => {};
|
|
135
|
+
|
|
136
|
+
try {
|
|
137
|
+
withWorkflow(workflow, (filePath) => {
|
|
138
|
+
assert.equal(checkWorkflow(filePath), 1);
|
|
139
|
+
});
|
|
140
|
+
} finally {
|
|
141
|
+
console.error = originalError;
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
it('rejects outdated setup-python and codecov versions', () => {
|
|
146
|
+
const workflow = `name: Test
|
|
147
|
+
on: push
|
|
148
|
+
env:
|
|
149
|
+
GIT_CONFIG_KEY_0: init.defaultBranch
|
|
150
|
+
jobs:
|
|
151
|
+
test:
|
|
152
|
+
runs-on: ubuntu-latest
|
|
153
|
+
timeout-minutes: 5
|
|
154
|
+
concurrency:
|
|
155
|
+
group: \${{ github.workflow }}-\${{ github.ref }}-test
|
|
156
|
+
cancel-in-progress: true
|
|
157
|
+
steps:
|
|
158
|
+
- uses: actions/checkout@v6
|
|
159
|
+
- uses: actions/setup-python@v5
|
|
160
|
+
- uses: codecov/codecov-action@v6
|
|
161
|
+
`;
|
|
162
|
+
const originalError = console.error;
|
|
163
|
+
console.error = () => {};
|
|
164
|
+
|
|
165
|
+
try {
|
|
166
|
+
withWorkflow(workflow, (filePath) => {
|
|
167
|
+
assert.equal(checkWorkflow(filePath), 2);
|
|
168
|
+
});
|
|
169
|
+
} finally {
|
|
170
|
+
console.error = originalError;
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
it('accepts a base_ref bound to any environment variable name', () => {
|
|
175
|
+
const workflow = `name: Test
|
|
176
|
+
on: pull_request
|
|
177
|
+
env:
|
|
178
|
+
GIT_CONFIG_KEY_0: init.defaultBranch
|
|
179
|
+
jobs:
|
|
180
|
+
test:
|
|
181
|
+
runs-on: ubuntu-latest
|
|
182
|
+
timeout-minutes: 5
|
|
183
|
+
concurrency:
|
|
184
|
+
group: \${{ github.workflow }}-\${{ github.ref }}-test
|
|
185
|
+
cancel-in-progress: true
|
|
186
|
+
steps:
|
|
187
|
+
- uses: actions/checkout@v6
|
|
188
|
+
- name: Simulate fresh merge
|
|
189
|
+
env:
|
|
190
|
+
BASE_REF: \${{ github.base_ref }}
|
|
191
|
+
run: bash scripts/simulate-fresh-merge.sh
|
|
192
|
+
`;
|
|
193
|
+
|
|
194
|
+
withWorkflow(workflow, (filePath) => {
|
|
195
|
+
assert.equal(checkWorkflow(filePath), 0);
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
it('still rejects a base_ref spliced into a run body', () => {
|
|
200
|
+
const workflow = `name: Test
|
|
201
|
+
on: pull_request
|
|
202
|
+
env:
|
|
203
|
+
GIT_CONFIG_KEY_0: init.defaultBranch
|
|
204
|
+
jobs:
|
|
205
|
+
test:
|
|
206
|
+
runs-on: ubuntu-latest
|
|
207
|
+
timeout-minutes: 5
|
|
208
|
+
concurrency:
|
|
209
|
+
group: \${{ github.workflow }}-\${{ github.ref }}-test
|
|
210
|
+
cancel-in-progress: true
|
|
211
|
+
steps:
|
|
212
|
+
- uses: actions/checkout@v6
|
|
213
|
+
- run: git fetch origin \${{ github.base_ref }}
|
|
214
|
+
`;
|
|
215
|
+
const originalError = console.error;
|
|
216
|
+
console.error = () => {};
|
|
217
|
+
|
|
218
|
+
try {
|
|
219
|
+
withWorkflow(workflow, (filePath) => {
|
|
220
|
+
assert.ok(checkWorkflow(filePath) > 0);
|
|
221
|
+
});
|
|
222
|
+
} finally {
|
|
223
|
+
console.error = originalError;
|
|
224
|
+
}
|
|
225
|
+
});
|
|
73
226
|
});
|