feat(builder): Android/iOS 构建与 copy_artifact 发布

新增 APK/IPA 轨道和 copy_artifact.sh(本地目录或 container:/dir)。
push 必须委托该脚本,禁止在 makefile 里内联 docker cp。
This commit is contained in:
2026-09-09 01:13:56 +08:00
parent aa7a265e76
commit 2ba027098f
10 changed files with 618 additions and 37 deletions
+58
View File
@@ -109,6 +109,9 @@ class BuilderCheckTests(unittest.TestCase):
self.assertIn("ARCHES", readme)
self.assertIn("amd64 arm64", readme)
self.assertIn("多架构", readme)
self.assertIn("copy_artifact.sh", skill)
self.assertIn("android", skill.lower())
self.assertIn("COPY_DEST", contract)
def test_no_makefile_without_ready_is_usage_error(self) -> None:
with tempfile.TemporaryDirectory() as temp:
@@ -406,6 +409,61 @@ class BuilderCheckTests(unittest.TestCase):
self.assertIn("Platform: linux/amd64", overridden.stdout)
self.assertNotIn("linux/arm64", overridden.stdout)
def test_android_copy_makefile_skips_missing_copy_dest(self) -> None:
template = REPO_ROOT / "skills" / "builder" / "templates" / "makefile.android.builder"
with tempfile.TemporaryDirectory() as temp:
project = Path(temp)
init_repo(project)
text = template.read_text(encoding="utf-8")
text = text.replace(
"include $(HOME)/.pouch/skills/builder/scripts/version.mk",
f"include {SCRIPTS / 'version.mk'}",
)
(project / "makefile.builder").write_text(text, encoding="utf-8")
code, out = run_check(project, "--ready")
self.assertEqual(code, 0, out)
self.assertIn("[PASS] 12. android 目标产物形状与纯构建", out)
self.assertIn("[SKIP] 13. ios 目标产物形状与纯构建", out)
self.assertIn("COPY_DEST: MISSING", out)
self.assertIn("blocks publish, not build", out)
def test_inline_docker_cp_in_push_fails(self) -> None:
with tempfile.TemporaryDirectory() as temp:
project = Path(temp)
init_repo(project)
(project / "makefile.builder").write_text(
"\n".join(
[
"ARCHES ?= amd64",
"ARCH ?= amd64",
"ifneq ($(filter $(ARCH),$(ARCHES)),$(ARCH))",
"$(error ARCH must be one of: $(ARCHES))",
"endif",
"DIST_DIR ?= dist",
f"include {SCRIPTS / 'version.mk'}",
".PHONY: help version arches clean build push",
"help:",
"\t@echo app $(VERSION)",
"version:",
"\t@echo $(VERSION)",
"arches:",
"\t@echo $(ARCHES)",
"clean:",
"\trm -rf $(DIST_DIR)",
"build:",
"\tmkdir -p $(DIST_DIR)/$(ARCH).apk",
"push:",
"\tdocker cp dist/app.apk file-server:/srv/app.apk",
"",
]
),
encoding="utf-8",
)
code, out = run_check(project, "--ready")
self.assertEqual(code, 1, out)
self.assertIn("[FAIL] 7. push 仅委托 builder 脚本", out)
self.assertIn("docker cp", out)
if __name__ == "__main__":
unittest.main()