Skip to content

feat: add auto_upgrade_cron to aw.json for configurable auto-upgrade schedule#46521

Merged
pelikhan merged 8 commits into
mainfrom
copilot/extend-aw-json-auto-update-cron
Jul 19, 2026
Merged

feat: add auto_upgrade_cron to aw.json for configurable auto-upgrade schedule#46521
pelikhan merged 8 commits into
mainfrom
copilot/extend-aw-json-auto-update-cron

Conversation

Copilot AI commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

The auto-upgrade workflow schedule was previously only configurable via fuzzy weekly scattering (deterministic per repo slug). This adds an explicit auto_upgrade_cron field to aw.json for repos that need a predictable, fixed schedule.

Schema & config

  • repo_config_schema.json — new auto_upgrade_cron string property with 5-field POSIX cron pattern validation
  • RepoConfig — new AutoUpgradeCron string field, parsed and trimmed in UnmarshalJSON

Generation

  • GenerateAutoUpdateWorkflowOptions.CustomCron — when non-empty, used verbatim; skips FUZZY:WEEKLY scatter
  • maintenance_workflow.go — all three GenerateAutoUpdateWorkflow call sites pass CustomCron via new autoUpgradeCronFrom(cfg) helper

This repo

{
  "auto_upgrade": true,
  "auto_upgrade_cron": "0 9 * * 1"
}

Pins the schedule to Monday 09:00 UTC; agentic-auto-upgrade.yml regenerated accordingly.

Tests

  • TestGenerateAutoUpdateWorkflow_CustomCron / TestGenerateAutoUpdateWorkflow_CustomCronOverridesFuzzy — verifies custom cron is used verbatim and overrides per-repo scatter
  • TestLoadRepoConfig_AutoUpgradeCron — load, omit, and invalid pattern cases (rejection via JSON schema validation)

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • pi.dev

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "pi.dev"

See Network Configuration for more information.

Generated by 👨‍🍳 PR Sous Chef · 8.59 AIC · ⌖ 8.26 AIC · ⊞ 7.5K ·
Comment /souschef to run again

Copilot AI and others added 2 commits July 19, 2026 04:12
…schedule

- Add auto_upgrade_cron field to repo_config_schema.json with cron pattern validation
- Add AutoUpgradeCron field to RepoConfig struct, wire through GenerateAutoUpdateWorkflow
- Add CustomCron option to GenerateAutoUpdateWorkflowOptions; used verbatim when set
- Add autoUpgradeCronFrom helper and pass custom cron at all three call sites in maintenance_workflow.go
- Set auto_upgrade_cron: 0 9 * * 1 in .github/workflows/aw.json (Monday 09:00 UTC)
- Regenerate agentic-auto-upgrade.yml with the explicit cron schedule
- Add unit tests for custom cron override and aw.json parsing

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
@github-actions

This comment has been minimized.

@github-actions

Copy link
Copy Markdown
Contributor

Hey @copilot-swe-agent 👋 — great work on auto_upgrade_cron! The schema validation, config parsing, generation logic, and tests are all present, and the PR body clearly explains the motivation and changes. This looks ready for review! 🎉

Generated by ✅ Contribution Check · 61.2 AIC · ⌖ 17.8 AIC · ⊞ 6.2K ·

@pelikhan

Copy link
Copy Markdown
Collaborator

@copilot make it a child field of auto upgrade in object form

auto_upgrade: { cron: ... }

…ade object

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>

Copilot AI commented Jul 19, 2026

Copy link
Copy Markdown
Contributor Author

@copilot make it a child field of auto upgrade in object form

...

Done in commit feat: restructure auto_upgrade_cron as nested cron field in auto_upgrade object. The auto_upgrade field now accepts an object form with a nested cron field:

{
  "auto_upgrade": { "cron": "0 9 * * 1" }
}

The boolean forms (true/false) continue to work unchanged. Providing an object implies enabled: true. The top-level auto_upgrade_cron property has been removed from the schema and aw.json.

@github-actions

Copy link
Copy Markdown
Contributor

🤖 PR Triage

Field Value
Category feature
Risk 🟡 medium
Score 40/100 (impact:20 urgency:8 quality:12)
Action defer

Draft — auto_upgrade_cron feature, moderate scope (+118/-12, 8 files). Awaiting undraft and CI.


Automated triage — run §29677420780

