ci: update and verify SDKs, lock lint dependencies #35754

pull l0rinc wants to merge 3 commits into bitcoin:master from l0rinc:l0rinc/ci-verify-external-inputs changing 12 files +614 −24
  1. l0rinc commented at 3:30 AM on July 20, 2026: contributor

    Problem: The NetBSD cross-build job references a release candidate that is no longer available from its configured CDN. The macOS and BSD cross-build jobs extract downloaded SDK archives without verifying their contents. The lint image pins its direct Python dependencies, but resolves their transitive dependencies again whenever the image is rebuilt.

    Fix: Update the NetBSD SDK, verify downloaded SDK archives against committed hashes, and lock the lint Python dependencies.

    <details><summary>Verification</summary>

    set -o pipefail
    grep -F '9600fa93644df674ee916b5e2c8a6ba8dacf631996a65dc922d003b98b5ea3b1' contrib/macdeploy/README.md
    
    MACOS_SDK_URL=https://bitcoincore.org/depends-sources/sdks/Xcode-26.1.1-17B100-extracted-SDK-with-libcxx-headers.tar
    curl -fsSL "$MACOS_SDK_URL" | sha256sum | grep -F '9600fa93644df674ee916b5e2c8a6ba8dacf631996a65dc922d003b98b5ea3b1'
    
    FREEBSD_SDK_URL=https://download.freebsd.org/releases/amd64/15.1-RELEASE/base.txz
    curl -fsSL "$FREEBSD_SDK_URL" | sha256sum | grep -F '3768988b151c20f965679062b065c63a977d6bbb9f47fd83695ec2c40790c18f'
    
    NETBSD_SDK_URL=https://cdn.netbsd.org/pub/NetBSD/NetBSD-11.0/amd64/binary/sets
    curl -fsSL "$NETBSD_SDK_URL/base.tar.xz" | sha512sum | grep -F 'e8871bbedb8c3e0f696cc2596ced0c1e6497939f725fb3495b8d2c168430325907550f5f840f4dd0e3c73e6090394747c5e54762f2737de81177b984403522a8'
    curl -fsSL "$NETBSD_SDK_URL/comp.tar.xz" | sha512sum | grep -F 'd8df6c07e9142dd8189292b769ac312f86185a6a278a752c18c840f7cd3a8dd3c535f9b0c8e06b62d556b2c75b97a01d786184e8a18f5e080ccd213591c8628f'
    
    OPENBSD_SDK_URL=https://cdn.openbsd.org/pub/OpenBSD/7.9/amd64
    curl -fsSL "$OPENBSD_SDK_URL/base79.tgz" | sha256sum | grep -F '923d2e03f06408d50d4848334398c6d04b5514dcac7917badfc178a0eef248de'
    curl -fsSL "$OPENBSD_SDK_URL/comp79.tgz" | sha256sum | grep -F '21a67af20aebcabf85b09f4206fc95b4cae0a35d42b154b976f0159f457724f9'
    
    UV_PROJECT_ENVIRONMENT=/tmp/bitcoin-core-lint-verify uv sync --project ci/lint --locked --only-group lint
    

    </details>

  2. DrahtBot added the label Tests on Jul 20, 2026
  3. DrahtBot commented at 3:30 AM on July 20, 2026: contributor

    <!--e57a25ab6845829454e8d69fc972939a-->

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    <!--006a51241073e994b41acfe9ec718e94-->

    Code Coverage & Benchmarks

    For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/35754.

    <!--021abf342d371248e50ceaed478a90ca-->

    Reviews

    See the guideline and AI policy for information on the review process.

    Type Reviewers
    Concept NACK maflcko, willcl-ark

    If your review is incorrectly listed, please copy-paste <code>&lt;!--meta-tag:bot-skip--&gt;</code> into the comment that the bot should ignore.

    <!--174a7506f384e20aa4161008e828411d-->

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #35855 (guix: update time-machine by fanquake)
    • #35722 (ci: cache BSD sdk sources separately by willcl-ark)

    If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

    <!--5faf32d7da4f0f540f40219e4f7537a3-->

  4. in ci/lint/01_install.sh:35 in 8e8572e3dd
      30 | @@ -31,13 +31,22 @@ python3 --version
      31 |  
      32 |  uv pip install --python /python_env --requirements /ci/lint/requirements.txt
      33 |  
      34 | +case "$(uname --machine)" in
      35 | +  x86_64)  SHELLCHECK_SHA256="8c3be12b05d5c177a04c29e3c78ce89ac86f1595681cab149b65b97c4e227198" MLC_SHA256="7a72a93d5b3ee8a554cb840abdfe90aefb709418f225461b52021e3a058238a2" ;;
    


    maflcko commented at 5:19 AM on July 20, 2026:

    The pip deps aren't pinned, so I wonder why those two should be pinned?


    l0rinc commented at 5:59 AM on July 20, 2026:

    I'm not familiar with how to pin the pip requirements but I'll investigate.


    willcl-ark commented at 10:18 AM on July 20, 2026:

    I can provide a patch to pin the dependencies using uv.lock, which would be the recommended approach to take when using uv.


    willcl-ark commented at 10:58 AM on July 20, 2026:

    This commit shows how to use uv.lock to lock pip deps, feel free to cherry-pick here, or I can open seperately:

    https://github.com/willcl-ark/bitcoin/commit/9b86a2969118693a5511042ef524f424c7c0a0ee

    by using a pyproject "group", we can also make this ~ natively compatible with pip >= 25.1, as this knows how to install "groups" of dependencies outside of having a main application to install, as we are configured.

  5. in ci/test/01_base_install.sh:33 in feb5270399
      29 | @@ -30,6 +30,7 @@ if [ -n "${APT_LLVM_V}" ]; then
      30 |    ${CI_RETRY_EXE} apt-get update
      31 |    ${CI_RETRY_EXE} apt-get install curl -y
      32 |    curl "https://apt.llvm.org/llvm-snapshot.gpg.key" | tee "/etc/apt/trusted.gpg.d/apt.llvm.org.asc"
      33 | +  sha256sum -c <<<"8b2a587ffd672c4687e7581dad4b2f6c1bb2ad6b480cd9771ba2ff48e0b8c75d /etc/apt/trusted.gpg.d/apt.llvm.org.asc"
    


    maflcko commented at 5:20 AM on July 20, 2026:

    Is this meant to be const? The CI will break the next time a signature is added or the expiry is extended?


    l0rinc commented at 6:00 AM on July 20, 2026:

    You suggest dropping it? How often do these change? Shouldn't we know about it?


    maflcko commented at 6:18 AM on July 20, 2026:

    Well, what is the goal here? If someone controlled this key, they could push arbitrarily different llvm code to the ppa, even when the key is pinned to a hash.


    Sjors commented at 9:06 AM on July 20, 2026:

    We also don't know how that key is managed, so if llvm.org is compromised, we don't know if the key is still safe. And if we trust the domain, we should just trust whatever key it gives us.


    l0rinc commented at 5:19 PM on July 20, 2026:

    My goal was to know when any of these change so that we at least have the possibility to review and approve them. With LLMs we can even do a quick check to see if we agree and update the hash if we do (sure, that's also not 100% safe, but a lot safer than what we have now). What I don't like is when these things just suddenly change between runs like #35202

    And if we trust the domain, we should just trust whatever key it gives us

    Maybe, but I still think it should be a deliberate choice where we have the option to intervene. We should decide when the CI state should change, not outsiders.


    maflcko commented at 5:36 AM on July 21, 2026:

    What I don't like is when these things just suddenly change between runs like #35202

    The CI generally assumes that any container engine should work. Sure, it is annoying when a failure comes when the underlying engine changes, but I don't think this can be avoided: It is up to the host system (e.g. GHA) to provide the container engine and I don't think we can or want to pin it.

    If we really wanted to pin the dependencies in the CI, we'd probably have to use nix and compile clang from LLVM ourselves?


    l0rinc commented at 5:41 AM on July 21, 2026:

    we'd probably have to use nix and compile clang from LLVM ourselves?

    I accepted your reasoning here and removed the unpinnable dependency.

    But the rest provide explicit pinning capability, so I think we should harden them. As you can see it's quite cheap and can avoid some surprises.

  6. Sjors commented at 9:10 AM on July 20, 2026: member

    @l0rinc can you elaborate in the PR description what you're actually checking and trusting?

    I'm skeptical this is going to very useful if we simply set these hashes based on the current value and blindly update them every time CI breaks due to a mismatch. In the case of #35754 (review) the trust assumption seems to be circular. But there might be a subset of checks that are useful.

  7. in ci/test/01_base_install.sh:119 in 49553283a2
     115 | @@ -116,6 +116,7 @@ if [ -n "$XCODE_VERSION" ] && [ ! -d "${DEPENDS_DIR}/SDKs/${OSX_SDK_BASENAME}" ]
     116 |    if [ ! -f "$OSX_SDK_PATH" ]; then
     117 |      ${CI_RETRY_EXE} curl --location --fail "${SDK_URL}/${OSX_SDK_FILENAME}" -o "$OSX_SDK_PATH"
     118 |    fi
     119 | +  sha256sum -c <<<"9600fa93644df674ee916b5e2c8a6ba8dacf631996a65dc922d003b98b5ea3b1 ${OSX_SDK_PATH}"
    


    Sjors commented at 9:13 AM on July 20, 2026:

    49553283a25c5ddb7ae778ff44a567ce40d06275: this matches contrib/macdeploy/README.md so it makes sense to check and should be easy to keep in sync.

  8. in ci/test/01_base_install.sh:140 in 49553283a2
     136 | @@ -136,6 +137,7 @@ if [ -n "$FREEBSD_VERSION" ] && [ ! -d "${DEPENDS_DIR}/SDKs/${FREEBSD_SDK_BASENA
     137 |    if [ ! -f "$FREEBSD_SDK_PATH" ]; then
     138 |      ${CI_RETRY_EXE} curl --location --fail "https://download.freebsd.org/releases/amd64/${FREEBSD_VERSION}-RELEASE/base.txz" -o "$FREEBSD_SDK_PATH"
     139 |    fi
     140 | +  sha256sum -c <<<"3768988b151c20f965679062b065c63a977d6bbb9f47fd83695ec2c40790c18f ${FREEBSD_SDK_PATH}"
    


    Sjors commented at 9:15 AM on July 20, 2026:

    4955328: I would either:

    1. download the signed hashes file, pgp verify against a hardcoded key, and then check the file hash; or
    2. at least put this FREEBSD_SDK_HASH instead of in the middle of the CI file
  9. l0rinc renamed this:
    ci: verify downloaded CI dependencies
    ci: pin and verify external inputs
    on Jul 20, 2026
  10. l0rinc force-pushed on Jul 20, 2026
  11. l0rinc commented at 11:14 PM on July 20, 2026: contributor

    can you elaborate in the PR description what you're actually checking and trusting?

    Updated the description to distinguish the pinned inputs from the package repositories, LLVM PPA, and hosted runner images that CI still trusts.

    And if we trust the domain, we should just trust whatever key it gives us.

    Dropped the LLVM signing-key hash.

    at least put this FREEBSD_SDK_HASH instead of in the middle of the CI file

    Moved each SDK digest beside its version, extended verification to NetBSD and OpenBSD, and moved the OpenBSD symlink creation after both archives are extracted, when all link targets are present.

    The pip deps aren't pinned

    I can provide a patch to pin the dependencies using uv.lock, which would be the recommended approach to take when using uv.

    Cherry-picked Will's uv lock commit and added index digests to its existing uv and ruff image tags.

    <details><summary>Will's commit compared with the local version</summary>

    git range-diff 9b86a2969118693a5511042ef524f424c7c0a0ee^! 8ba28acb872a8c7e880924a03006ac69067e74a5^!
    

    </details>

    Also added hash-checked requirements for pycapnp, pyzmq, and pycapnp's transitive dependencies, then copied them into test images so PIP_PACKAGES can read them during image construction. Kept the IWYU commit hash beside its LLVM version so version bumps expose both values together. Added hashes for the remaining container images in one commit and pinned GitHub Actions to full commit SHAs in another, using YAML anchors for repeated references.

  12. DrahtBot added the label CI failed on Jul 21, 2026
  13. l0rinc force-pushed on Jul 21, 2026
  14. in ci/test/00_setup_env_freebsd_cross.sh:10 in 49cc4e8cab
       6 | @@ -7,11 +7,12 @@
       7 |  export LC_ALL=C.UTF-8
       8 |  
       9 |  export CONTAINER_NAME=ci_freebsd_cross
      10 | -export CI_IMAGE_NAME_TAG="mirror.gcr.io/ubuntu:26.04"
      11 | +export CI_IMAGE_NAME_TAG="mirror.gcr.io/ubuntu:26.04@sha256:3131b4cc82a783df6c9df078f86e01819a13594b865c2cad47bd1bca2b7063bb"
    


    maflcko commented at 5:39 AM on July 21, 2026:

    I don't see the point here. Sure, the container image is pinned, but this is Ubuntu, so the apt install will just pick the latest version anyway, in which case this pin here is just a verbose no-op.


    l0rinc commented at 5:44 AM on July 21, 2026:

    I remember having a surprise at another company when we found out Docker image tags weren't deterministic. The point of this PR is to minimize surprises - sure, we can follow up with pinning apt install if you want, but first let's make sure the OS is what we think it is.


    maflcko commented at 6:48 AM on July 21, 2026:

    Yes, it may be surprising if unknown, but I don't think this change is reducing the surprise. In fact, it may be increasing it, because the line seems to imply this is somehow pinned to a deterministic hash, but the outcome will still be non-deterministic.

    Also, I don't think it is possible to pin apt install, or at least, if we'd try, it would be easier to just use nix.

    Finally, apart from being a verbose no-op, and possibly increasing surprises, this is also tedious to maintain.

    I suspect this will attract a flood of dependabot-style PRs to bump the hash to "fix CVEs", so before this is done, we should have a crew of reviewers to sign up to review those. (I won't be signing up)

  15. in .github/actions/cache/restore/internal/action.yml:30 in 49cc4e8cab
      26 | @@ -27,7 +27,7 @@ runs:
      27 |      - name: Restore cache with WarpBuild
      28 |        id: warp
      29 |        if: ${{ inputs.provider == 'warp' }}
      30 | -      uses: WarpBuilds/cache/restore@v1
      31 | +      uses: WarpBuilds/cache/restore@6ab98e7fdd65255995acec1de229a0bf2a40fe37 # v1
    


    maflcko commented at 5:44 AM on July 21, 2026:

    Same here: Adding hashes seems mostly like a corporate check-list item. Since, the hash doesn't cover transitive actions, nor does it cover the warpbuild infra. If the cache provider was compromised, they could still ship wrong stuff via transitive actions or by corrupting the cache or the cache logic in their infra, even with a pinned hash here.

    No objection, just leaving a comment.


    l0rinc commented at 5:46 AM on July 21, 2026:

    The concern is that the input can change without our knowledge, even if the replacement is correct.

  16. DrahtBot removed the label CI failed on Jul 21, 2026
  17. maflcko commented at 6:48 AM on July 21, 2026: member

    It is good to have a large pull to cover all topics here and explain what is changed and what is not changed.

    It seems there are some good changes, like checking the hash after a raw curl. Sure, we try to set curl --fail to catch I/O errors, but those won't catch corrupt server hardware. So adding a hash to the various SDKs could make sense.

    However, for other stuff, it is unclear what the goal is, or rather the stated goal is not achieved and will also lead to other problems. (https://github.com/bitcoin/bitcoin/pull/35754#discussion_r3619714965).

  18. sedited commented at 11:54 AM on July 24, 2026: contributor

    It seems there are some good changes, like checking the hash after a raw curl. Sure, we try to set curl --fail to catch I/O errors, but those won't catch corrupt server hardware. So adding a hash to the various SDKs could make sense.

    Agree with maflcko here. Beyond that, I also like using uv as a package manager for python. For the rest, the images, the actions, the packages, etc., it seems to mostly be adding to the maintenance burden and I'm also not sure what exactly it is trying to achieve.

    Re this excerpt in your description:

    clone Git sources at reviewed commits

    What is this meant to imply? That we have reviewed the cloned tools in complete up to that point?

  19. l0rinc commented at 5:48 PM on July 24, 2026: contributor

    What is this meant to imply? That we have reviewed the cloned tools in complete up to that point?

    Just that we minimize the changes that can happen without our explicit knowledge/approval. That's basically the point of this PR. It's not necessarily about sanctioning changes or commits, though LLMs could theoretically review some of the changes since the last pinned version, which can help us decide if we want to bump them or not. It's not foolproof of course, just slightly safer against potential supply chain attacks.

  20. in ci/test/01_base_install.sh:91 in b4efe448a9
      87 | @@ -88,15 +88,15 @@ if [[ -n "${USE_INSTRUMENTED_LIBCPP}" ]]; then
      88 |  fi
      89 |  
      90 |  if [[ ${BARE_METAL_RISCV} == "true" ]]; then
      91 | -    ${CI_RETRY_EXE} git clone --depth=1 https://github.com/riscv-collab/riscv-gnu-toolchain -b 2026.06.06 /riscv/gcc
      92 | +    ${CI_RETRY_EXE} git clone --depth=1 --revision=81bb1f89664aad156df3d2773195177c92dedc3a https://github.com/riscv-collab/riscv-gnu-toolchain /riscv/gcc # 2026.06.06
    


    maflcko commented at 7:33 PM on July 30, 2026:

    Same here. Pinning doesn't achieve anything, because the real pulls will be unpinned (possibly from the master branch):

    /riscv/gcc# cat .gitmodules 
    [submodule "binutils"]
    	path = binutils
    	url = https://sourceware.org/git/binutils-gdb.git
    	branch = binutils-2_46-branch
    	shallow = true
    [submodule "gcc"]
    	path = gcc
    	url = https://github.com/gcc-mirror/gcc.git
    	branch = releases/gcc-16
    	shallow = true
    [submodule "glibc"]
    	path = glibc
    	url = https://sourceware.org/git/glibc.git
    	shallow = true
    [submodule "dejagnu"]
    	path = dejagnu
    	url = https://git.savannah.gnu.org/git/dejagnu.git
    	branch = master
    	shallow = false
    [submodule "newlib"]
    	path = newlib
    	url = https://sourceware.org/git/newlib-cygwin.git
    	branch = master
    	shallow = true
    [submodule "gdb"]
    	path = gdb
    	url = https://sourceware.org/git/binutils-gdb.git
    	branch = gdb-16-branch
    	shallow = true
    [submodule "qemu"]
    	path = qemu
    	url = https://gitlab.com/qemu-project/qemu.git
    	shallow = true
    [submodule "musl"]
    	path = musl
    	url = https://git.musl-libc.org/git/musl
    	branch = master
    	shallow = true
    [submodule "spike"]
    	path = spike
    	url = https://github.com/riscv-software-src/riscv-isa-sim.git
    	branch = master
    	shallow = true
    [submodule "pk"]
    	path = pk
    	url = https://github.com/riscv-software-src/riscv-pk.git
    	branch = master
    	shallow = true
    [submodule "llvm"]
    	path = llvm
    	url = https://github.com/llvm/llvm-project.git
    	branch = release/20.x
    	shallow = true
    [submodule "uclibc-ng"]
    	path = uclibc-ng
    	url = https://github.com/wbx-github/uclibc-ng.git
    	shallow = true
    

    l0rinc commented at 8:41 PM on July 30, 2026:

    Same as with other cases, it doesn't cover all possible scenarios - but once they start hardening their supply chain, we just have to update the pin here. Do you suggest completely removing this pin here, or opening an issue so they also pin?

  21. maflcko commented at 10:01 AM on July 31, 2026: member

    Tend towards NACK, because:

    • This claims to pin external inputs. However, in reality, they are not pinned, as explained above in different threads.
    • So this gives a false sense of being a benefit.
    • Also, this makes it harder to experiment with the CI, because any change will have to bump a version number and a hash, manually.
    • Also, this makes it harder to update the CI, for the same reason. (Recall there is no unified and automated ci update command to handle the heterogeneous cases here)
    • Also, this makes it harder to review CI changes, for the same reason. Reviewers will have to manually verify the mapping of version to hash.
    • Also, there is not recommendation when to update a hash, and how often. Are there going to be weekly dependabot-style changes?
    • All of this is purely theoretical and I don't recall there was ever a real issue this would be fixing/addressing/uncovering over the last decade?

    Maybe the manual steps can be automated by an LLM (and then devs and reviewers just trust the LLM to do the update and the verification of the mapping), but this seems just extra steps for no benefit, when most places are inherently impossible to pin.

    If we want to make the CI more deterministic, we'd have to replace apt with guix/nix (or so) from the ground up. I left an idea in https://github.com/bitcoin-core/libmultiprocess/pull/318#issuecomment-5108942086, but I don't know how easy that would be.

  22. l0rinc commented at 11:48 PM on August 2, 2026: contributor

    I don't understand the pushback here - why would we leave all of these external dependencies completely unchecked? We can continue pinning these more and more precisely through big-bang nix migration, but why would we object to easily pinning some parts of the external dependencies? Updating new hashes is trivial, so that's obviously not the real reason, and I don't see any suggestion for a subset of the pins to be added, so it sounds like a concept nack - which I have a hard time understanding. Why would we prefer an externally controlled CI environment - just because we cannot make it 100% safe, shouldn't we strive towards minimizing the supply chain attack vectors?

  23. maflcko commented at 6:17 AM on August 3, 2026: member

    Updating new hashes is trivial

    It is for the SDKs, because the version is exactly pinned and any version update can go hand-in-hand with a hash update. So commit 3751aa302879d6bcd6cd210bc487c65e54f22770 is perfectly fine, as explained in #35754 (comment). It will check for e.g. bit-flips on the host server. However, other tools such as git or podman already protect against bit-flips internally.

    Moreover, pinning the container images, when neither the container engine, nor the package manager inside the image is pinned, seems confusing at best? Also, attracting a weekly dependabot-style bump of the ci container images doesn't seem useful either.

  24. willcl-ark commented at 10:50 AM on August 3, 2026: member

    Leaving my two cents here too:

    I have also wondered about out CI in this way of this PR before (mainly from wondering if we should not have a nightly docker image build (external to this repo) which our runs in here pull and use).

    I sort of came to the conclusion that we "like" these images being somewhat floating/freely-updating, as it helps us catch "nightly" breakages seen in common os tools/compiler versions/other assorted packages, whilst we still pin things like SDK versions, python deps, and a few other things which "make sense" (vague I know).

    For the 100% pinned-reproducible case we have guix builds (I think we should add a guix CI job and am working on a guix-substitute server which I think can make this a reality).

    Therefore despite this being a well-intentioned PR, and the NACK-rationale feeling pretty iffy (I agree!) I'm not convinced full pinning is exactly what we are after in our CI.

    On my side, I think using uv.lock is ~ free and fine. If we were doing release builds or signing or using SECRET_KEYs while inside a container I'd be 110% behind pinning container image tags, and perhaps even doing something like apt-mark showmanual and exporting all the exact package versions into a packages.lock to be downloaded from a fixed debian/ubuntu snapshot etc. etc.

    For the same reason I don't have much opinion of github actions pinning; I think it's fine either way. The WarpBuilds/cache action doesn't look like it's rebased on actions/cache since about 2024, but they do add their own fixes every week or so. There seems little benefit beyond pinning to a major version to avoid breaking changes.

    As with many things, it might benefit us to have some kind of spec or developer note describing what we want/need pinned and why. based on my own current understanding, this might read something like:

    In CI we pin inputs where an unexpected change could invalidate the test or cross an important trust boundary: SDK archives, Python dependencies, and tools whose exact version is part of the test contract. We intentionally leave compatibility-oriented inputs such as base images, distribution packages, runner images, and the container engine floating so CI can detect breakage in commonly used environments. CI is therefore not intended to be fully hermetic; reproducible and independently verifiable builds belong in the Guix build.

    Each pin should have a clear purpose and be maintained together with the corresponding version, rather than being added merely for consistency.

    I understand there is still pushback to be had here: lint tools are part of the "linting test contract" for example and currently un-hash-checked...

  25. DrahtBot added the label Needs rebase on Aug 3, 2026
  26. maflcko commented at 2:01 PM on August 3, 2026: member

    On my side, I think using uv.lock is ~ free and fine.

    This pull is adding a locking mechanism for uv, and also a separate one for pip. What is the goal here? Add ones for Poetry, Pipenv, Hatch, etc as well? I am not sure, ideally zero are added, or at most one.

  27. l0rinc force-pushed on Aug 3, 2026
  28. l0rinc renamed this:
    ci: pin and verify external inputs
    ci: verify SDK archives and lock lint dependencies
    on Aug 3, 2026
  29. in ci/test/00_setup_env_netbsd_cross.sh:13 in d452df531d
      11 | @@ -12,6 +12,9 @@ export APT_LLVM_V="22"
      12 |  export HOST=x86_64-unknown-netbsd
      13 |  export NETBSD_VERSION=11.0_RC6
    


    maflcko commented at 6:53 PM on August 3, 2026:
    [#11](/bitcoin-bitcoin/11/) 17.01 + retry curl --location --fail https://cdn.netbsd.org/pub/NetBSD/NetBSD-11.0_RC6/amd64/binary/sets/base.tar.xz -o /home/runner/work/_temp/depends/sdk-sources/base.tar.xz
    [#11](/bitcoin-bitcoin/11/) 17.02   % Total    % Received % Xferd  Average Speed  Time    Time    Time   Current
    [#11](/bitcoin-bitcoin/11/) 17.02                                  Dload  Upload  Total   Spent   Left   Speed
    [#11](/bitcoin-bitcoin/11/) 17.02 
      0      0   0      0   0      0      0      0                              0
    [#11](/bitcoin-bitcoin/11/) 17.23 curl: (22) The requested URL returned error: 404
    

    Looks like this needs to be bumped?

    Maybe the first commit can be split up, along with such a sdk bump?


    l0rinc commented at 7:16 PM on August 3, 2026:

    Yes, on it


    l0rinc commented at 7:41 PM on August 3, 2026:

    Split the NetBSD SDK update into a separate first commit, bumped it to 11.0, and verified both archive URLs and hashes.


    maflcko commented at 5:51 AM on August 4, 2026:

    I moved the CI bugfixes to #35875, to unbreak the CI.

    I kept your exact commit IDs, so I hope it is fine.

    The uv stuff can then be reviewed by itself on its own pace.

  30. l0rinc commented at 7:13 PM on August 3, 2026: contributor

    I reduced the PR to the two changes where there seems to be some agreement.

    commit 3751aa3 is perfectly fine

    Kept the SDK archive verification commit.

    using uv.lock is ~ free and fine

    Kept Will’s uv.lock commit, removed the uv and ruff OCI digest pins, dropped the Git source pins, lint binary hashes, separate hashed test requirements, container image digests, and GitHub Action SHA pins.

  31. ci: update NetBSD cross-build SDK
    The NetBSD 11.0_RC6 archives are no longer available from cdn.netbsd.org. Update the cross-build SDK to the final 11.0 release.
    2c87337efe
  32. ci: verify cross-build SDK archives
    The macOS and BSD cross-build jobs extract SDK archives fetched at runtime without checking their content.
    Keep each expected digest beside the corresponding SDK version and verify every archive before extraction.
    Create the OpenBSD library symlinks once after both archives are extracted, when all link targets are present.
    873550bea3
  33. lint: lock Python dependencies with uv
    `uv.lock` hash-locks Python dependencies.
    
    Running `uv sync --project /ci/lint --locked --only-group lint` in the container will fail if `pyproject.toml` does not match `uv.lock`.
    
    `.python-version` sets the Python version canonically, and `uv sync --locked` will fail if it does not satisfy `requires-python` in `pyproject.toml`.
    84ac1aa0d0
  34. l0rinc force-pushed on Aug 3, 2026
  35. l0rinc renamed this:
    ci: verify SDK archives and lock lint dependencies
    ci: update and verify SDKs, lock lint dependencies
    on Aug 3, 2026
  36. DrahtBot added the label CI failed on Aug 3, 2026
  37. DrahtBot commented at 7:37 PM on August 3, 2026: contributor

    <!--85328a0da195eb286784d51f73fa0af9-->

    🚧 At least one of the CI tasks failed. <sub>Task riscv32 bare metal, static libbitcoin_consensus: https://github.com/bitcoin/bitcoin/actions/runs/30842458911/job/91782603927</sub> <sub>LLM reason (✨ experimental): CI failed because the build container couldn’t clone the binutils-gdb submodule from sourceware.org due to an HTTP 429 (rate limit).</sub>

    <details><summary>Hints</summary>

    Try to run the tests locally, according to the documentation. However, a CI failure may still happen due to a number of reasons, for example:

    • Possibly due to a silent merge conflict (the changes in this pull request being incompatible with the current code in the target branch). If so, make sure to rebase on the latest commit of the target branch.

    • A sanitizer issue, which can only be found by compiling with the sanitizer and running the affected test.

    • An intermittent issue.

    Leave a comment here, if you need help tracking down a confusing failure.

    </details>

  38. DrahtBot removed the label Needs rebase on Aug 3, 2026
  39. l0rinc closed this on Aug 3, 2026

  40. l0rinc reopened this on Aug 3, 2026

  41. l0rinc closed this on Aug 4, 2026

  42. maflcko commented at 10:32 AM on August 4, 2026: member

    Sorry, if the discussion was a bit heated here, but I think it was useful to have. Also commit 873550bea381030b1aac70034a23f3985583ff5c is merged, which is nice.

    I sort of came to the conclusion that we "like" these images being somewhat floating/freely-updating, as it helps us catch "nightly" breakages

    Just checking in here again. I think nightly/bleeding-edge stuff should mostly sit outside this repo. We already have enough CI failures in the non-nightly part, and having all possible bleeding-nightly CI failures would likely mark every pull red.

    So having major version pins, where it makes sense, is useful.

    spec or developer note describing

    Yeah, could make sense to add a short note to the ci/README.md about pins. Maybe something like:

    Container and GitHub Action pins are not done, because they:
          - delay normal and security updates until someone bumps the pin;
          - require recurring manual maintenance;
          - are not recursive, so they can create false confidence about reproducibility
    

    About the others:

    • Git source pins and pip pins: They could be pinned, but with the above rationale, the trade-off seems questionable?
    • lint binary hashes: (I don't care about those, anything is fine)
    • SDKs (they are now pinned)
    • uv.lock: (Unclear outcome of the discussion above? Maybe the can be pinned?)

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-08-11 09:51 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me