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
76 changes: 65 additions & 11 deletions .github/workflows/build-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,25 @@ on:
installer_base_name:
required: true
type: string
linux_arch:
required: false
type: string
default: all

permissions:
contents: "read"

jobs:
build-linux:
strategy:
fail-fast: false
matrix: ${{ fromJSON(inputs.linux_arch == 'arm64' && '{"include":[{"arch":"arm64","runner":"ubuntu-24.04-arm"}]}' || inputs.linux_arch == 'amd64' && '{"include":[{"arch":"amd64","runner":"ubuntu-latest"}]}' || inputs.linux_arch == 'all' && '{"include":[{"arch":"amd64","runner":"ubuntu-latest"},{"arch":"arm64","runner":"ubuntu-24.04-arm"}]}') }}
env:
BUILD_TYPE: ${{ inputs.build_type }}
VERSION: ${{ inputs.version }}
runs-on: ubuntu-latest
TARGET_ARCH: ${{ matrix.arch }}
FULL_INSTALLER_NAME: ${{ inputs.installer_base_name }}${{ inputs.build_type != 'production' && format('-{0}', inputs.build_type) || '' }}${{ matrix.arch == 'arm64' && '-arm64' || '' }}
runs-on: ${{ matrix.runner }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
Expand Down Expand Up @@ -52,9 +64,9 @@ jobs:
continue-on-error: true
with:
path: ~/.cache/apt/archives
key: ${{ runner.os }}-apt-archives-v1-${{ hashFiles('.github/workflows/build-linux.yml') }}
key: ${{ runner.os }}-${{ matrix.arch }}-apt-archives-v1-${{ hashFiles('.github/workflows/build-linux.yml') }}
restore-keys: |
${{ runner.os }}-apt-archives-v1-
${{ runner.os }}-${{ matrix.arch }}-apt-archives-v1-

- name: Install Linux dependencies
run: |
Expand Down Expand Up @@ -95,13 +107,36 @@ jobs:
- name: Install the ninja build tool
uses: seanmiddleditch/gha-setup-ninja@master

- name: Install Flutter
- name: Load Flutter version
shell: bash
run: |
set -euo pipefail
FLUTTER_VERSION=$(grep -E '^[[:space:]]*flutter:' .github/flutter-version.yaml | sed -E 's/.*"([^"]+)".*/\1/')
if [[ -z "$FLUTTER_VERSION" ]]; then
echo "Failed to parse Flutter version from .github/flutter-version.yaml" >&2
exit 1
fi
echo "FLUTTER_VERSION=$FLUTTER_VERSION" >> "$GITHUB_ENV"

- name: Install Flutter (amd64)
uses: subosito/flutter-action@v2.22.0
if: ${{ matrix.arch == 'amd64' }}
with:
channel: stable
flutter-version-file: .github/flutter-version.yaml
cache: true

- name: Install Flutter (arm64 fallback)
if: ${{ matrix.arch == 'arm64' }}
shell: bash
run: |
set -euo pipefail
FLUTTER_HOME="$HOME/flutter"
git clone --depth 1 --branch "$FLUTTER_VERSION" https://github.com/flutter/flutter.git "$FLUTTER_HOME"
echo "$FLUTTER_HOME/bin" >> "$GITHUB_PATH"
export PATH="$FLUTTER_HOME/bin:$PATH"
flutter --version

- name: Install dependencies
run: make install-linux-deps

Expand All @@ -122,16 +157,19 @@ jobs:
BUILD_TYPE: ${{ inputs.build_type }}
VERSION: ${{ inputs.version }}
INSTALLER_NAME: ${{ inputs.installer_base_name }}
LINUX_TARGET_ARCH: ${{ matrix.arch }}
LINUX_CC_AMD64: gcc
LINUX_CC_ARM64: gcc

- name: Verify Linux package contents
run: |
./scripts/ci/verify_linux_package.sh "${{ inputs.installer_base_name }}${{ inputs.build_type != 'production' && format('-{0}', inputs.build_type) || '' }}.deb"
./scripts/ci/verify_linux_package.sh "./${{ env.FULL_INSTALLER_NAME }}.deb" "${{ matrix.arch }}"

- name: Install .deb and verify postinst started daemon
shell: bash
run: |
set -euxo pipefail
deb="./${{ inputs.installer_base_name }}${{ inputs.build_type != 'production' && format('-{0}', inputs.build_type) || '' }}.deb"
deb="./${{ env.FULL_INSTALLER_NAME }}.deb"
test -f "$deb"
sudo apt-get install -y "$deb"

Expand Down Expand Up @@ -180,9 +218,25 @@ jobs:
run: |
set -euxo pipefail
TEST_START_UTC="$(date -u '+%Y-%m-%d %H:%M:%S')"
sg lantern -c "env PATH=$PATH HOME=$HOME xvfb-run -a flutter test integration_test/vpn/linux_connect_smoke_test.dart -d linux --dart-define=DISABLE_SYSTEM_TRAY=true --dart-define=ENABLE_IP_CHECK=true"
ENABLE_IP_CHECK=false
if [[ "${TARGET_ARCH}" == "amd64" ]]; then
ENABLE_IP_CHECK=true
fi
set +e
sg lantern -c "env PATH=$PATH HOME=$HOME timeout --signal=TERM --kill-after=30s 8m xvfb-run -a flutter test integration_test/vpn/linux_connect_smoke_test.dart -d linux --reporter=expanded --dart-define=DISABLE_SYSTEM_TRAY=true --dart-define=ENABLE_IP_CHECK=${ENABLE_IP_CHECK}"
SMOKE_EXIT=$?
set -e

sudo journalctl -u lanternd.service --since "$TEST_START_UTC" --no-pager > /tmp/lanternd-journal-ui-smoke.log
if [[ "$SMOKE_EXIT" -eq 124 ]]; then
echo "Linux UI connect/disconnect smoke timed out after 8m"
tail -n 200 /tmp/lanternd-journal-ui-smoke.log || true
exit 1
fi
if [[ "$SMOKE_EXIT" -ne 0 ]]; then
tail -n 200 /tmp/lanternd-journal-ui-smoke.log || true
exit "$SMOKE_EXIT"
fi

if ! grep -Eq 'IPC request.*path=/service/start' /tmp/lanternd-journal-ui-smoke.log; then
echo "Missing /service/start IPC request in lanternd journal"
Expand All @@ -199,13 +253,13 @@ jobs:
- name: Upload Linux build
uses: actions/upload-artifact@v4
with:
name: lantern-installer-rpm
path: ${{ inputs.installer_base_name }}${{ inputs.build_type != 'production' && format('-{0}', inputs.build_type) || '' }}.rpm
name: lantern-installer-rpm-${{ matrix.arch }}
path: ${{ env.FULL_INSTALLER_NAME }}.rpm
retention-days: 2

- name: Upload Linux build
uses: actions/upload-artifact@v4
with:
name: lantern-installer-deb
path: ${{ inputs.installer_base_name }}${{ inputs.build_type != 'production' && format('-{0}', inputs.build_type) || '' }}.deb
name: lantern-installer-deb-${{ matrix.arch }}
path: ${{ env.FULL_INSTALLER_NAME }}.deb
retention-days: 2
34 changes: 34 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,15 @@ on:
required: false
type: string
default: "linux"
linux_arch:
description: "Linux arch to build when Linux is included"
required: false
type: choice
options:
- all
- amd64
- arm64
default: all
cleanup_on_failure:
description: "Delete draft release on failure"
required: false
Expand Down Expand Up @@ -49,6 +58,7 @@ jobs:
version: ${{ steps.meta.outputs.version }}
installer_base_name: ${{ steps.meta.outputs.installer_base_name }}
platform: ${{ steps.meta.outputs.platform }}
linux_arch: ${{ steps.meta.outputs.linux_arch }}
is_test_run: ${{ steps.meta.outputs.is_test_run }}
steps:
- name: Checkout repo
Expand All @@ -72,12 +82,14 @@ jobs:
VERSION=$(./scripts/ci/version.sh generate nightly)
RELEASE_TAG="v${VERSION}"
PLATFORM="all"
LINUX_ARCH="all"
;;

workflow_dispatch)
# Manual trigger
BUILD_TYPE="${{ github.event.inputs.build_type }}"
PLATFORM="${{ github.event.inputs.platforms }}"
LINUX_ARCH="${{ github.event.inputs.linux_arch }}"

