From 2c2efd83fde9557cc78bfcafc7e9f8d49ae10eca Mon Sep 17 00:00:00 2001 From: Krystie Date: Fri, 3 Jul 2026 17:25:16 -0700 Subject: [PATCH] ci: harden Tor expert bundle downloads against CI egress timeouts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The macOS build of e2cd0b6 (the NeedsBootstrap rocksdb/ fix) failed at the 'Bundle Tor into app' step with bash exit code 6 after exactly 30s of curl hanging against archive.torproject.org. All 4 Tor download sites (Windows Qt, Windows daemon, Linux Qt .deb, Linux daemon .deb, macOS Qt) used 'curl -sL' with no timeouts and no retries — a single transient network drop from Azure westus to the Tor archive killed the job. Fix at all 4 sites: * curl -fSL (HTTP error -> non-zero exit; fail loudly) * --connect-timeout 15 / --max-time 120 (per-attempt bounds) * --retry 3 --retry-delay 5 --retry-connrefused --retry-all-errors (covers 5xx, DNS timeouts, and connection refused) * 'set -euo pipefail' at script top so any failure aborts cleanly * PowerShell variants get a manual retry loop with size check (1MB minimum — a 0-byte '200 OK' response from a broken mirror used to silently slip through) Also bump CLIENT_VERSION_REVISION 1 -> 4 (v6.1.4) for the upcoming release that will include e2cd0b6 (NeedsBootstrap rocksdb/ fix). Release notes: v6.1.4: Tor bundle download resilience (4 CI sites hardened) + e2cd0b6 (NeedsBootstrap rocksdb/ chain state detection). Supersedes v6.1.3 only on CI reliability; no protocol/wallet/chain format changes. --- .github/workflows/build-all.yml | 68 ++++++++++++++++++++++++++++-- scripts/ci/package-linux-daemon.sh | 9 +++- src/clientversion.h | 8 ++-- 3 files changed, 76 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build-all.yml b/.github/workflows/build-all.yml index 9187dbc..925ed21 100644 --- a/.github/workflows/build-all.yml +++ b/.github/workflows/build-all.yml @@ -286,11 +286,33 @@ jobs: path: Cryptographic-Triangles-*-win-x64.zip - name: Download Tor + # Resilient download: archive.torproject.org occasionally times out + # from CI egress (observed 2026-07-03: macOS job exit code 6 after + # exactly 30s of curl hang). Retries cover transient connection + # drops; -SkipHttpErrorCheck surfaces HTTP error bodies so the next + # failure isn't silent. shell: powershell run: | $TOR_VERSION = "15.0.9" $TOR_URL = "https://archive.torproject.org/tor-package-archive/torbrowser/${TOR_VERSION}/tor-expert-bundle-windows-x86_64-${TOR_VERSION}.tar.gz" - Invoke-WebRequest -Uri $TOR_URL -OutFile tor-bundle.tar.gz + $torPath = "tor-bundle.tar.gz" + $attempts = 0 + $maxAttempts = 3 + while ($attempts -lt $maxAttempts) { + $attempts++ + try { + Invoke-WebRequest -Uri $TOR_URL -OutFile $torPath -UseBasicParsing ` + -ConnectionTimeout 15 -OperationTimeout 120 + $size = (Get-Item $torPath).Length + if ($size -gt 1MB) { break } + Write-Host "Download too small ($size bytes), retrying..." + Remove-Item $torPath -ErrorAction SilentlyContinue + } catch { + Write-Host "Download attempt $attempts failed: $_" + if ($attempts -ge $maxAttempts) { throw } + Start-Sleep -Seconds 5 + } + } New-Item -ItemType Directory -Path tor-extract -Force tar -xzf tor-bundle.tar.gz -C tor-extract New-Item -ItemType Directory -Path tor-files -Force @@ -386,10 +408,31 @@ jobs: run: bash scripts/ci/package-windows-daemon.sh daemon-dist trianglesd triangles-cli - name: Bundle Tor for daemon + # Resilient download: archive.torproject.org occasionally times out + # from CI egress (observed 2026-07-03: macOS job exit code 6 after + # exactly 30s of curl hang). Retries cover transient connection drops. shell: powershell run: | $TOR_VERSION = "15.0.9" - Invoke-WebRequest -Uri "https://archive.torproject.org/tor-package-archive/torbrowser/${TOR_VERSION}/tor-expert-bundle-windows-x86_64-${TOR_VERSION}.tar.gz" -OutFile tor-bundle.tar.gz + $TOR_URL = "https://archive.torproject.org/tor-package-archive/torbrowser/${TOR_VERSION}/tor-expert-bundle-windows-x86_64-${TOR_VERSION}.tar.gz" + $torPath = "tor-bundle.tar.gz" + $attempts = 0 + $maxAttempts = 3 + while ($attempts -lt $maxAttempts) { + $attempts++ + try { + Invoke-WebRequest -Uri $TOR_URL -OutFile $torPath -UseBasicParsing ` + -ConnectionTimeout 15 -OperationTimeout 120 + $size = (Get-Item $torPath).Length + if ($size -gt 1MB) { break } + Write-Host "Download too small ($size bytes), retrying..." + Remove-Item $torPath -ErrorAction SilentlyContinue + } catch { + Write-Host "Download attempt $attempts failed: $_" + if ($attempts -ge $maxAttempts) { throw } + Start-Sleep -Seconds 5 + } + } New-Item -ItemType Directory -Path tor-extract -Force tar -xzf tor-bundle.tar.gz -C tor-extract Copy-Item -Recurse tor-extract/tor/* daemon-dist/tor/ @@ -463,8 +506,16 @@ jobs: - name: Build .deb package (fully self-contained) run: | + set -euo pipefail TOR_VERSION="15.0.9" - curl -sL "https://archive.torproject.org/tor-package-archive/torbrowser/${TOR_VERSION}/tor-expert-bundle-linux-x86_64-${TOR_VERSION}.tar.gz" -o tor-bundle.tar.gz + # Resilient download: archive.torproject.org occasionally times out + # from CI egress (observed 2026-07-03: macOS job exit code 6 after + # exactly 30s of curl hang). Retries + --fail-with-body surface the + # next failure loudly instead of silently producing a 0-byte file. + curl -fSL --connect-timeout 15 --max-time 120 \ + --retry 3 --retry-delay 5 --retry-connrefused --retry-all-errors \ + "https://archive.torproject.org/tor-package-archive/torbrowser/${TOR_VERSION}/tor-expert-bundle-linux-x86_64-${TOR_VERSION}.tar.gz" \ + -o tor-bundle.tar.gz mkdir -p tor-extract && tar -xzf tor-bundle.tar.gz -C tor-extract PKG="cryptographic-triangles_${VERSION}_amd64" @@ -732,9 +783,18 @@ jobs: otool -L "$BINARY" | head -30 - name: Bundle Tor into app + # Resilient download: archive.torproject.org occasionally times out + # from Azure westus egress (observed 2026-07-03: macOS job exit code 6 + # after exactly 30s of curl hang). --retry 3 with --retry-connrefused + # handles transient connection refusals and timeouts; --fail-with-body + # surfaces HTTP error bodies so the next failure isn't silent. run: | + set -euo pipefail TOR_VERSION="15.0.9" - curl -sL "https://archive.torproject.org/tor-package-archive/torbrowser/${TOR_VERSION}/tor-expert-bundle-macos-aarch64-${TOR_VERSION}.tar.gz" -o tor-bundle.tar.gz + curl -fSL --connect-timeout 15 --max-time 120 \ + --retry 3 --retry-delay 5 --retry-connrefused --retry-all-errors \ + "https://archive.torproject.org/tor-package-archive/torbrowser/${TOR_VERSION}/tor-expert-bundle-macos-aarch64-${TOR_VERSION}.tar.gz" \ + -o tor-bundle.tar.gz mkdir -p tor-extract && tar -xzf tor-bundle.tar.gz -C tor-extract APP=$(find build/bin -name "*.app" -maxdepth 1 | head -1) mkdir -p "$APP/Contents/MacOS/tor" diff --git a/scripts/ci/package-linux-daemon.sh b/scripts/ci/package-linux-daemon.sh index ad19bb4..eba8539 100755 --- a/scripts/ci/package-linux-daemon.sh +++ b/scripts/ci/package-linux-daemon.sh @@ -30,7 +30,14 @@ mkdir -p "${PKG}/etc/systemd/system" TOR_TARBALL="tor-expert-bundle-linux-x86_64-${TOR_VERSION}.tar.gz" if [ ! -f "${TOR_TARBALL}" ]; then echo ">>> Downloading Tor ${TOR_VERSION}..." - curl -sL "https://archive.torproject.org/tor-package-archive/torbrowser/${TOR_VERSION}/${TOR_TARBALL}" -o "${TOR_TARBALL}" + # Resilient download: archive.torproject.org occasionally times out from + # CI egress (observed 2026-07-03: macOS job exit code 6 after exactly 30s + # of curl hang). --retry 3 + --retry-connrefused covers transient network + # drops; --fail-with-body surfaces HTTP errors loudly. + curl -fSL --connect-timeout 15 --max-time 120 \ + --retry 3 --retry-delay 5 --retry-connrefused --retry-all-errors \ + "https://archive.torproject.org/tor-package-archive/torbrowser/${TOR_VERSION}/${TOR_TARBALL}" \ + -o "${TOR_TARBALL}" fi mkdir -p tor-extract tar -xzf "${TOR_TARBALL}" -C tor-extract diff --git a/src/clientversion.h b/src/clientversion.h index 515e7e2..169cb1e 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -6,10 +6,10 @@ // // These need to be macros, as version.cpp's and triangles-qt.rc's voodoo requires it -#define CLIENT_VERSION_MAJOR 6 -#define CLIENT_VERSION_MINOR 1 -#define CLIENT_VERSION_REVISION 1 -#define CLIENT_VERSION_BUILD 0 +#define CLIENT_VERSION_MAJOR 6 +#define CLIENT_VERSION_MINOR 1 +#define CLIENT_VERSION_REVISION 4 +#define CLIENT_VERSION_BUILD 0 // Converts the parameter X to a string after macro replacement on X has been performed. // Don't merge these into one macro!