Skip to content

Add dual-arch Linux release support#8551

Merged
atavism merged 25 commits intomainfrom
atavism/linux-arm
Mar 31, 2026
Merged

Add dual-arch Linux release support#8551
atavism merged 25 commits intomainfrom
atavism/linux-arm

Conversation

@atavism
Copy link
Copy Markdown
Contributor

@atavism atavism commented Mar 19, 2026

No description provided.

Copilot AI review requested due to automatic review settings March 19, 2026 19:25
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds CI/release pipeline support to produce and publish Linux installers for both AMD64 and ARM64, including arch-specific naming, packaging inputs, and release messaging.

Changes:

  • Build Linux releases via a matrix over amd64/arm64, and verify .deb architecture during CI.
  • Publish Linux artifacts to S3 (and GitHub Releases) with arch-aware directory/filename handling.
  • Parameterize nfpm packaging inputs to package the correct Flutter bundle per architecture.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
scripts/ci/verify_linux_package.sh Adds optional expected-arch checking for .deb verification.
scripts/ci/publish-to-s3.sh Upload logic updated to locate/upload arch-specific Linux artifacts (amd64/arm64).
scripts/ci/format.sh Release notes/Slack formatting updated to emit arch-specific Linux download links.
Makefile Introduces LINUX_TARGET_ARCH, arch-suffixed package names, and bundle-dir selection for packaging.
linux/packaging/nfpm.yaml Switches Flutter bundle source to ${LINUX_BUNDLE_SRC} and uses ${GOARCH} for package arch.
.github/workflows/release.yml Adds linux_arch input/propagation and uploads arch-specific Linux assets to releases/S3.
.github/workflows/build-linux.yml Builds Linux for one or both arches via matrix, including ARM runner and artifact naming.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread scripts/ci/publish-to-s3.sh
Comment thread scripts/ci/format.sh
Comment thread .github/workflows/build-linux.yml Outdated
@jigar-f
Copy link
Copy Markdown
Contributor

jigar-f commented Mar 25, 2026

@atavism Did you mean to request a review? I see you assigned this to me??

@atavism atavism requested a review from jigar-f March 31, 2026 16:25
@atavism
Copy link
Copy Markdown
Contributor Author

atavism commented Mar 31, 2026

@garmr-ulfr Is this a known issue with the latest radiance? I haven't looked into it, but the connect smoke is failing now https://github.com/getlantern/lantern/actions/runs/23808257416/job/69387916243#step:19:126

[Debug] app-Logger: Starting VPN
Error:  app-Logger: Error changing VPN state: start service failed: 503 Service Unavailable: failed to start tunnel: initializing tunnel: create libbox service: create service: initialize outbound[2]: missing tags

@garmr-ulfr
Copy link
Copy Markdown
Contributor

Is this a known issue with the latest radiance?

Not that I'm aware of. It might have something to do with the latest change from @myleshorton. Let me check real quick.

@myleshorton
Copy link
Copy Markdown
Contributor

I'll check!!

@garmr-ulfr
Copy link
Copy Markdown
Contributor

Nevermind. I found the issue! A smart-routing outbound was still added without any tags. I thought that was fixed..

@garmr-ulfr
Copy link
Copy Markdown
Contributor

garmr-ulfr commented Mar 31, 2026

Oh, that PR wasn't merged yet.. I just merged it. Running the smoke tests to verify real quick before merging into lantern main.

@atavism atavism merged commit 395da08 into main Mar 31, 2026
24 checks passed
@atavism atavism deleted the atavism/linux-arm branch March 31, 2026 18:59
@atavism
Copy link
Copy Markdown
Contributor Author

atavism commented Mar 31, 2026

