1- name : Build Executables
1+ name : Build & Release App (Cross-platform)
22
33on :
44 push :
5- branches : [ main ]
6- pull_request :
7- branches : [ main ]
5+ tags :
6+ - ' v*'
7+
8+ permissions :
9+ contents : write
810
911jobs :
1012 build :
11- name : Build for ${{ matrix.os }}
13+ name : Build App on ${{ matrix.os }}
1214 runs-on : ${{ matrix.os }}
1315 strategy :
1416 matrix :
1517 os : [ubuntu-latest, windows-latest, macos-latest]
1618
1719 steps :
18- - name : Checkout code
20+ - name : Checkout Repository
1921 uses : actions/checkout@v3
2022
21- - name : Set up Python
22- uses : actions/setup-python@v4
23+ - name : Install Dependencies (Ubuntu)
24+ if : matrix.os == 'ubuntu-latest'
25+ run : |
26+ sudo apt update
27+ sudo apt install -y qtbase5-dev qt5-qmake cmake g++ appstream dpkg-dev fakeroot qttools5-dev-tools
28+
29+ - name : Install Dependencies (Windows)
30+ if : matrix.os == 'windows-latest'
31+ uses : jurplel/install-qt-action@v3
2332 with :
24- python-version : ' 3.11'
33+ version : ' 5.15.2'
34+ target : ' desktop'
2535
26- - name : Install dependencies
27- run : pip install pyinstaller
36+ - name : Install Dependencies (macOS)
37+ if : matrix.os == 'macos-latest'
38+ uses : jurplel/install-qt-action@v3
39+ with :
40+ version : ' 5.15.2'
41+ target : ' desktop'
2842
29- # Windows build
30- - name : Build executable on Windows
31- if : runner.os == 'Windows'
32- shell : cmd
43+ - name : Build App
3344 run : |
34- pyinstaller --onefile --name fe FrameExtractor.py --exclude-module libcrypto.so.3 --exclude-module libssl.so.3
45+ mkdir -p build
46+ cd build
47+ cmake .. -DCMAKE_BUILD_TYPE=Release
48+ cmake --build . --config Release
3549
36- # Linux build
37- - name : Build executable on Linux
38- if : runner.os == 'Linux'
39- run : pyinstaller --onefile --name fe FrameExtractor.py --exclude-module libcrypto.so.3 --exclude-module libssl.so.3
50+ - name : Run QTest Unit Tests
51+ run : |
52+ cd build
53+ ctest --output-on-failure || true
54+
55+ - name : Package DEB (Linux only)
56+ if : matrix.os == 'ubuntu-latest'
57+ run : |
58+ mkdir -p pkgdir/DEBIAN
59+ mkdir -p pkgdir/usr/bin
60+ cp build/FrameExtractor pkgdir/usr/bin/
61+ echo "Package: frameextractorqt" > pkgdir/DEBIAN/control
62+ echo "Version: 1.0.0" >> pkgdir/DEBIAN/control
63+ echo "Architecture: amd64" >> pkgdir/DEBIAN/control
64+ echo "Maintainer: You <you@example.com>" >> pkgdir/DEBIAN/control
65+ echo "Description: Frame Extractor Application" >> pkgdir/DEBIAN/control
66+ dpkg-deb --build pkgdir frameextractorqt.deb
67+
68+ - name : Package DMG (macOS only)
69+ if : matrix.os == 'macos-latest'
70+ run : |
71+ hdiutil create FrameExtractor.dmg -volname FrameExtractor -srcfolder build/
4072
41- # macOS build
42- - name : Build executable on macOS
43- if : runner.os == 'macOS'
44- run : pyinstaller --onefile --name fe FrameExtractor.py --exclude-module libcrypto.so.3 --exclude-module libssl.so.3
73+ - name : Archive Binaries
74+ run : |
75+ mkdir -p release
76+ if [ "$RUNNER_OS" = "Windows" ]; then
77+ cp build/Release/FrameExtractor.exe release/FrameExtractor.exe
78+ elif [ "$RUNNER_OS" = "macOS" ]; then
79+ cp FrameExtractor.dmg release/FrameExtractor.dmg
80+ cp build/FrameExtractor release/FrameExtractor-macos
81+ else
82+ cp build/FrameExtractor release/FrameExtractor-linux
83+ cp frameextractorqt.deb release/FrameExtractor.deb
4584
46- - name : Upload Executable Artifact
85+ - name : Upload Artifact
4786 uses : actions/upload-artifact@v4
4887 with :
49- name : fe-${{ matrix.os }}
50- path : dist/fe*
88+ name : FrameExtractor-${{ runner.os }}
89+ path : release/*
90+
91+ appimage :
92+ runs-on : ubuntu-latest
93+ steps :
94+ - name : Checkout Repository
95+ uses : actions/checkout@v3
96+
97+ - name : Install Qt + tools
98+ run : |
99+ sudo apt update
100+ sudo apt install -y qtbase5-dev qt5-qmake cmake g++ appstream appimagetool
101+
102+ - name : Build App
103+ run : |
104+ mkdir -p build
105+ cd build
106+ cmake .. -DCMAKE_BUILD_TYPE=Release
107+ make
108+
109+ - name : Prepare AppDir
110+ run : |
111+ mkdir -p AppDir/usr/bin
112+ cp build/FrameExtractor AppDir/usr/bin/
113+ cp packaging/AppRun AppDir/
114+ chmod +x AppDir/AppRun
115+ cp packaging/FrameExtractor.desktop AppDir/
116+ cp packaging/icon.png AppDir/
117+
118+ - name : Build AppImage
119+ run : |
120+ wget -q https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage
121+ chmod +x appimagetool-x86_64.AppImage
122+ ./appimagetool-x86_64.AppImage AppDir
123+
124+ - name : Upload AppImage Artifact
125+ uses : actions/upload-artifact@v4
126+ with :
127+ name : FrameExtractor.AppImage
128+ path : FrameExtractor*.AppImage
129+
130+ publish :
131+ needs : [build, appimage]
132+ runs-on : ubuntu-latest
133+ steps :
134+ - name : Checkout
135+ uses : actions/checkout@v3
136+ with :
137+ fetch-depth : 0
138+
139+ - name : Generate Changelog
140+ id : changelog
141+ run : |
142+ LAST_TAG=$(git tag --sort=-creatordate | head -n 1)
143+ if [ -z "$LAST_TAG" ]; then
144+ git log --pretty=format:"%s" > raw_log.txt
145+ else
146+ git log "$LAST_TAG"..HEAD --pretty=format:"%s" > raw_log.txt
147+ fi
148+
149+ echo "CHANGELOG<<EOF" >> $GITHUB_OUTPUT
150+ echo "### Changelog for ${{ github.ref_name }}" >> $GITHUB_OUTPUT
151+ echo >> $GITHUB_OUTPUT
152+ grep '^feat' raw_log.txt | sed 's/^/- /' >> $GITHUB_OUTPUT || true
153+ grep '^fix' raw_log.txt | sed 's/^/- /' >> $GITHUB_OUTPUT || true
154+ grep -vE '^(feat|fix)' raw_log.txt | sed 's/^/- /' >> $GITHUB_OUTPUT || true
155+ echo "EOF" >> $GITHUB_OUTPUT
156+
157+ - name : Download All Artifacts
158+ uses : actions/download-artifact@v4
159+ with :
160+ path : artifacts
161+
162+ - name : Create GitHub Release
163+ uses : softprops/action-gh-release@v2
164+ with :
165+ tag_name : ${{ github.ref_name }}
166+ name : Release ${{ github.ref_name }}
167+ body : ${{ steps.changelog.outputs.CHANGELOG }}
168+ draft : false
169+ prerelease : false
170+ files : artifacts/**
171+ env :
172+ GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
0 commit comments