Skip to content

Build for Linux

Build for Linux #60

Workflow file for this run

name: Build for Linux
on:
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-22.04
steps:
- name: Fail if branch is not master
if: github.ref != 'refs/heads/master'
run: |
echo "This workflow can only be run on master branch to ensure code-signed builds come from merged PRs"
exit 1
- uses: actions/checkout@v4
- name: Install system deps
env:
DEBIAN_FRONTEND: noninteractive
run: |
sudo apt-get update -y
sudo apt-get install -y \
software-properties-common \
autoconf automake build-essential clang cmake execstack fakeroot git \
libc-ares-dev libctemplate-dev libcurl4-openssl-dev libglib2.0-dev \
libicu-dev libsasl2-dev libsasl2-modules libsasl2-modules-gssapi-mit \
libsecret-1-dev libssl-dev libnss3 libnss3-dev libtidy-dev libtool \
libxext-dev libxkbfile-dev libxml2-dev libxtst-dev pkg-config rpm \
uuid-dev xvfb
# Note: dropped g++-5 and libgnome-keyring-dev (not available on 22.04).
# No PPA needed on 22.04 for these packages.
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20' # LTS; change to '22' if you’re ready for current
cache: 'npm' # enables npm cache based on lockfile
- name: Install Dependencies
run: npm ci
working-directory: .
- name: Setup AWS CLI
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1
- name: Lint
run: npm run lint
- name: Build
run: DEBUG=electron-packager npm run build
- name: Sync Artifacts to S3
run: |
aws s3 sync app/dist/ "s3://mailspring-builds/client/$(git rev-parse --short=8 HEAD)/linux" \
--acl public-read \
--exclude "*" --include *.deb --include *.rpm
- name: Upload DEB artifact for testing
uses: actions/upload-artifact@v4
with:
name: mailspring-deb
path: app/dist/*.deb
retention-days: 1
- name: Upload RPM artifact for testing
uses: actions/upload-artifact@v4
with:
name: mailspring-rpm
path: app/dist/*.rpm
retention-days: 1
build-snap:
needs: build
runs-on: ubuntu-22.04
steps:
- name: Fail if branch is not master
if: github.ref != 'refs/heads/master'
run: |
echo "This workflow can only be run on master branch to ensure code-signed builds come from merged PRs"
exit 1
- uses: actions/checkout@v4
- name: Download DEB artifact
uses: actions/download-artifact@v4
with:
name: mailspring-deb
path: app/dist/
- uses: snapcore/action-build@v1
id: build-snap
- uses: snapcore/action-publish@v1
env:
SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAPCRAFT_STORE_CREDENTIALS }}
with:
snap: ${{ steps.build-snap.outputs.snap }}
release: edge
test-ubuntu:
needs: build
runs-on: ubuntu-22.04
strategy:
matrix:
ubuntu_version: ['22.04', '24.04', '25.04']
steps:
- name: Download DEB artifact
uses: actions/download-artifact@v4
with:
name: mailspring-deb
- name: Test installation on Ubuntu ${{ matrix.ubuntu_version }}
run: |
docker run --rm -v ${{ github.workspace }}:/workspace ubuntu:${{ matrix.ubuntu_version }} bash -c "
set -e
echo '=== Testing Mailspring installation on Ubuntu ${{ matrix.ubuntu_version }} ==='
# Install the DEB package (this will auto-install dependencies)
cd /workspace
export DEBIAN_FRONTEND=noninteractive
apt-get update
# First try to install the .deb which will fail with dependency errors
dpkg -i *.deb || true
# Install the missing dependencies (automatically resolves from package metadata)
apt-get install -f -y
# Install xvfb for virtual display (needed for tests, not a package dependency)
apt-get install -y xvfb
# Verify installation succeeded
dpkg -l | grep mailspring || (echo '✗ Mailspring package not installed' && exit 1)
# Verify the binary exists and is executable
which mailspring || (echo '✗ mailspring binary not found in PATH' && exit 1)
# List installed files
echo 'Installed files:'
dpkg -L mailspring | head -20
# Run mailspring --version with virtual display (use --no-sandbox for Docker)
echo 'Running mailspring --version...'
xvfb-run -a mailspring --version --no-sandbox > /tmp/version.txt 2>&1 || true
cat /tmp/version.txt
# Verify version command succeeded (output should contain a version number)
if grep -qE '[0-9]+\.[0-9]+\.[0-9]+' /tmp/version.txt; then
echo '✓ mailspring --version passed on Ubuntu ${{ matrix.ubuntu_version }}'
else
echo '✗ mailspring --version failed on Ubuntu ${{ matrix.ubuntu_version }}'
exit 1
fi
# Verify mailsync binary exists (check multiple locations)
if [ -f /usr/share/mailspring/mailsync ]; then
echo 'Found mailsync binary at /usr/share/mailspring/mailsync'
MAILSYNC_PATH=/usr/share/mailspring/mailsync
elif [ -f /usr/share/mailspring/mailsync.bin ]; then
echo 'Found mailsync binary at /usr/share/mailspring/mailsync.bin'
MAILSYNC_PATH=/usr/share/mailspring/mailsync.bin
elif [ -f /usr/share/mailspring/resources/app.asar.unpacked/mailsync ]; then
echo 'Found mailsync binary at /usr/share/mailspring/resources/app.asar.unpacked/mailsync'
MAILSYNC_PATH=/usr/share/mailspring/resources/app.asar.unpacked/mailsync
elif [ -f /usr/share/mailspring/resources/app.asar.unpacked/mailsync.bin ]; then
echo 'Found mailsync binary at /usr/share/mailspring/resources/app.asar.unpacked/mailsync.bin'
MAILSYNC_PATH=/usr/share/mailspring/resources/app.asar.unpacked/mailsync.bin
else
echo '✗ mailsync binary not found'
echo 'Files in /usr/share/mailspring/:'
ls -la /usr/share/mailspring/ | head -30
exit 1
fi
# Run mailsync --help (no X11 required for mailsync)
echo 'Running mailsync --help...'
\$MAILSYNC_PATH --help > /tmp/mailsync-help.txt 2>&1 || true
cat /tmp/mailsync-help.txt
# Verify mailsync help output (should contain usage info and no errors)
if grep -qiE 'usage|help|mailsync|options|--mode' /tmp/mailsync-help.txt; then
if grep -qi 'error' /tmp/mailsync-help.txt; then
echo '✗ mailsync --help contains errors on Ubuntu ${{ matrix.ubuntu_version }}'
exit 1
fi
echo '✓ mailsync --help passed on Ubuntu ${{ matrix.ubuntu_version }}'
else
echo '✗ mailsync --help failed on Ubuntu ${{ matrix.ubuntu_version }}'
exit 1
fi
echo '✓ Mailspring installation test passed on Ubuntu ${{ matrix.ubuntu_version }}'
"
test-fedora:
needs: build
runs-on: ubuntu-22.04
strategy:
matrix:
fedora_version: ['40', '41', '43']
steps:
- name: Download RPM artifact
uses: actions/download-artifact@v4
with:
name: mailspring-rpm
- name: Test installation on Fedora ${{ matrix.fedora_version }}
run: |
docker run --rm -v ${{ github.workspace }}:/workspace fedora:${{ matrix.fedora_version }} bash -c "
set -e
echo '=== Testing Mailspring installation on Fedora ${{ matrix.fedora_version }} ==='
# Install dependencies first
cd /workspace
dnf install -y xorg-x11-server-Xvfb which alsa-lib
# Install the RPM package (dnf will auto-resolve dependencies)
dnf install -y *.rpm
# Verify installation succeeded
rpm -q mailspring || (echo '✗ Mailspring package not installed' && exit 1)
# Verify the binary exists and is executable
which mailspring || (echo '✗ mailspring binary not found in PATH' && exit 1)
# List installed files
echo 'Installed files:'
rpm -ql mailspring | head -20
# Run mailspring --version with virtual display (use --no-sandbox for Docker)
echo 'Running mailspring --version...'
xvfb-run -a mailspring --version --no-sandbox > /tmp/version.txt 2>&1 || true
cat /tmp/version.txt
# Verify version command succeeded (output should contain a version number)
if grep -qE '[0-9]+\.[0-9]+\.[0-9]+' /tmp/version.txt; then
echo '✓ mailspring --version passed on Fedora ${{ matrix.fedora_version }}'
else
echo '✗ mailspring --version failed on Fedora ${{ matrix.fedora_version }}'
exit 1
fi
# Verify mailsync binary exists (check multiple possible locations and names)
if [ -f /usr/share/mailspring/mailsync ]; then
echo 'Found mailsync binary at /usr/share/mailspring/mailsync'
MAILSYNC_PATH=/usr/share/mailspring/mailsync
elif [ -f /usr/share/mailspring/mailsync.bin ]; then
echo 'Found mailsync binary at /usr/share/mailspring/mailsync.bin'
MAILSYNC_PATH=/usr/share/mailspring/mailsync.bin
elif [ -f /usr/share/mailspring/resources/app.asar.unpacked/mailsync ]; then
echo 'Found mailsync binary at /usr/share/mailspring/resources/app.asar.unpacked/mailsync'
MAILSYNC_PATH=/usr/share/mailspring/resources/app.asar.unpacked/mailsync
elif [ -f /usr/share/mailspring/resources/app.asar.unpacked/mailsync.bin ]; then
echo 'Found mailsync binary at /usr/share/mailspring/resources/app.asar.unpacked/mailsync.bin'
MAILSYNC_PATH=/usr/share/mailspring/resources/app.asar.unpacked/mailsync.bin
elif [ -f /usr/local/share/mailspring/mailsync ]; then
echo 'Found mailsync binary at /usr/local/share/mailspring/mailsync'
MAILSYNC_PATH=/usr/local/share/mailspring/mailsync
elif [ -f /usr/local/share/mailspring/mailsync.bin ]; then
echo 'Found mailsync binary at /usr/local/share/mailspring/mailsync.bin'
MAILSYNC_PATH=/usr/local/share/mailspring/mailsync.bin
else
echo '✗ mailsync binary not found'
echo 'Searching for mailsync in RPM files:'
rpm -ql mailspring | grep -i mailsync || echo 'No mailsync found in package'
echo 'Files in /usr/share/mailspring/:'
ls -la /usr/share/mailspring/ | head -30
exit 1
fi
# Run mailsync --help (no X11 required for mailsync)
echo 'Running mailsync --help...'
\$MAILSYNC_PATH --help > /tmp/mailsync-help.txt 2>&1 || true
cat /tmp/mailsync-help.txt
# Verify mailsync help output (should contain usage info and no errors)
# Note: libcurl version warnings are harmless and expected on Fedora
if grep -qiE 'usage|help|mailsync|options|--mode' /tmp/mailsync-help.txt; then
if grep -qi 'error' /tmp/mailsync-help.txt; then
echo '✗ mailsync --help contains errors on Fedora ${{ matrix.fedora_version }}'
exit 1
fi
echo '✓ mailsync --help passed on Fedora ${{ matrix.fedora_version }}'
else
echo '✗ mailsync --help failed on Fedora ${{ matrix.fedora_version }}'
exit 1
fi
echo '✓ Mailspring installation test passed on Fedora ${{ matrix.fedora_version }}'
"
test-opensuse:
needs: build
runs-on: ubuntu-22.04
steps:
- name: Download RPM artifact
uses: actions/download-artifact@v4
with:
name: mailspring-rpm
- name: Test installation on openSUSE Tumbleweed
run: |
docker run --rm -v ${{ github.workspace }}:/workspace opensuse/tumbleweed bash -c "
set -e
echo '=== Testing Mailspring installation on openSUSE Tumbleweed ==='
# Install dependencies first
cd /workspace
# Note: zypper exit code 107 (ZYPPER_EXIT_INF_RPM_SCRIPT_FAILED) means
# the package installed but an RPM scriptlet failed. This is expected in
# Docker containers where PAM/systemd scriptlets cannot run properly.
zypper --non-interactive install xorg-x11-server-Xvfb xvfb-run which alsa-lib gawk; ZYPPER_EXIT=\$?
if [ \$ZYPPER_EXIT -ne 0 ] && [ \$ZYPPER_EXIT -ne 107 ]; then
echo \"zypper install dependencies failed with exit code \$ZYPPER_EXIT\"
exit 1
fi
# Install the RPM package (zypper will auto-resolve dependencies)
zypper --non-interactive --no-gpg-checks install *.rpm; ZYPPER_EXIT=\$?
if [ \$ZYPPER_EXIT -ne 0 ] && [ \$ZYPPER_EXIT -ne 107 ]; then
echo \"zypper install mailspring failed with exit code \$ZYPPER_EXIT\"
exit 1
fi
# Verify installation succeeded
rpm -q mailspring || (echo '✗ Mailspring package not installed' && exit 1)
# Verify the binary exists and is executable
which mailspring || (echo '✗ mailspring binary not found in PATH' && exit 1)
# List installed files
echo 'Installed files:'
rpm -ql mailspring | head -20
# Run mailspring --version with virtual display (use --no-sandbox for Docker)
echo 'Running mailspring --version...'
xvfb-run -a mailspring --version --no-sandbox > /tmp/version.txt 2>&1 || true
cat /tmp/version.txt
# Verify version command succeeded (output should contain a version number)
if grep -qE '[0-9]+\.[0-9]+\.[0-9]+' /tmp/version.txt; then
echo '✓ mailspring --version passed on openSUSE Tumbleweed'
else
echo '✗ mailspring --version failed on openSUSE Tumbleweed'
exit 1
fi
# Verify mailsync binary exists (check multiple possible locations and names)
if [ -f /usr/share/mailspring/mailsync ]; then
echo 'Found mailsync binary at /usr/share/mailspring/mailsync'
MAILSYNC_PATH=/usr/share/mailspring/mailsync
elif [ -f /usr/share/mailspring/mailsync.bin ]; then
echo 'Found mailsync binary at /usr/share/mailspring/mailsync.bin'
MAILSYNC_PATH=/usr/share/mailspring/mailsync.bin
elif [ -f /usr/share/mailspring/resources/app.asar.unpacked/mailsync ]; then
echo 'Found mailsync binary at /usr/share/mailspring/resources/app.asar.unpacked/mailsync'
MAILSYNC_PATH=/usr/share/mailspring/resources/app.asar.unpacked/mailsync
elif [ -f /usr/share/mailspring/resources/app.asar.unpacked/mailsync.bin ]; then
echo 'Found mailsync binary at /usr/share/mailspring/resources/app.asar.unpacked/mailsync.bin'
MAILSYNC_PATH=/usr/share/mailspring/resources/app.asar.unpacked/mailsync.bin
elif [ -f /usr/local/share/mailspring/mailsync ]; then
echo 'Found mailsync binary at /usr/local/share/mailspring/mailsync'
MAILSYNC_PATH=/usr/local/share/mailspring/mailsync
elif [ -f /usr/local/share/mailspring/mailsync.bin ]; then
echo 'Found mailsync binary at /usr/local/share/mailspring/mailsync.bin'
MAILSYNC_PATH=/usr/local/share/mailspring/mailsync.bin
else
echo '✗ mailsync binary not found'
echo 'Searching for mailsync in RPM files:'
rpm -ql mailspring | grep -i mailsync || echo 'No mailsync found in package'
echo 'Files in /usr/share/mailspring/:'
ls -la /usr/share/mailspring/ | head -30
exit 1
fi
# Run mailsync --help (no X11 required for mailsync)
echo 'Running mailsync --help...'
\$MAILSYNC_PATH --help > /tmp/mailsync-help.txt 2>&1 || true
cat /tmp/mailsync-help.txt
# Verify mailsync help output (should contain usage info and no errors)
if grep -qiE 'usage|help|mailsync|options|--mode' /tmp/mailsync-help.txt; then
if grep -qi 'error' /tmp/mailsync-help.txt; then
echo '✗ mailsync --help contains errors on openSUSE Tumbleweed'
exit 1
fi
echo '✓ mailsync --help passed on openSUSE Tumbleweed'
else
echo '✗ mailsync --help failed on openSUSE Tumbleweed'
exit 1
fi
echo '✓ Mailspring installation test passed on openSUSE Tumbleweed'
"
test-arch:
needs: build
runs-on: ubuntu-22.04
steps:
- name: Download DEB artifact
uses: actions/download-artifact@v4
with:
name: mailspring-deb
- name: Test installation on Arch Linux
run: |
docker run --rm -v ${{ github.workspace }}:/workspace archlinux:latest bash -c "
set -e
echo '=== Testing Mailspring installation on Arch Linux ==='
# Update package database and install required tools and libraries
pacman -Syu --noconfirm
pacman -S --noconfirm xorg-server-xvfb binutils nspr nss gtk3 alsa-lib tidy
# Extract the DEB package manually (ar + tar)
cd /workspace
DEB_FILE=\$(ls *.deb)
echo \"Extracting \$DEB_FILE...\"
# Extract .deb (which is an ar archive)
ar x \"\$DEB_FILE\"
# Extract data tarball to root
tar -xf data.tar.* -C /
# Verify the binary exists and is in PATH
ls -la /usr/bin/mailspring
ls -la /usr/share/mailspring/
# List installed files
echo 'Extracted files:'
find /usr/share/mailspring -type f | head -20
# Run mailspring --version with virtual display (use --no-sandbox for Docker)
echo 'Running mailspring --version...'
xvfb-run -a /usr/bin/mailspring --version --no-sandbox > /tmp/version.txt 2>&1 || true
cat /tmp/version.txt
# Verify version command succeeded (output should contain a version number)
if grep -qE '[0-9]+\.[0-9]+\.[0-9]+' /tmp/version.txt; then
echo '✓ mailspring --version passed on Arch Linux'
else
echo '✗ mailspring --version failed on Arch Linux'
exit 1
fi
# Verify mailsync binary exists (check multiple locations)
if [ -f /usr/share/mailspring/mailsync ]; then
echo 'Found mailsync binary at /usr/share/mailspring/mailsync'
MAILSYNC_PATH=/usr/share/mailspring/mailsync
elif [ -f /usr/share/mailspring/mailsync.bin ]; then
echo 'Found mailsync binary at /usr/share/mailspring/mailsync.bin'
MAILSYNC_PATH=/usr/share/mailspring/mailsync.bin
elif [ -f /usr/share/mailspring/resources/app.asar.unpacked/mailsync ]; then
echo 'Found mailsync binary at /usr/share/mailspring/resources/app.asar.unpacked/mailsync'
MAILSYNC_PATH=/usr/share/mailspring/resources/app.asar.unpacked/mailsync
elif [ -f /usr/share/mailspring/resources/app.asar.unpacked/mailsync.bin ]; then
echo 'Found mailsync binary at /usr/share/mailspring/resources/app.asar.unpacked/mailsync.bin'
MAILSYNC_PATH=/usr/share/mailspring/resources/app.asar.unpacked/mailsync.bin
else
echo '✗ mailsync binary not found'
echo 'Files in /usr/share/mailspring/:'
ls -la /usr/share/mailspring/ | head -30
exit 1
fi
# Run mailsync --help (no X11 required for mailsync)
echo 'Running mailsync --help...'
\$MAILSYNC_PATH --help > /tmp/mailsync-help.txt 2>&1 || true
cat /tmp/mailsync-help.txt
# Verify mailsync help output (should contain usage info and no errors)
if grep -qiE 'usage|help|mailsync|options|--mode' /tmp/mailsync-help.txt; then
if grep -qi 'error' /tmp/mailsync-help.txt; then
echo '✗ mailsync --help contains errors on Arch Linux'
exit 1
fi
echo '✓ mailsync --help passed on Arch Linux'
else
echo '✗ mailsync --help failed on Arch Linux'
exit 1
fi
echo '✓ Mailspring installation test passed on Arch Linux'
"
test-linuxmint:
needs: build
runs-on: ubuntu-22.04
strategy:
matrix:
mint_version: ['22']
steps:
- name: Download DEB artifact
uses: actions/download-artifact@v4
with:
name: mailspring-deb
- name: Test installation on Linux Mint ${{ matrix.mint_version }}
run: |
docker run --rm -v ${{ github.workspace }}:/workspace linuxmintd/mint${{ matrix.mint_version }}-amd64 bash -c "
set -e
echo '=== Testing Mailspring installation on Linux Mint ${{ matrix.mint_version }} ==='
# Install the DEB package using gdebi (what most users use)
# gdebi has stricter dependency checking than apt-get install -f
# and will fail if dependencies reference old package names that
# don't resolve properly (e.g., libgtk-3-0 vs libgtk-3-0t64)
cd /workspace
export DEBIAN_FRONTEND=noninteractive
apt-get update
# Install gdebi and xvfb
apt-get install -y gdebi-core xvfb
# Use gdebi to install - this will fail if dependencies can't be resolved
# gdebi is what users get when they double-click a .deb file
gdebi --non-interactive *.deb
# Verify installation succeeded
dpkg -l | grep mailspring || (echo '✗ Mailspring package not installed' && exit 1)
# Verify the binary exists and is executable
which mailspring || (echo '✗ mailspring binary not found in PATH' && exit 1)
# List installed files
echo 'Installed files:'
dpkg -L mailspring | head -20
# Run mailspring --version with virtual display (use --no-sandbox for Docker)
echo 'Running mailspring --version...'
xvfb-run -a mailspring --version --no-sandbox > /tmp/version.txt 2>&1 || true
cat /tmp/version.txt
# Verify version command succeeded (output should contain a version number)
if grep -qE '[0-9]+\.[0-9]+\.[0-9]+' /tmp/version.txt; then
echo '✓ mailspring --version passed on Linux Mint ${{ matrix.mint_version }}'
else
echo '✗ mailspring --version failed on Linux Mint ${{ matrix.mint_version }}'
exit 1
fi
# Verify mailsync binary exists (check multiple locations)
if [ -f /usr/share/mailspring/mailsync ]; then
echo 'Found mailsync binary at /usr/share/mailspring/mailsync'
MAILSYNC_PATH=/usr/share/mailspring/mailsync
elif [ -f /usr/share/mailspring/mailsync.bin ]; then
echo 'Found mailsync binary at /usr/share/mailspring/mailsync.bin'
MAILSYNC_PATH=/usr/share/mailspring/mailsync.bin
elif [ -f /usr/share/mailspring/resources/app.asar.unpacked/mailsync ]; then
echo 'Found mailsync binary at /usr/share/mailspring/resources/app.asar.unpacked/mailsync'
MAILSYNC_PATH=/usr/share/mailspring/resources/app.asar.unpacked/mailsync
elif [ -f /usr/share/mailspring/resources/app.asar.unpacked/mailsync.bin ]; then
echo 'Found mailsync binary at /usr/share/mailspring/resources/app.asar.unpacked/mailsync.bin'
MAILSYNC_PATH=/usr/share/mailspring/resources/app.asar.unpacked/mailsync.bin
else
echo '✗ mailsync binary not found'
echo 'Files in /usr/share/mailspring/:'
ls -la /usr/share/mailspring/ | head -30
exit 1
fi
# Run mailsync --help (no X11 required for mailsync)
echo 'Running mailsync --help...'
\$MAILSYNC_PATH --help > /tmp/mailsync-help.txt 2>&1 || true
cat /tmp/mailsync-help.txt
# Verify mailsync help output (should contain usage info and no errors)
if grep -qiE 'usage|help|mailsync|options|--mode' /tmp/mailsync-help.txt; then
if grep -qi 'error' /tmp/mailsync-help.txt; then
echo '✗ mailsync --help contains errors on Linux Mint ${{ matrix.mint_version }}'
exit 1
fi
echo '✓ mailsync --help passed on Linux Mint ${{ matrix.mint_version }}'
else
echo '✗ mailsync --help failed on Linux Mint ${{ matrix.mint_version }}'
exit 1
fi
echo '✓ Mailspring installation test passed on Linux Mint ${{ matrix.mint_version }}'
"