@@ -2,6 +2,8 @@ name: Build Bangen (Nuitka)
22
33on :
44 push :
5+ branches :
6+ - main
57 tags :
68 - " v*"
79 workflow_dispatch :
@@ -10,7 +12,45 @@ permissions:
1012 contents : write
1113
1214jobs :
15+ # --- Tagging Job ---
16+ # Ensures a version tag exists based on pyproject.toml if triggered from a branch
17+ tag :
18+ if : github.ref_type == 'branch'
19+ runs-on : ubuntu-latest
20+ outputs :
21+ version : ${{ steps.version.outputs.VERSION }}
22+ steps :
23+ - uses : actions/checkout@v4
24+ with :
25+ fetch-depth : 0
26+
27+ - name : Extract version
28+ id : version
29+ run : |
30+ VERSION=$(python - <<EOF
31+ import tomllib, pathlib
32+ data = tomllib.loads(pathlib.Path("pyproject.toml").read_text())
33+ print(data["project"]["version"])
34+ EOF
35+ )
36+ echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
37+
38+ - name : Create tag if missing
39+ run : |
40+ TAG_NAME="v${{ steps.version.outputs.VERSION }}"
41+ if git rev-parse "$TAG_NAME" >/dev/null 2>&1; then
42+ echo "Tag $TAG_NAME already exists."
43+ else
44+ git config user.name "github-actions"
45+ git config user.email "github-actions@github.com"
46+ git tag "$TAG_NAME"
47+ git push origin "$TAG_NAME"
48+ fi
49+
50+ # --- Build Job ---
51+ # Compiles the application into a single executable for Linux, macOS, and Windows
1352 build :
53+ needs : tag
1454 strategy :
1555 fail-fast : false
1656 matrix :
@@ -21,38 +61,46 @@ jobs:
2161 name : macos
2262 - os : windows-latest
2363 name : windows
24-
2564 runs-on : ${{ matrix.os }}
26-
2765 steps :
2866 - uses : actions/checkout@v4
2967
30- - name : Build fingerprint + cache key
68+ - name : Extract Metadata & Validate
3169 id : meta
3270 shell : bash
3371 run : |
34- VERSION=${GITHUB_REF_NAME#v}
35- SHA=$(git rev-parse --short HEAD)
72+ PYPROJECT_VERSION=$(python - <<EOF
73+ import tomllib, pathlib
74+ data = tomllib.loads(pathlib.Path("pyproject.toml").read_text())
75+ print(data["project"]["version"])
76+ EOF
77+ )
3678
37- # sha256sum on Linux, shasum on macOS — both unavailable on Windows
38- # so we use Python for a cross-platform hash
39- DEPS_HASH=$(python -c "
79+ if [[ "${GITHUB_REF}" == refs/tags/* ]]; then
80+ VERSION=${GITHUB_REF_NAME#v}
81+ else
82+ VERSION=$PYPROJECT_VERSION
83+ fi
84+
85+ SHA=$(git rev-parse --short HEAD)
86+ DEPS_HASH=$(python - <<EOF
4087 import hashlib, pathlib
41- p = pathlib.Path('pyproject.toml')
42- print(hashlib.sha256(p.read_bytes()).hexdigest()[:16] if p.exists() else 'nodeps')
43- ")
88+ p = pathlib.Path("pyproject.toml")
89+ print(hashlib.sha256(p.read_bytes()).hexdigest()[:16])
90+ EOF
91+ )
4492
45- echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
46- echo "SHA=$SHA" >> $GITHUB_OUTPUT
47- echo "DEPS=$DEPS_HASH" >> $GITHUB_OUTPUT
93+ echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
94+ echo "SHA=$SHA" >> $GITHUB_OUTPUT
4895 echo "CACHE_KEY=${{ runner.os }}-$VERSION-$DEPS_HASH" >> $GITHUB_OUTPUT
4996
50- - uses : actions/setup-python@v5
97+ - name : Setup Python
98+ uses : actions/setup-python@v5
5199 with :
52100 python-version : " 3.11"
53101 cache : " pip"
54102
55- - name : Cross-workflow cache ( Nuitka + deps)
103+ - name : Cache Nuitka
56104 uses : actions/cache@v4
57105 with :
58106 path : |
@@ -62,34 +110,28 @@ jobs:
62110 ~\AppData\Local\Nuitka\Nuitka\Cache
63111 key : nuitka-${{ steps.meta.outputs.CACHE_KEY }}
64112 restore-keys : |
65- nuitka-${{ runner.os }}-${{ steps.meta.outputs.VERSION }}-
66113 nuitka-${{ runner.os }}-
67114
68- - name : Install system deps (Linux)
115+ - name : Install System Dependencies (Linux)
69116 if : runner.os == 'Linux'
70- # build-essential already pulls in binutils (which provides strip).
71- # Do NOT list "strip" — it is not a package name and will abort apt.
72117 run : sudo apt-get update && sudo apt-get install -y build-essential patchelf
73118
74- - name : Install system deps (macOS)
119+ - name : Install System Dependencies (macOS)
75120 if : runner.os == 'macOS'
76121 run : xcode-select -p || xcode-select --install || true
77122
78- - name : MSVC setup (Windows)
123+ - name : MSVC Setup (Windows)
79124 if : runner.os == 'Windows'
80125 uses : ilammy/msvc-dev-cmd@v1
81126
82- - name : Install Python deps
127+ - name : Install Python Dependencies
83128 run : |
84129 python -m pip install -U pip wheel
85- # setuptools>=72 removed pkg_resources.DefaultProvider, which
86- # Nuitka 4.x's bundled Jinja2 copy requires during C code generation.
87- # Pin below 72 until Nuitka ships its own Jinja2 fix.
88130 pip install "setuptools<72"
89131 pip install nuitka[onefile]
90132 pip install .
91133
92- - name : Create entrypoint
134+ - name : Create Entrypoint Script
93135 shell : bash
94136 run : |
95137 cat > _entry.py << 'EOF'
@@ -103,95 +145,52 @@ jobs:
103145 run : |
104146 python -m nuitka \
105147 --onefile \
106- --lto=yes \
107- --jobs=2 \
148+ --jobs=auto \
108149 --assume-yes-for-downloads \
109150 --output-dir=build \
110151 --output-filename=bangen \
111- --include-package=bangen \
112- --include-package=rich \
113- --include-package=pyfiglet \
114- --include-package=PIL \
115- --include-package=typer \
116- --include-package=click \
117152 --nofollow-import-to=tkinter \
118153 --nofollow-import-to=unittest \
119154 --nofollow-import-to=test \
120- --nofollow-import-to=distutils \
121- --nofollow-import-to=setuptools \
122- --nofollow-import-to=pkg_resources \
123155 --python-flag=no_asserts \
124156 --python-flag=no_docstrings \
125157 --python-flag=isolated \
126- "--onefile-tempdir-spec={CACHE_DIR}/bangen/${{ steps.meta.outputs.VERSION }}" \
158+ --onefile-tempdir-spec="{TEMP}/bangen" \
159+ --plugin-enable=anti-bloat \
127160 _entry.py
128161
129- - name : Stage fingerprinted artifact
162+ - name : Stage Artifact
130163 shell : bash
131164 run : |
132165 mkdir -p dist
133166 NAME="bangen-${{ matrix.name }}-${{ steps.meta.outputs.VERSION }}-${{ steps.meta.outputs.SHA }}"
134-
135- if [[ "$RUNNER_OS" == "Linux" ]]; then
136- mv build/bangen dist/$NAME
137- # strip is provided by binutils (part of build-essential)
138- strip dist/$NAME
139- elif [[ "$RUNNER_OS" == "macOS" ]]; then
140- mv build/bangen dist/$NAME
141- # strip ships with Xcode Command Line Tools
142- strip dist/$NAME
167+ if [[ "$RUNNER_OS" == "Windows" ]]; then
168+ mv build/bangen.exe "dist/$NAME.exe"
143169 else
144- # Nuitka always appends .exe on Windows regardless of --output-filename
145- mv build/bangen.exe dist/$NAME.exe
170+ mv build/bangen "dist/$NAME"
146171 fi
147172
148- - uses : actions/upload-artifact@v4
173+ - name : Upload Artifact
174+ uses : actions/upload-artifact@v4
149175 with :
150176 name : ${{ matrix.name }}-build
151177 path : dist/*
152178
179+ # --- Release Job ---
180+ # Consolidates all builds and creates a draft GitHub Release
153181 release :
154- needs : build
182+ needs : [tag, build]
155183 runs-on : ubuntu-latest
156-
157184 steps :
158- # Checkout is required so git log/describe have history to work with
159- - uses : actions/checkout@v4
160- with :
161- fetch-depth : 0 # full history so git describe can find previous tags
162-
163185 - uses : actions/download-artifact@v4
164186 with :
165187 path : artifacts
166- merge-multiple : true # flatten into artifacts/ instead of artifacts/<name>/
188+ merge-multiple : true
167189
168- - name : Generate changelog
169- id : changelog
170- shell : bash
171- run : |
172- PREV=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "")
173- {
174- echo "CHANGELOG<<EOF"
175- if [[ -n "$PREV" ]]; then
176- git log "$PREV"..HEAD --pretty=format:"- %s"
177- else
178- git log --pretty=format:"- %s"
179- fi
180- echo ""
181- echo "EOF"
182- } >> $GITHUB_OUTPUT
183-
184- - name : Create DRAFT release
190+ - name : Create Draft Release
185191 uses : softprops/action-gh-release@v2
186192 with :
187- tag_name : ${{ github.ref_name }}
188- name : Bangen ${{ github.ref_name }}
189- body : |
190- ## 🚀 Changes
191- ${{ steps.changelog.outputs.CHANGELOG }}
192-
193- ## 🧬 Build Info
194- - Commit: `${{ github.sha }}`
195- - Matrix build: Linux · macOS · Windows
196- - Nuitka LTO + onefile
197- files : artifacts/*
193+ tag_name : v${{ needs.tag.outputs.version }}
194+ name : Bangen v${{ needs.tag.outputs.version }}
195+ draft : true
196+ files : artifacts/*
0 commit comments