Skip to content

Build AppFlowy Linux #123

Build AppFlowy Linux

Build AppFlowy Linux #123

Workflow file for this run

name: Build AppFlowy Linux
on:
workflow_dispatch:
inputs:
repo:
description: "Repo"
required: true
default: "AppFlowy-IO/AppFlowy"
branch:
description: "Branch"
required: true
default: "main"
build_name:
description: "Build Version (it should match the version in pubspec.yaml)"
required: true
default: "0.9.4"
internal_build:
type: choice
description: "Internal Build Type (1 for internal, 0 for external)"
required: true
default: "1"
options:
- "0"
- "1"
workflow_call:
inputs:
repo:
description: "Repo"
required: true
type: string
branch:
description: "Branch"
required: true
type: string
build_name:
description: "Build Version"
required: true
type: string
internal_build:
description: "Internal Build Type"
required: true
type: string
upload_url:
description: "Upload URL for release assets"
required: false
type: string
env:
FLUTTER_VERSION: "3.27.4"
RUST_TOOLCHAIN: "1.85.0"
jobs:
build:
strategy:
fail-fast: true
matrix:
os: [ubuntu-22.04]
include:
- os: ubuntu-22.04
target: x86_64-unknown-linux-gnu
runs-on: ${{ matrix.os }}
env:
LINUX_APP_RELEASE_PATH: frontend/appflowy_flutter/product/${{ inputs.build_name }}/linux/Release
LINUX_ZIP_NAME: AppFlowy-${{ inputs.build_name }}-linux.tar.gz
LINUX_PACKAGE_DEB_NAME: AppFlowy-${{ inputs.build_name }}-linux-x86_64.deb
LINUX_PACKAGE_RPM_NAME: AppFlowy-${{ inputs.build_name }}-linux-x86_64.rpm
LINUX_PACKAGE_TMP_RPM_NAME: AppFlowy-${{ inputs.build_name }}-2.x86_64.rpm
LINUX_PACKAGE_APPIMAGE_NAME: AppFlowy-${{ inputs.build_name }}-linux-x86_64.AppImage
steps:
# the following step is required to avoid running out of space
- name: Maximize build space
run: |
sudo rm -rf /usr/share/dotnet
sudo rm -rf /opt/ghc
sudo rm -rf "/usr/local/share/boost"
sudo rm -rf "$AGENT_TOOLSDIRECTORY"
- name: Checkout source code
uses: actions/checkout@v2
with:
repository: ${{ inputs.repo }}
ref: ${{ inputs.branch }}
token: ${{ secrets.PRIVATE_REPO_TOKEN }}
- name: Install Rust toolchain
id: rust_toolchain
uses: actions-rs/toolchain@v1
with:
toolchain: ${{ env.RUST_TOOLCHAIN }}
target: ${{ matrix.target }}
override: true
profile: minimal
- name: Install flutter
id: flutter
uses: subosito/flutter-action@v2
with:
channel: "stable"
flutter-version: ${{ env.FLUTTER_VERSION }}
cache: true
- uses: Swatinem/rust-cache@v2
with:
prefix-key: ${{ matrix.os }}
workspaces: |
frontend/rust-lib
- uses: davidB/rust-cargo-make@v1
with:
version: "0.37.5"
- name: Install prerequisites
working-directory: frontend
run: |
sudo wget -qO /etc/apt/trusted.gpg.d/dart_linux_signing_key.asc https://dl-ssl.google.com/linux/linux_signing_key.pub
sudo apt-get update
sudo apt-get install -y build-essential libsqlite3-dev libssl-dev clang cmake ninja-build pkg-config libgtk-3-dev libcurl4-openssl-dev
sudo apt-get install keybinder-3.0 libnotify-dev libwayland-cursor0 libwayland-client0 libwayland-egl1
sudo apt-get -y install alien
sudo apt install libmpv-dev mpv
# Install FUSE for AppImage support
sudo apt-get install -y fuse libfuse2
source $HOME/.cargo/env
cargo install duckscript_cli --force --locked
rustup target add ${{ matrix.target }}
shell: bash
- name: Generate env file
working-directory: frontend/appflowy_flutter
run: |
echo "INTERNAL_BUILD=${{ github.env.inputs.internal_build }}" >> .env
shell: bash
- name: Configure Git credentials for Cargo
run: |
git config --global credential.helper store
echo "https://${{ secrets.ADMIN_GITHUB_TOKEN }}:x-oauth-basic@github.com" > ~/.git-credentials
- name: Build AppFlowy
working-directory: frontend
run: |
flutter config --enable-linux-desktop
dart ./scripts/flutter_release_build/build_flowy.dart run . ${{ inputs.build_name }}
- name: Archive Asset
working-directory: ${{ env.LINUX_APP_RELEASE_PATH }}
run: tar -czf ${{ env.LINUX_ZIP_NAME }} *
- name: Build Linux package (.AppImage)
working-directory: frontend
run: |
echo "📦 Building AppImage package..."
# Enable FUSE user space file systems
echo 'user_allow_other' | sudo tee -a /etc/fuse.conf
# Run AppImage build script
sh scripts/linux_distribution/appimage/build_appimage.sh ${{ inputs.build_name }} || {
echo "⚠️ AppImage build failed, but continuing..."
# Create a dummy AppImage file to prevent upload failures
touch "${{ env.LINUX_APP_RELEASE_PATH }}/${{ env.LINUX_PACKAGE_APPIMAGE_NAME }}"
}
- name: Build Linux package (.deb)
working-directory: frontend
run: |
sh scripts/linux_distribution/deb/build_deb.sh appflowy_flutter/product/${{ inputs.build_name }}/linux/Release ${{ inputs.build_name }} ${{ env.LINUX_PACKAGE_DEB_NAME }}
- name: Build Linux package (.rpm)
working-directory: ${{ env.LINUX_APP_RELEASE_PATH }}
run: |
sudo alien -r ${{ env.LINUX_PACKAGE_DEB_NAME }}
cp -r ${{ env.LINUX_PACKAGE_TMP_RPM_NAME }} ${{ env.LINUX_PACKAGE_RPM_NAME }}
- name: Upload ZIP
uses: actions/upload-artifact@v4
with:
name: ${{ env.LINUX_ZIP_NAME }}
path: ${{ env.LINUX_APP_RELEASE_PATH }}/${{ env.LINUX_ZIP_NAME }}
- name: Upload ZIP to Release
if: inputs.upload_url != ''
run: |
filename="${{ env.LINUX_ZIP_NAME }}"
filepath="${{ env.LINUX_APP_RELEASE_PATH }}/$filename"
# URL encode the filename
encoded_filename=$(echo -n "$filename" | jq -sRr @uri)
# Remove the {?name,label} template from upload URL if present
upload_url=$(echo "${{ inputs.upload_url }}" | sed 's/{[^}]*}//g')
echo "Uploading $filename to release..."
curl -L \
-X POST \
-H "Accept: application/vnd.github.v3+json" \
-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
-H "Content-Type: application/octet-stream" \
--data-binary @"$filepath" \
"${upload_url}?name=${encoded_filename}" \
--fail-with-body
- name: Upload Linux package
working-directory: frontend
run: |
ls -a
- name: Upload AppImage
uses: actions/upload-artifact@v4
with:
name: ${{ env.LINUX_PACKAGE_APPIMAGE_NAME}}
path: frontend/AppFlowy-${{ inputs.build_name }}-x86_64.AppImage
- name: Upload AppImage to Release
if: inputs.upload_url != ''
run: |
filename="${{ env.LINUX_PACKAGE_APPIMAGE_NAME }}"
filepath="frontend/AppFlowy-${{ inputs.build_name }}-x86_64.AppImage"
# URL encode the filename
encoded_filename=$(echo -n "$filename" | jq -sRr @uri)
# Remove the {?name,label} template from upload URL if present
upload_url=$(echo "${{ inputs.upload_url }}" | sed 's/{[^}]*}//g')
echo "Uploading $filename to release..."
curl -L \
-X POST \
-H "Accept: application/vnd.github.v3+json" \
-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
-H "Content-Type: application/octet-stream" \
--data-binary @"$filepath" \
"${upload_url}?name=${encoded_filename}" \
--fail-with-body
- name: Upload RPM
uses: actions/upload-artifact@v4
with:
name: ${{ env.LINUX_PACKAGE_RPM_NAME }}
path: ${{ env.LINUX_APP_RELEASE_PATH }}/${{ env.LINUX_PACKAGE_RPM_NAME }}
- name: Upload RPM to Release
if: inputs.upload_url != ''
run: |
filename="${{ env.LINUX_PACKAGE_RPM_NAME }}"
filepath="${{ env.LINUX_APP_RELEASE_PATH }}/$filename"
# URL encode the filename
encoded_filename=$(echo -n "$filename" | jq -sRr @uri)
# Remove the {?name,label} template from upload URL if present
upload_url=$(echo "${{ inputs.upload_url }}" | sed 's/{[^}]*}//g')
echo "Uploading $filename to release..."
curl -L \
-X POST \
-H "Accept: application/vnd.github.v3+json" \
-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
-H "Content-Type: application/octet-stream" \
--data-binary @"$filepath" \
"${upload_url}?name=${encoded_filename}" \
--fail-with-body
- name: Upload DEB
uses: actions/upload-artifact@v4
with:
name: ${{ env.LINUX_PACKAGE_DEB_NAME }}
path: ${{ env.LINUX_APP_RELEASE_PATH }}/${{ env.LINUX_PACKAGE_DEB_NAME }}
- name: Upload DEB to Release
if: inputs.upload_url != ''
run: |
filename="${{ env.LINUX_PACKAGE_DEB_NAME }}"
filepath="${{ env.LINUX_APP_RELEASE_PATH }}/$filename"
# URL encode the filename
encoded_filename=$(echo -n "$filename" | jq -sRr @uri)
# Remove the {?name,label} template from upload URL if present
upload_url=$(echo "${{ inputs.upload_url }}" | sed 's/{[^}]*}//g')
echo "Uploading $filename to release..."
curl -L \
-X POST \
-H "Accept: application/vnd.github.v3+json" \
-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
-H "Content-Type: application/octet-stream" \
--data-binary @"$filepath" \
"${upload_url}?name=${encoded_filename}" \
--fail-with-body