cmyr-template-cli 1.32.2 → 1.33.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.
package/dist/plopfile.js
CHANGED
|
@@ -148,7 +148,7 @@ const TEMPLATES_META_LIST = [
|
|
|
148
148
|
language: 'typescript',
|
|
149
149
|
runtime: 'nodejs',
|
|
150
150
|
vueVersion: 0,
|
|
151
|
-
docker:
|
|
151
|
+
docker: true,
|
|
152
152
|
priority: 0,
|
|
153
153
|
},
|
|
154
154
|
{
|
|
@@ -349,6 +349,28 @@ async function createGithubRepo(authToken, data) {
|
|
|
349
349
|
return null;
|
|
350
350
|
}
|
|
351
351
|
}
|
|
352
|
+
async function replaceGithubRepositoryTopics(authToken, data) {
|
|
353
|
+
try {
|
|
354
|
+
const { owner, repo, topics } = data;
|
|
355
|
+
const resp = await axios__default["default"]({
|
|
356
|
+
url: `/repos/${owner}/${repo}/topics`,
|
|
357
|
+
baseURL: GITHUB_API_URL,
|
|
358
|
+
method: 'PUT',
|
|
359
|
+
headers: {
|
|
360
|
+
Authorization: `Bearer ${authToken}`,
|
|
361
|
+
Accept: 'application/vnd.github+json',
|
|
362
|
+
},
|
|
363
|
+
data: {
|
|
364
|
+
names: topics,
|
|
365
|
+
},
|
|
366
|
+
});
|
|
367
|
+
return resp.data;
|
|
368
|
+
}
|
|
369
|
+
catch (error) {
|
|
370
|
+
console.error(error);
|
|
371
|
+
return null;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
352
374
|
async function loadTemplateCliConfig() {
|
|
353
375
|
const paths = [process.cwd(), os__default["default"].homedir()].map((e) => path__default["default"].join(e, '.ctrc'));
|
|
354
376
|
const [local, home] = (await Promise.all(paths.map(async (p) => {
|
|
@@ -433,7 +455,7 @@ async function initProject(answers) {
|
|
|
433
455
|
}
|
|
434
456
|
async function init(projectPath, answers) {
|
|
435
457
|
var _a;
|
|
436
|
-
const { template, isOpenSource, isInitReadme, isInitContributing, isInitHusky, isInitSemanticRelease, isInitDocker,
|
|
458
|
+
const { template, isOpenSource, isInitReadme, isInitContributing, isInitHusky, isInitSemanticRelease, isInitDocker, isInitTest } = answers;
|
|
437
459
|
try {
|
|
438
460
|
const templateMeta = getTemplateMeta(template);
|
|
439
461
|
await asyncExec('git --version', {
|
|
@@ -477,8 +499,8 @@ async function init(projectPath, answers) {
|
|
|
477
499
|
await initTsconfig(projectPath, answers);
|
|
478
500
|
await initEslint(projectPath, answers);
|
|
479
501
|
await initStylelint(projectPath);
|
|
480
|
-
if (
|
|
481
|
-
await
|
|
502
|
+
if (isInitTest) {
|
|
503
|
+
await initTest(projectPath, answers);
|
|
482
504
|
}
|
|
483
505
|
await sortProjectJson(projectPath);
|
|
484
506
|
await initYarn(projectPath, answers);
|
|
@@ -574,10 +596,11 @@ async function getGitUserName() {
|
|
|
574
596
|
return username === null || username === void 0 ? void 0 : username.trim();
|
|
575
597
|
}
|
|
576
598
|
async function initRemoteGitRepo(projectPath, answers) {
|
|
577
|
-
var _a, _b;
|
|
599
|
+
var _a, _b, _c, _d, _e;
|
|
578
600
|
const loading = ora__default["default"]('正在初始化远程 Git 仓库……').start();
|
|
579
601
|
try {
|
|
580
|
-
const { name, description, gitRemoteUrl, isOpenSource, isInitRemoteRepo } = answers;
|
|
602
|
+
const { name, description, gitRemoteUrl, isOpenSource, isInitRemoteRepo, keywords, template } = answers;
|
|
603
|
+
const templateMeta = getTemplateMeta(template);
|
|
581
604
|
if (!gitRemoteUrl) {
|
|
582
605
|
loading.fail('未找到远程 Git 仓库地址,请自行初始化!');
|
|
583
606
|
return;
|
|
@@ -613,6 +636,29 @@ async function initRemoteGitRepo(projectPath, answers) {
|
|
|
613
636
|
if ((resp === null || resp === void 0 ? void 0 : resp.status) >= 200) {
|
|
614
637
|
loading.succeed('远程 Git 仓库初始化成功!');
|
|
615
638
|
console.info(colors__default["default"].green(`远程 Git 仓库地址 ${(_a = resp.data) === null || _a === void 0 ? void 0 : _a.html_url}`));
|
|
639
|
+
const owner = (_c = (_b = resp.data) === null || _b === void 0 ? void 0 : _b.owner) === null || _c === void 0 ? void 0 : _c.login;
|
|
640
|
+
const repo = (_d = resp.data) === null || _d === void 0 ? void 0 : _d.name;
|
|
641
|
+
if (owner && repo) {
|
|
642
|
+
console.info(colors__default["default"].green('正在初始化仓库 topics !'));
|
|
643
|
+
if (templateMeta.docker) {
|
|
644
|
+
keywords.push('docker');
|
|
645
|
+
}
|
|
646
|
+
if (templateMeta === null || templateMeta === void 0 ? void 0 : templateMeta.language) {
|
|
647
|
+
keywords.push(templateMeta === null || templateMeta === void 0 ? void 0 : templateMeta.language);
|
|
648
|
+
}
|
|
649
|
+
if (templateMeta === null || templateMeta === void 0 ? void 0 : templateMeta.runtime) {
|
|
650
|
+
keywords.push(templateMeta === null || templateMeta === void 0 ? void 0 : templateMeta.runtime);
|
|
651
|
+
}
|
|
652
|
+
if ((templateMeta === null || templateMeta === void 0 ? void 0 : templateMeta.vueVersion) === 3) {
|
|
653
|
+
keywords.push('vue3');
|
|
654
|
+
}
|
|
655
|
+
await replaceGithubRepositoryTopics(authToken, {
|
|
656
|
+
owner,
|
|
657
|
+
repo,
|
|
658
|
+
topics: lodash.uniq(keywords).map((e) => kebabCase(e)),
|
|
659
|
+
});
|
|
660
|
+
console.info(colors__default["default"].green('仓库 topics 初始化成功!'));
|
|
661
|
+
}
|
|
616
662
|
}
|
|
617
663
|
else {
|
|
618
664
|
loading.fail('远程 Git 仓库初始化失败!');
|
|
@@ -633,7 +679,7 @@ async function initRemoteGitRepo(projectPath, answers) {
|
|
|
633
679
|
});
|
|
634
680
|
if ((resp === null || resp === void 0 ? void 0 : resp.status) >= 200) {
|
|
635
681
|
loading.succeed('远程 Git 仓库初始化成功!');
|
|
636
|
-
console.info(colors__default["default"].green(`远程 Git 仓库地址 ${(
|
|
682
|
+
console.info(colors__default["default"].green(`远程 Git 仓库地址 ${(_e = resp.data) === null || _e === void 0 ? void 0 : _e.html_url}`));
|
|
637
683
|
}
|
|
638
684
|
else {
|
|
639
685
|
loading.fail('远程 Git 仓库初始化失败!');
|
|
@@ -1300,7 +1346,7 @@ async function initDocker(projectPath, answers) {
|
|
|
1300
1346
|
const loading = ora__default["default"]('正在初始化 Docker ……').start();
|
|
1301
1347
|
try {
|
|
1302
1348
|
const templateMeta = getTemplateMeta(answers.template);
|
|
1303
|
-
const files = ['.dockerignore', 'docker-compose.yml'];
|
|
1349
|
+
const files = ['.dockerignore', 'docker-compose.yml', '.github/workflows/docker.yml'];
|
|
1304
1350
|
await copyFilesFromTemplates(projectPath, files);
|
|
1305
1351
|
let dockerfile = 'Dockerfile';
|
|
1306
1352
|
const newPath = path__default["default"].join(projectPath, 'Dockerfile');
|
|
@@ -1319,7 +1365,7 @@ async function initDocker(projectPath, answers) {
|
|
|
1319
1365
|
if (!await fs__default["default"].pathExists(scriptsDir)) {
|
|
1320
1366
|
await fs__default["default"].mkdir(scriptsDir);
|
|
1321
1367
|
}
|
|
1322
|
-
await copyFilesFromTemplates(projectPath, ['scripts/minify-docker.
|
|
1368
|
+
await copyFilesFromTemplates(projectPath, ['scripts/minify-docker.cjs']);
|
|
1323
1369
|
}
|
|
1324
1370
|
const pkg = await getProjectJson(projectPath);
|
|
1325
1371
|
const mainFile = pkg === null || pkg === void 0 ? void 0 : pkg.main;
|
|
@@ -1347,35 +1393,69 @@ async function initDocker(projectPath, answers) {
|
|
|
1347
1393
|
loading.fail('Docker 初始化失败!');
|
|
1348
1394
|
}
|
|
1349
1395
|
}
|
|
1350
|
-
async function
|
|
1351
|
-
|
|
1396
|
+
async function initTest(projectPath, answers) {
|
|
1397
|
+
var _a, _b;
|
|
1398
|
+
const loading = ora__default["default"]('正在初始化测试 ……').start();
|
|
1352
1399
|
try {
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1400
|
+
if (answers.isInitTest === 'vitest') {
|
|
1401
|
+
const files = ['vitest.config.ts'];
|
|
1402
|
+
await copyFilesFromTemplates(projectPath, files);
|
|
1403
|
+
const pkg = await getProjectJson(projectPath);
|
|
1404
|
+
const devDependencies = {
|
|
1405
|
+
vitest: '^2.1.6',
|
|
1406
|
+
};
|
|
1407
|
+
if (!((_a = pkg === null || pkg === void 0 ? void 0 : pkg.dependencies) === null || _a === void 0 ? void 0 : _a.vite) && !((_b = pkg === null || pkg === void 0 ? void 0 : pkg.devDependencies) === null || _b === void 0 ? void 0 : _b.vite)) {
|
|
1408
|
+
devDependencies.vite = '^6.0.1';
|
|
1409
|
+
}
|
|
1410
|
+
const newPkg = lodash.merge({}, pkg, {
|
|
1411
|
+
scripts: {
|
|
1412
|
+
test: 'vitest run',
|
|
1413
|
+
'test:coverage': 'vitest run --coverage',
|
|
1414
|
+
...pkg === null || pkg === void 0 ? void 0 : pkg.scripts,
|
|
1415
|
+
},
|
|
1416
|
+
devDependencies: {
|
|
1417
|
+
...devDependencies,
|
|
1418
|
+
...pkg === null || pkg === void 0 ? void 0 : pkg.devDependencies,
|
|
1419
|
+
},
|
|
1420
|
+
});
|
|
1421
|
+
await saveProjectJson(projectPath, newPkg);
|
|
1422
|
+
loading.succeed('Vitest 初始化成功!');
|
|
1423
|
+
return;
|
|
1424
|
+
}
|
|
1425
|
+
if (answers.isInitTest === 'jest') {
|
|
1426
|
+
const files = ['jest.config.ts'];
|
|
1427
|
+
await copyFilesFromTemplates(projectPath, files);
|
|
1428
|
+
const pkg = await getProjectJson(projectPath);
|
|
1429
|
+
const devDependencies = {
|
|
1430
|
+
'@types/jest': '^29.5.12',
|
|
1431
|
+
jest: '^29.7.0',
|
|
1432
|
+
'ts-jest': '^29.1.2',
|
|
1433
|
+
'ts-node': '^10.9.2',
|
|
1434
|
+
};
|
|
1435
|
+
const newPkg = lodash.merge({}, pkg, {
|
|
1436
|
+
scripts: {
|
|
1437
|
+
test: 'jest --config jest.config.ts',
|
|
1438
|
+
'test:coverage': 'jest --config jest.config.ts --coverage',
|
|
1439
|
+
...pkg === null || pkg === void 0 ? void 0 : pkg.scripts,
|
|
1440
|
+
},
|
|
1441
|
+
devDependencies: {
|
|
1442
|
+
...devDependencies,
|
|
1443
|
+
...pkg === null || pkg === void 0 ? void 0 : pkg.devDependencies,
|
|
1444
|
+
},
|
|
1445
|
+
});
|
|
1446
|
+
newPkg.jest = undefined;
|
|
1447
|
+
await saveProjectJson(projectPath, newPkg);
|
|
1448
|
+
loading.succeed('Jest 初始化成功!');
|
|
1449
|
+
return;
|
|
1450
|
+
}
|
|
1451
|
+
if (answers.isInitTest === 'none') {
|
|
1452
|
+
loading.succeed('未选择测试框架,跳过测试初始化');
|
|
1453
|
+
return;
|
|
1454
|
+
}
|
|
1455
|
+
loading.succeed('未选择测试框架,跳过测试初始化');
|
|
1376
1456
|
}
|
|
1377
1457
|
catch (error) {
|
|
1378
|
-
loading.fail('
|
|
1458
|
+
loading.fail('测试初始化失败!');
|
|
1379
1459
|
}
|
|
1380
1460
|
}
|
|
1381
1461
|
async function jsFileExtRename(projectPath) {
|
|
@@ -1693,7 +1773,11 @@ module.exports = function (plop) {
|
|
|
1693
1773
|
},
|
|
1694
1774
|
default(answers) {
|
|
1695
1775
|
const templateMeta = getTemplateMeta(answers.template);
|
|
1696
|
-
|
|
1776
|
+
if (!['nodejs'].includes(templateMeta === null || templateMeta === void 0 ? void 0 : templateMeta.runtime)) {
|
|
1777
|
+
return '';
|
|
1778
|
+
}
|
|
1779
|
+
const nodeVersion = Number(process.version.split('.')[0].slice(1)) - 4;
|
|
1780
|
+
return nodeVersion >= 18 ? 'esm' : 'cjs';
|
|
1697
1781
|
},
|
|
1698
1782
|
when(answers) {
|
|
1699
1783
|
const templateMeta = getTemplateMeta(answers.template);
|
|
@@ -1840,11 +1924,14 @@ module.exports = function (plop) {
|
|
|
1840
1924
|
},
|
|
1841
1925
|
},
|
|
1842
1926
|
{
|
|
1843
|
-
type: '
|
|
1844
|
-
name: '
|
|
1845
|
-
message: '
|
|
1927
|
+
type: 'list',
|
|
1928
|
+
name: 'isInitTest',
|
|
1929
|
+
message: '请选择测试框架',
|
|
1930
|
+
choices() {
|
|
1931
|
+
return ['vitest', 'jest', 'none'];
|
|
1932
|
+
},
|
|
1846
1933
|
default(answers) {
|
|
1847
|
-
return answers.isPublishToNpm;
|
|
1934
|
+
return answers.isPublishToNpm ? 'vitest' : 'none';
|
|
1848
1935
|
},
|
|
1849
1936
|
when(answers) {
|
|
1850
1937
|
return answers.isOpenSource;
|
package/package.json
CHANGED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
name: Publish Docker Image
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
push:
|
|
6
|
+
branches:
|
|
7
|
+
- master
|
|
8
|
+
|
|
9
|
+
# 仅取消针对当前工作流正在进行的作业或运行
|
|
10
|
+
concurrency:
|
|
11
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
12
|
+
cancel-in-progress: true
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
test:
|
|
16
|
+
name: Test
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
timeout-minutes: 10
|
|
19
|
+
steps:
|
|
20
|
+
- uses: actions/checkout@v4
|
|
21
|
+
- name: Setup pnpm
|
|
22
|
+
uses: pnpm/action-setup@v4
|
|
23
|
+
with:
|
|
24
|
+
version: "latest"
|
|
25
|
+
- name: Setup Node.js@lts environment
|
|
26
|
+
uses: actions/setup-node@v4
|
|
27
|
+
with:
|
|
28
|
+
node-version: "lts/*"
|
|
29
|
+
cache: "pnpm"
|
|
30
|
+
- name: Cache Dependency
|
|
31
|
+
uses: actions/cache@v4
|
|
32
|
+
with:
|
|
33
|
+
path: |
|
|
34
|
+
~/.npm
|
|
35
|
+
~/.yarn
|
|
36
|
+
~/.cache/pnpm
|
|
37
|
+
~/cache
|
|
38
|
+
!~/cache/exclude
|
|
39
|
+
**/node_modules
|
|
40
|
+
key: pnpm-${{ runner.os }}-${{ hashFiles('package.json') }}
|
|
41
|
+
restore-keys: pnpm-${{ runner.os }}
|
|
42
|
+
- run: pnpm i --frozen-lockfile
|
|
43
|
+
- run: pnpm run lint
|
|
44
|
+
- run: pnpm run build
|
|
45
|
+
- run: pnpm run test
|
|
46
|
+
build:
|
|
47
|
+
needs: test # 等待 test 执行成功
|
|
48
|
+
runs-on: ubuntu-latest
|
|
49
|
+
timeout-minutes: 30
|
|
50
|
+
permissions:
|
|
51
|
+
packages: write
|
|
52
|
+
contents: read
|
|
53
|
+
steps:
|
|
54
|
+
- uses: actions/checkout@v4
|
|
55
|
+
with:
|
|
56
|
+
persist-credentials: false
|
|
57
|
+
- name: Set up QEMU
|
|
58
|
+
uses: docker/setup-qemu-action@v3
|
|
59
|
+
- name: Set up Docker Buildx
|
|
60
|
+
uses: docker/setup-buildx-action@v3
|
|
61
|
+
- name: Login to GitHub Container Registry
|
|
62
|
+
uses: docker/login-action@v3
|
|
63
|
+
with:
|
|
64
|
+
registry: ghcr.io
|
|
65
|
+
username: ${{ github.actor }}
|
|
66
|
+
password: ${{ secrets.GITHUB_TOKEN }}
|
|
67
|
+
# - name: Login to Docker Hub
|
|
68
|
+
# uses: docker/login-action@v3
|
|
69
|
+
# with:
|
|
70
|
+
# username: ${{ secrets.DOCKER_USERNAME }}
|
|
71
|
+
# password: ${{ secrets.DOCKER_PASSWORD }}
|
|
72
|
+
# - name: Login to Alibaba Cloud Container Registry
|
|
73
|
+
# uses: docker/login-action@v3
|
|
74
|
+
# with:
|
|
75
|
+
# registry: registry.cn-hangzhou.aliyuncs.com
|
|
76
|
+
# username: ${{ secrets.ALIYUN_USERNAME }}
|
|
77
|
+
# password: ${{ secrets.ALIYUN_PASSWORD }}
|
|
78
|
+
- name: Extract Docker metadata
|
|
79
|
+
id: metadata
|
|
80
|
+
uses: docker/metadata-action@v5
|
|
81
|
+
with:
|
|
82
|
+
# 发布到 docker.io / ghcr.io / registry.cn-hangzhou.aliyuncs.com
|
|
83
|
+
# registry.cn-hangzhou.aliyuncs.com/${{ github.repository }}
|
|
84
|
+
images: |
|
|
85
|
+
${{ github.repository }}
|
|
86
|
+
ghcr.io/${{ github.repository }}
|
|
87
|
+
tags: |
|
|
88
|
+
type=raw,value=latest,enable=true
|
|
89
|
+
type=raw,value={{date 'YYYY-MM-DD' tz='Asia/Shanghai'}},enable=true
|
|
90
|
+
type=sha,format=short,prefix=sha-,enable=true
|
|
91
|
+
flavor: latest=false
|
|
92
|
+
- name: Build and push Docker images
|
|
93
|
+
uses: docker/build-push-action@v5
|
|
94
|
+
with:
|
|
95
|
+
context: .
|
|
96
|
+
file: ./Dockerfile
|
|
97
|
+
# 推送到 dockerhub
|
|
98
|
+
push: false
|
|
99
|
+
tags: ${{ steps.metadata.outputs.tags }}
|
|
100
|
+
labels: ${{ steps.metadata.outputs.labels }}
|
|
101
|
+
platforms: linux/amd64,linux/arm64
|
|
102
|
+
# - name: Docker Hub README & description sync
|
|
103
|
+
# uses: meeDamian/sync-readme@v1.0.6
|
|
104
|
+
# with:
|
|
105
|
+
# user: ${{ secrets.DOCKER_USERNAME }}
|
|
106
|
+
# pass: ${{ secrets.DOCKER_PASSWORD }}
|
|
107
|
+
# slug: ${{ github.repository }}
|
|
108
|
+
# description: "基于 Hono 和 TypeScript 的云函数模板"
|
package/templates/Dockerfile
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
FROM caomeiyouren/alpine-nodejs:latest AS nodejs
|
|
2
2
|
|
|
3
|
-
RUN npm config set registry https://registry.npmmirror.com && \
|
|
4
|
-
|
|
3
|
+
# RUN npm config set registry https://registry.npmmirror.com && \
|
|
4
|
+
# pnpm config set registry https://registry.npmmirror.com
|
|
5
5
|
|
|
6
6
|
FROM caomeiyouren/alpine-nodejs-minimize:latest AS runtime
|
|
7
7
|
|
|
@@ -28,7 +28,7 @@ RUN pnpm add @vercel/nft@0.24.4 fs-extra@11.2.0 --save-prod
|
|
|
28
28
|
COPY --from=builder /app /app
|
|
29
29
|
|
|
30
30
|
RUN export PROJECT_ROOT=/app/ && \
|
|
31
|
-
node /app/scripts/minify-docker.
|
|
31
|
+
node /app/scripts/minify-docker.cjs && \
|
|
32
32
|
rm -rf /app/node_modules /app/scripts && \
|
|
33
33
|
mv /app/app-minimal/node_modules /app/ && \
|
|
34
34
|
rm -rf /app/app-minimal
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import path from 'path'
|
|
2
|
+
import { defineConfig } from 'vitest/config'
|
|
3
|
+
|
|
4
|
+
export default defineConfig({
|
|
5
|
+
test: {
|
|
6
|
+
globals: true,
|
|
7
|
+
environment: 'node',
|
|
8
|
+
},
|
|
9
|
+
resolve: {
|
|
10
|
+
alias: {
|
|
11
|
+
'@': path.resolve(__dirname, 'src'),
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
root: path.resolve('./'),
|
|
15
|
+
coverage: {
|
|
16
|
+
clean: true,
|
|
17
|
+
reportsDirectory: path.resolve('./coverage'),
|
|
18
|
+
},
|
|
19
|
+
})
|
|
File without changes
|