Skip to content

Commit aeca6ee

Browse files
committed
Refactor binary build
1 parent bc525e3 commit aeca6ee

File tree

6 files changed

+237
-44
lines changed

6 files changed

+237
-44
lines changed

.github/workflows/release.yml

Lines changed: 72 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@ jobs:
1212
release:
1313
if: startsWith(github.ref, 'refs/tags/')
1414
runs-on: ubuntu-latest
15-
outputs:
16-
upload_url: ${{ steps.create_release.outputs.upload_url }}
1715

1816
steps:
1917
- name: Build Changelog
@@ -48,6 +46,9 @@ jobs:
4846
body: ${{steps.github_release.outputs.changelog}}
4947
draft: true
5048
prerelease: true
49+
tag_name: ${{ github.ref_name }}
50+
make_latest: 'false'
51+
fail_on_unmatched_files: false
5152

5253
build:
5354
needs: [release]
@@ -57,6 +58,8 @@ jobs:
5758
device: [CPU, GPU]
5859

5960
runs-on: ${{ matrix.os }}
61+
permissions:
62+
contents: write
6063

6164
steps:
6265
- uses: actions/checkout@v2
@@ -78,58 +81,87 @@ jobs:
7881
run: |
7982
pip install .
8083
81-
- name: Install PyQt5 for macOS
82-
shell: bash -l {0}
83-
run: |
84-
conda install -c conda-forge pyqt==5.15.7
85-
if: runner.os == 'macOS'
86-
8784
- name: Run pyinstaller
8885
shell: bash -l {0}
8986
run: |
9087
pip install pyinstaller
9188
pyinstaller anylabeling.spec
9289
93-
- name: Upload release executable on macOS & Linux
94-
id: upload_release_executable_macos_linux
90+
- name: Rename for GPU version
91+
if: matrix.device == 'GPU'
92+
shell: bash -l {0}
93+
run: |
94+
if [ -f "./dist/anylabeling" ]; then
95+
mv ./dist/anylabeling ./dist/anylabeling-GPU
96+
fi
97+
if [ -f "./dist/anylabeling.exe" ]; then
98+
mv ./dist/anylabeling.exe ./dist/anylabeling-GPU.exe
99+
fi
100+
101+
- name: Upload Linux/Windows Release Assets
95102
uses: softprops/action-gh-release@v2
96103
env:
97104
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
98105
with:
99-
upload_url: ${{ needs.release.outputs.upload_url }}
100-
asset_path: ./dist/anylabeling
101-
asset_name: AnyLabeling-${{ runner.os }}${{ matrix.device == 'GPU' && '-GPU' || '' }}
102-
asset_content_type: application/octet-stream
103-
if: runner.os != 'Windows'
104-
105-
- name: Upload release executable on Windows
106-
id: upload_release_executable_windows
107-
uses: softprops/action-gh-release@v2
108-
env:
109-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
106+
tag_name: ${{ github.ref_name }}
107+
files: |
108+
./dist/anylabeling*
109+
fail_on_unmatched_files: false
110+
append_body: true
111+
preserve_order: true
112+
if: success()
113+
114+
build_macos_folder:
115+
needs: [release]
116+
runs-on: macos-latest
117+
permissions:
118+
contents: write
119+
strategy:
120+
matrix:
121+
device: [CPU, GPU]
122+
123+
steps:
124+
- uses: actions/checkout@v2
110125
with:
111-
upload_url: ${{ needs.release.outputs.upload_url }}
112-
asset_path: ./dist/anylabeling.exe
113-
asset_name: AnyLabeling${{ matrix.device == 'GPU' && '-GPU' || '' }}.exe
114-
asset_content_type: application/octet-stream
115-
if: runner.os == 'Windows'
126+
submodules: true
116127

117-
- name: Create dmg for macOS
128+
- uses: conda-incubator/setup-miniconda@v2
129+
with:
130+
python-version: "3.10.14"
131+
miniconda-version: "latest"
132+
133+
- name: Install main
134+
shell: bash -l {0}
135+
run: |
136+
pip install .
137+
138+
- name: Install PyQt5 for macOS
139+
shell: bash -l {0}
140+
run: |
141+
conda install -c conda-forge pyqt==5.15.7
142+
143+
- name: Make build script executable
144+
shell: bash -l {0}
145+
run: |
146+
chmod +x scripts/build_macos_folder.sh
147+
148+
- name: Build in folder mode
149+
shell: bash -l {0}
118150
run: |
119-
npm install -g create-dmg
120-
cd dist
121-
create-dmg AnyLabeling.app || test -f AnyLabeling\ 0.0.0.dmg
122-
mv AnyLabeling\ 0.0.0.dmg AnyLabeling${{ matrix.device == 'GPU' && '-GPU' || '' }}.dmg
123-
if: runner.os == 'macOS'
124-
125-
- name: Upload release app on macOS
126-
id: upload_release_app_macos
151+
./scripts/build_macos_folder.sh ${{ matrix.device }}
152+
153+
- name: Create zip archive
154+
shell: bash -l {0}
155+
run: |
156+
cd dist && zip -r AnyLabeling-Folder${{ matrix.device == 'GPU' && '-GPU' || '' }}.zip AnyLabeling-Folder${{ matrix.device == 'GPU' && '-GPU' || '' }}/
157+
158+
- name: Upload macOS Folder Build Assets
127159
uses: softprops/action-gh-release@v2
128160
env:
129161
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
130162
with:
131-
upload_url: ${{ needs.release.outputs.upload_url }}
132-
asset_path: ./dist/AnyLabeling${{ matrix.device == 'GPU' && '-GPU' || '' }}.dmg
133-
asset_name: AnyLabeling${{ matrix.device == 'GPU' && '-GPU' || '' }}.dmg
134-
asset_content_type: application/octet-stream
135-
if: runner.os == 'macOS'
163+
tag_name: ${{ github.ref_name }}
164+
files: ./dist/AnyLabeling-Folder${{ matrix.device == 'GPU' && '-GPU' || '' }}.zip
165+
append_body: true
166+
preserve_order: true
167+
if: success()

.pre-commit-config.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,6 @@ repos:
4040
hooks:
4141
- id: codespell
4242
files: \.(py|sh|rst|yml|yaml)$
43+
args:
44+
- --ignore-words-list=datas
45+
- --skip=scripts/build_macos_folder.sh

README.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,8 @@
4646

4747
- Download and run newest version from [Releases](https://github.com/vietanhdev/anylabeling/releases).
4848
- For MacOS:
49-
- After installing, go to Applications folder
50-
- Right click on the app and select Open
51-
- From the second time, you can open the app normally using Launchpad
49+
- Download the folder mode build (`AnyLabeling-Folder.zip`) from [Releases](https://github.com/vietanhdev/anylabeling/releases)
50+
- See [macOS folder mode instructions](docs/macos_folder_mode.md) for details
5251

5352
### Install from Pypi
5453

anylabeling/app_info.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
__appname__ = "AnyLabeling"
22
__appdescription__ = "Effortless data labeling with AI support"
3-
__version__ = "0.4.25"
3+
__version__ = "0.4.28"
44
__preferred_device__ = "CPU" # GPU or CPU

docs/macos_folder_mode.md

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# macOS Build for AnyLabeling
2+
3+
## Overview
4+
5+
The macOS build of AnyLabeling is provided as a directory structure rather than a bundled `.app` file. This approach offers:
6+
7+
- Easier integration with other tools or scripts
8+
- Customization of the application's resources
9+
- Better compatibility across different macOS versions
10+
- Direct access to application files
11+
12+
## Installation
13+
14+
1. Download the appropriate `AnyLabeling-Folder.zip` (CPU) or `AnyLabeling-Folder-GPU.zip` (GPU) from the [releases page](https://github.com/vietanhdev/anylabeling/releases).
15+
16+
2. Extract the downloaded ZIP file:
17+
```bash
18+
unzip AnyLabeling-Folder.zip
19+
```
20+
21+
3. The extracted folder `AnyLabeling-Folder` contains everything needed to run the application.
22+
23+
## Running the Application
24+
25+
To run the application, execute the `anylabeling` binary in the folder:
26+
27+
```bash
28+
cd AnyLabeling-Folder
29+
./anylabeling
30+
```
31+
32+
You can also create a shortcut or alias to this executable for easier access.
33+
34+
## Building Locally
35+
36+
If you want to build the application yourself:
37+
38+
1. Clone the repository:
39+
```bash
40+
git clone https://github.com/vietanhdev/anylabeling.git
41+
cd anylabeling
42+
```
43+
44+
2. Install dependencies:
45+
```bash
46+
pip install -r requirements-macos-dev.txt
47+
```
48+
49+
3. Make the build script executable:
50+
```bash
51+
chmod +x scripts/build_macos_folder.sh
52+
```
53+
54+
4. Run the build script:
55+
```bash
56+
# For CPU version
57+
./scripts/build_macos_folder.sh
58+
59+
# For GPU version
60+
./scripts/build_macos_folder.sh GPU
61+
```
62+
63+
5. The built application folder will be available at `./dist/AnyLabeling-Folder/` (CPU) or `./dist/AnyLabeling-Folder-GPU/` (GPU).
64+
65+
## Troubleshooting
66+
67+
If you encounter issues with the application:
68+
69+
- Ensure you have the correct permissions to execute the application:
70+
```bash
71+
chmod +x AnyLabeling-Folder/anylabeling
72+
```
73+
74+
- If you get dynamic library loading errors, make sure all dependencies are properly installed:
75+
```bash
76+
pip install -r requirements-macos.txt
77+
```
78+
79+
- If you encounter graphics or UI issues, try using the CPU version instead of GPU.
80+
81+
- For further assistance, please [open an issue](https://github.com/vietanhdev/anylabeling/issues/new) on GitHub.

scripts/build_macos_folder.sh

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
#!/bin/bash
2+
3+
# Script to build AnyLabeling in folder mode for macOS
4+
# This creates a directory-based application instead of a bundled .app
5+
6+
# Set CPU or GPU mode
7+
if [ "$1" == "GPU" ]; then
8+
sed -i'' -e 's/\_\_preferred_device\_\_[ ]*=[ ]*\"[A-Za-z0-9]*\"/__preferred_device__ = "GPU"/g' anylabeling/app_info.py
9+
SUFFIX="-GPU"
10+
else
11+
sed -i'' -e 's/\_\_preferred_device\_\_[ ]*=[ ]*\"[A-Za-z0-9]*\"/__preferred_device__ = "CPU"/g' anylabeling/app_info.py
12+
SUFFIX=""
13+
fi
14+
15+
# Create temporary PyInstaller spec for folder mode
16+
cat > anylabeling_folder.spec << EOL
17+
# -*- mode: python -*-
18+
# vim: ft=python
19+
20+
import sys
21+
22+
sys.setrecursionlimit(5000) # required on Windows
23+
24+
a = Analysis(
25+
['anylabeling/app.py'],
26+
pathex=['anylabeling'],
27+
binaries=[],
28+
datas=[
29+
('anylabeling/configs/auto_labeling/*.yaml', 'anylabeling/configs/auto_labeling'),
30+
('anylabeling/configs/*.yaml', 'anylabeling/configs'),
31+
('anylabeling/views/labeling/widgets/auto_labeling/auto_labeling.ui', 'anylabeling/views/labeling/widgets/auto_labeling')
32+
],
33+
hiddenimports=[],
34+
hookspath=[],
35+
runtime_hooks=[],
36+
excludes=[],
37+
)
38+
pyz = PYZ(a.pure, a.zipped_data)
39+
40+
# Create a directory structure instead of a bundled .app
41+
exe = EXE(
42+
pyz,
43+
a.scripts,
44+
exclude_binaries=True, # This is the key difference - exclude binaries
45+
name='anylabeling',
46+
debug=False,
47+
strip=False,
48+
upx=False,
49+
console=False,
50+
icon='anylabeling/resources/images/icon.icns',
51+
)
52+
53+
# Bundle binaries in a separate folder
54+
coll = COLLECT(
55+
exe,
56+
a.binaries,
57+
a.zipfiles,
58+
a.datas,
59+
strip=False,
60+
upx=False,
61+
name='AnyLabeling-Folder${SUFFIX}',
62+
)
63+
EOL
64+
65+
# Install PyInstaller if not already installed
66+
pip install pyinstaller
67+
68+
# Run PyInstaller with the folder mode spec
69+
pyinstaller --noconfirm anylabeling_folder.spec
70+
71+
# Cleanup
72+
rm anylabeling_folder.spec
73+
74+
# Print success message
75+
echo "Build completed. Application folder is located at ./dist/AnyLabeling-Folder${SUFFIX}/"
76+
77+
# Make the script executable
78+
chmod +x scripts/build_macos_folder.sh

0 commit comments

Comments
 (0)