🔧 Check conda-forge availability when a dependency is added, not at release time
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 0
- Forks
- 0
- Avg merge
- 6h 51m
- Merged PRs (30d)
- 104
Description
Description
Add a rule to .claude/rules/ requiring a conda-forge availability check at the moment a runtime dependency is added or its floor is raised — not at release time, when the release has already shipped to GitHub and PyPI and the only remaining lever is a third-party feedstock.
Proposed location: a new file, .claude/rules/dependencies.md. No existing rule covers dependency management. release-planning.md is the nearest neighbour but is about milestones and scopes, and filing this rule there would contradict its own point — the check belongs at dependency-add time, not in the release checklist. A new file keeps the trigger ("I am editing pyproject.toml's dependencies") next to the rule.
Details
The rule should say: when adding or raising a runtime dependency, check conda-forge at that moment.
-
Query the API, not the web page.
curl -s https://api.anaconda.org/package/conda-forge/<name> \ | python3 -c "import sys,json; d=json.load(sys.stdin); print(d['latest_version'], d['versions'])"https://anaconda.org/conda-forge/<name>returns HTTP 200 even for packages that do not exist, so a status-code check against the web page proves nothing. Verified:URL Nonexistent package https://anaconda.org/conda-forge/<name>200❌https://api.anaconda.org/package/conda-forge/<name>404✅That exact mistake is what let this slip through.
-
Confirm the constraint is satisfiable, not merely that the package exists. Read
versions/latest_versionand check the version range inpyproject.tomlagainst them. A package present at an older version is the same blocker as one that is absent. -
If it is missing or too old, open the fix then. A
staged-recipesPR for a genuinely new package, or a version-bump PR on the existing feedstock. A feedstock already existing means staged-recipes is the wrong route and the PR will be rejected — check forconda-forge/<name>-feedstockfirst. -
Also check that the upstream version publishes an sdist. conda-forge recipes conventionally source the PyPI sdist (
/packages/source/...tar.gz); a wheel-only release breaks both the recipe URL and the autotick bot, silently.
The check should also run in CI, not only live in a rule
A rule relies on someone remembering at the moment they edit a dependency — which is exactly what failed for cronsim. A path-filtered job removes that dependence.
Shape: a workflow triggered on changes to pyproject.toml (the paths: filter idiom ci-tests.yml already uses at .github/workflows/ci-tests.yml:18) that parses [project] dependencies, queries https://api.anaconda.org/package/conda-forge/<name> for each, and checks whether the declared constraint is satisfiable against the versions conda-forge actually has. It fails, or comments on the PR, when one is missing or too old.
Two design points that change the cost:
-
Deterministic script for the check, agent for the remediation. Parse, query, compare, report is cheap, runs on every PR, and has no judgement to get wrong — a script is the right tool. Choosing between a
staged-recipesPR and a version bump on an existing feedstock, spotting that a release is wheel-only, noticing arequires_pythonfloor moved — that is judgement, and the right tool is an agent. The repo already has agent-invoking workflows (claude.yml,claude-code-review.yml), so a failing check can hand off rather than trying to do everything itself. -
Name mapping is the part that will bite. PyPI and conda-forge names diverge, and this project's own recipe already carries the translation. Verified against the API right now:
Dependency conda-forge query Result aws-lambda-builders.../conda-forge/aws-lambda-builders404— false "missing"aws-lambda-builders.../conda-forge/aws_lambda_builders200✅A naive check produces a false "missing package" failure on every such dependency. The script needs the mapping, or must treat a miss as "verify by hand" rather than a hard failure — otherwise the first implementation is noisy enough to get disabled.
The same job can also check for a missing sdist on the pinned version — the condition that silently defeats the conda-forge autotick bot, and what left cronsim-feedstock un-bumped since February 2025.
Why — the concrete cost
During #222, cronsim>=2.7 and tzdata were added as core runtime dependencies. Nobody checked conda-forge. This surfaced only after v0.14.0 was tagged, released on GitHub, and published to PyPI, at which point:
- conda-forge had cronsim 2.6, and 2.6 is not API-compatible —
CronSimdoes not expose the parsed field sets we read, so relaxing the constraint was not an option. conda-forge/cronsim-feedstockhad never been bumped since it was created in Feb 2025 — four commits, all infrastructure, zero PRs.- cronsim 2.7 publishes no sdist (wheel only), so the recipe's
/packages/source/...tar.gzURL 404s — almost certainly why no automatic bump ever landed. - Fixing it needed a fresh feedstock PR moving the source to the GitHub tag archive and a local
python_min: "3.10"pin, because cronsim also raised its floor from>=3.8to>=3.10in that release.
Net effect: the conda-forge package for v0.14.0 was blocked after the release had already shipped everywhere else, and unblocking it required work on a third-party feedstock. Checking at dependency-add time would have cost minutes and surfaced all four problems while there was still slack.
Evidence:
- conda-forge/cronsim-feedstock#3 — the bump that unblocked it (GitHub tag archive source +
python_minpin) - conda-forge/zae-limiter-feedstock#25 — the v0.14.0 feedstock PR that was blocked on it
Refs #222
Acceptance Criteria
- A rule file exists under
.claude/rules/covering the conda-forge check at dependency-add time - The rule gives the
api.anaconda.orgcommand and states explicitly thatanaconda.org/conda-forge/<name>returns 200 for nonexistent packages - The rule requires checking the declared version constraint against
versions, not just package existence - The rule requires checking for an upstream sdist
- The rule distinguishes staged-recipes (new package) from a feedstock version-bump PR (existing package)
- The rule is reachable from
CLAUDE.mdor the rules index the same way the other.claude/rules/files are - A CI job runs on pull requests that modify
pyproject.tomland checks every entry in[project] dependenciesagainstapi.anaconda.org - The CI check resolves PyPI → conda-forge name differences, or reports an unresolved name as "verify by hand" rather than as a hard failure (verified against
aws-lambda-builders→aws_lambda_builders) - The CI check reports a dependency whose declared constraint is unsatisfiable on conda-forge, not merely one that is absent
- The CI check reports a pinned version that publishes no sdist on PyPI
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with pyproject.toml, .github/workflows/ci-tests.yml, and the existing .claude/rules/ files; inspect CLAUDE.md or the rules index to see how new rules are linked, then review claude.yml and claude-code-review.yml for agent workflow patterns. Add .claude/rules/dependencies.md and a path-filtered CI job that checks dependency constraints, conda-forge name mapping, and sdists; done means all acceptance criteria pass.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- github-actions, python, shell
- Domain
- ci-cd, devops, documentation
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100