Skip to content

Releases: zmaril/housekeeping

v0.21.0

Choose a tag to compare

@zmaril zmaril released this 18 Jul 21:38
e1a2ed8

Adds the strict-status-checks check, and fixes three defects in v0.20.0 that
surfaced while rolling it out across the fleet — two of which made v0.20.0's own
housekeeper fix unsafe to run.

Fixed

  • fix ci-exists no longer overwrites existing CI: it wrote
    .github/workflows/ci.yml unconditionally, but ci-exists fails two different
    ways — no CI at all, or CI that exists and is merely missing a test/lint/fmt step
    for some language — and the scaffold only answers the first. On a repo whose CI
    simply lacked a rust step, the fix replaced the entire hand-written workflow with
    a generic stub. It now scaffolds only when there is no workflow at all, and
    otherwise prints the missing steps to add by hand.
  • lockfiles no longer demands a lockfile that cannot exist: a package
    declaring no dependencies has no lockfile to produce (bun deletes an empty one
    outright), so the only way to pass was to fabricate a foreign lockfile. Such a
    package is now skipped, and the skip is surfaced in the note rather than passing
    silently. An unparseable manifest still counts as having dependencies, so a broken
    file can't quietly downgrade the check.
  • lockfiles gained an ignore list: nested-aware detection started grading
    packages whose lockfiles are gitignored on purpose. A repo can now exempt those
    directories with [lockfiles] ignore = ["spike", "crates/demo"].
  • repo-meta ignores markers inside fenced code blocks: read_markers scanned
    the whole README and let later matches win, so a README documenting the marker
    syntax had its own fenced example parsed as the declaration — silently overriding
    the real markers above it. housekeeping's own README hit this, and
    housekeeper fix repo-meta would have pushed the doc placeholder over the repo's
    real description and topics.

New checks

  • strict-status-checks (required, fixable): the default branch must require
    branches be up to date before merging — GitHub's required_status_checks.strict,
    read from the ruleset or classic protection (OR-ing, like required-checks). With
    it on, a PR can only merge once its branch is current, so CI reruns against the true
    merged state and two individually-green PRs from stale bases can't silently break
    main. Also recommends the repo-level "Always suggest updating pull request branches"
    setting (allow_update_branch). The fix sets the strict policy on the default-branch
    ruleset and turns allow_update_branch on (needs admin; required status checks must
    exist first).

v0.20.0

Choose a tag to compare

@zmaril zmaril released this 18 Jul 17:31
1d874fe

First release cut since v0.19.0. It consolidates the batch of checks, commands,
and verdict changes that landed on main after v0.19.0 (none of which were tagged
individually) into a single release.

New checks

  • coverage (recommended, advisory): every detected language ecosystem
    (rust, js, python) must wire up some coverage tool — presence-only, not a
    threshold. Accepts a config file, a CI step or task-runner target, or a manifest
    dependency; skips when no rust/js/python ecosystem is present.
  • allow-auto-merge (recommended, fixable): asserts GitHub's allow_auto_merge
    setting matches a declared preference (default off); opt in with
    [allow-auto-merge] enabled = true. The fix PATCHes the setting to match.
  • artifacts-built (recommended, warns): for every build artifact detection
    finds (napi addon, PyO3/maturin wheel, Magnus/rb-sys gem, Tauri app, web/site
    bundle, compiled binary), greps the workflows for the build step it needs and
    reports the ones with no coverage; conservative static parse, so it warns rather
    than gates.
  • pinned-versions (recommended, check-only): flags floating version
    specifiers per ecosystem (npm/bun exact semver, python ==X.Y.Z, ruby = X.Y.Z,
    actions a 40-char commit SHA; cargo advisory by default since Cargo.lock pins
    the build). Configure scope via [pinned-versions]; no auto-fix.
  • dependabot-automerge (recommended, fixable): when a repo opts in with
    [allow-auto-merge] dependabot = true, wants a workflow that auto-merges
    dependabot's non-major PRs once their required checks go green (also requires
    enabled = true). The fix writes .github/workflows/dependabot-automerge.yml.

New commands

  • housekeeper detect: prints the repo's detected ecosystems, typed-language
    layers, and build artifacts, plus the recommended fleet setup per ecosystem
    (--json for machine output). Backed by a new artifact-detection layer in
    languages.py that reads source manifests and skips vendored/build trees.
  • housekeeper new <name> --flavor rust|bun|python: scaffolds a
    fleet-compliant repo skeleton (CI/housekeeping workflows, committed git hooks,
    .housekeeping.toml, LICENSE, scripts/dev.sh, dependabot config, CODEOWNERS,
    notes/design.md), then prints the human next steps it can't do itself. The
    opt-in --dependabot-automerge flag (off by default) additionally writes the
    dependabot-automerge workflow and sets [allow-auto-merge] enabled = true, dependabot = true, so the new repo passes that check out of the gate.

