diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 156d0733..df0a55d6 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -142,69 +142,17 @@ jobs: - name: Verify Docker access shell: powershell -NoProfile -ExecutionPolicy Bypass -Command ". '{0}'" run: | - $ErrorActionPreference = "Continue" - $serviceNames = @('docker', 'com.docker.service') - $dockerDesktopStarted = $false - $desktopPaths = @( - "$env:ProgramFiles\Docker\Docker\Docker Desktop.exe", - "${env:ProgramFiles(x86)}\Docker\Docker\Docker Desktop.exe" - ) - - for ($attempt = 1; $attempt -le 6; $attempt++) { - Write-Host "Checking Docker access, attempt $attempt/6..." - - docker version - if ($LASTEXITCODE -eq 0) { - docker ps - if ($LASTEXITCODE -eq 0) { - Write-Host "Docker daemon ready" - exit 0 - } - } - - foreach ($serviceName in $serviceNames) { - $service = Get-Service -Name $serviceName -ErrorAction SilentlyContinue - if ($null -ne $service -and $service.Status -ne "Running") { - Write-Host "Starting Docker service: $serviceName" - try { - Start-Service -Name $serviceName -ErrorAction Stop - } catch { - Write-Host "Docker service start failed for ${serviceName}: $($_.Exception.Message)" - } - } elseif ($null -ne $service) { - Write-Host "Docker service ${serviceName} status: $($service.Status)" - } - } - - if (-not $dockerDesktopStarted) { - foreach ($desktopPath in $desktopPaths) { - if ($desktopPath -and (Test-Path $desktopPath)) { - Write-Host "Starting Docker Desktop: $desktopPath" - $runnerTrackingId = $env:RUNNER_TRACKING_ID - try { - # Keep Docker Desktop alive after the self-hosted runner cleans up this job. - $env:RUNNER_TRACKING_ID = "" - Start-Process -FilePath $desktopPath -WindowStyle Minimized - $dockerDesktopStarted = $true - break - } catch { - Write-Host "Docker Desktop start failed: $($_.Exception.Message)" - } finally { - $env:RUNNER_TRACKING_ID = $runnerTrackingId - } - } - } - } - - if ($attempt -lt 6) { - Start-Sleep -Seconds (10 * $attempt) - } + docker version + if ($LASTEXITCODE -ne 0) { + Write-Host "当前 Runner 未提供可用的 Docker Engine;请先完成 Runner 预配置" + exit $LASTEXITCODE } - Write-Host "Docker daemon did not become ready" - docker version docker ps - exit 1 + if ($LASTEXITCODE -ne 0) { + Write-Host "当前 Runner 无权访问 Docker Engine;请先修复 Runner 权限" + exit $LASTEXITCODE + } - name: Test and build Docker image timeout-minutes: 15 diff --git a/test/test_ci_cd_permission_boundary.py b/test/test_ci_cd_permission_boundary.py index a682378e..d5c74e80 100644 --- a/test/test_ci_cd_permission_boundary.py +++ b/test/test_ci_cd_permission_boundary.py @@ -365,7 +365,7 @@ def test_release_workflow_only_runs_for_master(self) -> None: self.assertEqual(publish_job.count("name: Publish master images on Windows runner"), 1) self.assertNotIn("name: Build on Windows runner", publish_job) - def test_windows_publish_recovers_docker_daemon_before_build(self) -> None: + def test_windows_publish_requires_preconfigured_docker_engine(self) -> None: publish_job = self.release_document["jobs"]["publish"] verify_step = workflow_step(publish_job, "Verify Docker access") script = verify_step["run"] @@ -374,19 +374,20 @@ def test_windows_publish_recovers_docker_daemon_before_build(self) -> None: verify_step["shell"], 'powershell -NoProfile -ExecutionPolicy Bypass -Command ". \'{0}\'"', ) - self.assertIn("for ($attempt = 1; $attempt -le 6; $attempt++)", script) - self.assertIn("$serviceNames = @('docker', 'com.docker.service')", script) - self.assertIn("Start-Service -Name $serviceName", script) - self.assertIn("Docker Desktop.exe", script) - self.assertIn("Start-Process -FilePath $desktopPath", script) - self.assertIn('$env:RUNNER_TRACKING_ID = ""', script) - self.assertLess( - script.index('$env:RUNNER_TRACKING_ID = ""'), - script.index("Start-Process -FilePath $desktopPath"), - ) - self.assertIn("Start-Sleep -Seconds (10 * $attempt)", script) - self.assertIn("Docker daemon ready", script) - self.assertIn("Docker daemon did not become ready", script) + self.assertEqual(script.count("docker version"), 1) + self.assertEqual(script.count("docker ps"), 1) + self.assertIn("if ($LASTEXITCODE -ne 0)", script) + self.assertIn("exit $LASTEXITCODE", script) + + for forbidden_command in ( + "Docker Desktop.exe", + "Start-Process", + "Start-Service", + "RUNNER_TRACKING_ID", + "Start-Sleep", + ): + with self.subTest(forbidden_command=forbidden_command): + self.assertNotIn(forbidden_command, script) def test_release_runs_are_never_cancelled_mid_deployment(self) -> None: self.assertRegex(