From 99e8ae76d056bfab497f9f52337327f23e288f57 Mon Sep 17 00:00:00 2001 From: rustaceanrob Date: Sun, 17 May 2026 16:19:17 +0100 Subject: [PATCH] Remove Windows CI jobs and helper scripts Co-Authored-By: Claude Sonnet 4.6 --- .github/ci-windows-cross.py | 159 ------------------ .github/ci-windows.py | 234 --------------------------- .github/workflows/ci.yml | 220 ------------------------- ci/test/00_setup_env_win64.sh | 21 --- ci/test/00_setup_env_win64_msvcrt.sh | 21 --- 5 files changed, 655 deletions(-) delete mode 100755 .github/ci-windows-cross.py delete mode 100755 .github/ci-windows.py delete mode 100755 ci/test/00_setup_env_win64.sh delete mode 100755 ci/test/00_setup_env_win64_msvcrt.sh diff --git a/.github/ci-windows-cross.py b/.github/ci-windows-cross.py deleted file mode 100755 index e4b715c304b4..000000000000 --- a/.github/ci-windows-cross.py +++ /dev/null @@ -1,159 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (c) The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or https://opensource.org/license/mit/. - -import argparse -import os -import shlex -import subprocess -import sys -from pathlib import Path - -sys.path.append(str(Path(__file__).resolve().parent.parent / "test")) -from download_utils import download_script_assets - - -def run(cmd, **kwargs): - print("+ " + shlex.join(cmd), flush=True) - kwargs.setdefault("check", True) - try: - return subprocess.run(cmd, **kwargs) - except Exception as e: - sys.exit(str(e)) - - -def print_version(): - bitcoind = Path.cwd() / "bin" / "bitcoind.exe" - run([str(bitcoind), "-version"]) - - -def check_manifests(): - release_dir = Path.cwd() / "bin" - manifest_path = release_dir / "bitcoind.manifest" - - cmd_bitcoind_manifest = [ - "mt.exe", - "-nologo", - f"-inputresource:{release_dir / 'bitcoind.exe'}", - f"-out:{manifest_path}", - ] - run(cmd_bitcoind_manifest) - print(manifest_path.read_text()) - - skipped = { # Skip as they currently do not have manifests - "fuzz.exe", - "bench_bitcoin.exe", - } - for entry in release_dir.iterdir(): - if entry.suffix.lower() != ".exe": - continue - if entry.name in skipped: - print(f"Skipping {entry.name} (no manifest present)") - continue - print(f"Checking {entry.name}") - run(["mt.exe", "-nologo", f"-inputresource:{entry}", "-validate_manifest"]) - - -def prepare_tests(): - workspace = Path.cwd() - config_path = workspace / "test" / "config.ini" - rpcauth_path = workspace / "share" / "rpcauth" / "rpcauth.py" - replacements = { - "SRCDIR=": f"SRCDIR={workspace}", - "BUILDDIR=": f"BUILDDIR={workspace}", - "RPCAUTH=": f"RPCAUTH={rpcauth_path}", - } - lines = config_path.read_text().splitlines() - for index, line in enumerate(lines): - for prefix, new_value in replacements.items(): - if line.startswith(prefix): - lines[index] = new_value - break - content = "\n".join(lines) + "\n" - config_path.write_text(content) - print(content) - previous_releases_dir = Path(os.environ["PREVIOUS_RELEASES_DIR"]) - cmd_download_prev_rel = [ - sys.executable, - str(workspace / "test" / "get_previous_releases.py"), - "--target-dir", - str(previous_releases_dir), - ] - run(cmd_download_prev_rel) - run([sys.executable, "-m", "pip", "install", "pyzmq"]) - - dest = workspace / "unit_test_data" - download_script_assets(dest) - - -def run_functional_tests(): - workspace = Path.cwd() - num_procs = str(os.process_cpu_count()) - test_runner_cmd = [ - sys.executable, - str(workspace / "test" / "functional" / "test_runner.py"), - "--jobs", - num_procs, - "--quiet", - f"--tmpdirprefix={workspace}", - "--combinedlogslen=99999999", - *shlex.split(os.environ.get("TEST_RUNNER_EXTRA", "").strip()), - # feature_unsupported_utxo_db.py fails on Windows because of emojis in the test data directory. - "--exclude", - "feature_unsupported_utxo_db.py", - ] - run(test_runner_cmd) - - # Run feature_unsupported_utxo_db sequentially in ASCII-only tmp dir, - # because it is excluded above due to lack of UTF-8 support in the - # ancient release. - cmd_feature_unsupported_db = [ - sys.executable, - str(workspace / "test" / "functional" / "feature_unsupported_utxo_db.py"), - "--previous-releases", - "--tmpdir", - str(Path(workspace) / "test_feature_unsupported_utxo_db"), - ] - run(cmd_feature_unsupported_db) - - -def run_unit_tests(): - workspace = Path.cwd() - os.environ["DIR_UNIT_TEST_DATA"] = str(workspace / "unit_test_data") - # Can't use ctest here like other jobs as we don't have a CMake build tree. - commands = [ - # Intentionally run sequentially here, to catch test case failures caused by dirty global state from prior test cases: - ["./bin/test_bitcoin.exe", "-l", "test_suite"], - ["./src/secp256k1/bin/exhaustive_tests.exe"], - ["./src/secp256k1/bin/noverify_tests.exe"], - ["./src/secp256k1/bin/tests.exe"], - ["./src/univalue/object.exe"], - ["./src/univalue/unitester.exe"], - ] - for cmd in commands: - run(cmd) - - -def main(): - parser = argparse.ArgumentParser(description="Utility to run Windows CI steps.") - steps = list(map(lambda f: f.__name__, [ - print_version, - check_manifests, - prepare_tests, - run_unit_tests, - run_functional_tests, - ])) - parser.add_argument("step", choices=steps, help="CI step to perform.") - args = parser.parse_args() - - os.environ.setdefault( - "PREVIOUS_RELEASES_DIR", - str(Path.cwd() / "previous_releases"), - ) - - exec(f'{args.step}()') - - -if __name__ == "__main__": - main() diff --git a/.github/ci-windows.py b/.github/ci-windows.py deleted file mode 100755 index d2ed22fbe234..000000000000 --- a/.github/ci-windows.py +++ /dev/null @@ -1,234 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (c) The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or https://opensource.org/license/mit/. - -import argparse -import os -import shlex -import subprocess -import sys -import time -from pathlib import Path - -sys.path.append(str(Path(__file__).resolve().parent.parent / "test")) -from download_utils import download_script_assets - - -def run(cmd, **kwargs): - print("+ " + shlex.join(cmd), flush=True) - kwargs.setdefault("check", True) - try: - return subprocess.run(cmd, **kwargs) - except Exception as e: - sys.exit(str(e)) - - -GENERATE_OPTIONS = { - "standard": [ - "-DBUILD_BENCH=ON", - "-DBUILD_KERNEL_LIB=ON", - "-DBUILD_UTIL_CHAINSTATE=ON", - "-DCMAKE_COMPILE_WARNING_AS_ERROR=ON", - ], - "fuzz": [ - "-DVCPKG_MANIFEST_NO_DEFAULT_FEATURES=ON", - "-DWITH_ZMQ=OFF", - "-DBUILD_FOR_FUZZING=ON", - "-DCMAKE_COMPILE_WARNING_AS_ERROR=ON", - ], -} - - -def github_import_vs_env(_ci_type): - vswhere_path = Path(os.environ["ProgramFiles(x86)"]) / "Microsoft Visual Studio" / "Installer" / "vswhere.exe" - installation_path = run( - [str(vswhere_path), "-latest", "-property", "installationPath"], - capture_output=True, - text=True, - ).stdout.strip() - vsdevcmd = Path(installation_path) / "Common7" / "Tools" / "vsdevcmd.bat" - comspec = os.environ["COMSPEC"] - output = run( - f'"{comspec}" /s /c ""{vsdevcmd}" -arch=x64 -no_logo && set"', - capture_output=True, - text=True, - ).stdout - github_env = os.environ["GITHUB_ENV"] - with open(github_env, "a") as env_file: - for line in output.splitlines(): - if "=" not in line: - continue - name, value = line.split("=", 1) - env_file.write(f"{name}={value}\n") - - -def generate(ci_type): - command = [ - "cmake", - "-B", - "build", - "-Werror=dev", - "--preset=vs2026", - # Using x64-windows-release for both host and target triplets - # to ensure vcpkg builds only release packages, thereby optimizing - # build time. - # See https://github.com/microsoft/vcpkg/issues/50927. - "-DVCPKG_HOST_TRIPLET=x64-windows-release", - "-DVCPKG_TARGET_TRIPLET=x64-windows-release", - ] + GENERATE_OPTIONS[ci_type] - if run(command, check=False).returncode != 0: - print("=== ⚠️ ===") - print("Generate failure! Network issue? Retry once ...") - time.sleep(12) - print("=== ⚠️ ===") - run(command) - - -def build(_ci_type): - command = [ - "cmake", - "--build", - "build", - "--config", - "Release", - ] - if run(command + ["-j", str(os.process_cpu_count())], check=False).returncode != 0: - print("Build failure. Verbose build follows.") - run(command + ["-j1", "--verbose"]) - - -def check_manifests(ci_type): - if ci_type != "standard": - print(f"Skipping manifest validation for '{ci_type}' ci type.") - return - - release_dir = Path.cwd() / "build" / "bin" / "Release" - manifest_path = release_dir / "bitcoind.manifest" - cmd_bitcoind_manifest = [ - "mt.exe", - "-nologo", - f"-inputresource:{release_dir / 'bitcoind.exe'}", - f"-out:{manifest_path}", - ] - run(cmd_bitcoind_manifest) - print(manifest_path.read_text()) - - skips = { # Skip as they currently do not have manifests - "fuzz.exe", - "bench_bitcoin.exe", - "bitcoin-chainstate.exe", - } - for entry in release_dir.iterdir(): - if entry.suffix.lower() != ".exe": - continue - if entry.name in skips: - print(f"Skipping {entry.name} (no manifest present)") - continue - print(f"Checking {entry.name}") - cmd_check_manifest = [ - "mt.exe", - "-nologo", - f"-inputresource:{entry}", - "-validate_manifest", - ] - run(cmd_check_manifest) - - -def prepare_tests(ci_type): - workspace = Path.cwd() - if ci_type == "standard": - run([sys.executable, "-m", "pip", "install", "pyzmq"]) - dest = workspace / "unit_test_data" - download_script_assets(dest) - elif ci_type == "fuzz": - repo_dir = str(workspace / "qa-assets") - clone_cmd = [ - "git", - "clone", - "--depth=1", - "https://github.com/bitcoin-core/qa-assets", - repo_dir, - ] - run(clone_cmd) - print("Using qa-assets repo from commit ...") - run(["git", "-C", repo_dir, "log", "-1"]) - - -def run_tests(ci_type): - workspace = Path.cwd() - build_dir = workspace / "build" - num_procs = str(os.process_cpu_count()) - release_bin = build_dir / "bin" / "Release" - - if ci_type == "standard": - os.environ["DIR_UNIT_TEST_DATA"] = str(workspace / "unit_test_data") - test_envs = { - "BITCOIN_BIN": "bitcoin.exe", - "BITCOIND": "bitcoind.exe", - "BITCOINCLI": "bitcoin-cli.exe", - "BITCOIN_BENCH": "bench_bitcoin.exe", - "BITCOINUTIL": "bitcoin-util.exe", - "BITCOINCHAINSTATE": "bitcoin-chainstate.exe", - } - for var, exe in test_envs.items(): - os.environ[var] = str(release_bin / exe) - - ctest_cmd = [ - "ctest", - "--test-dir", - str(build_dir), - "--output-on-failure", - "--stop-on-failure", - "-j", - num_procs, - "--build-config", - "Release", - ] - run(ctest_cmd) - - test_cmd = [ - sys.executable, - str(build_dir / "test" / "functional" / "test_runner.py"), - "--jobs", - num_procs, - "--quiet", - f"--tmpdirprefix={workspace}", - "--combinedlogslen=99999999", - *shlex.split(os.environ.get("TEST_RUNNER_EXTRA", "").strip()), - ] - run(test_cmd) - - elif ci_type == "fuzz": - os.environ["BITCOINFUZZ"] = str(release_bin / "fuzz.exe") - fuzz_cmd = [ - sys.executable, - str(build_dir / "test" / "fuzz" / "test_runner.py"), - "--par", - num_procs, - "--loglevel", - "DEBUG", - str(workspace / "qa-assets" / "fuzz_corpora"), - ] - run(fuzz_cmd) - - -def main(): - parser = argparse.ArgumentParser(description="Utility to run Windows CI steps.") - parser.add_argument("ci_type", choices=GENERATE_OPTIONS, help="CI type to run.") - steps = list(map(lambda f: f.__name__, [ - github_import_vs_env, - generate, - build, - check_manifests, - prepare_tests, - run_tests, - ])) - parser.add_argument("step", choices=steps, help="CI step to perform.") - args = parser.parse_args() - - exec(f'{args.step}("{args.ci_type}")') - - -if __name__ == "__main__": - main() diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9b256a52082e..734b9f38c762 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -213,226 +213,6 @@ jobs: # https://github.com/actions/cache/blob/main/tips-and-workarounds.md#update-a-cache key: ${{ steps.ccache-cache.outputs.cache-primary-key }} - windows-native-dll: - name: ${{ matrix.job-name }} - runs-on: windows-2025-vs2026 - - if: ${{ vars.SKIP_BRANCH_PUSH != 'true' || github.event_name == 'pull_request' }} - - env: - PYTHONUTF8: 1 - TEST_RUNNER_TIMEOUT_FACTOR: 40 - - strategy: - fail-fast: false - matrix: - job-type: [standard, fuzz] - include: - - job-type: standard - job-name: 'Windows native, VS' - - job-type: fuzz - job-name: 'Windows native, fuzz, VS' - - steps: - - *ANNOTATION_PR_NUMBER - - - *CHECKOUT - - - &IMPORT_VS_ENV - name: Import Visual Studio env vars - run: py -3 .github/ci-windows.py "standard" github_import_vs_env - - - name: Get tool information - run: | - set -o errexit -o pipefail -o xtrace -o nounset - - cmake -version | tee cmake_version - echo '---' - msbuild.exe -version | tee msbuild_version - echo "${VCToolsVersion-}" | tee toolset_version - py -3 --version - bash --version - - - name: Restore vcpkg downloads cache - id: vcpkg-downloads-cache - uses: actions/cache/restore@v5 - with: - path: | - ~/AppData/Local/vcpkg/downloads/* - !~/AppData/Local/vcpkg/downloads/tools - key: ${{ github.job }}-vcpkg-downloads-${{ hashFiles('vcpkg.json') }} - - - name: Restore vcpkg binary cache - uses: actions/cache/restore@v5 - id: vcpkg-binary-cache - with: - path: ~/AppData/Local/vcpkg/archives - key: ${{ github.job }}-vcpkg-binary-release-${{ hashFiles('cmake_version', 'msbuild_version', 'toolset_version', 'vcpkg.json') }} - - - name: Generate build system - run: | - py -3 .github/ci-windows.py ${{ matrix.job-type }} generate - - - name: Save vcpkg binary cache - uses: actions/cache/save@v5 - if: github.event_name != 'pull_request' && github.ref_name == github.event.repository.default_branch && steps.vcpkg-binary-cache.outputs.cache-hit != 'true' && matrix.job-type == 'standard' - with: - path: ~/AppData/Local/vcpkg/archives - key: ${{ steps.vcpkg-binary-cache.outputs.cache-primary-key }} - - - name: Save vcpkg downloads cache - uses: actions/cache/save@v5 - # Only save cache from the 'standard' job, as it includes the necessary downloads for other jobs in the matrix. If the matrix is modified, this may need amending. - if: github.event_name != 'pull_request' && github.ref_name == github.event.repository.default_branch && steps.vcpkg-binary-cache.outputs.cache-hit != 'true' && steps.vcpkg-downloads-cache.outputs.cache-hit != 'true' && matrix.job-type == 'standard' - with: - path: | - ~/AppData/Local/vcpkg/downloads/* - !~/AppData/Local/vcpkg/downloads/tools # Cache the tools once as archives, but not redundantly in extracted form. - key: ${{ steps.vcpkg-downloads-cache.outputs.cache-primary-key }} - - - name: Build - run: | - py -3 .github/ci-windows.py ${{ matrix.job-type }} build - - - name: Check executable manifests - run: | - py -3 .github/ci-windows.py ${{ matrix.job-type }} check_manifests - - - name: Prepare tests - run: | - py -3 .github/ci-windows.py ${{ matrix.job-type }} prepare_tests - - - name: Run tests - env: - TEST_RUNNER_EXTRA: "--timeout-factor=${{ env.TEST_RUNNER_TIMEOUT_FACTOR }} ${{ case(github.event_name == 'pull_request', '', '--extended') }}" - run: | - py -3 .github/ci-windows.py ${{ matrix.job-type }} run_tests - - record-frozen-commit: - # Record frozen commit, so that the native tests on cross-builds can run on - # the exact same commit id of the build. - name: '[meta] record frozen commit' - runs-on: ubuntu-slim - outputs: - commit: ${{ steps.record-commit.outputs.commit }} - steps: - - *ANNOTATION_PR_NUMBER - - *CHECKOUT - - name: Record commit - id: record-commit - run: echo "commit=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT" - - windows-cross: - name: 'Windows-cross to x86_64, ${{ matrix.crt }}' - needs: [runners, record-frozen-commit] - runs-on: ${{ needs.runners.outputs.provider == 'cirrus' && 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-sm' || 'ubuntu-24.04' }} - if: ${{ vars.SKIP_BRANCH_PUSH != 'true' || github.event_name == 'pull_request' }} - - strategy: - fail-fast: false - matrix: - crt: [msvcrt, ucrt] - include: - - crt: msvcrt - file-env: './ci/test/00_setup_env_win64_msvcrt.sh' - artifact-name: 'x86_64-w64-mingw32-executables' - - crt: ucrt - file-env: './ci/test/00_setup_env_win64.sh' - artifact-name: 'x86_64-w64-mingw32ucrt-executables' - - env: - FILE_ENV: ${{ matrix.file-env }} - DANGER_CI_ON_HOST_FOLDERS: 1 - - steps: - - *ANNOTATION_PR_NUMBER - - - name: Checkout - uses: actions/checkout@v6 - with: - ref: ${{ needs.record-frozen-commit.outputs.commit }} - - - name: Configure environment - uses: ./.github/actions/configure-environment - - - name: Restore caches - id: restore-cache - uses: ./.github/actions/restore-caches - - - name: Configure Docker - uses: ./.github/actions/configure-docker - with: - cache-provider: ${{ needs.runners.outputs.provider }} - - - name: CI script - run: ./ci/test_run_all.sh - - - name: Save caches - uses: ./.github/actions/save-caches - - - name: Upload built executables - uses: actions/upload-artifact@v7 - with: - name: ${{ matrix.artifact-name }}-${{ github.run_id }} - path: | - ${{ env.BASE_BUILD_DIR }}/bin/*.dll - ${{ env.BASE_BUILD_DIR }}/bin/*.exe - ${{ env.BASE_BUILD_DIR }}/src/secp256k1/bin/*.exe - ${{ env.BASE_BUILD_DIR }}/src/univalue/*.exe - ${{ env.BASE_BUILD_DIR }}/test/config.ini - - windows-native-test: - name: 'Windows, ${{ matrix.crt }}, test cross-built' - runs-on: windows-2022 - needs: [windows-cross, record-frozen-commit] - - strategy: - fail-fast: false - matrix: - crt: [msvcrt, ucrt] - include: - - crt: msvcrt - artifact-name: 'x86_64-w64-mingw32-executables' - - crt: ucrt - artifact-name: 'x86_64-w64-mingw32ucrt-executables' - - env: - PYTHONUTF8: 1 - TEST_RUNNER_TIMEOUT_FACTOR: 40 - - steps: - - *ANNOTATION_PR_NUMBER - - - name: Checkout - uses: actions/checkout@v6 - with: - ref: ${{ needs.record-frozen-commit.outputs.commit }} - - - name: Download built executables - uses: actions/download-artifact@v8 - with: - name: ${{ matrix.artifact-name }}-${{ github.run_id }} - - - name: Run bitcoind.exe - run: py -3 .github/ci-windows-cross.py print_version - - - *IMPORT_VS_ENV - - - name: Check executable manifests - run: py -3 .github/ci-windows-cross.py check_manifests - - - name: Prepare Windows test environment - run: py -3 .github/ci-windows-cross.py prepare_tests - - - name: Run unit tests - run: py -3 .github/ci-windows-cross.py run_unit_tests - - - name: Run functional tests - env: - TEST_RUNNER_EXTRA: "--timeout-factor=${{ env.TEST_RUNNER_TIMEOUT_FACTOR }} ${{ case(github.event_name == 'pull_request', '', '--extended') }}" - run: | - py -3 .github/ci-windows-cross.py run_functional_tests - ci-matrix: name: ${{ matrix.name }} needs: runners diff --git a/ci/test/00_setup_env_win64.sh b/ci/test/00_setup_env_win64.sh deleted file mode 100755 index b9f0991d60b6..000000000000 --- a/ci/test/00_setup_env_win64.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env bash -# -# Copyright (c) 2025-present The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. - -export LC_ALL=C.UTF-8 - -export CONTAINER_NAME=ci_win64 -export CI_IMAGE_NAME_TAG="mirror.gcr.io/debian:trixie" # Check that https://packages.debian.org/trixie/g++-mingw-w64-ucrt64 can cross-compile -export HOST=x86_64-w64-mingw32ucrt -export PACKAGES="g++-mingw-w64-ucrt64 nsis" -export RUN_UNIT_TESTS=false -export RUN_FUNCTIONAL_TESTS=false -export GOAL="deploy" -export BITCOIN_CONFIG="\ - --preset=dev-mode \ - -DWITH_USDT=OFF \ - -DREDUCE_EXPORTS=ON \ - -DCMAKE_CXX_FLAGS='-Wno-error=maybe-uninitialized' \ -" diff --git a/ci/test/00_setup_env_win64_msvcrt.sh b/ci/test/00_setup_env_win64_msvcrt.sh deleted file mode 100755 index 6dcb0d4194a8..000000000000 --- a/ci/test/00_setup_env_win64_msvcrt.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env bash -# -# Copyright (c) 2019-present The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. - -export LC_ALL=C.UTF-8 - -export CONTAINER_NAME=ci_win64_msvcrt -export CI_IMAGE_NAME_TAG="mirror.gcr.io/debian:trixie" # Check that https://packages.debian.org/trixie/g++-mingw-w64-x86-64-posix (version 14.x, similar to guix) can cross-compile -export HOST=x86_64-w64-mingw32 -export PACKAGES="g++-mingw-w64-x86-64-posix nsis" -export RUN_UNIT_TESTS=false -export RUN_FUNCTIONAL_TESTS=false -export GOAL="deploy" -export BITCOIN_CONFIG="\ - --preset=dev-mode \ - -DWITH_USDT=OFF \ - -DREDUCE_EXPORTS=ON \ - -DCMAKE_CXX_FLAGS='-Wno-error=maybe-uninitialized' \ -"