Skip to content

Commit 77dbee4

Browse files
Add version bump script and release workflows (#2322)
* Add version bump script and release workflows * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Improve release branch checkout and creation process Refactor release branch creation logic to check for existing branch and pull updates. * chore(release): update release workflows, bump script, and releasing docs * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 5f370bd commit 77dbee4

File tree

5 files changed

+627
-74
lines changed

5 files changed

+627
-74
lines changed
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
name: Release-bump-master-version
2+
3+
on:
4+
# Triggered only when a release is PUBLISHED
5+
release:
6+
types: [published]
7+
8+
jobs:
9+
bump-master-version:
10+
# CRITICAL: Only run if the published release is NOT a prerelease
11+
if: github.event.release.prerelease == false
12+
runs-on: ubuntu-latest
13+
permissions:
14+
contents: write
15+
pull-requests: write # Necessary for creating the PR
16+
17+
steps:
18+
- name: Checkout repository (Master Branch)
19+
uses: actions/checkout@v4
20+
with:
21+
# Checkout the master branch (the base of the new development branch)
22+
ref: master
23+
token: ${{ secrets.REPO_WRITE_TOKEN }}
24+
fetch-depth: 0
25+
26+
# FIX: Ensure the local master branch is updated to prevent non-fast-forward push errors.
27+
- name: Ensure Master is Up-to-Date
28+
run: |
29+
git pull origin master
30+
31+
- name: Set up Python
32+
uses: actions/setup-python@v5
33+
with:
34+
python-version: '3.11'
35+
36+
- name: Configure Git
37+
run: |
38+
git config user.name "github-actions[bot]"
39+
git config user.email "github-actions[bot]@users.noreply.github.com"
40+
41+
- name: Compute Next Development Version
42+
id: compute
43+
run: |
44+
# 1. Get the stable version from the published release tag (e.g., v0.36.7)
45+
STABLE_VERSION="${{ github.event.release.tag_name }}"
46+
47+
# 2. Strip the leading 'v' and append '.post0'
48+
BASE_VERSION=${STABLE_VERSION/v/}
49+
NEW_DEV_VERSION="${BASE_VERSION}.post0"
50+
51+
# Use a unique branch name tied to the new version
52+
NEW_BRANCH_NAME="chore/bump-to-${NEW_DEV_VERSION}"
53+
54+
echo "Setting master to development version: ${NEW_DEV_VERSION}"
55+
echo "new_dev_version=${NEW_DEV_VERSION}" >> $GITHUB_OUTPUT
56+
echo "new_branch_name=${NEW_BRANCH_NAME}" >> $GITHUB_OUTPUT
57+
58+
- name: Create New Development Branch
59+
run: |
60+
git checkout -b ${{ steps.compute.outputs.new_branch_name }}
61+
62+
- name: Run Version Bump Script
63+
run: |
64+
python scripts/bump_geemap_version.py ${{ steps.compute.outputs.new_dev_version }}
65+
66+
- name: Commit changes
67+
run: |
68+
# Check if the version bump actually changed the files
69+
if git diff --exit-code; then
70+
echo "Version files already up-to-date. No commit needed."
71+
# Set a flag to skip the PR step
72+
echo "skip_pr=true" >> $GITHUB_OUTPUT
73+
else
74+
git add pyproject.toml geemap/__init__.py
75+
# Use [skip ci] to prevent this commit from triggering other CI runs
76+
git commit -m "chore: Set development version to ${{ steps.compute.outputs.new_dev_version }} [skip ci]"
77+
echo "skip_pr=false" >> $GITHUB_OUTPUT
78+
fi
79+
id: commit_check
80+
81+
- name: Create Pull Request to Master (using gh CLI)
82+
# Only run if the commit_check step confirms changes were made.
83+
if: ${{ steps.commit_check.outputs.skip_pr == 'false' }}
84+
env:
85+
# Use the token for gh CLI authentication
86+
GH_TOKEN: ${{ secrets.REPO_WRITE_TOKEN }}
87+
run: |
88+
BRANCH="${{ steps.compute.outputs.new_branch_name }}"
89+
TITLE="chore: Sync master version to ${{ steps.compute.outputs.new_dev_version }}"
90+
91+
# 1. Push the local branch to the remote (Now guaranteed to work after the git pull)
92+
git push origin $BRANCH
93+
94+
# 2. Define the multiline body content
95+
PR_BODY="This is an **automated Pull Request** triggered by the publication of the stable release **${{ github.event.release.tag_name }}**.
96+
97+
This PR updates the version numbers in \`pyproject.toml\` and \`geemap/__init__.py\` from the stable version to **\`${{ steps.compute.outputs.new_dev_version }}\`**. This is done to indicate that the master branch is now tracking the next development cycle.
98+
99+
**Please review and merge only after all downstream release checks (PyPI, Conda, Docs, etc.) are confirmed successful.**"
100+
101+
# 3. Create the PR using the gh CLI
102+
gh pr create \
103+
--base master \
104+
--head $BRANCH \
105+
--title "$TITLE" \
106+
--body "$PR_BODY" \
107+
--label "automated" \
108+
--label "maintenance"
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
name: Release-prerelease
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
version:
7+
description: 'Base version number (e.g., 0.36.7)'
8+
required: true
9+
type: string
10+
rc_number:
11+
description: 'Release candidate number (default: 1)'
12+
required: false
13+
type: string
14+
default: '1'
15+
publish_immediately:
16+
description: 'Publish release immediately (otherwise created as draft)'
17+
required: false
18+
type: boolean
19+
default: false
20+
21+
jobs:
22+
create-prerelease:
23+
runs-on: ubuntu-latest
24+
permissions:
25+
contents: write
26+
27+
steps:
28+
- name: Checkout repository
29+
uses: actions/checkout@v4
30+
with:
31+
token: ${{ secrets.REPO_WRITE_TOKEN || secrets.GITHUB_TOKEN }}
32+
fetch-depth: 0
33+
34+
- name: Set up Python
35+
uses: actions/setup-python@v5
36+
with:
37+
python-version: '3.11'
38+
39+
- name: Configure Git
40+
run: |
41+
git config user.name "github-actions[bot]"
42+
git config user.email "github-actions[bot]@users.noreply.github.com"
43+
44+
- name: Compute branch and version names
45+
id: compute
46+
run: |
47+
VERSION="${{ github.event.inputs.version }}"
48+
RC_NUM="${{ github.event.inputs.rc_number }}"
49+
BRANCH_NAME="v${VERSION}-release"
50+
FULL_VERSION="${VERSION}rc${RC_NUM}"
51+
TAG_NAME="v${FULL_VERSION}"
52+
53+
echo "branch_name=${BRANCH_NAME}" >> $GITHUB_OUTPUT
54+
echo "full_version=${FULL_VERSION}" >> $GITHUB_OUTPUT
55+
echo "tag_name=${TAG_NAME}" >> $GITHUB_OUTPUT
56+
57+
echo "Branch to create: ${BRANCH_NAME}"
58+
echo "Full version: ${FULL_VERSION}"
59+
echo "Tag: ${TAG_NAME}"
60+
61+
- name: Checkout or Create Release Branch
62+
run: |
63+
BRANCH_NAME="${{ steps.compute.outputs.branch_name }}"
64+
if git fetch origin $BRANCH_NAME; then
65+
echo "Using existing branch $BRANCH_NAME."
66+
git checkout $BRANCH_NAME
67+
# Ensure the local branch tracks the remote for safe pushing
68+
git pull origin $BRANCH_NAME
69+
else
70+
echo "Creating branch $BRANCH_NAME from master."
71+
git fetch origin master
72+
git checkout -b $BRANCH_NAME origin/master
73+
fi
74+
75+
- name: Bump version to prerelease
76+
run: |
77+
python scripts/bump_geemap_version.py ${{ steps.compute.outputs.full_version }}
78+
79+
- name: Show git diff
80+
run: |
81+
echo "Changes made by version bump:"
82+
git --no-pager diff
83+
84+
- name: Commit and push changes
85+
run: |
86+
git add pyproject.toml geemap/__init__.py
87+
git commit -m "Bump geemap to v${{ steps.compute.outputs.full_version }}"
88+
git push origin ${{ steps.compute.outputs.branch_name }}
89+
90+
- name: Create and push tag
91+
run: |
92+
git tag -a "${{ steps.compute.outputs.tag_name }}" -m "Release ${{ steps.compute.outputs.full_version }}"
93+
git push origin "${{ steps.compute.outputs.tag_name }}"
94+
95+
- name: Create GitHub Prerelease
96+
env:
97+
GH_TOKEN: ${{ secrets.REPO_WRITE_TOKEN || secrets.GITHUB_TOKEN }}
98+
run: |
99+
# Find the last non-prerelease tag
100+
LAST_RELEASE=$(gh release list --exclude-pre-releases --limit 1 --json tagName --jq '.[0].tagName')
101+
102+
# Determine if release should be draft or published immediately
103+
if [ "${{ github.event.inputs.publish_immediately }}" == "true" ]; then
104+
DRAFT_FLAG=""
105+
else
106+
DRAFT_FLAG="--draft"
107+
fi
108+
109+
if [ -z "$LAST_RELEASE" ]; then
110+
echo "No previous release found, generating notes from all commits"
111+
gh release create "${{ steps.compute.outputs.tag_name }}" \
112+
--title "${{ steps.compute.outputs.tag_name }}" \
113+
--prerelease \
114+
$DRAFT_FLAG \
115+
--generate-notes
116+
else
117+
echo "Generating changelog from ${LAST_RELEASE} to ${{ steps.compute.outputs.tag_name }}"
118+
gh release create "${{ steps.compute.outputs.tag_name }}" \
119+
--title "${{ steps.compute.outputs.tag_name }}" \
120+
--prerelease \
121+
$DRAFT_FLAG \
122+
--generate-notes \
123+
--notes-start-tag "${LAST_RELEASE}"
124+
fi
125+
126+
- name: Summary
127+
run: |
128+
echo "## Prerelease Created Successfully! 🚀" >> $GITHUB_STEP_SUMMARY
129+
echo "" >> $GITHUB_STEP_SUMMARY
130+
echo "- **Branch**: ${{ steps.compute.outputs.branch_name }}" >> $GITHUB_STEP_SUMMARY
131+
echo "- **Version**: ${{ steps.compute.outputs.full_version }}" >> $GITHUB_STEP_SUMMARY
132+
echo "- **Tag**: ${{ steps.compute.outputs.tag_name }}" >> $GITHUB_STEP_SUMMARY
133+
echo "- **Release URL**: https://github.com/${{ github.repository }}/releases/tag/${{ steps.compute.outputs.tag_name }}" >> $GITHUB_STEP_SUMMARY
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
name: Release-stable
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
version:
7+
description: 'Version number (e.g., 0.36.6)'
8+
required: true
9+
type: string
10+
publish_immediately:
11+
description: 'Publish release immediately (otherwise created as draft)'
12+
required: false
13+
type: boolean
14+
default: false
15+
16+
jobs:
17+
create-release:
18+
runs-on: ubuntu-latest
19+
permissions:
20+
contents: write
21+
22+
steps:
23+
- name: Checkout repository
24+
uses: actions/checkout@v4
25+
with:
26+
token: ${{ secrets.REPO_WRITE_TOKEN || secrets.GITHUB_TOKEN }}
27+
fetch-depth: 0
28+
29+
- name: Set up Python
30+
uses: actions/setup-python@v5
31+
with:
32+
python-version: '3.11'
33+
34+
- name: Configure Git
35+
run: |
36+
git config user.name "github-actions[bot]"
37+
git config user.email "github-actions[bot]@users.noreply.github.com"
38+
39+
- name: Compute version and branch names
40+
id: compute
41+
run: |
42+
VERSION="${{ github.event.inputs.version }}"
43+
RELEASE_BRANCH="v${VERSION}-release"
44+
TAG_NAME="v${VERSION}"
45+
46+
echo "version=${VERSION}" >> $GITHUB_OUTPUT
47+
echo "release_branch=${RELEASE_BRANCH}" >> $GITHUB_OUTPUT
48+
echo "tag_name=${TAG_NAME}" >> $GITHUB_OUTPUT
49+
50+
echo "Version: ${VERSION}"
51+
echo "Expected release branch: ${RELEASE_BRANCH}"
52+
echo "Tag: ${TAG_NAME}"
53+
54+
- name: Checkout release branch
55+
run: |
56+
# Try to checkout the release branch
57+
if git fetch origin ${{ steps.compute.outputs.release_branch }}; then
58+
git checkout ${{ steps.compute.outputs.release_branch }}
59+
echo "Checked out existing release branch: ${{ steps.compute.outputs.release_branch }}"
60+
else
61+
echo "ERROR: Release branch ${{ steps.compute.outputs.release_branch }} does not exist."
62+
echo "Primary releases should be created from the prerelease branch."
63+
echo "Please create a prerelease first using the prerelease workflow."
64+
exit 1
65+
fi
66+
67+
- name: Bump version to release
68+
run: |
69+
python scripts/bump_geemap_version.py ${{ steps.compute.outputs.version }}
70+
71+
- name: Show git diff
72+
run: |
73+
echo "Changes made by version bump:"
74+
git --no-pager diff
75+
76+
- name: Commit changes
77+
run: |
78+
git add pyproject.toml geemap/__init__.py
79+
git commit -m "Bump geemap to v${{ steps.compute.outputs.version }}"
80+
81+
- name: Create and push tag
82+
run: |
83+
git tag -a "${{ steps.compute.outputs.tag_name }}" -m "Release ${{ steps.compute.outputs.version }}"
84+
git push origin "${{ steps.compute.outputs.tag_name }}"
85+
86+
- name: Create GitHub Release
87+
env:
88+
GH_TOKEN: ${{ secrets.REPO_WRITE_TOKEN || secrets.GITHUB_TOKEN }}
89+
run: |
90+
# Find the last non-prerelease tag
91+
LAST_RELEASE=$(gh release list --exclude-pre-releases --limit 1 --json tagName --jq '.[0].tagName')
92+
93+
# Determine if release should be draft or published immediately
94+
if [ "${{ github.event.inputs.publish_immediately }}" == "true" ]; then
95+
DRAFT_FLAG=""
96+
else
97+
DRAFT_FLAG="--draft"
98+
fi
99+
100+
if [ -z "$LAST_RELEASE" ]; then
101+
echo "No previous release found, generating notes from all commits"
102+
gh release create "${{ steps.compute.outputs.tag_name }}" \
103+
--title "${{ steps.compute.outputs.tag_name }}" \
104+
--latest \
105+
$DRAFT_FLAG \
106+
--generate-notes
107+
else
108+
echo "Generating changelog from ${LAST_RELEASE} to ${{ steps.compute.outputs.tag_name }}"
109+
gh release create "${{ steps.compute.outputs.tag_name }}" \
110+
--title "${{ steps.compute.outputs.tag_name }}" \
111+
--latest \
112+
$DRAFT_FLAG \
113+
--generate-notes \
114+
--notes-start-tag "${LAST_RELEASE}"
115+
fi
116+
117+
- name: Summary
118+
run: |
119+
echo "## Release Created Successfully! 🎉" >> $GITHUB_STEP_SUMMARY
120+
echo "" >> $GITHUB_STEP_SUMMARY
121+
echo "- **Version**: ${{ steps.compute.outputs.version }}" >> $GITHUB_STEP_SUMMARY
122+
echo "- **Tag**: ${{ steps.compute.outputs.tag_name }}" >> $GITHUB_STEP_SUMMARY
123+
echo "- **Release URL**: https://github.com/${{ github.repository }}/releases/tag/${{ steps.compute.outputs.tag_name }}" >> $GITHUB_STEP_SUMMARY
124+
echo "" >> $GITHUB_STEP_SUMMARY
125+
echo "A Pull Request for the development version bump to master has been initiated." >> $GITHUB_STEP_SUMMARY

0 commit comments

Comments
 (0)