Skip to content

Publish PyPI on develop as PEP 440 dev releases (prerelease channel) - #75

Merged
ptr727 merged 2 commits into
mainfrom
develop
May 11, 2026
Merged

Publish PyPI on develop as PEP 440 dev releases (prerelease channel)#75
ptr727 merged 2 commits into
mainfrom
develop

Conversation

@ptr727

Copy link
Copy Markdown
Owner

Release merge: brings one squashed PR from develop into main, plus a routine main → develop back-merge that catches develop up to main's last release commit.

Squashed PR included

  • Publish PyPI on develop as PEP 440 dev releases (prerelease channel) #74 — Publish PyPI on develop as PEP 440 dev releases (prerelease channel). Aligns PyPI publish behavior with the existing NuGet / Docker / GitHub-release pattern — develop pushes now publish a PEP 440 dev release alongside the main stable release on a single PyPI project.

    What changed

    • publish-pypi job in publish-release.yml no longer has the if: github.ref == 'refs/heads/main' guard — runs on both main and develop pushes.
    • New "Compute PyPI version step" in build-pypilibrary-task.yml formats the version per branch:
      • mainMajor.Minor.Patch.BuildNumber (PEP 440 release)
      • developMajor.Minor.Patch.BuildNumber.dev0 (PEP 440 dev release)
    • The BuildNumber stays in the release segment on develop so develop's release segments climb past main's per commit, giving pip install --pre <pkg> the correct ordering to resolve to develop.
    • Docs updated (PyPiLibrary/README.md "Two-channel publishing" + "Version" stack entry; _version.py docstring; inline workflow comments).
    • Through five rounds of Copilot review on the source PR.

Back-merge included

  • ffb9e64 — Merge remote-tracking branch 'origin/main' into develop. Per AGENTS.md release flow, brings main's last release merge commit (d03d810) into develop's history so develop is no longer "BEHIND" main. No content change; the second parent reference is what matters. Also bumps develop's NBGV gitHeight by 1, which activates the PyPI --pre channel from PR Publish PyPI on develop as PEP 440 dev releases (prerelease channel) #74 (the back-merge commit publishes 1.0.48.<B>.dev0, which is unambiguously higher than main's 1.0.47.53309).

Operator action items (already completed out-of-band)

  • CODEGEN_APP_ID / CODEGEN_APP_PRIVATE_KEY already in both Actions and Dependabot secret stores.
  • WORKFLOW_PAT secret + PAT revoked.
  • pypi GitHub environment Deployment branch rule already allows both main and develop.

Notes

