Skip to content

Commit 16e6e02

Browse files
authored
clarify release strategy (#23)
1 parent 3137a70 commit 16e6e02

3 files changed

Lines changed: 112 additions & 6 deletions

File tree

.github/workflows/publish.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,7 @@ jobs:
104104
}
105105
106106
$versionJson = Get-Content -Raw -Path version.json | ConvertFrom-Json
107-
$patch = if ($env:BUILD_NUMBER) { $env:BUILD_NUMBER } else { "$($versionJson.patch)" }
108-
$version = "$($versionJson.major).$($versionJson.minor).$patch"
107+
$version = "$($versionJson.major).$($versionJson.minor).$($versionJson.patch)"
109108
$exists = if ($versions -contains $version) { 'true' } else { 'false' }
110109
Write-Output "Release $version exists on PyPI: $exists"
111110
"exists=$exists" | Out-File -FilePath $env:GITHUB_OUTPUT -Append -Encoding utf8

RELEASE.md

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
# Release steps (minimal)
2+
3+
This file documents the minimal, explicit steps to bump the version and publish a release for moldflow-api.
4+
5+
Summary (short):
6+
7+
- Edit the root `version.json` (only this file).
8+
- Commit on a branch named `release/MAJOR.MINOR.PATCH` and push.
9+
- Wait for CI to pass on that branch.
10+
- Trigger the manual "Publish package (manual)" workflow in GitHub Actions and confirm.
11+
12+
Why this works (important notes):
13+
14+
- The canonical version source for releases is the root `version.json` in the repository root.
15+
- The `run.py` script (used for building and releasing locally and by many repo commands)
16+
reads the `patch` value directly from the root `version.json` and will raise a
17+
RuntimeError if `patch` is missing.
18+
- The workflow only publishes when run on a branch whose name starts with `release/` and when
19+
you confirm the manual workflow dispatch.
20+
- The release workflow checks PyPI for an existing version and will skip publishing if that
21+
exact version already exists.
22+
23+
Minimal step-by-step
24+
25+
1. Decide the new major/minor/patch values.
26+
27+
- Always set a numeric `patch` value in the root `version.json`.
28+
29+
2. Edit `version.json` at the repository root. Example (bumping to MAJOR.MINOR.PATCH, e.g. 1.2.0):
30+
31+
```json
32+
{
33+
"major": "27",
34+
"minor": "0",
35+
"patch": "0"
36+
}
37+
```
38+
39+
3. Commit and push on a `release/` branch. Example (use the placeholder branch name below and replace with your version):
40+
41+
```bash
42+
# create branch using the target version (branch name must start with 'release/')
43+
# use a placeholder like 'release/MAJOR.MINOR.PATCH' and replace with your values
44+
git checkout -b release/MAJOR.MINOR.PATCH # e.g. release/1.2.0
45+
git add version.json
46+
git commit -m "Bump version to MAJOR.MINOR.PATCH" # e.g. "Bump version to 1.2.0"
47+
git push -u origin release/MAJOR.MINOR.PATCH
48+
```
49+
50+
4. Wait for CI to pass on that branch.
51+
52+
- The publish workflow has a guard that requires the `ci.yml` workflow to have completed
53+
successfully for the same commit before allowing publish.
54+
55+
5. Trigger the publish workflow manually in the GitHub Actions UI for the repository.
56+
57+
- Open the `Publish package (manual)` workflow, choose `Run workflow`, set `confirm` to
58+
`true`, and run it on your `release/MAJOR.MINOR.PATCH` branch (replace the placeholder
59+
with the actual version).
60+
- Alternatively, you can use the GitHub CLI (if you have it configured). Example using a
61+
placeholder branch name (replace with your actual branch):
62+
```bash
63+
# example (replace with the correct workflow file name and branch if needed)
64+
# gh workflow run publish.yml --ref release/MAJOR.MINOR.PATCH -f confirm=true
65+
# e.g. --ref release/1.2.0
66+
```
67+
68+
6. What the workflow does (high level):
69+
70+
- Ensures CI (`ci.yml`) passed for the commit.
71+
- Computes the release version using `version.json`.
72+
- If the computed version already exists on PyPI the workflow will skip the publish.
73+
- If not present, it builds the package, uploads to PyPI (requires the repo to have
74+
`PYPI_API_TOKEN` in secrets), creates a GitHub release (tag `vMAJOR.MINOR.PATCH`) and
75+
deploys documentation to GitHub Pages.
76+
77+
Local testing and notes
78+
79+
- You can build the package locally to smoke test the build step:
80+
81+
```bash
82+
python run.py build
83+
```
84+
85+
- Publishing to PyPI is intentionally restricted to the manual GitHub Actions workflow.
86+
If you need to test publishing to TestPyPI locally, you can use `python -m twine upload`
87+
with TestPyPI credentials, but this is separate from the CI-based publish flow.
88+
89+
Edge cases and tips
90+
91+
- `run.py` now requires a `patch` value in the root `version.json`. It will raise a
92+
RuntimeError if that key is missing. Do not rely on `run.py` falling back to any
93+
environment variable.
94+
- If you want CI to inject a monotonic build number into the patch segment, make the CI
95+
step explicitly update `version.json` (or generate a temporary `version.json`) with the
96+
desired `patch` before running the build and publish steps. That keeps `run.py` and the
97+
workflow in agreement.
98+
- The `run.py` script will write a package-local `src/moldflow/version.json` at build time;
99+
you do not need to edit that file directly (it is generated and typically ignored by Git).
100+
101+
Cleanup (optional)
102+
103+
- After a successful release you may merge the `release/` branch to `main` (if you use merge
104+
workflow) and delete the `release/` branch.
105+
106+
Contact
107+
108+
If anything in CI behaves unexpectedly, check the logs for the `publish` workflow and the
109+
`ci` workflow; feel free to open an issue or ask a maintainer.

run.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@
7373
SITE_PACKAGES = 'moldflow-site-packages'
7474
VERSION_JSON = 'version.json'
7575
VERSION = ''
76-
BUILD_NUMBER = os.environ.get('BUILD_NUMBER', '0')
7776

7877
# FILE TYPES
7978
PY_FILES_EXT = '.py'
@@ -588,14 +587,13 @@ def set_version():
588587

589588
# Set global version for use in other functions
590589
global VERSION
591-
patch_value = vers_json_dict.get('patch', BUILD_NUMBER)
592-
VERSION = f"{vers_json_dict['major']}.{vers_json_dict['minor']}.{patch_value}"
590+
VERSION = f"{vers_json_dict['major']}.{vers_json_dict['minor']}.{vers_json_dict['patch']}"
593591

594592
# Create package version.json with complete version info
595593
package_version = {
596594
"major": vers_json_dict['major'],
597595
"minor": vers_json_dict['minor'],
598-
"patch": patch_value,
596+
"patch": vers_json_dict['patch'],
599597
}
600598

601599
# Ensure package directory exists

0 commit comments

Comments
 (0)