1+ name : Cross-platform Release
2+
3+ # Display the Tag Name (e.g., "v1.0.0") as the workflow run title
4+ run-name : Release ${{ github.ref_name }}
5+
6+ permissions :
7+ contents : write
8+
9+ on :
10+ push :
11+ tags :
12+ - ' v*'
13+ workflow_dispatch :
14+
15+ jobs :
16+ # ==================================================
17+ # JOB 1: Build Binaries
18+ # ==================================================
19+ build :
20+ name : Build ${{ matrix.tag }}
21+ runs-on : ${{ matrix.runner }}
22+ strategy :
23+ fail-fast : false
24+ matrix :
25+ include :
26+ # Windows (Standard x64)
27+ - runner : windows-latest
28+ os : windows
29+ python : " 3.10"
30+ arch : x64
31+ tag : windows-x64
32+
33+ # macOS (Apple Silicon M1/M2/M3) - Mainstream
34+ - runner : macos-latest
35+ os : macos
36+ python : " 3.10"
37+ arch : arm64
38+ tag : macos-arm64
39+
40+ # Linux (Standard x64 Server/Desktop)
41+ - runner : ubuntu-latest
42+ os : ubuntu
43+ python : " 3.10"
44+ arch : x64
45+ tag : linux-x64
46+
47+ # Linux (ARM64 for Raspberry Pi / Oracle Cloud)
48+ # Note: Uses GitHub's new ARM runner
49+ - runner : ubuntu-24.04-arm
50+ os : ubuntu
51+ python : " 3.10"
52+ arch : arm64
53+ tag : linux-arm64
54+
55+ steps :
56+ - name : Checkout repository
57+ uses : actions/checkout@v4
58+
59+ # Resolve Version ID
60+ - name : Resolve Version
61+ id : version
62+ shell : bash
63+ run : |
64+ if [[ "${{ github.ref }}" == refs/tags/* ]]; then
65+ echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
66+ else
67+ echo "VERSION=nightly-${GITHUB_SHA::7}" >> $GITHUB_OUTPUT
68+ fi
69+
70+ - name : Set up Python
71+ uses : actions/setup-python@v5
72+ with :
73+ python-version : ${{ matrix.python }}
74+ architecture : ${{ matrix.arch }}
75+
76+ - name : Install dependencies
77+ run : |
78+ python -m pip install --upgrade pip
79+ pip install -r requirements.txt pyinstaller
80+
81+ # Build Command
82+ - name : Build with PyInstaller
83+ shell : bash
84+ run : |
85+ pyinstaller --clean --onefile \
86+ --collect-all rich \
87+ --name "mailbot-${{ matrix.tag }}" main.py
88+
89+ # Bundle binary and create default config
90+ - name : Bundle binary and config
91+ shell : bash
92+ run : |
93+ set -euo pipefail
94+ VERSION="${{ steps.version.outputs.VERSION }}"
95+ BUNDLE="mailbot-${VERSION}-${{ matrix.tag }}"
96+
97+ # Locate the binary (handles .exe on Windows automatically)
98+ BIN_SRC=$(ls dist/mailbot-* | head -n 1)
99+
100+ mkdir -p bundle/$BUNDLE
101+ cp "$BIN_SRC" "bundle/$BUNDLE/"
102+
103+ # Create default config.json
104+ cat > "bundle/$BUNDLE/config.json" <<'EOF'
105+ {
106+ "poll_interval": 60,
107+ "max_retries": 3,
108+ "log_level": "INFO",
109+ "accounts": [],
110+ "notifiers": []
111+ }
112+ EOF
113+
114+ # Zip the bundle using Python (cross-platform way)
115+ python - <<'PY'
116+ import shutil
117+ from pathlib import Path
118+
119+ bundle_root = Path("bundle")
120+ for pkg_dir in bundle_root.iterdir():
121+ if pkg_dir.is_dir():
122+ shutil.make_archive(str(pkg_dir), "zip", root_dir=pkg_dir)
123+ PY
124+
125+ - name : Upload Artifact
126+ uses : actions/upload-artifact@v4
127+ with :
128+ name : mailbot-${{ steps.version.outputs.VERSION }}-${{ matrix.tag }}
129+ path : bundle/*.zip
130+ if-no-files-found : error
131+
132+ # ==================================================
133+ # JOB 2: Publish Release
134+ # ==================================================
135+ release :
136+ name : Publish Release
137+ needs : build
138+ runs-on : ubuntu-latest
139+ if : startsWith(github.ref, 'refs/tags/')
140+
141+ steps :
142+ - name : Download All Artifacts
143+ uses : actions/download-artifact@v4
144+ with :
145+ pattern : mailbot-*
146+ path : release_assets
147+ merge-multiple : true
148+
149+ - name : Create Release
150+ uses : softprops/action-gh-release@v2
151+ with :
152+ name : MailBot ${{ github.ref_name }} # Title of the Release page
153+ files : release_assets/*
154+ draft : true
155+ generate_release_notes : true
156+ env :
157+ GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
0 commit comments