diff --git a/.github/scripts/windows-cleanup.ps1 b/.github/scripts/windows-cleanup.ps1 index 5f050335..413c191c 100644 --- a/.github/scripts/windows-cleanup.ps1 +++ b/.github/scripts/windows-cleanup.ps1 @@ -1,4 +1,4 @@ -param( +param( [Parameter(Mandatory = $true)] [string]$ImageName, diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index df0a55d6..f25c0086 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -144,13 +144,13 @@ jobs: run: | docker version if ($LASTEXITCODE -ne 0) { - Write-Host "当前 Runner 未提供可用的 Docker Engine;请先完成 Runner 预配置" + Write-Host "Docker Engine is unavailable on this runner." exit $LASTEXITCODE } docker ps if ($LASTEXITCODE -ne 0) { - Write-Host "当前 Runner 无权访问 Docker Engine;请先修复 Runner 权限" + Write-Host "The runner cannot access Docker Engine." exit $LASTEXITCODE } diff --git a/test/test_ci_cd_permission_boundary.py b/test/test_ci_cd_permission_boundary.py index d5c74e80..1617aa86 100644 --- a/test/test_ci_cd_permission_boundary.py +++ b/test/test_ci_cd_permission_boundary.py @@ -389,6 +389,28 @@ def test_windows_publish_requires_preconfigured_docker_engine(self) -> None: with self.subTest(forbidden_command=forbidden_command): self.assertNotIn(forbidden_command, script) + def test_windows_powershell_51_inline_docker_check_is_ascii_only(self) -> None: + publish_job = self.release_document["jobs"]["publish"] + verify_step = workflow_step(publish_job, "Verify Docker access") + + self.assertTrue( + verify_step["run"].isascii(), + "Windows PowerShell 5.1 会错误解码 GitHub Actions 生成的无 BOM UTF-8 临时脚本", + ) + + def test_non_ascii_windows_powershell_files_have_utf8_bom(self) -> None: + for script_path in (BUILD_SCRIPT, CLEANUP_SCRIPT): + raw_script = script_path.read_bytes() + if raw_script.isascii(): + continue + + with self.subTest(script=script_path.name): + self.assertTrue( + raw_script.startswith(b"\xef\xbb\xbf"), + "含非 ASCII 字符的 Windows PowerShell 5.1 脚本必须使用 UTF-8 BOM", + ) + raw_script.decode("utf-8-sig") + def test_release_runs_are_never_cancelled_mid_deployment(self) -> None: self.assertRegex( self.release_workflow,