feat(builder): query CI via project status script
When BUILD_VENUE=ci, init confirms tea/glab/gh/curl (or a custom command) and writes .pouch/builder/ci-status.sh. wait_ci.sh only polls that script and no longer guesses forge CLIs.
This commit is contained in:
@@ -112,6 +112,9 @@ class BuilderCheckTests(unittest.TestCase):
|
||||
self.assertIn("copy_artifact.sh", skill)
|
||||
self.assertIn("android", skill.lower())
|
||||
self.assertIn("COPY_DEST", contract)
|
||||
self.assertIn("init_ci_status.sh", skill)
|
||||
self.assertIn("CI_STATUS_SCRIPT", contract)
|
||||
self.assertIn("ci-status.md", skill)
|
||||
|
||||
def test_no_makefile_without_ready_is_usage_error(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as temp:
|
||||
@@ -213,28 +216,62 @@ class BuilderCheckTests(unittest.TestCase):
|
||||
self.assertIn("[FAIL] 10. 轨道工具链", text)
|
||||
self.assertIn("docker: MISSING", text)
|
||||
|
||||
def test_ready_uses_curl_for_gitea_actions(self) -> None:
|
||||
def test_ready_ci_requires_status_script(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as temp:
|
||||
project = Path(temp)
|
||||
init_repo(project)
|
||||
write_contract_makefile(project)
|
||||
(project / "Dockerfile").write_text("FROM scratch\n", encoding="utf-8")
|
||||
git(project, "remote", "add", "origin", "https://gitea.example.test/acme/widget.git")
|
||||
code, text = run_check(
|
||||
project,
|
||||
"--ready",
|
||||
env={"BUILD_VENUE": "ci"},
|
||||
which={
|
||||
"docker": "/usr/bin/docker",
|
||||
"curl": "/usr/bin/curl",
|
||||
"curl": None,
|
||||
"gh": None,
|
||||
"glab": None,
|
||||
"tea": None,
|
||||
},
|
||||
)
|
||||
self.assertEqual(code, 1, text)
|
||||
self.assertIn("[FAIL] 15. CI_STATUS_SCRIPT 可执行", text)
|
||||
self.assertIn("does not point to a file", text)
|
||||
self.assertIn("CI status: project CI_STATUS_SCRIPT", text)
|
||||
self.assertNotIn("curl: found", text)
|
||||
self.assertNotIn("Gitea API", text)
|
||||
|
||||
def test_ready_ci_passes_with_executable_status_script(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as temp:
|
||||
project = Path(temp)
|
||||
init_repo(project)
|
||||
write_contract_makefile(project)
|
||||
(project / "Dockerfile").write_text("FROM scratch\n", encoding="utf-8")
|
||||
script = project / ".pouch" / "builder" / "ci-status.sh"
|
||||
script.parent.mkdir(parents=True)
|
||||
script.write_text("#!/bin/sh\necho STATUS=empty\n", encoding="utf-8")
|
||||
script.chmod(0o755)
|
||||
code, text = run_check(
|
||||
project,
|
||||
"--ready",
|
||||
env={"BUILD_VENUE": "ci"},
|
||||
which={"docker": "/usr/bin/docker", "curl": None, "gh": None, "glab": None},
|
||||
)
|
||||
self.assertEqual(code, 0, text)
|
||||
self.assertIn("curl: found", text)
|
||||
self.assertIn("Gitea API: /api/v1", text)
|
||||
self.assertNotIn("glab: ", text)
|
||||
self.assertIn("[PASS] 15. CI_STATUS_SCRIPT 可执行", text)
|
||||
self.assertIn("CI status: project CI_STATUS_SCRIPT", text)
|
||||
|
||||
def test_ready_local_skips_status_script(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as temp:
|
||||
project = Path(temp)
|
||||
init_repo(project)
|
||||
write_contract_makefile(project)
|
||||
code, text = run_check(
|
||||
project, "--ready", which={"dpkg-deb": "/usr/bin/dpkg-deb"}
|
||||
)
|
||||
self.assertEqual(code, 0, text)
|
||||
self.assertIn("[SKIP] 15. CI_STATUS_SCRIPT 可执行", text)
|
||||
self.assertIn("BUILD_VENUE is not ci", text)
|
||||
|
||||
def test_user_makefile_does_not_satisfy_contract(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as temp:
|
||||
|
||||
Reference in New Issue
Block a user