11#!/usr/bin/env python
2+ # /// script
3+ # requires-python = ">=3.13"
4+ # dependencies = [
5+ # "gitpython>=3.1.46,<3.2.0",
6+ # "packaging>=26.0,<26.1",
7+ # "pyyaml>=6.0.3,<6.1.0",
8+ # ]
9+ # ///
210
311import argparse
412import re
513import os
14+ import sys
615import tomllib
7- import yaml
16+ import typing as t
817from pathlib import Path
18+
19+ import yaml
920from packaging .version import Version
1021from git import Repo
1122
1425Z_CHANGELOG_EXTS = [".bugfix" , ".misc" ]
1526
1627
17- def options ():
28+ def options () -> argparse . Namespace :
1829 """Check which branches need a release."""
1930 parser = argparse .ArgumentParser ()
2031 parser .add_argument (
@@ -33,13 +44,13 @@ def options():
3344 return parser .parse_args ()
3445
3546
36- def template_config ():
47+ def template_config () -> dict [ str , t . Any ] :
3748 # Assume this script lies in .ci/scripts
3849 path = Path (__file__ ).absolute ().parent .parent .parent / "template_config.yml"
3950 return yaml .safe_load (path .read_text ())
4051
4152
42- def current_version (repo , commitish ) :
53+ def current_version (repo : Repo , commitish : str ) -> Version :
4354 try :
4455 pyproject_toml = tomllib .loads (repo .git .show (f"{ commitish } :pyproject.toml" ))
4556 try :
@@ -53,7 +64,7 @@ def current_version(repo, commitish):
5364 return Version (current_version )
5465
5566
56- def check_pyproject_dependencies (repo , from_commit , to_commit ) :
67+ def check_pyproject_dependencies (repo : Repo , from_commit : str , to_commit : str ) -> list [ str ] :
5768 try :
5869 new_pyproject = tomllib .loads (repo .git .show (f"{ to_commit } :pyproject.toml" ))
5970 try :
@@ -74,8 +85,8 @@ def check_pyproject_dependencies(repo, from_commit, to_commit):
7485 return ["pyproject.toml changed somehow (PLEASE check if dependencies are affected)." ]
7586
7687
77- def main (options , template_config ) :
78- DEFAULT_BRANCH = template_config ["plugin_default_branch" ]
88+ def main (options : argparse . Namespace , template_config : dict [ str , t . Any ]) -> int :
89+ DEFAULT_BRANCH : str = template_config ["plugin_default_branch" ]
7990
8091 repo = Repo ()
8192
@@ -88,9 +99,9 @@ def main(options, template_config):
8899
89100 # Warning: This will not work if branch names contain "/" but we don't really care here.
90101 heads = [h .split ("/" )[- 1 ] for h in repo .git .branch ("--remote" ).split ("\n " )]
91- available_branches = [ h for h in heads if re . search ( RELEASE_BRANCH_REGEX , h )]
92- available_branches . sort ( key = lambda ver : Version (ver ) )
93- available_branches . append ( DEFAULT_BRANCH )
102+ available_branches = sorted (
103+ { h for h in heads if re . fullmatch ( RELEASE_BRANCH_REGEX , h )}, key = lambda ver : Version (ver )
104+ ) + [ DEFAULT_BRANCH ]
94105
95106 branches = options .branches
96107 if branches == "supported" :
@@ -105,7 +116,10 @@ def main(options, template_config):
105116
106117 if diff := branches - set (available_branches ):
107118 print (f"Supplied branches contains non-existent branches! { diff } " )
108- exit (1 )
119+ return 1
120+
121+ branches = [branch for branch in available_branches if branch in branches ]
122+ branches .reverse ()
109123
110124 print (f"Checking for releases on branches: { branches } " )
111125
@@ -170,6 +184,8 @@ def main(options, template_config):
170184 if len (releases ) == 0 :
171185 print ("No new releases to perform." )
172186
187+ return 0
188+
173189
174190if __name__ == "__main__" :
175- main (options (), template_config ())
191+ sys . exit ( main (options (), template_config () ))
0 commit comments