case "$BUILD_TYPE" in
nightly|beta)
Expand Down Expand Up @@ -135,6 +147,19 @@ jobs:
all) ;;
*) VERSION="${VERSION%-$PLATFORM}" ;;
esac

case "$PLATFORM" in
all|linux) LINUX_ARCH="all" ;;
*) LINUX_ARCH="amd64" ;;
esac
;;
esac

case "$LINUX_ARCH" in
all|amd64|arm64) ;;
*)
echo "Error: Invalid linux_arch '$LINUX_ARCH' (expected: all, amd64, arm64)" >&2
exit 1
;;
esac

Expand All @@ -147,6 +172,7 @@ jobs:
echo " Release Tag: $RELEASE_TAG"
echo " Version: $VERSION"
echo " Platform: $PLATFORM"
echo " Linux Arch: $LINUX_ARCH"
echo " Installer: $INSTALLER_BASE_NAME"

# Test run: workflow_dispatch from non-default branch
Expand All @@ -163,6 +189,7 @@ jobs:
echo "release_tag=$RELEASE_TAG" >> $GITHUB_OUTPUT
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "platform=$PLATFORM" >> $GITHUB_OUTPUT
echo "linux_arch=$LINUX_ARCH" >> $GITHUB_OUTPUT
echo "installer_base_name=$INSTALLER_BASE_NAME" >> $GITHUB_OUTPUT
echo "is_test_run=$IS_TEST_RUN" >> $GITHUB_OUTPUT

