1beef44625
补齐审计指出的「CI 缺 lint/安全扫描/-race」低成本质量门: - go job:go test → go test -race(4 模块本地已验证 race-clean,ubuntu 自带 gcc)。 - lint job:golangci-lint(standard 集)仅 PR 跑 + only-new-issues —— 新代码必须干净, 存量 ~42 处(多为未检 Close/死代码)单独消化,不拿存量红门。加 .golangci.yml(测试放过 errcheck)。 - security job:govulncheck advisory(stdlib/nats CVE 靠 toolchain/依赖升级,只做可见性不阻断) + gitleaks 扫提交防密钥泄漏。 - 顺手清掉本会话新代码的 lint:blob GetBytes 的 defer Close、退款测试未检 CreateOrder。 注:gitleaks-action 个人/公开仓库免费;组织仓库需 GITLEAKS_LICENSE。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
158 lines
5.6 KiB
YAML
158 lines
5.6 KiB
YAML
name: CI
|
||
|
||
# 只认 main:push 到 main、以及任何以 main 为目标的 PR。
|
||
# 开发分支(feat/*)自己 push 不跑 CI,靠合入 main 前的 PR 把关。
|
||
on:
|
||
push:
|
||
branches: [main]
|
||
pull_request:
|
||
branches: [main]
|
||
|
||
# 同一分支新 push 取消上一次未完成的运行,省 CI 时间。
|
||
concurrency:
|
||
group: ci-${{ github.ref }}
|
||
cancel-in-progress: true
|
||
|
||
jobs:
|
||
go:
|
||
name: Go · build + vet + test
|
||
runs-on: ubuntu-latest
|
||
steps:
|
||
- uses: actions/checkout@v4
|
||
- uses: actions/setup-go@v5
|
||
with:
|
||
go-version: "1.25"
|
||
cache-dependency-path: "**/go.sum"
|
||
- name: build + vet + test -race(4 模块;bus 用内嵌 NATS,无需外部服务)
|
||
run: |
|
||
set -e
|
||
for m in sundynix-shared sundynix-gateway sundynix-dispatcher sundynix-mcp-go; do
|
||
echo "::group::$m"
|
||
# -race:数据竞争一票否决(4 模块本地已验证 race-clean)。ubuntu runner 自带 gcc,CGO 可用。
|
||
(cd "$m" && go build ./... && go vet ./... && go test -race ./...)
|
||
echo "::endgroup::"
|
||
done
|
||
|
||
# golangci-lint:只卡「新问题」——存量约 42 处(未检 Close/死代码)单独消化,不拿存量红门。
|
||
# 仅在 PR 跑:dev→main 的 PR 是唯一合入口,据 base 算 diff;push 到 main 不重复跑。
|
||
lint:
|
||
name: Go · golangci-lint (new issues)
|
||
if: github.event_name == 'pull_request'
|
||
runs-on: ubuntu-latest
|
||
strategy:
|
||
fail-fast: false
|
||
matrix:
|
||
module: [sundynix-shared, sundynix-gateway, sundynix-dispatcher, sundynix-mcp-go]
|
||
steps:
|
||
- uses: actions/checkout@v4
|
||
with:
|
||
fetch-depth: 0 # only-new-issues 要据 base 分支算 diff,需完整历史
|
||
- uses: actions/setup-go@v5
|
||
with:
|
||
go-version: "1.25"
|
||
cache-dependency-path: "**/go.sum"
|
||
- uses: golangci/golangci-lint-action@v6
|
||
with:
|
||
version: latest
|
||
working-directory: ${{ matrix.module }}
|
||
only-new-issues: true
|
||
|
||
# 安全扫描:govulncheck(依赖 CVE) advisory —— stdlib/nats CVE 要靠 toolchain/依赖升级,
|
||
# 不拿它红门,只做可见性;gitleaks(密钥泄漏)在 PR 上扫 diff,硬拦提交密钥。
|
||
security:
|
||
name: Security · govulncheck + gitleaks
|
||
runs-on: ubuntu-latest
|
||
steps:
|
||
- uses: actions/checkout@v4
|
||
with:
|
||
fetch-depth: 0
|
||
- uses: actions/setup-go@v5
|
||
with:
|
||
go-version: "1.25"
|
||
cache-dependency-path: "**/go.sum"
|
||
- name: govulncheck(advisory:报告不阻断)
|
||
continue-on-error: true
|
||
run: |
|
||
go install golang.org/x/vuln/cmd/govulncheck@latest
|
||
for m in sundynix-shared sundynix-gateway sundynix-dispatcher sundynix-mcp-go; do
|
||
echo "::group::govulncheck $m"
|
||
(cd "$m" && govulncheck ./...) || true
|
||
echo "::endgroup::"
|
||
done
|
||
- name: gitleaks(扫提交历史,命中即失败)
|
||
uses: gitleaks/gitleaks-action@v2
|
||
env:
|
||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||
|
||
web:
|
||
name: Frontend · tsc + vitest
|
||
runs-on: ubuntu-latest
|
||
strategy:
|
||
fail-fast: false
|
||
matrix:
|
||
dir: [sundynix-desktop/frontend, sundynix-admin, sundynix-web]
|
||
steps:
|
||
- uses: actions/checkout@v4
|
||
- uses: actions/setup-node@v4
|
||
with:
|
||
node-version: "20"
|
||
cache: npm
|
||
cache-dependency-path: ${{ matrix.dir }}/package-lock.json
|
||
- name: install + typecheck + test(三个前端都有 vitest,此前只跑 tsc,测试从没进过关卡)
|
||
working-directory: ${{ matrix.dir }}
|
||
run: |
|
||
npm ci
|
||
npx tsc --noEmit
|
||
npm test
|
||
|
||
# desktop 的 Go 模块不在 go.work 里,上面的 go job 从来没测过它(app.go 的
|
||
# download/另存为等桥方法有单测但 CI 一次没跑过)。用 macos runner:一来免装
|
||
# gtk/webkit(linux 编 wails 要一堆 CGO 头),二来 darwin 才是实际发行目标。
|
||
# go:embed frontend/dist 要求先出前端产物,故先 npm build。
|
||
desktop:
|
||
name: Desktop · go build + test (macOS)
|
||
runs-on: macos-latest
|
||
steps:
|
||
- uses: actions/checkout@v4
|
||
- uses: actions/setup-go@v5
|
||
with:
|
||
go-version: "1.25"
|
||
cache-dependency-path: sundynix-desktop/go.sum
|
||
- uses: actions/setup-node@v4
|
||
with:
|
||
node-version: "20"
|
||
cache: npm
|
||
cache-dependency-path: sundynix-desktop/frontend/package-lock.json
|
||
- name: 前端构建(供 go:embed)
|
||
working-directory: sundynix-desktop/frontend
|
||
run: |
|
||
npm ci
|
||
npm run build
|
||
- name: go build + vet + test
|
||
working-directory: sundynix-desktop
|
||
env:
|
||
GOWORK: "off" # 必须加引号:YAML 裸 off 会被解析成布尔 false
|
||
run: |
|
||
go build ./...
|
||
go vet ./...
|
||
go test ./...
|
||
|
||
py:
|
||
name: mcp-py · sandbox guard
|
||
runs-on: ubuntu-latest
|
||
steps:
|
||
- uses: actions/checkout@v4
|
||
- uses: actions/setup-python@v5
|
||
with:
|
||
python-version: "3.11"
|
||
cache: pip
|
||
- name: install + test(无 Docker 时测降级路径)
|
||
working-directory: sundynix-mcp-py
|
||
run: |
|
||
python -m pip install --upgrade pip
|
||
python -m pip install -e . pytest
|
||
PYTHONPATH=src:tests python -m pytest tests/ -q || \
|
||
PYTHONPATH=src:tests python -c "import test_sandbox as t; \
|
||
fns=[getattr(t,n) for n in dir(t) if n.startswith('test_')]; \
|
||
[ (f(),print('PASS',f.__name__)) for f in fns ]; print(f'{len(fns)} passed')"
|