This commit is contained in:
@@ -0,0 +1,156 @@
|
||||
name: build
|
||||
|
||||
# 提交 -> 本机 Runner 编译 -> 微信通知 + 网页预览
|
||||
# 实测结论(勿随意改动):
|
||||
# 1. 不用任何第三方 action(作业容器不联网拉 action,全用镜像自带工具)
|
||||
# 2. 必须自己 clone —— Runner 不会自动检出代码,工作区初始为空
|
||||
# 3. act 以 `bash -e -o pipefail` 执行每步 -> 禁止 `cmd | head` 这种会 SIGPIPE 提前退出的管道
|
||||
# 4. 工具链来自主机只读挂载 /opt/citools(go/uv),缓存写 /opt/citools-cache
|
||||
# 5. bridge 从容器内走 docker 网关 172.17.0.1:8899(实测可达)
|
||||
# 6. 校验/上报逻辑放在 .gitea/scripts/ 下的脚本里,YAML 只负责调用(避免 YAML 里嵌深缩进代码)
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- "**"
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
BRIDGE_URL: ${{ vars.CI_BRIDGE_URL }}
|
||||
BRIDGE_TOKEN: ${{ secrets.CI_BRIDGE_TOKEN }}
|
||||
GIT_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
concurrency:
|
||||
group: build-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 40
|
||||
steps:
|
||||
- name: 检出代码
|
||||
run: |
|
||||
set -uo pipefail
|
||||
SRV="${GITHUB_SERVER_URL:-http://192.168.50.223:3000}"
|
||||
HP="${SRV#*://}"
|
||||
BR="${GITHUB_REF_NAME:-${GITHUB_REF#refs/heads/}}"
|
||||
cd "${GITHUB_WORKSPACE:-$(pwd)}"
|
||||
rm -rf ./* .git 2>/dev/null || true
|
||||
git init -q .
|
||||
git remote add origin "http://x-access-token:${GIT_TOKEN}@${HP}/${GITHUB_REPOSITORY}.git"
|
||||
git fetch -q --depth 50 origin "$BR"
|
||||
git checkout -q -B "$BR" FETCH_HEAD
|
||||
git rev-parse HEAD > /tmp/ci-sha
|
||||
date +%s > /tmp/ci-start
|
||||
: > /tmp/ci-preview-url
|
||||
echo skipped > /tmp/ci-build-status
|
||||
git rev-list --count FETCH_HEAD > /tmp/ci-commits-count 2>/dev/null || echo 1 > /tmp/ci-commits-count
|
||||
echo "已检出 ${GITHUB_REPOSITORY} 分支 ${BR}"
|
||||
git log -1 --format=' %h %an %s'
|
||||
|
||||
- name: 提交信息规范校验
|
||||
run: python3 .gitea/scripts/ci_gate.py
|
||||
|
||||
- name: 编译与自检
|
||||
run: |
|
||||
set +e; set +o pipefail
|
||||
LOG=/tmp/ci-build.log; : > "$LOG"
|
||||
run() { echo "-- $* --"; "$@" 2>&1 | tee -a "$LOG"; return "${PIPESTATUS[0]}"; }
|
||||
runin(){ local d="$1"; shift; echo "-- ($d) $* --"; ( cd "$d" && "$@" ) 2>&1 | tee -a "$LOG"; return "${PIPESTATUS[0]}"; }
|
||||
|
||||
export PATH=/opt/citools/go/bin:/opt/citools/bin:$PATH
|
||||
export GOCACHE=/opt/citools-cache/gocache GOMODCACHE=/opt/citools-cache/gomod UV_CACHE_DIR=/opt/citools-cache/uv
|
||||
export GOPROXY=https://goproxy.cn,direct GOTOOLCHAIN=local GOFLAGS=-mod=mod GOPATH=/opt/citools-cache/gopath
|
||||
mkdir -p "$GOCACHE" "$GOMODCACHE" "$UV_CACHE_DIR" "$GOPATH" 2>/dev/null
|
||||
|
||||
echo "工具链: $(go version 2>&1) | $(uv --version 2>&1) | $(node -v 2>&1) | $(python3 -V 2>&1)"
|
||||
fail=0; ran=""
|
||||
|
||||
if [ -f go.mod ]; then
|
||||
ran="$ran go"
|
||||
run go build ./... || fail=1
|
||||
run go vet ./... || fail=1
|
||||
run go test ./... || fail=1
|
||||
fi
|
||||
|
||||
if [ -f pyproject.toml ] || [ -f requirements.txt ] || [ -f setup.py ]; then
|
||||
ran="$ran python"
|
||||
if grep -qE '^check:' Makefile 2>/dev/null; then
|
||||
run make UV=uv check || fail=1
|
||||
else
|
||||
run uv sync || fail=1
|
||||
run uv run pytest -q || fail=1
|
||||
fi
|
||||
fi
|
||||
|
||||
WEBPKG=""
|
||||
for p in package.json web/package.json frontend/package.json ui/package.json; do
|
||||
if [ -f "$p" ]; then WEBPKG="$p"; break; fi
|
||||
done
|
||||
if [ -n "$WEBPKG" ]; then
|
||||
ran="$ran node"
|
||||
D="$(dirname "$WEBPKG")"
|
||||
if [ -f "$D/package-lock.json" ]; then
|
||||
runin "$D" npm ci || fail=1
|
||||
else
|
||||
runin "$D" npm install || fail=1
|
||||
fi
|
||||
if grep -q '"build"[[:space:]]*:' "$WEBPKG" 2>/dev/null; then
|
||||
runin "$D" npm run build || fail=1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$ran" ] && [ -f Makefile ]; then
|
||||
ran="$ran make"
|
||||
run make || fail=1
|
||||
fi
|
||||
if [ -z "$ran" ]; then
|
||||
echo "未识别到构建入口(go.mod / pyproject.toml / package.json / Makefile 都没有),跳过编译"
|
||||
fi
|
||||
|
||||
if [ "$fail" -eq 0 ]; then echo success > /tmp/ci-build-status; else echo failure > /tmp/ci-build-status; fi
|
||||
tail -c 4000 "$LOG" > /tmp/ci-build-tail
|
||||
echo "构建结果: $(cat /tmp/ci-build-status)(识别:$ran)"
|
||||
[ "$fail" -eq 0 ] || exit 1
|
||||
|
||||
- name: 发布网页预览
|
||||
if: always()
|
||||
run: |
|
||||
set +e; set +o pipefail
|
||||
: > /tmp/ci-preview-url
|
||||
if [ "$(cat /tmp/ci-build-status 2>/dev/null)" != "success" ]; then
|
||||
echo "构建未成功,跳过预览发布"; exit 0
|
||||
fi
|
||||
WEB=""
|
||||
for d in web/dist dist build out public web/build frontend/dist; do
|
||||
if [ -f "$d/index.html" ]; then WEB="$d"; break; fi
|
||||
done
|
||||
if [ -z "$WEB" ]; then echo "未发现静态网页产物目录,跳过预览发布"; exit 0; fi
|
||||
tar -czf /tmp/ci-web.tgz -C "$WEB" . || { echo "打包失败"; exit 0; }
|
||||
B="${BRIDGE_URL:-}"
|
||||
for cand in "$B" "http://172.17.0.1:8899" "http://192.168.50.134:8899" "http://100.92.49.78:8899"; do
|
||||
if [ -n "$cand" ]; then
|
||||
curl -s -m 5 -o /dev/null "$cand/healthz" && { B="$cand"; break; }
|
||||
fi
|
||||
done
|
||||
SHA="$(cat /tmp/ci-sha)"
|
||||
echo "发布预览到 $B(产物目录 $WEB)"
|
||||
curl -sS -m 90 -X POST "$B/api/ci/publish?repo=${GITHUB_REPOSITORY}&sha=${SHA}" -H "X-CI-Token: ${BRIDGE_TOKEN}" -H 'Content-Type: application/gzip' --data-binary @/tmp/ci-web.tgz -o /tmp/ci-pub.json
|
||||
cat /tmp/ci-pub.json; echo
|
||||
URL="$(python3 -c "import json;print(json.load(open('/tmp/ci-pub.json')).get('url',''))" 2>/dev/null)"
|
||||
if [ -n "$URL" ]; then echo "$URL" > /tmp/ci-preview-url; echo "网页预览: $URL"; fi
|
||||
|
||||
- name: 通知微信
|
||||
if: always()
|
||||
run: |
|
||||
set +e; set +o pipefail
|
||||
B="${BRIDGE_URL:-}"
|
||||
for cand in "$B" "http://172.17.0.1:8899" "http://192.168.50.134:8899" "http://100.92.49.78:8899"; do
|
||||
if [ -n "$cand" ]; then
|
||||
curl -s -m 5 -o /dev/null "$cand/healthz" && { B="$cand"; break; }
|
||||
fi
|
||||
done
|
||||
echo "使用 ci-bridge: $B"
|
||||
S=$(date +%s); T=$(cat /tmp/ci-start 2>/dev/null); [ -n "$T" ] || T=$S
|
||||
echo $((S - T)) > /tmp/ci-duration
|
||||
CI_BRIDGE_RESOLVED="$B" python3 .gitea/scripts/ci_report.py
|
||||
Reference in New Issue
Block a user