Test plan

  • CI passes on the merge commit.
  • After merge, the publish-release run on main publishes 1.0.48.<B> as the next stable release (Patch bumped from 47 to 48 because of the back-merge contributing one to gitHeight).
  • pip install ptr727-projecttemplate-library (no --pre) still resolves to a release version (1.0.48.<B> after this merge, was 1.0.47.53309 before).
  • pip install --pre ptr727-projecttemplate-library resolves to the latest develop dev release (1.0.48.<B'>.dev0 from develop's tip, where B' >= B).

ptr727and others added 2 commits May 11, 2026 21:52
…74)
## Summary
Make PyPI behave like NuGet / Docker / GitHub releases — **main pushes
ship release versions, develop pushes ship prerelease versions**. PyPI
was the odd one out, only publishing on main.
## Workflow changes
### `build-pypilibrary-task.yml`
New **"Compute PyPI version step"** before "Write version into
_version.py":
| `github.ref` | Computed version | `pip install` behavior |
|---|---|---|
| `refs/heads/main` | `Major.Minor.Patch.BuildNumber` (e.g.
`1.0.47.53309`) | Picked by default. |
| `refs/heads/develop` | `Major.Minor.Patch.BuildNumber.dev0` (e.g.
`1.0.47.53400.dev0`) | Filtered out unless `--pre` is passed. |
| Anything else (PR validation, feature branches) |
`AssemblyFileVersion` as-is | Never published — version just needs to be
PEP 440 valid for `uv build`. |
**Why `.dev0` not `.devB`** (Copilot caught this on the first review):
PEP 440 compares release segments first. `M.N.P.devN` has release
`[M,N,P]` while main's `M.N.P.B` has `[M,N,P,B]` — main wins on segments
even with `--pre`. Keeping the BuildNumber in the release segment
(`M.N.P.B.dev0`) makes develop's segment grow past main's per commit,
which is what lets `--pre` actually prefer develop. NBGV BuildNumber is
unique per commit, so a constant `.dev0` is enough to disambiguate
uploads.
**Edge case** (documented inline): in the window between a release merge
to main and the next commit on develop, develop's BuildNumber equals
main's (or is one lower), so `--pre` will still resolve to the main
release until a new develop commit lands. Self-healing.
The sed step now consumes `steps.pypiver.outputs.version` instead of
`needs.get-version.outputs.AssemblyFileVersion` directly.
### `publish-release.yml`
- Drop `if: github.ref == 'refs/heads/main'` on `publish-pypi`. The job
now runs on every push to `main` AND `develop`, like its NuGet / Docker
/ executable siblings.
- Comment rewritten to describe the dual-channel model and point at the
env Deployment branch rule as the security boundary.
## Operator action (already done out-of-band)
- `pypi` GitHub environment's Deployment branch rule now allows **both**
`main` and `develop`. Without this, develop pushes would be blocked at
the env gate. _Confirmed done by repo owner._
## Documentation
- **`PyPiLibrary/README.md`**:
- Stack-table "Version" entry rewritten to describe the branch-aware
format.
- "Publishing" section gains a new **"Two-channel publishing"**
paragraph explaining `pip install <pkg>` (release channel) vs `pip
install --pre <pkg>` (dev channel), the BuildNumber-in-release-segment
rationale, and the edge case.
- First-time-setup step 2 lists both `main` and `develop` as required
entries in the env Deployment branch rule.
- **`_version.py` docstring** updated to describe both branches' PEP 440
forms and the post-release edge case.
## Test plan
- [ ] CI passes on this PR (PR validation runs build-pypilibrary-task;
the new Compute step lands in the "other refs" branch and uses
AssemblyFileVersion as-is — same observable behavior as before for PR
builds).
- [ ] After merge to develop: the develop push fires
`publish-release.yml`, `publish-pypi` enters the `pypi` environment (no
longer blocked by `if:` or env rule), and uploads `M.N.P.B.dev0` to
PyPI.
- [ ] `pip install ptr727-projecttemplate-library` still resolves to the
latest main release (unchanged); `pip install --pre
ptr727-projecttemplate-library` resolves to the latest develop dev
release.
- [ ] Next release on `main` ships PyPI at `M.N.P.B` as before.
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
CopilotAI review requested due to automatic review settings May 11, 2026 22:12

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the Python publishing pipeline so that pushes to develop publish PEP 440 development releases to the same PyPI project, aligning the PyPI behavior with the repo’s existing “develop prerelease / main release” pattern used for other artifacts.

Changes:

  • Enable the publish-pypi job to run on both main and develop pushes (with branch restriction enforced via the pypi environment deployment rules).
  • Add a branch-aware “Compute PyPI version” step that emits M.N.P.B on main and M.N.P.B.dev0 on develop, and write that into _version.py before uv build.
  • Update Python docs (PyPiLibrary/README.md and _version.py docstring) to describe the two-channel publishing model and the version ordering rationale.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.

FileDescription
PyPiLibrary/src/ptr727_projecttemplate_library/_version.pyUpdates the module docstring to document branch-aware PEP 440 version rewriting (main release vs develop dev release).
PyPiLibrary/README.mdDocuments two-channel PyPI publishing, branch-aware version formatting, and environment deployment-branch requirements.
.github/workflows/publish-release.ymlRuns the PyPI publish job on both main and develop pushes; relies on the pypi environment deployment branch rule as the security gate.
.github/workflows/build-pypilibrary-task.ymlComputes branch-aware PyPI version (.dev0 on develop) and writes it into _version.py before building artifacts.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@ptr727