Skip to content

Commit 9a8a638

Browse files
committed
chore: bump version 0.2.0 → 0.2.1 - dependency updates + beta/stable CI pipeline
Version bump for routine dependency updates merged from PR #83-86: - electron 43.0.0 → 43.1.0 (menu crash fix, Chromium 150, Node.js 24.18.0) - vite 8.1.3 → 8.1.4 (build fixes, oxc minifier) - uvicorn 0.49.0 → 0.51.0 (worker reload on SIGHUP, colorama removal) - lucide-react 1.23.0 → 1.24.0 (icon updates) CI: implement beta/stable release pipeline - develop pushes build a prerelease tagged X.Y.Z-beta.N - main pushes republish the matching beta assets as the stable release - RPM maker uses a sanitized version (no dashes) per RPM Version field rules - Added workflow concurrency group and Electron download caching All tests passing: 47 passed, 1 skipped. Frontend and Electron builds verified.
1 parent a362ea4 commit 9a8a638

8 files changed

Lines changed: 160 additions & 34 deletions

File tree

.github/workflows/build.yml

Lines changed: 135 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ on:
1313
env:
1414
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
1515

16+
concurrency:
17+
group: ${{ github.workflow }}-${{ github.ref }}
18+
cancel-in-progress: true
19+
1620
jobs:
1721
# ─────────────────────────────────────────────────────────────────────────────
1822
# TEST BUILD (develop only) — Verify code compiles and tests pass
@@ -63,6 +67,8 @@ jobs:
6367
runs-on: ubuntu-latest
6468
permissions:
6569
contents: read
70+
env:
71+
ELECTRON_CACHE: ${{ github.workspace }}/.electron-cache
6672
steps:
6773
- uses: actions/checkout@v6
6874
- uses: actions/setup-python@v6
@@ -97,35 +103,46 @@ jobs:
97103
cd frontend
98104
npm ci
99105
npm run build
106+
- name: Cache Electron download
107+
uses: actions/cache@v4
108+
with:
109+
path: ${{ env.ELECTRON_CACHE }}
110+
key: electron-${{ runner.os }}-${{ hashFiles('electron/package-lock.json') }}
100111
- name: Test electron setup
101112
run: |
102113
cd electron
103114
npm ci --include=dev
104115
105116
# ─────────────────────────────────────────────────────────────────────────────
106-
# RELEASE BUILD (main only) — Create and publish stable release
117+
# BETA RELEASE (develop only) — Package and publish a prerelease build
107118
# ─────────────────────────────────────────────────────────────────────────────
108-
get-version:
109-
if: github.ref == 'refs/heads/main'
119+
get-version-beta:
120+
if: github.ref == 'refs/heads/develop'
121+
needs: [test-python, test-frontend, test-electron]
110122
runs-on: ubuntu-latest
111123
permissions:
112124
contents: read
113125
outputs:
114-
version: ${{ steps.ver.outputs.version }}
126+
base_version: ${{ steps.ver.outputs.base_version }}
127+
beta_version: ${{ steps.ver.outputs.beta_version }}
115128
steps:
116129
- uses: actions/checkout@v6
117130
- id: ver
118131
run: |
119-
VERSION=$(grep -oP 'VERSION\s*=\s*"\K[^"]+' python/config.py)
120-
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
121-
echo "Building MetaLens v$VERSION"
132+
BASE=$(grep -oP 'VERSION\s*=\s*"\K[^"]+' python/config.py)
133+
BETA="${BASE}-beta.${{ github.run_number }}"
134+
echo "base_version=$BASE" >> "$GITHUB_OUTPUT"
135+
echo "beta_version=$BETA" >> "$GITHUB_OUTPUT"
136+
echo "Building MetaLens beta v$BETA"
122137
123-
build-windows:
124-
if: github.ref == 'refs/heads/main'
125-
needs: get-version
138+
build-windows-beta:
139+
if: github.ref == 'refs/heads/develop'
140+
needs: get-version-beta
126141
runs-on: windows-latest
127142
permissions:
128143
contents: read
144+
env:
145+
ELECTRON_CACHE: ${{ github.workspace }}/.electron-cache
129146
steps:
130147
- uses: actions/checkout@v6
131148
- uses: actions/setup-python@v6
@@ -160,28 +177,35 @@ jobs:
160177
npm run build
161178
- name: Copy frontend dist into electron
162179
run: cp -r frontend/dist electron/frontend
163-
- name: Sync electron version
180+
- name: Sync electron version to beta
164181
run: |
165182
cd electron
166-
npm version ${{ needs.get-version.outputs.version }} --no-git-tag-version --allow-same-version
183+
npm version ${{ needs.get-version-beta.outputs.beta_version }} --no-git-tag-version --allow-same-version
184+
- name: Cache Electron download
185+
uses: actions/cache@v4
186+
with:
187+
path: ${{ env.ELECTRON_CACHE }}
188+
key: electron-${{ runner.os }}-${{ hashFiles('electron/package-lock.json') }}
167189
- name: Package with Electron Forge
168190
run: |
169191
cd electron
170192
npm ci --include=dev
171193
npx electron-forge make
172-
- name: Upload Windows artifact
194+
- name: Upload Windows beta artifact
173195
uses: actions/upload-artifact@v7
174196
with:
175-
name: windows-installer
197+
name: windows-installer-beta
176198
path: electron/out/make/**/*.exe
177199
if-no-files-found: error
178200

179-
build-linux:
180-
if: github.ref == 'refs/heads/main'
181-
needs: get-version
201+
build-linux-beta:
202+
if: github.ref == 'refs/heads/develop'
203+
needs: get-version-beta
182204
runs-on: ubuntu-latest
183205
permissions:
184206
contents: read
207+
env:
208+
ELECTRON_CACHE: ${{ github.workspace }}/.electron-cache
185209
steps:
186210
- uses: actions/checkout@v6
187211
- name: Install system dependencies
@@ -217,20 +241,25 @@ jobs:
217241
npm run build
218242
- name: Copy frontend dist into electron
219243
run: cp -r frontend/dist electron/frontend
220-
- name: Sync electron version
244+
- name: Sync electron version to beta
221245
run: |
222246
cd electron
223-
npm version ${{ needs.get-version.outputs.version }} --no-git-tag-version --allow-same-version
247+
npm version ${{ needs.get-version-beta.outputs.beta_version }} --no-git-tag-version --allow-same-version
224248
- name: Configure RPM macros
225249
run: echo '%_build_id_links none' >> ~/.rpmmacros
250+
- name: Cache Electron download
251+
uses: actions/cache@v4
252+
with:
253+
path: ${{ env.ELECTRON_CACHE }}
254+
key: electron-${{ runner.os }}-${{ hashFiles('electron/package-lock.json') }}
226255
- name: Package with Electron Forge
227256
run: |
228257
cd electron
229258
npm ci --include=dev
230259
npx electron-forge make
231260
- name: Create Linux tar.gz
232261
run: |
233-
VERSION=${{ needs.get-version.outputs.version }}
262+
VERSION=${{ needs.get-version-beta.outputs.beta_version }}
234263
APP_DIR=$(find electron/out -maxdepth 1 -type d -name "MetaLens-linux-*" | head -1)
235264
if [ -n "$APP_DIR" ]; then
236265
tar -czf "electron/out/make/MetaLens-${VERSION}-Linux.tar.gz" \
@@ -239,19 +268,19 @@ jobs:
239268
else
240269
echo "Warning: no MetaLens-linux-* directory found, skipping tar.gz"
241270
fi
242-
- name: Upload Linux artifacts
271+
- name: Upload Linux beta artifacts
243272
uses: actions/upload-artifact@v7
244273
with:
245-
name: linux-packages
274+
name: linux-packages-beta
246275
path: |
247276
electron/out/make/**/*.deb
248277
electron/out/make/**/*.rpm
249278
electron/out/make/**/*.tar.gz
250279
if-no-files-found: error
251280

