99env :
1010 CARGO_TERM_COLOR : always
1111 RUST_BACKTRACE : 1
12+ APP_NAME : UltraLog
1213
1314jobs :
14- build :
15- name : Build ${{ matrix.target }}
16- runs-on : ${{ matrix.os }}
17- strategy :
18- fail-fast : false
19- matrix :
20- include :
21- # macOS Intel
22- - target : x86_64-apple-darwin
23- os : macos-latest
24- artifact_name : ultralog
25- asset_name : ultralog-macos-intel
26-
27- # macOS Apple Silicon
28- - target : aarch64-apple-darwin
29- os : macos-latest
30- artifact_name : ultralog
31- asset_name : ultralog-macos-arm64
32-
33- # Windows
34- - target : x86_64-pc-windows-msvc
35- os : windows-latest
36- artifact_name : ultralog.exe
37- asset_name : ultralog-windows
38-
39- # Linux
40- - target : x86_64-unknown-linux-gnu
41- os : ubuntu-latest
42- artifact_name : ultralog
43- asset_name : ultralog-linux
44-
15+ build-linux :
16+ name : Build Linux
17+ runs-on : ubuntu-latest
4518 steps :
4619 - name : Checkout code
4720 uses : actions/checkout@v4
4821
4922 - name : Install Rust toolchain
5023 uses : dtolnay/rust-toolchain@stable
5124 with :
52- targets : ${{ matrix.target }}
25+ targets : x86_64-unknown-linux-gnu
5326
5427 - name : Install Linux dependencies
55- if : matrix.os == 'ubuntu-latest'
5628 run : |
5729 sudo apt-get update
5830 sudo apt-get install -y \
@@ -68,30 +40,200 @@ jobs:
6840 libpango1.0-dev \
6941 libgdk-pixbuf2.0-dev
7042
43+ - name : Build release binary
44+ run : cargo build --release --target x86_64-unknown-linux-gnu
45+
46+ - name : Package Linux binary
47+ run : |
48+ mkdir -p output
49+ cp target/x86_64-unknown-linux-gnu/release/ultralog output/ultralog-linux
50+ chmod +x output/ultralog-linux
51+ cd output
52+ tar -czvf ultralog-linux.tar.gz ultralog-linux
53+ rm ultralog-linux
54+
55+ - name : Upload artifact
56+ uses : actions/upload-artifact@v4
57+ with :
58+ name : ultralog-linux
59+ path : output/
60+
61+ build-windows :
62+ name : Build Windows
63+ runs-on : windows-latest
64+ steps :
65+ - name : Checkout code
66+ uses : actions/checkout@v4
67+
68+ - name : Install Rust toolchain
69+ uses : dtolnay/rust-toolchain@stable
70+ with :
71+ targets : x86_64-pc-windows-msvc
72+
73+ - name : Build release binary
74+ run : cargo build --release --target x86_64-pc-windows-msvc
75+
76+ - name : Package Windows binary
77+ shell : pwsh
78+ run : |
79+ New-Item -ItemType Directory -Force -Path output
80+ Copy-Item "target/x86_64-pc-windows-msvc/release/ultralog.exe" -Destination "output/ultralog-windows.exe"
81+ Compress-Archive -Path "output/ultralog-windows.exe" -DestinationPath "output/ultralog-windows.zip"
82+ Remove-Item "output/ultralog-windows.exe"
83+
84+ - name : Upload artifact
85+ uses : actions/upload-artifact@v4
86+ with :
87+ name : ultralog-windows
88+ path : output/
89+
90+ build-macos :
91+ name : Build macOS (${{ matrix.arch }})
92+ runs-on : macos-latest
93+ strategy :
94+ fail-fast : false
95+ matrix :
96+ include :
97+ - target : x86_64-apple-darwin
98+ arch : intel
99+ asset_name : ultralog-macos-intel
100+ - target : aarch64-apple-darwin
101+ arch : arm64
102+ asset_name : ultralog-macos-arm64
103+
104+ steps :
105+ - name : Checkout code
106+ uses : actions/checkout@v4
107+
108+ - name : Install Rust toolchain
109+ uses : dtolnay/rust-toolchain@stable
110+ with :
111+ targets : ${{ matrix.target }}
112+
113+ - name : Install create-dmg
114+ run : brew install create-dmg
115+
116+ - name : Get version
117+ id : version
118+ run : echo "VERSION=$(grep '^version' Cargo.toml | head -1 | sed 's/.*\"\(.*\)\".*/\1/')" >> $GITHUB_OUTPUT
119+
71120 - name : Build release binary
72121 run : cargo build --release --target ${{ matrix.target }}
73122
74- - name : Create output directory
75- shell : bash
76- run : mkdir -p output
123+ - name : Create app bundle and DMG
124+ env :
125+ VERSION : ${{ steps.version.outputs.VERSION }}
126+ run : |
127+ mkdir -p output
128+
129+ # Create app bundle structure
130+ APP_DIR="output/${{ env.APP_NAME }}-${{ matrix.arch }}.app"
131+ mkdir -p "$APP_DIR/Contents/MacOS"
132+ mkdir -p "$APP_DIR/Contents/Resources"
133+
134+ # Copy binary
135+ cp target/${{ matrix.target }}/release/ultralog "$APP_DIR/Contents/MacOS/ultralog"
136+ chmod +x "$APP_DIR/Contents/MacOS/ultralog"
137+
138+ # Create Info.plist
139+ cat > "$APP_DIR/Contents/Info.plist" << EOF
140+ <?xml version="1.0" encoding="UTF-8"?>
141+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
142+ <plist version="1.0">
143+ <dict>
144+ <key>CFBundleName</key>
145+ <string>${{ env.APP_NAME }}</string>
146+ <key>CFBundleDisplayName</key>
147+ <string>${{ env.APP_NAME }}</string>
148+ <key>CFBundleIdentifier</key>
149+ <string>com.ultralog.app</string>
150+ <key>CFBundleVersion</key>
151+ <string>${VERSION}</string>
152+ <key>CFBundleShortVersionString</key>
153+ <string>${VERSION}</string>
154+ <key>CFBundlePackageType</key>
155+ <string>APPL</string>
156+ <key>CFBundleExecutable</key>
157+ <string>ultralog</string>
158+ <key>CFBundleIconFile</key>
159+ <string>AppIcon</string>
160+ <key>LSMinimumSystemVersion</key>
161+ <string>10.15</string>
162+ <key>NSHighResolutionCapable</key>
163+ <true/>
164+ <key>NSSupportsAutomaticGraphicsSwitching</key>
165+ <true/>
166+ <key>CFBundleDocumentTypes</key>
167+ <array>
168+ <dict>
169+ <key>CFBundleTypeExtensions</key>
170+ <array>
171+ <string>csv</string>
172+ <string>log</string>
173+ <string>txt</string>
174+ <string>mlg</string>
175+ </array>
176+ <key>CFBundleTypeName</key>
177+ <string>ECU Log File</string>
178+ <key>CFBundleTypeRole</key>
179+ <string>Viewer</string>
180+ </dict>
181+ </array>
182+ </dict>
183+ </plist>
184+ EOF
77185
78- - name : Copy binary (Unix)
79- if : matrix.os != 'windows-latest'
80- run : cp target/${{ matrix.target }}/release/${{ matrix.artifact_name }} output/${{ matrix.asset_name }}
186+ # Create PkgInfo
187+ echo -n "APPL????" > "$APP_DIR/Contents/PkgInfo"
81188
82- - name : Copy binary (Windows)
83- if : matrix.os == 'windows-latest'
84- run : cp target/${{ matrix.target }}/release/${{ matrix.artifact_name }} output/${{ matrix.asset_name }}.exe
189+ # Create icon from PNG if exists
190+ if [ -f "assets/icons/mac.png" ]; then
191+ ICONSET_DIR=$(mktemp -d)/AppIcon.iconset
192+ mkdir -p "$ICONSET_DIR"
193+ sips -z 16 16 "assets/icons/mac.png" --out "$ICONSET_DIR/icon_16x16.png"
194+ sips -z 32 32 "assets/icons/mac.png" --out "$ICONSET_DIR/icon_16x16@2x.png"
195+ sips -z 32 32 "assets/icons/mac.png" --out "$ICONSET_DIR/icon_32x32.png"
196+ sips -z 64 64 "assets/icons/mac.png" --out "$ICONSET_DIR/icon_32x32@2x.png"
197+ sips -z 128 128 "assets/icons/mac.png" --out "$ICONSET_DIR/icon_128x128.png"
198+ sips -z 256 256 "assets/icons/mac.png" --out "$ICONSET_DIR/icon_128x128@2x.png"
199+ sips -z 256 256 "assets/icons/mac.png" --out "$ICONSET_DIR/icon_256x256.png"
200+ sips -z 512 512 "assets/icons/mac.png" --out "$ICONSET_DIR/icon_256x256@2x.png"
201+ sips -z 512 512 "assets/icons/mac.png" --out "$ICONSET_DIR/icon_512x512.png"
202+ sips -z 1024 1024 "assets/icons/mac.png" --out "$ICONSET_DIR/icon_512x512@2x.png"
203+ iconutil -c icns "$ICONSET_DIR" -o "$APP_DIR/Contents/Resources/AppIcon.icns"
204+ fi
205+
206+ # Ad-hoc sign the app bundle
207+ codesign --force --deep --sign - "$APP_DIR"
208+
209+ # Create DMG
210+ create-dmg \
211+ --volname "${{ env.APP_NAME }}" \
212+ --window-pos 200 120 \
213+ --window-size 600 400 \
214+ --icon-size 100 \
215+ --icon "${{ env.APP_NAME }}-${{ matrix.arch }}.app" 150 190 \
216+ --hide-extension "${{ env.APP_NAME }}-${{ matrix.arch }}.app" \
217+ --app-drop-link 450 190 \
218+ "output/${{ matrix.asset_name }}.dmg" \
219+ "$APP_DIR" || \
220+ hdiutil create -volname "${{ env.APP_NAME }}" -srcfolder "$APP_DIR" -ov -format UDZO "output/${{ matrix.asset_name }}.dmg"
221+
222+ # Also create tar.gz of the app bundle
223+ cd output
224+ tar -czvf "${{ matrix.asset_name }}.tar.gz" "${{ env.APP_NAME }}-${{ matrix.arch }}.app"
85225
86226 - name : Upload artifact
87227 uses : actions/upload-artifact@v4
88228 with :
89229 name : ${{ matrix.asset_name }}
90- path : output/
230+ path : |
231+ output/*.dmg
232+ output/*.tar.gz
91233
92234 release :
93235 name : Create Release
94- needs : build
236+ needs : [ build-linux, build-windows, build-macos]
95237 runs-on : ubuntu-latest
96238 if : startsWith(github.ref, 'refs/tags/')
97239 permissions :
@@ -104,18 +246,46 @@ jobs:
104246 path : artifacts
105247
106248 - name : Display structure
107- run : ls -la artifacts/
249+ run : |
250+ echo "Artifacts structure:"
251+ ls -laR artifacts/
108252
109253 - name : Create release
110254 uses : softprops/action-gh-release@v1
111255 with :
112256 files : |
113- artifacts/ultralog-macos-intel/*
114- artifacts/ultralog-macos-arm64/*
115- artifacts/ultralog-windows/*
116- artifacts/ultralog-linux/*
257+ artifacts/ultralog-macos-intel/*.dmg
258+ artifacts/ultralog-macos-intel/*.tar.gz
259+ artifacts/ultralog-macos-arm64/*.dmg
260+ artifacts/ultralog-macos-arm64/*.tar.gz
261+ artifacts/ultralog-windows/*.zip
262+ artifacts/ultralog-linux/*.tar.gz
117263 draft : false
118264 prerelease : false
119265 generate_release_notes : true
266+ body : |
267+ ## Installation
268+
269+ ### macOS (Recommended: DMG)
270+ 1. Download the appropriate `.dmg` file for your Mac:
271+ - **Intel Mac**: `ultralog-macos-intel.dmg`
272+ - **Apple Silicon (M1/M2/M3/M4)**: `ultralog-macos-arm64.dmg`
273+ 2. Open the DMG and drag UltraLog to your Applications folder
274+ 3. On first run, right-click the app and select "Open" to bypass Gatekeeper
275+
276+ ### macOS (Alternative: tar.gz)
277+ 1. Download and extract the `.tar.gz` file
278+ 2. Move the `.app` to your Applications folder
279+ 3. Remove quarantine: `xattr -cr /Applications/UltraLog*.app`
280+
281+ ### Windows
282+ 1. Download `ultralog-windows.zip`
283+ 2. Extract the zip file
284+ 3. Run `ultralog-windows.exe`
285+
286+ ### Linux
287+ 1. Download `ultralog-linux.tar.gz`
288+ 2. Extract: `tar -xzf ultralog-linux.tar.gz`
289+ 3. Run: `./ultralog-linux`
120290 env :
121291 GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
0 commit comments