action_deploy/start_new.sh

537 lines
19 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
origin_path=`pwd`
env=$1
actionOrg=""
OS=$(uname)
auto_slash=""
case "$OS" in
Linux) # 在 Linux 系统上运行
;;
Darwin) # 在 macOS 系统上运行
;;
CYGWIN*|MINGW32*|MSYS*|MINGW*) # 在 Windows 系统上运行
auto_slash="/" # 将 $auto_slash
;;
*)
echo "Unknown OS: $OS" # 在其他系统上运行
;;
esac
check_package() {
local has_error=0
# 检查docker是否安装
if which docker > /dev/null; then
echo "✅ Docker已经安装"
else
echo "❌ Docker未安装"
has_error=1
fi
# 检查curl是否安装
if which curl > /dev/null; then
echo "✅ Curl已经安装"
else
echo "❌ Curl未安装"
has_error=1
fi
# 检查git是否安装
if which git > /dev/null; then
echo "✅ Git已经安装"
else
echo "❌ Git未安装"
has_error=1
fi
if [ $has_error -eq 1 ]; then
echo "❌ check_package: 缺少必要的依赖包,请安装后再试"
return 1
fi
echo "✅ check_package: 所有依赖包检查通过"
return 0
}
check_build_exists() {
docker image inspect "my-static:latest" > /dev/null 2>&1
return $?
}
start_static_server() {
echo "开始构建静态资源服务镜像"
cd $origin_path
if check_build_exists; then
echo "✅ Image my-static:latest exists"
else
echo "⚠️ Image my-static:latest not found"
docker build -t my-static .
# 验证构建是否成功
if check_build_exists; then
echo "🎉 Image built successfully"
else
echo "❌ Failed to build image my-static:latest" >&2
return 1
fi
fi
docker run --restart always --name my-action-static -d -p $staticServerPort:81 -v $auto_slash$origin_path/data:/usr/share/nginx/data my-static
# 检查容器是否实际在运行
if docker ps --format "{{.Names}}" | grep -q my-action-static; then
echo "构建静态资源服务正在运行。"
else
echo "构建静态资源服务没有运行。"
return 1
fi
return 0
}
check_static_server() {
echo "检查静态资源服务是否启动"
container_running=$(docker inspect -f '{{.State.Running}}' my-action-static)
if [ "$container_running" = "true" ]; then
echo "静态资源服务已启动"
docker stop my-action-static
docker rm my-action-static
if ! start_static_server; then
return 1
fi
else
echo "静态资源服务未启动"
if ! start_static_server; then
return 1
fi
fi
return 0
}
make_login_action() {
echo "开始登陆操作"
curl -c cookies.txt $forgeDomain/api/accounts/login.json -H 'Content-type:application/json' -d '{"login":"'"$username"'","password":"'"$password"'","autologin":1}'
}
create_organization() {
echo "开始创建 $actionOrg 组织"
response=$(curl -b cookies.txt --location --request POST ${forgeDomain}/api/organizations.json \
--header "Content-Type: application/json" \
--data "{
\"image\": \"data:image/png;base64,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\",
\"description\": \"${actionOrg}\",
\"name\": \"${actionOrg}\",
\"nickname\": \"${actionOrg}\",
\"visibility\": \"common\"
}")
echo "create_organization:$response"
if echo "$response" | grep -q '组织账号已被使用'; then
echo "组织 $actionOrg 已存在,继续后续操作。"
local query_response=$(curl -b cookies.txt --location --request GET "${forgeDomain}/api/organizations/${actionOrg}" \
--header "Content-Type: application/json" 2>/dev/null)
echo "查询响应: $query_response"
if echo "$query_response" | grep -q '"id":'; then
actionOrgID=$(echo "$query_response" | sed -n 's/.*"id":\([0-9]*\).*/\1/p')
echo "✅ 获取到现有组织ID: $actionOrgID"
else
echo "❌ 无法获取组织ID"
exit
fi
elif echo "$response" | grep -q '{"id":'; then
actionOrgID=$(echo "$response" | sed -n 's/.*"id":\([0-9]*\).*/\1/p')
response=$(curl -b cookies.txt --location --request POST ${pmsDomain}/api/pms/pmsEnterprise/createByGitlinkOrgId/${actionOrgID} \
--header "Content-Type: application/json" \
--data "[{
\"roleKey\": \"pms_org_admin\",
\"userId\": 1
}]")
if echo "$response" |grep -q '{"code":200'; then
echo ""创建 $actionOrg 组织成功。""
else
echo "创建 $actionOrg 组织失败。"
fi
else
echo "创建 $actionOrg 组织失败。"
fi
}
create_pms_project() {
echo "开始创建项目管理项目"
response=$(curl -b cookies.txt --location --request POST ${pmsDomain}/api/pms/${actionOrg}/pmsProject \
--header "Content-Type: application/json" \
--data "{
\"projectName\": \"actions\",
\"projectAssigneeId\": \"1\",
\"startTime\": \"2024-08-15T00:00:00\",
\"endTime\": \"2025-08-15T23:59:59\"
}")
echo $response
pmsProjectId=0
if echo "$response" | grep -q '{"msg":"操作成功"'; then
pmsProjectId=$(echo "$response" | sed -n 's/.*"data":\([0-9]*\).*/\1/p')
echo "创建项目成功。"
else
echo "创建项目失败。"
fi
}
create_one_repository() {
echo "开始创建 $1 项目"
# 构建正确的请求数据完全匹配Java类的字段名
local request_data="{
\"user_id\": ${actionOrgID},
\"pms_project_id\": ${pmsProjectId},
\"private\": false,
\"repository_name\": \"${1}\",
\"name\": \"${1}\",
\"description\": \"\",
\"ignoreFlag\": false,
\"languageFlag\": false,
\"needLog\": true
}"
response=$(curl -b cookies.txt --location --request POST ${pmsDomain}/api/pms/${actionOrg}/pmsProjectRepository/addRepository \
--header "Content-Type: application/json" \
--data "$request_data" 2>&1)
echo "响应: $response"
if echo "$response" | grep -q '"id":'; then
echo "✅ 创建 $1 项目成功。"
return 0
else
echo "❌ 创建 $1 项目失败。"
return 1
fi
}
create_two_repository() {
echo "开始创建software_factory_pipeline_test项目"
if curl -b cookies.txt --location --request POST ${pmsDomain}/api/pms/${actionOrg}/pmsProjectRepository/addRepository \
--header "Content-Type: application/json" \
--data "{
\"user_id\": \"${actionOrgID}\",
\"pms_project_id\": \"${pmsProjectId}\",
\"private\": \"false\",
\"repository_name\": \"software_factory_pipeline_test\",
\"name\": \"software_factory_pipeline_test\"
}" | grep -q '{"msg":"操作成功"'; then
echo "创建software_factory_pipeline_test项目成功。"
else
echo "创建software_factory_pipeline_test项目失败。"
fi
}
# 优化的create_repository函数从repository文件夹遍历
create_repository() {
create_organization
if [ "$actionOrgID" = "" ]; then
echo "❌ create_repository: 无法获取组织ID"
return 1
else
create_pms_project
if [ "$pmsProjectId" = "" ]; then
echo "❌ create_repository: 无法获取项目ID"
return 1
else
# 遍历repository文件夹中的所有子目录
repository_dir="$origin_path/repository"
if [ -d "$repository_dir" ]; then
for repo in "$repository_dir"/*; do
if [ -d "$repo" ]; then
repo_name=$(basename "$repo")
echo "正在处理仓库: $repo_name"
create_one_repository "$repo_name"
fi
done
else
echo "❌ repository文件夹不存在: $repository_dir"
return 1
fi
fi
fi
return 0
}
changeDefaultBranch() {
echo "开始更改 $1 项目的默认分支"
if curl -b cookies.txt --location --request PUT ${forgeDomain}/api/${actionOrg}/$1.json \
--header "Content-Type: application/json" \
--data-raw "{
\"default_branch\": \"main\"
}" | grep -q '{"id":'; then
echo "更改 $1 项目的默认分支成功。"
else
echo "更改 $1 项目的默认分支失败。"
fi
}
# 定义仓库配置: name|branch|reset_commit|sed_replace_pattern|sed_replace_value|files_to_sed
# 格式: repo_name|branch|reset_commit|pattern|replacement_value|files (空则不sed)
# 如果不需要sed替换pattern和replacement填"-"files留空
# 需要sed替换 #{staticServerDomain} 的仓库 (versions-*)
DEFINE_STATIC_REPOS() {
echo "go-versions|main|26d24036bc7e8039690dc3aed6352b0f70f64e23|#{staticServerDomain}|${localIP}:${staticServerPort}|versions-manifest.json"
echo "node-versions|main|7c6a88bde64272f043e5543c734f1fe4b971e0ab|#{staticServerDomain}|${localIP}:${staticServerPort}|versions-manifest.json"
echo "python-versions|main|cf36223d60f3192d6cb3b5c72316c31c3148d931|#{staticServerDomain}|${localIP}:${staticServerPort}|versions-manifest.json"
}
# 需要sed替换 #{giteaDomain} 的仓库 (setup-*)
DEFINE_GITEA_REPOS() {
echo "setup-go|main|c2aa616d4ba735e5f411e7863de9acf43069fefe|#{giteaDomain}|${giteaDomain}|dist/setup/index.js"
echo "setup-node|master|891a2112adc2599da487d1c37d6833db6e5b47f2|#{giteaDomain}|${giteaDomain}|dist/setup/index.js"
echo "setup-python|main|c147b8dcc12f4b88d2a3335458d1bd32024dda5e|#{giteaDomain}|${giteaDomain}|dist/setup/index.js src/install-python.ts"
}
# 普通仓库: 只需要push
DEFINE_SIMPLE_REPOS() {
echo "checkout"
echo "log_match_action"
echo "publish-releases-action"
echo "run_pipeline_action"
echo "upload-artifact-zpk"
echo "scp-action"
echo "ssh-action"
echo "setup-cpp"
echo "setup-maven"
echo "setup-java"
echo "sonarqube-scan-action"
echo "setup-buildx-action"
echo "metadata-action"
echo "login-action"
echo "upload-artifact"
echo "build-push-action"
echo "cache"
}
# 通用push函数处理单个仓库
push_one_repo() {
local repo_name=$1
local branch=$2
local reset_commit=$3
local sed_pattern=$4
local sed_value=$5
local sed_files=$6
cd "$origin_path/repository/$repo_name"
git config --local user.name "$author"
git config --local user.email "$authorEmail"
# 如果指定了reset_commit则执行reset和sed替换
if [ -n "$reset_commit" ] && [ "$reset_commit" != "-" ]; then
echo "正在对${repo_name}仓库进行服务地址替换"
git reset --hard "$reset_commit"
if [ -n "$sed_files" ] && [ "$sed_pattern" != "-" ]; then
for file in $sed_files; do
if [ -f "$file" ]; then
sed -i "s|${sed_pattern}|${sed_value}|g" "$file"
fi
done
git add $sed_files
git commit -m "auto更改服务地址"
fi
echo "结束${repo_name}仓库服务地址替换"
fi
# 删除 .github/workflows 目录下的文件,避免创建仓库就触发流水线
if [ -d ".github/workflows" ]; then
echo "正在删除${repo_name}仓库的 .github/workflows 目录下的文件"
rm -rf .github/workflows/*
if [ -d ".github/workflows" ] && [ "$(ls -A .github/workflows 2>/dev/null)" ]; then
git add .github/workflows/*
else
# workflows 目录可能为空,创建一个 .gitkeep 避免目录被删除
mkdir -p .github/workflows
touch .github/workflows/.gitkeep
git add .github/workflows/.gitkeep
fi
git commit -m "chore: 删除workflows避免创建仓库触发流水线"
echo "结束删除${repo_name}仓库的 workflows 文件"
fi
echo "开始进行${repo_name}仓库推送"
if ! git push -uf "$pushRepositoryPrefix/$actionOrg/$repo_name.git" "$branch"; then
echo "${repo_name}仓库推送失败"
return 1
fi
echo "结束${repo_name}仓库推送"
return 0
}
# 遍历推送所有仓库
push_repository() {
local push_failed=0
# 1. 推送需要 #{staticServerDomain} 替换的仓库
while IFS='|' read -r name branch commit pattern value files; do
[ -z "$name" ] && continue
if ! push_one_repo "$name" "$branch" "$commit" "$pattern" "$value" "$files"; then
push_failed=1
fi
done < <(DEFINE_STATIC_REPOS)
# 2. 推送需要 #{giteaDomain} 替换的仓库
while IFS='|' read -r name branch commit pattern value files; do
[ -z "$name" ] && continue
if ! push_one_repo "$name" "$branch" "$commit" "$pattern" "$value" "$files"; then
push_failed=1
fi
done < <(DEFINE_GITEA_REPOS)
# 3. 推送普通仓库
for repo_name in $(DEFINE_SIMPLE_REPOS); do
[ -z "$repo_name" ] && continue
cd "$origin_path/repository/$repo_name"
# 删除 .github/workflows 目录下的文件,避免创建仓库就触发流水线
if [ -d ".github/workflows" ]; then
echo "正在删除${repo_name}仓库的 .github/workflows 目录下的文件"
rm -rf .github/workflows/*
mkdir -p .github/workflows
touch .github/workflows/.gitkeep
git add .github/workflows/
git commit -m "chore: 删除workflows避免创建仓库触发流水线"
fi
echo "开始进行${repo_name}仓库推送"
if ! git push -uf "$pushRepositoryPrefix/$actionOrg/$repo_name.git" --all; then
echo "${repo_name}仓库推送失败(--all"
push_failed=1
fi
if ! git push -uf "$pushRepositoryPrefix/$actionOrg/$repo_name.git" --tags; then
echo "${repo_name}仓库推送失败(--tags"
push_failed=1
fi
echo "结束${repo_name}仓库推送"
done
if [ $push_failed -eq 1 ]; then
echo "❌ push_repository: 部分仓库推送失败"
return 1
fi
return 0
}
# 显示帮助信息的函数
show_help() {
echo "使用方法: $SCRIPT_NAME [环境变量] [选项]"
echo ""
echo "环境变量(示例):"
echo " local, 加载local.profile配置文件"
echo " test, 加载test.profile配置文件"
echo ""
echo "选项:"
echo " check_package, 检查是否安装包支持"
echo " check_static_server, 检查静态资源服务"
echo " create_repository, 创建actions相关的仓库"
echo " push_repository, 推送修改过地址的commit到仓库"
echo " deploy_all, 一键执行所有操作(检查包→检查服务→创建仓库→推送代码)"
}
# 一键执行所有操作
deploy_all() {
echo "========== 开始一键部署 =========="
echo ""
local failed=0
local step_output=""
echo ">>> 第1步检查依赖包 <<<"
step_output=$(check_package 2>&1)
if ! check_package > /dev/null 2>&1; then
echo "❌ 第1步失败依赖包检查未通过"
echo "--- 错误详情 ---"
echo "$step_output"
echo "----------------"
failed=1
fi
echo ""
if [ $failed -eq 0 ]; then
echo ">>> 第2步检查静态资源服务 <<<"
step_output=$(check_static_server 2>&1)
if ! check_static_server > /dev/null 2>&1; then
echo "❌ 第2步失败静态资源服务启动失败"
echo "--- 错误详情 ---"
echo "$step_output"
echo "----------------"
failed=2
fi
fi
echo ""
if [ $failed -eq 0 ]; then
echo ">>> 第3步创建仓库 <<<"
step_output=$(create_repository 2>&1)
if ! create_repository > /dev/null 2>&1; then
echo "❌ 第3步失败仓库创建失败"
echo "--- 错误详情 ---"
echo "$step_output"
echo "----------------"
failed=3
fi
fi
echo ""
if [ $failed -eq 0 ]; then
echo ">>> 第4步推送代码 <<<"
step_output=$(push_repository 2>&1)
if ! push_repository > /dev/null 2>&1; then
echo "❌ 第4步失败代码推送失败"
echo "--- 错误详情 ---"
echo "$step_output"
echo "----------------"
failed=4
fi
fi
echo ""
if [ $failed -eq 0 ]; then
echo "========== ✅ 一键部署全部完成 =========="
else
echo "========== ❌ 一键部署在第${failed}步失败 =========="
return 1
fi
}
case "$env" in
*)
{
if [ -f "$env.profile" ]; then
. ./"${env}.profile"
else
show_help
echo "错误:环境配置文件 '$env.profile' 不存在。"
exit
fi
}
;;
esac
case "$2" in
"check_package")
check_package
;;
"check_static_server")
check_static_server
;;
"create_repository")
create_repository
;;
"push_repository")
push_repository
;;
"deploy_all")
deploy_all
;;
*)
show_help
;;
esac