atavism added a commit that referenced this pull request Apr 1, 2026
* Update radiance to latest main (idle timeout fix) (#8587)

Picks up radiance with lantern-box v0.0.52, which fixes VPN losing
all proxy routes after ~15min idle / wake from sleep
(getlantern/engineering#3115).

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Update radiance to latest main (#8588)

Picks up:
- Fix: only remove old outbounds when new ones successfully load
- Distributed tracing: bandit trace context extraction + url_tests_complete span
- Config: populate all server locations for location picker
- Bump common to latest (PollIntervalSeconds in ConfigResponse)

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Migrate to xcode 26 (#8579)

* Migrate to newer xcode version

* code review updates

* remove node setup on ios

* Save user state (#8589)

* chore: bump radiance to latest (public IP detection) (#8590)

Updates radiance which now detects the client's public IP at startup
using getlantern/publicip (STUN, HTTP, DNS, UPnP consensus) and sends
it as X-Lantern-Config-Client-IP on all API requests. This ensures
the server can determine the correct country and ASN for bandit route
selection even when requests arrive via domain fronting.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Update radiance to latest main (nil idleTimer panic fix) (#8591)

Picks up radiance with lantern-box v0.0.54, which fixes the nil
pointer panic in keepAlive() introduced by #208's idle timeout fix.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Update radiance to latest (kindling rewrite) (#8593)

Bumps radiance to v0.0.0-20260329145230-a19ebe6b9b4d and kindling to
v0.0.0-20260329144042-b1825b9cb1bb.

Key changes from upstream:
- kindling race transport rewrite fixing deadlocks, response body leaks,
  and global mutable state (getlantern/kindling#30)
- radiance updated for kindling's new error-returning API with nil
  transport guards and thread-safe HTTPClient (getlantern/radiance#387)

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Windows: suppress settings-triggered VPN notifications (#8582)

* Fix remaining Windows issues

* Fix remaining Windows issues

* Bump radiance for smart-routing outbound fix

* Skip Windows signing for nightly test runs

* code review updates

* code review updates

* Update radiance to latest origin/main

* Update radiance to merged outbound fix branch

* Fix data cap reached ticker text colors

* code review updates

* Fix Android network blackout — call setUnderlyingNetworks on VPN start (#8594)

* Fix Android "no available network interface" — call setUnderlyingNetworks

On Android 10+, ConnectivityManager.getAllNetworks() may return only
the VPN network when VpnService.setUnderlyingNetworks() hasn't been
called. This causes sing-box's NetworkManager to see no physical
interfaces, making the direct outbound fail with "no available
network interface". With strict_route enabled, this creates a total
network blackout — the device loses all connectivity.

Three fixes:

1. Call setUnderlyingNetworks() after VPN start and on every default
   network change, so Android always reports physical networks
   alongside the VPN.

2. Add a network change callback from DefaultNetworkMonitor to the
   VPN service so setUnderlyingNetworks() is updated on WiFi/mobile
   switches.

3. Fix missing `return` in DefaultNetworkMonitor retry loop — the
   loop called updateDefaultInterface up to 10 times instead of
   stopping after the first success.

Fixes getlantern/engineering#3117 (partial — Android-specific)

Freshdesk tickets:
- https://lantern.freshdesk.com/a/tickets/171589 (total blackout, Vivo Android 10)
- https://lantern.freshdesk.com/a/tickets/171317 (connected but no data, Xiaomi Android 11)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Address PR review: prevent callback leak and fix KDoc

1. Clear networkChangeCallback in DefaultNetworkMonitor.stop()
   defensively, so the static singleton never holds a stale
   service reference.

2. Clear callback and stop monitor in the onFailure path of
   launchVPN, preventing leak when VPN start fails.

3. Fix KDoc link to use fully qualified android.net.VpnService.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Renewal flow (#8580)

* Added support for renewal

* fix card color issue on payment screen.

* fix OAuth button color issue

* code review updates

* fix service edge case

* fix syntax issue

* Fix Android VPN teardown cleanup and IAP loading state (#8596)

* code review updates

* code review updates

---------

Co-authored-by: atavism <paul@getlantern.org>
Co-authored-by: atavism <atavism@users.noreply.github.com>

* File watcher fix for IOS (#8597)

* Fix ios 26.3 issue due to file watcher

* code review updates

* code review updates

* update radiance to main (outbound creation error logging) (#8598)

Updates radiance to include PR #388 which logs individual outbound
creation errors. Previously these were silently swallowed, making it
impossible to diagnose why new proxies fail to load on the client.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Added guard on stripe service and flag UI issue

* Add AI-powered release notes generation (#8599)

* Add AI-powered release notes generation via Claude API

Uses Claude Haiku to generate categorized, human-readable release
notes from the git log between the previous release and the current
one. Runs in CI after builds complete, prepended to the existing
download links.

- New script: scripts/ci/generate-release-notes.sh
- Finds previous tag by build type (production, beta, nightly)
- Sends commit log to Claude API for summarization
- Falls back gracefully to basic changelog if API unavailable
- Uses Haiku for speed and cost-efficiency

Requires ANTHROPIC_API_KEY repo secret.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Address PR review: tag matching, jq guard, shallow clone fix

- Fix tag matching to include platform suffixes (e.g., v9.0.15-ios)
- Use grep -Fvx for fixed-string tag exclusion (avoid regex metachar issues)
- Add jq availability check with graceful fallback
- Remove unused COMMIT_RANGE and PR_LIST variables
- Add fetch-depth: 0 and fetch-tags: true to workflow checkout

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* update radiance: fix IPC JSON serialization for outbound options (#8600)

Updates radiance to include PR #390 which fixes the root cause of
"public_key must be 64 hex characters (32 bytes), got len=0" errors
when bandit arms rotate.

The IPC path between config fetcher and VPN tunnel used standard
encoding/json which can't reconstruct typed sing-box outbound options.
Now uses singjson.MarshalContext/UnmarshalExtendedContext with
box.BaseContext() so custom types like SamizdatOutboundOptions
survive the round-trip.

Also includes lantern-box v0.0.55 (key validation diagnostics).

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* pull in smart routing empty tags sanity check (#8601)

* Add dual-arch Linux release support (#8551)

* Add Linux arm64 packaging and CI support

* Fix Linux arch workflow input wiring

* Fix Linux workflow matrix selection

* Simplify Linux arch workflow selection

* Fix Linux arch matrix expression

* Fix release workflow input routing

* Polish Linux arch release flow

* Fix Flutter setup on Linux arm64 CI

* Fix arm64 Flutter fallback PATH

* Gate Linux smoke IP check by architecture

* Update scripts/ci/publish-to-s3.sh

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Set explicit token permissions for Linux workflow

* Fail fast Linux UI smoke test in CI

* Clean up connect smoke failure path

* code review updates

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* update radiance: honor server-recommended config poll interval (#8602)

Includes radiance#392: client now uses the server's poll_interval_seconds
instead of the hardcoded 10-minute default. The bandit server sends 60s
for new ASNs and up to 900s when converged, enabling 10x faster learning.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Stripe updates (#8604)

* update stripe payments

* update radiance.

* code review updates

* Fix Windows installer cleanup (#8576)

* Fix Windows installer cleanup

* Fix Windows installer script syntax

* code review updates

* Fix Inno script compile error on ExecSc logging

* code review updates

* Harden uninstall string parsing

---------

Co-authored-by: Myles Horton <afisk@getlantern.org>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: jigar-f <132374182+jigar-f@users.noreply.github.com>
Co-authored-by: Jigar-f <jigar@getlantern.org>
Co-authored-by: garmr-ulfr <104022054+garmr-ulfr@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
atavism added a commit that referenced this pull request Apr 1, 2026
…#8586)

* bundle signing requests as single zip to reduce artifact upload quota

* Bundle signing validation and nightly defaults (#8605)

* Update radiance to latest main (idle timeout fix) (#8587)

Picks up radiance with lantern-box v0.0.52, which fixes VPN losing
all proxy routes after ~15min idle / wake from sleep
(getlantern/engineering#3115).

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Update radiance to latest main (#8588)

Picks up:
- Fix: only remove old outbounds when new ones successfully load
- Distributed tracing: bandit trace context extraction + url_tests_complete span
- Config: populate all server locations for location picker
- Bump common to latest (PollIntervalSeconds in ConfigResponse)

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Migrate to xcode 26 (#8579)

* Migrate to newer xcode version

* code review updates

* remove node setup on ios

* Save user state (#8589)

* chore: bump radiance to latest (public IP detection) (#8590)

Updates radiance which now detects the client's public IP at startup
using getlantern/publicip (STUN, HTTP, DNS, UPnP consensus) and sends
it as X-Lantern-Config-Client-IP on all API requests. This ensures
the server can determine the correct country and ASN for bandit route
selection even when requests arrive via domain fronting.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Update radiance to latest main (nil idleTimer panic fix) (#8591)

Picks up radiance with lantern-box v0.0.54, which fixes the nil
pointer panic in keepAlive() introduced by #208's idle timeout fix.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Update radiance to latest (kindling rewrite) (#8593)

Bumps radiance to v0.0.0-20260329145230-a19ebe6b9b4d and kindling to
v0.0.0-20260329144042-b1825b9cb1bb.

Key changes from upstream:
- kindling race transport rewrite fixing deadlocks, response body leaks,
  and global mutable state (getlantern/kindling#30)
- radiance updated for kindling's new error-returning API with nil
  transport guards and thread-safe HTTPClient (getlantern/radiance#387)

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Windows: suppress settings-triggered VPN notifications (#8582)

* Fix remaining Windows issues

* Fix remaining Windows issues

* Bump radiance for smart-routing outbound fix

* Skip Windows signing for nightly test runs

* code review updates

* code review updates

* Update radiance to latest origin/main

* Update radiance to merged outbound fix branch

* Fix data cap reached ticker text colors

* code review updates

* Fix Android network blackout — call setUnderlyingNetworks on VPN start (#8594)

* Fix Android "no available network interface" — call setUnderlyingNetworks

On Android 10+, ConnectivityManager.getAllNetworks() may return only
the VPN network when VpnService.setUnderlyingNetworks() hasn't been
called. This causes sing-box's NetworkManager to see no physical
interfaces, making the direct outbound fail with "no available
network interface". With strict_route enabled, this creates a total
network blackout — the device loses all connectivity.

Three fixes:

1. Call setUnderlyingNetworks() after VPN start and on every default
   network change, so Android always reports physical networks
   alongside the VPN.

2. Add a network change callback from DefaultNetworkMonitor to the
   VPN service so setUnderlyingNetworks() is updated on WiFi/mobile
   switches.

3. Fix missing `return` in DefaultNetworkMonitor retry loop — the
   loop called updateDefaultInterface up to 10 times instead of
   stopping after the first success.

Fixes getlantern/engineering#3117 (partial — Android-specific)

Freshdesk tickets:
- https://lantern.freshdesk.com/a/tickets/171589 (total blackout, Vivo Android 10)
- https://lantern.freshdesk.com/a/tickets/171317 (connected but no data, Xiaomi Android 11)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Address PR review: prevent callback leak and fix KDoc

1. Clear networkChangeCallback in DefaultNetworkMonitor.stop()
   defensively, so the static singleton never holds a stale
   service reference.

2. Clear callback and stop monitor in the onFailure path of
   launchVPN, preventing leak when VPN start fails.

3. Fix KDoc link to use fully qualified android.net.VpnService.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Renewal flow (#8580)

* Added support for renewal

* fix card color issue on payment screen.

* fix OAuth button color issue

* code review updates

* fix service edge case

* fix syntax issue

* Fix Android VPN teardown cleanup and IAP loading state (#8596)

* code review updates

* code review updates

---------

Co-authored-by: atavism <paul@getlantern.org>
Co-authored-by: atavism <atavism@users.noreply.github.com>

* File watcher fix for IOS (#8597)

* Fix ios 26.3 issue due to file watcher

* code review updates

* code review updates

* update radiance to main (outbound creation error logging) (#8598)

Updates radiance to include PR #388 which logs individual outbound
creation errors. Previously these were silently swallowed, making it
impossible to diagnose why new proxies fail to load on the client.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Added guard on stripe service and flag UI issue

* Add AI-powered release notes generation (#8599)

* Add AI-powered release notes generation via Claude API

Uses Claude Haiku to generate categorized, human-readable release
notes from the git log between the previous release and the current
one. Runs in CI after builds complete, prepended to the existing
download links.

- New script: scripts/ci/generate-release-notes.sh
- Finds previous tag by build type (production, beta, nightly)
- Sends commit log to Claude API for summarization
- Falls back gracefully to basic changelog if API unavailable
- Uses Haiku for speed and cost-efficiency

Requires ANTHROPIC_API_KEY repo secret.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Address PR review: tag matching, jq guard, shallow clone fix

- Fix tag matching to include platform suffixes (e.g., v9.0.15-ios)
- Use grep -Fvx for fixed-string tag exclusion (avoid regex metachar issues)
- Add jq availability check with graceful fallback
- Remove unused COMMIT_RANGE and PR_LIST variables
- Add fetch-depth: 0 and fetch-tags: true to workflow checkout

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* update radiance: fix IPC JSON serialization for outbound options (#8600)

Updates radiance to include PR #390 which fixes the root cause of
"public_key must be 64 hex characters (32 bytes), got len=0" errors
when bandit arms rotate.

The IPC path between config fetcher and VPN tunnel used standard
encoding/json which can't reconstruct typed sing-box outbound options.
Now uses singjson.MarshalContext/UnmarshalExtendedContext with
box.BaseContext() so custom types like SamizdatOutboundOptions
survive the round-trip.

Also includes lantern-box v0.0.55 (key validation diagnostics).

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* pull in smart routing empty tags sanity check (#8601)

* Add dual-arch Linux release support (#8551)

* Add Linux arm64 packaging and CI support

* Fix Linux arch workflow input wiring

* Fix Linux workflow matrix selection

* Simplify Linux arch workflow selection

* Fix Linux arch matrix expression

* Fix release workflow input routing

* Polish Linux arch release flow

* Fix Flutter setup on Linux arm64 CI

* Fix arm64 Flutter fallback PATH

* Gate Linux smoke IP check by architecture

* Update scripts/ci/publish-to-s3.sh

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Set explicit token permissions for Linux workflow

* Fail fast Linux UI smoke test in CI

* Clean up connect smoke failure path

* code review updates

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* update radiance: honor server-recommended config poll interval (#8602)

Includes radiance#392: client now uses the server's poll_interval_seconds
instead of the hardcoded 10-minute default. The bandit server sends 60s
for new ASNs and up to 900s when converged, enabling 10x faster learning.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Stripe updates (#8604)

* update stripe payments

* update radiance.

* code review updates

* Fix Windows installer cleanup (#8576)

* Fix Windows installer cleanup

* Fix Windows installer script syntax

* code review updates

* Fix Inno script compile error on ExecSc logging

* code review updates

* Harden uninstall string parsing

---------

Co-authored-by: Myles Horton <afisk@getlantern.org>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: jigar-f <132374182+jigar-f@users.noreply.github.com>
Co-authored-by: Jigar-f <jigar@getlantern.org>
Co-authored-by: garmr-ulfr <104022054+garmr-ulfr@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Remove duplicate skip_signing input

---------

Co-authored-by: atavism <atavism@users.noreply.github.com>
Co-authored-by: Myles Horton <afisk@getlantern.org>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: jigar-f <132374182+jigar-f@users.noreply.github.com>
Co-authored-by: Jigar-f <jigar@getlantern.org>
Co-authored-by: garmr-ulfr <104022054+garmr-ulfr@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: atavism <paul@getlantern.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants