MCPcopy Create free account
hub / github.com/github/gh-aw / fetchAndSaveRemoteDispatchWorkflows

Function fetchAndSaveRemoteDispatchWorkflows

pkg/cli/dispatch.go:80–256  ·  view source on GitHub ↗

fetchAndSaveRemoteDispatchWorkflows fetches and saves the workflow files referenced in the safe-outputs.dispatch-workflow configuration of a remote workflow. Each listed workflow name (without extension) is resolved as a sibling file (" .md") in the same directory as the source workflow and dow

(ctx context.Context, content string, spec *WorkflowSpec, targetDir string, verbose bool, force bool, tracker *FileTracker, downloaders ...fileDownloadFn)

Source from the content-addressed store, hash-verified

78// An optional downloader function may be provided as the last argument to override the default
79// parser.DownloadFileFromGitHub implementation (used in tests to avoid real network calls).
80func fetchAndSaveRemoteDispatchWorkflows(ctx context.Context, content string, spec *WorkflowSpec, targetDir string, verbose bool, force bool, tracker *FileTracker, downloaders ...fileDownloadFn) error {
81 remoteWorkflowLog.Printf("Fetching remote dispatch workflows: repo=%s, targetDir=%s, force=%v", spec.RepoSlug, targetDir, force)
82 downloader := fileDownloadFn(parser.DownloadFileFromGitHub)
83 if len(downloaders) > 0 && downloaders[0] != nil {
84 downloader = downloaders[0]
85 }
86 if spec.RepoSlug == "" {
87 return nil
88 }
89
90 parts := strings.SplitN(spec.RepoSlug, "/", 2)
91 if len(parts) != 2 {
92 return nil
93 }
94 owner, repo := parts[0], parts[1]
95 ref := spec.Version
96 if ref == "" {
97 defaultBranch, err := getRepoDefaultBranch(ctx, spec.RepoSlug)
98 if err != nil {
99 remoteWorkflowLog.Printf("Failed to resolve default branch for %s, falling back to 'main': %v", spec.RepoSlug, err)
100 ref = "main"
101 } else {
102 ref = defaultBranch
103 }
104 spec.Version = ref
105 }
106
107 workflowNames := extractDispatchWorkflowNames(content)
108 if len(workflowNames) == 0 {
109 return nil
110 }
111
112 remoteWorkflowLog.Printf("Found %d dispatch workflow(s) to fetch from %s@%s", len(workflowNames), spec.RepoSlug, ref)
113
114 // workflowBaseDir is the directory of the source workflow in the remote repo
115 // (e.g. ".github/workflows"). Dispatch-workflow names are resolved relative to it.
116 workflowBaseDir := getParentDir(spec.WorkflowPath)
117
118 // Pre-compute the absolute target directory for path-traversal boundary checks.
119 absTargetDir, err := filepath.Abs(targetDir)
120 if err != nil {
121 remoteWorkflowLog.Printf("Failed to resolve absolute path for target directory %s: %v", targetDir, err)
122 return nil
123 }
124
125 for _, workflowName := range workflowNames {
126 // Build the remote file path for this dispatch workflow
127 var remoteFilePath string
128 if workflowBaseDir != "" {
129 remoteFilePath = path.Join(workflowBaseDir, workflowName+".md")
130 } else {
131 remoteFilePath = workflowName + ".md"
132 }
133 remoteFilePath = path.Clean(remoteFilePath)
134
135 // The local path is just the workflow filename in targetDir
136 localRelPath := filepath.Clean(workflowName + ".md")
137 targetPath := filepath.Join(targetDir, localRelPath)

Calls 14

FormatWarningMessageFunction · 0.92
FormatInfoMessageFunction · 0.92
FormatSuccessMessageFunction · 0.92
fileDownloadFnFuncType · 0.85
getRepoDefaultBranchFunction · 0.85
getParentDirFunction · 0.85
readSourceRepoFromFileFunction · 0.85
sourceRepoLabelFunction · 0.85
addSourceToWorkflowFunction · 0.85
TrackModifiedMethod · 0.80
TrackCreatedMethod · 0.65