Expand Down Expand Up @@ -266,6 +293,7 @@ jobs:
version: ${{ needs.set-metadata.outputs.version }}
build_type: ${{ needs.set-metadata.outputs.build_type }}
installer_base_name: ${{ needs.set-metadata.outputs.installer_base_name }}
linux_arch: ${{ needs.set-metadata.outputs.linux_arch }}

build-ios:
needs: [set-metadata, release-create, release-approval]
Expand Down Expand Up @@ -365,6 +393,7 @@ jobs:
RELEASE_TAG: ${{ needs.set-metadata.outputs.release_tag }}
INSTALLER_BASE_NAME: ${{ needs.set-metadata.outputs.installer_base_name }}
PLATFORM: ${{ needs.set-metadata.outputs.platform }}
LINUX_ARCH: ${{ needs.set-metadata.outputs.linux_arch }}
BUCKET: ${{ vars.S3_RELEASES_BUCKET }}
GITHUB_REF_NAME: ${{ github.ref_name }}
steps:
Expand Down Expand Up @@ -445,6 +474,7 @@ jobs:
RELEASE_TAG: ${{ needs.set-metadata.outputs.release_tag }}
INSTALLER_BASE_NAME: ${{ needs.set-metadata.outputs.installer_base_name }}
PLATFORM: ${{ needs.set-metadata.outputs.platform }}
LINUX_ARCH: ${{ needs.set-metadata.outputs.linux_arch }}
BUCKET: ${{ vars.S3_RELEASES_BUCKET }}
GITHUB_REF_NAME: ${{ github.ref_name }}
steps:
Expand Down Expand Up @@ -487,6 +517,10 @@ jobs:
upload_if_exists "lantern-installer-dmg/${FULL_NAME}.dmg"
upload_if_exists "lantern-installer-exe/${FULL_NAME}.exe"
upload_if_exists "lantern-installer-apk/${FULL_NAME}.apk"
upload_if_exists "lantern-installer-deb-amd64/${FULL_NAME}.deb"
upload_if_exists "lantern-installer-rpm-amd64/${FULL_NAME}.rpm"
upload_if_exists "lantern-installer-deb-arm64/${FULL_NAME}-arm64.deb"
upload_if_exists "lantern-installer-rpm-arm64/${FULL_NAME}-arm64.rpm"
upload_if_exists "lantern-installer-deb/${FULL_NAME}.deb"
upload_if_exists "lantern-installer-rpm/${FULL_NAME}.rpm"
upload_if_exists "lantern-installer-ipa/${FULL_NAME}.ipa"
Expand Down
57 changes: 37 additions & 20 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,20 @@ LINUX_LIB := $(LANTERN_LIB_NAME).so
LINUX_LIB_AMD64 := $(BIN_DIR)/linux-amd64/$(LANTERN_LIB_NAME).so
LINUX_LIB_ARM64 := $(BIN_DIR)/linux-arm64/$(LANTERN_LIB_NAME).so
LINUX_LIB_BUILD := $(BIN_DIR)/linux/$(LINUX_LIB)
LINUX_INSTALLER_DEB := $(INSTALLER_NAME)$(if $(filter-out production,$(BUILD_TYPE)),-$(BUILD_TYPE)).deb
LINUX_INSTALLER_RPM := $(INSTALLER_NAME)$(if $(filter-out production,$(BUILD_TYPE)),-$(BUILD_TYPE)).rpm
LINUX_INSTALLER_ARCH := $(INSTALLER_NAME)$(if $(filter-out production,$(BUILD_TYPE)),-$(BUILD_TYPE)).pkg.tar.zst
LINUX_TARGET_ARCH ?= amd64
LINUX_PACKAGE_ARCH_SUFFIX := $(if $(filter amd64,$(LINUX_TARGET_ARCH)),,-$(LINUX_TARGET_ARCH))
LINUX_INSTALLER_DEB := $(INSTALLER_NAME)$(if $(filter-out production,$(BUILD_TYPE)),-$(BUILD_TYPE))$(LINUX_PACKAGE_ARCH_SUFFIX).deb
LINUX_INSTALLER_RPM := $(INSTALLER_NAME)$(if $(filter-out production,$(BUILD_TYPE)),-$(BUILD_TYPE))$(LINUX_PACKAGE_ARCH_SUFFIX).rpm
LINUX_INSTALLER_ARCH := $(INSTALLER_NAME)$(if $(filter-out production,$(BUILD_TYPE)),-$(BUILD_TYPE))$(LINUX_PACKAGE_ARCH_SUFFIX).pkg.tar.zst
LINUX_SERVICE_NAME := lanternd
LINUX_SERVICE_SRC := $(RADIANCE_REPO)/cmd/lanternd
LINUX_SERVICE_BUILD_AMD64 := $(BIN_DIR)/linux-amd64/$(LINUX_SERVICE_NAME)
LINUX_SERVICE_BUILD_ARM64 := $(BIN_DIR)/linux-arm64/$(LINUX_SERVICE_NAME)
LINUX_SERVICE_BUILD_TARGET := $(BIN_DIR)/linux-$(LINUX_TARGET_ARCH)/$(LINUX_SERVICE_NAME)
LINUX_BUNDLE_DIR_X64 := build/linux/x64/release/bundle
LINUX_BUNDLE_DIR_ARM64 := build/linux/arm64/release/bundle
LINUX_CC_AMD64 ?= x86_64-linux-gnu-gcc
LINUX_CC_ARM64 ?= aarch64-linux-gnu-gcc
LINUX_PKG_ROOT := linux/packaging
LINUX_SERVICE_DST := $(LINUX_PKG_ROOT)/usr/sbin
LINUX_PKG_SYSTEMD_DIR := $(LINUX_PKG_ROOT)/usr/lib/systemd/system
Expand Down Expand Up @@ -260,20 +267,20 @@ install-linux-deps:
linux-arm64: $(LINUX_LIB_ARM64)

