Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
439 changes: 0 additions & 439 deletions .cirrus.yml

This file was deleted.

204 changes: 204 additions & 0 deletions .github/workflows/builds.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
name: builds

on:
schedule:
- cron: '30 2 * * *' # 02:30 UTC daily
workflow_dispatch:
inputs:
target:
description: 'Which build(s) to run'
required: true
default: 'all'
type: choice
options: [all, windows, android, appimage, tarball]
android_arch:
description: 'Android architecture (when running android)'
required: false
default: 'arm64-v8a'
type: choice
options: [arm64-v8a, armeabi-v7a, x86_64]

permissions:
contents: read

concurrency:
group: builds-${{ github.ref }}
cancel-in-progress: false # never kill a nightly or in-progress build

env:
ARTIFACT_RETENTION: '14'

jobs:
windows:
name: "build: Windows"
if: ${{ github.event_name != 'workflow_dispatch' || inputs.target == 'all' || inputs.target == 'windows' }}
runs-on: ubuntu-24.04
timeout-minutes: 90
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0 # for git describe / version detection

- name: Cache Wine pip
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: contrib/build-wine/.cache/win*/wine_pip_cache
key: wine-pip-${{ hashFiles('contrib/deterministic-build/*.txt', 'contrib/build-wine/**') }}

- name: Cache Wine native lib builds (libsecp256k1, libusb, libzbar)
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: contrib/build-wine/.cache/win*/build
key: wine-build-${{ hashFiles('contrib/make_libsecp256k1.sh', 'contrib/make_libusb.sh', 'contrib/make_zbar.sh', 'contrib/build-wine/**') }}

- name: Build Windows binaries
run: ./contrib/build-wine/build.sh

- name: List output
run: ls -lah contrib/build-wine/dist/