Changed verdicts / behavior

  • lockfiles git-history staleness fallback: for ecosystems with no native
    sync check (ruby's Gemfile.lock, go's go.sum), the check now compares commit
    timestamps and flags a lockfile whose manifest was committed in a strictly later
    commit as likely stale; it also distinguishes a gitignored lockfile and falls
    back to the heuristic when a native tool is absent. Verdict change: can now fail
    ruby/go repos carrying a stale-by-history lockfile.
  • Nested-aware ecosystem detection: detect_ecosystems now returns one
    Ecosystem per location (each carrying its dir) instead of probing only the
    repo root, so nested manifests under crates/* are detected. lockfiles,
    dependabot, ci-exists, coverage, and gitignore now grade nested packages
    per-directory, so repos with nested packages (entl, disponent) may now fail for
    genuinely-ungraded nested lockfiles, dependabot coverage, or CI. Closes #90.
  • repo-meta reconciles a README declaration: description and topics are
    declared at the top of the README via <!-- housekeeper:description ... --> and
    <!-- housekeeper:topics a, b, c --> markers, and the check asserts GitHub's
    actual values match them (README = source of truth; topics validated to GitHub's
    rules). Verdict change: a repo with no markers now fails with an adoption nudge.
    housekeeper fix repo-meta pushes the declared values to GitHub, or — when a
    repo has no markers yet — seeds them into the README from GitHub's current values.
  • bun lockfile check no longer runs postinstall: the frozen
    bun install --dry-run now passes --ignore-scripts (matching npm), so a repo
    whose postinstall needs network/tools is no longer falsely flagged bun.lock
    out of sync after the frozen check itself passed.
  • ruby test signal recognizes the ruby -Itest test/... idiom: ci-exists
    now credits ruby tests run that way, so it no longer under-credits ruby.

v0.19.0 — per-repo `only` targeting for managed-config

Choose a tag to compare

@zmaril zmaril released this 08 Jul 22:04
6de5e1a
  • Per-repo only targeting for [[policy.managed-config]]: an optional only = ["owner/repo", …] allow-list restricts a fleet-owned config to just the members that actually use it, instead of syncing byte-identically to every in-scope member. Empty only (the default) keeps today's apply-to-every-in-scope-member behavior; a non-empty list scopes both the sync and the drift notes to the listed repos, emitting a skipped (not in only list) row for the rest. Values must match [[member]].repo exactly, and unknown repos are tolerated — a listed repo that isn't a member simply never matches. Lets a config like biome, used by only a subset of the fleet, target precisely. (#68)

Usage: uses: zmaril/housekeeping@v0.19.0

v0.18.0 — PR-context grading + ruleset-bypass

Choose a tag to compare

@zmaril zmaril released this 08 Jul 19:41
de96033

PR-context grading: ci-green / branch-protection / required-checks grade main's runs or repo settings — nothing a PR can change — so on pull_request events they demote to recommended (warn, with an explanatory note). Push/schedule/local runs keep them hard; the captain still catches rot. Ends the admin-merge treadmill.

ruleset-bypass (new, recommended, fixable): gating rulesets must name a bypass actor — rulesets ignore gh pr merge --admin without one. housekeeper fix ruleset-bypass grants Repository admin / always.

Hardening: hooks and tests strip GIT_DIR/GIT_INDEX_FILE/GIT_WORK_TREE so suites running under git hooks can never operate on the real repo.

Full notes in CHANGELOG.md.

v0.17.0 — scripts check + serve + fleet dashboard

Choose a tag to compare

@zmaril zmaril released this 08 Jul 16:21
d31519a
  • scripts check (required): shell scripts live under scripts/, a
    scripts/dev.sh stands up the basic dev environment, and the README points at
    it. Hidden and vendored trees (.githooks/, node_modules/, …) are never
    scanned — git hooks belong in .githooks/. Configurable via [scripts]
    (dir, dev, allow). Housekeeping now ships its own scripts/dev.sh.
  • Fleet dashboard now carries a second table: every open PR and issue across
    the fleet
    , one row each, with the repo as a column (PRs first, then issues,
    each linking to GitHub) and a per-fleet count. Open issues/PRs are folded into
    the audit payload (fetch_activity), so the dashboard stays a pure view.
  • New housekeeper serve housecaptain.toml command: serves the dashboard from a
    local web server with a Regenerate button — and an optional 60s
    auto-refresh — that re-audits the fleet on demand. The static --html file
    output is untouched; the live controls are injected only into the served page.
  • housekeeper fleet now audits members concurrently (a thread pool,
    results still in fleet order), so a full re-audit drops to about the slowest
    single repo instead of the sum — roughly 3× faster on the powderworks fleet.
  • Dashboard legend spells out the glyphs — warn is now
    "recommended, not required" and fail is "required", with hover tooltips —
    so a ! cell reads as advisory rather than mysterious.

v0.15.0 — stylelint, vale, codespell + managed configs

Choose a tag to compare

@zmaril zmaril released this 05 Jul 21:55
8c373ca
  • stylelint check (recommended): stylesheets present → config + CI wiring; skips when there's no CSS.
  • vale check (recommended): .vale.ini (+ StylesPath) + CI wiring, for prose style and terminology.
  • codespell check (recommended): codespell in CI — low-noise spelling, split from vale (which false-positives on jargon). codespell flags only known misspellings.
  • Managed configs: the fleet captain can own a check's config under .fleet/ and push it outward as isolated PRs via housekeeper captain --sync-configs (action input sync-configs). Distribution, not a fix — members adopt at their own pace.
  • stray-todos fix: marker match tightened so it no longer flags enum/object keys named Todo or the word "todo" mid-sentence.

Pin the full version: uses: zmaril/housekeeping@v0.15.0.

v0.14.0 — stray-todos

Choose a tag to compare

@zmaril zmaril released this 05 Jul 17:23
9682954

Adds the stray-todos check (TODO/TBD/FIXME/WIP markers must live in the todo file). Fleet members should bump to this from v0.9.0 so the fleet-locked stray-todos = required policy resolves. See the changelog.

v0.9.0 — continue-on-error, reproducible-toolchain, codeowners

Choose a tag to compare

@zmaril zmaril released this 05 Jul 16:26
de1d5fd

Re-baselined from v1.9.0 to 0.x (housekeeping is pre-1.0). Same release, renamed. See the changelog.