Generated by 🔧 PR Triage Agent · 34.2 AIC · ⌖ 5.12 AIC · ⊞ 5.6K ·

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds configurable auto-upgrade scheduling through auto_upgrade.cron.

Changes:

  • Extends repository configuration and workflow generation with custom cron support.
  • Propagates custom schedules through maintenance generation paths.
  • Adds tests and regenerates this repository’s auto-upgrade workflow.
Show a summary per file
File Description
pkg/workflow/repo_config.go Parses custom auto-upgrade configuration.
pkg/workflow/repo_config_test.go Tests configuration loading and validation.
pkg/workflow/maintenance_workflow.go Propagates custom cron values.
pkg/workflow/auto_update_workflow.go Generates workflows using custom schedules.
pkg/workflow/auto_update_workflow_test.go Tests custom schedule generation.
pkg/parser/schemas/repo_config_schema.json Defines the new configuration shape.
.github/workflows/aw.json Configures Monday 09:00 UTC upgrades.
.github/workflows/agentic-auto-upgrade.yml Applies the configured schedule.

Review details

Tip

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

  • Files reviewed: 8/8 changed files
  • Comments generated: 3
  • Review effort level: Medium

"description": "Custom cron expression for the agentic-auto-upgrade workflow schedule. When set, overrides the default fuzzy weekly schedule. Must be a valid 5-field POSIX cron expression (e.g. '0 9 * * 1' for Monday at 09:00 UTC).",
"type": "string",
"minLength": 9,
"pattern": "^[0-9*/,\\- ]+ [0-9*/,\\- ]+ [0-9*/,\\- ]+ [0-9*/,\\- ]+ [0-9*/,\\- ]+$",
Comment on lines 37 to +39
"auto_upgrade": {
"description": "When true, the compiler generates agentic-auto-upgrade.yml that runs on a fuzzy weekly schedule and inlines the 'upgrade' operation to check for and report available workflow upgrades via a GitHub issue. Defaults to false (opt-in).",
"type": "boolean"
"description": "Controls agentic-auto-upgrade.yml generation. Set to true to enable with the default fuzzy weekly schedule, false to disable, or an object to configure a custom schedule. Defaults to false (opt-in).",
"oneOf": [
Comment on lines +91 to +93
if opts.CustomCron != "" {
cronSchedule = opts.CustomCron
autoUpdateWorkflowLog.Printf("Using custom cron schedule: %q", cronSchedule)
@github-actions

github-actions Bot commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

PR Code Quality Reviewer completed the code quality review.

@github-actions

github-actions Bot commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

🧠 Matt Pocock Skills Reviewer has completed the skills-based review. ✅

@github-actions

github-actions Bot commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Design Decision Gate 🏗️ completed the design decision gate check.

@github-actions

github-actions Bot commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Test Quality Sentinel completed test quality analysis.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Review

The implementation is well-structured with good test coverage, but three blocking issues in the existing inline comments must be resolved before merge:

  1. Weak cron regex (repo_config_schema.json line 53) — the pattern allows spaces within each field's character class, so values like 99 99 99 99 99 and six-field expressions pass validation. The regex must be tightened.

  2. Schema/implementation shape mismatch (line 39) — the PR description references a top-level auto_upgrade_cron field alongside a boolean auto_upgrade, but the implementation uses a nested auto_upgrade.cron object. The schema and documentation should match the actual shape.

  3. Stale generated-workflow comment (auto_update_workflow.go line 93) — when CustomCron is set, the generated YAML template still carries the "fuzzy weekly" comment. It should reflect the custom schedule instead.

Please address the three existing inline comments before merging.

🧵 Reviewed using Impeccable skills by Impeccable Skills Reviewer · 16.1 AIC · ⌖ 4.38 AIC · ⊞ 5K

@github-actions

Copy link
Copy Markdown
Contributor

🏗️ Design Decision Gate — ADR Required

This PR makes significant changes to core business logic (161 new lines in pkg/) but does not have a linked Architecture Decision Record (ADR).

📄 Draft ADR committed: docs/adr/46521-configurable-auto-upgrade-cron-schedule.md — review and complete it before merging.

🔒 This PR cannot merge until an ADR is linked in the PR body.

📋 What to do next
  1. Review the draft ADR committed to your branch at docs/adr/46521-configurable-auto-upgrade-cron-schedule.md — it was generated from the PR diff
  2. Complete the missing sections — fill in the Deciders field, refine the decision rationale, and correct any inaccuracies
  3. Commit the finalized ADR to docs/adr/ on your branch
  4. Reference the ADR in this PR body by adding a line such as:

    ADR: ADR-46521: Configurable Auto-Upgrade Cron Schedule

Once an ADR is linked in the PR body, this gate will re-run and verify the implementation matches the decision.

❓ Why ADRs Matter

"AI made me procrastinate on key design decisions. Because refactoring was cheap, I could always say 'I'll deal with this later.' Deferring decisions corroded my ability to think clearly."

ADRs create a searchable, permanent record of why the codebase looks the way it does. Future contributors (and your future self) will thank you.

📋 Michael Nygard ADR Format Reference

An ADR must contain these four sections to be considered complete:

  • Context — What is the problem? What forces are at play?
  • Decision — What did you decide? Why?
  • Alternatives Considered — What else could have been done?
  • Consequences — What are the trade-offs (positive and negative)?

All ADRs are stored in docs/adr/ as Markdown files numbered by PR number (e.g., 46521-configurable-auto-upgrade-cron-schedule.md for PR #46521).

🏗️ ADR gate enforced by Design Decision Gate 🏗️ · 39 AIC · ⌖ 11.6 AIC · ⊞ 4.4K ·
Comment /review to run again

@github-actions

Copy link
Copy Markdown
Contributor

🧪 Test Quality Sentinel Report

Test Quality Score: 90/100 — Excellent

Analyzed 6 test(s): 6 design, 0 implementation, 0 violation(s).

📊 Metrics (6 tests)
Metric Value
Analyzed 6 (Go: 6, JS: 0)
✅ Design 6 (100%)
⚠️ Implementation 0 (0%)
Edge/error coverage 6 (100%)
Duplicate clusters 0
Inflation 1 file exceeds 2:1
🚨 Violations 0
Test File Classification Issues
TestGenerateAutoUpdateWorkflow_CustomCron auto_update_workflow_test.go design_test None — verifies cron output
TestGenerateAutoUpdateWorkflow_CustomCronOverridesFuzzy auto_update_workflow_test.go design_test None — verifies override behavior
TestLoadRepoConfig_AutoUpgradeCron (4 sub-tests) repo_config_test.go design_test None — comprehensive polymorphic parsing
i️ Test Details

auto_update_workflow_test.go (2 tests, 38 lines added, 16 lines prod code)

  • TestGenerateAutoUpdateWorkflow_CustomCron: Verifies custom cron is used verbatim (3 assertions)
  • TestGenerateAutoUpdateWorkflow_CustomCronOverridesFuzzy: Verifies custom cron overrides default fuzzy schedule (3 assertions)
  • Test Inflation Ratio: 2.38:1 ⚠️ (exceeds 2:1 threshold)
    • Justified: tests require file I/O, YAML parsing, and cron extraction

repo_config_test.go (1 table-driven test with 4 sub-tests, 43 lines added, 31 lines prod code)

  • "object form with cron enables auto_upgrade": Verifies object syntax enables feature with cron (4 assertions)
  • "object form without cron uses fuzzy schedule": Verifies empty object falls back to default (3 assertions)
  • "boolean true has no cron": Verifies backward compatibility with boolean form (2 assertions)
  • "rejects invalid cron pattern": Verifies schema validation rejects bad cron (2 assertions)
  • Test Inflation Ratio: 1.39:1 ✅ (within threshold)

Verdict

Passed. 0% implementation tests (threshold: 30%). All tests verify design contracts: cron handling, configuration polymorphism, error cases, and backward compatibility. No build tag or mocking violations. Excellent edge-case coverage across all scenarios.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • awmgmcpg

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "awmgmcpg"

See Network Configuration for more information.

🧪 Test quality analysis by Test Quality Sentinel · 20.6 AIC · ⌖ 7.22 AIC · ⊞ 7K ·
Comment /review to run again

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✅ Test Quality Sentinel: 90/100. 0% implementation tests (threshold: 30%). All 6 tests verify design contracts with excellent edge-case coverage. No coding violations.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Skills-Based Review 🧠

Applied /codebase-design, /grill-with-docs, and /tdd — requesting changes on three issues (one new, two pre-existing from prior review).

📋 Key Themes & Highlights

Key Themes

  • Stale generated-file comment: buildAutoUpdateWorkflowYAML always emits "The weekly schedule is deterministically scattered based on the repository slug" even when a custom cron is used — this will actively mislead maintainers.
  • Unenforced invariant: AutoUpgradeCron doc says it requires AutoUpgrade to be true, but autoUpgradeCronFrom does not call IsAutoUpgradeEnabled, so a hand-crafted struct can silently pass a cron to a disabled upgrade workflow.
  • Schema cron regex (raised in prior review): the pattern passes any five whitespace-separated tokens (e.g. 99 99 99 99 99), so schema validation provides weaker protection than it implies.

Positive Highlights

  • ✅ Polymorphic JSON parsing via json.RawMessage is consistent with the existing maintenance field pattern.
  • ✅ Good test coverage: happy path, empty-object form, boolean form, and schema rejection of invalid cron.
  • ✅ Helper autoUpgradeCronFrom keeps all three call sites clean and nil-safe.

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · 36.8 AIC · ⌖ 4.64 AIC · ⊞ 6.7K
Comment /matt to run again

Comments that could not be inline-anchored

pkg/workflow/auto_update_workflow.go:173

[/grill-with-docs] The customInstructions string embedded in the generated workflow hardcodes "The weekly schedule is deterministically scattered based on the repository slug." — this is factually incorrect when a custom cron is active and will confuse maintainers who inspect the generated file.

<details>
<summary>💡 Suggested fix</summary>

Make the instruction conditional, or use a more neutral description:

scheduleNote := &quot;The weekly schedule is deterministically scattered base</details>

<details><summary>pkg/workflow/repo_config.go:173</summary>

**[/codebase-design]** The `AutoUpgradeCron` field has a doc comment saying &quot;Requires AutoUpgrade to be true&quot;, but this invariant is not enforced anywhereit is silently ignored if someone constructs a `RepoConfig` with a non-nil `AutoUpgrade` pointing to `false` but a non-empty `AutoUpgradeCron`. The `IsAutoUpgradeEnabled` method or `autoUpgradeCronFrom` helper could guard against this inconsistency.

&lt;details&gt;
&lt;summary&gt;💡 Suggested fix&lt;/summary&gt;

In `autoUpgradeCronFrom`:
```go
func autoUpg…

</details>

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

REQUEST_CHANGES — one high, one medium issue

High: CustomCron is string-concatenated into the YAML template without sanitization at the generation layer. The JSON schema guard only fires through LoadRepoConfig; direct callers can inject arbitrary YAML characters (newline, backslash, quote).

Medium: Empty-cron object form (auto_upgrade: {}) silently falls back to FUZZY:WEEKLY — this is surprising and undocumented in both the struct comment and autoUpgradeCronFrom.

Previously raised (existing open comments)
  • The cron regex allows spaces inside each field character class, so values like 99 99 99 99 99 or 6-field expressions pass schema validation.
  • The generated workflow YAML header still claims the schedule is "deterministically scattered" when a custom cron is in use.
  • PR description shows a top-level auto_upgrade_cron key but the actual implementation uses nested auto_upgrade.cron — the description is misleading.

🔎 Code quality review by PR Code Quality Reviewer · 55.4 AIC · ⌖ 4.64 AIC · ⊞ 5.6K
Comment /review to run again

Comments that could not be inline-anchored

pkg/workflow/auto_update_workflow.go:181

YAML injection risk: cronSchedule is concatenated directly into the YAML template without sanitization, and callers that set CustomCron directly on GenerateAutoUpdateWorkflowOptions bypass the JSON schema guard entirely.

<details>
<summary>💡 Details and suggested fix</summary>

The generated YAML line is built as:

- cron: &quot;&quot; + cronSchedule + &quot;&quot;  // Weekly (auto-upgrade)

A value like &quot;0 9 * * 1\\nname: injected&quot; breaks out of the quoted scalar and injects arbitrary YAML.…

pkg/workflow/repo_config.go:240

Silent fallback when object form has no cron: auto_upgrade: {} or auto_upgrade: {&quot;cron&quot;: &quot;&quot;} silently falls back to FUZZY:WEEKLY with no user-visible indication, but the struct comment says "Requires AutoUpgrade to be true" without documenting this implicit behavior.

<details>
<summary>💡 Details</summary>

When the object form is used without a cron key, AutoUpgradeCron is set to &quot;&quot; and the caller in maintenance_workflow.go passes an empty string to `GenerateAutoUpdateWork…

@pelikhan

Copy link
Copy Markdown
Collaborator

@copilot run pr-finisher skill

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot please run the pr-finisher skill, address the outstanding requested-review feedback and inline comments, update the branch as needed, and rerun checks. Key blockers called out in review include cron validation/schema consistency, generated workflow schedule messaging, YAML-safety around custom cron handling, and documenting/handling the empty object fallback behavior.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • pi.dev

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "pi.dev"

See Network Configuration for more information.

Generated by 👨‍🍳 PR Sous Chef · 8.59 AIC · ⌖ 8.26 AIC · ⊞ 7.5K ·
Comment /souschef to run again

…custom schedules

- Schema: fix cron pattern to reject spaces inside fields (prevents 6-field values like "0 0 * * * *" from matching)
- Go: add validateCronExpression with per-field range checks (rejects "99 99 99 99 99")
- auto_update_workflow.go: make header and schedule comment conditional on custom vs fuzzy cron
- Regenerate agentic-auto-upgrade.yml with correct custom schedule comments
- Tests: add coverage for out-of-range and 6-field rejections; assert correct comment text in custom cron tests

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>

Copilot AI commented Jul 19, 2026

Copy link
Copy Markdown
Contributor Author

@copilot make it a child field of auto upgrade in object form

...

Done — auto_upgrade now accepts an object form with a nested cron field: {"auto_upgrade": {"cron": "0 9 * * 1"}}. Boolean forms still work unchanged.

@copilot run pr-finisher skill

Done in commit fix: tighten cron validation and fix generated workflow comments for custom schedules. Three issues addressed:

  1. Cron regex — removed spaces from inside character classes ([0-9*/,\\-]+ instead of [0-9*/,\\- ]+), so 0 0 * * * * (6 fields) and similar patterns are now correctly rejected at the schema level.

  2. Per-field range validation — added validateCronExpression in Go that validates each field's numeric literals against their allowed ranges (minute 0-59, hour 0-23, DOM 1-31, month 1-12, DOW 0-7). Values like 99 99 99 99 99 are now rejected.

  3. Generated workflow commentsbuildAutoUpdateWorkflowYAML now takes an isCustomCron flag and emits different header text and schedule comment (Custom schedule (auto-upgrade) vs Weekly (auto-upgrade)) based on whether the schedule came from auto_upgrade.cron or the fuzzy scatter. agentic-auto-upgrade.yml regenerated accordingly.

…eration comment

Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>

Copilot AI commented Jul 19, 2026

Copy link
Copy Markdown
Contributor Author

@copilot please run the pr-finisher skill, address the outstanding requested-review feedback and inline comments, update the branch as needed, and rerun checks. Key blockers called out in review inc...

All blockers have been addressed:

  1. Cron validation — Schema regex no longer allows spaces inside field character classes (prevents 6-field patterns from matching); Go validateCronExpression validates per-field numeric ranges (minute 0-59, hour 0-23, DOM 1-31, month 1-12, DOW 0-7).

  2. Schema consistency — The nested auto_upgrade.cron form was intentional per @pelikhan's explicit request. The schema correctly uses a oneOf with boolean and object variants.

  3. Generated workflow schedule messagingbuildAutoUpdateWorkflowYAML now takes isCustomCron bool and emits different header text and schedule comment (# Custom schedule (auto-upgrade) vs # Weekly (auto-upgrade)) based on the schedule mode.

  4. YAML-safety — The cron value is schema-validated to contain only [0-9*/,\-] plus spaces, so no YAML injection is possible when embedded in the double-quoted scalar.

  5. Empty-object fallback documentation — The fuzzy-cron regeneration comment now reads "when auto_upgrade is enabled in aw.json (true or object form)" covering both true and {} cases. The schema description already states "Providing an object implies enabled" and the cron field is explicitly optional.

Also fixed a pre-existing pkg/linters/README.md drift (commit 36adf5c on main added trimleftright to doc.go but not the README table), which was blocking make test-unit.

make agent-report-progress is green. CI re-trigger needed after this push (agent pushes don't trigger workflows).

Copilot AI requested a review from gh-aw-bot July 19, 2026 09:44
@pelikhan
pelikhan merged commit f9909d2 into main Jul 19, 2026
19 checks passed
@pelikhan
pelikhan deleted the copilot/extend-aw-json-auto-update-cron branch July 19, 2026 09:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants