Skip to content

fix(sqlite): scan json text columns safely #61

fix(sqlite): scan json text columns safely

fix(sqlite): scan json text columns safely #61

Workflow file for this run

name: uat-bypass
# Phase 47 Plan 03 BYPASS-VERIFY-02/03/04:v3.5 白名单 fail-closed CI 守护。
#
# 工作流分两层:
#
# 1. lint — 永远跑:bash -n、--help、--dry-run 6 场景全过。
# 这一步在 ubuntu runner 不需要 nft/docker/sudo,只验证脚本本身。
#
# 2. uat — 真实 6 场景 × ubuntu-24.04 矩阵。
# fixture 脚本(scripts/uat-bypass-fixture-up.sh,需要起完整控制面
# + 颁发 admin token + 起带 sing-box gateway 的 bypass host)在
# Phase 47 verification 之后才会落地。本 job 通过 preflight step
# 检测 fixture 是否存在:
# - 存在 → 完整跑 6 场景断言 I1–I10。
# - 缺失 → 显式 SKIP(脚本 exit 2,被 continue-on-error 吞下),
# 仍记录为绿色,但 Summary 里能看到 "fixture missing"。
# 这样既能在 fixture 合入后 CI 立刻生效守护 ROADMAP SC#5,
# 又不会在 fixture 缺失阶段假阳性阻塞 PR。
#
# 通过这种分层,PR 阶段能立刻 catch 脚本回归(如 bash 语法、--dry-run 退出码),
# 也能在 fixture 合入后零配置切换到真实 CI 守护。
on:
pull_request:
paths:
- "internal/network/**"
- "internal/runtime/tasks/**"
- "internal/controlplane/http/admin_bypass*"
- "scripts/uat-bypass.sh"
- ".github/workflows/uat-bypass.yml"
push:
branches: [main]
permissions:
contents: read
concurrency:
group: uat-bypass-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
lint:
name: lint + dry-run 6 scenarios
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install minimal tools (jq / curl)
run: |
sudo apt-get update -y
sudo apt-get install -y jq curl
- name: bash -n (syntax)
run: bash -n scripts/uat-bypass.sh
- name: --help contains 6 scenarios + I1..I10
run: |
set -euo pipefail
OUT=$(bash scripts/uat-bypass.sh --help)
SCEN_COUNT=$(echo "$OUT" | grep -cE 'loopback-only|lan-only|loopback-lan|custom-ip|custom-domain|fail-closed-pkill')
INV_COUNT=$(echo "$OUT" | grep -cE 'I[0-9]')
echo "scenario references: $SCEN_COUNT"
echo "invariant references: $INV_COUNT"
test "$SCEN_COUNT" -ge 6
test "$INV_COUNT" -ge 10
- name: --dry-run all 6 scenarios
run: |
set -euo pipefail
for s in loopback-only lan-only loopback-lan custom-ip custom-domain fail-closed-pkill; do
echo "=== dry-run scenario=$s ==="
bash scripts/uat-bypass.sh \
--scenario="$s" \
--target-host-id=ci-dryrun \
--admin-token=ci-dryrun \
--dry-run
done
uat:
name: uat scenario=${{ matrix.scenario }}
runs-on: ubuntu-24.04
needs: lint
strategy:
fail-fast: false
matrix:
scenario:
- loopback-only
- lan-only
- loopback-lan
- custom-ip
- custom-domain
- fail-closed-pkill
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Preflight — check fixture script availability
id: preflight
run: |
if [ -f scripts/uat-bypass-fixture-up.sh ]; then
echo "fixture_available=true" >> "$GITHUB_OUTPUT"
echo "[INFO] scripts/uat-bypass-fixture-up.sh 存在,将跑完整 uat 流程"
else
echo "fixture_available=false" >> "$GITHUB_OUTPUT"
echo "::warning::scripts/uat-bypass-fixture-up.sh 缺失,本次 uat job 仅 lint job 已守护脚本回归;完整 6 场景断言留待 fixture 落地"
fi
- name: Install prerequisites
if: steps.preflight.outputs.fixture_available == 'true'
run: |
sudo apt-get update -y
sudo apt-get install -y nftables tcpdump jq dnsutils curl
- name: Setup Go
if: steps.preflight.outputs.fixture_available == 'true'
uses: actions/setup-go@v5
with:
go-version-file: go.mod
cache: true
- name: Build control plane
if: steps.preflight.outputs.fixture_available == 'true'
run: go build -o /tmp/cloud-cli-proxy ./cmd/control-plane
- name: Bring up bypass fixture
if: steps.preflight.outputs.fixture_available == 'true'
run: |
# scripts/uat-bypass-fixture-up.sh 必须输出 /tmp/uat-fixture.json
# 含 host_id + admin_token 两个字段(fixture 契约)。
bash scripts/uat-bypass-fixture-up.sh
echo "HOST_ID=$(jq -r '.host_id' /tmp/uat-fixture.json)" >> "$GITHUB_ENV"
echo "ADMIN_TOKEN=$(jq -r '.admin_token' /tmp/uat-fixture.json)" >> "$GITHUB_ENV"
- name: Run uat-bypass scenario=${{ matrix.scenario }}
if: steps.preflight.outputs.fixture_available == 'true'
env:
CLOUD_CLI_PROXY_ADMIN_TOKEN: ${{ env.ADMIN_TOKEN }}
CLOUD_CLI_PROXY_API_BASE: http://localhost:8080
run: |
bash scripts/uat-bypass.sh \
--scenario=${{ matrix.scenario }} \
--target-host-id="$HOST_ID"
- name: Teardown fixture
if: always() && steps.preflight.outputs.fixture_available == 'true'
run: |
if [ -f scripts/uat-bypass-fixture-down.sh ]; then
bash scripts/uat-bypass-fixture-down.sh
else
bash scripts/test-fixture-down.sh || true
fi