Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
187 changes: 166 additions & 21 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ jobs:
artifacts/linux-packages-beta/**

# ─────────────────────────────────────────────────────────────────────────────
# STABLE RELEASE (main only) — Promote the matching beta build, no rebuild
# STABLE RELEASE (main only) — Rebuild from main with stable metadata
# ─────────────────────────────────────────────────────────────────────────────
get-version:
if: github.ref == 'refs/heads/main'
Expand Down Expand Up @@ -354,33 +354,176 @@ jobs:
exit 1
fi
echo "beta_tag=$TAG" >> "$GITHUB_OUTPUT"
echo "Promuovendo $TAG a stable v${VERSION}"
echo "Validated matching beta $TAG for stable v${VERSION}"

promote-stable:
build-windows-stable:
if: github.ref == 'refs/heads/main'
needs: [get-version, find-latest-beta]
runs-on: windows-latest
permissions:
contents: read
env:
ELECTRON_CACHE: ${{ github.workspace }}/.electron-cache
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: '3.12'
cache: pip
cache-dependency-path: python/requirements.txt
- name: Build Python sidecar
shell: pwsh
run: |
cd python
pip install -r requirements.txt -q
pip install pyinstaller -q
python -m PyInstaller main.py --onefile --name metalens-sidecar --distpath dist --clean --noconfirm `
--hidden-import piexif `
--hidden-import mutagen `
--hidden-import hachoir `
--hidden-import olefile `
--hidden-import openpyxl `
--hidden-import docx `
--hidden-import pptx `
--hidden-import pypdf
- uses: actions/setup-node@v6
with:
node-version: '22'
cache: npm
cache-dependency-path: frontend/package-lock.json
- name: Build React frontend
run: |
cd frontend
npm ci
npm run build
- name: Copy frontend dist into electron
run: cp -r frontend/dist electron/frontend
- name: Cache Electron download
uses: actions/cache@v4
with:
path: ${{ env.ELECTRON_CACHE }}
key: electron-${{ runner.os }}-${{ hashFiles('electron/package-lock.json') }}
- name: Package with Electron Forge
run: |
cd electron
npm ci --include=dev
npx electron-forge make
- name: Verify Windows artifacts use stable version
shell: pwsh
run: |
$version = "${{ needs.get-version.outputs.version }}"
$bad = Get-ChildItem electron/out -Recurse -File | Where-Object { $_.Name -match 'beta' }
if ($bad) {
$bad | ForEach-Object { Write-Error "Unexpected beta artifact: $($_.FullName)" }
exit 1
}
$expected = "electron/out/make/squirrel.windows/x64/MetaLens-$version-win-x64.exe"
if (!(Test-Path $expected)) {
Write-Error "Missing expected stable installer: $expected"
exit 1
}
- name: Upload Windows stable artifact
uses: actions/upload-artifact@v7
with:
name: windows-installer-stable
path: electron/out/make/**/*.exe
if-no-files-found: error

