@@ -202,10 +202,167 @@ This workflow tests remote mode with array toolsets.
202202
203203 yamlStr := string (yamlContent )
204204
205- // In remote mode, toolsets are not currently supported via environment variables
206- // The remote server might have different configuration mechanism
207- // For now, we verify the workflow compiles successfully
205+ // In remote mode, toolsets should be passed via X-MCP-Toolsets header
208206 if ! strings .Contains (yamlStr , "https://api.githubcopilot.com/mcp/" ) {
209207 t .Errorf ("Expected remote mode URL in YAML" )
210208 }
209+
210+ // Check for X-MCP-Toolsets header with the configured toolsets
211+ if ! strings .Contains (yamlStr , `"X-MCP-Toolsets": "repos,issues"` ) {
212+ t .Errorf ("Expected X-MCP-Toolsets header with 'repos,issues' in remote mode, but didn't find it.\n Generated YAML:\n %s" , yamlStr )
213+ }
214+ }
215+
216+ func TestGitHubToolsetRemoteModeMultipleEngines (t * testing.T ) {
217+ tests := []struct {
218+ name string
219+ workflowMD string
220+ expectedHeader string
221+ engineType string
222+ }{
223+ {
224+ name : "Claude remote mode with toolsets" ,
225+ workflowMD : `---
226+ on: push
227+ engine: claude
228+ tools:
229+ github:
230+ mode: remote
231+ toolset: [repos, issues, pull_requests]
232+ ---
233+
234+ # Test Workflow
235+
236+ Claude remote mode with toolsets.
237+ ` ,
238+ expectedHeader : `"X-MCP-Toolsets": "repos,issues,pull_requests"` ,
239+ engineType : "claude" ,
240+ },
241+ {
242+ name : "Copilot remote mode with toolsets" ,
243+ workflowMD : `---
244+ on: push
245+ engine: copilot
246+ tools:
247+ github:
248+ mode: remote
249+ toolset: [actions, discussions]
250+ ---
251+
252+ # Test Workflow
253+
254+ Copilot remote mode with toolsets.
255+ ` ,
256+ expectedHeader : `"X-MCP-Toolsets": "actions,discussions"` ,
257+ engineType : "copilot" ,
258+ },
259+ {
260+ name : "Remote mode with all toolsets" ,
261+ workflowMD : `---
262+ on: push
263+ engine: claude
264+ tools:
265+ github:
266+ mode: remote
267+ toolset: [all]
268+ ---
269+
270+ # Test Workflow
271+
272+ Remote mode with all toolsets.
273+ ` ,
274+ expectedHeader : `"X-MCP-Toolsets": "all"` ,
275+ engineType : "claude" ,
276+ },
277+ {
278+ name : "Remote mode without toolsets" ,
279+ workflowMD : `---
280+ on: push
281+ engine: claude
282+ tools:
283+ github:
284+ mode: remote
285+ ---
286+
287+ # Test Workflow
288+
289+ Remote mode without toolsets.
290+ ` ,
291+ expectedHeader : "" , // No header should be added
292+ engineType : "claude" ,
293+ },
294+ {
295+ name : "Remote mode with toolsets and read-only" ,
296+ workflowMD : `---
297+ on: push
298+ engine: copilot
299+ tools:
300+ github:
301+ mode: remote
302+ toolset: [repos, issues]
303+ read-only: true
304+ ---
305+
306+ # Test Workflow
307+
308+ Remote mode with toolsets and read-only.
309+ ` ,
310+ expectedHeader : `"X-MCP-Toolsets": "repos,issues"` ,
311+ engineType : "copilot" ,
312+ },
313+ }
314+
315+ for _ , tt := range tests {
316+ t .Run (tt .name , func (t * testing.T ) {
317+ // Create temporary directory for test
318+ tempDir := t .TempDir ()
319+ mdPath := filepath .Join (tempDir , "test-workflow.md" )
320+
321+ // Write workflow file
322+ err := os .WriteFile (mdPath , []byte (tt .workflowMD ), 0644 )
323+ if err != nil {
324+ t .Fatalf ("Failed to write test workflow: %v" , err )
325+ }
326+
327+ // Compile the workflow
328+ compiler := NewCompiler (false , "" , "test" )
329+ compileErr := compiler .CompileWorkflow (mdPath )
330+ if compileErr != nil {
331+ t .Fatalf ("Failed to compile workflow: %v" , compileErr )
332+ }
333+
334+ // Read the generated YAML
335+ yamlPath := strings .TrimSuffix (mdPath , ".md" ) + ".lock.yml"
336+ yamlContent , readErr := os .ReadFile (yamlPath )
337+ if readErr != nil {
338+ t .Fatalf ("Failed to read generated YAML: %v" , readErr )
339+ }
340+
341+ yamlStr := string (yamlContent )
342+
343+ // Verify remote mode URL
344+ if ! strings .Contains (yamlStr , "https://api.githubcopilot.com/mcp/" ) {
345+ t .Errorf ("Expected remote mode URL in YAML" )
346+ }
347+
348+ // Check for expected header
349+ if tt .expectedHeader != "" {
350+ if ! strings .Contains (yamlStr , tt .expectedHeader ) {
351+ t .Errorf ("Expected header %q in YAML but didn't find it.\n Generated YAML:\n %s" , tt .expectedHeader , yamlStr )
352+ }
353+ } else {
354+ // Verify no X-MCP-Toolsets header is present
355+ if strings .Contains (yamlStr , "X-MCP-Toolsets" ) {
356+ t .Errorf ("Expected no X-MCP-Toolsets header in YAML but found one.\n Generated YAML:\n %s" , yamlStr )
357+ }
358+ }
359+
360+ // If read-only is in the test name, also verify X-MCP-Readonly header
361+ if strings .Contains (tt .name , "read-only" ) {
362+ if ! strings .Contains (yamlStr , `"X-MCP-Readonly": "true"` ) {
363+ t .Errorf ("Expected X-MCP-Readonly header in YAML but didn't find it.\n Generated YAML:\n %s" , yamlStr )
364+ }
365+ }
366+ })
367+ }
211368}
0 commit comments