From 9cd653cac1762df5a4f7e3b526410108a05ab2f4 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Tue, 2 Jun 2026 15:32:58 -0700 Subject: [PATCH] Use venv in the release script --- support/release.py | 39 +++++++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/support/release.py b/support/release.py index 25b719f0..1e7961a7 100755 --- a/support/release.py +++ b/support/release.py @@ -61,11 +61,14 @@ def clean_checkout(repo, branch): class Runner: - def __init__(self, cwd): + def __init__(self, cwd, env=None): self.cwd = cwd + self.env = env def __call__(self, *args, **kwargs): kwargs['cwd'] = kwargs.get('cwd', self.cwd) + if self.env is not None: + kwargs['env'] = kwargs.get('env', self.env) check_call(args, **kwargs) @@ -80,6 +83,26 @@ def create_build_env(): return env +def create_doc_env(env, fmt_repo): + """Create a virtualenv with the pinned documentation dependencies and + return an environment dict with it prepended to PATH. This ensures the + docs are built with the exact mkdocs/mkdocstrings versions required by the + custom handler, regardless of what is installed system-wide.""" + venv_dir = os.path.join(env.build_dir, 'venv') + shutil.rmtree(venv_dir, ignore_errors=True) + check_call([sys.executable, '-m', 'venv', venv_dir]) + venv_bin = os.path.join(venv_dir, 'bin') + pip = os.path.join(venv_bin, 'pip') + check_call([pip, 'install', '--quiet', '--upgrade', 'pip']) + requirements = os.path.join( + fmt_repo.dir, 'support', 'doc-requirements.txt') + check_call( + [pip, 'install', '--quiet', '--require-hashes', '-r', requirements]) + doc_env = os.environ.copy() + doc_env['PATH'] = venv_bin + os.pathsep + doc_env.get('PATH', '') + return doc_env + + if __name__ == '__main__': args = docopt.docopt(__doc__) env = create_build_env() @@ -151,10 +174,14 @@ if __name__ == '__main__': fmt_repo.add(changelog) fmt_repo.commit('-m', 'Update version') - # Build the docs locally; the source zip is now built and attached to the - # release in CI by .github/workflows/release.yml, which also generates a - # SLSA provenance attestation for it. - run = Runner(fmt_repo.dir) + # Build the docs locally in a virtualenv with the pinned doc dependencies; + # the source zip is now built and attached to the release in CI by + # .github/workflows/release.yml, which also generates a SLSA provenance + # attestation for it. The venv is prepended to PATH so that CMake's + # find_program(MKDOCS mkdocs) and the ./mkdocs deploy step below both pick + # up the correct mkdocs/mkdocstrings versions. + doc_env = create_doc_env(env, fmt_repo) + run = Runner(fmt_repo.dir, env=doc_env) run('cmake', '.') run('make', 'doc') @@ -176,4 +203,4 @@ if __name__ == '__main__': '{response.status} {response.reason}') short_version = '.'.join(version.split('.')[:-1]) - check_call(['./mkdocs', 'deploy', short_version]) + check_call(['./mkdocs', 'deploy', short_version], env=doc_env)