Shipping huggingface_hub weekly with AI, open tools, and a human who actually checks the work

Shipping huggingface_hub weekly with AI, open tools, and a human who actually checks the work

6 0 0

The huggingface_hub Python client sits at the bottom of the Hugging Face ecosystem. Transformers, datasets, diffusers, sentence-transformers—dozens of libraries depend on it to talk to the Hub. Every week without a release is a week where fixes and features sit on main, useless to anyone.

For a long time, the team shipped every four to six weeks. Now they ship every week, driven by a single GitHub Actions workflow built with open-source tools and open-weights models. The only place a human still touches the process is where judgment actually matters: reviewing the AI’s output before anything goes live.

Nothing here requires a vendor contract, a closed model, or infrastructure you can’t run yourself. That was a deliberate design constraint from the start. The team wanted other maintainers to be able to pick this up and adapt it without asking for permission or paying for access.

Where they started: mostly manual, partly painful

Before this, the release process was a hybrid. Some parts were already in CI—publishing to PyPI once a tag was pushed, opening test branches in downstream libraries with the release candidate pinned. But the rest was manual, every single time.

Someone had to create the release branch, bump the version in __init__.py, commit, tag, push. Watch the downstream CI runs and triage failures. Read through every PR merged since the last release and write release notes by hand—grouped by theme, with context, in a voice that didn’t read like a git log dump. Cut the stable release after the RC period. Draft an internal Slack announcement and social posts. Open the post-release PR to bump main to the next dev0.

Writing good release notes was the heavy part. Aggregating tens of PRs on different topics isn’t technically hard, but it takes focused attention for a few hours. Add the announcements on top, and a minor release was easily half a day of work spread over several days.

Two kinds of work, two approaches

Looking at that list, the work splits cleanly into two categories.

Some steps are purely mechanical: bumping the version, committing, tagging, pushing, opening downstream test branches, opening the post-release PR. Nobody needs to think about those. They just have to happen in the right order, every time. That’s exactly what a CI workflow is good at.

The rest is different. Writing release notes, deciding what to highlight, phrasing an announcement for a human audience—that’s brain work. It’s the kind of judgment that kept the release manual for years. This is where AI comes in, turning a blank page into a solid first draft in seconds. It’s also where you have to be careful, because a draft that looks confident and is subtly wrong is worse than no draft at all.

The stack: open parts, reusable by anyone

When the team decided to fix this, they set one constraint up front: every moving part had to be something any maintainer could run themselves. No closed model behind an API they couldn’t swap, no proprietary release platform, no secret sauce.

Here’s the entire stack:

  • GitHub Actions orchestrates the whole release
  • OpenCode is the agent runtime that drives the model
  • An open-weights model (currently GLM-5.2 from Z.ai) drafts the release notes and Slack announcement
  • HF Inference Providers serves the model
  • PyPI Trusted Publishing publishes the package

The second principle: the model drafts, a human decides. Language models are good at turning thirty terse PR titles into readable release notes. They are not good at being trusted blindly. So the workflow is human-supervised: the model does the first pass, a deterministic script checks its work, and a human reviews and edits before anything ships.

A tour of the pipeline

The full workflow is a single file, .github/workflows/release.yml, triggered by hand from the Actions UI. It takes exactly one input: the release type—minor-prerelease, minor-release, or patch-release.

From there, the jobs run roughly in this order:

  • Prepare. Compute the next version, create or reuse the release branch, bump __version__, commit, tag, push.
  • Publish to PyPI. Build and upload huggingface_hub. In parallel, build and upload the hf CLI as its own PyPI package.
  • Release notes. Diff the commit range since the last tag, pull PR metadata from the GitHub API, and have the model draft a structured changelog. Saved as a draft GitHub release.
  • Downstream test branches. For RCs, open a branch in transformers, datasets, diffusers, sentence-transformers with the RC pinned, so their CI tells them fast if something broke.
  • Slack announcement. Read the notes and produce an internal announcement in the team’s voice.
  • Archive notes. Upload both the raw AI draft and the human-edited version to a Hugging Face Bucket, side by side.
  • Post-release bump. After a stable release, open a PR on main bumping to the next dev0.
  • Comment on shipped PRs. Leave a “this shipped in vX.Y.Z” comment on every PR in the release.
  • Sync CLI docs. Open a PR to their skills repo with the regenerated hf CLI skill docs.
  • Report to Slack. Every step posts its status as a thread reply; a final job updates the root message with ✅ or ❌.

The remaining manual steps are reviewing and publishing the draft release notes, and reviewing and posting an internal Slack message. Those two steps are where they want a human in the loop.

Trust but verify

Here’s the failure mode everyone worries about with AI-generated release notes: the model quietly drops an important change, or mischaracterizes something, or invents a detail that sounds plausible but isn’t true. A draft that looks polished and is wrong is worse than no draft at all.

The team’s approach is straightforward. The model produces the first draft. A deterministic script checks for obvious issues—missing PR numbers, inconsistent formatting, things that shouldn’t be there. Then a human reads it, edits it, and hits publish. That’s it. No blind trust, no skipping the review step.

This is the right balance. The AI saves hours of staring at a blank page and organizing PR titles into coherent groups. The human catches the things the AI gets wrong. The result is release notes that are both faster to produce and actually accurate.

What this means for other maintainers

The whole thing is open. The workflow file is in the huggingface_hub repo. The model is an open-weights model you can run yourself. The tools are all free and open-source. If you maintain a Python library and want to ship more frequently without burning out your maintainers, this is a blueprint you can adapt.

I’ve been watching the open-source release automation space for a while, and most solutions fall into two camps. Either they’re fully manual and slow, or they’re fully automated and you’re trusting the AI to get everything right. This approach splits the difference in a way that actually makes sense: automate the mechanical parts, use AI for the creative parts, but keep a human in the loop for the parts where mistakes matter.

The weekly cadence is ambitious. Most libraries can’t sustain that. But if you have the CI infrastructure and the automation in place, it’s not as crazy as it sounds. The team has been running this for a while now, and it works. The releases are smaller, more frequent, and less painful to produce.

I’d like to see more projects adopt something like this. The tooling is there, the models are good enough, and the workflow is well-documented. The only thing holding most projects back is the initial investment of setting it up. But once it’s running, it pays for itself in maintainer sanity pretty quickly.

Comments (0)

Be the first to comment!