Skip to content

Commit dcbd11a

Browse files
authored
release process (#51)
* release process * nits * nits --------- Co-authored-by: Datata1 <>
1 parent d55700a commit dcbd11a

File tree

4 files changed

+346
-35
lines changed

4 files changed

+346
-35
lines changed

.github/workflows/publish.yml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,13 @@ on:
44
push:
55
tags:
66
- 'v*'
7-
branches:
8-
- main
97

108
env:
119
UV_PUBLISH_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
1210

1311
jobs:
14-
uv-example:
15-
name: python
12+
publish:
13+
name: Publish to PyPI & GitHub Release
1614
runs-on: ubuntu-latest
1715

1816
permissions:

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,5 @@ env/
1919
*.env
2020

2121
.pytest_cache
22+
23+
__marimo__

Makefile

Lines changed: 86 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1-
.PHONY: help install commit lint format test test-integration test-unit bump
1+
.PHONY: help install lint format test test-integration test-unit bump release pypi tree version changelog
22

33
.DEFAULT_GOAL := help
44

5+
CURRENT_VERSION = $(shell grep '^version' pyproject.toml | head -1 | sed 's/.*"\(.*\)"/\1/')
6+
57
help: ## Shows a help message with all available commands
68
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf " \033[36m%-15s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST)
79

10+
811
install: ## Sets up the development environment
912
@echo ">>> Setting up the development environment..."
1013
@echo "1. Creating virtual environment with uv..."
@@ -15,15 +18,6 @@ install: ## Sets up the development environment
1518
uv run pre-commit install --hook-type commit-msg --hook-type pre-commit --hook-type pre-push
1619
@echo "\n\033[0;32mSetup complete! Please activate the virtual environment with 'source .venv/bin/activate'.\033[0m"
1720

18-
commit: ## Starts Commitizen for a guided commit message
19-
@echo ">>> Starting Commitizen for a guided commit message..."
20-
@if git diff --cached --quiet; then \
21-
echo "\033[0;33mWarning: No changes added to commit (please use 'git add ...' first).\033[0m"; \
22-
exit 1; \
23-
fi
24-
uv run cz commit
25-
uv run cz bump --changelog --allow-no-commit
26-
2721

2822
lint: ## Checks code quality with ruff
2923
@echo ">>> Checking code quality with ruff..."
@@ -53,35 +47,96 @@ test-integration: ## Runs integration tests (requires CS_TOKEN env var or .env f
5347
fi; \
5448
uv run pytest tests/integration -v --run-integration
5549

56-
release: ## Pushes a new tag and release
57-
@echo ">>> Starting release process..."
58-
git config --global push.followTags true
50+
version: ## Shows the current project version
51+
@echo "$(CURRENT_VERSION)"
5952

60-
@echo "\n>>> Verifying tag and pushing to remote..."
61-
export VERSION=$$(uv run cz version --project); \
62-
if [ -z "$${VERSION}" ]; then \
63-
echo "\033[0;31mERROR: Could not determine version using 'cz version --project'.\033[0m"; \
53+
bump: ## Bumps the version. Usage: make bump VERSION=0.5.0
54+
@if [ -z "$(VERSION)" ]; then \
55+
echo "\033[0;31mERROR: VERSION is required. Usage: make bump VERSION=0.5.0\033[0m"; \
56+
echo " Current version: $(CURRENT_VERSION)"; \
6457
exit 1; \
65-
fi; \
66-
echo "--- Found project version: v$${VERSION} ---"; \
67-
if git rev-parse "v$${VERSION}" >/dev/null 2>&1; then \
68-
echo "--- Verified local tag v$${VERSION} exists. ---"; \
58+
fi
59+
@echo ">>> Bumping version from $(CURRENT_VERSION) to $(VERSION)..."
60+
@sed -i '' 's/^version = ".*"/version = "$(VERSION)"/' pyproject.toml
61+
@echo "\033[0;32mVersion updated to $(VERSION) in pyproject.toml\033[0m"
62+
63+
changelog: ## Generates a changelog entry from git log since last tag. Usage: make changelog [VERSION=x.y.z]
64+
@NEW_VERSION=$${VERSION:-$(CURRENT_VERSION)}; \
65+
LAST_TAG=$$(git describe --tags --abbrev=0 2>/dev/null || echo ""); \
66+
DATE=$$(date +%Y-%m-%d); \
67+
echo ">>> Generating changelog for v$${NEW_VERSION} ($${DATE})..."; \
68+
TMPFILE=$$(mktemp); \
69+
echo "## v$${NEW_VERSION} ($${DATE})" > $$TMPFILE; \
70+
echo "" >> $$TMPFILE; \
71+
if [ -n "$$LAST_TAG" ]; then \
72+
FEATS=$$(git log $${LAST_TAG}..HEAD --pretty=format:"- %s" --grep="^feat" 2>/dev/null); \
73+
FIXES=$$(git log $${LAST_TAG}..HEAD --pretty=format:"- %s" --grep="^fix" 2>/dev/null); \
74+
REFACTORS=$$(git log $${LAST_TAG}..HEAD --pretty=format:"- %s" --grep="^refactor" 2>/dev/null); \
75+
OTHERS=$$(git log $${LAST_TAG}..HEAD --pretty=format:"- %s" --invert-grep --grep="^feat" --grep="^fix" --grep="^refactor" 2>/dev/null); \
6976
else \
70-
echo "\033[0;31mERROR: Git tag v$${VERSION} was not found! Please check for errors.\033[0m"; \
71-
exit 1; \
77+
FEATS=$$(git log --pretty=format:"- %s" --grep="^feat" 2>/dev/null); \
78+
FIXES=$$(git log --pretty=format:"- %s" --grep="^fix" 2>/dev/null); \
79+
REFACTORS=$$(git log --pretty=format:"- %s" --grep="^refactor" 2>/dev/null); \
80+
OTHERS=""; \
7281
fi; \
73-
echo "--- Pushing commit and tag to remote... ---"; \
74-
git tag -d v$${VERSION}; \
75-
git tag -a v$${VERSION} -m "Release $${VERSION}"; \
76-
git push --follow-tags; \
77-
echo "\n\033[0;32m✅ SUCCESS: Tag v$${VERSION} pushed to GitHub. The release workflow has been triggered.\033[0m"
82+
if [ -n "$$FEATS" ]; then echo "### Features\n" >> $$TMPFILE; echo "$$FEATS" >> $$TMPFILE; echo "" >> $$TMPFILE; fi; \
83+
if [ -n "$$FIXES" ]; then echo "### Fixes\n" >> $$TMPFILE; echo "$$FIXES" >> $$TMPFILE; echo "" >> $$TMPFILE; fi; \
84+
if [ -n "$$REFACTORS" ]; then echo "### Refactors\n" >> $$TMPFILE; echo "$$REFACTORS" >> $$TMPFILE; echo "" >> $$TMPFILE; fi; \
85+
if [ -n "$$OTHERS" ]; then echo "### Other\n" >> $$TMPFILE; echo "$$OTHERS" >> $$TMPFILE; echo "" >> $$TMPFILE; fi; \
86+
if [ -f CHANGELOG.md ]; then \
87+
cat CHANGELOG.md >> $$TMPFILE; \
88+
fi; \
89+
mv $$TMPFILE CHANGELOG.md; \
90+
echo "\033[0;32mChangelog updated.\033[0m"
91+
92+
release: ## Bumps version, updates changelog, commits, tags, and pushes. Usage: make release VERSION=0.5.0
93+
@if [ -z "$(VERSION)" ]; then \
94+
echo "\033[0;31mERROR: VERSION is required. Usage: make release VERSION=0.5.0\033[0m"; \
95+
echo " Current version: $(CURRENT_VERSION)"; \
96+
exit 1; \
97+
fi
98+
@echo ">>> Starting release v$(VERSION)..."
99+
@# Guard: ensure working tree is clean (except for staged changes)
100+
@if [ -n "$$(git status --porcelain)" ]; then \
101+
echo "\033[0;33mWarning: You have uncommitted changes. Please commit or stash them first.\033[0m"; \
102+
git status --short; \
103+
exit 1; \
104+
fi
105+
@# Guard: ensure we are on main branch
106+
@BRANCH=$$(git rev-parse --abbrev-ref HEAD); \
107+
if [ "$$BRANCH" != "main" ]; then \
108+
echo "\033[0;33mWarning: You are on branch '$$BRANCH', not 'main'. Continue? [y/N]\033[0m"; \
109+
read -r CONFIRM; \
110+
if [ "$$CONFIRM" != "y" ] && [ "$$CONFIRM" != "Y" ]; then \
111+
echo "Aborted."; \
112+
exit 1; \
113+
fi; \
114+
fi
115+
@# Guard: ensure tag does not already exist
116+
@if git rev-parse "v$(VERSION)" >/dev/null 2>&1; then \
117+
echo "\033[0;31mERROR: Tag v$(VERSION) already exists.\033[0m"; \
118+
exit 1; \
119+
fi
120+
@# Step 1: Bump version in pyproject.toml
121+
$(MAKE) bump VERSION=$(VERSION)
122+
@# Step 2: Update CHANGELOG.md
123+
$(MAKE) changelog VERSION=$(VERSION)
124+
@# Step 3: Commit and tag
125+
@echo ">>> Committing release..."
126+
git add pyproject.toml CHANGELOG.md
127+
git commit -m "release: v$(VERSION)"
128+
git tag -a "v$(VERSION)" -m "Release $(VERSION)"
129+
@# Step 4: Push commit and tag
130+
@echo ">>> Pushing to remote..."
131+
git push --follow-tags
132+
@echo "\n\033[0;32m✅ Released v$(VERSION). GitHub Actions will publish to PyPI and create the GitHub Release.\033[0m"
78133

79-
pypi: ## publishes to PyPI
134+
pypi: ## Builds and publishes to PyPI (usually called by CI)
80135
@echo "\n>>> Building package for distribution..."
81136
uv build
82137
@echo "\n>>> Publishing to PyPI..."
83138
uv publish
84-
@echo "\n\033[0;32mPyPI release complete! The GitHub Action will now create the GitHub Release.\033[0m"
139+
@echo "\n\033[0;32mPyPI release complete!\033[0m"
85140

86-
tree: ## shows filetree in terminal without uninteresting files
141+
tree: ## Shows filetree in terminal without uninteresting files
87142
tree -I "*.pyc|*.lock"

0 commit comments

Comments
 (0)