GetWorkflowLockFileName returns the lock file name (e.g. "smoke-copilot.lock.yml") for the given workflow input. It accepts a workflow ID (e.g. "smoke-copilot"), a file name with any supported extension (e.g. "smoke-copilot.md"), or a display name (e.g. "Smoke Copilot"). Returns an error if no match
(input string)
| 199 | // a file name with any supported extension (e.g. "smoke-copilot.md"), or a display |
| 200 | // name (e.g. "Smoke Copilot"). Returns an error if no matching workflow is found. |
| 201 | func GetWorkflowLockFileName(input string) (string, error) { |
| 202 | if input == "" { |
| 203 | return "", nil |
| 204 | } |
| 205 | |
| 206 | // Strategy 1: Normalize and check if the lock file exists directly. |
| 207 | // This handles workflow IDs and filenames with .md or .lock.yml extensions. |
| 208 | workflowsDir := constants.GetWorkflowDir() |
| 209 | normalizedName := stringutil.NormalizeWorkflowName(input) |
| 210 | lockFile := filepath.Join(workflowsDir, normalizedName+".lock.yml") |
| 211 | if _, err := os.Stat(lockFile); err == nil { |
| 212 | return normalizedName + ".lock.yml", nil |
| 213 | } |
| 214 | |
| 215 | // Strategy 2: Match by display name (case-insensitive) via GetAllWorkflows. |
| 216 | // This handles inputs like "Smoke Copilot" that normalize to non-existent filenames. |
| 217 | workflows, err := GetAllWorkflows() |
| 218 | if err != nil { |
| 219 | return "", fmt.Errorf("failed to get workflows: %w", err) |
| 220 | } |
| 221 | |
| 222 | for _, wf := range workflows { |
| 223 | if strings.EqualFold(wf.DisplayName, input) { |
| 224 | return wf.WorkflowID + ".lock.yml", nil |
| 225 | } |
| 226 | } |
| 227 | |
| 228 | return "", fmt.Errorf("workflow lock file not found for '%s'", input) |
| 229 | } |
| 230 | |
| 231 | // GetAllWorkflows returns all available workflows with their IDs and display names |
| 232 | func GetAllWorkflows() ([]WorkflowNameMatch, error) { |