Inside Bitcoin
Opening the selected file…
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
1#!/usr/bin/env python32# Copyright (c) The Bitcoin Core developers3# Distributed under the MIT software license, see the accompanying4# file COPYING or https://opensource.org/license/mit/.6import argparse7import os8import shlex9import subprocess10import sys11import time12from pathlib import Path14sys.path.append(str(Path(__file__).resolve().parent.parent / "test"))15from download_utils import download_script_assets18def run(cmd, **kwargs):19print("+ " + shlex.join(cmd), flush=True)20kwargs.setdefault("check", True)21try:22return subprocess.run(cmd, **kwargs)23except Exception as e:24sys.exit(str(e))27GENERATE_OPTIONS = {28"standard": [29"-DBUILD_BENCH=ON",30"-DBUILD_KERNEL_LIB=ON",31"-DBUILD_UTIL_CHAINSTATE=ON",32"-DCMAKE_COMPILE_WARNING_AS_ERROR=ON",33],34"fuzz": [35"-DVCPKG_MANIFEST_NO_DEFAULT_FEATURES=ON",36"-DVCPKG_MANIFEST_FEATURES=wallet",37"-DBUILD_FOR_FUZZING=ON",38"-DCMAKE_COMPILE_WARNING_AS_ERROR=ON",39],40}43def github_import_vs_env(_ci_type):44vswhere_path = Path(os.environ["ProgramFiles(x86)"]) / "Microsoft Visual Studio" / "Installer" / "vswhere.exe"45installation_path = run(46[str(vswhere_path), "-latest", "-property", "installationPath"],47capture_output=True,48text=True,49).stdout.strip()50vsdevcmd = Path(installation_path) / "Common7" / "Tools" / "vsdevcmd.bat"51comspec = os.environ["COMSPEC"]52output = run(53f'"{comspec}" /s /c ""{vsdevcmd}" -arch=x64 -no_logo && set"',54capture_output=True,55text=True,56).stdout57github_env = os.environ["GITHUB_ENV"]58with open(github_env, "a") as env_file:59for line in output.splitlines():60if "=" not in line:61continue62name, value = line.split("=", 1)63env_file.write(f"{name}={value}\n")66def generate(ci_type):67command = [68"cmake",69"-B",70"build",71"-Werror=dev",72"--preset=vs2026",73# Using x64-windows-release for both host and target triplets74# to ensure vcpkg builds only release packages, thereby optimizing75# build time.76# See https://github.com/microsoft/vcpkg/issues/50927.77"-DVCPKG_HOST_TRIPLET=x64-windows-release",78"-DVCPKG_TARGET_TRIPLET=x64-windows-release",79] + GENERATE_OPTIONS[ci_type]80if run(command, check=False).returncode != 0:81print("=== ⚠️ ===")82print("Generate failure! Network issue? Retry once ...")83time.sleep(12)84print("=== ⚠️ ===")85run(command)88def build(_ci_type):89command = [90"cmake",91"--build",92"build",93"--config",94"Release",95]96if run(command + ["-j", str(os.process_cpu_count())], check=False).returncode != 0:97print("Build failure. Verbose build follows.")98run(command + ["-j1", "--verbose"])101def check_manifests(ci_type):102if ci_type != "standard":103print(f"Skipping manifest validation for '{ci_type}' ci type.")104return106release_dir = Path.cwd() / "build" / "bin" / "Release"107manifest_path = release_dir / "bitcoind.manifest"108cmd_bitcoind_manifest = [109"mt.exe",110"-nologo",111f"-inputresource:{release_dir / 'bitcoind.exe'}",112f"-out:{manifest_path}",113]114run(cmd_bitcoind_manifest)115print(manifest_path.read_text())117skips = { # Skip as they currently do not have manifests118"fuzz.exe",119"bench_bitcoin.exe",120"test_bitcoin-qt.exe",121"bitcoin-chainstate.exe",122}123for entry in release_dir.iterdir():124if entry.suffix.lower() != ".exe":125continue126if entry.name in skips:127print(f"Skipping {entry.name} (no manifest present)")128continue129print(f"Checking {entry.name}")130cmd_check_manifest = [131"mt.exe",132"-nologo",133f"-inputresource:{entry}",134"-validate_manifest",135]136run(cmd_check_manifest)139def prepare_tests(ci_type):140workspace = Path.cwd()141if ci_type == "standard":142run([sys.executable, "-m", "pip", "install", "pyzmq"])143dest = workspace / "unit_test_data"144download_script_assets(dest)145elif ci_type == "fuzz":146repo_dir = str(workspace / "qa-assets")147clone_cmd = [148"git",149"clone",150"--depth=1",151"https://github.com/bitcoin-core/qa-assets",152repo_dir,153]154run(clone_cmd)155print("Using qa-assets repo from commit ...")156run(["git", "-C", repo_dir, "log", "-1"])159def run_tests(ci_type):160workspace = Path.cwd()161build_dir = workspace / "build"162num_procs = str(os.process_cpu_count())163release_bin = build_dir / "bin" / "Release"165if ci_type == "standard":166os.environ["DIR_UNIT_TEST_DATA"] = str(workspace / "unit_test_data")167test_envs = {168"BITCOIN_BIN": "bitcoin.exe",169"BITCOIND": "bitcoind.exe",170"BITCOINCLI": "bitcoin-cli.exe",171"BITCOIN_BENCH": "bench_bitcoin.exe",172"BITCOINTX": "bitcoin-tx.exe",173"BITCOINUTIL": "bitcoin-util.exe",174"BITCOINWALLET": "bitcoin-wallet.exe",175"BITCOINCHAINSTATE": "bitcoin-chainstate.exe",176}177for var, exe in test_envs.items():178os.environ[var] = str(release_bin / exe)180ctest_cmd = [181"ctest",182"--test-dir",183str(build_dir),184"--output-on-failure",185"--stop-on-failure",186"-j",187num_procs,188"--build-config",189"Release",190]191run(ctest_cmd)193test_cmd = [194sys.executable,195str(build_dir / "test" / "functional" / "test_runner.py"),196"--jobs",197num_procs,198"--quiet",199f"--tmpdirprefix={workspace / '_ _'}",200"--combinedlogslen=99999999",201*shlex.split(os.environ.get("TEST_RUNNER_EXTRA", "").strip()),202]203run(test_cmd)205elif ci_type == "fuzz":206os.environ["BITCOINFUZZ"] = str(release_bin / "fuzz.exe")207fuzz_cmd = [208sys.executable,209str(build_dir / "test" / "fuzz" / "test_runner.py"),210"--par",211num_procs,212"--loglevel",213"DEBUG",214str(workspace / "qa-assets" / "fuzz_corpora"),215]216run(fuzz_cmd)219def main():220parser = argparse.ArgumentParser(description="Utility to run Windows CI steps.")221parser.add_argument("ci_type", choices=GENERATE_OPTIONS, help="CI type to run.")222steps = list(map(lambda f: f.__name__, [223github_import_vs_env,224generate,225build,226check_manifests,227prepare_tests,228run_tests,229]))230parser.add_argument("step", choices=steps, help="CI step to perform.")231args = parser.parse_args()233exec(f'{args.step}("{args.ci_type}")')236if __name__ == "__main__":237main()
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.