build-linux-stable:
if: github.ref == 'refs/heads/main'
needs: [get-version, find-latest-beta]
runs-on: ubuntu-latest
permissions:
contents: write
contents: read
env:
ELECTRON_CACHE: ${{ github.workspace }}/.electron-cache
steps:
- name: Download beta release assets
env:
GH_TOKEN: ${{ github.token }}
- uses: actions/checkout@v6
- name: Install system dependencies
run: sudo apt-get update -qq && sudo apt-get install -y rpm fakeroot
- uses: actions/setup-python@v6
with:
python-version: '3.12'
cache: pip
cache-dependency-path: python/requirements.txt
- name: Build Python sidecar
run: |
cd python
pip install -r requirements.txt -q
pip install pyinstaller -q
python -m PyInstaller main.py --onefile --name metalens-sidecar --distpath dist --clean --noconfirm \
--hidden-import piexif \
--hidden-import mutagen \
--hidden-import hachoir \
--hidden-import olefile \
--hidden-import openpyxl \
--hidden-import docx \
--hidden-import pptx \
--hidden-import pypdf
- uses: actions/setup-node@v6
with:
node-version: '22'
cache: npm
cache-dependency-path: frontend/package-lock.json
- name: Build React frontend
run: |
mkdir -p promoted
gh release download "${{ needs.find-latest-beta.outputs.beta_tag }}" \
--repo "$GITHUB_REPOSITORY" --dir promoted
- name: Strip beta suffix from filenames
cd frontend
npm ci
npm run build
- name: Copy frontend dist into electron
run: cp -r frontend/dist electron/frontend
- name: Configure RPM macros
run: echo '%_build_id_links none' >> ~/.rpmmacros
- name: Cache Electron download
uses: actions/cache@v4
with:
path: ${{ env.ELECTRON_CACHE }}
key: electron-${{ runner.os }}-${{ hashFiles('electron/package-lock.json') }}
- name: Package with Electron Forge
run: |
cd promoted
# Each maker encodes the beta suffix differently: "-beta.N" (exe/tar.gz),
# "beta.N" with no separator (rpm, dash stripped for Version field rules),
# ".beta.N" (deb, dot-separated per Debian version conventions).
for f in *; do
new=$(echo "$f" | sed -E 's/[-.]?beta\.?[0-9]+//')
if [ "$f" != "$new" ]; then mv -- "$f" "$new"; fi
done
ls -la
cd electron
npm ci --include=dev
npx electron-forge make
- name: Create Linux tar.gz
run: |
VERSION=${{ needs.get-version.outputs.version }}
APP_DIR=$(find electron/out -maxdepth 1 -type d -name "MetaLens-linux-*" | head -1)
if [ -n "$APP_DIR" ]; then
tar -czf "electron/out/make/MetaLens-${VERSION}-Linux.tar.gz" \
-C "$(dirname "$APP_DIR")" "$(basename "$APP_DIR")"
echo "Created MetaLens-${VERSION}-Linux.tar.gz"
else
echo "Warning: no MetaLens-linux-* directory found, skipping tar.gz"
fi
- name: Verify Linux artifacts use stable version
run: |
if find electron/out -type f -name '*beta*' | grep -q .; then
find electron/out -type f -name '*beta*'
echo "::error::Stable build produced beta-named artifacts."
exit 1
fi
- name: Upload Linux stable artifacts
uses: actions/upload-artifact@v7
with:
name: linux-packages-stable
path: |
electron/out/make/**/*.deb
electron/out/make/**/*.rpm
electron/out/make/**/*.tar.gz
if-no-files-found: error

release-stable:
if: github.ref == 'refs/heads/main'
needs: [get-version, find-latest-beta, build-windows-stable, build-linux-stable]
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/download-artifact@v8
with:
path: artifacts
- name: List artifacts
run: find artifacts -type f
- name: Create stable GitHub Release
uses: softprops/action-gh-release@v3
with:
Expand All @@ -391,4 +534,6 @@ jobs:
prerelease: false
generate_release_notes: true
make_latest: true
files: promoted/*
files: |
artifacts/windows-installer-stable/**
artifacts/linux-packages-stable/**
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,18 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) —

---

## [0.2.8] — 2026-07-25

### Fixed
- Stable releases now rebuild Windows and Linux packages from `main` with stable version metadata,
instead of republishing beta-built binaries with renamed filenames.

### Quality
- Stable release workflow verifies that generated artifacts do not contain beta suffixes in their
filenames.

---

## [0.2.7] — 2026-07-25

### Security
Expand Down
4 changes: 2 additions & 2 deletions electron/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion electron/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "metalens",
"version": "0.2.7",
"version": "0.2.8",
"description": "Universal File Metadata Manager",
"author": "Graziano Mariella",
"license": "MIT",
Expand Down
4 changes: 2 additions & 2 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "metalens-frontend",
"version": "0.2.7",
"version": "0.2.8",
"private": true,
"type": "module",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion python/config.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from dataclasses import dataclass


VERSION = "0.2.7"
VERSION = "0.2.8"
APP_NAME = "MetaLens"
SIDECAR_HOST = "127.0.0.1"

Expand Down
Loading