@zairakai/js-dev-tools 3.3.0 → 3.3.2
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.
|
@@ -134,6 +134,8 @@ variables:
|
|
|
134
134
|
secret_detection:
|
|
135
135
|
stage: security
|
|
136
136
|
rules:
|
|
137
|
+
- if: $UPDATE_DEPENDENCIES == "true"
|
|
138
|
+
when: never
|
|
137
139
|
- if: $CI_PIPELINE_SOURCE == "merge_request_event" || $CI_MERGE_REQUEST_ID
|
|
138
140
|
- if: $CI_COMMIT_BRANCH == "main" || $CI_COMMIT_BRANCH == "develop"
|
|
139
141
|
|
|
@@ -144,6 +146,8 @@ js:tag-format:
|
|
|
144
146
|
stage: security
|
|
145
147
|
image: ${ALPINE_IMAGE}
|
|
146
148
|
rules:
|
|
149
|
+
- if: $UPDATE_DEPENDENCIES == "true"
|
|
150
|
+
when: never
|
|
147
151
|
- if: $CI_COMMIT_TAG
|
|
148
152
|
script:
|
|
149
153
|
- |
|
|
@@ -166,6 +170,10 @@ js:tag-format:
|
|
|
166
170
|
js:install:
|
|
167
171
|
<<: [*base_job, *cache_node_push]
|
|
168
172
|
stage: install
|
|
173
|
+
rules:
|
|
174
|
+
- if: $UPDATE_DEPENDENCIES == "true"
|
|
175
|
+
when: never
|
|
176
|
+
- when: on_success
|
|
169
177
|
image: ${NODE_IMAGE}
|
|
170
178
|
script:
|
|
171
179
|
- npm ci --cache .npm --prefer-offline
|
|
@@ -184,6 +192,10 @@ js:install:
|
|
|
184
192
|
js:validate:markdownlint:
|
|
185
193
|
<<: [*base_job, *cache_node]
|
|
186
194
|
stage: validate
|
|
195
|
+
rules:
|
|
196
|
+
- if: $UPDATE_DEPENDENCIES == "true"
|
|
197
|
+
when: never
|
|
198
|
+
- when: on_success
|
|
187
199
|
image: ${NODE_IMAGE}
|
|
188
200
|
script:
|
|
189
201
|
- bash "$JS_DEV_TOOLS_SCRIPTS/markdownlint.sh"
|
|
@@ -191,6 +203,10 @@ js:validate:markdownlint:
|
|
|
191
203
|
js:validate:shellcheck:
|
|
192
204
|
<<: *base_job
|
|
193
205
|
stage: validate
|
|
206
|
+
rules:
|
|
207
|
+
- if: $UPDATE_DEPENDENCIES == "true"
|
|
208
|
+
when: never
|
|
209
|
+
- when: on_success
|
|
194
210
|
image: ${SHELLCHECK_IMAGE}
|
|
195
211
|
before_script:
|
|
196
212
|
- apk add --no-cache bash
|
|
@@ -208,6 +224,10 @@ js:validate:shellcheck:
|
|
|
208
224
|
js:quality:lint:
|
|
209
225
|
<<: *job_node
|
|
210
226
|
stage: quality
|
|
227
|
+
rules:
|
|
228
|
+
- if: $UPDATE_DEPENDENCIES == "true"
|
|
229
|
+
when: never
|
|
230
|
+
- when: on_success
|
|
211
231
|
script:
|
|
212
232
|
- bash "$JS_DEV_TOOLS_SCRIPTS/eslint.sh"
|
|
213
233
|
artifacts:
|
|
@@ -221,18 +241,30 @@ js:quality:lint:
|
|
|
221
241
|
js:quality:format:
|
|
222
242
|
<<: *job_node
|
|
223
243
|
stage: quality
|
|
244
|
+
rules:
|
|
245
|
+
- if: $UPDATE_DEPENDENCIES == "true"
|
|
246
|
+
when: never
|
|
247
|
+
- when: on_success
|
|
224
248
|
script:
|
|
225
249
|
- bash "$JS_DEV_TOOLS_SCRIPTS/prettier.sh"
|
|
226
250
|
|
|
227
251
|
js:quality:stylelint:
|
|
228
252
|
<<: *job_node
|
|
229
253
|
stage: quality
|
|
254
|
+
rules:
|
|
255
|
+
- if: $UPDATE_DEPENDENCIES == "true"
|
|
256
|
+
when: never
|
|
257
|
+
- when: on_success
|
|
230
258
|
script:
|
|
231
259
|
- bash "$JS_DEV_TOOLS_SCRIPTS/stylelint.sh"
|
|
232
260
|
|
|
233
261
|
js:quality:typecheck:
|
|
234
262
|
<<: *job_node
|
|
235
263
|
stage: quality
|
|
264
|
+
rules:
|
|
265
|
+
- if: $UPDATE_DEPENDENCIES == "true"
|
|
266
|
+
when: never
|
|
267
|
+
- when: on_success
|
|
236
268
|
script:
|
|
237
269
|
- |
|
|
238
270
|
if [ -f tsconfig.json ] && [ -f node_modules/.bin/tsc ]; then
|
|
@@ -244,12 +276,20 @@ js:quality:typecheck:
|
|
|
244
276
|
js:quality:knip:
|
|
245
277
|
<<: *job_node
|
|
246
278
|
stage: quality
|
|
279
|
+
rules:
|
|
280
|
+
- if: $UPDATE_DEPENDENCIES == "true"
|
|
281
|
+
when: never
|
|
282
|
+
- when: on_success
|
|
247
283
|
script:
|
|
248
284
|
- bash "$JS_DEV_TOOLS_SCRIPTS/knip.sh"
|
|
249
285
|
|
|
250
286
|
js:quality:bats:
|
|
251
287
|
<<: [*base_job, *cache_node]
|
|
252
288
|
stage: quality
|
|
289
|
+
rules:
|
|
290
|
+
- if: $UPDATE_DEPENDENCIES == "true"
|
|
291
|
+
when: never
|
|
292
|
+
- when: on_success
|
|
253
293
|
image: ${ALPINE_IMAGE}
|
|
254
294
|
before_script:
|
|
255
295
|
- apk add --no-cache bash bats git
|
|
@@ -265,6 +305,8 @@ js:quality:outdated:
|
|
|
265
305
|
<<: *job_node
|
|
266
306
|
stage: quality
|
|
267
307
|
rules:
|
|
308
|
+
- if: $UPDATE_DEPENDENCIES == "true"
|
|
309
|
+
when: never
|
|
268
310
|
- if: $CI_PIPELINE_SOURCE == "schedule"
|
|
269
311
|
script:
|
|
270
312
|
- bash "$JS_DEV_TOOLS_SCRIPTS/outdated.sh"
|
|
@@ -280,6 +322,10 @@ js:quality:outdated:
|
|
|
280
322
|
js:test:
|
|
281
323
|
<<: [*base_job, *cache_node]
|
|
282
324
|
stage: test
|
|
325
|
+
rules:
|
|
326
|
+
- if: $UPDATE_DEPENDENCIES == "true"
|
|
327
|
+
when: never
|
|
328
|
+
- when: on_success
|
|
283
329
|
image: ${NODE_TEST_IMAGE}
|
|
284
330
|
script:
|
|
285
331
|
- CI=true bash "$JS_DEV_TOOLS_SCRIPTS/test.sh"
|
|
@@ -314,6 +360,8 @@ js:build:
|
|
|
314
360
|
expire_in: 1 week
|
|
315
361
|
when: on_success
|
|
316
362
|
rules:
|
|
363
|
+
- if: $UPDATE_DEPENDENCIES == "true"
|
|
364
|
+
when: never
|
|
317
365
|
- if: $CI_COMMIT_TAG =~ $VERSION_TAG_REGEX
|
|
318
366
|
- if: $CI_COMMIT_BRANCH == "main" || $CI_COMMIT_BRANCH == "develop"
|
|
319
367
|
- if: $CI_PIPELINE_SOURCE == "merge_request_event" || $CI_MERGE_REQUEST_ID
|
|
@@ -326,6 +374,8 @@ js:publish:
|
|
|
326
374
|
stage: publish
|
|
327
375
|
image: ${NODE_IMAGE}
|
|
328
376
|
rules:
|
|
377
|
+
- if: $UPDATE_DEPENDENCIES == "true"
|
|
378
|
+
when: never
|
|
329
379
|
- if: $CI_COMMIT_TAG =~ $VERSION_TAG_REGEX
|
|
330
380
|
script:
|
|
331
381
|
- |
|
|
@@ -356,6 +406,8 @@ js:release:
|
|
|
356
406
|
stage: release
|
|
357
407
|
image: ${RELEASE_CLI_IMAGE}
|
|
358
408
|
rules:
|
|
409
|
+
- if: $UPDATE_DEPENDENCIES == "true"
|
|
410
|
+
when: never
|
|
359
411
|
- if: $CI_COMMIT_TAG =~ $VERSION_TAG_REGEX
|
|
360
412
|
before_script:
|
|
361
413
|
- apk add --no-cache bash git jq
|
|
@@ -402,6 +454,7 @@ deps:update:
|
|
|
402
454
|
script:
|
|
403
455
|
- node --version
|
|
404
456
|
- "[ -d node_modules ] || npm ci --no-audit --no-fund"
|
|
457
|
+
- '[ "${JS_DEV_TOOLS_SCRIPTS}" = "scripts" ] || npm install --no-save --no-audit --no-fund "@zairakai/js-dev-tools@latest"'
|
|
405
458
|
- node "${JS_DEV_TOOLS_SCRIPTS}/update-dependencies.mjs" update
|
|
406
459
|
rules:
|
|
407
460
|
- if: $UPDATE_DEPENDENCIES == "true" && $CI_COMMIT_BRANCH == "develop"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zairakai/js-dev-tools",
|
|
3
|
-
"version": "3.3.
|
|
3
|
+
"version": "3.3.2",
|
|
4
4
|
"description": "The unified and centralized development toolkit for JavaScript/TypeScript projects - ESLint, Prettier, Stylelint, Knip, Vitest, Git Hooks, and GitLab CI pipeline templates",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"dev-tools",
|
|
@@ -111,6 +111,23 @@ export function formatChanges(rows) {
|
|
|
111
111
|
return lines.join('\n')
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
+
/** The identity and the key used to sign, from the group variables. It fails when one is missing: no unsigned tag. */
|
|
115
|
+
export function signerIdentity(env) {
|
|
116
|
+
const missing = ['GPG_PRIVATE_KEY_B64', 'RELEASE_SIGNER_NAME', 'RELEASE_SIGNER_EMAIL'].filter((name) => !env[name])
|
|
117
|
+
|
|
118
|
+
if (0 < missing.length) {
|
|
119
|
+
throw new Error(
|
|
120
|
+
`${missing.join(', ')} not set: the commits and the tags are signed, see the handbook (versioning).`
|
|
121
|
+
)
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return {
|
|
125
|
+
name: env.RELEASE_SIGNER_NAME,
|
|
126
|
+
email: env.RELEASE_SIGNER_EMAIL,
|
|
127
|
+
key: Buffer.from(env.GPG_PRIVATE_KEY_B64, 'base64').toString('utf8'),
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
114
131
|
/** What `tag` has to do: the version to create, or null (and why). */
|
|
115
132
|
export function planTag({ config, last, commits, before, after }) {
|
|
116
133
|
if ('never' === config.tag.when) return { version: null, reason: 'the project is never tagged by the update' }
|
|
@@ -179,9 +196,52 @@ function assertEnvironment() {
|
|
|
179
196
|
run('git', ['config', '--global', '--add', 'safe.directory', process.cwd()])
|
|
180
197
|
}
|
|
181
198
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
199
|
+
/** GPG is not in the image of the CI: add it with the package manager of the image (Alpine or Debian). */
|
|
200
|
+
function ensureGpg() {
|
|
201
|
+
const available = () => {
|
|
202
|
+
try {
|
|
203
|
+
run('gpg', ['--version'])
|
|
204
|
+
return true
|
|
205
|
+
} catch {
|
|
206
|
+
return false
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
if (available()) return
|
|
211
|
+
|
|
212
|
+
for (const [command, args] of [
|
|
213
|
+
['apk', ['add', '--no-cache', 'gnupg']],
|
|
214
|
+
['apt-get', ['install', '-y', '--no-install-recommends', 'gnupg']],
|
|
215
|
+
]) {
|
|
216
|
+
try {
|
|
217
|
+
run(command, args)
|
|
218
|
+
} catch {
|
|
219
|
+
continue
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
if (available()) return
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
throw new Error('gpg is not installed and could not be added: add gnupg to the image of the job.')
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/** Import the signing key and make Git sign the commits and the tags with it. */
|
|
229
|
+
function configureSigning() {
|
|
230
|
+
const signer = signerIdentity(process.env)
|
|
231
|
+
|
|
232
|
+
ensureGpg()
|
|
233
|
+
|
|
234
|
+
run('gpg', ['--batch', '--import'], { input: signer.key, stdio: ['pipe', 'pipe', 'pipe'] })
|
|
235
|
+
const fingerprint = run('gpg', ['--list-secret-keys', '--with-colons'])
|
|
236
|
+
.split('\n')
|
|
237
|
+
.find((line) => line.startsWith('fpr'))
|
|
238
|
+
.split(':')[9]
|
|
239
|
+
|
|
240
|
+
run('git', ['config', 'user.name', signer.name])
|
|
241
|
+
run('git', ['config', 'user.email', signer.email])
|
|
242
|
+
run('git', ['config', 'user.signingkey', fingerprint])
|
|
243
|
+
run('git', ['config', 'commit.gpgsign', 'true'])
|
|
244
|
+
run('git', ['config', 'tag.gpgsign', 'true'])
|
|
185
245
|
}
|
|
186
246
|
|
|
187
247
|
function remoteUrl() {
|
|
@@ -244,7 +304,7 @@ async function update(config) {
|
|
|
244
304
|
return
|
|
245
305
|
}
|
|
246
306
|
|
|
247
|
-
|
|
307
|
+
configureSigning()
|
|
248
308
|
const before = JSON.parse(readFileSync('package.json', 'utf8'))
|
|
249
309
|
const branch = `${BRANCH_PREFIX}-${new Date().toISOString().slice(0, 10).replaceAll('-', '')}`
|
|
250
310
|
run('git', ['switch', '-c', branch])
|
|
@@ -333,16 +393,11 @@ async function tag(config) {
|
|
|
333
393
|
return
|
|
334
394
|
}
|
|
335
395
|
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
message: plan.version,
|
|
340
|
-
})
|
|
341
|
-
|
|
342
|
-
if (!result.ok)
|
|
343
|
-
throw new Error(`The tag ${plan.version} could not be created: ${secret(JSON.stringify(result.data))}`)
|
|
396
|
+
configureSigning()
|
|
397
|
+
run('git', ['tag', '-s', plan.version, '-m', plan.version, process.env.CI_COMMIT_SHA])
|
|
398
|
+
run('git', ['push', remoteUrl(), `refs/tags/${plan.version}`])
|
|
344
399
|
|
|
345
|
-
log(`Tag ${plan.version}
|
|
400
|
+
log(`Tag ${plan.version} signed and pushed (last tag ${last}): ${plan.reason}. Its pipeline publishes the package.`)
|
|
346
401
|
}
|
|
347
402
|
|
|
348
403
|
async function cascade(config) {
|