- name: Upload Windows artifacts
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: electrum-windows-${{ github.sha }}
path: contrib/build-wine/dist/*
retention-days: ${{ env.ARTIFACT_RETENTION }}
if-no-files-found: error
compression-level: 0

android:
name: "build: Android (${{ inputs.android_arch || 'arm64-v8a' }})"
if: ${{ github.event_name != 'workflow_dispatch' || inputs.target == 'all' || inputs.target == 'android' }}
runs-on: ubuntu-24.04
timeout-minutes: 180
env:
APK_ARCH: ${{ inputs.android_arch || 'arm64-v8a' }}
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0

# GitHub guarantees 14 GB of free space, but we can delete some things for more space.
- name: Free disk space
run: |
df -h
sudo rm -rf \
/usr/share/dotnet \
/usr/share/swift \
/usr/local/lib/android \
/usr/local/.ghcup \
/usr/local/share/powershell \
/opt/ghc \
/opt/hostedtoolcache/CodeQL \
/opt/microsoft \
/opt/pipx
sudo docker image prune --all --force || true
df -h

- name: Cache python packages
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: packages
key: android-packages-${{ env.APK_ARCH }}-${{ hashFiles('contrib/deterministic-build/requirements.txt', 'contrib/make_packages.sh', 'contrib/android/**') }}

- name: Cache buildozer (p4a)
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: |
.buildozer_qml/android/platform/build-${{ env.APK_ARCH }}/packages
.buildozer_qml/android/platform/build-${{ env.APK_ARCH }}/build
# note: should *at least* depend on Dockerfile and p4a_recipes/, but contrib/android/ is simplest
key: android-buildozer-${{ env.APK_ARCH }}-${{ hashFiles('contrib/android/**') }}

- name: Build APK (debug)
run: ./contrib/android/build.sh qml "$APK_ARCH" debug

- name: List output
run: ls -lah dist/

- name: Upload Android APK
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: electrum-android-${{ env.APK_ARCH }}-${{ github.sha }}
path: dist/*
retention-days: ${{ env.ARTIFACT_RETENTION }}
if-no-files-found: error
compression-level: 0

appimage:
name: "build: AppImage"
if: ${{ github.event_name != 'workflow_dispatch' || inputs.target == 'all' || inputs.target == 'appimage' }}
runs-on: ubuntu-24.04
timeout-minutes: 90
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0

- name: Cache AppImage pip
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: contrib/build-linux/appimage/.cache/pip_cache
key: appimage-pip-${{ hashFiles('contrib/deterministic-build/*.txt', 'contrib/build-linux/appimage/**') }}

- name: Cache AppImage build
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: contrib/build-linux/appimage/.cache/appimage
key: appimage-build-${{ hashFiles('contrib/make_libsecp256k1.sh', 'contrib/make_zbar.sh', 'contrib/build-linux/appimage/**') }}

- name: Build AppImage
run: ./contrib/build-linux/appimage/build.sh

- name: List output
run: ls -lah dist/

- name: Upload AppImage
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: electrum-appimage-${{ github.sha }}
path: dist/*.AppImage
retention-days: ${{ env.ARTIFACT_RETENTION }}
if-no-files-found: error
compression-level: 0

tarball:
name: "build: tarball (${{ matrix.variant }})"
if: ${{ github.event_name != 'workflow_dispatch' || inputs.target == 'all' || inputs.target == 'tarball' }}
runs-on: ubuntu-24.04
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
include:
- variant: full
omit_unclean: '0'
artifact_name: electrum-tarball
- variant: source-only
omit_unclean: '1'
artifact_name: electrum-sourceonly-tarball
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0

- name: Build source tarball (${{ matrix.variant }})
env:
OMIT_UNCLEAN_FILES: ${{ matrix.omit_unclean }}
run: ./contrib/build-linux/sdist/build.sh

- name: List output
run: ls -lah dist/

- name: Upload tarball
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: ${{ matrix.artifact_name }}-${{ github.sha }}
path: dist/*.tar.gz
retention-days: ${{ env.ARTIFACT_RETENTION }}
if-no-files-found: error
compression-level: 0
44 changes: 44 additions & 0 deletions .github/workflows/locale.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: locale

on:
push:
branches: [master]
workflow_dispatch:

permissions:
contents: read

jobs:
push-locale:
name: "locale: upload to crowdin"
runs-on: ubuntu-24.04
steps:
- name: Checkout (with submodules)
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
submodules: true
fetch-depth: 0

- name: Setup Python
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: "3.10"
cache: 'pip'
cache-dependency-path: contrib/requirements/requirements-ci.txt

- name: Install OS deps
run: |
sudo apt-get update
sudo apt-get -y install gettext qt6-l10n-tools

- name: Install Python deps
run: |
pip install -r contrib/requirements/requirements-ci.txt
pip install requests

- name: Push locale to Crowdin
# CROWDIN_API_KEY needs to be set in GitHub repository settings
# - api key is for crowdin account: "SomberNight_CI_BOT"
env:
crowdin_api_key: ${{ secrets.CROWDIN_API_KEY }}
run: ./contrib/locale/push_locale.py
113 changes: 113 additions & 0 deletions .github/workflows/regtest.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
name: regtest

on:
push:
branches: [master]
tags: ['*']
pull_request:
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}

permissions:
contents: read

jobs:
regtest:
name: "Regtest functional tests"
runs-on: ubuntu-24.04
env:
LD_LIBRARY_PATH: contrib/_saved_secp256k1_build/
ELECTRUM_ECC_DONT_COMPILE: "1" # we build manually to make caching it easier
PIP_BREAK_SYSTEM_PACKAGES: "1"
# ElectrumX exits with an error without this:
ALLOW_ROOT: "1"
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: "3.10"
cache: 'pip'
cache-dependency-path: contrib/requirements/requirements.txt
- name: Determine latest bitcoind version
id: bitcoind-version
run: |
BITCOIND_VERSION=$(curl https://bitcoincore.org/en/download/ | grep -E -i --only-matching 'Latest version: [0-9\.]+' | grep -E --only-matching '[0-9\.]+')
if [ -z "$BITCOIND_VERSION" ]; then
echo "Failed to detect bitcoind version from bitcoincore.org" >&2
exit 1
fi
echo "Detected bitcoind version: $BITCOIND_VERSION"
echo "version=$BITCOIND_VERSION" >> "$GITHUB_OUTPUT"
- name: Cache bitcoind binary
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: /tmp/bitcoind
key: bitcoind-ubuntu-24.04-${{ steps.bitcoind-version.outputs.version }}
- name: Install OS deps
run: |
sudo apt-get update
sudo apt-get -y install curl jq bc automake libtool
- name: Install Electrum and ElectrumX
# installs e-x some commits after 1.18.0 tag
# uses --ignore-installed to ignore installed system installed attrs
run: |
python3 -m pip install --user --upgrade pip
python3 -m pip install --user .[tests] --ignore-installed
python3 -m pip install --user git+https://github.com/spesmilo/electrumx.git@0b260d4345242cc41e316e97d7de10ae472fd172
- name: Fetch bitcoind binary
env:
BITCOIND_VERSION: ${{ steps.bitcoind-version.outputs.version }}
run: |
mkdir -p /tmp/bitcoind
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
cd /tmp/bitcoind
tar -xaf $BITCOIND_PATH || (rm -f /tmp/bitcoind/* && curl --output $BITCOIND_PATH $BITCOIND_URL && tar -xaf $BITCOIND_PATH)
sudo cp -a bitcoin-$BITCOIND_VERSION/* /usr/
- name: Cache libsecp256k1 build
id: cache-libsecp
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: contrib/_saved_secp256k1_build
key: libsecp-${{ runner.os }}-${{ hashFiles('contrib/make_libsecp256k1.sh') }}
- name: Build libsecp256k1
if: steps.cache-libsecp.outputs.cache-hit != 'true'
run: |
./contrib/make_libsecp256k1.sh
mkdir -p contrib/_saved_secp256k1_build
cp electrum/libsecp256k1.so.* contrib/_saved_secp256k1_build/
- name: Start bitcoind (regtest)
run: nohup tests/regtest/run_bitcoind.sh > /tmp/bitcoind.log 2>&1 &
- name: Start electrumx
run: nohup tests/regtest/run_electrumx.sh > /tmp/electrumx.log 2>&1 &
- name: Run regtest tests
run: |
sleep 10
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}
# if any test fails, the test will get aborted (--failfast) and the wallet directories will be
# available for download in the Cirrus UI
- name: Upload test wallets (on failure)
if: failure()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: test-wallets
path: test_wallets.tar.gz
if-no-files-found: ignore
retention-days: 7
- name: Dump service logs (on failure)
if: failure()
run: |
echo "--- bitcoind log ---"
tail -200 /tmp/bitcoind.log || true
echo "--- electrumx log ---"
tail -200 /tmp/electrumx.log || true
Loading