$(LINUX_LIB_ARM64): $(GO_SOURCES)
CC=aarch64-linux-gnu-gcc GOARCH=arm64 LIB_NAME=$@ make desktop-lib
CC=$(LINUX_CC_ARM64) GOOS=linux GOARCH=arm64 LIB_NAME=$@ $(MAKE) desktop-lib

.PHONY: linux-amd64
linux-amd64: $(LINUX_LIB_AMD64)

$(LINUX_LIB_AMD64): $(GO_SOURCES)
CC=x86_64-linux-gnu-gcc GOARCH=amd64 LIB_NAME=$@ make desktop-lib
CC=$(LINUX_CC_AMD64) GOOS=linux GOARCH=amd64 LIB_NAME=$@ $(MAKE) desktop-lib

.PHONY: linux
linux: linux-amd64
linux: linux-$(LINUX_TARGET_ARCH)
mkdir -p $(BIN_DIR)/linux
cp $(LINUX_LIB_AMD64) $(LINUX_LIB_BUILD)
cp $(BIN_DIR)/linux-$(LINUX_TARGET_ARCH)/$(LINUX_LIB) $(LINUX_LIB_BUILD)

.PHONY: linux-service-amd64 linux-service-arm64 stage-linux-service
.PHONY: linux-service-amd64 linux-service-arm64 linux-service stage-linux-service

linux-service-amd64: $(GO_SOURCES)
$(call MKDIR_P,$(dir $(LINUX_SERVICE_BUILD_AMD64)))
Expand All @@ -291,10 +298,12 @@ linux-service-arm64: $(GO_SOURCES)
-o $(LINUX_SERVICE_BUILD_ARM64) $(LINUX_SERVICE_SRC)
@echo "Built Linux service: $(LINUX_SERVICE_BUILD_ARM64)"

stage-linux-service: linux-service-amd64
linux-service: linux-service-$(LINUX_TARGET_ARCH)

stage-linux-service: linux-service
@echo "Staging systemd unit + service binary $(LINUX_PKG_ROOT)..."
$(call MKDIR_P,$(LINUX_SERVICE_DST))
$(call COPY_FILE,$(LINUX_SERVICE_BUILD_AMD64),$(LINUX_SERVICE_DST)/$(LINUX_SERVICE_NAME))
$(call COPY_FILE,$(LINUX_SERVICE_BUILD_TARGET),$(LINUX_SERVICE_DST)/$(LINUX_SERVICE_NAME))
$(call MKDIR_P,$(LINUX_PKG_SYSTEMD_DIR))
$(call COPY_FILE,$(LINUX_SYSTEMD_UNIT_SRC),$(LINUX_SYSTEMD_UNIT_DST))

Expand All @@ -309,21 +318,29 @@ linux-release: clean linux-release-ci
linux-release-ci: linux pubget gen
@echo "Building Flutter app (release) for Linux..."
flutter build linux --release $(DART_DEFINES)

cp $(LINUX_LIB_BUILD) build/linux/x64/release/bundle
$(MAKE) stage-linux-service
patchelf --set-rpath '$$ORIGIN/lib' build/linux/x64/release/bundle/lantern || true

@echo "Packaging deb, rpm, and archlinux with nfpm..."
VERSION=$(APP_VERSION) SYSTEMD_UNIT_SRC=$(LINUX_SYSTEMD_UNIT_DST) \
@if [ "$(LINUX_TARGET_ARCH)" = "arm64" ]; then \
BUNDLE_DIR="$(LINUX_BUNDLE_DIR_ARM64)"; \
else \
BUNDLE_DIR="$(LINUX_BUNDLE_DIR_X64)"; \
fi; \
if [ ! -d "$$BUNDLE_DIR" ]; then \
echo "Expected Linux bundle dir not found: $$BUNDLE_DIR"; \
exit 1; \
fi; \
echo "Using Linux bundle dir: $$BUNDLE_DIR"; \
cp "$(LINUX_LIB_BUILD)" "$$BUNDLE_DIR"; \
patchelf --set-rpath '$$ORIGIN/lib' "$$BUNDLE_DIR/lantern" || true; \
VERSION=$(APP_VERSION) GOARCH=$(LINUX_TARGET_ARCH) LINUX_BUNDLE_SRC="$$BUNDLE_DIR/" SYSTEMD_UNIT_SRC=$(LINUX_SYSTEMD_UNIT_DST) \
LANTERND_SRC=$(LINUX_SERVICE_DST)/$(LINUX_SERVICE_NAME) LANTERND_DST=/usr/sbin/$(LINUX_SERVICE_NAME) \
nfpm package -f $(LINUX_PKG_ROOT)/nfpm.yaml -p deb -t $(LINUX_INSTALLER_DEB)
VERSION=$(APP_VERSION) SYSTEMD_UNIT_SRC=$(LINUX_SYSTEMD_UNIT_DST) \
nfpm package -f $(LINUX_PKG_ROOT)/nfpm.yaml -p deb -t $(LINUX_INSTALLER_DEB); \
VERSION=$(APP_VERSION) GOARCH=$(LINUX_TARGET_ARCH) LINUX_BUNDLE_SRC="$$BUNDLE_DIR/" SYSTEMD_UNIT_SRC=$(LINUX_SYSTEMD_UNIT_DST) \
LANTERND_SRC=$(LINUX_SERVICE_DST)/$(LINUX_SERVICE_NAME) LANTERND_DST=/usr/sbin/$(LINUX_SERVICE_NAME) \
nfpm package -f $(LINUX_PKG_ROOT)/nfpm.yaml -p rpm -t $(LINUX_INSTALLER_RPM)
VERSION=$(APP_VERSION) SYSTEMD_UNIT_SRC=$(LINUX_SYSTEMD_UNIT_DST) \
nfpm package -f $(LINUX_PKG_ROOT)/nfpm.yaml -p rpm -t $(LINUX_INSTALLER_RPM); \
VERSION=$(APP_VERSION) GOARCH=$(LINUX_TARGET_ARCH) LINUX_BUNDLE_SRC="$$BUNDLE_DIR/" SYSTEMD_UNIT_SRC=$(LINUX_SYSTEMD_UNIT_DST) \
LANTERND_SRC=$(LINUX_SERVICE_DST)/$(LINUX_SERVICE_NAME) LANTERND_DST=/usr/bin/$(LINUX_SERVICE_NAME) \
nfpm package -f $(LINUX_PKG_ROOT)/nfpm.yaml -p archlinux -t $(LINUX_INSTALLER_ARCH)
nfpm package -f $(LINUX_PKG_ROOT)/nfpm.yaml -p archlinux -t $(LINUX_INSTALLER_ARCH)

.PHONY: verify-linux-package
verify-linux-package:
Expand Down
Loading
Loading