Summary
Add a Python automation script (utility/automation/check_milestone.py) and a companion GitHub Actions workflow to verify that all issues assigned to a milestone have been correctly backported to the corresponding release branch.
Motivation
During release preparation, it is easy to miss a backport PR for a fix that was merged on master but not carried over to the stable branch (e.g. 2026.01.xx). Manual checking across many issues is time-consuming and error-prone. This tool automates the entire cross-check.
What was added
utility/automation/check_milestone.py
A standalone Python script (requires only requests) that:
- Resolves the milestone by title (e.g.
2026.01.01) to its numeric GitHub API id, with full pagination support.
- Fetches all issues in the milestone, excluding PR entries returned by the GitHub API.
- Determines the branch-cut date by querying the merge-base commit between the main branch and the target branch. Issues whose main-branch PR was merged before the branch was cut are already included in the release branch and require no backport — they are marked ✅ automatically.
- Classifies each issue with two Search API calls (one per branch) and assigns a status:
| Icon |
Status |
Meaning |
| ✅ |
OK |
Backport merged, or merged before branch cut |
| ⚠️ |
Missing backport |
Merged on main, no backport PR found |
| 📥 |
In progress |
Merged on main, backport PR open |
| 🏗️ |
In progress |
Main PR still open |
| ❓ |
No PR |
No PR found anywhere (release tasks, manual items) |
- Prints a structured report with a per-issue row and a final summary bucketed by status.
- Exits with code 1 only when confirmed missing backports are found, so it integrates cleanly in CI.
Rate-limit handling:
- Configurable sleep interval between Search API calls (2.5 s authenticated / 7 s unauthenticated).
- Exponential back-off with up to 5 retries on
403/429 responses, honouring the Retry-After header.
Configuration via CLI args or environment variables:
| CLI arg |
Env var |
Default |
--token |
GITHUB_TOKEN |
(empty) |
--repo |
REPO |
geosolutions-it/MapStore2 |
--milestone |
MILESTONE_TITLE |
2026.01.01 |
--main-branch |
MAIN_BRANCH |
master |
--branch |
TARGET_BRANCH |
2026.01.xx |
.github/workflows/check_milestone.yml
A workflow_dispatch GitHub Actions workflow that runs the script on demand with inputs for milestone title, target branch, and main branch. Uses the built-in GITHUB_TOKEN — no additional secrets required.
Usage
Locally:
python utility/automation/check_milestone.py \
--token ghp_... \
--milestone 2026.01.01 \
--branch 2026.01.xx
GitHub Actions: trigger manually from the Actions tab, filling in the two required inputs.
Summary
Add a Python automation script (
utility/automation/check_milestone.py) and a companion GitHub Actions workflow to verify that all issues assigned to a milestone have been correctly backported to the corresponding release branch.Motivation
During release preparation, it is easy to miss a backport PR for a fix that was merged on
masterbut not carried over to the stable branch (e.g.2026.01.xx). Manual checking across many issues is time-consuming and error-prone. This tool automates the entire cross-check.What was added
utility/automation/check_milestone.pyA standalone Python script (requires only
requests) that:2026.01.01) to its numeric GitHub API id, with full pagination support.Rate-limit handling:
403/429responses, honouring theRetry-Afterheader.Configuration via CLI args or environment variables:
--tokenGITHUB_TOKEN--repoREPOgeosolutions-it/MapStore2--milestoneMILESTONE_TITLE2026.01.01--main-branchMAIN_BRANCHmaster--branchTARGET_BRANCH2026.01.xx.github/workflows/check_milestone.ymlA
workflow_dispatchGitHub Actions workflow that runs the script on demand with inputs for milestone title, target branch, and main branch. Uses the built-inGITHUB_TOKEN— no additional secrets required.Usage
Locally:
python utility/automation/check_milestone.py \ --token ghp_... \ --milestone 2026.01.01 \ --branch 2026.01.xxGitHub Actions: trigger manually from the Actions tab, filling in the two required inputs.