Compare commits
1
Commits
03b48f063c
...
installer
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d63ac31b8a |
No files matched your search
@@ -1,6 +1,6 @@
|
|||||||
# Baut die Windows-Version (.exe, mit Windows-Python unter Wine) und die Linux-Version.
|
# Baut die Windows-Version (.exe, mit Windows-Python unter Wine) und die Linux-Version.
|
||||||
# - jeder Push / PR: Tests + Programmdateien als Build-Artefakte
|
# - jeder Push / PR: Tests + Programmdateien als Build-Artefakte
|
||||||
# - Tag "v*" (z. B. v1.0.0): zusätzlich Gitea-Release mit .exe, .zip und Linux-.tar.gz
|
# - Tag "v*" (z. B. v1.0.0): zusätzlich Gitea-Release mit .exe, .zip, Setup und Linux-.tar.gz
|
||||||
name: Build
|
name: Build
|
||||||
|
|
||||||
on:
|
on:
|
||||||
@@ -37,6 +37,7 @@ jobs:
|
|||||||
path: |
|
path: |
|
||||||
dist/Provisionsmanager95.exe
|
dist/Provisionsmanager95.exe
|
||||||
dist/Provisionsmanager95-*.zip
|
dist/Provisionsmanager95-*.zip
|
||||||
|
dist/Provisionsmanager-Setup-*.exe
|
||||||
|
|
||||||
- name: Release erstellen / ergänzen
|
- name: Release erstellen / ergänzen
|
||||||
if: startsWith(github.ref, 'refs/tags/v')
|
if: startsWith(github.ref, 'refs/tags/v')
|
||||||
@@ -44,7 +45,9 @@ jobs:
|
|||||||
TOKEN: ${{ secrets.RELEASE_TOKEN || secrets.GITEA_TOKEN }}
|
TOKEN: ${{ secrets.RELEASE_TOKEN || secrets.GITEA_TOKEN }}
|
||||||
API: ${{ github.server_url }}/api/v1/repos/${{ github.repository }}
|
API: ${{ github.server_url }}/api/v1/repos/${{ github.repository }}
|
||||||
TAG: ${{ github.ref_name }}
|
TAG: ${{ github.ref_name }}
|
||||||
run: build/release_hochladen.sh dist/Provisionsmanager95.exe dist/Provisionsmanager95-$(tr -d '\r\n' < dist/VERSION).zip
|
run: |
|
||||||
|
V=$(tr -d '\r\n' < dist/VERSION)
|
||||||
|
build/release_hochladen.sh dist/Provisionsmanager95.exe dist/Provisionsmanager95-$V.zip dist/Provisionsmanager-Setup-$V.exe
|
||||||
|
|
||||||
linux:
|
linux:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|||||||
@@ -5,6 +5,16 @@ von **freenet** (CSV/Excel) und **Vodafone/Euronics** (Excel) ein, ordnet die Po
|
|||||||
Unterhändlern zu, erlaubt freie Anpassung der Auszahlung und exportiert je Händler eine
|
Unterhändlern zu, erlaubt freie Anpassung der Auszahlung und exportiert je Händler eine
|
||||||
fertige Excel-Abrechnung. Optik: Windows 95.
|
fertige Excel-Abrechnung. Optik: Windows 95.
|
||||||
|
|
||||||
|
## Installation (Windows)
|
||||||
|
|
||||||
|
`Provisionsmanager-Setup-<version>.exe` aus dem Release herunterladen und starten – keine
|
||||||
|
Admin-Rechte nötig. Das Programm landet in `%LOCALAPPDATA%\Programs\Provisionsmanager` mit
|
||||||
|
Eintrag im Startmenü (Desktop-Verknüpfung optional) und startet schneller als die einzelne `.exe`.
|
||||||
|
Ein Update installiert man einfach drüber (ein laufendes Programm wird dafür geschlossen).
|
||||||
|
Deinstallieren über *Einstellungen ▸ Apps*; Datenbank und Einstellungen in
|
||||||
|
`%APPDATA%\Provisionsmanager95` bleiben dabei erhalten. Ohne Installation geht weiterhin
|
||||||
|
`Provisionsmanager95.exe` (bzw. das `.zip`) – einfach starten.
|
||||||
|
|
||||||
## Erster Start
|
## Erster Start
|
||||||
|
|
||||||
Beim ersten Start führt ein **Einrichtungs-Assistent** durch Speicherort, Unterhändler
|
Beim ersten Start führt ein **Einrichtungs-Assistent** durch Speicherort, Unterhändler
|
||||||
@@ -134,7 +144,9 @@ Gitea Actions (`.gitea/workflows/windows-build.yml`) baut die `.exe` im Containe
|
|||||||
- jeder Push: alle Tests unter Windows-Python (Wine) **inklusive Oberflächen-Tests** auf einem
|
- jeder Push: alle Tests unter Windows-Python (Wine) **inklusive Oberflächen-Tests** auf einem
|
||||||
virtuellen Bildschirm, danach `Provisionsmanager95.exe` bauen und mit
|
virtuellen Bildschirm, danach `Provisionsmanager95.exe` bauen und mit
|
||||||
`Provisionsmanager95.exe --selbsttest` die **fertige .exe** prüfen; erst dann gibt es das Artefakt
|
`Provisionsmanager95.exe --selbsttest` die **fertige .exe** prüfen; erst dann gibt es das Artefakt
|
||||||
- Tag `vX.Y.Z` (passend zu `provtool/__init__.py`): zusätzlich ein Gitea-Release mit `.exe` und `.zip`
|
- danach das Setup (`build/installer.iss`, Inno Setup unter Wine) bauen, still installieren,
|
||||||
|
den Selbsttest in der installierten `.exe` laufen lassen und still deinstallieren
|
||||||
|
- Tag `vX.Y.Z` (passend zu `provtool/__init__.py`): zusätzlich ein Gitea-Release mit `.exe`, `.zip` und Setup
|
||||||
|
|
||||||
Die Oberflächen-Tests (`tests/test_gui.py`) bedienen die echte Oberfläche: Dialoge öffnen,
|
Die Oberflächen-Tests (`tests/test_gui.py`) bedienen die echte Oberfläche: Dialoge öffnen,
|
||||||
Programm schließen, während Assistent/Rückfragen/Rundgang offen sind, Alt+F4, Beträge ändern usw.
|
Programm schließen, während Assistent/Rückfragen/Rundgang offen sind, Alt+F4, Beträge ändern usw.
|
||||||
|
|||||||
+40
-4
@@ -1,6 +1,7 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# Baut die Windows-.exe mit Windows-Python unter Wine (z. B. im Container tobix/pywine:3.12).
|
# Baut die Windows-.exe mit Windows-Python unter Wine (z. B. im Container tobix/pywine:3.12).
|
||||||
# Ergebnis: dist/Provisionsmanager95.exe und dist/Provisionsmanager95-<version>.zip
|
# Ergebnis: dist/Provisionsmanager95.exe, dist/Provisionsmanager95-<version>.zip und
|
||||||
|
# dist/Provisionsmanager-Setup-<version>.exe (Inno Setup, Installation pro Benutzer)
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
cd "$(dirname "$0")/.."
|
cd "$(dirname "$0")/.."
|
||||||
|
|
||||||
@@ -40,19 +41,24 @@ echo "== PyInstaller =="
|
|||||||
$PY -m PyInstaller --noconfirm --clean --distpath dist --workpath build/tmp build/provisionsmanager.spec
|
$PY -m PyInstaller --noconfirm --clean --distpath dist --workpath build/tmp build/provisionsmanager.spec
|
||||||
|
|
||||||
test -f dist/Provisionsmanager95.exe
|
test -f dist/Provisionsmanager95.exe
|
||||||
|
test -f dist/Provisionsmanager/Provisionsmanager.exe # Ordner-Variante für das Setup
|
||||||
|
|
||||||
echo "== Selbsttest der fertigen .exe =="
|
selbsttest() { # $1 = zu prüfende .exe
|
||||||
rm -f selbsttest.txt
|
rm -f selbsttest.txt
|
||||||
set +e
|
set +e
|
||||||
timeout 300 wine dist/Provisionsmanager95.exe --selbsttest selbsttest.txt
|
timeout 300 wine "$1" --selbsttest selbsttest.txt
|
||||||
CODE=$?
|
CODE=$?
|
||||||
set -e
|
set -e
|
||||||
cat selbsttest.txt 2>/dev/null || echo "(keine Ergebnisdatei – die .exe ist vermutlich gar nicht gestartet)"
|
cat selbsttest.txt 2>/dev/null || echo "(keine Ergebnisdatei – die .exe ist vermutlich gar nicht gestartet)"
|
||||||
if [ "$CODE" -ne 0 ] || ! head -1 selbsttest.txt 2>/dev/null | tr -d '\r' | grep -qx OK; then
|
if [ "$CODE" -ne 0 ] || ! head -1 selbsttest.txt 2>/dev/null | tr -d '\r' | grep -qx OK; then
|
||||||
echo "Selbsttest der .exe FEHLGESCHLAGEN (Exit-Code $CODE)"
|
echo "Selbsttest von $1 FEHLGESCHLAGEN (Exit-Code $CODE)"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
echo "Selbsttest bestanden"
|
echo "Selbsttest bestanden"
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "== Selbsttest der fertigen .exe =="
|
||||||
|
selbsttest dist/Provisionsmanager95.exe
|
||||||
cp README.md dist/LIESMICH.md 2>/dev/null || true
|
cp README.md dist/LIESMICH.md 2>/dev/null || true
|
||||||
( cd dist && rm -f Provisionsmanager95-*.zip && \
|
( cd dist && rm -f Provisionsmanager95-*.zip && \
|
||||||
python3 -c "import zipfile,sys; z=zipfile.ZipFile(sys.argv[1],'w',zipfile.ZIP_DEFLATED); [z.write(f) for f in sys.argv[2:]]; z.close()" \
|
python3 -c "import zipfile,sys; z=zipfile.ZipFile(sys.argv[1],'w',zipfile.ZIP_DEFLATED); [z.write(f) for f in sys.argv[2:]]; z.close()" \
|
||||||
@@ -60,4 +66,34 @@ cp README.md dist/LIESMICH.md 2>/dev/null || true
|
|||||||
|| $PY -c "import zipfile,sys; z=zipfile.ZipFile(sys.argv[1],'w',zipfile.ZIP_DEFLATED); [z.write(f) for f in sys.argv[2:]]; z.close()" \
|
|| $PY -c "import zipfile,sys; z=zipfile.ZipFile(sys.argv[1],'w',zipfile.ZIP_DEFLATED); [z.write(f) for f in sys.argv[2:]]; z.close()" \
|
||||||
"Provisionsmanager95-${VERSION}.zip" Provisionsmanager95.exe LIESMICH.md )
|
"Provisionsmanager95-${VERSION}.zip" Provisionsmanager95.exe LIESMICH.md )
|
||||||
echo "$VERSION" > dist/VERSION
|
echo "$VERSION" > dist/VERSION
|
||||||
|
|
||||||
|
echo "== Setup (Inno Setup) =="
|
||||||
|
INNO_VERSION=6.7.3
|
||||||
|
INNO_SHA256=9c73c3bae7ed48d44112a0f48e66742c00090bdb5bef71d9d3c056c66e97b732
|
||||||
|
INNO_EXE=build/tmp/innosetup-$INNO_VERSION.exe
|
||||||
|
mkdir -p build/tmp
|
||||||
|
curl -fsSL -o "$INNO_EXE" "https://github.com/jrsoftware/issrc/releases/download/is-${INNO_VERSION//./_}/innosetup-$INNO_VERSION.exe"
|
||||||
|
echo "$INNO_SHA256 $INNO_EXE" | sha256sum -c -
|
||||||
|
timeout 300 wine "$INNO_EXE" /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP- /CURRENTUSER '/DIR=C:\InnoSetup'
|
||||||
|
rm -f dist/Provisionsmanager-Setup-*.exe
|
||||||
|
timeout 300 wine 'C:\InnoSetup\ISCC.exe' /Q "/DAppVersion=$VERSION" 'build\installer.iss'
|
||||||
|
SETUP="dist/Provisionsmanager-Setup-$VERSION.exe"
|
||||||
|
test -f "$SETUP"
|
||||||
|
|
||||||
|
echo "== Installer-Test (still installieren, Selbsttest, still deinstallieren) =="
|
||||||
|
winordner() { winepath -u "$(wine cmd /c echo "%$1%" | tr -d '\r')"; } # z. B. APPDATA -> /opt/wineprefix/...
|
||||||
|
DATEN="$(winordner APPDATA)/Provisionsmanager95"
|
||||||
|
ZIEL="$(winordner LOCALAPPDATA)/Programs/Provisionsmanager"
|
||||||
|
mkdir -p "$DATEN"
|
||||||
|
echo "Benutzerdaten" > "$DATEN/installer-test.txt"
|
||||||
|
timeout 300 wine "$SETUP" /VERYSILENT /SUPPRESSMSGBOXES /CURRENTUSER /NORESTART
|
||||||
|
test -f "$(winordner APPDATA)/Microsoft/Windows/Start Menu/Programs/Provisions-Manager.lnk"
|
||||||
|
selbsttest "$ZIEL/Provisionsmanager.exe"
|
||||||
|
timeout 300 wine "$ZIEL/unins000.exe" /VERYSILENT /SUPPRESSMSGBOXES /NORESTART
|
||||||
|
# Der Deinstaller arbeitet als Kopie im Temp-Ordner weiter – auf das Ende warten
|
||||||
|
for _ in $(seq 60); do [ -e "$ZIEL" ] || break; sleep 1; done
|
||||||
|
if [ -e "$ZIEL" ]; then echo "Deinstallation FEHLGESCHLAGEN – Programmordner noch da:"; ls -la "$ZIEL"; exit 1; fi
|
||||||
|
if [ ! -f "$DATEN/installer-test.txt" ]; then echo "Deinstallation hat Benutzerdaten gelöscht!"; exit 1; fi
|
||||||
|
rm "$DATEN/installer-test.txt"
|
||||||
|
echo "Installer-Test bestanden"
|
||||||
ls -la dist
|
ls -la dist
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
; Inno-Setup-Skript: Installation pro Benutzer (ohne Admin-Rechte) aus dist/Provisionsmanager/
|
||||||
|
; Aufruf (siehe build/build_windows.sh): ISCC.exe /DAppVersion=1.2.3 build\installer.iss
|
||||||
|
; Ergebnis: dist/Provisionsmanager-Setup-<version>.exe
|
||||||
|
#ifndef AppVersion
|
||||||
|
#error AppVersion fehlt – ISCC mit /DAppVersion=<version> aufrufen
|
||||||
|
#endif
|
||||||
|
|
||||||
|
[Setup]
|
||||||
|
; AppId nie ändern: daran erkennt Windows bei Updates die bestehende Installation
|
||||||
|
AppId={{79CF85D1-16DC-4FD5-924B-B6C9AFB90309}
|
||||||
|
AppName=Provisions-Manager
|
||||||
|
AppVersion={#AppVersion}
|
||||||
|
AppPublisher=Handy-Insel Miesbach
|
||||||
|
PrivilegesRequired=lowest
|
||||||
|
DefaultDirName={localappdata}\Programs\Provisionsmanager
|
||||||
|
DefaultGroupName=Provisions-Manager
|
||||||
|
DisableProgramGroupPage=yes
|
||||||
|
UninstallDisplayIcon={app}\Provisionsmanager.exe
|
||||||
|
SetupIconFile=..\assets\app.ico
|
||||||
|
OutputDir=..\dist
|
||||||
|
OutputBaseFilename=Provisionsmanager-Setup-{#AppVersion}
|
||||||
|
CloseApplications=yes
|
||||||
|
WizardStyle=modern
|
||||||
|
; Benutzerdaten liegen in %APPDATA%\Provisionsmanager95 – das Setup fasst sie nicht an,
|
||||||
|
; der Deinstaller entfernt nur, was er selbst installiert hat.
|
||||||
|
|
||||||
|
[Languages]
|
||||||
|
Name: "de"; MessagesFile: "compiler:Languages\German.isl"
|
||||||
|
|
||||||
|
[Tasks]
|
||||||
|
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
|
||||||
|
|
||||||
|
[InstallDelete]
|
||||||
|
; Update: Bibliotheken der alten Version entfernen, damit keine veralteten Dateien liegen bleiben
|
||||||
|
Type: filesandordirs; Name: "{app}\_internal"
|
||||||
|
|
||||||
|
[Files]
|
||||||
|
Source: "..\dist\Provisionsmanager\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
|
||||||
|
|
||||||
|
[Icons]
|
||||||
|
Name: "{autoprograms}\Provisions-Manager"; Filename: "{app}\Provisionsmanager.exe"
|
||||||
|
Name: "{autodesktop}\Provisions-Manager"; Filename: "{app}\Provisionsmanager.exe"; Tasks: desktopicon
|
||||||
|
|
||||||
|
[Run]
|
||||||
|
Filename: "{app}\Provisionsmanager.exe"; Description: "{cm:LaunchProgram,Provisions-Manager}"; Flags: nowait postinstall skipifsilent
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
# PyInstaller-Spezifikation – erzeugt eine einzelne Programmdatei (Windows: .exe, Linux: ELF)
|
# PyInstaller-Spezifikation – erzeugt eine einzelne Programmdatei (Windows: .exe, Linux: ELF),
|
||||||
|
# unter Windows zusätzlich den Ordner dist/Provisionsmanager/ (schneller Start, Inhalt des Setups)
|
||||||
# Aufruf: pyinstaller --noconfirm build/provisionsmanager.spec
|
# Aufruf: pyinstaller --noconfirm build/provisionsmanager.spec
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
@@ -31,3 +32,19 @@ exe = EXE(
|
|||||||
strip=False,
|
strip=False,
|
||||||
runtime_tmpdir=None,
|
runtime_tmpdir=None,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if WIN:
|
||||||
|
exe_ordner = EXE(
|
||||||
|
pyz,
|
||||||
|
a.scripts,
|
||||||
|
[],
|
||||||
|
exclude_binaries=True,
|
||||||
|
name="Provisionsmanager",
|
||||||
|
icon=os.path.join(ROOT, "assets", "app.ico"),
|
||||||
|
version=os.path.join(ROOT, "build", "version_info.txt"),
|
||||||
|
console=False,
|
||||||
|
upx=False,
|
||||||
|
debug=False,
|
||||||
|
strip=False,
|
||||||
|
)
|
||||||
|
COLLECT(exe_ordner, a.binaries, a.datas, name="Provisionsmanager", upx=False, strip=False)
|
||||||
@@ -11,7 +11,7 @@ release_id() { curl -sf "$API/releases/tags/$TAG" -H "Authorization: token $TOKE
|
|||||||
id=$(release_id || true)
|
id=$(release_id || true)
|
||||||
if [ -z "$id" ]; then
|
if [ -z "$id" ]; then
|
||||||
curl -sf -X POST "$API/releases" -H "Authorization: token $TOKEN" -H "Content-Type: application/json" \
|
curl -sf -X POST "$API/releases" -H "Authorization: token $TOKEN" -H "Content-Type: application/json" \
|
||||||
-d "{\"tag_name\":\"$TAG\",\"name\":\"Provisions-Manager 95 $TAG\",\"body\":\"Windows: .exe herunterladen und starten. Linux: tar.gz entpacken, Provisionsmanager95 starten (ab Debian 12 / Ubuntu 24.04).\"}" \
|
-d "{\"tag_name\":\"$TAG\",\"name\":\"Provisions-Manager 95 $TAG\",\"body\":\"Windows: Setup installieren (oder die .exe direkt starten). Linux: tar.gz entpacken, Provisionsmanager95 starten (ab Debian 12 / Ubuntu 24.04).\"}" \
|
||||||
>/dev/null || sleep 5 # Gleichzeitig angelegt? Dann gibt es das Release jetzt.
|
>/dev/null || sleep 5 # Gleichzeitig angelegt? Dann gibt es das Release jetzt.
|
||||||
id=$(release_id)
|
id=$(release_id)
|
||||||
fi
|
fi
|
||||||
|
|||||||
Reference in new issue
Block a user