Skip to content

Add agentic workflow repo-assist#19738

Closed
dsyme wants to merge 4 commits intomainfrom
add-workflow-repo-assist-1672
Closed

Add agentic workflow repo-assist#19738
dsyme wants to merge 4 commits intomainfrom
add-workflow-repo-assist-1672

Conversation

@dsyme
Copy link
Contributor

@dsyme dsyme commented Mar 5, 2026

Add agentic workflow repo-assist

Copilot AI and others added 4 commits March 5, 2026 09:43
When adding a scheduled workflow via `gh aw add-wizard`, the wizard now
detects the schedule trigger and offers a choice of standard frequencies:
hourly, every 3 hours, daily, weekly, or monthly.

- The form defaults to the workflow's existing schedule.
- Custom schedules (not matching a standard frequency) are shown as a
  "Custom: <expr> (keep existing)" option which is the default.
- If the user selects the same frequency or "Custom", the frontmatter is
  left unchanged.
- For multi-trigger workflows (schedule + other triggers), the selector is
  skipped to avoid losing other triggers.

New files:
  pkg/cli/add_interactive_schedule.go       - detection & selection logic
  pkg/cli/add_interactive_schedule_test.go  - unit tests

Changed files:
  pkg/cli/add_interactive_orchestrator.go   - calls selectScheduleFrequency
                                              as step 7b in RunAddInteractive

Co-authored-by: dsyme <7204669+dsyme@users.noreply.github.com>
Copilot AI review requested due to automatic review settings March 5, 2026 17:20
@dsyme dsyme closed this Mar 5, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an “agentic workflow repo-assist” workflow and extends the interactive add flow with a schedule-frequency wizard to detect and optionally rewrite scheduled workflow frontmatter. Also adjusts PR creation scripting to harden context access and simplify footer/run URL generation.

Changes:

  • Add schedule detection/classification + interactive schedule-frequency selection with unit tests.
  • Wire the new schedule step into the interactive orchestrator.
  • Add repo-assist workflow markdown and adjust PR creation JS (run URL building, permission-denied handling, footer inputs).

Reviewed changes

Copilot reviewed 5 out of 6 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
pkg/cli/add_interactive_schedule.go Implements schedule detection/classification and an interactive frequency selector that updates workflow frontmatter.
pkg/cli/add_interactive_schedule_test.go Adds tests covering schedule classification, detection, and option ordering/labels.
pkg/cli/add_interactive_orchestrator.go Invokes the new schedule-frequency step during interactive add.
actions/setup/js/create_pull_request.cjs Adjusts context guarding, run URL construction, footer generation inputs, and permission-denied behavior.
.github/workflows/repo-assist.md Adds the new “repo-assist” agentic workflow definition and instructions.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +245 to +252
// Update the workflow content in memory.
// For multi-trigger on: maps, update the "schedule" sub-field to preserve other triggers.
// For simple on: strings, update the "on" field directly.
updateField := "on"
if detection.IsMultiTrigger {
updateField = "schedule"
}
updatedContent, err := UpdateFieldInFrontmatter(content, updateField, newExpr)
Copy link

Copilot AI Mar 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When on: is a map (even if it only contains schedule + workflow_dispatch), updating updateField := \"on\" will replace the entire on: map with a string and drop workflow_dispatch (and any other keys). Also, setting updateField = \"schedule\" risks writing a top-level schedule key instead of updating on.schedule unless UpdateFieldInFrontmatter supports nested updates. Consider detecting whether on is a map and always updating the nested on.schedule value (preserving other triggers), e.g., by updating the parsed frontmatter structure and re-serializing, or by extending UpdateFieldInFrontmatter to accept a nested path like on.schedule.

Copilot uses AI. Check for mistakes.
Comment on lines +88 to +110
// Schedule as string shorthand (e.g., "schedule: daily")
if schedStr, ok := schedValue.(string); ok {
return scheduleDetection{
RawExpr: schedStr,
Frequency: classifyScheduleFrequency(schedStr),
IsUpdatable: true,
IsMultiTrigger: isMultiTrigger,
}
}

// Schedule as array (e.g., "schedule:\n - cron: daily")
if schedArray, ok := schedValue.([]any); ok && len(schedArray) > 0 {
if item, ok := schedArray[0].(map[string]any); ok {
if cronVal, ok := item["cron"].(string); ok {
return scheduleDetection{
RawExpr: cronVal,
Frequency: classifyScheduleFrequency(cronVal),
IsUpdatable: true,
IsMultiTrigger: isMultiTrigger,
}
}
}
}
Copy link

Copilot AI Mar 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unlike the on: <string> case (which validates via parser.ParseSchedule), the on: { schedule: ... } cases don’t validate that schedStr / cronVal are actually parseable schedules before marking the workflow as updatable. This can create false positives and offer the wizard for invalid/misconfigured values. Suggest mirroring the string-path behavior by calling parser.ParseSchedule (or an equivalent validator) before returning IsUpdatable: true for both the shorthand string and the cron: array forms.

Copilot uses AI. Check for mistakes.
Comment on lines +536 to +538
const runId = context.runId;
const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
const runUrl = context.payload.repository ? `${context.payload.repository.html_url}/actions/runs/${runId}` : `${githubServer}/${repoParts.owner}/${repoParts.repo}/actions/runs/${runId}`;
Copy link

Copilot AI Mar 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The run URL construction logic is duplicated. To reduce drift and keep edge-case handling consistent, extract this into a small helper (e.g., buildRunUrl(context, repoParts)), and reuse it in both places.

Copilot uses AI. Check for mistakes.
Comment on lines 725 to +727
const runId = context.runId;
const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
const runUrl = context.payload.repository ? `${context.payload.repository.html_url}/actions/runs/${runId}` : `${githubServer}/${repoParts.owner}/${repoParts.repo}/actions/runs/${runId}`;
Copy link

Copilot AI Mar 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The run URL construction logic is duplicated. To reduce drift and keep edge-case handling consistent, extract this into a small helper (e.g., buildRunUrl(context, repoParts)), and reuse it in both places.

Copilot uses AI. Check for mistakes.
Comment on lines +985 to +994
// Set output variable for conclusion job to handle
core.setOutput(
"error_message",
"GitHub Actions is not permitted to create or approve pull requests. Please enable 'Allow GitHub Actions to create and approve pull requests' in repository settings: https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/enabling-features-for-your-repository/managing-github-actions-settings-for-a-repository#preventing-github-actions-from-creating-or-approving-pull-requests"
);
return {
success: false,
error: errorMessage,
error_type: "permission_denied",
};
Copy link

Copilot AI Mar 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This removes the prior behavior that created a fallback issue (with a ready-to-use compare/create-PR link) when PR creation is permission-denied, and instead relies on a downstream 'conclusion job' consuming error_message. In this PR, no corresponding consumer is shown, so repositories hitting this error may lose the previous self-serve remediation path. Consider either (a) keeping the fallback issue creation behind fallbackAsIssue, or (b) also outputting the key fields needed to recreate the prior UX (e.g., create_pr_url, branch_name, base_branch, title) and ensuring this PR includes the conclusion-job handling.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants