Skip to content

Adopt the shared project standard: hatch-vcs, zensical, and the four workflows #380

Description

@wtgee

The rebuild spans four repositories, and each was set up at a different time by a different template. panoptes/panoptes-pipeline#218 surveys the divergence and settles a single standard; the reasoning lives in plans/project-standards.md in panoptes-pipeline, which is where the reasoning for cross-repository work lives regardless of which repository the work happens in.

This issue is this repository's half. It is deliberately not a restatement of the standard — read the plan document for why each choice was made.

What changes here

Build backend: setuptools + setuptools-scm → hatchling + hatch-vcs.

[build-system]
requires = ["hatchling>=1.25", "hatch-vcs>=0.4"]
build-backend = "hatchling.build"

[tool.hatch.version]
source = "vcs"

[tool.hatch.build.targets.wheel]
packages = ["src/panoptes"]

The consequence that needs care: [tool.setuptools_scm] version_file writes src/panoptes/utils/_version.py, which is committed and is extend-excluded from ruff. hatch-vcs writes no such file. Anything importing _version moves to importlib.metadata.version("panoptes-utils"), the file is deleted, and the ruff exclusion goes with it. Grep before deleting — a stale import is an ImportError at package import time, not a quiet degradation.

Documentation: mkdocs-material → zensical. mkdocs.yml becomes zensical.toml; the nav, theme palette and markdown extensions carry over nearly unchanged. Root Markdown files are included into docs/ pages via pymdownx.snippets rather than duplicated.

Publishing: mkdocs gh-deploy → the Pages deployment API. gh-deploy force-pushes a built site to gh-pages, so the branch is a second copy of the site in the repository's history and the job needs contents: write on a run that executes branch code. The replacement builds with contents: read and uploads an artifact; a separate job, gated on main and building nothing, deploys it. This needs Settings → Pages → Source set to GitHub Actions.

Workflows: pythontest.yaml, docs.yml, create-release.yml → tests.yml, docs.yml, create-release.yml, canary.yml. Specifically:

  • uv sync --locked in CI, so a dependency edit that skipped uv lock fails rather than silently testing a re-resolved tree.
  • Release notes come from the annotated tag message, not an awk scrape of CHANGELOG.md. Today a heading that does not match the pattern yields an empty release body rather than an error, and the workflow also does not require the tag to be annotated.
  • PyPI Trusted Publishing instead of a stored token. Needs a one-time publisher setup on PyPI for panoptes-utils naming workflow create-release.yml.
  • A weekly dependency canary: an unlocked re-resolution, so an upstream break surfaces on a schedule instead of in a user's environment.
  • actions/setup-python goes away — uv resolves an interpreter matching requires-python on its own. Several jobs here pin astral-sh/setup-uv@v4 and actions/checkout@v2; those come up to current.

AGENTS.md canonical. AGENTS.md and GEMINI.md both exist here and are copies. AGENTS.md stays as the real file; GEMINI.md and a new CLAUDE.md become symlinks to it.

Tooling in [dependency-groups], never extras. This repository ships a docs extra in [project.optional-dependencies], so anyone installing the package can ask for a documentation toolchain. Extras are published metadata and belong to users of the package; a docs build is not that. It moves to a docs group.

Not changing

ruff settings — 110 columns with E,W,F,I,UP is already the standard, taken from this repository.

Done when

panoptes-utils builds, lints, tests, documents and releases the same way as the other three, and a contributor moving between them meets no surprises.

Dependencies

Depends on panoptes/panoptes-pipeline#219 for the written standard. Related to panoptes/panoptes-pipeline#189, which wants a uv workspace spanning these repositories — three repositories that build the same way are a workspace; three that each differ are three environments sharing a directory.


Filed by Claude Opus 5 · effort: high · 🤖 Claude Code

Activity

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

Metadata

Metadata

Assignees

Labels

cross-repoDepends on or blocks work in POCS, panoptes-pipeline or panoptes-datapython:uvPull requests that update python:uv code

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions