259 lines
10 KiB
YAML
259 lines
10 KiB
YAML
name: Desktop installers
|
|
|
|
# Produit les installeurs de BUREAU (.msi Windows + AppImage Linux) et les publie
|
|
# en tant qu'assets d'une GitHub Release, sur tag `v*`.
|
|
#
|
|
# Complementaire au pipeline Gitea Actions (.gitea/workflows/release.yml) qui,
|
|
# lui, build et pousse les IMAGES Docker. Ici on est sur GitHub car jpackage ne
|
|
# sait PAS cross-compiler : le .msi DOIT etre construit sur un runner Windows et
|
|
# l'AppImage sur un runner Linux — GitHub fournit les deux gratuitement.
|
|
#
|
|
# Prerequis : le depot Gitea doit etre mirrore vers GitHub (push mirror, tags
|
|
# inclus) pour que le tag declenche ce workflow.
|
|
#
|
|
# Tag stable vX.Y.Z -> GitHub Release PUBLIQUE avec le .msi attache.
|
|
# Tag beta vX.Y.Z-beta* -> AUCUNE publication publique. Le .msi est depose en
|
|
# ARTEFACT PRIVE du run (telechargeable seulement par
|
|
# toi via l'onglet Actions) ; tu le joins ensuite a un
|
|
# post Patreon reserve a un palier. Patreon = la
|
|
# barriere d'acces (equivalent du registry prive +
|
|
# relais pour les images Docker beta).
|
|
|
|
on:
|
|
push:
|
|
tags: ['v*']
|
|
# Declenchement MANUEL depuis l'onglet Actions ("Run workflow"). Utile quand un
|
|
# tag a ete pousse AVANT que le workflow existe sur GitHub (ne se redeclenche
|
|
# pas tout seul), ou pour rejouer un build. Saisir la version SANS le "v".
|
|
workflow_dispatch:
|
|
inputs:
|
|
version:
|
|
description: "Version a builder (doit correspondre a un tag existant, ex: 0.15.0 ou 0.15.0-beta)"
|
|
required: true
|
|
|
|
permissions:
|
|
contents: write # requis pour creer la Release et y attacher le .msi
|
|
|
|
jobs:
|
|
# GATE : les 3 suites unitaires (Java / Python / Angular) doivent passer avant
|
|
# de construire le .msi. Tourne sur ubuntu-latest (moins cher/plus rapide que
|
|
# windows) ; le build natif lui-meme reste sur windows-latest via `needs`.
|
|
# Auto-suffisant : ne depend PAS du resultat de Gitea (CI separee), il rejoue
|
|
# les memes tests ici. Un test rouge => pas d'installeur publie.
|
|
tests:
|
|
runs-on: ubuntu-latest
|
|
# Base PostgreSQL réelle pour les tests Core. Sur les runners GitHub (job sur
|
|
# la VM, pas en conteneur), le service est joignable via localhost + le port mappé.
|
|
services:
|
|
postgres:
|
|
image: postgres:16-alpine
|
|
env:
|
|
POSTGRES_DB: loremind_test
|
|
POSTGRES_USER: loremind_test
|
|
POSTGRES_PASSWORD: loremind_test
|
|
ports:
|
|
- 5432:5432
|
|
options: >-
|
|
--health-cmd "pg_isready -U loremind_test -d loremind_test"
|
|
--health-interval 10s
|
|
--health-timeout 5s
|
|
--health-retries 10
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
ref: ${{ github.event_name == 'workflow_dispatch' && format('v{0}', inputs.version) || github.ref }}
|
|
|
|
- name: Set up JDK 17
|
|
uses: actions/setup-java@v4
|
|
with:
|
|
distribution: temurin
|
|
java-version: '17'
|
|
cache: maven
|
|
- name: Core — mvn test (+ JaCoCo check)
|
|
working-directory: core
|
|
env:
|
|
SPRING_DATASOURCE_URL: jdbc:postgresql://localhost:5432/loremind_test
|
|
SPRING_DATASOURCE_USERNAME: loremind_test
|
|
SPRING_DATASOURCE_PASSWORD: loremind_test
|
|
run: |
|
|
chmod +x ./mvnw
|
|
./mvnw -B test
|
|
|
|
- name: Set up Python 3.12
|
|
uses: actions/setup-python@v5
|
|
with:
|
|
python-version: '3.12'
|
|
cache: pip
|
|
cache-dependency-path: brain/requirements-dev.txt
|
|
- name: Brain — pytest (+ couverture)
|
|
working-directory: brain
|
|
run: |
|
|
pip install -r requirements-dev.txt
|
|
pytest --cov=app --cov-report=term-missing --cov-fail-under=50
|
|
|
|
- name: Set up Node 20
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: '20'
|
|
cache: npm
|
|
cache-dependency-path: web/package-lock.json
|
|
- name: Web — vitest (+ couverture)
|
|
working-directory: web
|
|
run: |
|
|
npm ci --no-audit --no-fund
|
|
npm run test:unit:coverage
|
|
|
|
windows:
|
|
needs: tests
|
|
runs-on: windows-latest
|
|
steps:
|
|
# En declenchement manuel, on checkout le TAG correspondant a la version
|
|
# saisie (sinon checkout prendrait la branche par defaut). En push de tag,
|
|
# on prend la ref poussee.
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
ref: ${{ github.event_name == 'workflow_dispatch' && format('v{0}', inputs.version) || github.ref }}
|
|
|
|
# Apporte jpackage (lanceur d'empaquetage natif) dans le PATH.
|
|
- name: Set up JDK 21
|
|
uses: actions/setup-java@v4
|
|
with:
|
|
distribution: temurin
|
|
java-version: '21'
|
|
|
|
- name: Set up Node
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: '20'
|
|
|
|
# Python 3.12 = meme version que l'image Docker du Brain (coherence runtime).
|
|
- name: Set up Python
|
|
uses: actions/setup-python@v5
|
|
with:
|
|
python-version: '3.12'
|
|
|
|
# jpackage genere le MSI via WiX Toolset v3 (candle.exe/light.exe). WiX 4+
|
|
# ne convient pas (outils renommes). Le paquet choco `wixtoolset` est la
|
|
# ligne 3.x et s'ajoute au PATH.
|
|
- name: Install WiX Toolset 3
|
|
shell: pwsh
|
|
run: choco install wixtoolset -y --no-progress
|
|
|
|
# Tesseract OCR : non preinstalle sur windows-latest. Requis pour que
|
|
# build-windows.ps1 embarque l'OCR des PDF scannes (sinon il skip en
|
|
# degradation gracieuse). Installe dans %ProgramFiles%\Tesseract-OCR.
|
|
- name: Install Tesseract OCR
|
|
shell: pwsh
|
|
run: choco install tesseract -y --no-progress
|
|
|
|
# Version de l'installeur = version du tag (push) OU de l'input (manuel).
|
|
# Sorties : version (numerique X.Y.Z pour le MSI), tag (vX.Y.Z[-beta]),
|
|
# isbeta (true/false) — independant du nom de ref (qui est une branche en manuel).
|
|
- name: Derive version
|
|
id: ver
|
|
shell: pwsh
|
|
run: |
|
|
if ('${{ github.event_name }}' -eq 'workflow_dispatch') {
|
|
$raw = '${{ inputs.version }}'
|
|
} else {
|
|
$raw = '${{ github.ref_name }}'
|
|
}
|
|
$raw = $raw -replace '^v','' # 0.15.0 ou 0.15.0-beta
|
|
$num = ($raw -split '-')[0] # 0.15.0
|
|
$isbeta = if ($raw -like '*-beta*') { 'true' } else { 'false' }
|
|
"version=$num" >> $env:GITHUB_OUTPUT
|
|
"tag=v$raw" >> $env:GITHUB_OUTPUT
|
|
"isbeta=$isbeta" >> $env:GITHUB_OUTPUT
|
|
|
|
- name: Build Windows installer
|
|
shell: pwsh
|
|
run: .\installers\desktop\build-windows.ps1 -Version ${{ steps.ver.outputs.version }}
|
|
|
|
# STABLE uniquement : Release GitHub publique avec le .msi.
|
|
# tag_name explicite : en declenchement manuel, github.ref est une branche,
|
|
# donc on cible le tag derive (la release est attachee au bon tag).
|
|
- name: Publish installer to GitHub Release (stable)
|
|
if: ${{ steps.ver.outputs.isbeta == 'false' }}
|
|
uses: softprops/action-gh-release@v2
|
|
with:
|
|
tag_name: ${{ steps.ver.outputs.tag }}
|
|
files: core/target/dist-out/*.msi
|
|
fail_on_unmatched_files: true
|
|
generate_release_notes: true
|
|
|
|
# BETA uniquement : artefact PRIVE (pas de release publique). A recuperer
|
|
# via l'onglet Actions puis a joindre a un post Patreon gate par palier.
|
|
- name: Upload installer as private artifact (beta)
|
|
if: ${{ steps.ver.outputs.isbeta == 'true' }}
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: loremind-beta-${{ steps.ver.outputs.version }}-msi
|
|
path: core/target/dist-out/*.msi
|
|
retention-days: 90
|
|
|
|
# LINUX : AppImage (1 fichier, toutes distros) attache a la MEME release.
|
|
# Tourne sur ubuntu-latest (jpackage ne cross-compile pas -> build natif Linux).
|
|
# Brain empaquete via python-build-standalone (pas de Python embeddable Linux
|
|
# officiel ; pas de PyInstaller -> pas de faux positif AV). Memes regles de
|
|
# publication que windows : stable -> release publique ; beta -> artefact prive.
|
|
linux:
|
|
needs: tests
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
ref: ${{ github.event_name == 'workflow_dispatch' && format('v{0}', inputs.version) || github.ref }}
|
|
|
|
# Apporte jpackage (empaquetage natif) dans le PATH.
|
|
- name: Set up JDK 21
|
|
uses: actions/setup-java@v4
|
|
with:
|
|
distribution: temurin
|
|
java-version: '21'
|
|
|
|
- name: Set up Node
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: '20'
|
|
|
|
# Pas de setup-python : le Brain utilise SON python-build-standalone
|
|
# (telecharge par le script, avec son propre pip). Le host n'en a pas besoin.
|
|
|
|
# Version (numerique X.Y.Z) + tag + isbeta, comme le job windows.
|
|
- name: Derive version
|
|
id: ver
|
|
run: |
|
|
if [ '${{ github.event_name }}' = 'workflow_dispatch' ]; then
|
|
raw='${{ inputs.version }}'
|
|
else
|
|
raw='${{ github.ref_name }}'
|
|
fi
|
|
raw="${raw#v}" # 0.15.0 ou 0.15.0-beta
|
|
num="${raw%%-*}" # 0.15.0
|
|
case "$raw" in *-beta*) isbeta=true ;; *) isbeta=false ;; esac
|
|
echo "version=$num" >> "$GITHUB_OUTPUT"
|
|
echo "tag=v$raw" >> "$GITHUB_OUTPUT"
|
|
echo "isbeta=$isbeta" >> "$GITHUB_OUTPUT"
|
|
|
|
- name: Build Linux AppImage
|
|
run: bash ./installers/desktop/build-linux.sh --version ${{ steps.ver.outputs.version }}
|
|
|
|
# STABLE uniquement : attache l'AppImage a la release publique (meme tag que
|
|
# le .msi -> les deux installeurs sur la meme release).
|
|
- name: Publish AppImage to GitHub Release (stable)
|
|
if: ${{ steps.ver.outputs.isbeta == 'false' }}
|
|
uses: softprops/action-gh-release@v2
|
|
with:
|
|
tag_name: ${{ steps.ver.outputs.tag }}
|
|
files: core/target/dist-out/*.AppImage
|
|
fail_on_unmatched_files: true
|
|
|
|
# BETA uniquement : artefact PRIVE (pas de release publique).
|
|
- name: Upload AppImage as private artifact (beta)
|
|
if: ${{ steps.ver.outputs.isbeta == 'true' }}
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: loremind-beta-${{ steps.ver.outputs.version }}-appimage
|
|
path: core/target/dist-out/*.AppImage
|
|
retention-days: 90
|