创建项目/添加微服务git操作流程
说明:
- 此文档介绍了 创建项目/添加微服务的git操作流程
- gitlab地址:https://gitlab.dxsuite.cn/
1.创建group
gitlab创建gruop来管理整个项目(例如前端、后端项目),如果已存在,则跳过此步骤
- git首页 --> Groups --> Yours groups --> New group
2. 创建总git库(父模块)
在创建好的group下,创建项目的总git库,用于管理各个微服务,然后拉取到本地,如果已存在,则跳过此步骤
- 在创建好的group下 --> New project
3. 创建微服务git库(子模块)
在创建好的group下,创建需要添加的微服务git库
- 在创建好的group下 --> New project
4. 创建快速生成微服务模块脚本
- 在本地刚拉取的父工程目录下创建 generate-module.sh 文件,内容如下(此脚本用于快速生成微服务模版,方便快速开发):
#!/usr/bin/env bash
#
# 模块项目结构生成脚本
#
MODULE_VERSION="0.0.1-SNAPSHOT"
BASE_PACKAGE_NAME="cn.dxsuite"
PROJECT_PACKAGE_NAME="${BASE_PACKAGE_NAME}"
check_data_source_type () {
if ! [[ "$1" =~ ^(mysql|mongo|es)?$ ]]; then
printf "\e[91m数据源类型无效\e[0m\n\n"
exit 1
fi
}
check_package_name () {
if ! [[ "$1" =~ ^([a-z][0-9a-z]*\.)*[a-z][0-9a-z]*$ ]]; then
printf "\e[91m包名格式不正确\e[0m\n\n"
exit 1
fi
}
get_data_source_dependency () {
case "$1" in
mysql)
printf "\n api(\"cn.dxsuite.commons:commons-jpa:%s\")\n" "${MODULE_VERSION}"
;;
mongo)
printf "\n api(\"cn.dxsuite.commons:commons-mongo:%s\")\n" "${MODULE_VERSION}"
;;
es)
;;
esac
printf ""
}
# 设置模块名称
printf "\n\e[96m模块名称:\e[0m"
read -r MODULE_NAME
if ! [[ "${MODULE_NAME}" =~ ^([a-z][0-9a-z]*-)*[a-z][0-9a-z]*$ ]]; then
printf "\e[91m模块名应由英文小写字母、数字、横线组成,以英文开头,且不出现连续的横线\e[0m\n\n"
exit 1
fi
# 设置基础包名
printf "\e[96m基础包名\e[36m(默认:%s)\e[96m:\e[0m" "${BASE_PACKAGE_NAME}"
read -r BASE_PACKAGE_NAME_INPUT
if ! [ "${BASE_PACKAGE_NAME_INPUT}" == "" ]; then
BASE_PACKAGE_NAME="${BASE_PACKAGE_NAME_INPUT}"
PROJECT_PACKAGE_NAME="${BASE_PACKAGE_NAME}"
fi
check_package_name "${BASE_PACKAGE_NAME}"
# 设置项目包名
printf "\e[96m项目包名:\e[0m"
read -r PROJECT_PACKAGE_NAME_INPUT
if ! [ "${PROJECT_PACKAGE_NAME_INPUT}" == "" ]; then
PROJECT_PACKAGE_NAME="${BASE_PACKAGE_NAME}.${PROJECT_PACKAGE_NAME_INPUT}"
fi
check_package_name "${PROJECT_PACKAGE_NAME}"
PROJECT_PACKAGE_PATH="${PROJECT_PACKAGE_NAME//\.//}"
# 设置模块包名
MODULE_PACKAGE_NAME="${MODULE_NAME//-/}"
printf "\e[96m模块包名\e[36m(默认:%s)\e[96m:\e[0m" "${MODULE_PACKAGE_NAME}"
read -r PACKAGE_NAME_INPUT
if ! [ "${PACKAGE_NAME_INPUT}" == "" ]; then
MODULE_PACKAGE_NAME="${PACKAGE_NAME_INPUT}"
fi
check_package_name "${MODULE_PACKAGE_NAME}"
PACKAGE_PATH="${MODULE_PACKAGE_NAME//\.//}"
# 设置数据源类型
printf "\e[96m数据源类型\e[36m(mysql|mongo|es)\e[0m\n"
printf "\e[96m 命令领域:\e[0m"
read -r DATA_SOURCE_TYPE_COMMAND
check_data_source_type "${DATA_SOURCE_TYPE_COMMAND}"
printf "\e[96m 查询领域:\e[0m"
read -r DATA_SOURCE_TYPE_QUERY
check_data_source_type "${DATA_SOURCE_TYPE_QUERY}"
printf "\n\e[36m以下路径及文件将被创建:\e[0m\n"
printf "\n \e[1;92m%s\e[0;32m" "${MODULE_NAME}"
printf "\n ├─ \e[1;92m%s\e[0;32m" "${MODULE_NAME}"
printf "\n │ ├─ src/main"
printf "\n │ │ ├─ java/${PROJECT_PACKAGE_PATH}/\e[1;92m%s\e[0;32m/..." "${PACKAGE_PATH}"
printf "\n │ │ └─ resources"
printf "\n │ └─ build.gradle.kts"
printf "\n ├─ \e[1;92m%s\e[0;32m-command-api" "${MODULE_NAME}"
printf "\n │ ├─ src/main"
printf "\n │ │ ├─ java/${PROJECT_PACKAGE_PATH}/\e[1;92m%s\e[0;32m/command/..." "${PACKAGE_PATH}"
printf "\n │ │ └─ resources"
printf "\n │ └─ build.gradle.kts"
printf "\n ├─ \e[1;92m%s\e[0;32m-command" "${MODULE_NAME}"
printf "\n │ ├─ src/main"
printf "\n │ │ ├─ java/${PROJECT_PACKAGE_PATH}/\e[1;92m%s\e[0;32m/command/..." "${PACKAGE_PATH}"
printf "\n │ │ └─ resources"
printf "\n │ └─ build.gradle.kts"
printf "\n ├─ \e[1;92m%s\e[0;32m-query-api" "${MODULE_NAME}"
printf "\n │ ├─ src/main"
printf "\n │ │ ├─ java/${PROJECT_PACKAGE_PATH}/\e[1;92m%s\e[0;32m/query/..." "${PACKAGE_PATH}"
printf "\n │ │ └─ resources"
printf "\n │ └─ build.gradle.kts"
printf "\n ├─ \e[1;92m%s\e[0;32m-query" "${MODULE_NAME}"
printf "\n │ ├─ src/main"
printf "\n │ │ ├─ java/${PROJECT_PACKAGE_PATH}/\e[1;92m%s\e[0;32m/query/..." "${PACKAGE_PATH}"
printf "\n │ │ └─ resources"
printf "\n │ └─ build.gradle.kts"
printf "\n ├─ README.md"
printf "\n ├─ .editorconfig"
printf "\n ├─ .gitignore"
printf "\n ├─ settings.gradle.kts"
printf "\n └─ build.gradle.kts\e[0m\n"
printf "\n\e[96m确定要创建以上路径及文件吗?(确定:Y;取消:N)\e[0m"
read -r CONFIRM_INPUT
echo ""
if [ "${CONFIRM_INPUT}" != "Y" ] && [ "${CONFIRM_INPUT}" != "y" ]; then
printf "\e[33m已取消\e[0m\n\n"
exit 0
fi
# 清理已生成的目录结构
rm -rf "${MODULE_NAME:?}/${MODULE_NAME}"
rm -rf "${MODULE_NAME:?}/${MODULE_NAME}-command-api"
rm -rf "${MODULE_NAME:?}/${MODULE_NAME}-command"
rm -rf "${MODULE_NAME:?}/${MODULE_NAME}-query-api"
rm -rf "${MODULE_NAME:?}/${MODULE_NAME}-query"
# 构建项目目录结构
mkdir -p "${MODULE_NAME}"/{"${MODULE_NAME}","${MODULE_NAME}"-command-api,"${MODULE_NAME}"-command,"${MODULE_NAME}"-query-api,"${MODULE_NAME}"-query}/src/{main,test}/{java,resources}
# 构建共通模块项目源代码目录结构
mkdir -p "${MODULE_NAME}"/"${MODULE_NAME}"/src/{main,test}/java/"${PROJECT_PACKAGE_PATH}"/"${PACKAGE_PATH}"/{dto,entity,vo}
# 构建命令领域模块项目源代码目录结构
mkdir -p "${MODULE_NAME}"/"${MODULE_NAME}"-command-api/src/{main,test}/java/"${PROJECT_PACKAGE_PATH}"/"${PACKAGE_PATH}"/command/{api,dto,entity,vo}
mkdir -p "${MODULE_NAME}"/"${MODULE_NAME}"-command/src/{main,test}/java/"${PROJECT_PACKAGE_PATH}"/"${PACKAGE_PATH}"/command/{controller,repository,service,service/impl}
# 构建查询领域模块项目源代码目录结构
mkdir -p "${MODULE_NAME}"/"${MODULE_NAME}"-query-api/src/{main,test}/java/"${PROJECT_PACKAGE_PATH}"/"${PACKAGE_PATH}"/query/{api,dto,entity,vo}
mkdir -p "${MODULE_NAME}"/"${MODULE_NAME}"-query/src/{main,test}/java/"${PROJECT_PACKAGE_PATH}"/"${PACKAGE_PATH}"/query/{controller,repository,service,service/impl}
# 创建 Gradle 配置文件
touch "${MODULE_NAME}"/README.md
touch "${MODULE_NAME}"/.editorconfig
touch "${MODULE_NAME}"/.gitignore
touch "${MODULE_NAME}"/settings.gradle.kts
touch "${MODULE_NAME}"/build.gradle.kts
touch "${MODULE_NAME}"/"${MODULE_NAME}"/build.gradle.kts
touch "${MODULE_NAME}"/"${MODULE_NAME}"-command-api/build.gradle.kts
touch "${MODULE_NAME}"/"${MODULE_NAME}"-command/build.gradle.kts
touch "${MODULE_NAME}"/"${MODULE_NAME}"-query-api/build.gradle.kts
touch "${MODULE_NAME}"/"${MODULE_NAME}"-query/build.gradle.kts
# 设置 README.md 文件内容
echo "# ${MODULE_NAME}" > "${MODULE_NAME}"/README.md
# 设置 .editorconfig 文件内容
echo "root = true
[*]
charset = utf-8
indent_style = space
indent_size = 4
trim_trailing_whitespace = true
end_of_line = lf
insert_final_newline = true
[*.{css,scss,js,jsx,json}]
indent_size = 2
[*.{bat,cmd}]
end_of_line = crlf" > "${MODULE_NAME}"/.editorconfig
# 设置 .gitignore 文件内容
echo ".gradle
**/build
**/node_modules
**/*.log
**/*.log.gz
**/*.pid
.idea
**/*.iml
**/.classpath
**/.project
**/.settings
**/.vscode
**/.DS_Store
**/desktop.ini
**/Thumbs.db
**/~\$*.xlsx
**/~\$*.docx
**/~\$*.pptx
**/*.hprof" > "${MODULE_NAME}"/.gitignore
# 设置 settings.gradle.kts 配置文件
echo "rootProject.name = \"${MODULE_NAME}\"
include(\"${MODULE_NAME}\")
include(\"${MODULE_NAME}-command-api\")
include(\"${MODULE_NAME}-command\")
include(\"${MODULE_NAME}-query-api\")
include(\"${MODULE_NAME}-query\")" > "${MODULE_NAME}"/settings.gradle.kts
# 设置 build.gradle.kts 配置文件
echo "plugins {
id(\"java\")
id(\"java-library\")
id(\"maven-publish\")
id(\"idea\")
}
group = \"${PROJECT_PACKAGE_NAME}\"
allprojects {
apply(plugin = \"java\")
apply(plugin = \"java-library\")
apply(plugin = \"maven-publish\")
apply(plugin = \"idea\")
version = \"${MODULE_VERSION}\"
java {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
idea {
module {
isDownloadJavadoc = true
isDownloadSources = true
}
}
}
subprojects {
group = \"${PROJECT_PACKAGE_NAME}.${MODULE_NAME}\"
repositories {
mavenLocal()
if (hasProperty(\"dxsuite.nexus.url\")) {
maven {
url = uri(property(\"dxsuite.nexus.url\") as String)
credentials {
username = property(\"dxsuite.nexus.username\") as String
password = property(\"dxsuite.nexus.password\") as String
}
}
}
mavenCentral()
}
dependencies {
annotationProcessor(\"javax.annotation:javax.annotation-api:1.3.2\")
annotationProcessor(\"org.springframework.boot:spring-boot-configuration-processor:2.4.5\")
annotationProcessor(\"org.projectlombok:lombok:1.18.18\")
annotationProcessor(\"com.querydsl:querydsl-apt:4.4.0:jpa\")
testImplementation(\"cn.dxsuite.commons:commons-junit:0.0.1-SNAPSHOT\");
}
tasks {
withType(Test::class) {
useJUnitPlatform()
}
getByName<Jar>(\"jar\") {
enabled = true
duplicatesStrategy = DuplicatesStrategy.INCLUDE
archiveClassifier.set(\"resources\")
from(sourceSets.main.get().resources) {
include(\"**/*\")
}
}
}
publishing {
publications {
create<MavenPublication>(\"mavenJava\") {
from(components[\"java\"])
}
}
}
}
publishing {
publications {
create<MavenPublication>(\"mavenJava\") {
}
}
}" > "${MODULE_NAME}"/build.gradle.kts
# 设置 {MODULE_NAME}/{MODULE_NAME}/build.gradle.kts 配置文件
echo "dependencies {
api(\"${BASE_PACKAGE_NAME}.commons:commons-core:${MODULE_VERSION}\")
}" > "${MODULE_NAME}"/"${MODULE_NAME}"/build.gradle.kts
# 设置 {MODULE_NAME}/{MODULE_NAME}-command-api/build.gradle.kts 配置文件
echo "dependencies {$(get_data_source_dependency "${DATA_SOURCE_TYPE_COMMAND}")
api(\"${PROJECT_PACKAGE_NAME}.${MODULE_NAME}:${MODULE_NAME}:${MODULE_VERSION}\")
}" > "${MODULE_NAME}"/"${MODULE_NAME}"-command-api/build.gradle.kts
# 设置 {MODULE_NAME}/{MODULE_NAME}-command/build.gradle.kts 配置文件
echo "dependencies {
implementation(\"${PROJECT_PACKAGE_NAME}.${MODULE_NAME}:${MODULE_NAME}-command-api:${MODULE_VERSION}\")
}" > "${MODULE_NAME}"/"${MODULE_NAME}"-command/build.gradle.kts
# 设置 {MODULE_NAME}/{MODULE_NAME}-query-api/build.gradle.kts 配置文件
echo "dependencies {$(get_data_source_dependency "${DATA_SOURCE_TYPE_QUERY}")
api(\"${PROJECT_PACKAGE_NAME}.${MODULE_NAME}:${MODULE_NAME}:${MODULE_VERSION}\")
}" > "${MODULE_NAME}"/"${MODULE_NAME}"-query-api/build.gradle.kts
# 设置 {MODULE_NAME}/{MODULE_NAME}-query/build.gradle.kts 配置文件
echo "dependencies {
implementation(\"${PROJECT_PACKAGE_NAME}.${MODULE_NAME}:${MODULE_NAME}-query-api:${MODULE_VERSION}\")
}" > "${MODULE_NAME}"/"${MODULE_NAME}"-query/build.gradle.kts
printf "\e[36m完成\e[0m\n\n"
- 执行以下命令,根据提示输入微服务模块名称完成微服务模块创建
# 将文件设置可执行
chmod +x ./generate-module.sh
# 创建微服务 根据提示输入微服务名称,最后确认完成创建
./generate-module.sh
5. 将本地微服务文件于远端git库关联
- 进入刚创建的文服务文件夹,然后执行以下命令初始化git仓库
# 初始化git
git init
# 使本地文件夹与远端git仓库关联
git remote add origin git@gitlab.dxsuite.cn:git-test/git-sub-project.git
#拉取远程线上代码
git pull origin master
# 将当前改动进行提交
git add .
# 提交全部并加上注释
git commit -am 'project-init'
# 把所有的东西都推送到远程服务器上
git push --set-upstream origin master
6. 将新建微服务添作为子模块添加到上面的父模块git下
# 返回到项目工程根目录下,执行 git submodule add <子项目git url 子项目本地路径>
# 例如:
git submodule add git@gitlab.xxx.git ./sub-module
7. 最后推送到远端服务器即可
# 提交全部并加上注释
git commit -am 'init'
# 推送远端
git push