Skip to content

Ship engine as a package (Nix flake first); stop vendoring scripts with the template #2

Closed

Description

@williamdemeo

Context

The first external adopter has landed: formalverification/agda-native-air#92 (its PR #93) retired a vendored ancestor of the populate script and adopted docs/GITHUB_PROJECT.md, calling this repository's engine from a local checkout via a GHPROJECT_DIR Makefile variable. That works, but it is a stopgap. The template's distribution model — consumers copy scripts/ at project creation via "Use this template" — guarantees that every consumer's copy decays the moment the engine improves here (case-in-point: agda-native-air's copy predated update, lint, _gh_project_lib, and the generated-region model entirely).

Design: engine and data separate; the engine is referenced, never copied

  • The per-project artifacts are data: docs/GITHUB_PROJECT.md and a thin Makefile stub, scaffolded once by the template.
  • The engine (gh_project_populate.py, gh_project_update.py, gh_project_lint.py, _gh_project_lib.py, _utils/) is a versioned package with exactly one home, this repository; scripts/VERSION becomes the package version.
  • Primary channel, Nix: flake outputs — a package plus apps (nix run .#populate, .#update, .#update-check, .#lint). Consumers add this repo as a flake input, pin it in their flake.lock, and upgrade deliberately with nix flake update. The engine is stdlib-only Python, so the package is trivial.
  • Secondary channel, later: pyproject.toml with console entry points (still zero third-party dependencies) for uv tool install / pipx from a tagged release.
  • The template's Makefile stub becomes channel-agnostic: prefer the flake input or installed CLI, fall back to GHPROJECT_DIR ?= ~/git/williamdemeo/github-project/main for checkout-based use (the shape agda-native-air already wired).

Consequences for the template

  • "Use this template" stops meaning "you now own a copy of the engine": the post-create instructions (or a make init step) remove scripts/ from the new project and wire the stub instead.
  • Existing consumers migrate by deleting their copies and adopting the stub; agda-native-air#92 is the worked example.

Open questions

  • Where _utils ultimately lives: it is generic functional-Python plumbing with consumers that need it without the engine. Candidate: a dedicated python-workflow-utilities repository that the engine depends on; until then it ships inside the engine package. This supersedes the earlier "vendor _utils from this repo" decision once distribution is by reference rather than by copy.
  • Whether the post-create cleanup is documented prose or a make init target.

Acceptance

  • A Nix consumer runs lint/update against its plan file with no engine files in its own tree, pinned by its flake.lock.
  • The template README documents the consumption channels and no longer implies the copied scripts are how the engine is run.
  • agda-native-air's project-* targets switch from GHPROJECT_DIR to the flake input, closing the loop with its #92.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions