Skip to content
Closed
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
89 changes: 86 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -209,16 +209,99 @@ jobs:
chmod +x "dist/MkPFS.app/Contents/MacOS/$exe_name" || true
fi
fi
# create component package then product package so installer shows proper title/version
# sanitize ART_VERSION for filename use

# Ensure the generated .icns is embedded in the app bundle and Info.plist points to it
if [ -f "dist/MkPFS.icns" ]; then
mkdir -p dist/MkPFS.app/Contents/Resources || true
cp -f "dist/MkPFS.icns" "dist/MkPFS.app/Contents/Resources/MkPFS.icns" || true
/usr/libexec/PlistBuddy -c "Set :CFBundleIconFile \"MkPFS.icns\"" "$PLIST" || /usr/libexec/PlistBuddy -c "Add :CFBundleIconFile string \"MkPFS.icns\"" "$PLIST" || true
fi

# create a simple postinstall script that writes a VERSION file into the app bundle
mkdir -p dist/installer-scripts || true
cat > dist/installer-scripts/postinstall <<'POST'
#!/bin/bash
set -e
APP="/Applications/MkPFS.app"
if [ -d "$APP" ]; then
RES="$APP/Contents/Resources"
mkdir -p "$RES"
echo "MkPFS ${ART_VERSION}" > "$RES/VERSION.txt"
chown root:wheel "$RES/VERSION.txt" || true
chmod 644 "$RES/VERSION.txt" || true
fi
exit 0
POST
chmod +x dist/installer-scripts/postinstall || true

# create installer resources (welcome, background) and use manifest from assets
mkdir -p dist/installer-resources || true
# create installer resources directory
mkdir -p dist/installer-resources || true

# Copy welcome.rtf from assets (inject ART_VERSION)
if [ -f assets/installer/welcome.rtf ]; then
sed "s/__ART_VERSION__/${ART_VERSION//\//\/}/g" assets/installer/welcome.rtf > dist/installer-resources/welcome.rtf || cp assets/installer/welcome.rtf dist/installer-resources/welcome.rtf || true
fi

# copy distribution manifest from assets and substitute ART_VERSION placeholder
if [ -f assets/installer/distribution.xml ]; then
sed "s/__ART_VERSION__/${ART_VERSION//\//\/}/g" assets/installer/distribution.xml > dist/installer-resources/distribution.xml || cp assets/installer/distribution.xml dist/installer-resources/distribution.xml || true
fi

# create component package (the raw pkg that installs the .app)
ART_FILE_SAFE=$(echo "$ART_VERSION" | tr ' ' '_' | tr -d '()')
pkgbuild \
--install-location /Applications \
--component "dist/MkPFS.app" \
--version "${ART_VERSION}" \
--identifier "com.psbrew.mkpfs" \
--scripts dist/installer-scripts \
dist/mkpfs-component.pkg
productbuild --identifier com.psbrew.mkpfs --version "${ART_VERSION}" --package dist/mkpfs-component.pkg "dist/mkpfs-${ART_FILE_SAFE}-macos-${ARCH}.pkg" || cp dist/mkpfs-component.pkg "dist/mkpfs-${ART_FILE_SAFE}-macos-${ARCH}.pkg"

# copy the component package into the distribution resources so productbuild can find it by #mkpfs-component.pkg
cp -f dist/mkpfs-component.pkg dist/installer-resources/mkpfs-component.pkg || true

# Diagnostic: show installer resources and synthesized distribution to help debug "no software to install" errors
echo "--- dist/installer-resources listing ---"
ls -la dist/installer-resources || true
echo "--- distribution.xml ---"
cat dist/installer-resources/distribution.xml || true
echo "--- Attempting productbuild --synthesize (diagnostic) ---"
/usr/bin/productbuild --synthesize --package dist/installer-resources/mkpfs-component.pkg dist/installer-resources/synth_distribution.xml || true
echo "--- synthesized distribution (if produced) ---"
cat dist/installer-resources/synth_distribution.xml || true

