@zairakai/dev-tools 1.0.11
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/.editorconfig +86 -0
- package/.gitlab/ci/pipeline-js.yml +189 -0
- package/.gitlab/ci/pipeline-npm-package.yml +353 -0
- package/LICENSE +21 -0
- package/README.md +162 -0
- package/config/.markdownlint.json +7 -0
- package/config/.markdownlintignore +5 -0
- package/config/.prettierignore +10 -0
- package/config/.stylelintignore +7 -0
- package/config/eslint.config.js +191 -0
- package/config/prettier.config.js +121 -0
- package/config/stylelint.config.js +56 -0
- package/config/tsconfig.base.json +20 -0
- package/config/vitest.config.js +25 -0
- package/index.js +22 -0
- package/package.json +137 -0
- package/scripts/build.sh +54 -0
- package/scripts/ci-quality.sh +47 -0
- package/scripts/config.sh +193 -0
- package/scripts/eslint-fix.sh +34 -0
- package/scripts/eslint.sh +46 -0
- package/scripts/install-bats.sh +227 -0
- package/scripts/install-shellcheck.sh +232 -0
- package/scripts/knip.sh +33 -0
- package/scripts/markdownlint-fix.sh +8 -0
- package/scripts/markdownlint.sh +43 -0
- package/scripts/prettier-fix.sh +33 -0
- package/scripts/prettier.sh +34 -0
- package/scripts/setup-project.sh +702 -0
- package/scripts/stylelint-fix.sh +39 -0
- package/scripts/stylelint.sh +47 -0
- package/scripts/test.sh +43 -0
- package/scripts/typecheck.sh +35 -0
- package/scripts/validate-shellcheck.sh +70 -0
- package/stubs/eslint.config.js.stub +18 -0
- package/stubs/gitlab-ci.yml.stub +18 -0
- package/stubs/gitlab-pipeline-js.yml.stub +16 -0
- package/stubs/prettier.config.js.stub +16 -0
- package/stubs/stylelint.config.js.stub +17 -0
- package/stubs/tsconfig.json.stub +10 -0
- package/stubs/vitest.config.js.stub +18 -0
- package/tools/make/bats.mk +49 -0
- package/tools/make/code-style.mk +29 -0
- package/tools/make/core.mk +50 -0
- package/tools/make/help.mk +32 -0
- package/tools/make/markdownlint.mk +17 -0
- package/tools/make/quality.mk +20 -0
- package/tools/make/shellcheck.mk +14 -0
- package/tools/make/stylelint.mk +0 -0
- package/tools/make/test.mk +19 -0
- package/tools/make/typescript.mk +14 -0
- package/tools/make/variables.mk +35 -0
package/.editorconfig
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# ===============================================
|
|
2
|
+
# EDITORCONFIG
|
|
3
|
+
# Coding standards for consistent formatting
|
|
4
|
+
# ===============================================
|
|
5
|
+
|
|
6
|
+
root = true
|
|
7
|
+
|
|
8
|
+
# ======================
|
|
9
|
+
# ALL FILES
|
|
10
|
+
# ======================
|
|
11
|
+
[*]
|
|
12
|
+
charset = utf-8
|
|
13
|
+
end_of_line = lf
|
|
14
|
+
indent_size = 4
|
|
15
|
+
indent_style = space
|
|
16
|
+
insert_final_newline = true
|
|
17
|
+
trim_trailing_whitespace = true
|
|
18
|
+
|
|
19
|
+
# ======================
|
|
20
|
+
# MARKDOWN FILES
|
|
21
|
+
# ======================
|
|
22
|
+
[markdown]
|
|
23
|
+
indent_style = space
|
|
24
|
+
indent_size = 4
|
|
25
|
+
trim_trailing_whitespace = false
|
|
26
|
+
insert_final_newline = true
|
|
27
|
+
max_line_length = 120
|
|
28
|
+
|
|
29
|
+
[*.md]
|
|
30
|
+
trim_trailing_whitespace = false
|
|
31
|
+
|
|
32
|
+
# ======================
|
|
33
|
+
# SHELL SCRIPTS
|
|
34
|
+
# ======================
|
|
35
|
+
[*.sh]
|
|
36
|
+
end_of_line = lf
|
|
37
|
+
|
|
38
|
+
# ======================
|
|
39
|
+
# YAML FILES
|
|
40
|
+
# ======================
|
|
41
|
+
[*.{yml,yaml}]
|
|
42
|
+
indent_size = 2
|
|
43
|
+
|
|
44
|
+
[docker-compose.yml]
|
|
45
|
+
indent_size = 4
|
|
46
|
+
|
|
47
|
+
# ======================
|
|
48
|
+
# BUILD FILES
|
|
49
|
+
# ======================
|
|
50
|
+
[Makefile]
|
|
51
|
+
indent_style = tab
|
|
52
|
+
|
|
53
|
+
[Dockerfile*]
|
|
54
|
+
indent_size = 4
|
|
55
|
+
|
|
56
|
+
# ======================
|
|
57
|
+
# CONFIGURATION FILES
|
|
58
|
+
# ======================
|
|
59
|
+
[*.{ini,conf}]
|
|
60
|
+
indent_size = 4
|
|
61
|
+
|
|
62
|
+
# ======================
|
|
63
|
+
# FRONTEND FILES
|
|
64
|
+
# ======================
|
|
65
|
+
[*.json]
|
|
66
|
+
indent_size = 2
|
|
67
|
+
|
|
68
|
+
# ======================
|
|
69
|
+
# PHP FILES
|
|
70
|
+
# ======================
|
|
71
|
+
[*.php]
|
|
72
|
+
indent_size = 4
|
|
73
|
+
max_line_length = 120
|
|
74
|
+
|
|
75
|
+
# ======================
|
|
76
|
+
# Test FILES
|
|
77
|
+
# ======================
|
|
78
|
+
[*.feature]
|
|
79
|
+
charset = utf-8
|
|
80
|
+
gherkin_indent_feature_children = true
|
|
81
|
+
gherkin_indent_steps = true
|
|
82
|
+
gherkin_indent_datatable = true
|
|
83
|
+
gherkin_indent_docstring = true
|
|
84
|
+
gherkin_indent_examples_table = true
|
|
85
|
+
gherkin_table_cell_padding_size = 2
|
|
86
|
+
gherkin_table_cell_right_align_numeric_content = true
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
# ================================
|
|
2
|
+
# PIPELINE TEMPLATE — Laravel App JS/Frontend
|
|
3
|
+
# ================================
|
|
4
|
+
# Provides JS/Frontend CI jobs for a Laravel application.
|
|
5
|
+
# PHP jobs come from laravel-dev-tools (pipeline-laravel-app.yml).
|
|
6
|
+
#
|
|
7
|
+
# Fullstack usage (recommended — single include):
|
|
8
|
+
# ─────────────────────────────────────────────────────
|
|
9
|
+
# include:
|
|
10
|
+
# - project: 'zairakai/packagist/laravel-dev-tools'
|
|
11
|
+
# ref: main
|
|
12
|
+
# file: '.gitlab/ci/pipeline-laravel-fullstack.yml'
|
|
13
|
+
#
|
|
14
|
+
# Standalone usage (without laravel-dev-tools):
|
|
15
|
+
# ─────────────────────────────────────────────────────
|
|
16
|
+
# include:
|
|
17
|
+
# - project: 'zairakai/packagist/laravel-dev-tools'
|
|
18
|
+
# ref: main
|
|
19
|
+
# file: '.gitlab/ci/pipeline-laravel-app.yml'
|
|
20
|
+
# - project: 'zairakai/npm/dev-tools'
|
|
21
|
+
# ref: main
|
|
22
|
+
# file: '.gitlab/ci/pipeline-js.yml'
|
|
23
|
+
#
|
|
24
|
+
# variables:
|
|
25
|
+
# CACHE_KEY: "my-app-v1"
|
|
26
|
+
# ================================
|
|
27
|
+
|
|
28
|
+
# ================================
|
|
29
|
+
# STAGES
|
|
30
|
+
# ================================
|
|
31
|
+
# Merges with PHP pipeline stages — GitLab deduplicates identical names.
|
|
32
|
+
stages:
|
|
33
|
+
- security
|
|
34
|
+
- install
|
|
35
|
+
- validate
|
|
36
|
+
- quality
|
|
37
|
+
- test
|
|
38
|
+
- deploy
|
|
39
|
+
- metrics
|
|
40
|
+
|
|
41
|
+
# ================================
|
|
42
|
+
# DEFAULT VARIABLES
|
|
43
|
+
# ================================
|
|
44
|
+
variables:
|
|
45
|
+
# ── OVERRIDE PER PROJECT ──────────────────────────────────────────────────
|
|
46
|
+
CACHE_KEY: "zairakai-laravel-app"
|
|
47
|
+
|
|
48
|
+
# Points to the installed npm dev-tools package
|
|
49
|
+
DEV_TOOLS_SCRIPTS: "node_modules/@zairakai/dev-tools/scripts"
|
|
50
|
+
|
|
51
|
+
# ── NODE ──────────────────────────────────────────────────────────────────
|
|
52
|
+
NODE_VERSION: "22"
|
|
53
|
+
NODE_IMAGE: "zairakai/node:latest-dev"
|
|
54
|
+
|
|
55
|
+
# ── GIT ───────────────────────────────────────────────────────────────────
|
|
56
|
+
GIT_DEPTH: 1
|
|
57
|
+
GIT_STRATEGY: fetch
|
|
58
|
+
# Note: GIT_CLEAN_FLAGS is intentionally NOT set here.
|
|
59
|
+
# In fullstack mode, pipeline-laravel-fullstack.yml sets the combined value
|
|
60
|
+
# to exclude both vendor/ and node_modules/ from git clean.
|
|
61
|
+
|
|
62
|
+
# ================================
|
|
63
|
+
# ANCHORS
|
|
64
|
+
# ================================
|
|
65
|
+
.base_job_js: &base_job_js
|
|
66
|
+
retry:
|
|
67
|
+
max: 2
|
|
68
|
+
when:
|
|
69
|
+
- runner_system_failure
|
|
70
|
+
- stuck_or_timeout_failure
|
|
71
|
+
|
|
72
|
+
.cache_node_js: &cache_node_js
|
|
73
|
+
cache:
|
|
74
|
+
key:
|
|
75
|
+
files:
|
|
76
|
+
- package-lock.json
|
|
77
|
+
prefix: "js-${CACHE_KEY}"
|
|
78
|
+
paths:
|
|
79
|
+
- node_modules/
|
|
80
|
+
- .npm/
|
|
81
|
+
policy: pull
|
|
82
|
+
|
|
83
|
+
.cache_node_js_push: &cache_node_js_push
|
|
84
|
+
cache:
|
|
85
|
+
key:
|
|
86
|
+
files:
|
|
87
|
+
- package-lock.json
|
|
88
|
+
prefix: "js-${CACHE_KEY}"
|
|
89
|
+
paths:
|
|
90
|
+
- node_modules/
|
|
91
|
+
- .npm/
|
|
92
|
+
policy: pull-push
|
|
93
|
+
|
|
94
|
+
.job_node_js: &job_node_js
|
|
95
|
+
<<: [*base_job_js, *cache_node_js]
|
|
96
|
+
image: ${NODE_IMAGE}
|
|
97
|
+
before_script:
|
|
98
|
+
- node --version
|
|
99
|
+
- npm --version
|
|
100
|
+
|
|
101
|
+
.js_validate_needs: &js_validate_needs
|
|
102
|
+
needs:
|
|
103
|
+
- validate:js:markdownlint
|
|
104
|
+
|
|
105
|
+
# ================================
|
|
106
|
+
# INSTALL (JS)
|
|
107
|
+
# ================================
|
|
108
|
+
install:js:
|
|
109
|
+
<<: [*base_job_js, *cache_node_js_push]
|
|
110
|
+
stage: install
|
|
111
|
+
image: ${NODE_IMAGE}
|
|
112
|
+
script:
|
|
113
|
+
- npm ci --cache .npm --prefer-offline
|
|
114
|
+
artifacts:
|
|
115
|
+
paths:
|
|
116
|
+
- node_modules/
|
|
117
|
+
expire_in: 1 hour
|
|
118
|
+
|
|
119
|
+
# ================================
|
|
120
|
+
# VALIDATE (JS)
|
|
121
|
+
# ================================
|
|
122
|
+
validate:js:markdownlint:
|
|
123
|
+
<<: *job_node_js
|
|
124
|
+
stage: validate
|
|
125
|
+
needs:
|
|
126
|
+
- install:js
|
|
127
|
+
script:
|
|
128
|
+
- bash "$DEV_TOOLS_SCRIPTS/markdownlint.sh"
|
|
129
|
+
|
|
130
|
+
# ================================
|
|
131
|
+
# QUALITY (JS)
|
|
132
|
+
# ================================
|
|
133
|
+
quality:js:lint:
|
|
134
|
+
<<: [*job_node_js, *js_validate_needs]
|
|
135
|
+
stage: quality
|
|
136
|
+
script:
|
|
137
|
+
- bash "$DEV_TOOLS_SCRIPTS/eslint.sh"
|
|
138
|
+
artifacts:
|
|
139
|
+
reports:
|
|
140
|
+
junit: reports/eslint.xml
|
|
141
|
+
paths:
|
|
142
|
+
- reports/
|
|
143
|
+
expire_in: 1 week
|
|
144
|
+
when: always
|
|
145
|
+
|
|
146
|
+
quality:js:format:
|
|
147
|
+
<<: [*job_node_js, *js_validate_needs]
|
|
148
|
+
stage: quality
|
|
149
|
+
script:
|
|
150
|
+
- bash "$DEV_TOOLS_SCRIPTS/prettier.sh"
|
|
151
|
+
|
|
152
|
+
quality:js:stylelint:
|
|
153
|
+
<<: [*job_node_js, *js_validate_needs]
|
|
154
|
+
stage: quality
|
|
155
|
+
script:
|
|
156
|
+
- bash "$DEV_TOOLS_SCRIPTS/stylelint.sh"
|
|
157
|
+
allow_failure: true
|
|
158
|
+
|
|
159
|
+
quality:js:typecheck:
|
|
160
|
+
<<: [*job_node_js, *js_validate_needs]
|
|
161
|
+
stage: quality
|
|
162
|
+
script:
|
|
163
|
+
- |
|
|
164
|
+
if [ -f tsconfig.json ] && [ -f node_modules/.bin/tsc ]; then
|
|
165
|
+
bash "$DEV_TOOLS_SCRIPTS/typecheck.sh"
|
|
166
|
+
else
|
|
167
|
+
echo "TypeScript not configured — skipping (add tsconfig.json + typescript to devDependencies)"
|
|
168
|
+
fi
|
|
169
|
+
allow_failure: true
|
|
170
|
+
|
|
171
|
+
# ================================
|
|
172
|
+
# TEST (JS)
|
|
173
|
+
# ================================
|
|
174
|
+
test:js:
|
|
175
|
+
<<: *job_node_js
|
|
176
|
+
stage: test
|
|
177
|
+
script:
|
|
178
|
+
- CI=true bash "$DEV_TOOLS_SCRIPTS/test.sh"
|
|
179
|
+
coverage: '/All files[^|]*\|[^|]*\s+([\d\.]+)/'
|
|
180
|
+
artifacts:
|
|
181
|
+
reports:
|
|
182
|
+
junit: build/coverage/junit.xml
|
|
183
|
+
coverage_report:
|
|
184
|
+
coverage_format: cobertura
|
|
185
|
+
path: build/coverage/cobertura-coverage.xml
|
|
186
|
+
paths:
|
|
187
|
+
- build/coverage/
|
|
188
|
+
expire_in: 1 week
|
|
189
|
+
when: always
|
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
# ================================
|
|
2
|
+
# PIPELINE TEMPLATE — NPM Package
|
|
3
|
+
# ================================
|
|
4
|
+
# Shared pipeline template for NPM packages in the Zairakai namespace.
|
|
5
|
+
# Self-contained: anchors and jobs are all in this single file.
|
|
6
|
+
# YAML anchors do not survive cross-file include: — this is a YAML parser
|
|
7
|
+
# limitation, not a GitLab one. Everything is therefore kept here.
|
|
8
|
+
#
|
|
9
|
+
# USAGE in a consumer project:
|
|
10
|
+
# ─────────────────────────────────────────
|
|
11
|
+
# include:
|
|
12
|
+
# - project: 'zairakai/npm/dev-tools'
|
|
13
|
+
# ref: main
|
|
14
|
+
# file: '.gitlab/ci/pipeline-npm-package.yml'
|
|
15
|
+
#
|
|
16
|
+
# variables:
|
|
17
|
+
# CACHE_KEY: "my-package-v1"
|
|
18
|
+
# NPM_PACKAGE_NAME: "@myorg/my-package"
|
|
19
|
+
#
|
|
20
|
+
# FOR dev-tools ITSELF (self-hosted mode):
|
|
21
|
+
# ─────────────────────────────────────────────────────
|
|
22
|
+
# include:
|
|
23
|
+
# - local: '.gitlab/ci/pipeline-npm-package.yml'
|
|
24
|
+
#
|
|
25
|
+
# variables:
|
|
26
|
+
# CACHE_KEY: "dev-tools-v1"
|
|
27
|
+
# NPM_PACKAGE_NAME: "@zairakai/dev-tools"
|
|
28
|
+
# DEV_TOOLS_SCRIPTS: "scripts"
|
|
29
|
+
# ================================
|
|
30
|
+
|
|
31
|
+
include:
|
|
32
|
+
- template: Jobs/Secret-Detection.gitlab-ci.yml
|
|
33
|
+
|
|
34
|
+
# ================================
|
|
35
|
+
# WORKFLOW
|
|
36
|
+
# ================================
|
|
37
|
+
workflow:
|
|
38
|
+
rules:
|
|
39
|
+
- if: $CI_COMMIT_TAG =~ /^v\d+\.\d+\.\d+$/
|
|
40
|
+
- if: $CI_PIPELINE_SOURCE == "merge_request_event" || $CI_MERGE_REQUEST_ID
|
|
41
|
+
- if: $CI_COMMIT_BRANCH == "main" || $CI_COMMIT_BRANCH == "develop"
|
|
42
|
+
- if: $CI_COMMIT_REF_NAME =~ /^feature\// || $CI_COMMIT_REF_NAME =~ /^fix\// || $CI_COMMIT_REF_NAME =~ /^hotfix\//
|
|
43
|
+
- when: never
|
|
44
|
+
|
|
45
|
+
# ================================
|
|
46
|
+
# STAGES
|
|
47
|
+
# ================================
|
|
48
|
+
stages:
|
|
49
|
+
- security
|
|
50
|
+
- install
|
|
51
|
+
- validate
|
|
52
|
+
- quality
|
|
53
|
+
- test
|
|
54
|
+
- build
|
|
55
|
+
- publish
|
|
56
|
+
- release
|
|
57
|
+
|
|
58
|
+
# ================================
|
|
59
|
+
# DEFAULT VARIABLES
|
|
60
|
+
# ================================
|
|
61
|
+
variables:
|
|
62
|
+
# ── OVERRIDE PER PROJECT ──────────────────────────────────────────────────
|
|
63
|
+
CACHE_KEY: "zairakai-npm-package"
|
|
64
|
+
NPM_PACKAGE_NAME: "@zairakai/package"
|
|
65
|
+
|
|
66
|
+
# Paths to dev-tools scripts.
|
|
67
|
+
# Consumer projects do NOT need to override these.
|
|
68
|
+
# dev-tools itself overrides them in its own .gitlab-ci.yml.
|
|
69
|
+
DEV_TOOLS_SCRIPTS: "node_modules/@zairakai/dev-tools/scripts"
|
|
70
|
+
|
|
71
|
+
# ── NODE ──────────────────────────────────────────────────────────────────
|
|
72
|
+
NODE_VERSION: "22"
|
|
73
|
+
NODE_IMAGE: "zairakai/node:latest-dev"
|
|
74
|
+
NODE_TEST_IMAGE: "zairakai/node:latest-test"
|
|
75
|
+
SHELLCHECK_IMAGE: "koalaman/shellcheck-alpine:v0.10.0"
|
|
76
|
+
RELEASE_CLI_IMAGE: "registry.gitlab.com/gitlab-org/release-cli:v0.18.0"
|
|
77
|
+
ALPINE_IMAGE: "alpine:3.18"
|
|
78
|
+
|
|
79
|
+
# ── GIT ───────────────────────────────────────────────────────────────────
|
|
80
|
+
GIT_DEPTH: 1
|
|
81
|
+
GIT_STRATEGY: fetch
|
|
82
|
+
GIT_CLEAN_FLAGS: "-ffdx -e node_modules/ -e .npm/"
|
|
83
|
+
|
|
84
|
+
# ── SECURITY ──────────────────────────────────────────────────────────────
|
|
85
|
+
SECRET_DETECTION_EXCLUDED_PATHS: "node_modules/,dist/,build/,coverage/"
|
|
86
|
+
|
|
87
|
+
# ================================
|
|
88
|
+
# ANCHORS
|
|
89
|
+
# ================================
|
|
90
|
+
.base_job: &base_job
|
|
91
|
+
retry:
|
|
92
|
+
max: 2
|
|
93
|
+
when:
|
|
94
|
+
- runner_system_failure
|
|
95
|
+
- stuck_or_timeout_failure
|
|
96
|
+
|
|
97
|
+
.cache_node: &cache_node
|
|
98
|
+
cache:
|
|
99
|
+
key:
|
|
100
|
+
files:
|
|
101
|
+
- package-lock.json
|
|
102
|
+
prefix: $CACHE_KEY
|
|
103
|
+
paths:
|
|
104
|
+
- node_modules/
|
|
105
|
+
- .npm/
|
|
106
|
+
policy: pull
|
|
107
|
+
|
|
108
|
+
.cache_node_push: &cache_node_push
|
|
109
|
+
cache:
|
|
110
|
+
key:
|
|
111
|
+
files:
|
|
112
|
+
- package-lock.json
|
|
113
|
+
prefix: $CACHE_KEY
|
|
114
|
+
paths:
|
|
115
|
+
- node_modules/
|
|
116
|
+
- .npm/
|
|
117
|
+
policy: pull-push
|
|
118
|
+
|
|
119
|
+
.job_node: &job_node
|
|
120
|
+
<<: [*base_job, *cache_node]
|
|
121
|
+
image: ${NODE_IMAGE}
|
|
122
|
+
before_script:
|
|
123
|
+
- node --version
|
|
124
|
+
- npm --version
|
|
125
|
+
|
|
126
|
+
.quality_needs: &quality_needs
|
|
127
|
+
needs:
|
|
128
|
+
- validate:shellcheck
|
|
129
|
+
|
|
130
|
+
# ================================
|
|
131
|
+
# SECURITY
|
|
132
|
+
# ================================
|
|
133
|
+
secret_detection:
|
|
134
|
+
stage: security
|
|
135
|
+
rules:
|
|
136
|
+
- if: $CI_PIPELINE_SOURCE == "merge_request_event" || $CI_MERGE_REQUEST_ID
|
|
137
|
+
- if: $CI_COMMIT_BRANCH == "main" || $CI_COMMIT_BRANCH == "develop"
|
|
138
|
+
|
|
139
|
+
# ================================
|
|
140
|
+
# INSTALL
|
|
141
|
+
# ================================
|
|
142
|
+
install:dependencies:
|
|
143
|
+
<<: [*base_job, *cache_node_push]
|
|
144
|
+
stage: install
|
|
145
|
+
image: ${NODE_IMAGE}
|
|
146
|
+
script:
|
|
147
|
+
- npm ci --cache .npm --prefer-offline
|
|
148
|
+
artifacts:
|
|
149
|
+
paths:
|
|
150
|
+
- node_modules/
|
|
151
|
+
expire_in: 1 hour
|
|
152
|
+
|
|
153
|
+
# ================================
|
|
154
|
+
# VALIDATE
|
|
155
|
+
# ================================
|
|
156
|
+
validate:shellcheck:
|
|
157
|
+
<<: *base_job
|
|
158
|
+
stage: validate
|
|
159
|
+
image: ${SHELLCHECK_IMAGE}
|
|
160
|
+
needs:
|
|
161
|
+
- install:dependencies
|
|
162
|
+
before_script:
|
|
163
|
+
- apk add --no-cache bash
|
|
164
|
+
script:
|
|
165
|
+
- |
|
|
166
|
+
if [[ -d scripts/ ]]; then
|
|
167
|
+
bash "$DEV_TOOLS_SCRIPTS/validate-shellcheck.sh"
|
|
168
|
+
else
|
|
169
|
+
echo "No scripts/ directory found — skipping ShellCheck"
|
|
170
|
+
fi
|
|
171
|
+
|
|
172
|
+
# ================================
|
|
173
|
+
# QUALITY
|
|
174
|
+
# ================================
|
|
175
|
+
quality:lint:
|
|
176
|
+
<<: [*job_node, *quality_needs]
|
|
177
|
+
stage: quality
|
|
178
|
+
script:
|
|
179
|
+
- bash "$DEV_TOOLS_SCRIPTS/eslint.sh"
|
|
180
|
+
artifacts:
|
|
181
|
+
reports:
|
|
182
|
+
junit: reports/eslint.xml
|
|
183
|
+
paths:
|
|
184
|
+
- reports/
|
|
185
|
+
expire_in: 1 week
|
|
186
|
+
when: always
|
|
187
|
+
|
|
188
|
+
quality:format:
|
|
189
|
+
<<: [*job_node, *quality_needs]
|
|
190
|
+
stage: quality
|
|
191
|
+
script:
|
|
192
|
+
- bash "$DEV_TOOLS_SCRIPTS/prettier.sh"
|
|
193
|
+
|
|
194
|
+
quality:markdownlint:
|
|
195
|
+
<<: [*job_node, *quality_needs]
|
|
196
|
+
stage: quality
|
|
197
|
+
script:
|
|
198
|
+
- bash "$DEV_TOOLS_SCRIPTS/markdownlint.sh"
|
|
199
|
+
|
|
200
|
+
quality:stylelint:
|
|
201
|
+
<<: [*job_node, *quality_needs]
|
|
202
|
+
stage: quality
|
|
203
|
+
script:
|
|
204
|
+
- bash "$DEV_TOOLS_SCRIPTS/stylelint.sh"
|
|
205
|
+
|
|
206
|
+
quality:typecheck:
|
|
207
|
+
<<: [*job_node, *quality_needs]
|
|
208
|
+
stage: quality
|
|
209
|
+
script:
|
|
210
|
+
- |
|
|
211
|
+
if [ -f tsconfig.json ] && [ -f node_modules/.bin/tsc ]; then
|
|
212
|
+
bash "$DEV_TOOLS_SCRIPTS/typecheck.sh"
|
|
213
|
+
else
|
|
214
|
+
echo "TypeScript not configured — skipping (add tsconfig.json + typescript to devDependencies)"
|
|
215
|
+
fi
|
|
216
|
+
|
|
217
|
+
quality:knip:
|
|
218
|
+
<<: [*job_node, *quality_needs]
|
|
219
|
+
stage: quality
|
|
220
|
+
script:
|
|
221
|
+
- bash "$DEV_TOOLS_SCRIPTS/knip.sh"
|
|
222
|
+
|
|
223
|
+
quality:bats:
|
|
224
|
+
<<: [*base_job, *cache_node, *quality_needs]
|
|
225
|
+
stage: quality
|
|
226
|
+
image: alpine:3.18
|
|
227
|
+
before_script:
|
|
228
|
+
- apk add --no-cache bash bats
|
|
229
|
+
script:
|
|
230
|
+
- |
|
|
231
|
+
if [[ -d tests/bats ]]; then
|
|
232
|
+
bats tests/bats --recursive
|
|
233
|
+
else
|
|
234
|
+
echo "No BATS tests found — skipping"
|
|
235
|
+
fi
|
|
236
|
+
|
|
237
|
+
# ================================
|
|
238
|
+
# TEST
|
|
239
|
+
# ================================
|
|
240
|
+
test:
|
|
241
|
+
<<: [*base_job, *cache_node]
|
|
242
|
+
stage: test
|
|
243
|
+
image: ${NODE_TEST_IMAGE}
|
|
244
|
+
script:
|
|
245
|
+
- CI=true bash "$DEV_TOOLS_SCRIPTS/test.sh"
|
|
246
|
+
coverage: '/All files[^|]*\|[^|]*\s+([\d\.]+)/'
|
|
247
|
+
artifacts:
|
|
248
|
+
reports:
|
|
249
|
+
junit: build/coverage/junit.xml
|
|
250
|
+
coverage_report:
|
|
251
|
+
coverage_format: cobertura
|
|
252
|
+
path: build/coverage/cobertura-coverage.xml
|
|
253
|
+
paths:
|
|
254
|
+
- build/coverage/
|
|
255
|
+
expire_in: 1 week
|
|
256
|
+
when: always
|
|
257
|
+
|
|
258
|
+
# ================================
|
|
259
|
+
# BUILD
|
|
260
|
+
# ================================
|
|
261
|
+
build:
|
|
262
|
+
<<: *job_node
|
|
263
|
+
stage: build
|
|
264
|
+
needs:
|
|
265
|
+
- test
|
|
266
|
+
script:
|
|
267
|
+
- |
|
|
268
|
+
if [ -f node_modules/.bin/tsup ] || [ -f node_modules/.bin/tsc ]; then
|
|
269
|
+
bash "$DEV_TOOLS_SCRIPTS/build.sh"
|
|
270
|
+
else
|
|
271
|
+
echo "No TypeScript builder configured — skipping (install tsup or typescript)"
|
|
272
|
+
fi
|
|
273
|
+
artifacts:
|
|
274
|
+
paths:
|
|
275
|
+
- dist/
|
|
276
|
+
expire_in: 1 week
|
|
277
|
+
when: on_success
|
|
278
|
+
rules:
|
|
279
|
+
- if: $CI_COMMIT_TAG =~ /^v\d+\.\d+\.\d+$/
|
|
280
|
+
- if: $CI_COMMIT_BRANCH == "main"
|
|
281
|
+
- when: never
|
|
282
|
+
allow_failure: true
|
|
283
|
+
|
|
284
|
+
# ================================
|
|
285
|
+
# PUBLISH
|
|
286
|
+
# ================================
|
|
287
|
+
publish:npm:
|
|
288
|
+
<<: [*base_job, *cache_node]
|
|
289
|
+
stage: publish
|
|
290
|
+
image: ${NODE_IMAGE}
|
|
291
|
+
rules:
|
|
292
|
+
- if: $CI_COMMIT_TAG =~ /^v\d+\.\d+\.\d+$/
|
|
293
|
+
needs:
|
|
294
|
+
- build
|
|
295
|
+
script:
|
|
296
|
+
- |
|
|
297
|
+
if [[ -z "${NPM_TOKEN:-}" ]]; then
|
|
298
|
+
echo "ERROR: NPM_TOKEN is not set or empty"
|
|
299
|
+
echo "Go to: GitLab → Settings → CI/CD → Variables → add NPM_TOKEN (type: Variable, protected, masked)"
|
|
300
|
+
exit 1
|
|
301
|
+
fi
|
|
302
|
+
- echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > "${CI_PROJECT_DIR}/.npmrc"
|
|
303
|
+
- |
|
|
304
|
+
if [[ $CI_COMMIT_TAG =~ ^v[0-9]+\.[0-9]+\.[0-9]+.*$ ]]; then
|
|
305
|
+
echo "Publishing ${NPM_PACKAGE_NAME}@${CI_COMMIT_TAG#v} to npm..."
|
|
306
|
+
npm version "${CI_COMMIT_TAG#v}" --no-git-tag-version
|
|
307
|
+
npm publish --access public
|
|
308
|
+
else
|
|
309
|
+
echo "Invalid tag format: ${CI_COMMIT_TAG}. Expected: v1.0.0"
|
|
310
|
+
exit 1
|
|
311
|
+
fi
|
|
312
|
+
environment:
|
|
313
|
+
name: production
|
|
314
|
+
url: https://www.npmjs.com/package/${NPM_PACKAGE_NAME}
|
|
315
|
+
|
|
316
|
+
# ================================
|
|
317
|
+
# RELEASE
|
|
318
|
+
# ================================
|
|
319
|
+
release:gitlab:
|
|
320
|
+
<<: *base_job
|
|
321
|
+
stage: release
|
|
322
|
+
image: ${RELEASE_CLI_IMAGE}
|
|
323
|
+
rules:
|
|
324
|
+
- if: $CI_COMMIT_TAG =~ /^v\d+\.\d+\.\d+$/
|
|
325
|
+
needs:
|
|
326
|
+
- publish:npm
|
|
327
|
+
before_script:
|
|
328
|
+
- apk add --no-cache bash git jq
|
|
329
|
+
- git config --global --add safe.directory '*'
|
|
330
|
+
- git config --global user.name "GitLab CI"
|
|
331
|
+
- git config --global user.email "ci@gitlab.com"
|
|
332
|
+
script:
|
|
333
|
+
- |
|
|
334
|
+
PREVIOUS_TAG=$(git tag --sort=-version:refname | head -n 2 | tail -n 1 || echo "")
|
|
335
|
+
if [[ -n "$PREVIOUS_TAG" && "$PREVIOUS_TAG" != "$CI_COMMIT_TAG" ]]; then
|
|
336
|
+
COMMITS=$(git log --pretty=format:"- %s" "${PREVIOUS_TAG}..${CI_COMMIT_TAG}" | head -20)
|
|
337
|
+
else
|
|
338
|
+
COMMITS="- Initial release"
|
|
339
|
+
fi
|
|
340
|
+
cat > release_notes.md << NOTES
|
|
341
|
+
## ${CI_COMMIT_TAG}
|
|
342
|
+
|
|
343
|
+
${COMMITS}
|
|
344
|
+
NOTES
|
|
345
|
+
release-cli create \
|
|
346
|
+
--tag-name "${CI_COMMIT_TAG}" \
|
|
347
|
+
--name "Release ${CI_COMMIT_TAG}" \
|
|
348
|
+
--description "$(cat release_notes.md)" \
|
|
349
|
+
--assets-link "{\"name\":\"npm\",\"url\":\"https://www.npmjs.com/package/${NPM_PACKAGE_NAME}/v/${CI_COMMIT_TAG#v}\"}"
|
|
350
|
+
artifacts:
|
|
351
|
+
paths:
|
|
352
|
+
- release_notes.md
|
|
353
|
+
expire_in: 1 year
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Stanislas Poisson (Zairakai)
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|