@rtorcato/js-tooling 2.13.0 → 2.14.0

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.
@@ -661,7 +661,7 @@ async function checkGitLabCI(dir) {
661
661
  check: 'GitLab CI',
662
662
  status: 'optional-missing',
663
663
  detail: 'no .gitlab-ci.yml',
664
- hint: 'Add a .gitlab-ci.yml if this repo is hosted on GitLab',
664
+ hint: 'Run `npx @rtorcato/js-tooling fix gitlab-ci` to scaffold a starter GitLab pipeline',
665
665
  };
666
666
  }
667
667
  export async function runDoctor(dir) {
@@ -21,6 +21,7 @@ export const FIX_TARGETS = {
21
21
  Dependabot: 'dependabot',
22
22
  CodeQL: 'codeql',
23
23
  CODEOWNERS: 'codeowners',
24
+ 'GitLab CI': 'gitlab-ci',
24
25
  lockfile: 'lockfile',
25
26
  '.js-tooling.json': 'lockfile',
26
27
  };
@@ -5,6 +5,7 @@ import inquirer from 'inquirer';
5
5
  import { generateSemanticReleaseConfig } from '../generators/build.js';
6
6
  import { generateCommitlintConfig, generateHuskyConfig, generatePrePushHook, } from '../generators/git.js';
7
7
  import { generateGitHubActions } from '../generators/github-actions.js';
8
+ import { generateGitLabCI } from '../generators/gitlab-ci.js';
8
9
  import { generateESLintConfig, generatePrettierConfig } from '../generators/linting.js';
9
10
  import { ensureEnginesNode, generateCodeowners, generateEditorConfig, generateKnipConfig, generateNvmrc, generateSizeLimitConfig, } from '../generators/misc.js';
10
11
  import { generateConfigs } from '../generators/index.js';
@@ -243,6 +244,17 @@ const FIXERS = [
243
244
  return { filesWritten: [written] };
244
245
  },
245
246
  },
247
+ {
248
+ target: 'gitlab-ci',
249
+ description: 'Scaffold .gitlab-ci.yml (lint/typecheck/test/build mirrored from GitHub Actions)',
250
+ appliesTo: ['GitLab CI'],
251
+ outputs: ['.gitlab-ci.yml'],
252
+ canFixDrift: true,
253
+ async run({ targetDir, pkg }) {
254
+ const written = await generateGitLabCI(inferProjectConfig(pkg), targetDir);
255
+ return { filesWritten: [written] };
256
+ },
257
+ },
246
258
  {
247
259
  target: 'editorconfig',
248
260
  description: 'Scaffold .editorconfig (UTF-8, LF, tab indent)',
@@ -0,0 +1,87 @@
1
+ import path from 'node:path';
2
+ import fs from 'fs-extra';
3
+ export async function generateGitLabCI(config, targetDir) {
4
+ const yamlPath = path.join(targetDir, '.gitlab-ci.yml');
5
+ await fs.writeFile(yamlPath, renderGitLabCI(config));
6
+ return '.gitlab-ci.yml';
7
+ }
8
+ function lintCommand(config) {
9
+ if (config.linting.tool === 'biome' || config.linting.tool === 'both')
10
+ return 'pnpm check';
11
+ return 'pnpm lint';
12
+ }
13
+ function renderGitLabCI(config) {
14
+ const hasTypeScript = config.typescript.enabled;
15
+ const hasTests = config.testing.framework !== 'none';
16
+ const hasLint = config.linting.tool !== 'none';
17
+ const hasBuild = config.bundler !== 'none';
18
+ const stages = [];
19
+ if (hasLint || hasTypeScript || hasTests)
20
+ stages.push('test');
21
+ if (hasBuild)
22
+ stages.push('build');
23
+ if (stages.length === 0)
24
+ stages.push('test');
25
+ const jobs = [];
26
+ if (hasLint) {
27
+ jobs.push(`lint:
28
+ stage: test
29
+ script:
30
+ - ${lintCommand(config)}`);
31
+ }
32
+ if (hasTypeScript) {
33
+ jobs.push(`typecheck:
34
+ stage: test
35
+ script:
36
+ - pnpm typecheck`);
37
+ }
38
+ if (hasTests) {
39
+ const testCmd = config.testing.framework === 'vitest'
40
+ ? 'pnpm exec vitest run'
41
+ : config.testing.framework === 'playwright'
42
+ ? 'pnpm test:e2e'
43
+ : 'pnpm test';
44
+ jobs.push(`test:
45
+ stage: test
46
+ script:
47
+ - ${testCmd}`);
48
+ }
49
+ if (hasBuild) {
50
+ jobs.push(`build:
51
+ stage: build
52
+ script:
53
+ - pnpm build
54
+ artifacts:
55
+ paths:
56
+ - dist/
57
+ expire_in: 1 week`);
58
+ }
59
+ return `# .gitlab-ci.yml — generated by @rtorcato/js-tooling
60
+ # Customize stages and jobs to fit your pipeline.
61
+
62
+ image: node:20
63
+
64
+ stages:
65
+ ${stages.map((s) => ` - ${s}`).join('\n')}
66
+
67
+ variables:
68
+ PNPM_CACHE_FOLDER: .pnpm-store
69
+
70
+ cache:
71
+ key:
72
+ files:
73
+ - pnpm-lock.yaml
74
+ paths:
75
+ - .pnpm-store
76
+ - node_modules
77
+
78
+ default:
79
+ before_script:
80
+ - corepack enable
81
+ - corepack prepare pnpm@latest --activate
82
+ - pnpm config set store-dir "$PNPM_CACHE_FOLDER"
83
+ - pnpm install --frozen-lockfile
84
+
85
+ ${jobs.join('\n\n')}
86
+ `;
87
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rtorcato/js-tooling",
3
- "version": "2.13.0",
3
+ "version": "2.14.0",
4
4
  "description": "JavaScript and TypeScript tooling for Node.js, React, Next.js, and Vitest.",
5
5
  "type": "module",
6
6
  "keywords": [