Add Phase 0 build verification gate (T-004)

This commit is contained in:
ila
2026-07-16 15:51:34 +08:00
parent 6f920eb457
commit 45c242ecec
10 changed files with 458 additions and 29 deletions
+23
View File
@@ -0,0 +1,23 @@
name: Phase 0 build gate
on:
push:
pull_request:
permissions: read-all
jobs:
verify:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
persist-credentials: false
- name: Set up Go 1.25
uses: actions/setup-go@v5
with:
go-version: "1.25.0"
cache: false
- name: Run Phase 0 verification
run: bash scripts/verify_phase0.sh
+6 -6
View File
@@ -45,12 +45,12 @@ SoftBox 软件盒子是一个使用 Go + Gio 开发的 Windows 桌面客户端,
## 当前阶段
当前项目处于:**MVP 起步(Phase 0 工程骨架建设中)**。
当前项目处于:**M1 已完成(Phase 0 工程骨架、双 Gio 窗口与双目标编译闸门已建立),准备进入 Phase 1 高风险原型**。
优先路径:
1. Phase 0:monorepo 骨架 + 双目标编译 + 空 Gio 窗口。
2. Phase 1:三大高风险原型(清单验签、ZIP 安全解压、原子切换回滚)。
1. 已完成 Phase 0:monorepo 骨架 + 双目标编译 + 空 Gio 窗口。
2. 下一步 Phase 1:三大高风险原型(清单验签、ZIP 安全解压、原子切换回滚)。
3. Phase 2-3:清单/列表 → 下载/安装。
4. Phase 4-5:启动/更新/自更新 → 授权。
5. Phase 6:Win7 加固与双通道发布。
@@ -133,17 +133,17 @@ MVP 不做:
## 验证命令
统一启动与验证入口收敛到根目录 `./init.sh` / `./init.ps1`;脚本会同步工作区依赖并运行 core 基础验证。标准命令:
统一启动与验证入口收敛到根目录 `./init.sh` / `./init.ps1`;脚本会同步工作区依赖并运行完整 Phase 0 闸门。也可直接运行 `bash scripts/verify_phase0.sh` / `./scripts/verify_phase0.ps1`。标准分项命令:
```bash
# core 测试(Linux 无头可跑)
cd core && go vet ./... && go test -count=1 ./...
# 现代版构建
cd app-modern && GOTOOLCHAIN=go1.25.0 GOOS=windows GOARCH=amd64 go build ./cmd/softbox
cd app-modern && GOTOOLCHAIN=go1.25.0 CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -trimpath -ldflags="-H=windowsgui" ./cmd/softbox
# Win7 版构建(强制 Go 1.20)
cd app-win7 && GOTOOLCHAIN=go1.20.14 GOOS=windows GOARCH=amd64 go build ./cmd/softbox
cd app-win7 && GOTOOLCHAIN=go1.20.14 CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -trimpath -ldflags="-H=windowsgui" ./cmd/softbox
```
说明:
+6 -4
View File
@@ -21,7 +21,7 @@
| Windows API | golang.org/x/sys/windows + 动态加载(LoadLibrary) | 已定 | Win10 专属 API 动态加载并降级,不进导入表 |
| EXE 签名 | Authenticode | 已定 | 主程序与 Updater 均签名;证书采购待确认 |
| 测试 | go test(core 无头可测) + fake/stub 注入 | 已定 | domain/application 不依赖 Gio 与 Windows API |
| CI | 待定(Gitea Actions 或本地脚本) | 待定 | 需同时编译 modern 与 win7 双目标 |
| CI | Gitea Actions 模板 + 本地 Phase 0 脚本 | 部分已定 | `.gitea/workflows/phase0-build.yml` 复用本地入口;远端 runner 可用性待确认 |
| 静态检查 | go vet(+ 待定 golangci-lint) | 部分已定 | vet 必跑;lint 工具后续确认 |
## 二、决策记录与演进
@@ -37,13 +37,15 @@
> 工程骨架由 T-001 建立;根目录 `init.sh`/`init.ps1` 统一执行依赖同步与 core 基础验证,并打印双目标构建命令。
| 用途 | 命令(计划) |
| 用途 | 命令 |
| --- | --- |
| Phase 0 完整闸门(Unix) | `bash scripts/verify_phase0.sh` |
| Phase 0 完整闸门(Windows) | `./scripts/verify_phase0.ps1` |
| 同步工作区依赖 | `go work sync` |
| core 测试 | `cd core && go test -count=1 ./...` |
| core 静态检查 | `cd core && go vet ./...` |
| 现代版构建 | `cd app-modern && GOTOOLCHAIN=go1.25.0 GOOS=windows GOARCH=amd64 go build -o ../dist/SoftBox.exe ./cmd/softbox` |
| Win7 版构建 | `cd app-win7 && GOTOOLCHAIN=go1.20.14 GOOS=windows GOARCH=amd64 go build -o ../dist/SoftBox-win7.exe ./cmd/softbox` |
| 现代版构建 | `cd app-modern && GOTOOLCHAIN=go1.25.0 CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -trimpath -ldflags="-H=windowsgui" -o ../dist/SoftBox.exe ./cmd/softbox` |
| Win7 版构建 | `cd app-win7 && GOTOOLCHAIN=go1.20.14 CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -trimpath -ldflags="-H=windowsgui" -o ../dist/SoftBox-win7.exe ./cmd/softbox` |
| 本地运行(开发) | Windows 下直接 `go run ./cmd/softbox`(WSL 中构建 EXE 后到 Windows 侧运行) |
根 `go.work` 纳入三个模块并使用 modern 所需的 Go 1.25 workspace 版本;`app-win7/go.work` 是就近的 Go 1.20 workspace,只纳入 `app-win7` 与 `core`,确保 Go 1.20.14 不需要解析 modern 模块。
+12 -15
View File
@@ -13,15 +13,15 @@
## 当前快照
- 日期:2026-07-16
- 阶段:MVP 起步(Phase 0 工程骨架建设中)
- 阶段:M1 已完成(Phase 0 工程骨架、状态/事件模型、双 Gio 窗口、平台 stub 与双目标验证闸门全部落地)
- 技术栈:根 Go workspace 纳入 core/app-modern/app-win7 三模块;`app-win7/go.work` 隔离 Go 1.20.14 构建;modern Gio v0.10.1 与 win7 Gio v0.6.0 已实际接入
- 生产代码:core 已有状态模型与事件 runtime;modern/win7 均可打开最小 AppShell,并有平台接口、Windows 实现与非 Windows stub
- 测试:core 覆盖状态/事件 runtime;两个 app 覆盖 AppShell 布局尺寸与平台 stub 契约
- 测试:core 覆盖状态/事件 runtime;两个 app 覆盖 AppShell 布局尺寸与平台 stub 契约;Phase 0 脚本统一执行全部验证
- 数据:无;Catalog 清单与测试样例待建
- 标准启动路径:`./init.sh` / `./init.ps1`(同步依赖、验证 core、打印 modern/win7 双目标构建命令)
- 标准验证路径:`go -C core vet ./...` + `go -C core test -count=1 ./...`;双目标构建命令见下文
- 标准启动路径:`./init.sh` / `./init.ps1`(同步依赖、执行完整 Phase 0 闸门、打印双目标构建命令)
- 标准验证路径:`bash scripts/verify_phase0.sh` / `./scripts/verify_phase0.ps1`
- 版本管理:git 已初始化,main 分支,远端 origin 为 Gitea `opc/soft_quay`;harness 文档已提交
- 当前 blocker:无;下一步按路线图落成并领取 T-004
- 当前 blocker:无;下一步按路线图落成并领取 T-101
## 当前目录要点
@@ -29,7 +29,7 @@
| --- | --- | --- |
| `docs/` | 已有 | harness coding 文档集(本次初始化完成) |
| `docs/tasks/` | 已有 | 任务目录;T-001 已完成,T-002 待按路线图落成 |
| `scripts/` | 已有 | harness 治理脚本 + `check_core_boundaries.py`;Phase 0 构建闸门待 T-004 |
| `scripts/` | 已有 | harness 治理、core 边界、Go 版本检查与 Phase 0 双平台验证入口 |
| `core/` | 已建 | Go 1.20 兼容共享模块;已有 domain 状态模型与 application 事件 runtime |
| `app-modern/` | 已建 | Go 1.25.0 + Gio v0.10.1;可打开 Modern AppShell |
| `app-win7/` | 已建 | Go 1.20 + Gio v0.6.0;可打开带 Legacy 标识的 AppShell |
@@ -40,23 +40,20 @@
任务状态以 `docs/tasks/` 各任务文件 frontmatter 的 `status` 为准。本节只写项目级摘要:
- 已完成:`T-001 初始化 monorepo 骨架`、`T-002 建立 domain 状态模型与事件总线`、`T-003 Gio 空窗口 + 平台层 stub`。
- 已完成:Phase 0 的 `T-001`、`T-002`、`T-003`、`T-004`。
- 正在进行:无。
- 下一个可领取任务:按路线图落成并领取 `T-004 CI 双目标编译闸门`。
- 下一个可领取任务:按路线图落成并领取 `T-101 签名清单验签与缓存回退原型`。
## 当前可运行内容
```bash
# 统一依赖同步 + core 验证:
# 统一依赖同步 + 完整 Phase 0 验证:
./init.sh
# Windows PowerShell 使用 ./init.ps1
# 独立验证:
go -C core vet ./...
go -C core test -count=1 ./...
python scripts/check_core_boundaries.py
GOTOOLCHAIN=go1.25.0 GOOS=windows GOARCH=amd64 go -C app-modern build ./cmd/softbox
GOTOOLCHAIN=go1.20.14 GOOS=windows GOARCH=amd64 go -C app-win7 build ./cmd/softbox
# 直接运行验证闸门:
bash scripts/verify_phase0.sh
# Windows PowerShell 使用 ./scripts/verify_phase0.ps1
```
## 开始编码前检查
+67
View File
@@ -0,0 +1,67 @@
---
id: T-004
title: 建立 Phase 0 双目标编译与依赖版本闸门
phase: 0
deps: [T-001]
status: DONE
created: 2026-07-16
issue: null
context_ref: 6f920eb4578c17c0962b6e593177cd2a3ca57f1b
claim_branch: null
work_branch: agent/codex/T-004
write_paths:
- docs/tasks/T-004.md
- scripts/check_go_versions.py
- scripts/verify_phase0.ps1
- scripts/verify_phase0.sh
- .gitea/workflows/phase0-build.yml
- init.ps1
- init.sh
- docs/00-ai-start-here.md
- docs/03-tech-stack.md
- docs/current-state.md
---
## 问题 / 背景
Phase 0 已有可编译骨架、core 状态/事件模型和两个 Gio 窗口,但验证命令仍分散在文档与人工操作中。需要一个可重复执行的本地/CI 闸门,防止 modern、Win7 或 core 兼容性在后续任务中悄然破坏。
## 方案
1. 新增 Windows PowerShell 与 Unix shell 两个等价入口,统一运行治理检查、core 边界检查、Go 1.20 core vet/test、modern UI/platform 测试与构建、win7 UI/platform 测试与构建。
2. 新增 Python 标准库依赖版本检查:校验 go/workspace 指令与 Gio 锁定版本,并用 Go 1.20.14 的 `go list -m -json all` 拒绝 core/win7 依赖声明 Go 1.21+。
3. Windows 构建统一使用 `CGO_ENABLED=0`、`-trimpath` 与 Windows GUI subsystem linker flag。
4. 根 init 脚本的 VERIFY 命令改为调用 Phase 0 闸门。
5. 新增 Gitea Actions workflow 模板,在 push/PR 使用同一 Unix 验证入口;runner 未启用时以本地同命令为验收证据。
## 验收要点
- `scripts/verify_phase0.ps1` 在当前 Windows 环境全绿。
- Git Bash `scripts/verify_phase0.sh` 在当前环境全绿。
- 闸门包含 core vet/test、core 边界、modern 构建、win7 Go 1.20.14 构建、UI/platform 测试和治理检查。
- 版本检查能拒绝 core/win7 的 Go 1.21+ 模块,并验证 Gio v0.10.1/v0.6.0 锁定。
- `.gitea/workflows/phase0-build.yml` 只读权限、关闭 checkout 凭据持久化,调用同一本地入口。
- `./init.ps1` 与 Git Bash `./init.sh` 通过新的完整 VERIFY 路径。
## 边界(不改什么)
- 不启用或配置远端 runner,不宣称远端 CI 已运行。
- 不升级 Go、Gio 或其他依赖版本。
- 不实现 Phase 1 业务功能。
- 不写入密钥、token 或真实发布配置。
## 协作约束
未启用 Gitea;本任务在 `agent/codex/T-004` 分支串行执行。CI 与本地必须复用同一脚本,不得维护两套不同验证逻辑。
## 执行记录
- 2026-07-16:新增 `scripts/verify_phase0.ps1` 与 `scripts/verify_phase0.sh`,统一运行治理、core 边界、Go 1.20 core vet/test、modern/win7 adapter 测试与双目标 GUI 构建。
- 2026-07-16:新增 `scripts/check_go_versions.py`,校验 root/core/modern/win7 的 go 指令与 Gio 锁定版本,并强制使用 Go 1.20.14 扫描 core/win7 完整模块图。
- 2026-07-16:版本检查确认 13 个模块记录均声明 Go 1.20 或更低;内置 self-check 明确接受 1.20、拒绝 1.21。
- 2026-07-16:Windows 构建统一使用 `CGO_ENABLED=0`、`-trimpath`、`-H=windowsgui`;根 init 脚本 VERIFY 已切换到完整 Phase 0 闸门。
- 2026-07-16:新增 `.gitea/workflows/phase0-build.yml`,使用只读权限、禁用 checkout 凭据持久化并复用 Unix 本地入口。远端 runner 未启用/未验证,不宣称远端 CI 已跑绿。
- 验证通过:`./scripts/verify_phase0.ps1`。
- 验证通过:Git Bash `bash scripts/verify_phase0.sh`。
- 验证通过:`./init.ps1` 与 Git Bash `./init.sh`,均执行完整 Phase 0 闸门。
- 验证结果:core Go 1.20.14 vet/test、modern Go 1.25.0 Windows amd64 GUI 构建、win7 Go 1.20.14 Windows amd64 GUI 构建、两个 adapter 测试、治理与边界检查全部通过。
+5 -2
View File
@@ -7,11 +7,14 @@
# 三个命令是仓库统一入口;换工具链时同步更新文档与这里。
$ErrorActionPreference = "Stop"
$Utf8 = [System.Text.UTF8Encoding]::new($false)
[Console]::OutputEncoding = $Utf8
$OutputEncoding = $Utf8
Set-Location -Path $PSScriptRoot
$InstallCmd = "go work sync"
$VerifyCmd = 'go -C core vet ./...; if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }; go -C core test -count=1 ./...'
$StartCmd = '$env:GOTOOLCHAIN="go1.25.0"; $env:GOOS="windows"; $env:GOARCH="amd64"; go build -C app-modern -o ../dist/SoftBox.exe ./cmd/softbox; if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }; $env:GOTOOLCHAIN="go1.20.14"; go build -C app-win7 -o ../dist/SoftBox-win7.exe ./cmd/softbox'
$VerifyCmd = "./scripts/verify_phase0.ps1"
$StartCmd = '$env:CGO_ENABLED="0"; $env:GOOS="windows"; $env:GOARCH="amd64"; $env:GOTOOLCHAIN="go1.25.0"; go build -C app-modern -trimpath "-ldflags=-H=windowsgui" -o ../dist/SoftBox.exe ./cmd/softbox; if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }; $env:GOTOOLCHAIN="go1.20.14"; go build -C app-win7 -trimpath "-ldflags=-H=windowsgui" -o ../dist/SoftBox-win7.exe ./cmd/softbox'
Write-Host "==> 当前目录: $($PWD.Path)"
+2 -2
View File
@@ -12,8 +12,8 @@ ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$ROOT_DIR"
INSTALL_CMD="go work sync"
VERIFY_CMD="go -C core vet ./... && go -C core test -count=1 ./..."
START_CMD="GOTOOLCHAIN=go1.25.0 GOOS=windows GOARCH=amd64 go -C app-modern build -o ../dist/SoftBox.exe ./cmd/softbox && GOTOOLCHAIN=go1.20.14 GOOS=windows GOARCH=amd64 go -C app-win7 build -o ../dist/SoftBox-win7.exe ./cmd/softbox"
VERIFY_CMD="bash scripts/verify_phase0.sh"
START_CMD="GOTOOLCHAIN=go1.25.0 CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go -C app-modern build -trimpath -ldflags=-H=windowsgui -o ../dist/SoftBox.exe ./cmd/softbox && GOTOOLCHAIN=go1.20.14 CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go -C app-win7 build -trimpath -ldflags=-H=windowsgui -o ../dist/SoftBox-win7.exe ./cmd/softbox"
echo "==> 当前目录: $PWD"
+179
View File
@@ -0,0 +1,179 @@
#!/usr/bin/env python3
"""Validate toolchain pins and Go 1.20 compatibility of core/win7 modules."""
import json
import os
import pathlib
import re
import subprocess
import sys
MAX_LEGACY_GO_VERSION = (1, 20)
def version_tuple(value):
match = re.fullmatch(r"(\d+)\.(\d+)(?:\.(\d+))?", value)
if not match:
raise ValueError("invalid Go version {!r}".format(value))
return tuple(int(part or 0) for part in match.groups())
def decode_json_stream(text):
decoder = json.JSONDecoder()
index = 0
while index < len(text):
while index < len(text) and text[index].isspace():
index += 1
if index >= len(text):
return
value, index = decoder.raw_decode(text, index)
yield value
def read_text(path):
return path.read_text(encoding="utf-8")
def go_directive(path):
match = re.search(r"(?m)^go\s+(\d+\.\d+(?:\.\d+)?)\s*$", read_text(path))
if not match:
raise ValueError("{} has no go directive".format(path))
return match.group(1)
def required_version(path, module_path):
pattern = r"(?m)^\s*{}\s+(v[^\s]+)".format(re.escape(module_path))
match = re.search(pattern, read_text(path))
if not match:
raise ValueError(
"{} does not require {}".format(path, module_path)
)
return match.group(1)
def run_go(repo_root, cwd, arguments, go_work):
environment = os.environ.copy()
environment["GOWORK"] = str(go_work) if go_work else "off"
result = subprocess.run(
["go"] + arguments,
cwd=str(cwd),
env=environment,
check=False,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
universal_newlines=True,
)
if result.returncode != 0:
print(result.stderr, file=sys.stderr, end="")
raise SystemExit(result.returncode)
return result.stdout
def validate_pins(repo_root):
expected_go_directives = {
repo_root / "go.work": "1.25.0",
repo_root / "core" / "go.mod": "1.20",
repo_root / "app-modern" / "go.mod": "1.25.0",
repo_root / "app-win7" / "go.mod": "1.20",
repo_root / "app-win7" / "go.work": "1.20",
}
violations = []
for path, expected in expected_go_directives.items():
actual = go_directive(path)
if actual != expected:
violations.append(
"{} go directive is {}, want {}".format(
path.relative_to(repo_root), actual, expected
)
)
gio_pins = {
repo_root / "app-modern" / "go.mod": "v0.10.1",
repo_root / "app-win7" / "go.mod": "v0.6.0",
}
for path, expected in gio_pins.items():
actual = required_version(path, "gioui.org")
if actual != expected:
violations.append(
"{} pins gioui.org {}, want {}".format(
path.relative_to(repo_root), actual, expected
)
)
return violations
def validate_go20_toolchain(repo_root):
output = run_go(repo_root, repo_root, ["version"], None).strip()
if "go1.20.14" not in output:
return ["compatibility scan uses {!r}, want go1.20.14".format(output)]
return []
def validate_module_versions(repo_root):
module_sets = (
("core", repo_root / "core", None),
(
"win7",
repo_root / "app-win7",
repo_root / "app-win7" / "go.work",
),
)
violations = []
checked = 0
for label, cwd, go_work in module_sets:
output = run_go(
repo_root,
cwd,
["list", "-m", "-json", "all"],
go_work,
)
for module in decode_json_stream(output):
checked += 1
go_version = module.get("GoVersion")
if not go_version:
continue
if version_tuple(go_version)[:2] > MAX_LEGACY_GO_VERSION:
violations.append(
"{} module {} declares go {}, exceeds 1.20".format(
label, module["Path"], go_version
)
)
return violations, checked
def self_check():
if version_tuple("1.20")[:2] > MAX_LEGACY_GO_VERSION:
raise AssertionError("Go 1.20 should be accepted")
if version_tuple("1.20.14")[:2] > MAX_LEGACY_GO_VERSION:
raise AssertionError("Go 1.20.14 should be accepted")
if not version_tuple("1.21")[:2] > MAX_LEGACY_GO_VERSION:
raise AssertionError("Go 1.21 should be rejected")
def main():
self_check()
repo_root = pathlib.Path(__file__).resolve().parents[1]
violations = validate_pins(repo_root)
violations.extend(validate_go20_toolchain(repo_root))
module_violations, checked = validate_module_versions(repo_root)
violations.extend(module_violations)
if violations:
for violation in violations:
print("ERROR: " + violation, file=sys.stderr)
raise SystemExit(1)
print(
"Go version check passed: pins valid; {} module records are Go 1.20-compatible.".format(
checked
)
)
if __name__ == "__main__":
main()
+95
View File
@@ -0,0 +1,95 @@
#!/usr/bin/env pwsh
$ErrorActionPreference = "Stop"
$Utf8 = [System.Text.UTF8Encoding]::new($false)
[Console]::OutputEncoding = $Utf8
$OutputEncoding = $Utf8
$Root = Split-Path -Parent $PSScriptRoot
Set-Location -Path $Root
function Assert-NativeSuccess {
param([string]$Step)
if ($LASTEXITCODE -ne 0) {
throw "$Step failed with exit code $LASTEXITCODE"
}
}
function Invoke-Step {
param(
[string]$Name,
[scriptblock]$Command
)
Write-Host "==> $Name"
& $Command
Assert-NativeSuccess -Step $Name
}
$GoPath = (& go env GOPATH).Trim()
Assert-NativeSuccess -Step "Locate GOPATH"
$GoBin = Join-Path $GoPath "bin"
if (Test-Path (Join-Path $GoBin "go1.20.14.exe")) {
$env:PATH = "$GoBin;$env:PATH"
}
New-Item -ItemType Directory -Force -Path (Join-Path $Root "dist") | Out-Null
Invoke-Step "Sync root workspace" {
$env:GOTOOLCHAIN = "go1.25.0"
Remove-Item Env:GOWORK -ErrorAction SilentlyContinue
go work sync
}
Invoke-Step "Validate harness governance" {
python scripts/validate_agent_context.py
Assert-NativeSuccess -Step "Validate agent context"
python -m unittest discover -s tests -p "test_*.py"
Assert-NativeSuccess -Step "Run governance tests"
python scripts/validate_harness_governance.py
}
Invoke-Step "Validate core architecture boundary" {
python scripts/check_core_boundaries.py --self-test
Assert-NativeSuccess -Step "Self-test core boundary matcher"
python scripts/check_core_boundaries.py
}
Invoke-Step "Validate Go and dependency pins" {
$env:GOTOOLCHAIN = "go1.20.14"
python scripts/check_go_versions.py
}
Invoke-Step "Vet and test core with Go 1.20.14" {
$env:GOTOOLCHAIN = "go1.20.14"
$env:GOWORK = "off"
go -C core vet ./...
Assert-NativeSuccess -Step "Vet core"
go -C core test -count=1 ./...
}
Invoke-Step "Test and build modern target with Go 1.25.0" {
$env:GOTOOLCHAIN = "go1.25.0"
$env:GOWORK = (Resolve-Path "go.work").Path
Remove-Item Env:GOOS -ErrorAction SilentlyContinue
Remove-Item Env:GOARCH -ErrorAction SilentlyContinue
$env:CGO_ENABLED = "0"
go -C app-modern test -count=1 ./ui/gio ./platform/windows
Assert-NativeSuccess -Step "Test modern adapters"
$env:GOOS = "windows"
$env:GOARCH = "amd64"
go -C app-modern build -trimpath "-ldflags=-H=windowsgui" -o ../dist/SoftBox.exe ./cmd/softbox
}
Invoke-Step "Test and build Win7 target with Go 1.20.14" {
$env:GOTOOLCHAIN = "go1.20.14"
$env:GOWORK = (Resolve-Path "app-win7/go.work").Path
Remove-Item Env:GOOS -ErrorAction SilentlyContinue
Remove-Item Env:GOARCH -ErrorAction SilentlyContinue
$env:CGO_ENABLED = "0"
go -C app-win7 test -count=1 ./ui/gio ./platform/windows
Assert-NativeSuccess -Step "Test Win7 adapters"
$env:GOOS = "windows"
$env:GOARCH = "amd64"
go -C app-win7 build -trimpath "-ldflags=-H=windowsgui" -o ../dist/SoftBox-win7.exe ./cmd/softbox
}
Write-Host "Phase 0 verification passed."
+63
View File
@@ -0,0 +1,63 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$ROOT_DIR"
if python3 --version >/dev/null 2>&1; then
PYTHON=python3
elif python --version >/dev/null 2>&1; then
PYTHON=python
else
echo "ERROR: Python 3 is required." >&2
exit 2
fi
GO_PATH="$(go env GOPATH)"
if command -v cygpath >/dev/null 2>&1; then
GO_PATH="$(cygpath -u "$GO_PATH")"
fi
GO_BIN="$GO_PATH/bin"
if [ -x "$GO_BIN/go1.20.14" ] || [ -x "$GO_BIN/go1.20.14.exe" ]; then
export PATH="$GO_BIN:$PATH"
fi
mkdir -p dist
echo "==> Sync root workspace"
GOTOOLCHAIN=go1.25.0 go work sync
echo "==> Validate harness governance"
"$PYTHON" scripts/validate_agent_context.py
"$PYTHON" -m unittest discover -s tests -p "test_*.py"
"$PYTHON" scripts/validate_harness_governance.py
echo "==> Validate core architecture boundary"
"$PYTHON" scripts/check_core_boundaries.py --self-test
"$PYTHON" scripts/check_core_boundaries.py
echo "==> Validate Go and dependency pins"
GOTOOLCHAIN=go1.20.14 "$PYTHON" scripts/check_go_versions.py
echo "==> Vet and test core with Go 1.20.14"
GOTOOLCHAIN=go1.20.14 GOWORK=off go -C core vet ./...
GOTOOLCHAIN=go1.20.14 GOWORK=off go -C core test -count=1 ./...
echo "==> Test and build modern target with Go 1.25.0"
GOTOOLCHAIN=go1.25.0 GOWORK="$ROOT_DIR/go.work" CGO_ENABLED=0 \
go -C app-modern test -count=1 ./ui/gio ./platform/windows
GOTOOLCHAIN=go1.25.0 GOWORK="$ROOT_DIR/go.work" CGO_ENABLED=0 \
GOOS=windows GOARCH=amd64 \
go -C app-modern build -trimpath -ldflags="-H=windowsgui" \
-o ../dist/SoftBox.exe ./cmd/softbox
echo "==> Test and build Win7 target with Go 1.20.14"
GOTOOLCHAIN=go1.20.14 GOWORK="$ROOT_DIR/app-win7/go.work" CGO_ENABLED=0 \
go -C app-win7 test -count=1 ./ui/gio ./platform/windows
GOTOOLCHAIN=go1.20.14 GOWORK="$ROOT_DIR/app-win7/go.work" CGO_ENABLED=0 \
GOOS=windows GOARCH=amd64 \
go -C app-win7 build -trimpath -ldflags="-H=windowsgui" \
-o ../dist/SoftBox-win7.exe ./cmd/softbox
echo "Phase 0 verification passed."