Skip to content

ci(cpp): job 超时 15→30 分钟——vcpkg 重装+新增测试逼近原预算 #2176

ci(cpp): job 超时 15→30 分钟——vcpkg 重装+新增测试逼近原预算

ci(cpp): job 超时 15→30 分钟——vcpkg 重装+新增测试逼近原预算 #2176

Workflow file for this run

name: CI - Core
on:
push:
branches: [main]
pull_request:
branches: [main]
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
jobs:
lint:
name: Lint
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- timeout-minutes: 3
uses: actions/checkout@v7
- timeout-minutes: 5
uses: actions/setup-go@v7
with:
go-version-file: "go.mod"
- name: Install ripgrep
timeout-minutes: 2
run: |
sudo apt-get update -qq && sudo apt-get install -y -qq ripgrep
rg --version
- name: Architecture guard
timeout-minutes: 5
run: bash .github/scripts/architecture_guard.sh
- name: Contracts guard
timeout-minutes: 5
run: bash .github/scripts/contracts_guard.sh
- name: API response guard
timeout-minutes: 5
run: bash .github/scripts/api_response_guard.sh
- name: Dashboard vNext guard
timeout-minutes: 5
run: bash scripts/dashboard_vnext_guard.sh
- name: Dashboard vNext guard regression test
timeout-minutes: 5
run: bash scripts/dashboard_vnext_guard_test.sh
- name: SDK matrix conformance
timeout-minutes: 5
run: bash scripts/check-sdk-matrix.sh
- name: Normalize Go toolchain env
timeout-minutes: 2
shell: bash
run: |
go env -u GOROOT || true
go env -u GOTOOLDIR || true
go env -u GOTOOLCHAIN || true
echo "GOCACHE=$RUNNER_TEMP/go-build-${{ github.run_id }}-${{ github.run_attempt }}" >> "$GITHUB_ENV"
echo "GOMODCACHE=$RUNNER_TEMP/go-mod-${{ github.run_id }}" >> "$GITHUB_ENV"
go version
go env GOROOT GOTOOLDIR GOVERSION GOOS GOARCH
- name: Install buf
timeout-minutes: 5
shell: bash
env:
BUF_VERSION: "1.47.2"
run: |
set -euo pipefail
mkdir -p "$RUNNER_TEMP/bin"
curl -sSLf "https://github.com/bufbuild/buf/releases/download/v${BUF_VERSION}/buf-Linux-x86_64" -o "$RUNNER_TEMP/bin/buf"
chmod +x "$RUNNER_TEMP/bin/buf"
echo "$RUNNER_TEMP/bin" >> "$GITHUB_PATH"
"$RUNNER_TEMP/bin/buf" --version
- name: Lint proto
timeout-minutes: 5
run: buf lint proto
- name: Go mod download
timeout-minutes: 5
run: |
for i in 1 2 3; do
go mod download && exit 0
echo "go mod download failed (attempt $i/3), retrying in 5s..."
sleep 5
done
exit 1
- name: Check gofmt
timeout-minutes: 5
run: |
mapfile -d '' -t go_files < <(git ls-files -z '*.go' || true)
if [[ ${#go_files[@]} -eq 0 ]]; then
exit 0
fi
fmt_result=$(gofmt -l "${go_files[@]}")
if [[ -n "$fmt_result" ]]; then
echo "The following files need gofmt:"
echo "$fmt_result"
exit 1
fi
- name: Vet Go code
timeout-minutes: 5
run: go vet ./...
security:
name: Security Scan
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- timeout-minutes: 3
uses: actions/checkout@v7
- timeout-minutes: 5
uses: actions/setup-go@v7
with:
go-version-file: "go.mod"
- name: Normalize Go toolchain env
timeout-minutes: 2
shell: bash
run: |
go env -u GOROOT || true
go env -u GOTOOLDIR || true
go env -u GOTOOLCHAIN || true
echo "GOCACHE=$RUNNER_TEMP/go-build-${{ github.run_id }}-${{ github.run_attempt }}" >> "$GITHUB_ENV"
echo "GOMODCACHE=$RUNNER_TEMP/go-mod-${{ github.run_id }}" >> "$GITHUB_ENV"
go version
go env GOROOT GOTOOLDIR GOVERSION GOOS GOARCH
- name: Install govulncheck
timeout-minutes: 5
run: go install golang.org/x/vuln/cmd/govulncheck@latest
- name: Go mod download
timeout-minutes: 5
run: |
for i in 1 2 3; do
go mod download && exit 0
echo "go mod download failed (attempt $i/3), retrying in 5s..."
sleep 5
done
exit 1
- name: Run govulncheck
timeout-minutes: 10
run: |
echo "Running Go vulnerability scan..."
~/go/bin/govulncheck ./...
test:
name: Test
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- timeout-minutes: 3
uses: actions/checkout@v7
- timeout-minutes: 5
uses: actions/setup-go@v7
with:
go-version-file: "go.mod"
- name: Normalize Go toolchain env
timeout-minutes: 2
shell: bash
run: |
go env -u GOROOT || true
go env -u GOTOOLDIR || true
go env -u GOTOOLCHAIN || true
echo "GOCACHE=$RUNNER_TEMP/go-build-${{ github.run_id }}-${{ github.run_attempt }}" >> "$GITHUB_ENV"
echo "GOMODCACHE=$RUNNER_TEMP/go-mod-${{ github.run_id }}" >> "$GITHUB_ENV"
go version
go env GOROOT GOTOOLDIR GOVERSION GOOS GOARCH
# Proto 代码无需本地生成
- name: Go mod download
timeout-minutes: 5
run: |
for i in 1 2 3; do
go mod download && exit 0
echo "go mod download failed (attempt $i/3), retrying in 5s..."
sleep 5
done
exit 1
- name: Prepare storage directory
timeout-minutes: 1
run: mkdir -p data/uploads
- name: Unit tests
timeout-minutes: 10
env:
DB_DRIVER: sqlite
DATABASE_URL: ":memory:"
STORAGE_DRIVER: file
STORAGE_BASE_DIR: data/uploads
run: |
# Only test internal packages (core business logic)
go test -count=1 -coverprofile=coverage.out -covermode=atomic ./internal/...
- name: Upload coverage to Codecov
timeout-minutes: 3
uses: codecov/codecov-action@v7
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: coverage.out
flags: server
fail_ci_if_error: ${{ github.event_name != 'pull_request' }}
verbose: true
disable_search: true
e2e:
name: E2E Tests
# Restored: uses the SQLite config so no external DB is needed. The earlier
# instability came from booting with configs/server.yaml (mysql/postgres)
# in a CI runner with no database service.
runs-on: ubuntu-latest
timeout-minutes: 30
needs: [test]
steps:
- timeout-minutes: 3
uses: actions/checkout@v7
- timeout-minutes: 5
uses: actions/setup-go@v7
with:
go-version-file: "go.mod"
- name: Normalize Go toolchain env
timeout-minutes: 2
shell: bash
run: |
go env -u GOROOT || true
go env -u GOTOOLDIR || true
go env -u GOTOOLCHAIN || true
echo "GOCACHE=$RUNNER_TEMP/go-build-${{ github.run_id }}-${{ github.run_attempt }}" >> "$GITHUB_ENV"
echo "GOMODCACHE=$RUNNER_TEMP/go-mod-${{ github.run_id }}" >> "$GITHUB_ENV"
go version
go env GOROOT GOTOOLDIR GOVERSION GOOS GOARCH
- name: Setup E2E scripts
timeout-minutes: 1
run: chmod +x scripts/e2e/*.sh
- name: Start Server (SQLite, no external DB)
timeout-minutes: 15
run: |
set -euo pipefail
go build -o bin/croupier-server ./cmd/server
# Build the agent registration probe so happy-path.sh can exercise
# the Agent→Server TCP handshake (Register + Heartbeat). Without it,
# the agent TCP step is skipped (./bin/e2e-agent-probe absent).
go build -o bin/e2e-agent-probe ./examples/cmd/e2e-agent-probe
# Function-seed helper: inserts the function metadata row that the
# task-lifecycle E2E's POST /tasks requires (no create API exists).
go build -o bin/e2e-function-seed ./examples/cmd/e2e-function-seed
# Each run owns an isolated directory under RUNNER_TEMP. Never
# delete repository data/ or test-data/: CI may run in a worktree
# containing useful local SQLite fixtures.
E2E_DIR="$RUNNER_TEMP/croupier-e2e-${{ github.run_id }}-${{ github.run_attempt }}"
mkdir -p "$E2E_DIR/uploads"
echo "E2E_DIR=$E2E_DIR" >> "$GITHUB_ENV"
echo "E2E_DSN=$E2E_DIR/croupier.db" >> "$GITHUB_ENV"
# Use the SQLite test config so the server boots without a database
# service. Admin/games are seeded from configs/*.json. Redirect
# output to a log file so failures (panic/migrate errors) are
# visible in the failed step instead of being lost to the background.
: > "$E2E_DIR/server.log"
DB_DRIVER=sqlite \
DATABASE_URL="$E2E_DIR/croupier.db" \
STORAGE_DRIVER=file \
STORAGE_BASE_DIR="$E2E_DIR/uploads" \
./bin/croupier-server --config configs/test-sqlite.yaml >> "$E2E_DIR/server.log" 2>&1 &
SERVER_PID=$!
echo "SERVER_PID=$SERVER_PID" >> $GITHUB_ENV
# Wait for server REST to be ready (deterministic readiness probe).
ready=0
for i in $(seq 1 60); do
if curl -sf http://localhost:18780/healthz > /dev/null; then
echo "Server is ready (after ${i}s)"
ready=1
break
fi
# If the server process already exited, it panicked — stop early.
if ! kill -0 "$SERVER_PID" 2>/dev/null; then
echo "::error::server process exited before becoming ready"
break
fi
sleep 1
done
if [ "$ready" -ne 1 ]; then
echo "::error::server did not become ready within 60s; server log:"
cat "$E2E_DIR/server.log"
exit 1
fi
- name: Run E2E tests
timeout-minutes: 10
env:
SERVER_URL: http://localhost:18780
DSN: ${{ env.E2E_DSN }}
run: |
bash scripts/e2e/happy-path.sh
bash scripts/e2e/task-lifecycle.sh
- name: Cleanup
timeout-minutes: 2
if: always()
run: |
if [ -n "${SERVER_PID:-}" ]; then
kill "$SERVER_PID" 2>/dev/null || true
fi
migrate-matrix:
name: Migration Matrix (MySQL/Postgres/SQLServer)
# Phase 4 of docs/architecture/database-migration-strategy.md: the
# versioned migration executor must work on all four dialects. SQLite is
# covered by the unit tests in internal/svc/migrations_test.go; this job
# runs the integration-tagged matrix against real MySQL, Postgres and
# SQL Server servers (fresh DB → baseline + catch-up, concurrent first
# boot proving the session lock, idempotent second boot).
runs-on: ubuntu-latest
timeout-minutes: 20
needs: [test]
services:
mysql:
image: mysql:8.4
env:
MYSQL_ROOT_PASSWORD: root
ports:
- 3306:3306
options: >-
--health-cmd "mysqladmin ping -h 127.0.0.1 -proot"
--health-interval 5s
--health-timeout 5s
--health-retries 20
postgres:
image: postgres:16
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
ports:
- 5432:5432
options: >-
--health-cmd "pg_isready -U postgres"
--health-interval 5s
--health-timeout 5s
--health-retries 20
mssql:
image: mcr.microsoft.com/mssql/server:2022-latest
env:
ACCEPT_EULA: "Y"
MSSQL_SA_PASSWORD: "YourStr0ngPassw0rd"
ports:
- 1433:1433
options: >-
--health-cmd "/opt/mssql-tools18/bin/sqlcmd -C -No -S 127.0.0.1 -U sa -P 'YourStr0ngPassw0rd' -Q 'SELECT 1'"
--health-interval 10s
--health-timeout 5s
--health-retries 30
env:
TEST_MYSQL_DSN: "root:root@tcp(127.0.0.1:3306)/"
TEST_POSTGRES_DSN: "postgres://postgres:postgres@127.0.0.1:5432/postgres?sslmode=disable"
TEST_SQLSERVER_DSN: "sqlserver://sa:YourStr0ngPassw0rd@127.0.0.1:1433"
steps:
- timeout-minutes: 3
uses: actions/checkout@v7
- timeout-minutes: 5
uses: actions/setup-go@v7
with:
go-version-file: "go.mod"
- name: Normalize Go toolchain env
timeout-minutes: 2
shell: bash
run: |
go env -u GOROOT || true
go env -u GOTOOLDIR || true
go env -u GOTOOLCHAIN || true
echo "GOCACHE=$RUNNER_TEMP/go-build-${{ github.run_id }}-${{ github.run_attempt }}" >> "$GITHUB_ENV"
echo "GOMODCACHE=$RUNNER_TEMP/go-mod-${{ github.run_id }}" >> "$GITHUB_ENV"
go version
go env GOROOT GOTOOLDIR GOVERSION GOOS GOARCH
- name: Go mod download
timeout-minutes: 5
run: |
for i in 1 2 3; do
go mod download && exit 0
echo "go mod download failed (attempt $i/3), retrying in 5s..."
sleep 5
done
exit 1
- name: Migration matrix tests
timeout-minutes: 10
run: |
go test -tags=integration -count=1 -timeout 8m \
-run 'TestMigrationMatrix' \
./internal/svc/ -v
- name: Validate migration directory (atlas)
# Community-edition atlas: verifies the atlas.sum checksum and file
# ordering of embedded SQL migrations. (Rule-based `migrate lint` is
# Pro-only since atlas v0.38.)
timeout-minutes: 5
uses: ariga/setup-atlas@v0
with:
cloud-token: ${{ secrets.ATLAS_CLOUD_TOKEN || '' }}
- name: atlas migrate validate
timeout-minutes: 3
run: |
atlas migrate validate --dir "file://internal/db/migrate/migrations" --dir-format goose