# build product package using the Distribution XML and the resources directory so the installer UI is customized
# Use --package-path to ensure productbuild can locate and embed the component package from our resources folder
productbuild --distribution dist/installer-resources/distribution.xml --package-path dist/installer-resources --resources dist/installer-resources "dist/mkpfs-${ART_FILE_SAFE}-macos-${ARCH}.pkg"

# Diagnostic: show the produced product and its size, then attempt to expand it to verify it contains packages
echo "--- dist listing (post-productbuild) ---"
ls -la dist || true
echo "--- produced product file size ---"
stat -f "%N %z bytes" "dist/mkpfs-${ART_FILE_SAFE}-macos-${ARCH}.pkg" || ls -la "dist/mkpfs-${ART_FILE_SAFE}-macos-${ARCH}.pkg" || true
echo "--- du summary ---"
du -sh dist/* || true

# Try to expand the product package to inspect contents (diagnostic)
TMP_EXPAND_DIR=$(mktemp -d /tmp/mkpfs-expand.XXXX)
echo "Expanding product to $TMP_EXPAND_DIR"
if /usr/bin/pkgutil --expand-full "dist/mkpfs-${ART_FILE_SAFE}-macos-${ARCH}.pkg" "$TMP_EXPAND_DIR"; then
echo "--- expanded product listing ---"
ls -la "$TMP_EXPAND_DIR" || true
else
echo "pkgutil --expand-full failed or product is not expandable" || true
fi

# Fail fast if produced product looks suspiciously small (< 100KB)
PROD_SIZE=$(stat -f "%z" "dist/mkpfs-${ART_FILE_SAFE}-macos-${ARCH}.pkg" 2>/dev/null || echo 0)
echo "produced product size: $PROD_SIZE"
if [ "$PROD_SIZE" -lt 102400 ]; then
echo "ERROR: produced product pkg is unexpectedly small ($PROD_SIZE bytes). Aborting upload." >&2
exit 1
fi

rm -f dist/mkpfs-component.pkg || true

- name: Build Linux onefile GUI
Expand Down
17 changes: 17 additions & 0 deletions assets/installer/distribution.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<installer-gui-script minSpecVersion="1">
<title>MkPFS __ART_VERSION__</title>
<welcome file="welcome.rtf"/>
<choices-outline>
<line choice="default">
<line choice="com.psbrew.mkpfs"/>
</line>
</choices-outline>
<!-- Choice id must match pkg-ref id so productbuild marks it visible correctly -->
<choice id="com.psbrew.mkpfs" title="MkPFS" visible="true">
<!-- Use an anchor reference so productbuild embeds the package from the resources directory -->
<pkg-ref id="com.psbrew.mkpfs">#mkpfs-component.pkg</pkg-ref>
</choice>
<!-- Point package reference to the component file placed in the resources directory -->
<pkg-ref id="com.psbrew.mkpfs" version="__ART_VERSION__" auth="root">#mkpfs-component.pkg</pkg-ref>
</installer-gui-script>
18 changes: 18 additions & 0 deletions assets/installer/welcome.rtf
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{\rtf1\ansi\ansicpg1252\cocoartf2870
\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fswiss\fcharset0 Helvetica-Bold;\f1\fswiss\fcharset0 Helvetica;}
{\colortbl;\red255\green255\blue255;}
{\*\expandedcolortbl;;}
\paperw11900\paperh16840\vieww12000\viewh15840\viewkind0
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0

\f0\b\fs36 \cf0 MkPFS
\fs24 __ART_VERSION__.
\f1\b0 \
\
\pard\pardeftab720\partightenfactor0
\cf0 MkPFS is a tool and Python library for building, verifying, inspecting, browsing, and extracting PFS disk images. It works with common image naming conventions such as .ffpfs, .ffpfsc, .pfs, .dat, .exfat, and .bin.\
\pard\pardeftab720\partightenfactor0
\cf0 \
For source and updates: {\field{\*\fldinst{HYPERLINK "https://github.com/psbrew/mkpfs"}}{\fldrslt https://github.com/psbrew/mkpfs}}\
\
Click Continue to install MkPFS.}
Loading