Repository navigation
feat: publish releases to npm and PyPI through trusted publishing, when asked - #76
Merged
Merged
Conversation
…en asked modules.publish, off unless asked for and in no preset, adds a publish job to release.yml. When the release job creates a release it publishes a node package to npm (Node.js 24, the stack's install command, npm publish --access public) or builds a python package and publishes it to PyPI with pypa/gh-action-pypi-publish. The job has id-token: write and stores no token; npm adds provenance by itself on a public repository. It is a job of release.yml, not a reusable workflow: PyPI takes no reusable workflow as a trusted publisher, and npm checks the caller. The actions are pinned to the commits the reusable workflows use, and Dependabot is told to leave them alone so a bump does not show up as drift. A released stack other than node or python, one in a folder, or release switched off writes nothing and says why. init names the trusted publisher entry to add. The docs explain the setup on npmjs.com and pypi.org and the 404/403 that npm answers when the entry does not match the repository and release.yml exactly.
A step of a managed YAML key that uses the same action at another commit or tag, as a Dependabot pull request leaves it, now reads as unchanged: check passes and update keeps the newer version. While the key is still what repokeeper wrote, update moves the pin as before. Any other change still counts, and so does the ref a job calls a reusable workflow at, a local action or a Docker image. So the publish job no longer makes dependabot.yml ignore its actions, which also stopped Dependabot from bumping them in the repository's own workflows.
vannt-dev
force-pushed
the
feat/publish-module
branch
from
October 20, 2026 15:46
e2b5499 to
3987e52
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changes for users
modules.publish(off by default, in no preset). It addsjobs.publishto thegenerated
release.yml. The job runs whenrelease_created == 'true':then
npm publish --access public;python -m build(build 1.6.1), thenpypa/gh-action-pypi-publish.permissions: { contents: read, id-token: write }, and no token or secretanywhere. npm adds provenance by itself for a public repository.
--provenanceis left out onpurpose, because npm refuses it for a private repository.
release.yml, not in a reusable workflow. PyPI does not accept reusableworkflows as trusted publishers, and npm checks the caller's filename, so both registries name
release.yml.init/update/check: a released stack other than node/python, astack in a folder (release-please prefixes the outputs with the folder name and the reusable release
workflow does not pass those on, so this is documented as not supported), or
modules.releaseoff.GitLab writes nothing.
initprints the trusted publisher entry to add. The docs (docs/ci-and-releases.md#publishing-to-npm-and-pypi)cover the npmjs.com and pypi.org setup (exact owner/repo/
release.yml, empty environment, allowingnpm publish, publishing once by hand first on npm) and the 404/403 trap when the entry does notmatch exactly.
init -iand the playground (with the "needs repokeeper 0.11.0" note) list the switch.Pinned actions and Dependabot (second commit)
The publish job is the first generated output with third-party actions in a key repokeeper manages
(checkout, setup-node or setup-python, pypi-publish). They are SHA-pinned to the same commits as the
reusable workflows here (
ACTION_PINSin version.ts, held together by a test). Until now, a Dependabotbump of such a pin would have counted as drift.
Choice: option (a), a newer version of the same action is not drift. I chose it because option (b)
had nothing to follow: no generated output had a third-party action before, and
checkcompared everymanaged YAML key by its exact content. The change is in
decide()(src/sync/decide.ts):uses:names the same action at another commit or tag reads asunchanged.
checkpasses andupdatekeeps the newer version. YAML comments such as# v7.2.0were never compared.updatemoves the pin as before../…), a Docker image,and the ref a job calls a reusable workflow at (
uses: …/.github/workflows/…@v0), which repokeeperpins on purpose.
dependabot.ymlno longer ignores the publish job's actions. The ignore would have stoppedDependabot from bumping them in the repository's own workflows too.
Known gaps:
switched off,
updatedoes not see the key as repokeeper's own. It reports it as edited and keepsit (
orphan-edited) instead of deleting it. The lock stores only a hash of what repokeeper wrote,so it can't tell a version-only change from other edits there. Fixing that would change the lock
format, which I left alone.
(say, a new step) after Dependabot bumped a pin,
updatereports a conflict, as it does today forany edited key. It is resolved with
--accept.This PR is rebased onto main after #74 and #75. Module and question order everywhere: cache_cleanup,
automerge, publish.
Verification
npm run typecheck,biome check .,npm test(524 passed),npm run build: all pass.test/sync-action-versions.test.ts, written before the change:edit, reusable-workflow ref, local/docker → still drift);
initwith publish on, then the setup-node pin moved to another commit with a# v7.2.0comment →checkexits 0 andupdatekeeps it; changing therun:line →checkexits 1.
node dist/cli.js initon a sample node repo and a sample python repo with cache_cleanup, automergeand publish all on.
dependabot.ymlhas no action ignores, andactionlint1.7.12 reports nothing.