Archived
KofTwentyTwo/ci-policy: ci / fork-guard (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / go-0 (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / go-nix-1 (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / gradle-2 (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / gradle-3 (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / java-docker-4 (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / java-maven-5 (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / manifests-6 (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / nix-7 (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / node-8 (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / python-9 (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / rust-10 (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / rust-11 (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / rust-12 (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / source-config-13 (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / source-config-14 (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / image-build-0 (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / image-build-1 (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / image-build-2 (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / image-build-3 (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / image-build-4 (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / image-build-5 (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / image-build-6 (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / image-build-7 (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / not-enrolled (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / content-validate-0 (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / standards-0 (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / node-matrix-0 (pull_request) Skipped
KofTwentyTwo/ci-policy: ci / source-config-15 (pull_request) Blocked by required conditions
KofTwentyTwo/ci-policy: Shared source and config CI / verify (pull_request) Blocked by required conditions
KofTwentyTwo/ci-policy: Shared source and config CI / secrets (pull_request) Blocked by required conditions
KofTwentyTwo/ci-policy: Shared source and config CI / gate (pull_request) Waiting for needed jobs
KofTwentyTwo/ci-policy: ci / ci-result (pull_request) Waiting for needed jobs
KofTwentyTwo/ci-policy: native / fork-deny (pull_request) Skipped
KofTwentyTwo/ci-policy: native / build-macos-0 (pull_request) Skipped
KofTwentyTwo/ci-policy: native / build-macos-1 (pull_request) Skipped
KofTwentyTwo/ci-policy: native / build-macos-2 (pull_request) Skipped
KofTwentyTwo/ci-policy: native / build-macos-3 (pull_request) Skipped
KofTwentyTwo/ci-policy: native / build-windows-4 (pull_request) Skipped
KofTwentyTwo/ci-policy: native / build-windows-5 (pull_request) Skipped
KofTwentyTwo/ci-policy: native / build-windows-6 (pull_request) Skipped
KofTwentyTwo/ci-policy: native / build-windows-7 (pull_request) Skipped
KofTwentyTwo/ci-policy: native / dotnet-8 (pull_request) Skipped
KofTwentyTwo/ci-policy: native / dotnet-9 (pull_request) Skipped
KofTwentyTwo/ci-policy: native / dotnet-10 (pull_request) Skipped
KofTwentyTwo/ci-policy: native / dotnet-11 (pull_request) Skipped
KofTwentyTwo/ci-policy: native / swift-12 (pull_request) Skipped
KofTwentyTwo/ci-policy: native / swift-13 (pull_request) Skipped
KofTwentyTwo/ci-policy: native / swift-14 (pull_request) Skipped
KofTwentyTwo/ci-policy: native / swift-15 (pull_request) Skipped
KofTwentyTwo/ci-policy: native / swift-16 (pull_request) Skipped
KofTwentyTwo/ci-policy: native / swift-17 (pull_request) Skipped
KofTwentyTwo/ci-policy: native / swift-18 (pull_request) Skipped
KofTwentyTwo/ci-policy: native / swift-19 (pull_request) Skipped
KofTwentyTwo/ci-policy: native / native-result (pull_request) Canceled after 6s
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
104 lines
5.5 KiB
Python
104 lines
5.5 KiB
Python
"""The `script` tool runs a checked-in program in one declared runtime: control (the default), java or node.
|
|
|
|
NOT YET RUN: written with the integration of the script-toolchain patch while test execution was suspended.
|
|
"""
|
|
|
|
import tempfile
|
|
import unittest
|
|
from pathlib import Path
|
|
from typing import Any, cast
|
|
|
|
from platform_ci.build_inputs import compute_build_inputs
|
|
from platform_ci.build_tools import BUILD_TOOLS
|
|
from platform_ci.caching import cache_family, cache_unsupported_reason
|
|
from platform_ci.configuration import ConfigurationError, parse_project_configuration
|
|
from platform_ci.execution import run_target_commands
|
|
from platform_ci.plan import Target
|
|
from tests.support import JAVA_IMAGE, NODE_IMAGE, SOURCE_TREE, event, plan_for
|
|
|
|
|
|
def script_configuration(toolchains: dict[str, str], **component: object) -> dict[str, object]:
|
|
"""A one-component `script` configuration."""
|
|
body: dict[str, object] = {"toolchains": toolchains, "build": {"tool": "script", "commands": [["./scripts/ci/check.sh", "argument"]]}, **component}
|
|
return {"schema": 1, "components": {"checks": body}}
|
|
|
|
|
|
def planned(toolchains: dict[str, str], **component: object) -> Target:
|
|
"""Plan one script component against the test catalog and return its target."""
|
|
return plan_for(parse_project_configuration(script_configuration(toolchains, **component)), event())["targets"][0]
|
|
|
|
|
|
class ScriptToolchainConfigurationTest(unittest.TestCase):
|
|
"""Exactly one declared toolchain of the closed set is accepted."""
|
|
|
|
def test_java_and_node_select_their_catalog_images_and_control_stays_the_default(self) -> None:
|
|
java = planned({"java": "21"})
|
|
self.assertEqual((java["toolchain"], java["image"], java["commands"]), ("java", JAVA_IMAGE, [["./scripts/ci/check.sh", "argument"]]))
|
|
self.assertIn("Java 21", java["display"])
|
|
node = planned({"node": "22.20.0"})
|
|
self.assertEqual((node["toolchain"], node["image"]), ("node", NODE_IMAGE))
|
|
self.assertEqual(BUILD_TOOLS["script"].toolchain, "control")
|
|
|
|
def test_zero_two_and_unknown_toolchains_are_rejected(self) -> None:
|
|
for name, toolchains in {"none": {}, "two": {"java": "21", "node": "22.20.0"}, "unknown": {"go": "1"}}.items():
|
|
with self.subTest(name), self.assertRaises(ConfigurationError):
|
|
parse_project_configuration(script_configuration(toolchains))
|
|
|
|
def test_other_tools_still_take_only_their_own_toolchain(self) -> None:
|
|
configuration = {"schema": 1, "components": {"library": {"toolchains": {"node": "22.20.0"}, "build": {"tool": "maven", "arguments": ["verify"]}}}}
|
|
with self.assertRaises(ConfigurationError):
|
|
parse_project_configuration(configuration)
|
|
|
|
def test_the_docker_profile_and_a_program_outside_the_component_are_handled_like_other_tools(self) -> None:
|
|
self.assertEqual(parse_project_configuration(script_configuration({"java": "21"}, requires=["docker"])).components[0].requires, ("docker",))
|
|
bad = script_configuration({"java": "21"})
|
|
cast("dict[str, Any]", cast("dict[str, Any]", bad["components"])["checks"]["build"])["commands"] = [["../escape.sh"]]
|
|
with self.assertRaises(ConfigurationError):
|
|
parse_project_configuration(bad)
|
|
|
|
|
|
class ScriptToolchainFingerprintAndCacheTest(unittest.TestCase):
|
|
"""The selected toolchain is part of the build-input record, and dependency caching follows the declared toolchain."""
|
|
|
|
def test_the_build_input_record_names_the_selected_toolchain(self) -> None:
|
|
java = compute_build_inputs(planned({"java": "21"}), SOURCE_TREE, "1")
|
|
node = compute_build_inputs(planned({"node": "22.20.0"}), SOURCE_TREE, "1")
|
|
self.assertIn("java", java["toolchain"])
|
|
self.assertIn("node", node["toolchain"])
|
|
self.assertNotEqual(java["config_digest"], node["config_digest"])
|
|
self.assertNotIn("control", java["toolchain"])
|
|
|
|
def test_cache_family_follows_the_toolchain_not_the_script_tool(self) -> None:
|
|
self.assertEqual((cache_family(planned({"java": "21"})), cache_family(planned({"node": "22.20.0"}))), ("maven", "node"))
|
|
self.assertIsNone(cache_unsupported_reason(planned({"java": "21"})))
|
|
self.assertIn("no dependency cache", cache_unsupported_reason(plan_for(parse_project_configuration(script_configuration({"control": "1"})), event(), _control_catalog())["targets"][0]) or "")
|
|
|
|
|
|
def _control_catalog():
|
|
"""A catalog that also qualifies the control toolchain."""
|
|
from platform_ci.runtimes import parse_runtime_catalog # noqa: PLC0415
|
|
|
|
return parse_runtime_catalog({"schema": 1, "toolchains": {"control": {"1": {"image": JAVA_IMAGE}}}})
|
|
|
|
|
|
class ScriptToolchainExecutionTest(unittest.TestCase):
|
|
"""A java-toolchain script gets the credential-free Maven settings; a node or control script does not."""
|
|
|
|
def _run(self, toolchains: dict[str, str]) -> Path:
|
|
with tempfile.TemporaryDirectory() as directory:
|
|
base = Path(directory)
|
|
source = base / "src"
|
|
(source / "scripts" / "ci").mkdir(parents=True)
|
|
(source / "scripts" / "ci" / "check.sh").write_text("#!/bin/sh\n", encoding="utf-8")
|
|
(base / "home").mkdir()
|
|
run_target_commands(planned(toolchains), source, lambda command, working_directory, environment: 0, {"PATH": "/usr/bin", "HOME": str(base / "home")})
|
|
return base / "home" / ".m2" / "settings.xml" if (base / "home" / ".m2" / "settings.xml").exists() else base / "missing"
|
|
|
|
def test_maven_settings_only_for_a_java_toolchain(self) -> None:
|
|
self.assertEqual(self._run({"java": "21"}).name, "settings.xml")
|
|
self.assertEqual(self._run({"node": "22.20.0"}).name, "missing")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|