Skip to content

Commit 23fba9d

Browse files
Fix AppImage executable (#1069)
AppImage executable now supports all flags that the `pulsar` command supports on other installation methods
1 parent a2c236f commit 23fba9d

File tree

3 files changed

+134
-1
lines changed

3 files changed

+134
-1
lines changed

.cirrus.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ arm_linux_task:
8585
libxss-dev
8686
libasound2-dev
8787
libnss3
88+
wget
8889
xvfb
8990
- gem install dotenv -v '~> 2.8'
9091
- gem install fpm
@@ -100,6 +101,8 @@ arm_linux_task:
100101
- yarn dist || yarn dist
101102
rename_binary_script:
102103
- node script/rename.js "ARM.Linux"
104+
fix_linux_appimage_script:
105+
- ./script/fix-linux-appimage.sh aarch64
103106
binary_artifacts:
104107
path: ./binaries/*
105108
test_script:

.github/workflows/build.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ jobs:
3737
steps:
3838
- name: Install build dependencies - Linux
3939
if: ${{ runner.os == 'Linux' }}
40-
run: apt-get update && apt-get install -y git python3 python3-pip make gcc g++ libx11-dev libxkbfile-dev pkg-config libsecret-1-dev rpm xvfb ffmpeg zstd
40+
run: apt-get update && apt-get install -y git python3 python3-pip make gcc g++ libx11-dev libxkbfile-dev pkg-config libsecret-1-dev rpm xvfb ffmpeg zstd wget squashfs-tools
4141

4242
- name: Checkout the latest code
4343
uses: actions/checkout@v4
@@ -177,6 +177,10 @@ jobs:
177177
if: ${{ runner.os == 'Windows' }}
178178
run: node ./script/rename.js "Windows"
179179

180+
- name: Fix AppImage target - Linux
181+
if: ${{ runner.os == 'Linux' }}
182+
run: ./script/fix-linux-appimage.sh x86_64
183+
180184
- name: Cache Pulsar Binaries - Linux
181185
if: ${{ runner.os == 'Linux' }}
182186
uses: actions/cache/save@v4

script/fix-linux-appimage.sh

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
#!/usr/bin/env bash
2+
3+
# NOTE: This script is a post-build task for the Linux AppImage version of
4+
# Pulsar. It's meant to run in Pulsar's CI and almost certainly won't do
5+
# anything useful if run on your local machine.
6+
7+
# Usage: Takes a single argument for the architecture — either `x86_64` or
8+
# `ARM_64` — and “fixes” an AppImage file as emitted by `electron-builder` so
9+
# that it points to `pulsar.sh` internally and runs _that_ when invoked instead
10+
# of the direct binary.
11+
#
12+
# This is important for a couple of reasons:
13+
#
14+
# 1. Some command-line arguments, like `--wait`, don't work properly unless
15+
# they rely on `pulsar.sh` to do some work for them.
16+
# 2. `pulsar.sh` can intercept the `-p`/`--package` switch (signaling that the
17+
# user wants to run `ppm`) and call it more quickly than Pulsar can.
18+
#
19+
# This is pretty easy to do with an AppImage, but `electron-builder` isn't
20+
# customizable enough for us to make that change without it affecting other
21+
# things. Luckily, AppImage is straightforward enough as a tool that we can
22+
# do it manually.
23+
#
24+
# The workflow here is as follows:
25+
#
26+
# * Extract the AppImage (every AppImage has the ability to do this by itself).
27+
# * Modify the `AppRun` script whose purpose is to invoke the Electron
28+
# executable; modify it to invoke our `pulsar.sh` script instead.
29+
# * Download and extract `appimagetool`.
30+
# * Use it to package everything back into an AppImage at the original location
31+
# on disk.
32+
#
33+
# If you're unsure if this modification has worked, the best way to find out is
34+
# to run
35+
#
36+
# ./Pulsar.AppImage --wait foo.txt
37+
#
38+
# and keep an eye on the terminal window after Pulsar launches. It should not
39+
# return to a new prompt until you close `foo.txt` for editing. If you don't
40+
# get a new prompt after closing `foo.txt`, or if you see logging statements in
41+
# your terminal after launch, then it's almost certain that the AppImage hasn't
42+
# been fixed.
43+
44+
45+
# Fail on first error. None of these steps is prone to random failure, except
46+
# _possibly_ the part where we download `appimagetool`; if that's ever the
47+
# cause of failures, we could spin that off into a separate step that uses
48+
# the `retry` action. Otherwise this script is quite straightforward.
49+
set -e
50+
51+
# Use `appimagetool`’s names for our two processor architectures.
52+
if [[ "${1:x86_64}" == "x86_64" ]]; then
53+
APPIMAGE_ARCH="x86_64"
54+
APPIMAGETOOL_ARCH="x86_64"
55+
else
56+
APPIMAGE_ARCH="aarch64"
57+
APPIMAGETOOL_ARCH="arm_aarch64"
58+
fi
59+
60+
echo "Architecture is: ${APPIMAGE_ARCH}"
61+
62+
cd binaries
63+
PULSAR_APPIMAGE="$(ls *.AppImage | xargs)"
64+
echo "Existing binary is ${PULSAR_APPIMAGE}."
65+
chmod +x "${PULSAR_APPIMAGE}"
66+
67+
echo "Extracting ${PULSAR_APPIMAGE} to Pulsar.AppDir…"
68+
"./${PULSAR_APPIMAGE}" "--appimage-extract"
69+
# Will extract to `squashfs-root`. Let's rename it just for sanity.
70+
mv "squashfs-root" "Pulsar.AppDir"
71+
72+
# Move the `AppImage` to a new filename because we'll be replacing it soon.
73+
mv "${PULSAR_APPIMAGE}" "${PULSAR_APPIMAGE%.AppImage}.old.AppImage"
74+
75+
# `AppRun` is the entry point of an `AppImage`. Ours is generated by
76+
# `electron-builder`. We need to customize it to launch a script rather than
77+
# our executable.
78+
79+
# First we'll copy the existing `AppRun` file to a temporary path.
80+
cd "Pulsar.AppDir"
81+
echo "Moving AppRun to AppRun.old…"
82+
mv AppRun AppRun.old
83+
rm -f AppRun
84+
85+
# Next we'll use `awk` to replace the reference to BIN in `AppRun` so that it
86+
# points to `pulsar.sh` rather than the `pulsar` executable.
87+
echo "Making new AppRun…"
88+
awk '{sub(/BIN=(.*?)/,"BIN=\"$APPDIR/resources/pulsar.sh\""); print}' AppRun.old > AppRun
89+
chmod a+x AppRun
90+
91+
# For sanity's sake, show the new line so we know that this was done properly
92+
# just by inspecting the CI job output. This will help if we ever upgrade
93+
# `electron-builder` and find that this generated line has changed somehow.
94+
echo "Rewrote BIN to read:"
95+
cat AppRun | grep "BIN="
96+
97+
# We don't need the old `AppRun` anymore.
98+
echo "Removing AppRun.old…"
99+
rm -f AppRun.old
100+
101+
cd ../..
102+
103+
# Now that we've made the change, we can use `appimagetool` to bundle
104+
# everything up with the original file name.
105+
echo "Downloading appimagetool…"
106+
wget "https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-${APPIMAGE_ARCH}.AppImage" -O appimagetool
107+
echo "Making appimagetool executable…"
108+
chmod +x appimagetool
109+
110+
# Docker can't run AppImage apps natively, but we can use the
111+
# `--appimage-extract-and-run` option to extract the app to a location on disk
112+
# instead.
113+
#
114+
# It makes us set an `ARCH` environment variable — no idea why, since these are
115+
# thin binaries, but whatever.
116+
echo "Building new AppImage at: binaries/${PULSAR_APPIMAGE} with ARCH value: ${APPIMAGETOOL_ARCH}"
117+
ARCH="${APPIMAGETOOL_ARCH}" ./appimagetool --appimage-extract-and-run "binaries/Pulsar.AppDir" "binaries/${PULSAR_APPIMAGE}"
118+
chmod a+x "binaries/${PULSAR_APPIMAGE}"
119+
echo "…done building AppImage."
120+
121+
# Clean up! Remove the old AppImage and the temporary directory.
122+
echo "Removing temporary Pulsar.AppDir and old AppImage…"
123+
rm -rf "binaries/Pulsar.AppDir"
124+
rm -f "binaries/${PULSAR_APPIMAGE%.AppImage}.old.AppImage"
125+
126+
echo "…done! AppImage is fixed!"

0 commit comments

Comments
 (0)