Skip to content

feat: auto-generate side-repo maintenance workflow for SideRepoOps pattern#26382

Merged
pelikhan merged 12 commits intomainfrom
copilot/support-auto-generate-agentics-yml
Apr 15, 2026
Merged

feat: auto-generate side-repo maintenance workflow for SideRepoOps pattern#26382
pelikhan merged 12 commits intomainfrom
copilot/support-auto-generate-agentics-yml

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 15, 2026

In a SideRepoOps setup, agentics-maintenance.yml is only generated for the hosting repo. The target repo's maintenance workflow (safe-outputs replay, label creation, expired-entity cleanup) had to be hand-rolled and manually synced on every gh aw upgrade cycle.

Changes

Go — workflow generation (pkg/workflow/maintenance_workflow.go)

  • collectSideRepoTargets() — scans compiled WorkflowData for checkout configs with current: true and a static (non-expression) repository field; deduplicates by slug, preserving first-seen order. When the same repo appears multiple times with different tokens, the non-empty token is preferred.
  • sanitizeRepoForFilename() — converts owner/repoowner-repo for use in file names
  • sideRepoCronSeed() / generateSideRepoMaintenanceCron() — derives a deterministic minute and hour offset from the FNV-1a hash of the repository slug, scattering each side-repo workflow's cron across the clock face so multiple targets don't all fire at the same time. Frequency tier (every 2h / 6h / 12h / daily) is still governed by minExpiresDays.
  • generateSideRepoMaintenanceWorkflow() — emits agentics-maintenance-<slug>.yml with:
    • workflow_call + workflow_dispatch triggers
    • schedule: cron trigger with fuzzy offset (included when any workflow uses expires, matching the close-expired-entities job condition)
    • apply_safe_outputs job: uses custom token from the checkout config + GH_AW_TARGET_REPO_SLUG; includes actions/checkout sparse-checkout step in dev/script modes
    • create_labels job: creates labels in the target repo
    • validate_workflows job: same as hosting-repo variant
    • close-expired-entities job: included only when any workflow uses expires
  • generateAllSideRepoMaintenanceWorkflows() — removes stale agentics-maintenance-*.yml files no longer referenced by current targets on recompile
  • GenerateMaintenanceWorkflow() modified to invoke side-repo generation even when no expires is set (so create_labels/apply_safe_outputs are always available)

When no custom token is in the checkout config, the generated workflow falls back to ${{ secrets.GH_AW_GITHUB_TOKEN }}.

Example: a workflow with

checkout:
  repository: my-org/target-repo
  current: true
  github-token: ${{ secrets.GH_AW_TARGET_TOKEN }}

will produce .github/workflows/agentics-maintenance-my-org-target-repo.yml pre-wired with the custom token and GH_AW_TARGET_REPO_SLUG: "my-org/target-repo" on every cross-repo job. Expression-based repositories (e.g. ${{ inputs.target_repo }}) are skipped since no static filename can be derived.

JavaScript — cross-repo support (actions/setup/js/)

close_expired_discussions.cjs, close_expired_issues.cjs, close_expired_pull_requests.cjs, and create_labels.cjs now resolve owner/repo via a shared resolveExecutionOwnerRepo() helper added to repo_helpers.cjs. The helper reads GH_AW_TARGET_REPO_SLUG and validates it with parseRepoSlug(); if the variable is set but malformed it throws (instead of silently falling back to context.repo) to prevent wrong-repo operations.

Tests

  • TestCollectSideRepoTargets — includes cases for token preference and first-seen order preservation
  • TestSanitizeRepoForFilename
  • TestGenerateSideRepoMaintenanceCron — verifies determinism, distinct offsets per repo, valid minute range, and correct frequency-tier selection
  • TestGenerateSideRepoMaintenanceWorkflow — includes cases for schedule trigger presence and correct fuzzy cron value, and stale file cleanup
  • repo_helpers.test.cjs — covers resolveExecutionOwnerRepo() including the throw-on-malformed-slug behaviour
  • side_repo_maintenance_integration_test.go — end-to-end integration tests using compiler.ParseWorkflowFileGenerateMaintenanceWorkflow:
    • Verifies generated file structure (triggers, jobs, GH_AW_TARGET_REPO_SLUG, custom token)
    • Verifies schedule: trigger and close-expired-entities: job when expires is set, with correct fuzzy cron
    • Verifies GH_AW_GITHUB_TOKEN fallback when no custom token is configured
    • Verifies no file is generated for expression-based repository values
    • Verifies distinct cron expressions for different side-repo targets (scatter correctness)

Copilot AI and others added 3 commits April 15, 2026 06:45
…attern

- Detect SideRepoOps patterns from checkout configs with current: true
- Generate agentics-maintenance-<slug>.yml for each static target repo
- Add GH_AW_TARGET_REPO_SLUG support to close_expired_* and create_labels scripts
- Include close-expired-entities, apply_safe_outputs, create_labels, validate jobs
- Use custom token from checkout config for target repo authentication
- Add unit tests for collectSideRepoTargets, sanitizeRepoForFilename, and workflow generation

Agent-Logs-Url: https://github.com/github/gh-aw/sessions/dc073fff-9a15-4d12-93e4-a16cdc65fdc9

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
@github-actions github-actions Bot mentioned this pull request Apr 15, 2026
…-independent test comparison

Agent-Logs-Url: https://github.com/github/gh-aw/sessions/dc073fff-9a15-4d12-93e4-a16cdc65fdc9

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Add auto-generation of agentics-maintenance.yml for target repository feat: auto-generate side-repo maintenance workflow for SideRepoOps pattern Apr 15, 2026
Copilot AI requested a review from pelikhan April 15, 2026 07:03
@github-actions
Copy link
Copy Markdown
Contributor

🎉 Great work on this PR! The implementation of auto-generating side-repo maintenance workflows for the SideRepoOps pattern is well-structured and cohesive — covering the Go generation logic (collectSideRepoTargets, sanitizeRepoForFilename, generateSideRepoMaintenanceWorkflow), cross-repo JS support via GH_AW_TARGET_REPO_SLUG, and solid test coverage (284 lines). No new dependencies were introduced, and the PR description clearly explains the problem and all changes. This looks ready for maintainer review! 🚀

Generated by Contribution Check · ● 1.9M ·

