The naive version of this is a webhook: commit pushed, post published. People build it in an afternoon and turn it off within a week.
Understanding why it fails tells you what the useful version looks like.
Why commit-to-post fails
Most commits are not worth mentioning. A working day produces typo fixes, dependency bumps, formatting changes and merge commits. Publishing them is noise, and noise costs you reach on everything else you post.
A commit is not a unit of work. "Added export button" means nothing alone. It matters as part of "shipped CSV export", which was four commits across two days. The interesting unit spans commits.
Commit messages are written for a different reader. fix: handle null in export path is correct and unpublishable. It assumes context the reader does not have.
Nothing checks the output. Automated posting with no review means the first time something wrong goes out, it goes out publicly.
What the useful version does
Four things, in order.
Filter. Drop the noise before anything else. Merge commits, dependency bumps, formatting, version tags, generated files. In practice this removes most of a normal day's commits, which is correct.
Group. Cluster the remainder into stories. Commits belong together if they share a scope, touch the same code, or use the same distinctive words. Four commits about CSV export become one candidate story.
Score. Not every story deserves a post. Score on user impact, size, coherence and type. Take the best one or two.
Draft, do not publish. Generate, then wait for a human. This is the single most important difference between something you keep using and something you turn off.
The review step is not a compromise
It is tempting to treat approval as a stepping stone to full automation. It is not.
Approval is the thing that makes the automation safe to leave on. Review takes about thirty seconds. Writing from scratch takes twenty minutes. The automation captured most of the value and left the judgment where it belongs.
Full auto-publish saves thirty seconds a day and adds the permanent risk of publishing something wrong in your name.
Things that break in practice
Timezone. "Yesterday's commits" needs the user's local day, not UTC. A user in Sydney gets a different set of commits than the server thinks. This is where the naive version breaks first and most confusingly.
Duplicates. A scheduled job that retries can post twice. You need an idempotency key on workspace plus local date, and a lock with a TTL so a crashed run does not block tomorrow.
Rate limits. GitHub gives 5,000 requests per hour per installation. Scanning many repositories for many users gets there fast. Check the remaining budget before expensive calls, and never spin on 403.
Private repos. Names, file paths and internal terminology leak. Strip absolute paths, redact anything that looks like a credential, and let the user mark repositories as private for content purposes.
What it looks like when it works
Once a day, a draft appears based on what you actually did. You read it, fix a sentence, post it or skip it.
That is the whole product. The interesting engineering is in the filtering and grouping, not the AI, because the AI can only be as good as the material it is handed.