What changed, and why it matters
This commit simply removes the old Cirrus CI configuration file and a small related check in a build script because the project has finished moving its automated testing and build tasks to GitHub Actions. There is no change to Electrum's wallet, networking, or cryptographic code, and no security vulnerability is introduced or fixed.
No security action needed. Treat as routine CI maintenance.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The diff deletes .cirrus.yml (441 lines of CI job definitions for unit tests, linting, regtest, and binary builds) and removes a CIRRUS_CPU special-case from contrib/build_tools_util.sh so CPU_COUNT is always derived from nproc/sysctl. The commit is purely infrastructure cleanup after migrating CI to GitHub Actions.
Changed components
.cirrus.ymlcontrib/build_tools_util.shInspect captured patch +1 / −447
diff --git a/.cirrus.yml b/.cirrus.yml
deleted file mode 100644
index aef2e79..0000000
--- a/.cirrus.yml
+++ /dev/null
@@ -1,441 +0,0 @@
-# unittests using the 'latest' runtime python-dependencies
-task:
- container:
- image: $ELECTRUM_IMAGE
- cpu: 1
- memory: 2G
- matrix:
- - name: "unittests: py$ELECTRUM_PYTHON_VERSION"
- env:
- ELECTRUM_IMAGE: python:$ELECTRUM_PYTHON_VERSION
- matrix:
- - env:
- ELECTRUM_PYTHON_VERSION: 3.10
- - env:
- ELECTRUM_PYTHON_VERSION: 3.11
- - env:
- ELECTRUM_PYTHON_VERSION: 3.12
- - env:
- ELECTRUM_PYTHON_VERSION: 3.13
- - env:
- ELECTRUM_PYTHON_VERSION: 3.14
- - name: "unittests: py3.14, debug-mode"
- env:
- ELECTRUM_PYTHON_VERSION: 3.14
- # enable additional checks:
- PYTHONASYNCIODEBUG: "1"
- PYTHONDEVMODE: "1"
- pip_cache:
- folder: ~/.cache/pip
- fingerprint_script: echo $ELECTRUM_IMAGE && cat $ELECTRUM_REQUIREMENTS_CI && cat $ELECTRUM_REQUIREMENTS
- tag_script:
- - git tag
- libsecp_build_cache:
- folder: contrib/_saved_secp256k1_build
- fingerprint_script: sha256sum ./contrib/make_libsecp256k1.sh
- populate_script:
- - apt-get update
- - apt-get -y install automake libtool
- - ./contrib/make_libsecp256k1.sh
- - mkdir contrib/_saved_secp256k1_build
- - cp electrum/libsecp256k1.so.* contrib/_saved_secp256k1_build/
- install_script:
- - apt-get update
- # qml test reqs:
- - apt-get -y install libgl1 libegl1 libxkbcommon0 libdbus-1-3
- - pip install -r $ELECTRUM_REQUIREMENTS_CI
- # electrum itself:
- - export ELECTRUM_ECC_DONT_COMPILE=1
- - pip install ".[tests,qml_gui]"
- version_script:
- - python3 --version
- - pip freeze --all
- pytest_script:
- - >
- coverage run --source=electrum \
- "--omit=electrum/gui/*,electrum/plugins/*,electrum/scripts/*" \
- -m pytest tests -v
- - coverage report
- coveralls_script:
- - if [ ! -z "$COVERALLS_REPO_TOKEN" ] && [ "$ELECTRUM_PYTHON_VERSION" = "3.10" ] ; then coveralls ; fi
- env:
- LD_LIBRARY_PATH: contrib/_saved_secp256k1_build/
- ELECTRUM_REQUIREMENTS_CI: contrib/requirements/requirements-ci.txt
- ELECTRUM_REQUIREMENTS: contrib/requirements/requirements.txt
- # following CI_* env vars are set up for coveralls
- CI_NAME: "CirrusCI"
- CI_BUILD_NUMBER: $CIRRUS_BUILD_ID
- CI_JOB_ID: $CIRRUS_TASK_ID
- CI_BUILD_URL: "https://cirrus-ci.com/task/$CIRRUS_TASK_ID"
- CI_BRANCH: $CIRRUS_BRANCH
- CI_PULL_REQUEST: $CIRRUS_PR
- # in addition, COVERALLS_REPO_TOKEN is set as an "override" in https://cirrus-ci.com/settings/...
- depends_on:
- - "linter: Flake8 Mandatory"
-
-# unittests using the ~same frozen dependencies that are used in the released binaries
-# note: not using pinned pyqt here, due to "qml_gui" extra
-task:
- container:
- image: $ELECTRUM_IMAGE
- cpu: 1
- memory: 2G
- name: "unittests: py3.10, frozen-deps"
- pip_cache:
- folder: ~/.cache/pip
- fingerprint_script: echo $ELECTRUM_IMAGE && cat contrib/requirements/requirements*.txt && cat contrib/deterministic-build/requirements*.txt
- tag_script:
- - git tag
- libsecp_build_cache:
- folder: contrib/_saved_secp256k1_build
- fingerprint_script: sha256sum ./contrib/make_libsecp256k1.sh
- populate_script:
- - apt-get update
- - apt-get -y install automake libtool
- - ./contrib/make_libsecp256k1.sh
- - mkdir contrib/_saved_secp256k1_build
- - cp electrum/libsecp256k1.so.* contrib/_saved_secp256k1_build/
- install_script:
- - apt-get update
- # qml test reqs:
- - apt-get -y install libgl1 libegl1 libxkbcommon0 libdbus-1-3
- - pip install -r contrib/deterministic-build/requirements-build-base.txt
- - pip install -r contrib/requirements/requirements-ci.txt
- # electrum itself:
- - export ELECTRUM_ECC_DONT_COMPILE=1
- - pip install -r contrib/deterministic-build/requirements.txt -r contrib/deterministic-build/requirements-binaries.txt
- - pip install ".[tests,qml_gui]"
- version_script:
- - python3 --version
- - pip freeze --all
- pytest_script:
- - pytest tests -v
- env:
- ELECTRUM_IMAGE: python:3.10
- LD_LIBRARY_PATH: contrib/_saved_secp256k1_build/
- depends_on:
- - "linter: Flake8 Mandatory"
-
-task:
- name: "locale: upload to crowdin"
- container:
- image: $ELECTRUM_IMAGE
- cpu: 1
- memory: 1G
- pip_cache:
- folder: ~/.cache/pip
- fingerprint_script: echo Locale && echo $ELECTRUM_IMAGE && cat $ELECTRUM_REQUIREMENTS_CI
- install_script:
- - apt-get update
- - apt-get -y install gettext qt6-l10n-tools
- - pip install -r $ELECTRUM_REQUIREMENTS_CI
- - pip install requests
- submodules_script:
- - git submodule update --init
- locale_script:
- - contrib/locale/push_locale.py
- env:
- ELECTRUM_IMAGE: python:3.10
- ELECTRUM_REQUIREMENTS_CI: contrib/requirements/requirements-ci.txt
- # in addition, crowdin_api_key is set as an "override" in https://cirrus-ci.com/settings/...
- # - api key is for crowdin account: "SomberNight_CI_BOT"
- # - see https://crowdin.com/settings#api-key
- depends_on:
- - "unittests: py3.10"
- only_if: $CIRRUS_BRANCH == 'master'
-
-task:
- name: "Regtest functional tests"
- compute_engine_instance:
- image_project: cirrus-images
- image: family/docker-builder
- platform: linux
- cpu: 1
- memory: 1G
- pip_cache:
- folder: ~/.cache/pip
- fingerprint_script: echo Regtest && echo docker_builder && cat $ELECTRUM_REQUIREMENTS
- bitcoind_cache:
- folder: /tmp/bitcoind
- populate_script: mkdir -p /tmp/bitcoind
- install_script:
- - apt-get update
- - apt-get -y install curl jq bc
- - python3 -m pip install --user --upgrade pip
- # install electrum
- - export ELECTRUM_ECC_DONT_COMPILE=1 # we build manually to make caching it easier
- - python3 -m pip install .[tests] --ignore-installed # ignore installed system installed attrs
- # install e-x some commits after 1.18.0 tag
- - python3 -m pip install git+https://github.com/spesmilo/electrumx.git@0b260d4345242cc41e316e97d7de10ae472fd172
- - "BITCOIND_VERSION=$(curl https://bitcoincore.org/en/download/ | grep -E -i --only-matching 'Latest version: [0-9\\.]+' | grep -E --only-matching '[0-9\\.]+')"
- - BITCOIND_FILENAME=bitcoin-$BITCOIND_VERSION-x86_64-linux-gnu.tar.gz
- - BITCOIND_PATH=/tmp/bitcoind/$BITCOIND_FILENAME
- - BITCOIND_URL=https://bitcoincore.org/bin/bitcoin-core-$BITCOIND_VERSION/$BITCOIND_FILENAME
- - tar -xaf $BITCOIND_PATH || (rm -f /tmp/bitcoind/* && curl --output $BITCOIND_PATH $BITCOIND_URL && tar -xaf $BITCOIND_PATH)
- - cp -a bitcoin-$BITCOIND_VERSION/* /usr/
- libsecp_build_cache:
- folder: contrib/_saved_secp256k1_build
- fingerprint_script: sha256sum ./contrib/make_libsecp256k1.sh
- populate_script:
- - apt-get -y install automake libtool
- - ./contrib/make_libsecp256k1.sh
- - mkdir contrib/_saved_secp256k1_build
- - cp electrum/libsecp256k1.so.* contrib/_saved_secp256k1_build/
- bitcoind_service_background_script:
- - tests/regtest/run_bitcoind.sh
- electrumx_service_background_script:
- - tests/regtest/run_electrumx.sh
- # if any test fails, the test will get aborted (--failfast) and the wallet directories will be
- # available for download in the Cirrus UI
- regtest_script:
- - sleep 10s
- - python3 -m unittest tests/regtest.py --failfast || TEST_EXIT_CODE=$?
- - tar -czf test_wallets.tar.gz /tmp/alice /tmp/bob /tmp/carol || true
- - exit ${TEST_EXIT_CODE:-0}
- on_failure:
- wallet_artifacts:
- path: "test_wallets.tar.gz"
- env:
- LD_LIBRARY_PATH: contrib/_saved_secp256k1_build/
- ELECTRUM_REQUIREMENTS: contrib/requirements/requirements.txt
- PIP_BREAK_SYSTEM_PACKAGES: 1
- # ElectrumX exits with an error without this:
- ALLOW_ROOT: 1
- depends_on:
- - "linter: Flake8 Mandatory"
-
-task:
- container:
- image: $ELECTRUM_IMAGE
- cpu: 1
- memory: 1G
- pip_cache:
- folder: ~/.cache/pip
- fingerprint_script: echo Flake8 && echo $ELECTRUM_IMAGE && cat $ELECTRUM_REQUIREMENTS
- install_script:
- - pip install "flake8==7.3.0" "flake8-bugbear==25.10.21"
- flake8_script:
- - flake8 . --count --select="$ELECTRUM_LINTERS" --ignore="$ELECTRUM_LINTERS_IGNORE" --show-source --statistics --exclude "*_pb2.py,electrum/_vendor/"
- env:
- ELECTRUM_IMAGE: python:3.10
- ELECTRUM_REQUIREMENTS: contrib/requirements/requirements.txt
- matrix:
- - name: "linter: Flake8 Mandatory"
- env:
- # list of error codes:
- # - https://flake8.pycqa.org/en/latest/user/error-codes.html
- # - https://pycodestyle.pycqa.org/en/latest/intro.html#error-codes
- # - https://github.com/PyCQA/flake8-bugbear/tree/8c0e7eb04217494d48d0ab093bf5b31db0921989#list-of-warnings
- ELECTRUM_LINTERS: E9,E101,E129,E273,E274,E703,E71,E722,F5,F6,F7,F8,W191,W29,B,B909
- ELECTRUM_LINTERS_IGNORE: B007,B009,B010,B036,B042,F541,F841
- - name: "linter: Flake8 Non-Mandatory"
- env:
- ELECTRUM_LINTERS: E,F,W,C90,B
- ELECTRUM_LINTERS_IGNORE: ""
- allow_failures: true
-
-task:
- name: "linter: ban unicode"
- container:
- image: python:3.10
- cpu: 1
- memory: 1G
- main_script:
- - contrib/ban_unicode.py
-
-task:
- name: "security review: Claude Code"
- # NOTE: claude has access to all API keys available in the Cirrus CI environment.
- # If we would add some critical api keys in here we should consider this.
- matrix:
- - trigger_type: automatic
- only_if: $CIRRUS_PR != '' && ($CIRRUS_USER_PERMISSION == 'write' || $CIRRUS_USER_PERMISSION == 'admin')
- - trigger_type: manual
- only_if: $CIRRUS_PR != '' && !($CIRRUS_USER_PERMISSION == 'write' || $CIRRUS_USER_PERMISSION == 'admin')
- container:
- image: node:20
- cpu: 1
- memory: 2G
- # CLAUDE_CODE_OAUTH_TOKEN is set as an encrypted "override" in https://cirrus-ci.com/settings/...
- # It must be stored encrypted (ENCRYPTED[...]) so Cirrus CI refuses to decrypt it for
- # fork PRs from users without write permission.
- # Generate with: claude setup-token
- # Optional: set GITHUB_TOKEN to enable PR comments on failure
- install_script:
- - npm install -g @anthropic-ai/claude-code
- review_script:
- # the script is executed as 'node' user as claude refuses to run with root permissions
- - chown -R node:node .
- - su node -c "python3 contrib/ci/claude_security_review.py"
-
-# Cron jobs configured in https://cirrus-ci.com/settings/...
-# - job "nightly" on branch "master" at "0 30 2 * * ?" (every day at 02:30Z)
-task:
- name: "build: Windows"
- matrix:
- - trigger_type: manual
- only_if: $CIRRUS_CRON == ""
- - trigger_type: automatic
- only_if: $CIRRUS_CRON == "nightly"
- container:
- dockerfile: contrib/build-wine/Dockerfile
- cpu: 1
- memory: 3G
- pip_cache:
- folders:
- - contrib/build-wine/.cache/win*/wine_pip_cache
- fingerprint_script:
- - echo $CIRRUS_TASK_NAME
- - git ls-files -s contrib/deterministic-build/*.txt
- - git ls-files -s contrib/build-wine/
- build2_cache:
- folders:
- - contrib/build-wine/.cache/win*/build
- fingerprint_script:
- - echo $CIRRUS_TASK_NAME
- - cat contrib/make_libsecp256k1.sh | sha256sum
- - cat contrib/make_libusb.sh | sha256sum
- - cat contrib/make_zbar.sh | sha256sum
- - git ls-files -s contrib/build-wine/
- build_script:
- - cd contrib/build-wine
- - ./make_win.sh
- binaries_artifacts:
- path: "contrib/build-wine/dist/*"
- env:
- CIRRUS_WORKING_DIR: /opt/wine64/drive_c/electrum
- CIRRUS_DOCKER_CONTEXT: contrib/build-wine
- depends_on:
- - "unittests: py3.10"
-
-task:
- name: "build: Android (QML $APK_ARCH)"
- matrix:
- - trigger_type: manual
- only_if: $CIRRUS_CRON == ""
- - trigger_type: automatic
- only_if: $CIRRUS_CRON == "nightly"
- timeout_in: 90m
- container:
- dockerfile: contrib/android/Dockerfile
- cpu: 8
- memory: 24G
- env:
- APK_ARCH: arm64-v8a
- packages_tld_folder_cache:
- folder: packages
- fingerprint_script:
- - echo $CIRRUS_TASK_NAME && cat contrib/deterministic-build/requirements.txt && cat contrib/make_packages.sh
- - git ls-files -s contrib/android/
- p4a_cache:
- folders:
- - ".buildozer/android/platform/build-$APK_ARCH/packages"
- - ".buildozer/android/platform/build-$APK_ARCH/build"
- fingerprint_script:
- # note: should *at least* depend on Dockerfile and p4a_recipes/, but contrib/android/ is simplest
- - git ls-files -s contrib/android/
- - echo "qml $APK_ARCH"
- build_script:
- - ./contrib/android/make_apk.sh qml "$APK_ARCH" debug
- binaries_artifacts:
- path: "dist/*"
- depends_on:
- - "unittests: py3.10"
-
-## mac build disabled, as Cirrus CI no longer supports Intel-based mac builds
-#task:
-# name: "build: macOS"
-# macos_instance:
-# image: catalina-xcode-11.3.1
-# env:
-# TARGET_OS: macOS
-# pip_cache:
-# folder: ~/Library/Caches/pip
-# fingerprint_script:
-# - echo $CIRRUS_TASK_NAME
-# - git ls-files -s contrib/deterministic-build/*.txt
-# - git ls-files -s contrib/osx/
-# build2_cache:
-# folder: contrib/osx/.cache
-# fingerprint_script:
-# - echo $CIRRUS_TASK_NAME
-# - cat contrib/make_libsecp256k1.sh | shasum -a 256
-# - cat contrib/make_libusb.sh | shasum -a 256
-# - cat contrib/make_zbar.sh | shasum -a 256
-# - git ls-files -s contrib/osx/
-# install_script:
-# - git fetch --all --tags
-# build_script:
-# - ./contrib/osx/make_osx.sh
-# sum_script:
-# - ls -lah dist
-# - shasum -a 256 dist/*.dmg
-# binaries_artifacts:
-# path: "dist/*"
-
-task:
- name: "build: AppImage"
- matrix:
- - trigger_type: manual
- only_if: $CIRRUS_CRON == ""
- - trigger_type: automatic
- only_if: $CIRRUS_CRON == "nightly"
- compute_engine_instance:
- image_project: cirrus-images
- image: family/docker-builder
- platform: linux
- cpu: 2
- memory: 2G
- pip_cache:
- folder: contrib/build-linux/appimage/.cache/pip_cache
- fingerprint_script:
- - echo $CIRRUS_TASK_NAME
- - git ls-files -s contrib/deterministic-build/*.txt
- - git ls-files -s contrib/build-linux/appimage/
- build2_cache:
- folder: contrib/build-linux/appimage/.cache/appimage
- fingerprint_script:
- - echo $CIRRUS_TASK_NAME
- - cat contrib/make_libsecp256k1.sh | sha256sum
- - git ls-files -s contrib/build-linux/appimage/
- build_script:
- - ./contrib/build-linux/appimage/build.sh
- binaries_artifacts:
- path: "dist/*"
- depends_on:
- - "unittests: py3.10"
-
-task:
- container:
- dockerfile: contrib/build-linux/sdist/Dockerfile
- cpu: 1
- memory: 1G
- pip_cache:
- folder: ~/.cache/pip
- fingerprint_script:
- - echo $CIRRUS_TASK_NAME
- - git ls-files -s contrib/deterministic-build/*.txt
- - git ls-files -s contrib/build-linux/sdist/
- build_script:
- - ./contrib/build-linux/sdist/make_sdist.sh
- binaries_artifacts:
- path: "dist/*"
- matrix:
- - name: "build: tarball"
- - name: "build: source-only tarball"
- env:
- OMIT_UNCLEAN_FILES: 1
- depends_on:
- - "unittests: py3.10"
-
-task:
- name: "check submodules"
- container:
- image: python:3.10
- cpu: 1
- memory: 1G
- fetch_script:
- - git fetch --all --tags
- check_script:
- - ./contrib/deterministic-build/check_submodules.sh
- only_if: $CIRRUS_TAG != ''
diff --git a/contrib/build_tools_util.sh b/contrib/build_tools_util.sh
index 2dd9b8b..1e8d9c2 100755
--- a/contrib/build_tools_util.sh
+++ b/contrib/build_tools_util.sh
@@ -172,12 +172,7 @@ fi
export GCC_STRIP_BINARIES="${GCC_STRIP_BINARIES:-0}"
-if [ -n "$CIRRUS_CPU" ] ; then
- # special-case for CI. see https://github.com/cirruslabs/cirrus-ci-docs/issues/1115
- export CPU_COUNT="$CIRRUS_CPU"
-else
- export CPU_COUNT="$(nproc 2> /dev/null || sysctl -n hw.ncpu)"
-fi
+export CPU_COUNT="$(nproc 2> /dev/null || sysctl -n hw.ncpu)"
info "Found $CPU_COUNT CPUs, which we might use for building."
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.