ci: Move check_manifests step to ci-windows-cross.py
What changed, and why it matters
This change simply moves an existing Windows CI check from a GitHub Actions workflow file into a Python helper script. It does not change what the check does, only where the code lives and which folder temporarily holds one output file. There is no security issue here.
No security action required. This is a routine CI refactoring.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The commit refactors the Windows manifest validation step in Bitcoin Core’s CI. The PowerShell logic that invokes mt.exe to extract and validate executable manifests is relocated into .github/ci-windows-cross.py as a new check_manifests() step. Functionality is preserved: the same mt.exe commands are run against the same binaries, with the same skip set. The only behavioral difference is that bitcoind.manifest is now written to the bin/ directory instead of the current working directory. This is a CI-only change with no effect on shipped binaries or runtime behavior.
Changed components
.github/ci-windows-cross.py.github/workflows/ci.ymlInspect captured patch +32 / −17
diff --git a/.github/ci-windows-cross.py b/.github/ci-windows-cross.py
index 5382b5b6..4327d10c 100755
--- a/.github/ci-windows-cross.py
+++ b/.github/ci-windows-cross.py
@@ -24,16 +24,47 @@ def print_version():
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",
+ "test_kernel.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 main():
parser = argparse.ArgumentParser(description="Utility to run Windows CI steps.")
steps = [
"print_version",
+ "check_manifests",
]
parser.add_argument("step", choices=steps, help="CI step to perform.")
args = parser.parse_args()
if args.step == "print_version":
print_version()
+ elif args.step == "check_manifests":
+ check_manifests()
if __name__ == "__main__":
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index c6ac3472..9efdb3c3 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -412,23 +412,7 @@ jobs:
- *SET_UP_VS
- name: Check executable manifests
- shell: pwsh -Command "$PSVersionTable; $PSNativeCommandUseErrorActionPreference = $true; $ErrorActionPreference = 'Stop'; & '{0}'"
- run: |
- mt.exe -nologo -inputresource:bin\bitcoind.exe -out:bitcoind.manifest
- Get-Content bitcoind.manifest
-
- Get-ChildItem -Filter "bin\*.exe" | ForEach-Object {
- $exeName = $_.Name
-
- # Skip as they currently do not have manifests
- if ($exeName -eq "fuzz.exe" -or $exeName -eq "bench_bitcoin.exe" -or $exeName -eq "test_kernel.exe") {
- Write-Host "Skipping $exeName (no manifest present)"
- return
- }
-
- Write-Host "Checking $exeName"
- & mt.exe -nologo -inputresource:$_.FullName -validate_manifest
- }
+ run: py -3 .github/ci-windows-cross.py check_manifests
- name: Run unit tests
# Can't use ctest here like other jobs as we don't have a CMake build tree.
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.