ci: Call docker exec from Python script to fix word splitting #33732

pull maflcko wants to merge 6 commits into bitcoin:master from maflcko:2510-ci-rewrite-bash-python changing 4 files +47 −44
  1. maflcko commented at 12:13 pm on October 29, 2025: member

    The remaining ci/test/02_run_container.sh is fine, but has a bunch of shellcheck SC2086 word splitting violations.

    This is fine currently, because the only place that needed them had additional escaping, and all other commands happened to split fine on spaces.

    However, this may change in the future. So fix it now, by rewriting it in Python, which is recommended in the dev notes.

  2. DrahtBot added the label Tests on Oct 29, 2025
  3. DrahtBot commented at 12:13 pm on October 29, 2025: contributor

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

    Code Coverage & Benchmarks

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

    Reviews

    See the guideline for information on the review process.

    Type Reviewers
    ACK frankomosh, m3dwards

    If your review is incorrectly listed, please copy-paste <!–meta-tag:bot-skip–> into the comment that the bot should ignore.

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #33362 (Run feature_bind_port_(discover|externalip).py in CI by vasild)

    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.

  4. maflcko marked this as a draft on Oct 29, 2025
  5. maflcko force-pushed on Oct 29, 2025
  6. maflcko marked this as ready for review on Oct 29, 2025
  7. maflcko force-pushed on Oct 29, 2025
  8. in ci/test/02_run_container.py:185 in faceba8867
    189+        "--human-readable",
    190+        f"{os.environ['BASE_READ_ONLY_DIR']}/",
    191+        f"{os.environ['BASE_ROOT_DIR']}",
    192+    ]
    193+    if ci_exec(rsync_cmd, check=False).returncode != 0:
    194+        print(f"Nothing to copy from {os.environ['BASE_READ_ONLY_DIR']}")
    


    frankomosh commented at 10:05 am on November 3, 2025:
    nit: Should all non-zero exits be treated as “nothing to copy from”? am making the assumption that rsync could fail for other reasons

    maflcko commented at 10:22 am on November 3, 2025:

    This is just moving the code one-to-one, but possibly rsync, along with the rsync command passing, could be required here. (IIRC the error message may have been better worded to reflect the intention: rsync not found, no need to copy from ...)

    At least on macOS, it seems to pass: https://github.com/bitcoin/bitcoin/actions/runs/18913390006/job/53990076461?pr=33732#step:7:134

    0+ rsync --recursive --perms --stats --human-readable /Users/runner/work/bitcoin/bitcoin/ /Users/runner/work/bitcoin/bitcoin
    1Number of files: 3105
    2Number of files transferred: 0
    3...
    

    maflcko commented at 10:23 am on November 3, 2025:
    (added a commit to require rsync)
  9. frankomosh commented at 10:06 am on November 3, 2025: contributor
    Concept ACK
  10. maflcko force-pushed on Nov 3, 2025
  11. maflcko force-pushed on Nov 12, 2025
  12. maflcko force-pushed on Nov 17, 2025
  13. DrahtBot added the label CI failed on Nov 17, 2025
  14. DrahtBot removed the label CI failed on Nov 17, 2025
  15. maflcko marked this as a draft on Nov 18, 2025
  16. ci: Move folder creation and docker kill to Python script
    The container_id is already known in the Python script, as well as the
    folders to create, so just do it there.
    666675e95f
  17. ci: Document the retry script in PATH
    The `retry` script is required for CI_RETRY_EXE and there are two ways
    to put it into PATH:
    
    * When running in a container engine, by copying it into /usr/bin
    * When running without a container engine, by prepending its location to PATH
    fa37559ac5
  18. ci: Move macos snippet under DANGER_RUN_CI_ON_HOST
    This move-only refactor clarifies that macos assumes and requires
    DANGER_RUN_CI_ON_HOST.
    
    So move the snippet under the condition for self-documenting code.
    
    Can be reviewed with the git options:
    --color-moved=dimmed-zebra --color-moved-ws=ignore-all-space
    fa21fd1dc2
  19. ci: Untangle CI_EXEC bash function
    It contains a large `bash -c` string, which is hard to parse. So pull
    out components:
    
    * CI_EXEC is only called with absolute folders as args, so the `cd` is
      not needed in CI_EXEC. It is only needed to specify the working dir of
      running the tests in 03_test_script.sh, so move it there.
    
    * The PATH modification is only needed after commit
      4756114e505cff8848fb6344ef9a48d8822066c1 to check that depends does
      work properly, even when the PATH contains a space.
    
    * This allows to also drop the `bash -c` and use the proper and safer
      "$@" to forward args without the risk of word splitting.
    eeee02ea53
  20. ci: Require rsync to pass
    In theory one could run the CI without the rsync package installed, and
    with DANGER_RUN_CI_ON_HOST=1. However, this seems to be an edge case.
    Simply requiring rsync to be installed is less code and avoids brittle
    edge cases around rsync failures.
    fa83555d16
  21. Move ci_exec to the Python script
    The Bash script was acceptable, but CI_EXEC_CMD_PREFIX was a single
    string, relying on brittle word splitting that the shellcheck SC2086
    would warn about.
    
    So just fix that by moving everything to the Python script and deleting
    the Bash script.
    
    This also removes the need to export the CI_CONTAINER_ID env var.
    fa336053aa
  22. maflcko force-pushed on Nov 25, 2025
  23. maflcko marked this as ready for review on Nov 25, 2025
  24. maflcko requested review from frankomosh on Dec 9, 2025
  25. in ci/test/02_run_container.py:170 in fa336053aa
    174-        os.environ["IN_GETOPT_BIN"] = f"{prefix}/bin/getopt"
    175+    def ci_exec(cmd_inner, **kwargs):
    176+        if os.getenv("DANGER_RUN_CI_ON_HOST"):
    177+            prefix = []
    178+        else:
    179+            prefix = ["docker", "exec", container_id]
    


    frankomosh commented at 8:52 am on December 10, 2025:
    Shouldn’t we initialise container_id = None before the if/else? …. Or am I missing something?

    maflcko commented at 9:39 am on December 10, 2025:
    The container id is properly initialized by running the subprocess to launch the container engine, see the line container_id = run(... above.

    frankomosh commented at 10:56 am on December 10, 2025:
    Ah, right. I see what confused me. Looking again, I see the variable is created down the Docker branch. I was imagining a host mode run(DANGER_RUN_CI_ON_HOST=1) where the else block is skipped and container_id would still be referenced later, a case that would need an initial None, otherwise an error.
  26. in ci/test/02_run_container.py:175 in fa336053aa
    179+            prefix = ["docker", "exec", container_id]
    180+
    181+        return run([*prefix, *cmd_inner], **kwargs)
    182+
    183+    # Normalize all folders to BASE_ROOT_DIR
    184+    ci_exec([
    


    frankomosh commented at 9:13 am on December 10, 2025:
    Would this be better if wrapped in try/finally to guarantee cleanup? ..am trying to imagine if ci_exec() fails, and the container is never killed.

    maflcko commented at 9:39 am on December 10, 2025:
    Yes, that is intentionally kept in this refactor: It is useful to keep the container around when the tests fail, so that it is easier to attach to it, and debug.

    frankomosh commented at 10:52 am on December 10, 2025:
    Ok, understood. Makes sense, if its a design choice.
  27. frankomosh commented at 10:56 am on December 10, 2025: contributor
    Code Review ACK fa33605
  28. maflcko requested review from m3dwards on Dec 12, 2025
  29. maflcko requested review from willcl-ark on Dec 12, 2025
  30. m3dwards approved
  31. m3dwards commented at 5:02 pm on December 16, 2025: contributor

    ACK fa336053aada79d13cd771ce025857256814465e

    Tested on my own fork on GHA Tested locally on Debian both with DANGER_RUN_CI_ON_HOST set and unset Tested locally on MacOS

  32. maflcko requested review from fanquake on Dec 19, 2025
  33. fanquake merged this on Dec 19, 2025
  34. fanquake closed this on Dec 19, 2025

  35. maflcko deleted the branch on Dec 19, 2025

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: 2025-12-23 03:13 UTC

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