1111
1212jobs :
1313 publish :
14+ if : ${{ github.actor != 'github-actions[bot]' }}
1415 runs-on : ubuntu-latest
1516 permissions :
16- contents : read
17+ contents : write
1718 id-token : write
1819 defaults :
1920 run :
@@ -32,38 +33,126 @@ jobs:
3233 python -m pip install --upgrade pip
3334 python -m pip install build
3435
35- - name : Decide whether to publish
36- id : should_publish
36+ - name : Decide version
37+ id : version
3738 run : |
3839 python - <<'PY'
3940 import json
4041 import os
42+ import re
4143 import urllib.request
4244 import tomllib
4345 from pathlib import Path
4446
4547 data = tomllib.loads(Path("pyproject.toml").read_text())
4648 name = data["project"]["name"]
47- version = data["project"]["version"]
49+ current = data["project"]["version"]
50+
51+ def parse(value: str) -> list[int]:
52+ core = value.split("-", 1)[0].split("+", 1)[0]
53+ parts = [int(part) for part in core.split(".") if part.isdigit()]
54+ while len(parts) < 3:
55+ parts.append(0)
56+ return parts[:3]
57+
58+ def compare(left: str, right: str) -> int:
59+ a = parse(left)
60+ b = parse(right)
61+ for i in range(3):
62+ if a[i] > b[i]:
63+ return 1
64+ if a[i] < b[i]:
65+ return -1
66+ return 0
67+
68+ def bump_patch(value: str) -> str:
69+ major, minor, patch = parse(value)
70+ return f"{major}.{minor}.{patch + 1}"
4871
4972 url = f"https://pypi.org/pypi/{name}/json"
5073 try:
5174 with urllib.request.urlopen(url, timeout=10) as resp:
5275 payload = json.loads(resp.read().decode("utf-8"))
53- published = version in payload.get("releases ", {})
76+ published = payload.get("info ", {}).get("version" )
5477 except Exception:
55- published = False
78+ published = None
79+
80+ next_version = current
81+ bump_needed = False
82+ if published:
83+ comparison = compare(current, published)
84+ if comparison <= 0:
85+ next_version = bump_patch(current if comparison == 0 else published)
86+ bump_needed = True
87+
88+ publish = (published is None) or (compare(next_version, published) > 0 if published else True)
5689
5790 output = os.environ.get("GITHUB_OUTPUT")
5891 if output:
5992 with open(output, "a", encoding="utf-8") as handle:
60- handle.write(f"publish={'false' if published else 'true'}\n")
93+ handle.write(f"current_version={current}\n")
94+ handle.write(f"published_version={published or ''}\n")
95+ handle.write(f"next_version={next_version}\n")
96+ handle.write(f"bump_needed={'true' if bump_needed else 'false'}\n")
97+ handle.write(f"publish={'true' if publish else 'false'}\n")
98+ PY
99+
100+ - name : Sync version files
101+ id : sync_version
102+ env :
103+ NEXT_VERSION : ${{ steps.version.outputs.next_version }}
104+ run : |
105+ python - <<'PY'
106+ import os
107+ import re
108+ from pathlib import Path
109+
110+ next_version = os.environ.get("NEXT_VERSION")
111+ if not next_version:
112+ raise SystemExit(0)
113+
114+ pyproject_path = Path("pyproject.toml")
115+ pyproject_text = pyproject_path.read_text()
116+ updated_pyproject = re.sub(
117+ r'(?m)^version = "[^"]+"',
118+ f'version = "{next_version}"',
119+ pyproject_text,
120+ count=1,
121+ )
122+ if updated_pyproject != pyproject_text:
123+ pyproject_path.write_text(updated_pyproject)
124+
125+ init_path = Path("src/diffio/__init__.py")
126+ if init_path.exists():
127+ init_text = init_path.read_text()
128+ updated_init = re.sub(
129+ r'(?m)^__version__ = "[^"]+"',
130+ f'__version__ = "{next_version}"',
131+ init_text,
132+ count=1,
133+ )
134+ if updated_init != init_text:
135+ init_path.write_text(updated_init)
61136 PY
137+ if git diff --quiet -- pyproject.toml src/diffio/__init__.py; then
138+ echo "changed=false" >> "$GITHUB_OUTPUT"
139+ else
140+ echo "changed=true" >> "$GITHUB_OUTPUT"
141+ fi
142+
143+ - name : Commit version update
144+ if : ${{ steps.sync_version.outputs.changed == 'true' }}
145+ run : |
146+ git config user.name "github-actions[bot]"
147+ git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
148+ git add pyproject.toml src/diffio/__init__.py
149+ git commit -m "chore(release): bump Python SDK to ${{ steps.version.outputs.next_version }}"
150+ git push origin "HEAD:${GITHUB_REF_NAME}"
62151
63152 - name : Build
64- if : ${{ steps.should_publish .outputs.publish == 'true' }}
153+ if : ${{ steps.version .outputs.publish == 'true' }}
65154 run : python -m build
66155
67156 - name : Publish to PyPI
68- if : ${{ steps.should_publish .outputs.publish == 'true' }}
157+ if : ${{ steps.version .outputs.publish == 'true' }}
69158 uses : pypa/gh-action-pypi-publish@release/v1
0 commit comments