1- # Reusable workflow to setup Windows build environment for AI coding agents
1+ # Direct Copilot setup workflow for Windows-based GitHub Copilot coding agent runs
22# Optimized for windows-2022 which already includes most FieldWorks dependencies.
33# This workflow is for managed/native validation only.
44#
1717# Rationale: cloud agent jobs should not require high-privilege credentials
1818# (signing, release upload, deployment) and should minimize secret exposure.
1919#
20+ # ACCEPTED RESIDUAL RISK:
21+ # - GitHub's Windows Copilot guidance explicitly notes that the integrated
22+ # Copilot firewall is not compatible with Windows runs. In addition, GitHub
23+ # documents that the agent firewall does not protect processes started in
24+ # copilot-setup-steps, even where the firewall is otherwise enabled.
25+ # - As a result, this workflow is designed under the assumption that setup-step
26+ # traffic could exfiltrate repository data or any credentials intentionally
27+ # exposed to the agent environment.
28+ # - We accept that residual risk for this repository because the credentials in
29+ # scope here are deliberately low-privilege and narrowly scoped: `contents: read`
30+ # for checkout only, Jira service-user credentials limited by Jira/API policy,
31+ # and no installer/signing/deployment secrets.
32+ # - Additional exposure that remains in scope: package/dependency downloads,
33+ # shallow helper-repo clones, and any network access performed by build/test
34+ # tooling during setup.
35+ # - This acceptance is conditional on keeping this workflow limited to managed/
36+ # native validation and never adding high-privilege release, signing, deployment,
37+ # or broadly scoped cross-system credentials.
38+ # - If stronger exfiltration controls become required, move Copilot Windows runs
39+ # to a self-hosted ephemeral runner or a larger runner with Azure private
40+ # networking, and re-review this workflow before adding new secrets.
41+ #
2042# ============================================================================
2143# EXPECTED FROM windows-2022 (DO NOT RE-INSTALL):
2244# ============================================================================
4971#
5072# ============================================================================
5173
52- name : " Agents: Windows setup steps "
74+ name : " Copilot Setup Steps "
5375
5476on :
55- workflow_call :
56- # Inputs are intentionally wrapper-script focused to avoid ad-hoc build
57- # command injection and to preserve FieldWorks build ordering rules.
58- inputs :
59- build_args :
60- required : false
61- type : string
62- description : ' Arguments to pass to build.ps1 (e.g., "-Configuration Release -BuildTests")'
63- test_args :
64- required : false
65- type : string
66- description : ' Arguments to pass to test.ps1 (e.g., "-NoBuild -TestProject FwUtilsTests")'
67- skip_serena :
68- required : false
69- type : boolean
70- default : false
71- description : ' Skip Serena MCP setup (for builds that do not need code intelligence)'
72- clone_helper_repos :
73- required : false
74- type : boolean
75- default : true
76- description : ' Clone FwHelps/FwLocalizations/liblcm with shallow checkout for full build compatibility'
77-
78- permissions :
79- contents : read
77+ workflow_dispatch :
78+ push :
79+ paths :
80+ - .github/workflows/copilot-setup-steps.yml
81+ - Build/Agent/**
82+ - build.ps1
83+ - test.ps1
84+ - .serena/project.yml
85+ pull_request :
86+ paths :
87+ - .github/workflows/copilot-setup-steps.yml
88+ - Build/Agent/**
89+ - build.ps1
90+ - test.ps1
91+ - .serena/project.yml
8092
8193jobs :
82- windows -setup :
94+ copilot -setup-steps :
8395 runs-on : windows-2022
84- outputs :
85- msbuild-path : ${{ steps.setup-env.outputs.msbuild-path }}
86- vs-install-path : ${{ steps.setup-env.outputs.vs-install-path }}
96+ permissions :
97+ contents : read
8798
8899 steps :
89100 - name : Checkout repo
@@ -101,7 +112,6 @@ jobs:
101112 nuget-${{ runner.os }}-
102113
103114 - name : Cache Serena language servers
104- if : inputs.skip_serena != true
105115 uses : actions/cache@v5
106116 with :
107117 path : |
@@ -119,13 +129,11 @@ jobs:
119129 uses : microsoft/setup-msbuild@v2
120130
121131 - name : Setup uv (Python package manager for Serena)
122- if : inputs.skip_serena != true
123132 uses : astral-sh/setup-uv@v7
124133 with :
125134 version : " 0.6.x"
126135
127136 - name : Configure FieldWorks build environment
128- id : setup-env
129137 shell : pwsh
130138 run : |
131139 # Run testable script with GitHub Actions output
@@ -169,17 +177,7 @@ jobs:
169177 Write-Host "Jira service-user credentials detected. Ensure the token is scoped by the approved visibility API/policy." -ForegroundColor DarkGray
170178 }
171179
172- - name : Guardrail - block installer builds in agent workflow
173- if : inputs.build_args != '' && inputs.build_args != null
174- shell : pwsh
175- run : |
176- $argsText = "${{ inputs.build_args }}"
177- if ($argsText -match '(?i)(-BuildInstaller|InstallerToolset|Build/InstallerBuild\.proj|FLExInstaller)') {
178- throw "Installer builds are not allowed in this workflow. Use dedicated installer pipelines."
179- }
180-
181180 - name : Clone helper repos (shallow)
182- if : inputs.clone_helper_repos == true
183181 shell : pwsh
184182 run : |
185183 function Invoke-ShallowClone {
@@ -223,35 +221,38 @@ jobs:
223221 # SERENA MCP SETUP - for agent code intelligence
224222 # ================================================================
225223 - name : " Serena: Setup and verify"
226- if : inputs.skip_serena != true
227224 shell : pwsh
228225 timeout-minutes : 10
229226 run : |
230227 # Run testable script with GitHub Actions output
231228 .\Build\Agent\Setup-Serena.ps1 -OutputGitHubEnv -SkipLanguageServerCheck
232229
233230 # ================================================================
234- # BUILD (optional)
231+ # BUILD AND TEST VALIDATION
232+ # This workflow always pre-seeds the Copilot environment the same way:
233+ # Debug build, include managed test binaries, then run managed tests.
235234 # ================================================================
236235 - name : Run build.ps1
237- if : inputs.build_args != '' && inputs.build_args != null
238236 shell : pwsh
239237 timeout-minutes : 60
240238 run : |
241- Write-Host "Running: ./build.ps1 ${{ inputs.build_args }}" -ForegroundColor Cyan
242- ./build.ps1 ${{ inputs.build_args }}
239+ $buildArgs = @('-Configuration', 'Debug', '-BuildTests')
240+
241+ Write-Host "Running: ./build.ps1 $($buildArgs -join ' ')" -ForegroundColor Cyan
242+ ./build.ps1 @buildArgs
243243 if ($LASTEXITCODE -ne 0) {
244244 throw "build.ps1 failed with exit code $LASTEXITCODE"
245245 }
246246 Write-Host "build.ps1 completed successfully!" -ForegroundColor Green
247247
248248 - name : Run test.ps1
249- if : inputs.test_args != '' && inputs.test_args != null
250249 shell : pwsh
251250 timeout-minutes : 60
252251 run : |
253- Write-Host "Running: ./test.ps1 ${{ inputs.test_args }}" -ForegroundColor Cyan
254- ./test.ps1 ${{ inputs.test_args }}
252+ $testArgs = @('-Configuration', 'Debug', '-NoBuild')
253+
254+ Write-Host "Running: ./test.ps1 $($testArgs -join ' ')" -ForegroundColor Cyan
255+ ./test.ps1 @testArgs
255256 if ($LASTEXITCODE -ne 0) {
256257 throw "test.ps1 failed with exit code $LASTEXITCODE"
257258 }
0 commit comments