Comment thread actions/setup/js/close_expired_discussions.cjs Outdated
@pelikhan pelikhan marked this pull request as ready for review April 15, 2026 12:58
Copilot AI review requested due to automatic review settings April 15, 2026 12:58
@github-actions
Copy link
Copy Markdown
Contributor

🧪 Test Quality Sentinel Report

Test Quality Score: 100/100

Excellent test quality

Metric Value
New/modified tests analyzed 3
✅ Design tests (behavioral contracts) 3 (100%)
⚠️ Implementation tests (low value) 0 (0%)
Tests with error/edge cases 3 (100%)
Duplicate test clusters 0
Test inflation detected No (0.67:1 ratio — 284 test lines / 423 prod lines)
🚨 Coding-guideline violations 0

Test Classification Details

Test File Classification Notes
TestCollectSideRepoTargets pkg/workflow/maintenance_workflow_test.go:828 ✅ Design 8 table-driven cases; covers nil/empty/expression/dedup edge cases; uses t.Errorf with contextual format strings
TestSanitizeRepoForFilename pkg/workflow/maintenance_workflow_test.go ✅ Design 4 table-driven cases; verifies observable string-transformation output including special-character inputs
TestGenerateSideRepoMaintenanceWorkflow pkg/workflow/maintenance_workflow_test.go ✅ Design 4 subtests exercising file generation, absence of files, conditional content, and expression-based skipping; strong behavioral assertions on generated YAML content

Flagged Tests — Requires Review

None — all new tests passed all quality checks. 🎉


Language Support

