Skip to content

CD - Release Build

CD - Release Build #82

Workflow file for this run

name: CD - Release Build
on:
workflow_run:
workflows: ["CI - Build and Test"]
types: [completed]
branches: [main]
permissions:
contents: write
actions: read
jobs:
create-release:
name: Create Release
runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.conclusion == 'success' }}
outputs:
version: ${{ steps.version.outputs.version }}
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Generate Version
id: version
run: |
COUNT=$(git rev-list --count HEAD)
echo "version=0.1.${COUNT}" >> $GITHUB_OUTPUT
echo "Release version: v0.1.${COUNT}"
- name: Create GitHub Release
uses: softprops/action-gh-release@v3
with:
tag_name: v${{ steps.version.outputs.version }}
name: Amplitron v${{ steps.version.outputs.version }}
body: |
## Amplitron v${{ steps.version.outputs.version }}
### Downloads
| Platform | File | Type |
|----------|------|------|
| **Windows** 10/11 (64-bit) | `Amplitron-Windows-Setup.exe` | Installer |
| **macOS** 10.15+ | `Amplitron-macOS.dmg` | Disk Image |
| **Linux** x64 | `Amplitron-Linux-x64.tar.gz` | Archive |
| **Android** 8.0+ (arm64 / x86_64) | `Amplitron-Android.apk` | APK (sideload) |
| **iOS** 15.0+ | `Amplitron-iOS.ipa` | Install via [AltStore](https://altstore.io) |
### Installation
**Windows**
1. Run `Amplitron-Windows-Setup.exe`
2. If SmartScreen appears, click **"More info"** → **"Run anyway"**
3. Follow the setup wizard — creates Start Menu & Desktop shortcuts
**macOS**
1. Open `Amplitron-macOS.dmg`, drag Amplitron to Applications
2. **First launch**: Right-click the app → **Open** → click **Open** in the dialog
3. Or run: `xattr -cr /Applications/Amplitron.app` then open normally
**Linux**
1. Extract the archive: `tar -xzf Amplitron-Linux-x64.tar.gz`
2. Run: `cd Amplitron-Linux && ./amplitron.sh`
> ⚠️ **Note**: Windows SmartScreen and macOS Gatekeeper warnings appear because the app is not yet code-signed with a paid certificate. The app is fully open-source — verify the code on GitHub.
**Website**: https://amplitron.sudipmondal.co.in
**Author**: Sudip Mondal (sudmondal2002@gmail.com)
package-windows:
name: Package Windows Installer
needs: create-release
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Download Windows Build
uses: actions/download-artifact@v8
with:
name: windows-build
path: artifacts/windows
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Install NSIS
run: sudo apt-get update && sudo apt-get install -y nsis
- name: Prepare Files
run: |
mkdir -p staging
cp artifacts/windows/Amplitron.exe staging/Amplitron.exe
cp artifacts/windows/*.dll staging/ 2>/dev/null || true
cp README.md staging/
cp -r assets staging/ || true
ls -la staging/
- name: Build Installer
run: |
makensis "-DSRCDIR=$(pwd)/staging" "-DOUTFILE=$(pwd)/Amplitron-Windows-Setup.exe" scripts/installer.nsi
- name: Upload to Release
uses: softprops/action-gh-release@v3
with:
tag_name: v${{ needs.create-release.outputs.version }}
files: Amplitron-Windows-Setup.exe
package-macos:
name: Package macOS DMG
needs: create-release
runs-on: macos-latest
steps:
- uses: actions/checkout@v6
- name: Download macOS Build
uses: actions/download-artifact@v8
with:
name: macos-build
path: artifacts/macos
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Create App Icon (icns)
run: |
mkdir -p icon.iconset
# Rasterize SVG to multiple sizes using sips
for size in 16 32 64 128 256 512; do
sips -z $size $size assets/favicon.ico --out icon.iconset/icon_${size}x${size}.png 2>/dev/null || true
done
# Generate from a 512px PNG as base
sips -s format png -z 512 512 assets/favicon.ico --out /tmp/icon_base.png 2>/dev/null || true
if [ -f /tmp/icon_base.png ]; then
for size in 16 32 64 128 256 512; do
sips -z $size $size /tmp/icon_base.png --out icon.iconset/icon_${size}x${size}.png
double=$((size * 2))
if [ $double -le 1024 ]; then
sips -z $double $double /tmp/icon_base.png --out icon.iconset/icon_${size}x${size}@2x.png
fi
done
iconutil -c icns icon.iconset -o icon.icns 2>/dev/null || true
fi
ls -la icon.icns 2>/dev/null || echo "icns generation failed, will skip icon"
- name: Create App Bundle
run: |
mkdir -p Amplitron.app/Contents/MacOS
mkdir -p Amplitron.app/Contents/Resources
mkdir -p Amplitron.app/Contents/Frameworks
# Copy binary
cp artifacts/macos/Amplitron Amplitron.app/Contents/MacOS/Amplitron
chmod +x Amplitron.app/Contents/MacOS/Amplitron
# Copy ALL bundled dylibs from CI
for dylib in artifacts/macos/*.dylib; do
[ -f "$dylib" ] || continue
libname=$(basename "$dylib")
echo "Copying dylib: $libname"
cp "$dylib" Amplitron.app/Contents/Frameworks/
chmod 644 "Amplitron.app/Contents/Frameworks/$libname"
done
# Rewrite binary rpaths: @executable_path/X -> @executable_path/../Frameworks/X
otool -L Amplitron.app/Contents/MacOS/Amplitron | tail -n +2 | awk '{print $1}' | while read -r lib; do
case "$lib" in
@executable_path/*)
libname=$(basename "$lib")
install_name_tool -change "$lib" "@executable_path/../Frameworks/$libname" Amplitron.app/Contents/MacOS/Amplitron
echo "Rewritten: $lib -> @executable_path/../Frameworks/$libname"
;;
esac
done
# Rewrite inter-dylib references in Frameworks
for fw in Amplitron.app/Contents/Frameworks/*.dylib; do
[ -f "$fw" ] || continue
libname=$(basename "$fw")
install_name_tool -id "@rpath/$libname" "$fw" 2>/dev/null || true
otool -L "$fw" | tail -n +2 | awk '{print $1}' | while read -r lib; do
case "$lib" in
@executable_path/*)
depname=$(basename "$lib")
install_name_tool -change "$lib" "@rpath/$depname" "$fw" 2>/dev/null || true
;;
esac
done
done
# Add rpath to binary so it finds Frameworks
install_name_tool -add_rpath @executable_path/../Frameworks Amplitron.app/Contents/MacOS/Amplitron 2>/dev/null || true
# Copy assets to Contents/Resources/ — SDL_GetBasePath() on macOS app bundles
# returns Contents/Resources/, not Contents/MacOS/, so the font loader finds:
# base_path + "assets/fonts/Roboto-Medium.ttf" = Contents/Resources/assets/fonts/...
cp -r assets Amplitron.app/Contents/Resources/assets || true
# Copy icon
cp icon.icns Amplitron.app/Contents/Resources/icon.icns 2>/dev/null || true
# Write Info.plist
VERSION="${{ needs.create-release.outputs.version }}"
/usr/libexec/PlistBuddy -c "Add :CFBundleExecutable string Amplitron" Amplitron.app/Contents/Info.plist
/usr/libexec/PlistBuddy -c "Add :CFBundleIdentifier string com.amplitron.app" Amplitron.app/Contents/Info.plist
/usr/libexec/PlistBuddy -c "Add :CFBundleName string Amplitron" Amplitron.app/Contents/Info.plist
/usr/libexec/PlistBuddy -c "Add :CFBundleVersion string ${VERSION}" Amplitron.app/Contents/Info.plist
/usr/libexec/PlistBuddy -c "Add :CFBundleShortVersionString string ${VERSION}" Amplitron.app/Contents/Info.plist
/usr/libexec/PlistBuddy -c "Add :CFBundlePackageType string APPL" Amplitron.app/Contents/Info.plist
/usr/libexec/PlistBuddy -c "Add :CFBundleIconFile string icon" Amplitron.app/Contents/Info.plist
/usr/libexec/PlistBuddy -c "Add :NSHighResolutionCapable bool true" Amplitron.app/Contents/Info.plist
/usr/libexec/PlistBuddy -c "Add :NSMicrophoneUsageDescription string 'Amplitron needs microphone access for guitar input.'" Amplitron.app/Contents/Info.plist
/usr/libexec/PlistBuddy -c "Add :LSMinimumSystemVersion string 10.15" Amplitron.app/Contents/Info.plist
echo "=== Final binary links ==="
otool -L Amplitron.app/Contents/MacOS/Amplitron
echo "=== Frameworks ==="
ls -la Amplitron.app/Contents/Frameworks/
echo "=== Info.plist ==="
cat Amplitron.app/Contents/Info.plist
- name: Ad-hoc Codesign
run: |
# Sign each framework dylib first
for fw in Amplitron.app/Contents/Frameworks/*.dylib; do
[ -f "$fw" ] || continue
codesign --force --sign - "$fw"
done
# Then sign the whole app
codesign --force --deep --sign - Amplitron.app
# Verify
codesign --verify --verbose Amplitron.app
- name: Create DMG
run: |
mkdir -p dmg_staging
cp -r Amplitron.app dmg_staging/
ln -s /Applications dmg_staging/Applications
hdiutil create -volname "Amplitron" -srcfolder dmg_staging -ov -format UDZO Amplitron-macOS.dmg
- name: Upload to Release
uses: softprops/action-gh-release@v3
with:
tag_name: v${{ needs.create-release.outputs.version }}
files: Amplitron-macOS.dmg
package-linux:
name: Package Linux Archive
needs: create-release
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Download Linux Build
uses: actions/download-artifact@v8
with:
name: linux-build
path: artifacts/linux
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Package
run: |
mkdir -p Amplitron-Linux
cp artifacts/linux/Amplitron Amplitron-Linux/amplitron
chmod +x Amplitron-Linux/amplitron
cp README.md Amplitron-Linux/
cp -r assets Amplitron-Linux/ || true
printf '#!/bin/bash\ncd "$(dirname "$0")"\n./amplitron\n' > Amplitron-Linux/amplitron.sh
chmod +x Amplitron-Linux/amplitron.sh
tar -czf Amplitron-Linux-x64.tar.gz Amplitron-Linux
- name: Upload to Release
uses: softprops/action-gh-release@v3
with:
tag_name: v${{ needs.create-release.outputs.version }}
files: Amplitron-Linux-x64.tar.gz
package-android:
name: Package Android APK
needs: create-release
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Download Android Build
uses: actions/download-artifact@v8
with:
name: android-build
path: artifacts/android
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Rename APK
run: |
APK=$(find artifacts/android -name "*.apk" | head -1)
if [ -z "$APK" ]; then
echo "Error: No APK found in artifacts/android"
exit 1
fi
cp "$APK" Amplitron-Android.apk
ls -lh Amplitron-Android.apk
- name: Upload to Release
uses: softprops/action-gh-release@v3
with:
tag_name: v${{ needs.create-release.outputs.version }}
files: Amplitron-Android.apk
package-ios:
name: Package iOS IPA
needs: create-release
runs-on: ubuntu-latest
steps:
- name: Download iOS Build
uses: actions/download-artifact@v8
with:
name: ios-build
path: artifacts/ios
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Rename IPA
run: |
cp artifacts/ios/Amplitron.ipa Amplitron-iOS.ipa
ls -lh Amplitron-iOS.ipa
- name: Upload to Release
uses: softprops/action-gh-release@v3
with:
tag_name: v${{ needs.create-release.outputs.version }}
files: Amplitron-iOS.ipa
deploy-website:
name: Deploy Download Page + Web Demo
needs: [create-release, package-windows, package-macos, package-linux, package-android, package-ios]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Download Web Build
uses: actions/download-artifact@v8
with:
name: web-build
path: web-demo
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ secrets.GITHUB_TOKEN }}
continue-on-error: true
- name: Merge Web Demo into docs
run: |
mkdir -p docs/demo
if [ -d web-demo/build-web ]; then
cp web-demo/build-web/* docs/demo/ 2>/dev/null || true
elif [ -d web-demo ]; then
cp web-demo/*.html web-demo/*.js web-demo/*.wasm web-demo/*.data docs/demo/ 2>/dev/null || true
fi
echo "=== docs/demo contents ==="
ls -la docs/demo/ 2>/dev/null || echo "(empty)"
- uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./docs
publish_branch: gh-pages