Skip to content

ci-lint: implement ci.yml#23 rules (ci-pre.yml name, janitor concurrency, pr-<N> keys, install-free) #51

Closed

Description

@zackees

The ci-lint side of #23, none of which exists yet:

  • flag ci-precheck.yml and require the ci-pre.yml name;
  • flag a workflow-level concurrency in ci-pre.yml;
  • flag any job other than the janitor that has concurrency or needs: cache-janitor;
  • flag a janitor without the repo-wide group;
  • flag a PR-context cache save without a pr-<N> key component;
  • flag an install step in ci-pre.yml.

Also:

  • make the cache classifier accept the delimited pr-<N> form;
  • add janitor LRU convergence and a grace window;
  • make the budget verdict warn-only in PR context.

Rename across examples, fixtures and #6's design text. Reference template issue: zackees/template-python-rust-cmd (adopt ci-pre.yml).

Activity

  1. zackees commented on Sep 29, 2026

    @zackees
    OwnerAuthor

    Implemented by #60, squash-merged as af6d22d.

    ci-lint side of #23:

    • Rename: ci-pre.yml is the canonical name. GEN-014 flags a ci-precheck.yml file, a uses: of one, or an [allow].workflows key naming it. The example, every fixture (CT-004, GEN-008, CACHE-009, _e2e and the rest) and the docs are renamed.
    • Concurrency:
      • GEN-015 flags a workflow-level concurrency in ci-pre.yml. WF-002 now exempts that file.
      • GEN-016 flags a job other than cache-janitor that has concurrency or needs: cache-janitor.
      • GEN-017 flags a janitor that lacks { group: cache-janitor, cancel-in-progress: false }.
    • Installs: GEN-018 flags an install step in ci-pre.yml.
    • PR cache keys: CACHE-013 flags a PR-reachable cache save without a delimited pr-<N> key component. The planner has a new --github-output key, cache_key_pr, which holds pr-<N> on a PR and is empty elsewhere.
    • Classifier: it recognizes a delimited pr-<N> anywhere in a key, still accepts the legacy delta-v1-pr<N> form, and treats a refs/pull/<N>/merge ref as belonging to PR N.
    • Janitor:
      • Deletes every entry of a closed or merged PR. A failed lookup keeps them.
      • Evicts least-recently-used entries in families marked with the new evict = "lru" key.
      • Keeps the newest entry per key prefix for other families.
      • Never deletes the newest entry a required job restores.
      • Never deletes an entry younger than 10 minutes.
    • ci-lint cache budget:
      • PR context: warn-only, except for the PR's own pr-<N> entries.
      • Default branch, schedule and dispatch: a hard fail when over budget.

    Rule IDs are GEN-014..018 and CACHE-013 because GEN-012, GEN-013 and CACHE-010..012 were taken by #57, #61 and #62 while this was in flight.

    Validation: there is no CI in ci.yml, so the selftest pair is the validation (435 tests):

    • uv run --no-project --with pyyaml python3 -m ci_lint selftest: OK
    • python3 -S -m ci_lint selftest (PyYAML not importable): OK (skipped=63)

    The RED/GREEN output for every rule is in the PR body.

    Not done here:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions