1
0
mirror of https://github.com/142vip/408CSFamily.git synced 2026-04-14 02:09:56 +08:00

feat: 引入@142vip/utils模块,删除.exec执行器,优化scripts脚本逻辑和流程 (#100)

* feat: 引入`@142vip/utils`模块,删除`.exec`执行器,优化`scripts`脚本逻辑和流程

* chore: update

* chore: update package.json

---------

Co-authored-by: 142vip.cn <fairy@2925.com>
This commit is contained in:
142vip.cn
2024-09-25 15:14:17 +08:00
committed by GitHub
parent 00435ea417
commit e792ed40b2
10 changed files with 70 additions and 493 deletions

View File

@@ -42,19 +42,17 @@ jobs:
# “最近更新时间” 等 git 日志相关信息,需要拉取全部提交记录
fetch-depth: 0
## 安装PNPM
# 安装PNPM
- name: PNPM Install
uses: pnpm/action-setup@v2
uses: pnpm/action-setup@v4
with:
version: 8
version: 9.6.0
## 安装Node环境
- name: Install Node.js
uses: actions/setup-node@v3
with:
node-version: 18.18.0
## 淘宝镜像加速
registry-url: 'https://registry.npmmirror.com'
## 缓存
cache: 'pnpm'
@@ -69,11 +67,11 @@ jobs:
- name: Build Site
run: |
./scripts/bundle build
pnpm build
- name: Build Site With Proxy
run: |
./scripts/bundle build_proxy
pnpm build:proxy
Build-Docker-Image:
name: "构建Docker镜像"

View File

@@ -45,5 +45,5 @@ LABEL "repo.name"=$APP_NAME "repo.version"=$APP_VERSION \
# Git信息
LABEL "git.hash"="$GIT_HASH" "git.message"="$GIT_MESSAGE"
# 将dist文件中的内容复制到 /usr/share/nginx/html/ 这个目录下面 注意:--from参数
COPY --from=build_base /apps/docs/.vuepress/dist/ /usr/share/nginx/html/
COPY nginx.conf /etc/nginx/
COPY --from=build_base /apps/docs/.vuepress/dist/ /usr/share/nginx/html/
COPY --from=build_base /apps/nginx.conf /etc/nginx/

View File

@@ -22,13 +22,14 @@
"lint:fix": "npx fa lint --fix",
"dev": "vuepress dev docs",
"build": "vuepress build docs --clean-temp --clean-cache",
"build:proxy": "./scripts/bundle build_proxy",
"build:proxy": "PROXY_DOMAIN=true vuepress build docs --clean-temp --clean-cache",
"build:mark-map": "./scripts/mark-map",
"deploy:vercel": "vercel --prod",
"release": "npx fa release --vip"
},
"devDependencies": {
"@142vip/fairy-cli": "0.0.3-alpha.11",
"@142vip/utils": "0.0.1-alpha.5",
"@typescript-eslint/eslint-plugin": "^5.62.0",
"@typescript-eslint/parser": "^5.62.0",
"@vuepress/client": "2.0.0-beta.67",

14
pnpm-lock.yaml generated
View File

@@ -11,6 +11,9 @@ importers:
'@142vip/fairy-cli':
specifier: 0.0.3-alpha.11
version: 0.0.3-alpha.11
'@142vip/utils':
specifier: 0.0.1-alpha.5
version: 0.0.1-alpha.5
'@typescript-eslint/eslint-plugin':
specifier: ^5.62.0
version: 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5)
@@ -114,6 +117,10 @@ packages:
resolution: {integrity: sha512-AzeWlLpD/M6KKqygywKLx0mNOensWN8VJ2q3Bk+ffWwXjdsh/pR1goHd1cATbYwuFBEVlcIRwxRSDNupSzKi4Q==}
engines: {node: '>=16.0.0'}
'@142vip/utils@0.0.1-alpha.5':
resolution: {integrity: sha512-w+2zcFBGwO+tfKaSjWuOrK8HUgHptF4yCHIKqPyC62W9ZYsH2eHuaLqj9fMrOK56/Gp+1gyVXijeKOkiN/QxUA==}
engines: {node: '>=16.0.0'}
'@ampproject/remapping@2.3.0':
resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==}
engines: {node: '>=6.0.0'}
@@ -5882,6 +5889,13 @@ snapshots:
dayjs: 1.11.13
inquirer: 7.3.3
'@142vip/utils@0.0.1-alpha.5':
dependencies:
'@inquirer/confirm': 3.2.0
ansi-colors: 4.1.3
dayjs: 1.11.13
inquirer: 7.3.3
'@ampproject/remapping@2.3.0':
dependencies:
'@jridgewell/gen-mapping': 0.3.5

