Skip to content

Commit 5b51698

Browse files
authored
chore: add appimage build (#2549)
1 parent 833663f commit 5b51698

File tree

6 files changed

+427
-3
lines changed

6 files changed

+427
-3
lines changed
Lines changed: 255 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,255 @@
1+
# GitHub Actions workflow for creating AppImage builds of GeoDa
2+
# This workflow embeds all dependencies (libgdal, etc.) inside the AppImage
3+
# making it larger but fully portable across Linux distributions
4+
5+
name: AppImage builds
6+
7+
# Controls when the action will run.
8+
on:
9+
# Triggers the workflow on push only for the master branch
10+
push:
11+
branches: [master]
12+
tags: ['v*']
13+
paths-ignore:
14+
- '**/README.md'
15+
pull_request:
16+
branches: [master]
17+
paths-ignore:
18+
- '**/README.md'
19+
20+
# Allows you to run this workflow manually from the Actions tab
21+
workflow_dispatch:
22+
23+
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
24+
jobs:
25+
# This workflow contains a single job called "appimage_build"
26+
appimage_build:
27+
# The type of runner that the job will run on
28+
runs-on: ubuntu-22.04
29+
if: ${{ !contains(github.event.head_commit.message, '[ci skip]') && !contains(github.event.head_commit.message, '[skip ci]') }}
30+
31+
env:
32+
GEODA_VER: '1.22.0'
33+
TARGET_OS: 'jammy'
34+
# Use dynamic linking - AppImage tools will bundle libraries
35+
# for nobel: ldflags: '-lgdal -lcurl -L/usr/lib/x86_64-linux-gnu -lz -lwebkit2gtk-4.1 -lEGL -ljavascriptcoregtk-4.1'
36+
EXTRA_GEODA_LD_FLAGS: '-lgdal -lcurl -L/usr/lib/x86_64-linux-gnu -lz -lwebkit2gtk-4.0 -lEGL -ljavascriptcoregtk-4.0'
37+
38+
# Steps represent a sequence of tasks that will be executed as part of the job
39+
steps:
40+
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
41+
- uses: actions/checkout@v4
42+
43+
- name: Prepare build environment
44+
run: |
45+
chmod +x BuildTools/ubuntu/create_deps.sh
46+
chmod +x BuildTools/ubuntu/install.sh
47+
echo ${{ env.TARGET_OS }}
48+
# Install AppImage tools
49+
export DEBIAN_FRONTEND=noninteractive
50+
sudo apt-get update -y
51+
sudo apt-get install -y fuse libfuse2
52+
# Download AppImageTools with retry logic
53+
wget -O appimagetool-x86_64.AppImage https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage || \
54+
wget -O appimagetool-x86_64.AppImage https://github.com/AppImage/AppImageKit/releases/download/13/appimagetool-x86_64.AppImage
55+
chmod +x appimagetool-x86_64.AppImage
56+
# Download linuxdeploy for easier AppImage creation
57+
wget -O linuxdeploy-x86_64.AppImage https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage || \
58+
wget -O linuxdeploy-x86_64.AppImage https://github.com/linuxdeploy/linuxdeploy/releases/download/1-alpha-20220822-1/linuxdeploy-x86_64.AppImage
59+
chmod +x linuxdeploy-x86_64.AppImage
60+
# Download for geoda dependencies
61+
sudo apt-get install -y ca-certificates libgnutls30
62+
echo '-k' > ~/.curlrc
63+
sudo apt-get install -y libpq-dev
64+
sudo apt-get install -y gdal-bin
65+
sudo apt-get install -y libgdal-dev
66+
sudo apt-get install -y unzip cmake dh-autoreconf libgtk-3-dev libgl1-mesa-dev libglu1-mesa-dev
67+
export OS=${{ env.TARGET_OS }}
68+
if [ $OS = 'jammy' ] ; then
69+
sudo apt-get install -y libwebkit2gtk-4.0-dev
70+
elif [ $OS = 'focal' ] ; then
71+
sudo apt-get install -y libwebkit2gtk-4.0-dev
72+
elif [ $OS = 'noble' ] ; then
73+
sudo apt-get install -y libgtk-4-dev libwebkit2gtk-4.1-dev
74+
else
75+
sudo apt-get install -y libwebkitgtk-3.0-dev
76+
fi
77+
78+
- uses: actions/cache@v4
79+
id: cache
80+
with:
81+
path: |
82+
BuildTools/ubuntu/libraries
83+
BuildTools/ubuntu/temp
84+
key: ${{ runner.os }}-${{ env.TARGET_OS }}-appimage-deps-cache-${{ hashFiles('BuildTools/ubuntu/create_deps.sh') }}
85+
86+
# Create Deps - reuse create_deps.sh (no modifications needed)
87+
- if: steps.cache.outputs.cache-hit != 'true'
88+
name: Create Dependencies
89+
run: |
90+
export WORK_DIR=$PWD
91+
export OS=${{ env.TARGET_OS }}
92+
export VER=${{ env.GEODA_VER }}
93+
export APT="sudo apt-get"
94+
cd BuildTools/ubuntu
95+
./create_deps.sh
96+
97+
# Build GeoDa - reuse install.sh (no modifications needed)
98+
- name: Build GeoDa
99+
run: |
100+
mkdir -p o
101+
chmod 755 o
102+
export WORK_DIR=$PWD
103+
export OS=${{ env.TARGET_OS }}
104+
export VER=${{ env.GEODA_VER }}
105+
export APT="sudo apt-get"
106+
export EXTRA_GEODA_LD_FLAGS='${{ env.EXTRA_GEODA_LD_FLAGS }}'
107+
cd BuildTools/ubuntu
108+
./install.sh
109+
110+
# Create AppImage
111+
- name: Create AppImage
112+
run: |
113+
export GEODA_VER=${{ env.GEODA_VER }}
114+
115+
echo "Creating AppImage for GeoDa version $GEODA_VER"
116+
117+
# Verify GeoDa executable exists
118+
if [ ! -f "BuildTools/ubuntu/build/GeoDa" ]; then
119+
echo "ERROR: GeoDa executable not found!"
120+
exit 1
121+
fi
122+
echo "GeoDa executable found: $(ls -la BuildTools/ubuntu/build/GeoDa)"
123+
124+
# Create AppDir structure
125+
mkdir -p GeoDa.AppDir/usr/bin
126+
mkdir -p GeoDa.AppDir/usr/lib
127+
mkdir -p GeoDa.AppDir/usr/share/applications
128+
mkdir -p GeoDa.AppDir/usr/share/icons/hicolor/128x128/apps
129+
130+
# Copy GeoDa executable
131+
cp BuildTools/ubuntu/build/GeoDa GeoDa.AppDir/usr/bin/
132+
chmod +x GeoDa.AppDir/usr/bin/GeoDa
133+
134+
# Bundle template cache.sqlite next to the executable for first-run copy
135+
if [ -f "BuildTools/CommonDistFiles/cache.sqlite" ]; then
136+
cp BuildTools/CommonDistFiles/cache.sqlite GeoDa.AppDir/usr/bin/cache.sqlite
137+
fi
138+
139+
# Bundle geoda_prefs files used by the application
140+
if [ -f "BuildTools/CommonDistFiles/geoda_prefs.sqlite" ]; then
141+
cp BuildTools/CommonDistFiles/geoda_prefs.sqlite GeoDa.AppDir/usr/bin/geoda_prefs.sqlite
142+
fi
143+
if [ -f "BuildTools/CommonDistFiles/geoda_prefs.json" ]; then
144+
cp BuildTools/CommonDistFiles/geoda_prefs.json GeoDa.AppDir/usr/bin/geoda_prefs.json
145+
fi
146+
147+
# Bundle web_plugins (contains samples.sqlite and sample assets)
148+
if [ -d "BuildTools/CommonDistFiles/web_plugins" ]; then
149+
mkdir -p GeoDa.AppDir/usr/bin/web_plugins
150+
cp -a BuildTools/CommonDistFiles/web_plugins/. GeoDa.AppDir/usr/bin/web_plugins/
151+
fi
152+
153+
# Bundle basemap_cache
154+
mkdir -p GeoDa.AppDir/usr/bin/basemap_cache
155+
156+
# Bundle Resources
157+
mkdir -p GeoDa.AppDir/usr/bin/Resources
158+
cp -a rc/*.xrc GeoDa.AppDir/usr/bin/Resources/
159+
160+
# Bundle internationalization
161+
mkdir -p GeoDa.AppDir/usr/bin/lang
162+
cp -rf internationalization/lang/* GeoDa.AppDir/usr/bin/lang/
163+
164+
# Bundle gdaldata
165+
mkdir -p GeoDa.AppDir/usr/bin/gdaldata
166+
cp -a /usr/share/gdal/* GeoDa.AppDir/usr/bin/gdaldata/
167+
168+
# Bundle proj
169+
mkdir -p GeoDa.AppDir/usr/bin/proj
170+
cp -a /usr/share/proj/* GeoDa.AppDir/usr/bin/proj/
171+
172+
# Copy existing desktop file and modify for AppImage
173+
cp BuildTools/ubuntu/package/usr/share/applications/GeoDa.desktop GeoDa.AppDir/usr/share/applications/geoda.desktop
174+
175+
# Modify desktop file for AppImage use
176+
cat > GeoDa.AppDir/usr/share/applications/geoda.desktop << EOF
177+
[Desktop Entry]
178+
Version=1.0
179+
Type=Application
180+
Name=GeoDa
181+
GenericName=GeoDa Software
182+
Comment=GeoDa Software for Geospatial Analysis and Computation
183+
Exec=GeoDa
184+
Icon=geoda
185+
Categories=Education;Geography;
186+
Terminal=false
187+
EOF
188+
189+
# Copy existing GeoDa icon (128x128 should be good for AppImage)
190+
cp BuildTools/ubuntu/package/usr/share/icons/hicolor/128x128/apps/geoda.png GeoDa.AppDir/usr/share/icons/hicolor/128x128/apps/
191+
192+
# Copy desktop file and icon to AppDir root (required for AppImage)
193+
cp GeoDa.AppDir/usr/share/applications/geoda.desktop GeoDa.AppDir/
194+
cp BuildTools/ubuntu/package/usr/share/icons/hicolor/128x128/apps/geoda.png GeoDa.AppDir/
195+
196+
# Pre-bundle libraries built in our deps tree (if present)
197+
if [ -d BuildTools/ubuntu/libraries/lib ]; then
198+
cp -a BuildTools/ubuntu/libraries/lib/* GeoDa.AppDir/usr/lib/ || true
199+
fi
200+
201+
# Create AppRun script
202+
cat > GeoDa.AppDir/AppRun << 'EOF'
203+
#!/bin/bash
204+
HERE="$(dirname "$(readlink -f "${0}")")"
205+
export LD_LIBRARY_PATH="${HERE}/usr/lib:${LD_LIBRARY_PATH}"
206+
export PATH="${HERE}/usr/bin:${PATH}"
207+
# Set GDAL data directory if needed
208+
export GDAL_DATA="${HERE}/usr/share/gdal"
209+
# Set wxWidgets data directory if needed
210+
export WX_DATA_DIR="${HERE}/usr/share/wx"
211+
exec "${HERE}/usr/bin/GeoDa" "$@"
212+
EOF
213+
chmod +x GeoDa.AppDir/AppRun
214+
215+
echo "AppDir structure created, attempting to create AppImage..."
216+
217+
# Show AppDir structure for debugging
218+
echo "AppDir contents:"
219+
find GeoDa.AppDir -type f | head -20
220+
221+
# Use linuxdeploy to bundle dependencies automatically
222+
echo "Using linuxdeploy to bundle dynamic libraries..."
223+
./linuxdeploy-x86_64.AppImage \
224+
--appdir GeoDa.AppDir \
225+
--executable GeoDa.AppDir/usr/bin/GeoDa \
226+
--desktop-file GeoDa.AppDir/usr/share/applications/geoda.desktop \
227+
--icon-file GeoDa.AppDir/usr/share/icons/hicolor/128x128/apps/geoda.png \
228+
--deploy-deps-only=GeoDa.AppDir/usr/bin/GeoDa \
229+
--deploy-deps-only=GeoDa.AppDir/usr/lib \
230+
--output appimage || {
231+
echo "linuxdeploy failed, trying alternative approach with appimagetool directly"
232+
# Try using appimagetool directly if linuxdeploy fails
233+
echo "Using appimagetool directly..."
234+
./appimagetool-x86_64.AppImage GeoDa.AppDir GeoDa-${GEODA_VER}-x86_64.AppImage
235+
}
236+
237+
# Rename the generated AppImage (if created by linuxdeploy)
238+
if [ -f GeoDa-*.AppImage ] && [ ! -f GeoDa-${GEODA_VER}-x86_64.AppImage ]; then
239+
mv GeoDa-*.AppImage GeoDa-${GEODA_VER}-x86_64.AppImage
240+
fi
241+
242+
# Verify the AppImage was created
243+
if [ -f GeoDa-${GEODA_VER}-x86_64.AppImage ]; then
244+
echo "AppImage created successfully: $(ls -la GeoDa-${GEODA_VER}-x86_64.AppImage)"
245+
chmod +x GeoDa-${GEODA_VER}-x86_64.AppImage
246+
else
247+
echo "ERROR: AppImage creation failed!"
248+
exit 1
249+
fi
250+
251+
# Upload artifact
252+
- uses: actions/upload-artifact@v4
253+
with:
254+
name: GeoDa-${{ env.GEODA_VER }}-AppImage
255+
path: ${{ github.workspace }}/GeoDa-${{ env.GEODA_VER }}-x86_64.AppImage

.github/workflows/ubuntu_build.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ jobs:
106106
export APT="sudo apt-get"
107107
cd BuildTools/ubuntu
108108
./install.sh
109+
./create_deb.sh $OS $VER
109110
110111
# Upload artifact
111112
- uses: actions/upload-artifact@v4

0 commit comments

Comments
 (0)