Tests analyzed:

  • 🐹 Go (*_test.go): 3 tests — unit (//go:build !integration ✅ present)
  • 🟨 JavaScript (*.test.cjs, *.test.js): 0 tests (JS files changed are CJS scripts without test counterparts)

Verdict

Check passed. 0% of new tests are implementation tests (threshold: 30%). All three tests verify genuine behavioral contracts: TestCollectSideRepoTargets checks which repositories are collected as side-repo targets (including deduplication and expression-filtering), TestSanitizeRepoForFilename verifies the filename-safe string transformation, and TestGenerateSideRepoMaintenanceWorkflow validates the generated YAML content for multiple scenarios including the no-expires and expression-based-repo edge cases.


📖 Understanding Test Classifications

Design Tests (High Value) verify what the system does:

  • Assert on observable outputs, return values, or state changes
  • Cover error paths and boundary conditions
  • Would catch a behavioral regression if deleted
  • Remain valid even after internal refactoring

Implementation Tests (Low Value) verify how the system does it:

  • Assert on internal function calls (mocking internals)
  • Only test the happy path with typical inputs
  • Break during legitimate refactoring even when behavior is correct
  • Give false assurance: they pass even when the system is wrong

Goal: Shift toward tests that describe the system's behavioral contract — the promises it makes to its users and collaborators.

References: §24455822796

🧪 Test quality analysis by Test Quality Sentinel · ● 459.8K ·

Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

✅ Test Quality Sentinel: 100/100. Test quality is excellent — 0% of new tests are implementation tests (threshold: 30%). All 3 new tests verify genuine behavioral contracts with comprehensive edge-case coverage and no coding-guideline violations.

@github-actions
Copy link
Copy Markdown
Contributor

Commit pushed: 65cd06e

🏗️ ADR gate enforced by Design Decision Gate 🏗️

@github-actions
Copy link
Copy Markdown
Contributor

🏗️ Design Decision Gate — ADR Required

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

AI has analyzed the PR diff and generated a draft ADR to help you get started:

📄 Draft ADR: docs/adr/26382-auto-generate-side-repo-maintenance-workflows.md

What to do next

  1. Review the draft ADR committed to your branch — it was generated from the PR diff
  2. Complete the missing sections — add context the AI couldn't infer, refine the decision rationale, and list real alternatives you considered
  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-26382: Auto-Generate Side-Repo Maintenance Workflows for SideRepoOps Pattern

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. 26382-auto-generate-side-repo-maintenance-workflows.md for PR #26382).

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

References: §24455822765

Note

🔒 Integrity filter blocked 1 item

The following item were blocked because they don't meet the GitHub integrity level.

To allow these resources, lower min-integrity in your GitHub frontmatter:

tools:
  github:
    min-integrity: approved  # merged | approved | unapproved | none

🏗️ ADR gate enforced by Design Decision Gate 🏗️ · ● 133.9K ·

Copy link
Copy Markdown
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 first-class SideRepoOps support by generating per-target maintenance workflows and enabling existing JS maintenance scripts to operate against a target repo (via GH_AW_TARGET_REPO_SLUG) instead of always using context.repo.

Changes:

  • Generate agentics-maintenance-<owner-repo>.yml side-repo maintenance workflows based on checkout configs with current: true.
  • Add cross-repo targeting support to maintenance JS scripts (create_labels, close-expired-*).
  • Add Go tests for side-repo target collection, filename sanitization, and side-repo workflow generation.
Show a summary per file
File Description
pkg/workflow/maintenance_workflow.go Adds side-repo target detection and emits per-target maintenance workflows; calls side-repo generation even when expires isn’t used.
pkg/workflow/maintenance_workflow_test.go Adds tests covering side-repo target detection and side-repo workflow generation behavior.
actions/setup/js/create_labels.cjs Uses GH_AW_TARGET_REPO_SLUG (when valid) to create labels in a target repo.
actions/setup/js/close_expired_discussions.cjs Resolves owner/repo from GH_AW_TARGET_REPO_SLUG to close expired discussions cross-repo.
actions/setup/js/close_expired_issues.cjs Resolves owner/repo from GH_AW_TARGET_REPO_SLUG to close expired issues cross-repo.
actions/setup/js/close_expired_pull_requests.cjs Resolves owner/repo from GH_AW_TARGET_REPO_SLUG to close expired PRs cross-repo.

Copilot's findings

Tip

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

  • Files reviewed: 7/7 changed files
  • Comments generated: 9

Comment thread pkg/workflow/maintenance_workflow.go Outdated
Comment thread pkg/workflow/maintenance_workflow.go Outdated
Comment on lines +869 to +871
This workflow is generated for the SideRepoOps target repository "` + repoSlug + `".
It is invoked via workflow_call from the hosting repository's agentics-maintenance.yml
and runs maintenance operations against the target repository.`
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

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

The side-repo workflow header/instructions state it "is invoked via workflow_call from the hosting repository's agentics-maintenance.yml", but this generator does not add any caller job/step to agentics-maintenance.yml (and there are no other references to agentics-maintenance-.yml in this file). Either update the hosting maintenance workflow generation to actually call these reusable workflows, or adjust the generated instructions so they don’t claim an invocation path that doesn’t exist.

Copilot uses AI. Check for mistakes.
Comment thread pkg/workflow/maintenance_workflow.go Outdated
Comment thread actions/setup/js/create_labels.cjs Outdated
Comment on lines +89 to +98
// Fetch all existing labels from the repository.
// When GH_AW_TARGET_REPO_SLUG is set (SideRepoOps pattern), create labels in that
// repository instead of the execution context repository.
// The slug must be in exact "owner/repo" format (one slash, non-empty on both sides).
const targetRepoSlug = process.env.GH_AW_TARGET_REPO_SLUG;
const isCrossRepo = Boolean(targetRepoSlug && /^[^/]+\/[^/]+$/.test(targetRepoSlug));
const [owner, repo] = isCrossRepo ? targetRepoSlug.split("/", 2) : [context.repo.owner, context.repo.repo];
if (isCrossRepo) {
core.info(`Using target repository from GH_AW_TARGET_REPO_SLUG: ${owner}/${repo}`);
}
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

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

This code treats GH_AW_TARGET_REPO_SLUG as optional and silently falls back to context.repo when it’s set but invalid. That contradicts the preceding comment that the slug "must" be in exact owner/repo format and can lead to label creation happening in the wrong repo without any signal. Consider reusing the existing repo parsing/validation helpers in actions/setup/js/repo_helpers.cjs (e.g., parseRepoSlug) and calling core.setFailed (or at least core.warning) when GH_AW_TARGET_REPO_SLUG is present but malformed.

Copilot uses AI. Check for mistakes.
Comment thread actions/setup/js/close_expired_pull_requests.cjs Outdated
Comment on lines +53 to +55
const isCrossRepo = Boolean(targetRepoSlug && /^[^/]+\/[^/]+$/.test(targetRepoSlug));
const [owner, repo] = isCrossRepo ? targetRepoSlug.split("/", 2) : [context.repo.owner, context.repo.repo];
if (isCrossRepo) {
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

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

This script silently ignores GH_AW_TARGET_REPO_SLUG when it’s set but malformed, despite the comment stating it must be in exact owner/repo format. That can cause the cleanup to run against context.repo unexpectedly. Consider centralizing slug parsing via actions/setup/js/repo_helpers.cjs (parseRepoSlug / resolveAndValidateRepo) and failing (or at least warning) when GH_AW_TARGET_REPO_SLUG is present but invalid.

Suggested change
const isCrossRepo = Boolean(targetRepoSlug && /^[^/]+\/[^/]+$/.test(targetRepoSlug));
const [owner, repo] = isCrossRepo ? targetRepoSlug.split("/", 2) : [context.repo.owner, context.repo.repo];
if (isCrossRepo) {
const hasTargetRepoSlug = typeof targetRepoSlug === "string" && targetRepoSlug.length > 0;
const isValidTargetRepoSlug = hasTargetRepoSlug && /^[^/]+\/[^/]+$/.test(targetRepoSlug);
if (hasTargetRepoSlug && !isValidTargetRepoSlug) {
throw new Error(
`Invalid GH_AW_TARGET_REPO_SLUG: "${targetRepoSlug}". Expected exact "owner/repo" format.`,
);
}
const [owner, repo] = isValidTargetRepoSlug
? targetRepoSlug.split("/", 2)
: [context.repo.owner, context.repo.repo];
if (isValidTargetRepoSlug) {

Copilot uses AI. Check for mistakes.
Comment thread actions/setup/js/close_expired_discussions.cjs Outdated
}
fmt.Fprintf(os.Stderr, " Generated side-repo maintenance workflow: %s\n", filename)
}

Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

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

generateAllSideRepoMaintenanceWorkflows builds a generatedFiles map (and the comment says it will be used to clean up stale files), but the map is never read and no cleanup actually happens. As-is, stale agentics-maintenance-.yml files will accumulate when targets are removed/renamed. Either implement the cleanup (e.g., scan workflowDir for agentics-maintenance-.yml not in generatedFiles and remove them) or drop the unused tracking/comment to avoid misleading future readers.

Suggested change
entries, err := os.ReadDir(workflowDir)
if err != nil {
return fmt.Errorf("failed to read workflow directory %s for stale side-repo maintenance workflow cleanup: %w", workflowDir, err)
}
for _, entry := range entries {
if entry.IsDir() {
continue
}
name := entry.Name()
if !strings.HasPrefix(name, "agentics-maintenance-") || !strings.HasSuffix(name, ".yml") {
continue
}
if generatedFiles[name] {
continue
}
stalePath := filepath.Join(workflowDir, name)
maintenanceLog.Printf("Removing stale side-repo maintenance workflow: %s", name)
if err := os.Remove(stalePath); err != nil {
return fmt.Errorf("failed to remove stale side-repo maintenance workflow %s: %w", stalePath, err)
}
}

Copilot uses AI. Check for mistakes.
Comment thread pkg/workflow/maintenance_workflow.go Outdated
@pelikhan
Copy link
Copy Markdown
Collaborator

@copilot review all comments

…s for cross-repo parsing

Agent-Logs-Url: https://github.com/github/gh-aw/sessions/b6e9b78c-2911-4790-afd2-19c256e942ed

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 15, 2026

Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • https://api.github.com/graphql
    • Triggering command: /usr/bin/gh /usr/bin/gh api graphql -f query=query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -f owner=github -f name=gh-aw (http block)
  • https://api.github.com/repos/actions/ai-inference/git/ref/tags/v1
    • Triggering command: /usr/bin/gh gh api /repos/actions/ai-inference/git/ref/tags/v1 --jq .object.sha -unreachable=false /tmp/go-build3317151021/b119/vet.cfg /opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linux_amd64/vet re --log-level=egit (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v3
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v3 --jq .object.sha --noprofile (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v5
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha th .prettierignore --log-level=error pull.rebase es/.bin/node (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha --show-toplevel -tests /usr/bin/git get --local sh git rev-�� --show-toplevel git /usr/bin/git th .prettierignogit user.name h git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha --show-toplevel x_amd64/vet /usr/bin/git npx prettier --cgit (http block)
  • https://api.github.com/repos/actions/github-script/git/ref/tags/v8
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq .object.sha --show-toplevel git /usr/bin/git json&#39; --ignore-pgrep committer.email p/bin/sh git rev-�� --show-toplevel git /usr/bin/git flib/difflib.go (http block)
  • https://api.github.com/repos/actions/github-script/git/ref/tags/v9
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v9 --jq .object.sha 7151021/b368/_pkg_.a (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v9 --jq .object.sha /tmp/go-build3317151021/b125/_pkg_.a -trimpath 7151021/b261/vet.cfg -p github.com/aymanrev-parse -lang=go1.24 /opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linux_amd64/vet -ato�� -bool -buildtags /opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linux_amd64/vet -errorsas -ifaceassert -nilfunc /opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linux_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v9 --jq .object.sha /tmp/go-build3317151021/b358/_pkg_.a -trimpath /opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linux_amd64/vet -p github.com/pmezarev-parse -lang=go1.16 /opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linux_amd64/vet -uns�� -unreachable=false /tmp/go-build3317151021/b114/vet.cfg /opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linux_amd64/vet -c=4 -nolocalimports -importcfg /opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linux_amd64/vet (http block)
  • https://api.github.com/repos/actions/setup-go/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v4 --jq .object.sha /tmp/go-build3317151021/b126/_pkg_.a -trimpath /opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linux_amd64/vet -p github.com/aymanrev-parse -lang=go1.24 /opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linux_amd64/vet -ato�� -bool -buildtags /opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linux_amd64/vet -errorsas -ifaceassert -nilfunc /opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linu--jq (http block)
  • https://api.github.com/repos/actions/setup-node/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v4 --jq .object.sha (http block)
  • https://api.github.com/repos/actions/upload-artifact/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/upload-artifact/git/ref/tags/v4 --jq .object.sha te &#39;scripts/**/*.js&#39; --ignore-path .prettierigno-errorsas .cfg 64/pkg/tool/linux_amd64/vet tierignore (http block)
  • https://api.github.com/repos/actions/upload-artifact/git/ref/tags/v7
    • Triggering command: /usr/bin/gh gh api /repos/actions/upload-artifact/git/ref/tags/v7 --jq .object.sha th .prettierigno-errorsas copilot/support--ifaceassert n-dir/node (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/upload-artifact/git/ref/tags/v7 --jq .object.sha heck &#39;**/*.cjs&#39; &#39;**/*.ts&#39; &#39;**/*.json&#39; --ignore-path ../../../.pr**/*.json (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/upload-artifact/git/ref/tags/v7 --jq .object.sha &#39;**/*.ts&#39; &#39;**/*.json&#39; --ignore-path ../../../.pr**/*.json (http block)
  • https://api.github.com/repos/github/gh-aw-actions/git/ref/tags/v0.1.2
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v0.1.2 --jq .object.sha 7151021/b001/workflow.test (http block)
  • https://api.github.com/repos/github/gh-aw-actions/git/ref/tags/v1.0.0
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.0.0 --jq .object.sha te &#39;scripts/**/*.js&#39; --ignore-path .prettierignore --log-level=error .cfg 64/pkg/tool/linux_amd64/vet --log-target journal-or-kmsg (http block)
  • https://api.github.com/repos/github/gh-aw-actions/git/ref/tags/v1.2.3
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.2.3 --jq .object.sha te &#39;scripts/**/*.js&#39; --ignore-path .prettierignore --log-level=error .cfg 64/pkg/tool/linux_amd64/vet &#43;30 -delete ode-gyp-bin/sh 64/pkg/tool/linux_amd64/vet k/gh�� --noprofile .cfg 64/pkg/tool/linux_amd64/vet ath ../../../.prgit (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/v0.47.4
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v0.47.4 --jq .object.sha --show-toplevel git /usr/bin/git .js&#39; --ignore-pagit credential.helperev-parse ache/go/1.25.8/x--show-toplevel git rev-�� --show-toplevel git /usr/bin/git --local commit.gpgsign 1/x64/bin/bash git (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/v1.0.0
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.0.0 --jq .object.sha &#39;**/*.ts&#39; &#39;**/*.json&#39; --ignore-path ../../../.pr**/*.json --local 8d519d9/node_modules/.bin/node gpg.program (http block)
  • https://api.github.com/repos/nonexistent/action/git/ref/tags/v999.999.999
    • Triggering command: /usr/bin/gh gh api /repos/nonexistent/action/git/ref/tags/v999.999.999 --jq .object.sha &#39;**/*.ts&#39; &#39;**/*.json&#39; --ignore-path ../../../.pr**/*.json --local ules/.bin/node gpg.program (http block)

If you need me to access, download, or install something from one of these locations, you can either:

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 15, 2026

@copilot review all comments

Addressed all reviewer comments across two commits (6bc1ab3 and 0a3a930):

  1. Token preferencecollectSideRepoTargets now upgrades to a non-empty token when the same repo appears multiple times. Added tests for both token preference and first-seen order preservation.

  2. Misleading header comment — Removed "invoked via workflow_call from the hosting repository's agentics-maintenance.yml"; replaced with an accurate description of standalone trigger capability.

  3. Missing schedule: trigger — Side-repo workflow now includes a schedule: cron trigger when hasExpires is true (matching the buildNotForkAndScheduled condition used by the close-expired-entities job). Cron values are computed once and reused.

  4. Silent malformed slug fallbackresolveExecutionOwnerRepo() now throws Error: Invalid GH_AW_TARGET_REPO_SLUG: "..." when the env var is set but malformed. Tests updated.

  5. Stale file cleanupgenerateAllSideRepoMaintenanceWorkflows now removes agentics-maintenance-*.yml files not generated in the current run. Added a test.

  6. Missing checkout step — Added actions/checkout (sparse-checkout: actions) step in apply_safe_outputs for dev/script modes, matching the pattern in close-expired-entities.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • https://api.github.com/graphql
    • Triggering command: /usr/bin/gh /usr/bin/gh api graphql -f query=query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -f owner=github -f name=gh-aw **/*.cjs 64/bin/go git rev-�� --show-toplevel /opt/hostedtoolcGOPROXY /usr/bin/git /tmp/go-build296git -trimpath 64/bin/go git (http block)
    • Triggering command: /usr/bin/gh /usr/bin/gh api graphql -f query=query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -f owner=github -f name=gh-aw GO111MODULE ache/go/1.25.8/x64/bin/go git rev-�� --show-toplevel go /usr/bin/git -json GO111MODULE p/bin/bash git (http block)
    • Triggering command: /usr/bin/gh /usr/bin/gh api graphql -f query=query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -f owner=github -f name=gh-aw GO111MODULE ache/go/1.25.8/x64/bin/go git rev-�� --show-toplevel go /usr/bin/git -json GO111MODULE bash git (http block)
  • https://api.github.com/repos/actions/ai-inference/git/ref/tags/v1
    • Triggering command: /usr/bin/gh gh api /repos/actions/ai-inference/git/ref/tags/v1 --jq .object.sha -json GO111MODULE /opt/hostedtoolcache/go/1.25.8/x64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE /usr/bin/git GOINSECURE GOMOD GOMODCACHE git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/ai-inference/git/ref/tags/v1 --jq .object.sha --write **/*.cjs /home/REDACTED/node_modules/.bin/sh **/*.json --ignore-path ../../../.pretti--show-toplevel sh -c &#34;prettier&#34; --write &#39;../../../**/*.json&#39; &#39;!../../../pkg/workflow/js/**/*.json&#39; --ignore-path ../.git git /usr/bin/git elpers.cjs rsion=9c62537-direv-parse run-script/lib/n--show-toplevel git (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v3
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v3 --jq .object.sha -json GO111MODULE ache/go/1.25.8/x64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE ache/go/1.25.8/x64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v3 --jq .object.sha ae4e774c75d8e8a126541bd2:pkg/workflow/maintenance_workflow_test.go config bash son git r: $owner, name:--show-toplevel git -C /home/REDACTED/work/gh-aw/gh-aw show rgo/bin/sh nore git repository(owne--show-toplevel git (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v5
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha AdMB/DTftb_aKXvyGOINSECURE GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE 5680517/b396/impGO111MODULE -c k/gh-aw/gh-aw/pkGOINSECURE k/gh-aw/gh-aw/pkGOMOD 64/bin/go GOSUMDB GOWORK 64/bin/go /opt/hostedtoolcGOPROXY (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha --show-toplevel GOPROXY /usr/bin/git GOSUMDB GOWORK 64/bin/go git rev-�� --show-toplevel go /usr/bin/git -json GO111MODULE 64/bin/go git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha --show-toplevel go /usr/bin/git -json GO111MODULE 64/bin/go git rev-�� --show-toplevel go /usr/bin/git -json GO111MODULE 64/bin/go git (http block)
  • https://api.github.com/repos/actions/github-script/git/ref/tags/v8
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq .object.sha --show-toplevel go /usr/bin/git -json GO111MODULE 64/bin/go git rev-�� --show-toplevel node /usr/bin/git --check **/*.cjs 64/bin/go git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq .object.sha --show-toplevel node /usr/bin/git h ../../../.pretgrep po maintenance w^From [0-9a-f]\{40\} (http block)
  • https://api.github.com/repos/actions/github-script/git/ref/tags/v9
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v9 --jq .object.sha -json GO111MODULE /opt/hostedtoolcache/go/1.25.8/x64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE /opt/hostedtoolcache/go/1.25.8/x64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v9 --jq .object.sha --show-toplevel go /usr/bin/git -json GO111MODULE 64/bin/go git rev-�� heckout/git/ref/tags/v3 go /usr/bin/git -json GO111MODULE 64/bin/go git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v9 --jq .object.sha --noprofile git /node_modules/.bin/node go git ache/node/24.14.--show-toplevel node /opt�� prettier --write /bin/sh **/*.ts **/*.json --ignore-path /bin/sh (http block)
  • https://api.github.com/repos/actions/setup-go/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v4 --jq .object.sha -json GO111MODULE /opt/hostedtoolcache/go/1.25.8/x64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE /opt/hostedtoolcache/go/1.25.8/x64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v4 --jq .object.sha --noprofile docker-compose /home/node_modules/.bin/sh ./../.prettieriggit git ache/node/24.14.--show-toplevel sh -c &#34;prettier&#34; --write &#39;**/*.cjs&#39; &#39;**/*.ts&#39; &#39;**/*.json&#39; --ignore-path ../../../.prettierignore git /node_modules/.bin/sh ithub/workflows git ry sh (http block)
  • https://api.github.com/repos/actions/setup-node/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v4 --jq .object.sha -json GO111MODULE /opt/hostedtoolcache/go/1.25.8/x64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE /opt/hostedtoolcache/go/1.25.8/x64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v4 --jq .object.sha --noprofile git /home/REDACTED/work/node_modules/.bin/sh ./../.prettieriggit git r: $owner, name:--show-toplevel sh -c &#34;prettier&#34; --write &#39;**/*.cjs&#39; &#39;**/*.ts&#39; &#39;**/*.json&#39; --ignore-path ../../../.prettierignore git /home/REDACTED/node_modules/.bin/sh --show-toplevel git sionclean sh (http block)
  • https://api.github.com/repos/actions/upload-artifact/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/upload-artifact/git/ref/tags/v4 --jq .object.sha -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/upload-artifact/git/ref/tags/v4 --jq .object.sha &#39;**/*.ts&#39; &#39;**/*.json&#39; --ignore-path ../../../.pr**/*.json -f cal/bin/git -f owner=github -f git -C .js&#39; --ignore-path .prettierignore --log-level=e!../../../pkg/workflow/js/**/*.json config k/_temp/uv-python-dir/bash elete rl: https://githrev-parse ae4e774c75d8e8a1--show-toplevel git (http block)
  • https://api.github.com/repos/actions/upload-artifact/git/ref/tags/v7
    • Triggering command: /usr/bin/gh gh api /repos/actions/upload-artifact/git/ref/tags/v7 --jq .object.sha che/go-build/f9/GOINSECURE **/*.cjs 64/bin/go **/*.json --ignore-path ../../../.pretti--show-toplevel /opt/hostedtoolcGOPROXY -o /tmp/go-build296GOSUMDB -trimpath 64/bin/go -p github.com/githurev-parse -lang=go1.25 go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/upload-artifact/git/ref/tags/v7 --jq .object.sha --check scripts/**/*.js 64/bin/go .prettierignore (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/upload-artifact/git/ref/tags/v7 --jq .object.sha /tmp/go-build296GOSUMDB -trimpath 64/bin/go -p main -lang=go1.25 go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/astral-sh/setup-uv/git/ref/tags/eac588ad8def6316056a12d4907a9d4d84ff7a3b
    • Triggering command: /usr/bin/gh gh api /repos/astral-sh/setup-uv/git/ref/tags/eac588ad8def6316056a12d4907a9d4d84ff7a3b --jq .object.sha --show-toplevel go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/astral-sh/setup-uv/git/ref/tags/eac588ad8def6316056a12d4907a9d4d84ff7a3b --jq .object.sha --show-toplevel go /usr/bin/git -json GO111MODULE /opt/hostedtoolc--noprofile git rev-�� --show-toplevel go /usr/bin/git -json GO111MODULE /opt/hostedtoolcxterm-color git (http block)
  • https://api.github.com/repos/docker/build-push-action/git/ref/tags/v7
    • Triggering command: /usr/bin/gh gh api /repos/docker/build-push-action/git/ref/tags/v7 --jq .object.sha --oneline -10 /usr/bin/git GOPATH GOPROXY /usr/bin/git git rev-�� --show-toplevel git 1/x64/bin/node --show-toplevel &#34;$k=&#34;.$v[&#34;local-C /usr/bin/git git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/docker/build-push-action/git/ref/tags/v7 --jq .object.sha &#34;type&#34;[[:space:]]*:[[:space:]]*&#34;(create_pull_request|push_to_pull_request_branch)&#34; /opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linux_amd64/cgo $name) { hasDiscussionsEnabled } } GOPATH GOPROXY /usr/bin/git git rev-�� --show-toplevel git r: $owner, name:-f --show-toplevel go /usr/bin/git git (http block)
  • https://api.github.com/repos/github/gh-aw-actions/git/ref/tags/v0.1.2
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v0.1.2 --jq .object.sha -json GO111MODULE /opt/hostedtoolcache/go/1.25.8/x64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 179385/b123/vet.cfg GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v0.1.2 --jq .object.sha 401386/b001/workflow.test git 401386/b001/importcfg.link go git me: String!) { --show-toplevel jRn21Z7x5OcuI/SfVKi1NnYSq-1--IUG64/rLjML9eFUZtiHgu0i9fb/b0k__wXjRn21Z7x5OcuI /opt�� ry=1 --write che/go-build/96/967f1b6d6e761d6a23cca557d087c35a4573701c39afefb22b0460270cd3c65b-d **/*.ts **/*.json --ignore-path node (http block)
  • https://api.github.com/repos/github/gh-aw-actions/git/ref/tags/v1.0.0
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.0.0 --jq .object.sha -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/bash GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.0.0 --jq .object.sha &#39;**/*.ts&#39; &#39;**/*.json&#39; --ignore-path ../../../.pr**/*.json show /usr/bin/git initial.txt go /usr/bin/git git -C .js&#39; --ignore-path .prettierignore --log-level=error rev-parse ules/.bin/node --show-toplevel git $name) { has--show-toplevel /usr/bin/gh (http block)
  • https://api.github.com/repos/github/gh-aw-actions/git/ref/tags/v1.2.3
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.2.3 --jq .object.sha -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE ache/go/1.25.8/x64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.2.3 --jq .object.sha &#39;**/*.ts&#39; &#39;**/*.json&#39; --ignore-path ../../../.pr**/*.json rev-parse /usr/bin/git user.email test@example.comrev-parse /usr/bin/git git -C .js&#39; --ignore-path .prettierignore --log-level=error config tions/node_modules/.bin/node elete rl: https://githrev-parse ae4e774c75d8e8a1--show-toplevel git (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/v0.47.4
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v0.47.4 --jq .object.sha --show-toplevel go /usr/bin/git -json GO111MODULE 64/bin/go git rev-�� --show-toplevel sh /usr/bin/git npx prettier --c/bin/sh GOPROXY 64/bin/go git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v0.47.4 --jq .object.sha --show-toplevel node /usr/bin/git k/gh-aw/gh-aw/.ggit git lock.yml git rev-�� --show-toplevel node /usr/bin/git k/gh-aw/gh-aw git kflows/daily-mcpgit-upload-pack &#39;origin&#39; git (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/v1.0.0
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.0.0 --jq .object.sha GOSUMDB GOWORK 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE sh (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.0.0 --jq .object.sha ignore-path ../../../.prettierignore git 86_64/node --show-toplevel go /usr/bin/git node 1/x6�� k/gh-aw/gh-aw/.github/workflows git /usr/bin/sed l go ed } } sed (http block)
  • https://api.github.com/repos/githubnext/agentics/git/ref/tags/-
    • Triggering command: /usr/bin/gh gh api /repos/githubnext/agentics/git/ref/tags/- --jq .object.sha --show-toplevel go /usr/bin/git -json GO111MODULE /opt/hostedtoolc/home/REDACTED/work/gh-aw/gh-aw/.github/workflows git s --show-toplevel go /usr/bin/basename -json GO111MODULE /opt/hostedtoolc/home/REDACTED/work/gh-aw/gh-aw/.github/workflows basename (http block)
  • https://api.github.com/repos/nonexistent/action/git/ref/tags/v999.999.999
    • Triggering command: /usr/bin/gh gh api /repos/nonexistent/action/git/ref/tags/v999.999.999 --jq .object.sha GOSUMDB GOWORK 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE sh (http block)
    • Triggering command: /usr/bin/gh gh api /repos/nonexistent/action/git/ref/tags/v999.999.999 --jq .object.sha ignore-path ../../../.prettierignore git repository(owner: $owner, name:-f --show-toplevel go /usr/bin/gh node 1/x6�� 64/bin/go gh er: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabl--write /repos/actions/csh --jq /usr/bin/git sed (http block)

If you need me to access, download, or install something from one of these locations, you can either:

@pelikhan
Copy link
Copy Markdown
Collaborator

@copilot use fuzzy scheduling to scatter cron

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 15, 2026

@copilot use fuzzy scheduling to scatter cron

Done in 7ad9368. Added generateSideRepoMaintenanceCron(repoSlug, minExpiresDays) which uses FNV-1a hash of the repo slug to derive a deterministic but unique minute (0-59) and, for sub-daily schedules, a scattered start-hour. Different repos now get different cron offsets:

my-org/target-repo   →  11 8 * * *  (Daily)
company/service-a    →  38 2 * * *  (Daily)
company/service-b    →   7 8 * * *  (Daily)
company/service-c    →  36 14 * * *  (Daily)

The frequency tier (every 2h / 6h / 12h / daily) is still determined by minExpiresDays — only the offsets within the period are scattered. Added TestGenerateSideRepoMaintenanceCron to verify determinism, valid minute range, and frequency-tier correctness.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • https://api.github.com/graphql
    • Triggering command: /usr/bin/gh /usr/bin/gh api graphql -f query=query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -f owner=github -f name=gh-aw (http block)
  • https://api.github.com/repos/actions/ai-inference/git/ref/tags/v1
    • Triggering command: /usr/bin/gh gh api /repos/actions/ai-inference/git/ref/tags/v1 --jq .object.sha --write **/*.cjs /node_modules/.bin/sh **/*.json --ignore-path ../../../.pretti--show-toplevel sh -c &#34;prettier&#34; --write &#39;../../../**/*.json&#39; &#39;!../../../pkg/workflow/js/**/*.json&#39; --ignore-path ../.git (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v3
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v3 --jq .object.sha se 6330097/b246/vet.cfg p/bin/bash son -d 168.63.129.16 /opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linux_amd64/vet -uns�� -unreachable=false /tmp/go-build2736330097/b006/vet.cfg cal/bin/sh nore (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v5
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha ath ../../../.pr**/*.json (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha --show-toplevel (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha --show-toplevel 64/pkg/tool/linux_amd64/vet /usr/bin/git ../pkg/workflow/git --local 64/pkg/tool/linu--show-toplevel git rev-�� --show-toplevel 64/pkg/tool/linux_amd64/link /usr/bin/git kflow.test 6330097/b031/vetrev-parse ode git (http block)
  • https://api.github.com/repos/actions/github-script/git/ref/tags/v8
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq .object.sha --show-toplevel x_amd64/vet /usr/bin/git h ../../../.pretgrep (http block)
  • https://api.github.com/repos/actions/github-script/git/ref/tags/v9
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v9 --jq .object.sha -bool -buildtags /node_modules/.bin/node -errorsas -ifaceassert -nilfunc node /opt�� prettier --write /home/REDACTED/work/_temp/uv-python-dir/node **/*.ts **/*.json --ignore-path node (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v9 --jq .object.sha --noprofile -tests /opt/hostedtoolcache/node/24.14.1/x64/lib/node_modules/npm/node_modules/@npmcli/run-script/lib/n--show-toplevel ./../.prettieriggit (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v9 --jq .object.sha --noprofile -tests /home/REDACTED/work/gh-aw/gh-aw/actions/node_modules/.bin/sh ./../.prettieriggit (http block)
  • https://api.github.com/repos/actions/setup-go/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v4 --jq .object.sha --noprofile (http block)
  • https://api.github.com/repos/actions/setup-node/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v4 --jq .object.sha --noprofile -tests /home/REDACTED/work/node_modules/.bin/sh ./../.prettieriggit (http block)
  • https://api.github.com/repos/actions/upload-artifact/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/upload-artifact/git/ref/tags/v4 --jq .object.sha --local committer.email .cfg (http block)
  • https://api.github.com/repos/actions/upload-artifact/git/ref/tags/v7
    • Triggering command: /usr/bin/gh gh api /repos/actions/upload-artifact/git/ref/tags/v7 --jq .object.sha (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/upload-artifact/git/ref/tags/v7 --jq .object.sha js/**/*.json&#39; --ignore-path ../../../.prettierignore (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/upload-artifact/git/ref/tags/v7 --jq .object.sha get .cfg 64/pkg/tool/linux_amd64/vet http.https://gitgit (http block)
  • https://api.github.com/repos/github/gh-aw-actions/git/ref/tags/v0.1.2
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v0.1.2 --jq .object.sha t0 0s /home/REDACTED/.local/bin/node -errorsas -ifaceassert -nilfunc node /opt�� prettier --write /opt/hostedtoolcache/go/1.25.8/x64/bin/node **/*.ts **/*.json --ignore-path node (http block)
  • https://api.github.com/repos/github/gh-aw-actions/git/ref/tags/v1.0.0
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.0.0 --jq .object.sha &#39;**/*.ts&#39; &#39;**/*.json&#39; --ignore-path ../../../.pr**/*.json 6330097/b049/vet.cfg .cfg (http block)
  • https://api.github.com/repos/github/gh-aw-actions/git/ref/tags/v1.2.3
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.2.3 --jq .object.sha &#39;**/*.ts&#39; &#39;**/*.json&#39; --ignore-path ../../../.pr**/*.json 6330097/b051/vet.cfg .cfg (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/v0.47.4
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v0.47.4 --jq .object.sha --show-toplevel x_amd64/vet /usr/bin/git (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/v1.0.0
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.0.0 --jq .object.sha ignore-path ../../../.prettierignore (http block)
  • https://api.github.com/repos/nonexistent/action/git/ref/tags/v999.999.999
    • Triggering command: /usr/bin/gh gh api /repos/nonexistent/action/git/ref/tags/v999.999.999 --jq .object.sha ignore-path ../../../.prettierignore (http block)

If you need me to access, download, or install something from one of these locations, you can either:

@pelikhan
Copy link
Copy Markdown
Collaborator

@copilot add integration tests

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 15, 2026

@copilot add integration tests

Done in 007a21a. Added side_repo_maintenance_integration_test.go with 6 integration tests that parse real workflow frontmatter via compiler.ParseWorkflowFile, call GenerateMaintenanceWorkflow, and assert on the generated YAML:

  • TestSideRepoMaintenanceWorkflowGenerated_EndToEnd — verifies the generated file has workflow_dispatch, workflow_call, apply_safe_outputs, create_labels, GH_AW_TARGET_REPO_SLUG, and the custom token
  • TestSideRepoMaintenanceWorkflowWithExpires_EndToEnd — asserts schedule:, close-expired-entities:, and the fuzzy cron value when expires is set
  • TestSideRepoMaintenanceWorkflowFallbackToken_EndToEnd — confirms GH_AW_GITHUB_TOKEN fallback when no token is configured
  • TestNoSideRepoMaintenanceForExpressionRepository_EndToEnd — confirms no side-repo file is created for expression-based repositories
  • TestSideRepoMaintenanceFuzzyScheduleScattered_EndToEnd — verifies two different repos receive distinct cron expressions

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • https://api.github.com/graphql
    • Triggering command: /usr/bin/gh /usr/bin/gh api graphql -f query=query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -f owner=github -f name=gh-aw .cfg x_amd64/link git rev-�� --show-toplevel x_amd64/link /usr/bin/git --verify copilot/support-rev-parse odules/npm/node_--show-toplevel git (http block)
  • https://api.github.com/repos/actions/ai-inference/git/ref/tags/v1
    • Triggering command: /usr/bin/gh gh api /repos/actions/ai-inference/git/ref/tags/v1 --jq .object.sha prettier --write /opt/hostedtoolcache/node/24.14.1/x64/bin/sh --ignore-path .prettierignore --log-level=erro--show-toplevel sh -c &#34;prettier&#34; --write &#39;../../../**/*.json&#39; &#39;!../../../pkg/workflow/js/**/*.json&#39; --ignore-path ../.git x_amd64/vet /usr/bin/git (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v3
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v3 --jq .object.sha -unreachable=false /tmp/go-build2178140031/b242/vet.cfg ache/go/1.25.8/x64/pkg/tool/linux_amd64/compile son (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v5
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha ath ../../../.pr**/*.json --local er commit.gpgsign (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha --show-toplevel x_amd64/vet /usr/bin/git --local --get x_amd64/vet git rev-�� --show-toplevel x_amd64/vet /usr/bin/git ath ../../../.prgit g/workflow/checkrev-parse k/_temp/ghcca-no--show-toplevel git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha --show-toplevel ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet /usr/bin/git ../pkg/workflow/git 8140031/b062/vetrev-parse 1/x64/bin/bash git rev-�� --show-toplevel ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet /usr/bin/git --noprofile (http block)
  • https://api.github.com/repos/actions/github-script/git/ref/tags/v8
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq .object.sha --show-toplevel x_amd64/vet /usr/bin/git h ../../../.pretgrep --local 64/pkg/tool/linu/tmp/gh-aw/aw-master.patch git rev-�� --show-toplevel 64/pkg/tool/linu../../../**/*.json /usr/bin/git w/js/**/*.json&#39; git .cfg 64/pkg/tool/linu--show-toplevel git (http block)
  • https://api.github.com/repos/actions/github-script/git/ref/tags/v9
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v9 --jq .object.sha 30036/b368/_pkg_.a (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v9 --jq .object.sha --show-toplevel (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v9 --jq .object.sha --noprofile (http block)
  • https://api.github.com/repos/actions/setup-go/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v4 --jq .object.sha --show-toplevel (http block)
  • https://api.github.com/repos/actions/setup-node/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v4 --jq .object.sha -test.paniconexit0 -test.timeout=10m0s /home/REDACTED/work/gh-aw/gh-aw/actions/node_modules/.bin/sh ./../.prettieriggit (http block)
  • https://api.github.com/repos/actions/upload-artifact/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/upload-artifact/git/ref/tags/v4 --jq .object.sha &#39;**/*.ts&#39; &#39;**/*.json&#39; --ignore-path ../../../.pr**/*.json 8140031/b258/vet.cfg /home/REDACTED/.cargo/bin/bash (http block)
  • https://api.github.com/repos/actions/upload-artifact/git/ref/tags/v7
    • Triggering command: /usr/bin/gh gh api /repos/actions/upload-artifact/git/ref/tags/v7 --jq .object.sha w/js/**/*.json&#39; --ignore-path outputs_types.go../../../.prettierignore x_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/upload-artifact/git/ref/tags/v7 --jq .object.sha js/**/*.json&#39; --ignore-path ../../../.prettierignore .cfg 64/pkg/tool/linux_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/upload-artifact/git/ref/tags/v7 --jq .object.sha --abbrev-ref .cfg 64/pkg/tool/linux_amd64/vet (http block)
  • https://api.github.com/repos/github/gh-aw-actions/git/ref/tags/v0.1.2
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v0.1.2 --jq .object.sha 30036/b001/workflow.test (http block)
  • https://api.github.com/repos/github/gh-aw-actions/git/ref/tags/v1.0.0
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.0.0 --jq .object.sha &#39;**/*.ts&#39; &#39;**/*.json&#39; --ignore-path ../../../.pr**/*.json 8140031/b231/vet.cfg bash (http block)
  • https://api.github.com/repos/github/gh-aw-actions/git/ref/tags/v1.2.3
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.2.3 --jq .object.sha &#39;**/*.ts&#39; &#39;**/*.json&#39; --ignore-path ../../../.pr**/*.json 8140031/b269/vet.cfg bin/node (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/v0.47.4
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v0.47.4 --jq .object.sha --show-toplevel x_amd64/vet /usr/bin/git get --local /node git rev-�� --show-toplevel x_amd64/vet /usr/bin/git --local credential.usern-c 64/pkg/tool/linugit-upload-pack &#39;origin&#39; git (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/v1.0.0
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.0.0 --jq .object.sha ignore-path ../../../.prettierignore --local x_amd64/vet (http block)
  • https://api.github.com/repos/nonexistent/action/git/ref/tags/v999.999.999
    • Triggering command: /usr/bin/gh gh api /repos/nonexistent/action/git/ref/tags/v999.999.999 --jq .object.sha ignore-path ../../../.prettierignore --local x_amd64/vet (http block)

If you need me to access, download, or install something from one of these locations, you can either:

@pelikhan pelikhan merged commit 31ef7c6 into main Apr 15, 2026
56 of 57 checks passed
@pelikhan pelikhan deleted the copilot/support-auto-generate-agentics-yml branch April 15, 2026 14:42
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.

Support auto-generation of agentics-maintenance.yml for target repository in SideRepoOps pattern

3 participants