@@ -255,6 +255,11 @@ def get_git_branch():
255255 instead of the real branch. A workaround is provided using
256256 ``READTHEDOCS_VERSION_TYPE`` and ``READTHEDOCS_VERSION`` according to the build type:
257257 - ``"branch"`` builds: READTHEDOCS_VERSION is the branch name (e.g. ``"3.6.x"``) → use it.
258+ Exception: RTD pseudo-name ``"latest"`` is not a real git branch; return None so
259+ resolve_fallback_branch falls back to master/main.
260+ Exception: RTD pseudo-name ``"stable"`` is not a real git branch either; instead we
261+ query ``git describe --tags --abbrev=0 HEAD`` to get the nearest ancestor tag (e.g.
262+ ``"v3.6.1"``), which works whether HEAD is exactly at the tag or has moved past it.
258263 - ``"tag"`` builds: READTHEDOCS_VERSION is the tag name (e.g. ``"v3.6.0"``) → use it.
259264 - ``"external"`` (PR preview) builds: READTHEDOCS_VERSION is the PR number (e.g. ``"1241"``)
260265 which is not a valid git ref. In this case we return None so resolve_fallback_branch falls
@@ -263,7 +268,31 @@ def get_git_branch():
263268 """
264269 rtd_type = os .environ .get ("READTHEDOCS_VERSION_TYPE" )
265270 if rtd_type in ("branch" , "tag" ):
266- return os .environ .get ("READTHEDOCS_VERSION" )
271+ version_name = os .environ .get ("READTHEDOCS_VERSION" )
272+ if version_name == "latest" :
273+ # "latest" is an RTD pseudo-name, not a real branch → fall back to master.
274+ return None
275+ if version_name == "stable" :
276+ # "stable" is an RTD pseudo-name. Find the latest vX.Y.Z tag in the repo.
277+ # Release tags live on dedicated branches (not main), so we scan all tags
278+ # rather than restricting to those reachable from HEAD.
279+ path_to_here = os .path .abspath (os .path .dirname (__file__ ))
280+ try :
281+ p = subprocess .Popen (
282+ ["git" , "tag" , "--sort=-version:refname" ],
283+ stdout = subprocess .PIPE ,
284+ stderr = subprocess .PIPE ,
285+ cwd = path_to_here ,
286+ )
287+ tags = p .communicate ()[0 ].decode ().splitlines ()
288+ release_tag_re = re .compile (r'^v\d+\.\d+\.\d+$' )
289+ for tag in tags :
290+ if release_tag_re .match (tag .strip ()):
291+ return tag .strip ()
292+ except Exception :
293+ pass
294+ return None
295+ return version_name
267296 if rtd_type == "external" :
268297 return None
269298
@@ -410,13 +439,16 @@ def configure_doxyfile(
410439 fastdds_repo_name ,
411440 )
412441
413- # Verify the desired branch actually exists in the cloned remote, falling back to master if not.
442+ # Verify the desired branch/tag actually exists in the cloned remote, falling back to master if not.
414443 fastdds_branch = fastdds_fallback_branch
415444 if fastdds .refs .__contains__ ("origin/{}" .format (fastdds_branch )):
416445 fastdds_branch = "origin/{}" .format (fastdds_branch )
446+ elif fastdds .tags .__contains__ (fastdds_branch ):
447+ # GitPython exposes tags by bare name, e.g. "v3.6.1".
448+ pass
417449 else :
418450 print (
419- 'Fast DDS does not have branch "{}"; falling back to master' .format (
451+ 'Fast DDS does not have branch or tag "{}"; falling back to master' .format (
420452 fastdds_branch
421453 )
422454 )
@@ -433,13 +465,16 @@ def configure_doxyfile(
433465 fastdds_python_repo_name ,
434466 )
435467
436- # Verify the desired branch actually exists in the cloned remote, falling back to master if not.
468+ # Verify the desired branch/tag actually exists in the cloned remote, falling back to master if not.
437469 fastdds_python_branch = fastdds_python_fallback_branch
438470 if fastdds_python .refs .__contains__ ("origin/{}" .format (fastdds_python_branch )):
439471 fastdds_python_branch = "origin/{}" .format (fastdds_python_branch )
472+ elif fastdds_python .tags .__contains__ (fastdds_python_branch ):
473+ # GitPython exposes tags by bare name, e.g. "v3.6.1".
474+ pass
440475 else :
441476 print (
442- 'Fast DDS Python does not have branch "{}"; falling back to master' .format (
477+ 'Fast DDS Python does not have branch or tag "{}"; falling back to master' .format (
443478 fastdds_python_branch
444479 )
445480 )
0 commit comments