Skip to content

Bug: --schedule-seed is silently overridden by per-file git-remote detection during compile #31098

@trask

Description

@trask

Summary

gh aw compile --schedule-seed owner/repo is silently overridden by per-file git-remote detection during workflow processing, so the flag has no effect when compiling inside a repository whose origin (or sole remote) resolves to a different owner/repo.

This was discovered while investigating why gh aw compile produces different scattered cron values on a fork checkout vs the upstream CI checkout (related to #31018, #24384). The documented workaround in those issues — passing --schedule-seed — currently does not apply.

Affects v0.71.5 and main as of 2026-05-08.

Reproduction

In any clone whose origin remote does not match the upstream slug (e.g. a fork: origin = trask/gh-aw):

gh aw compile some-workflow --schedule-seed github/gh-aw

Expected: scattered cron values are computed from seed github/gh-aw/<workflow-rel-path>.
Actual: scattered cron values are computed from seed trask/gh-aw/<workflow-rel-path> (the per-file remote-derived slug).

Concretely, in my repo the lockfile diff shows cron: "9 */1 * * *" (from my fork's slug) instead of cron: "26 */1 * * *" (the upstream CI's slug), and --schedule-seed open-telemetry/opentelemetry-java-instrumentation does not change the output.

Root cause

pkg/cli/compile_compiler_setup.go::setupRepositoryContext correctly honors --schedule-seed:

if config.ScheduleSeed != "" {
    ...
    compiler.SetRepositorySlug(config.ScheduleSeed)
    compileCompilerSetupLog.Printf("Repository slug overridden via --schedule-seed: %s", config.ScheduleSeed)
    return
}

But pkg/cli/compile_workflow_processor.go::processAndValidateWorkflow is then called per workflow file and unconditionally overwrites it:

// Set repository slug for this specific file (may differ from CWD's repo)
fileRepoSlug := getRepositorySlugFromRemoteForPath(resolvedFile)
if fileRepoSlug != "" {
    compiler.SetRepositorySlug(fileRepoSlug)
    compileWorkflowProcessorLog.Printf("Repository slug for file set: %s", fileRepoSlug)
}

There is no check for whether the slug was explicitly overridden via --schedule-seed (or set via the higher-precedence path in setupRepositoryContext), so the per-file detection wins.

Proposed fix

Track whether the slug was set via --schedule-seed (or any explicit override) and skip the per-file overwrite in that case. Two reasonable shapes:

  1. Plumb the flag: pass config.ScheduleSeed into processAndValidateWorkflow and skip the fileRepoSlug block when it is non-empty and valid.
  2. Add a boolean on Compiler: e.g. c.repositorySlugLocked = true set by setupRepositoryContext when --schedule-seed is honored; have SetRepositorySlug no-op when locked, or expose SetRepositorySlugIfUnset.

Option 2 keeps the wiring local. Either way:

  • The per-file fallback should still apply when no explicit seed was provided (to support --workflow path/to/file.md that lives in a different repo than CWD, which is the comment's stated motivation).
  • The validation/invalid-seed warning path in setupRepositoryContext should not engage the lock.

Tests to add

  • TestCompile_ScheduleSeedOverridesGitRemote: in a temp repo whose origin is trask/gh-aw, run compile with --schedule-seed github/gh-aw against a workflow with a fuzzy schedule, and assert the produced cron matches the upstream-seed scatter.
  • TestCompile_NoScheduleSeed_PerFileRemoteStillUsed: regression — without --schedule-seed, multi-repo workflow paths still pick up their per-file slug.

Out of scope

  • The Windows Merge remote .github folder drop is a separate bug — see #31097.
  • Parsing GHE SSH remote URLs is #31018.

Environment

  • gh aw v0.71.5 and main as of 2026-05-08
  • Reproduced on Windows 11 (git-bash). Code path is OS-independent — the same override happens on Linux/macOS.

Metadata

Metadata

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions