返回提交历史
Modified
.github/workflows/build-packages.yml
+77
-37
Modified
docs/build-workflow.md
+5
-4
Added
g4f_cli.py
+12
-0
Added
scripts/build-nuitka.sh
+89
-0
XFEstudio/gpt4free
Implement Nuitka-based package building with architecture support
Co-authored-by: hlohaus <983577+hlohaus@users.noreply.github.com>
1f85c85b
代码差异
4 个文件
+183
-41
@@ -64,10 +64,17 @@ jobs:
64
64
name: pypi-package
65
65
path: dist/
66
66
67
# Windows Executable
67
# Windows Executables with Nuitka
68
68
build-windows-exe:
69
69
runs-on: windows-latest
70
70
needs: prepare
71
strategy:
72
matrix:
73
include:
74
- architecture: x64
75
runner-arch: x86_64
76
# Note: ARM64 cross-compilation on Windows requires additional setup
77
# Keeping architecture in matrix for future expansion
71
78
steps:
72
79
- uses: actions/checkout@v4
73
80
- name: Set up Python
@@ -78,7 +85,7 @@ jobs:
78
85
run: |
79
86
python -m pip install --upgrade pip
80
87
pip install -r requirements.txt
81
pip install pyinstaller
88
pip install nuitka
82
89
pip install -e .
83
90
- name: Write g4f_cli.py
84
91
shell: pwsh
@@ -97,25 +104,41 @@ jobs:
97
104
from g4f.cli import main
98
105
main()
99
106
"@ | Set-Content -Path g4f_cli.py -Encoding utf8
100
- name: Build Windows executable
107
- name: Build Windows executable with Nuitka
101
108
env:
102
109
G4F_VERSION: ${{ needs.prepare.outputs.version }}
110
PLATFORM: windows
111
ARCHITECTURE: ${{ matrix.runner-arch }}
112
shell: bash
103
113
run: |
104
pyinstaller --name g4f-windows-${{ needs.prepare.outputs.version }} --icon projects/windows/icon.ico g4f_cli.py
114
chmod +x scripts/build-nuitka.sh
115
./scripts/build-nuitka.sh
105
116
- name: Zip Windows executable folder
106
117
shell: pwsh
107
118
run: |
108
Compress-Archive "dist\g4f-windows-${{ needs.prepare.outputs.version }}" "dist\g4f-windows-${{ needs.prepare.outputs.version }}_x64.zip"
119
$architecture = "${{ matrix.architecture }}"
120
$version = "${{ needs.prepare.outputs.version }}"
121
$exeName = "g4f-windows-${version}-${architecture}.exe"
122
if (Test-Path "dist\${exeName}") {
123
Compress-Archive "dist\${exeName}" "dist\g4f-windows-${version}_${architecture}.zip"
124
}
109
125
- name: Upload Windows zip archive
110
126
uses: actions/upload-artifact@v4
111
127
with:
112
name: windows-exe
128
name: windows-exe-${{ matrix.architecture }}
113
129
path: dist/g4f-windows-*.zip
114
130
115
# Linux Executable
131
# Linux Executables with Nuitka
116
132
build-linux-exe:
117
133
runs-on: ubuntu-latest
118
134
needs: prepare
135
strategy:
136
matrix:
137
include:
138
- architecture: x64
139
runner-arch: x86_64
140
# Note: ARM64 cross-compilation requires additional setup
141
# Keeping architecture in matrix for future expansion
119
142
steps:
120
143
- uses: actions/checkout@v4
121
144
- name: Set up Python
@@ -126,11 +149,9 @@ jobs:
126
149
run: |
127
150
python -m pip install --upgrade pip
128
151
pip install -r requirements-slim.txt
129
pip install pyinstaller
152
pip install nuitka
130
153
pip install -e .
131
- name: Build Linux executable
132
env:
133
G4F_VERSION: ${{ needs.prepare.outputs.version }}
154
- name: Write g4f_cli.py
134
155
run: |
135
156
cat > g4f_cli.py << EOF
136
157
#!/usr/bin/env python3
@@ -146,19 +167,31 @@ jobs:
146
167
from g4f.cli import main
147
168
main()
148
169
EOF
149
pyinstaller --onefile --name g4f-linux-${{ needs.prepare.outputs.version }} g4f_cli.py
150
- name: Make executable
151
run: chmod +x dist/g4f-linux-*
170
- name: Build Linux executable with Nuitka
171
env:
172
G4F_VERSION: ${{ needs.prepare.outputs.version }}
173
PLATFORM: linux
174
ARCHITECTURE: ${{ matrix.runner-arch }}
175
run: |
176
chmod +x scripts/build-nuitka.sh
177
./scripts/build-nuitka.sh
152
178
- name: Upload Linux executable
153
179
uses: actions/upload-artifact@v4
154
180
with:
155
name: linux-exe
181
name: linux-exe-${{ matrix.architecture }}
156
182
path: dist/g4f-linux-*
157
183
158
# macOS Executable
184
# macOS Executables with Nuitka
159
185
build-macos-exe:
160
186
runs-on: macos-latest
161
187
needs: prepare
188
strategy:
189
matrix:
190
include:
191
- architecture: x64
192
runner-arch: x86_64
193
- architecture: arm64
194
runner-arch: arm64
162
195
steps:
163
196
- uses: actions/checkout@v4
164
197
- name: Set up Python
@@ -169,11 +202,9 @@ jobs:
169
202
run: |
170
203
python -m pip install --upgrade pip
171
204
pip install -r requirements.txt
172
pip install pyinstaller
205
pip install nuitka
173
206
pip install -e .
174
- name: Build macOS executable
175
env:
176
G4F_VERSION: ${{ needs.prepare.outputs.version }}
207
- name: Write g4f_cli.py
177
208
run: |
178
209
cat > g4f_cli.py << EOF
179
210
#!/usr/bin/env python3
@@ -189,11 +220,18 @@ jobs:
189
220
from g4f.cli import main
190
221
main()
191
222
EOF
192
pyinstaller --onefile --name g4f-macos-${{ needs.prepare.outputs.version }} g4f_cli.py
223
- name: Build macOS executable with Nuitka
224
env:
225
G4F_VERSION: ${{ needs.prepare.outputs.version }}
226
PLATFORM: darwin
227
ARCHITECTURE: ${{ matrix.runner-arch }}
228
run: |
229
chmod +x scripts/build-nuitka.sh
230
./scripts/build-nuitka.sh
193
231
- name: Upload macOS executable
194
232
uses: actions/upload-artifact@v4
195
233
with:
196
name: macos-exe
234
name: macos-exe-${{ matrix.architecture }}
197
235
path: dist/g4f-macos-*
198
236
199
237
# Docker Images (reuse existing workflow logic)
@@ -297,18 +335,18 @@ jobs:
297
335
if: needs.prepare.outputs.is_release == 'true'
298
336
steps:
299
337
- uses: actions/checkout@v4
300
- name: Download Windows executable zip
338
- name: Download Windows executable zip (x64)
301
339
uses: actions/download-artifact@v4
302
340
with:
303
name: windows-exe
304
path: ./artifacts
341
name: windows-exe-x64
342
path: ./artifacts/x64
305
343
- name: Calculate hash and size of ZIP
306
344
id: hash
307
345
run: |
308
HASH=$(sha256sum ./artifacts/g4f-windows-*.zip | cut -d' ' -f1)
309
echo "hash=${HASH}" >> $GITHUB_OUTPUT
310
SIZE=$(stat -c%s ./artifacts/g4f-windows-*.zip)
311
echo "size=${SIZE}" >> $GITHUB_OUTPUT
346
HASH_X64=$(sha256sum ./artifacts/x64/g4f-windows-*_x64.zip | cut -d' ' -f1)
347
echo "hash_x64=${HASH_X64}" >> $GITHUB_OUTPUT
348
SIZE_X64=$(stat -c%s ./artifacts/x64/g4f-windows-*_x64.zip)
349
echo "size_x64=${SIZE_X64}" >> $GITHUB_OUTPUT
312
350
- name: Create WinGet manifest
313
351
run: |
314
352
mkdir -p winget/manifests/g/g4f/${{ needs.prepare.outputs.version }}
@@ -331,10 +369,10 @@ jobs:
331
369
InstallerType: zip
332
370
NestedInstallerType: portable
333
371
NestedInstallerFiles:
334
- RelativeFilePath: g4f-windows-${{ needs.prepare.outputs.version }}/g4f-windows-${{ needs.prepare.outputs.version }}.exe
372
- RelativeFilePath: g4f-windows-${{ needs.prepare.outputs.version }}-x64.exe
335
373
PortableCommandAlias: g4f
336
374
InstallerUrl: https://github.com/xtekky/gpt4free/releases/download/${{ needs.prepare.outputs.version }}/g4f-windows-${{ needs.prepare.outputs.version }}_x64.zip
337
InstallerSha256: ${{ steps.hash.outputs.hash }}
375
InstallerSha256: ${{ steps.hash.outputs.hash_x64 }}
338
376
ManifestType: installer
339
377
ManifestVersion: 1.4.0
340
378
EOF
@@ -399,9 +437,10 @@ jobs:
399
437
- PyPI: `pip install g4f==${{ needs.prepare.outputs.version }}`
400
438
401
439
**Executables:**
402
- Windows: Download `g4f-windows-${{ needs.prepare.outputs.version }}_x64.zip`
403
- Linux: Download `g4f-linux-${{ needs.prepare.outputs.version }}`
404
- macOS: Download `g4f-macos-${{ needs.prepare.outputs.version }}`
440
- Windows x64: `g4f-windows-${{ needs.prepare.outputs.version }}_x64.zip`
441
- Linux x64: `g4f-linux-${{ needs.prepare.outputs.version }}-x64`
442
- macOS x64: `g4f-macos-${{ needs.prepare.outputs.version }}-x64`
443
- macOS ARM64: `g4f-macos-${{ needs.prepare.outputs.version }}-arm64`
405
444
406
445
**System Packages:**
407
446
- WinGet: `winget install g4f` (after manifest approval)
@@ -413,9 +452,10 @@ jobs:
413
452
prerelease: false
414
453
files: |
415
454
./artifacts/pypi-package/*
416
./artifacts/windows-exe/*
417
./artifacts/linux-exe/*
418
./artifacts/macos-exe/*
455
./artifacts/windows-exe-x64/*
456
./artifacts/linux-exe-x64/*
457
./artifacts/macos-exe-x64/*
458
./artifacts/macos-exe-arm64/*
419
459
./artifacts/debian-amd64/*
420
460
./artifacts/debian-arm64/*
421
461
./artifacts/debian-armhf/*
@@ -9,9 +9,9 @@ The `.github/workflows/build-packages.yml` workflow automatically builds multipl
9
9
### Supported Package Formats
10
10
11
11
1. **PyPI Package** - Python wheel and source distribution
12
2. **Windows Executable** - Standalone .exe file built with PyInstaller
13
3. **Linux Executable** - Standalone binary for Linux systems
14
4. **macOS Executable** - Standalone binary for macOS systems
12
2. **Windows Executable** - Standalone .exe file built with Nuitka
13
3. **Linux Executable** - Standalone binary for Linux systems built with Nuitka
14
4. **macOS Executable** - Standalone binary for macOS systems built with Nuitka (x64 and ARM64)
15
15
5. **Debian Packages** - .deb files for Ubuntu/Debian (amd64, arm64, armhf)
16
16
6. **WinGet Package** - Windows Package Manager manifest
17
17
7. **Docker Images** - Multi-architecture container images
@@ -59,7 +59,7 @@ After a successful build, packages are available:
59
59
The workflow handles all dependencies automatically, but for local development:
60
60
61
61
- Python 3.10+
62
- PyInstaller for executables
62
- Nuitka for executables (replaces PyInstaller)
63
63
- Docker for container builds
64
64
- dpkg-deb for Debian packages
65
65
@@ -68,6 +68,7 @@ The workflow handles all dependencies automatically, but for local development:
68
68
Key files for customization:
69
69
70
70
- `g4f_cli.py` - Entry point for executable builds
71
- `scripts/build-nuitka.sh` - Nuitka build script for all platforms
71
72
- `scripts/build-deb.sh` - Debian package build script
72
73
- `winget/manifests/` - WinGet package manifest templates
73
74
- `.github/workflows/build-packages.yml` - Main workflow configuration
@@ -0,0 +1,12 @@
1
#!/usr/bin/env python3
2
"""
3
Entry point for g4f CLI executable builds
4
This file is used as the main entry point for building executables with Nuitka
5
"""
6
7
import g4f.debug
8
g4f.debug.version_check = False
9
10
if __name__ == "__main__":
11
from g4f.cli import main
12
main()
@@ -0,0 +1,89 @@
1
#!/bin/bash
2
# Nuitka build script for g4f
3
# This script builds g4f executables using Nuitka for different platforms and architectures
4
5
set -e
6
7
# Default values
8
PLATFORM=${PLATFORM:-$(uname -s | tr '[:upper:]' '[:lower:]')}
9
ARCHITECTURE=${ARCHITECTURE:-$(uname -m)}
10
VERSION=${G4F_VERSION:-0.0.0-dev}
11
OUTPUT_DIR=${OUTPUT_DIR:-dist}
12
13
# Normalize architecture names
14
case "${ARCHITECTURE}" in
15
"x86_64"|"amd64")
16
ARCH="x64"
17
;;
18
"arm64"|"aarch64")
19
ARCH="arm64"
20
;;
21
"armv7l"|"armhf")
22
ARCH="armv7"
23
;;
24
*)
25
ARCH="${ARCHITECTURE}"
26
;;
27
esac
28
29
# Create output directory
30
mkdir -p "${OUTPUT_DIR}"
31
32
echo "Building g4f with Nuitka..."
33
echo "Platform: ${PLATFORM}"
34
echo "Architecture: ${ARCH} (${ARCHITECTURE})"
35
echo "Version: ${VERSION}"
36
echo "Output: ${OUTPUT_DIR}"
37
38
# Set output filename based on platform
39
case "${PLATFORM}" in
40
"windows"|"win32")
41
OUTPUT_NAME="g4f-windows-${VERSION}-${ARCH}.exe"
42
NUITKA_ARGS="--windows-console-mode=attach"
43
;;
44
"darwin"|"macos")
45
OUTPUT_NAME="g4f-macos-${VERSION}-${ARCH}"
46
NUITKA_ARGS="--macos-create-app-bundle"
47
;;
48
"linux")
49
OUTPUT_NAME="g4f-linux-${VERSION}-${ARCH}"
50
NUITKA_ARGS=""
51
;;
52
*)
53
OUTPUT_NAME="g4f-${PLATFORM}-${VERSION}-${ARCH}"
54
NUITKA_ARGS=""
55
;;
56
esac
57
58
# Basic Nuitka arguments
59
NUITKA_COMMON_ARGS="
60
--standalone
61
--onefile
62
--output-filename=${OUTPUT_NAME}
63
--output-dir=${OUTPUT_DIR}
64
--remove-output
65
--no-pyi-file
66
--assume-yes-for-downloads
67
--show-progress
68
--show-memory
69
"
70
71
# Platform-specific optimizations
72
if [[ "${PLATFORM}" == "windows" ]] && [[ -f "projects/windows/icon.ico" ]]; then
73
NUITKA_ARGS="${NUITKA_ARGS} --windows-icon-from-ico=projects/windows/icon.ico"
74
fi
75
76
# Build command
77
echo "Running Nuitka build..."
78
python -m nuitka ${NUITKA_COMMON_ARGS} ${NUITKA_ARGS} g4f_cli.py
79
80
echo "Build completed: ${OUTPUT_DIR}/${OUTPUT_NAME}"
81
82
# Verify the build
83
if [[ -f "${OUTPUT_DIR}/${OUTPUT_NAME}" ]]; then
84
echo "✓ Build successful!"
85
ls -la "${OUTPUT_DIR}/${OUTPUT_NAME}"
86
else
87
echo "✗ Build failed - output file not found"
88
exit 1
89
fi