diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0fefc95..c326204 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -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 diff --git a/assets/installer/distribution.xml b/assets/installer/distribution.xml new file mode 100644 index 0000000..8eb1892 --- /dev/null +++ b/assets/installer/distribution.xml @@ -0,0 +1,17 @@ + + + MkPFS __ART_VERSION__ + + + + + + + + + + #mkpfs-component.pkg + + + #mkpfs-component.pkg + diff --git a/assets/installer/welcome.rtf b/assets/installer/welcome.rtf new file mode 100644 index 0000000..ba8b26d --- /dev/null +++ b/assets/installer/welcome.rtf @@ -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.} \ No newline at end of file