@zairakai/js-dev-tools 3.3.0 → 3.3.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zairakai/js-dev-tools",
3
- "version": "3.3.0",
3
+ "version": "3.3.1",
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,28 @@ function assertEnvironment() {
179
196
  run('git', ['config', '--global', '--add', 'safe.directory', process.cwd()])
180
197
  }
181
198
 
182
- function configureGit() {
183
- run('git', ['config', 'user.name', 'Stanislas Poisson (autoupdate)'])
184
- run('git', ['config', 'user.email', 'contact@stanislas-poisson.fr'])
199
+ /** Import the signing key and make Git sign the commits and the tags with it. */
200
+ function configureSigning() {
201
+ const signer = signerIdentity(process.env)
202
+
203
+ try {
204
+ run('gpg', ['--version'])
205
+ } catch {
206
+ run('apt-get', ['update'])
207
+ run('apt-get', ['install', '-y', '--no-install-recommends', 'gnupg'])
208
+ }
209
+
210
+ run('gpg', ['--batch', '--import'], { input: signer.key, stdio: ['pipe', 'pipe', 'pipe'] })
211
+ const fingerprint = run('gpg', ['--list-secret-keys', '--with-colons'])
212
+ .split('\n')
213
+ .find((line) => line.startsWith('fpr'))
214
+ .split(':')[9]
215
+
216
+ run('git', ['config', 'user.name', signer.name])
217
+ run('git', ['config', 'user.email', signer.email])
218
+ run('git', ['config', 'user.signingkey', fingerprint])
219
+ run('git', ['config', 'commit.gpgsign', 'true'])
220
+ run('git', ['config', 'tag.gpgsign', 'true'])
185
221
  }
186
222
 
187
223
  function remoteUrl() {
@@ -244,7 +280,7 @@ async function update(config) {
244
280
  return
245
281
  }
246
282
 
247
- configureGit()
283
+ configureSigning()
248
284
  const before = JSON.parse(readFileSync('package.json', 'utf8'))
249
285
  const branch = `${BRANCH_PREFIX}-${new Date().toISOString().slice(0, 10).replaceAll('-', '')}`
250
286
  run('git', ['switch', '-c', branch])
@@ -333,16 +369,11 @@ async function tag(config) {
333
369
  return
334
370
  }
335
371
 
336
- const result = await api('POST', `/projects/${projectId()}/repository/tags`, {
337
- tag_name: plan.version,
338
- ref: process.env.CI_COMMIT_SHA,
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))}`)
372
+ configureSigning()
373
+ run('git', ['tag', '-s', plan.version, '-m', plan.version, process.env.CI_COMMIT_SHA])
374
+ run('git', ['push', remoteUrl(), `refs/tags/${plan.version}`])
344
375
 
345
- log(`Tag ${plan.version} created (last tag ${last}): ${plan.reason}. Its pipeline publishes the package.`)
376
+ log(`Tag ${plan.version} signed and pushed (last tag ${last}): ${plan.reason}. Its pipeline publishes the package.`)
346
377
  }
347
378
 
348
379
  async function cascade(config) {