View File

@@ -1,47 +0,0 @@
#!/usr/bin/env node
/**
* 脚本执行器执行shell命令
*/
const {join} = require('path')
const cwd = join(__dirname, '..')
process.env.PATH = `${join(cwd, 'node_modules', '.bin')}:${process.env.PATH}`
const {exec, exit} = require('shelljs');
/**
* 监听进程
* - 退出进程
*/
process.on('exit', () => {
exit()
})
/**
* 执行shell指令
*/
exports.execShell = async commands => {
let runCommands = []
if (typeof commands === 'string') {
runCommands.push(commands)
}
// 批量执行
if (Array.isArray(commands)) {
runCommands = commands
}
for (let index = 0; index < runCommands.length; index++) {
const command = runCommands[index]
const count = index + 1
console.log(`step${count}:\n${command} \nstep${count}(start): === `)
// await syncExec(command)
const execResult = await exec(command)
// 打印输出结果
console.log(execResult.stdout);
console.log(`step${count}(ending): === \n`)
// 指令异常不执行后续指令非0退出
if (execResult.code !== 0) {
exit(1)
break;
}
}
}

View File

@@ -1,173 +1,52 @@
#!/usr/bin/env node
/**
*
* 将应用程序打包成可部署的包、文件、镜像
* 例如:
* - ./scripts/bundle build 基础部署打包
* - ./scripts/bundle build_proxy 用于三方平台部署打包
* - ./scripts/bundle image 构建容器镜像
* - ./scripts/bundle image_faster 本地build快速构建容器镜像
* - ./scripts/bundle xxx 其他参数默认执行build命令
* - ./scripts/bundle 交互式选择执行的命令
*/
const {execShell} = require('./.exec')
const {execSync} = require('child_process');
const {Select} = require('enquirer')
// 仓库地址
const repoAddress = 'registry.cn-hangzhou.aliyuncs.com/142vip/doc_book'
const packageInfo = require('../package.json')
const packageVersion = packageInfo.version
const projectName = packageInfo.name
// 镜像地址
const imageName = `${repoAddress}:${projectName}-${packageVersion}`
/**
* 获取最近一次Git提交信息
* - 短哈希值
* - 提交信息
* 功能构建Docker镜像
* 使用:
* - ./scripts/bundle
* - ./scripts/bundle --proxy
*/
async function getGitInfo() {
// 执行 git log 命令获取最新一次提交的哈希值和消息
const gitLog = execSync('git log --no-merges -1 --pretty=format:"%h %s"').toString();
// 分割输出字符串以获取哈希值和消息
const [commitHash, ...commitMessage] = gitLog.trim().split(' ');
import {createRequire} from 'node:module'
import process from 'node:process'
import {
VipDockerAddress,
buildImage,
getRecentGitCommit,
} from '@142vip/utils'
// 输出最近一次提交的信息
return {
gitHash: commitHash,
gitMessage: commitMessage.join(' ')
}
}
/**
* 获取构建镜像的脚本
* @param containerBuild 是否容器内构建
* @param preBuild 是否预编译
* @param needProxy 是否配置代理路径
*/
async function getBuildImageScript({containerBuild, preBuild, needProxy = false}) {
// 基础构建脚本
let baseBuildScript = ''
(async () => {
try {
// 获取package.json文件
const pkg = createRequire(import.meta.url)('../package.json')
if (preBuild) {
baseBuildScript = needProxy ? './scripts/bundle build_proxy' : './scripts/bundle build'
}
// 镜像地址
const imageName = `${VipDockerAddress}/docs:${pkg.name}-${pkg.version}`
const {gitHash, gitMessage} = await getGitInfo()
// 最近一次提交信息
const {hash: gitHash} = await getRecentGitCommit()
return [
// 构建镜像
`
${baseBuildScript}
docker build \
--build-arg CONTAINER_BUILD=${containerBuild} \
--build-arg APP_VERSION=${packageVersion} \
--build-arg APP_NAME=${projectName} \
--build-arg HOME_PAGE=${packageInfo.authorInfo.homePage} \
--build-arg AUTHOR=${packageInfo.authorInfo.name} \
--build-arg EMAIL=${packageInfo.authorInfo.email} \
--build-arg DESCRIPTION=${packageInfo.description} \
--build-arg GIT_HASH=${gitHash} \
--build-arg GIT_MESSAGE="${gitMessage}" \
-t ${imageName} .
`,
// 推送镜像
`
if [ "$(docker images -q ${imageName} 2> /dev/null)" != "" ];then
## 推送
docker push ${imageName}
echo "---------------- 上传镜像成功,删除本地镜像 ---------------- "
docker rmi ${imageName}
exit 0;
else
echo "镜像: ${imageName} , 不存在"
exit 1;
fi
`
]
}
/**
* 支持的脚本命令
*/
const SupportScripts = {
build: 'vuepress build docs',
build_proxy: 'PROXY_DOMAIN=true vuepress build docs',
image: getBuildImageScript({
containerBuild: true,
needProxy: false
}),
image_proxy: getBuildImageScript({
containerBuild: true,
needProxy: true
}),
// 直接从本地拿dist文件生成镜像
image_faster: getBuildImageScript({
containerBuild: false,
needProxy: false
})
}
async function getScriptCommand() {
const scriptName = process.argv[2]
let scriptCommand = SupportScripts.build
if (scriptName == null) {
const prompt = new Select({
header: '======================== 408CSFamily Cli For Building ========================',
footer: '======================== 408CSFamily Cli For Building ========================',
name: 'color',
message: 'What script will you want to run ',
choices: [
{
message: 'build',
name: SupportScripts.build,
value: '#00ffff'
},
{
message: 'build for fixing proxy',
name: SupportScripts.build_proxy,
value: '#000000'
},
{
message: 'build to docker image',
name: SupportScripts.image,
value: '#0000ff'
},
{
message: 'build to docker image with proxy',
name: SupportScripts.image_proxy,
value: '#0000ff'
},
{
message: 'build to docker image faster',
name: SupportScripts.image_faster,
value: '#0000ff'
}
]
await buildImage({
imageName,
buildArgs: [
// 参数中是否包含 --proxy
['NEED_PROXY', process.argv.includes('--proxy')],
['APP_NAME', pkg.name],
['APP_VERSION', pkg.version],
['APP_DESCRIPTION', pkg.description],
['AUTHOR', pkg.authorInfo.name],
['EMAIL', pkg.authorInfo.email],
['HOME_PAGE', pkg.authorInfo.homePage],
['GIT_HASH', gitHash],
],
memory:20000,
push: true,
delete: true,
logger: true,
})
scriptCommand = await prompt.run()
} else {
// 命中支持的脚本
if (Object.keys(SupportScripts).includes(scriptName)) {
scriptCommand = SupportScripts[scriptName]
}
} catch (e) {
console.log('异常信息:', e)
}
return scriptCommand
}
/**
* 执行构建命令
*/
;(async () => {
const scriptCommand = await getScriptCommand()
await execShell(scriptCommand)
})()

View File

@@ -1,90 +0,0 @@
#!/usr/bin/env node
/**
*
* 例如:
* - ./scripts/deploy ali
* - ./scripts/deploy github
*/
const {execShell} = require('./.exec')
const packageVersion = require('../package.json').version
const dockerDeployInfo = {
repoAddress: 'registry.cn-hangzhou.aliyuncs.com/142vip/doc_book',
containerName: '408CSFamily',
networkName: 'service_env_net'
}
const imageName = `${dockerDeployInfo.repoAddress}:${dockerDeployInfo.containerName}-${packageVersion}`
// 支持的命令
const SupportScripts = {
Github: `
set -e
./scripts/build proxy && cd docs/.vuepress/dist
git init && git add -A
## 配置信息
git config user.name 'chu fan'
git config user.email 'fairy_408@2925.com'
git config --list
git commit -m "release v${packageVersion}"
## 部署到github pages
git push -f https://github.com/mmdapl/408CSFamily.git master:pages/github
cd -
`,
Ali: [
// 容器存在即删除
`
if docker inspect --format='{{.State.Running}}' ${dockerDeployInfo.containerName} >/dev/null 2>&1;then
docker rm -f ${dockerDeployInfo.containerName}
exit 0;
else
echo "容器:${dockerDeployInfo.containerName},不存在"
exit 1;
fi
`,
// 镜像存在即删除
`
if [ "$(docker images -q ${imageName} 2> /dev/null)" != "" ];then
docker rmi ${imageName}
exit 0;
else
echo -e "镜像:${imageName},不存在"
exit 1;
fi
`,
// 运行容器
`
docker run -d --name ${dockerDeployInfo.containerName} \
-p 7000:80 \
--network=${dockerDeployInfo.networkName} \
--restart=unless-stopped \
--ip=172.30.0.100 \
${imageName}
`
]
}
const deployName = process.argv[2]
function getDeployCommand() {
let deployCommand = SupportScripts.Ali
// 部署到阿里云服务器
if (deployName === 'ali') {
deployCommand = SupportScripts.Ali
}
// 部署到Github
if (deployName === 'github') {
deployCommand = SupportScripts.Github
}
return deployCommand
}
/**
* 执行部署相关命令
*/
;(async () => {
const deployCommand = getDeployCommand()
// console.log(deployCommand)
await execShell(deployCommand)
})()

View File

@@ -6,8 +6,9 @@
* - ./scripts/dev
*/
const {execShell} = require('./.exec');
(async () => await execShell([
'npm run build:mark-map',
'vuepress dev docs'
import {commandStandardExecutor} from '@142vip/utils'
(async () => await commandStandardExecutor([
'pnpm build:mark-map',
'pnpm dev'
]))()

View File

@@ -1,176 +0,0 @@
#!/usr/bin/env node
/**
* docker cli工具
* 例如:
* - ./scripts/docker container xxx 容器相关
* - ./scripts/network image xxx 镜像相关
* - ./scripts/docker network xxx 网络相关
*/
const { execShell } = require('./.exec')
const scriptName = process.argv[2]
/**
* 网络基础信息
* - 网络名称
* - 子网掩码
* - 网关地址
*/
const dockerNetworkInfo = {
defaultName: 'service_env_net',
subnet: '172.30.0.0/24',
gateway: '172.30.0.1'
}
/**
* docker containers 容器相关指令
*/
const SupportScriptsInContainer = {
run: '',
rm: '',
ps: 'docker ps'
}
/**
* docker images 相关脚本指令
*/
const SupportScriptsInImage = {
rm: 'docker rmi **',
ps: 'docker images'
}
/**
* docker network 相关脚本指令
*/
const SupportScriptsInNetWork = {
ls: 'docker network ls',
create: [
// 创建网关
`
docker network create \
--subnet=${dockerNetworkInfo.subnet} \
--gateway=${dockerNetworkInfo.gateway} \
${dockerNetworkInfo.defaultName}
`,
// 查看创建后基本信息
`
docker network inspect ${dockerNetworkInfo.defaultName}
`
],
rm: [
// 参数校验
`
if test -z "${dockerNetworkInfo.defaultName}";then
echo "参数错误 网络名称不能为空。脚本执行eg bash xxx.sh rm 网络名称"
exit 1;
fi
`,
// 判断网络是否存在
`
docker network ls | grep -w "${dockerNetworkInfo.defaultName}"
if [ $? -eq 1 ] ;then
echo "容器网络:${dockerNetworkInfo.defaultName} 不存在,删除无效"
exit 1;
fi
`,
// 删除网络
`
docker network rm "${dockerNetworkInfo.defaultName}"
`
],
inspect:
`
docker network inspect ${dockerNetworkInfo.defaultName}
`
}
function getContainerCommand() {
const name = process.argv[3]
if (name in SupportScriptsInContainer) {
return SupportScriptsInContainer[name]
}
// 默认查看所有容器
return SupportScriptsInContainer.ps
}
function getImageCommand() {
const name = process.argv[3]
if (name in SupportScriptsInImage) {
return SupportScriptsInImage[name]
}
return SupportScriptsInImage.ps
}
function getNetworkCommand() {
const name = process.argv[3]
if (name in SupportScriptsInNetWork) {
return SupportScriptsInNetWork[scriptName]
}
return SupportScriptsInNetWork.ls
}
// 支持的命令
const SupportScripts = {
ls: 'docker network ls',
create: [
// 创建网关
`
docker network create \
--subnet=${dockerNetworkInfo.subnet} \
--gateway=${dockerNetworkInfo.gateway} \
${dockerNetworkInfo.defaultName}
`,
// 查看创建后基本信息
`
docker network inspect ${dockerNetworkInfo.defaultName}
`
],
rm: [
// 参数校验
`
if test -z "${dockerNetworkInfo.defaultName}";then
echo "参数错误 网络名称不能为空。脚本执行eg bash xxx.sh rm 网络名称"
exit 1;
fi
`,
// 判断网络是否存在
`
docker network ls | grep -w "${dockerNetworkInfo.defaultName}"
if [ $? -eq 1 ] ;then
echo "容器网络:${dockerNetworkInfo.defaultName} 不存在,删除无效"
exit 1;
fi
`,
// 删除网络
`
docker network rm "${dockerNetworkInfo.defaultName}"
`
],
inspect:
`
docker network inspect ${dockerNetworkInfo.defaultName}
`
}
function getCommand() {
const scriptName = process.argv[3]
switch (scriptName) {
case 'network':
return getNetworkCommand()
case 'container':
return getContainerCommand()
case 'image':
return getImageCommand()
}
}
// 执行
;(async() => {
const command = getCommand(scriptName)
await execShell(command)
})()

View File

@@ -4,7 +4,7 @@
* 将思维导图的md格式转化为html提供在线预览
* 链接https://www.npmjs.com/package/markmap-cli
*/
const {execShell} = require("./.exec");
const {commandStandardExecutor} = require("@142vip/utils");
const path = require('path');
const fs = require('fs');
const markMapSourcePath = path.join(__dirname, '../', 'docs/manuscripts/mark-map')
@@ -66,7 +66,7 @@ function scanDirectory(directory, fileType) {
// 脚本执行
await execShell([
await commandStandardExecutor([
delHtmlDir,
mdToHtmlCmdStr,
moveHtmlCmdStr,
@@ -78,14 +78,11 @@ function scanDirectory(directory, fileType) {
* 第六步: 对mark-map中的xmind文件重命名
*
*/
const markMapData = require(path.join(markMapTargetPath, 'index.json'))
for (const {originXmindFileName, targetXmindFileName} of markMapData) {
const originPath = path.join(markMapTargetPath, originXmindFileName)
const targetPath = path.join(markMapTargetPath, targetXmindFileName)
await fs.renameSync(originPath, targetPath)
}
})()
})()