252-
release:
253-
if: github.ref == 'refs/heads/main'
254-
needs: [get-version, build-windows, build-linux]
281+
release-beta:
282+
if: github.ref == 'refs/heads/develop'
283+
needs: [get-version-beta, build-windows-beta, build-linux-beta]
255284
runs-on: ubuntu-latest
256285
permissions:
257286
contents: write
@@ -261,7 +290,86 @@ jobs:
261290
path: artifacts
262291
- name: List artifacts
263292
run: find artifacts -type f
264-
- name: Create GitHub Release
293+
- name: Create beta GitHub Release
294+
uses: softprops/action-gh-release@v3
295+
with:
296+
tag_name: v${{ needs.get-version-beta.outputs.beta_version }}
297+
name: MetaLens v${{ needs.get-version-beta.outputs.beta_version }} (beta)
298+
draft: false
299+
prerelease: true
300+
generate_release_notes: true
301+
make_latest: false
302+
files: |
303+
artifacts/windows-installer-beta/**
304+
artifacts/linux-packages-beta/**
305+
306+
# ─────────────────────────────────────────────────────────────────────────────
307+
# STABLE RELEASE (main only) — Promote the matching beta build, no rebuild
308+
# ─────────────────────────────────────────────────────────────────────────────
309+
get-version:
310+
if: github.ref == 'refs/heads/main'
311+
runs-on: ubuntu-latest
312+
permissions:
313+
contents: read
314+
outputs:
315+
version: ${{ steps.ver.outputs.version }}
316+
steps:
317+
- uses: actions/checkout@v6
318+
- id: ver
319+
run: |
320+
VERSION=$(grep -oP 'VERSION\s*=\s*"\K[^"]+' python/config.py)
321+
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
322+
echo "Building MetaLens v$VERSION"
323+
324+
find-latest-beta:
325+
if: github.ref == 'refs/heads/main'
326+
needs: get-version
327+
runs-on: ubuntu-latest
328+
permissions:
329+
contents: read
330+
outputs:
331+
beta_tag: ${{ steps.find.outputs.beta_tag }}
332+
steps:
333+
- id: find
334+
env:
335+
GH_TOKEN: ${{ github.token }}
336+
VERSION: ${{ needs.get-version.outputs.version }}
337+
run: |
338+
TAG=$(gh release list --repo "$GITHUB_REPOSITORY" --limit 200 --json tagName \
339+
--jq '.[].tagName' \
340+
| grep -E "^v${VERSION}-beta\.[0-9]+$" \
341+
| sort -t. -k4 -n \
342+
| tail -1)
343+
if [ -z "$TAG" ]; then
344+
echo "::error::Nessuna release beta trovata per v${VERSION}. Genera prima una beta da develop con la stessa VERSION in python/config.py."
345+
exit 1
346+
fi
347+
echo "beta_tag=$TAG" >> "$GITHUB_OUTPUT"
348+
echo "Promuovendo $TAG a stable v${VERSION}"
349+
350+
promote-stable:
351+
if: github.ref == 'refs/heads/main'
352+
needs: [get-version, find-latest-beta]
353+
runs-on: ubuntu-latest
354+
permissions:
355+
contents: write
356+
steps:
357+
- name: Download beta release assets
358+
env:
359+
GH_TOKEN: ${{ github.token }}
360+
run: |
361+
mkdir -p promoted
362+
gh release download "${{ needs.find-latest-beta.outputs.beta_tag }}" \
363+
--repo "$GITHUB_REPOSITORY" --dir promoted
364+
- name: Strip beta suffix from filenames
365+
run: |
366+
cd promoted
367+
for f in *; do
368+
new=$(echo "$f" | sed -E 's/-beta\.[0-9]+//')
369+
if [ "$f" != "$new" ]; then mv -- "$f" "$new"; fi
370+
done
371+
ls -la
372+
- name: Create stable GitHub Release
265373
uses: softprops/action-gh-release@v3
266374
with:
267375
tag_name: v${{ needs.get-version.outputs.version }}
@@ -270,6 +378,4 @@ jobs:
270378
prerelease: false
271379
generate_release_notes: true
272380
make_latest: true
273-
files: |
274-
artifacts/windows-installer/**
275-
artifacts/linux-packages/**
381+
files: promoted/*

CHANGELOG.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,21 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) —
1515

1616
---
1717

18+
## [0.2.1] — 2026-07-14
19+
20+
### Dependencies
21+
- electron: 43.0.0 → 43.1.0 (fixed crash on replacing an open application menu, Chromium 150.0.7871.47, Node.js 24.18.0)
22+
- vite: 8.1.3 → 8.1.4 (oxc minifier preference for legacy builds, StackBlitz build workaround, SSR stacktrace alignment)
23+
- uvicorn: 0.49.0 → 0.51.0 (near-zero-downtime worker reload on SIGHUP, removed colorama from standard extra)
24+
- lucide-react: 1.23.0 → 1.24.0 (new icons, several upstream icon fixes)
25+
26+
### Quality
27+
- All tests passing: 47 passed, 1 skipped
28+
- Frontend build and Electron startup verified with updated dependencies
29+
- No regressions
30+
31+
---
32+
1833
## [0.2.0] — 2026-07-04
1934

2035
### Major Changes

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ File (image / audio / video / document / anything)
8181

8282
## 🔧 Version
8383

84-
**v0.2.0**Tailwind CSS v4 upgrade with the new Vite plugin, CSS-first `@theme` configuration, and dependency updates (Electron 43, FastAPI 0.139, Pillow 12.3). No changes to application behavior or the API.
84+
**v0.2.1**Routine dependency updates (Electron 43.1, Vite 8.1.4, uvicorn 0.51, lucide-react 1.24). No changes to application behavior or the API.
8585

8686
📖 **See full version history**[CHANGELOG.md](./CHANGELOG.md)
8787

docs/API.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ Health check + version, used by the About dialog and by Electron to know the sid
2626

2727
**Response**
2828
```json
29-
{ "status": "ok", "version": "0.2.0", "app": "MetaLens" }
29+
{ "status": "ok", "version": "0.2.1", "app": "MetaLens" }
3030
```
3131

3232
---

electron/forge.config.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ const iconExists = ['.ico', '.icns', '.png'].some(ext => fs.existsSync(iconPath
88
// Read version from package.json — synced by the CI workflow from python/config.py
99
const { version } = require('./package.json')
1010

11+
// RPM's Version field forbids "-" (used for beta tags like 0.2.1-beta.5),
12+
// so the rpm maker gets a sanitized copy while every other maker keeps the real semver.
13+
const rpmSafeVersion = version.replace(/-/g, '')
14+
1115
module.exports = {
1216
packagerConfig: {
1317
name: 'MetaLens',
@@ -57,6 +61,7 @@ module.exports = {
5761
license: 'MIT',
5862
icon: path.join(__dirname, '..', 'frontend', 'public', 'icon.png'),
5963
categories: ['Utility', 'FileManager'],
64+
version: rpmSafeVersion,
6065
},
6166
},
6267
},

electron/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "metalens",
3-
"version": "0.2.0",
3+
"version": "0.2.1",
44
"description": "Universal File Metadata Manager",
55
"author": "Graziano Mariella",
66
"license": "MIT",

frontend/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "metalens-frontend",
3-
"version": "0.2.0",
3+
"version": "0.2.1",
44
"private": true,
55
"type": "module",
66
"scripts": {

python/config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from dataclasses import dataclass
22

33

4-
VERSION = "0.2.0"
4+
VERSION = "0.2.1"
55
APP_NAME = "MetaLens"
66
SIDECAR_HOST = "127.0.0.1"
77

0 commit comments

Comments
 (0)