Files
DocprintService/.gitea/workflows/build.yml
T

112 lines
6.4 KiB
YAML
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.
name: build
# .NET Core 应用 CI(对齐 springboot 模式:构建在独立 sdk 容器内,Dockerfile 只拷产物)
# 链路:clone 源码 -> dotnet sdk 容器 publish(入 infra-infra-net,容器名直连 nexus 拉 NuGet 包,
# 复用宿主 nuget 缓存卷)-> docker build -f docker/Dockerfile(COPY publish/ 产物,RUN 零网络)-> push Nexus -> 通知 projman 建档
# 触发:push 到 main / 手动 Run workflow(可勾选缓存重建)
# cache_bust 勾选时清空宿主 nuget 缓存卷 + docker builder 层缓存,强制下次全量重建。
# 依赖仓库 Secrets:NEXUS_USER / NEXUS_PASSWORD(docker-hosted 推送)/ DEPLOY_TOKEN(webhook 鉴权)
# 依赖 docker/Dockerfile(由 projman 注入,开发者也可自备——已写则尊重不覆盖)
on:
push:
branches: [ main ]
workflow_dispatch:
inputs:
cache_bust:
description: '构建前清空 NuGet 缓存'
required: false
default: 'false'
jobs:
build-push:
runs-on: ubuntu-latest
container:
image: docker:24
options: --network infra-infra-net
steps:
- name: 安装 git / curl(alpine)
run: apk add --no-cache git curl
- name: 拉取源码(内网无 GitHub,手动 clone 本仓库)
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
git clone --depth 1 --branch main "http://x-access-token:${GITHUB_TOKEN}@gitea.yunhaixingtong.com/${{ github.repository }}.git" /tmp/src
cp -a /tmp/src/. .
rm -rf /tmp/src
COMMIT_MSG=$(git log -1 --pretty=%s | tr '\n' ' ' | sed 's/["\\]/ /g' | cut -c1-200)
echo "COMMIT_MSG=${COMMIT_MSG}" >> "$GITHUB_ENV"
# 可选:清空 nuget 缓存卷 + docker 构建层缓存(仅手动勾选 cache_bust 时)
- name: 可选清空构建缓存
if: ${{ inputs.cache_bust == 'true' }}
run: |
docker run --rm -v /opt/docker/projman-dotnet-nuget:/root/.nuget/packages alpine sh -c 'rm -rf /root/.nuget/packages/*'
docker builder prune -f
echo "nuget + docker build cache busted"
# dotnet 构建(对齐 maven 模式):起独立 sdk 容器(入 infra-infra-net 用容器名 nexus 直连拉 NuGet 包)
# 通过 docker.sock 调宿主 dockerd,故 -v 路径按宿主解析;用 docker cp 进出源码/产物
# nuget 缓存挂宿主固定目录 /opt/docker/projman-dotnet-nuget,跨构建复用依赖
# 仓库 nuget.config 常指向域名(nexus.<域名>,本地走宿主 Caddy 反代);容器内改写为容器名 nexus:8081 直连
# 构建目标自愈式定位:候选排序(根 sln > 根 csproj > Web SDK > OutputType=Exe > 其余非 Test),
# 逐个 publish,产出 *.runtimeconfig.json(可执行项目唯一标志)者胜出——类库 publish 无 runtimeconfig,
# 自动跳过换下一个(grep csproj 特征不可靠,以实际产物为准);.slnx 需 SDK 9+ 解析,不参与定位
- name: 构建 publish 产物(dotnet sdk 容器,复用宿主 nuget 缓存)
run: |
set -e
docker rm -f dotnetbuild 2>/dev/null || true
docker run -d --name dotnetbuild \
--network infra-infra-net \
-v /opt/docker/projman-dotnet-nuget:/root/.nuget/packages \
-w /build mcr.microsoft.com/dotnet/sdk:5.0 sleep 3600
docker cp "${PWD}/." dotnetbuild:/build/
docker exec dotnetbuild sh -c "find /build -maxdepth 2 -iname nuget.config -exec sed -i 's|//nexus.yunhaixingtong.com|//nexus:8081|g' {} +"
docker exec dotnetbuild sh -c '
set -e
root_sln=$(ls /build/*.sln 2>/dev/null | head -1 || true)
root_csproj=$(ls /build/*.csproj 2>/dev/null | head -1 || true)
if [ -n "$root_sln" ] || [ -n "$root_csproj" ]; then
ordered="$root_sln $root_csproj"
else
cands=$(find /build -mindepth 2 -name "*.csproj" -not -path "*/bin/*" -not -path "*/obj/*" | grep -vi test || true)
web=$(echo "$cands" | xargs -r grep -l "Microsoft.NET.Sdk.Web" 2>/dev/null || true)
exe=$(echo "$cands" | xargs -r grep -l "<OutputType>Exe" 2>/dev/null || true)
ordered=$(printf "%s\n%s\n%s\n" "$web" "$exe" "$cands" | grep -v "^$" | awk "!seen[\$0]++")
fi
if [ -z "$ordered" ]; then echo "ERROR: 未找到 .sln/.csproj(请自备 Dockerfile)"; exit 1; fi
target=""
for t in $ordered; do
rm -rf /app
echo "try publish: $t"
if dotnet publish "$t" -c Release -o /app /p:UseAppHost=false 2>/tmp/pub.err; then
if ls /app/*.runtimeconfig.json >/dev/null 2>&1; then target="$t"; break; fi
echo " -> 非 executable(类库),换下一候选"
else
echo " -> publish 失败,换下一候选: $(tail -3 /tmp/pub.err)"
fi
done
if [ -z "$target" ]; then echo "ERROR: 所有候选均未产出可执行产物(多可执行项目请自备 Dockerfile)"; exit 1; fi
echo "publish target: $target"
'
mkdir -p "${PWD}/publish"
docker cp dotnetbuild:/app/. "${PWD}/publish/"
docker rm -f dotnetbuild
# 入口脚本:runtimeconfig.json 是可执行项目唯一标志(X.runtimeconfig.json <-> X.dll),
# 类库 deps.json 无 runtimeconfig 兄弟文件,天然不会误选
entry=$(ls "${PWD}"/publish/*.runtimeconfig.json | head -1)
dll=$(basename "${entry}" .runtimeconfig.json)
echo "exec dotnet ${dll}.dll" > "${PWD}/publish/entrypoint.sh"
- name: 构建并推送镜像
run: |
set -e
TAG=$(echo "$GITHUB_SHA" | cut -c1-8)
echo "${{ secrets.NEXUS_PASSWORD }}" | docker login nexus:8083 -u "${{ secrets.NEXUS_USER }}" --password-stdin
docker build -t "nexus:8083/docker-hosted/docprint-service:${TAG}" -f docker/Dockerfile .
docker push "nexus:8083/docker-hosted/docprint-service:${TAG}"
echo "TAG=${TAG}" >> "$GITHUB_ENV"
- name: 通知 projman 部署
run: |
curl -sS -X POST "http://192.168.10.160:8090/projman/api/deploy/webhook" \
-H "Content-Type: application/json" \
-H "X-Deploy-Token: ${{ secrets.DEPLOY_TOKEN }}" \
-d "{\"app\":\"docprint\",\"tag\":\"${TAG}\",\"sha\":\"${GITHUB_SHA}\",\"message\":\"${COMMIT_MSG}\"}"