Skip to content

sync includes jobs from non-PR workflows (schedule/dispatch-only) as required checks → they block every PR #81

Description

@Aerendir

Problem

sync derives the required-checks set from every job matrix in every workflow file, without looking at each workflow's on: triggers. So it also includes jobs from workflows that never run on a pull request — e.g. workflows triggered on schedule (cron) or workflow_dispatch only.

Such jobs can never report a check on a PR, so once sync adds them to branch protection they stay "Waiting for status" forever and block every pull request. The user is forced to discover them and add each one to ignoreJob() by hand.

Real case that motivated this: the [Backend] Flex and [Legacy] Flex workflows (jobs backend-recipes / legacy-recipes) trigger on schedule: only (no push, no pull_request). sync added backend-recipes (…) / legacy-recipes (…) as required checks; every PR then got stuck on those two never-reported checks until they were manually excluded.

Root cause (exact location)

src/Workflow/Reader.php, method createFromYaml(). It reads name and jobs, then iterates the jobs — it never inspects the on: key:

$workflowName = $parsed['name'];
$jobs         = $parsed['jobs'];

$localJobs = new JobsCollection();
foreach ($jobs as $jobName => $jobContent) {
    // ... ignoredJobs + non-derivable checks ...
    $job = Job::createFromArray($jobName, $jobContent, $fileInfo->getFilename(), $workflowName, $jobName);
    $localJobs->addJob($job);
}

Required change

Make createFromYaml() skip all jobs of a workflow that cannot run on a pull request, i.e. whose on: triggers include none of the PR-eligible events.

Exact behavior

  1. In createFromYaml(), after $parsed = Yaml::parse(...) and the existing name/jobs checks, read the workflow triggers from $parsed['on'].
    • Note on parsing: with the pinned Symfony YAML the key is the string 'on' (verified — it is NOT converted to boolean). Read $parsed['on']. Defensively also accept the boolean/int form ($parsed[true] / $parsed[1]) in case a different YAML version normalizes it, but do not depend on it.
  2. Normalize the trigger value to a set of event names. GitHub allows three shapes — all must be handled:
    • string: on: push['push']
    • list: on: [push, pull_request]['push', 'pull_request']
    • map: on:\n push:\n pull_request:\n types: [...] → the map keys ['push', 'pull_request']
  3. Define the PR-eligible event set exactly as: push, pull_request, pull_request_target. (Everything else — schedule, workflow_dispatch, workflow_call, repository_dispatch, etc. — is non-gating.)
  4. If the workflow's triggers contain at least one PR-eligible event → process its jobs as today.
    If they contain none (or on: is missing/empty) → skip the entire workflow's jobs (contribute nothing to the collection) and record a warning via the existing JobsCollection::addWarning() channel (same one used for non-derivable contexts), naming the workflow and explaining why, e.g.:

    Workflow "[Backend] Flex" is not triggered by push/pull_request (triggers: schedule); its jobs are excluded from the required-checks set because they can never report a check on a pull request.

  5. ignoreJob() and the non-derivable-context handling must keep working unchanged for workflows that ARE processed.

Acceptance criteria

  • A workflow with on: { schedule: [...] } (no push/pull_request) contributes zero jobs to the computed set, and emits the explanatory warning.
  • A workflow with on: [push], on: push, on: { pull_request: ... }, or on: { push: ..., pull_request: ... } contributes its jobs exactly as before.
  • A workflow with on: { workflow_dispatch: {} } only → zero jobs.
  • Mixed: on: { push: ..., schedule: [...] } → jobs INCLUDED (push is present).
  • Existing behavior for ignoreJob, non-derivable contexts, and requiredChecks (external bare-name checks) is unchanged.
  • Add unit tests in the existing Workflow/Reader test suite covering each shape above (string / list / map) and the schedule-only / dispatch-only / mixed cases. Follow the existing test structure and fixtures.

Docs

Update README.md: state that sync only considers jobs from workflows triggered by push / pull_request / pull_request_target; jobs from schedule-only or dispatch-only workflows are automatically excluded from the required-checks set (so you no longer need to ignoreJob() them).

Guardrails (do not wander)

  • Touch ONLY src/Workflow/Reader.php, README.md, and the relevant test file(s) (+ a test fixture if the suite uses fixture files).
  • Do NOT change Job, JobsCollection, the CLI, the config API, or any command flow beyond what is described.
  • Do NOT add new dependencies.
  • Keep the diff minimal and focused; keep the existing test suite / static analysis green.

Metadata

Metadata

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions