ci: Job desktop ueberspringt den Bau, wenn der Desktop-Stand unveraendert ist — Pakete aus dem Zwischenspeicher
- Neues Skript .gitea/scripts/desktop-stamp.sh (Unterbefehle stamp/check):
Stempel aus Version + letztem Commit an den Desktop-Pfaden, Pruefung eines
restaurierten desktop-dist/ gegen Manifest, Kanal, Groesse und sha256
- ci.yml Job desktop: stamp -> actions/cache/restore (Stempel-Schluessel,
nur main) -> check -> 13 Bau-Schritte mit if: steps.reuse.outputs.reuse,
Stempel-Save vor unveraenderter Uebergabe an publish; quality/test/publish
und on: unveraendert (js-yaml-Tiefenvergleich gegen 38c1400)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Executable
+162
@@ -0,0 +1,162 @@
|
||||
#!/bin/sh
|
||||
# desktop-stamp.sh -- Stempel aus Version + letztem Commit an den
|
||||
# Desktop-Pfaden berechnen und pruefen, ob dazu bereits fertige Pakete im
|
||||
# Zwischenspeicher des Runners liegen (quick-260917-jdh).
|
||||
#
|
||||
# Zweck: Der CI-Job `desktop` baut die Rust/Tauri-Pakete heute bei jedem
|
||||
# Push auf main, auch wenn sich an der Desktop-App seit dem letzten Bau
|
||||
# nichts geaendert hat. Dieses Skript berechnet einen Stempel aus der
|
||||
# aktuellen Versionsnummer und dem letzten Commit an den Desktop-Pfaden;
|
||||
# liegen zu diesem Stempel bereits geprueft-vollstaendige Pakete im
|
||||
# Zwischenspeicher, kann der Job den kompletten Bau ueberspringen.
|
||||
#
|
||||
# Aufrufformen:
|
||||
# desktop-stamp.sh stamp -- Stempel berechnen, Ausgaben: stamp, version,
|
||||
# sha7, skip_allowed (Version aus
|
||||
# desktop-version.sh --print; SHA aus dem
|
||||
# letzten Commit an DESKTOP_PATHS)
|
||||
# desktop-stamp.sh check -- prueft, ob ein per stamp-cache restaurierter
|
||||
# desktop-dist/ vollstaendig und stempel-echt
|
||||
# ist, Ausgaben: reuse, bei Treffer zusaetzlich
|
||||
# files
|
||||
#
|
||||
# Umgebungsvariablen:
|
||||
# DESKTOP_TAG nur fuer stamp, lokale Probe (siehe desktop-version.sh)
|
||||
# GITHUB_REF nur fuer stamp: skip_allowed=true ausschliesslich bei
|
||||
# refs/heads/main (Beta-Kanal) -- Tags bauen immer neu
|
||||
# GITHUB_OUTPUT nur fuer stamp: wenn gesetzt, werden alle Ausgaben
|
||||
# zusaetzlich per >> hineingeschrieben (wie im CI ueblich)
|
||||
# CACHE_HIT nur fuer check: Ergebnis von actions/cache/restore
|
||||
# (steps.<id>.outputs.cache-hit), muss exakt "true" sein
|
||||
# STAMP_VERSION nur fuer check: Version aus dem stamp-Schritt, muss mit
|
||||
# der Version im Manifest uebereinstimmen
|
||||
# STAMP_SHA7 nur fuer check: 7-stelliger SHA aus dem stamp-Schritt,
|
||||
# nur fuer die Log-Zeile bei Treffer
|
||||
# DESKTOP_DIST nur fuer check: Zielordner der Pakete (Vorgabe:
|
||||
# desktop-dist, wie desktop-collect.sh)
|
||||
#
|
||||
# DESKTOP_PATHS deckt alle Bau-Eingaben ab: apps/desktop (inkl.
|
||||
# Cargo.lock/package.json), die drei Skripte und die Workflow-Datei selbst
|
||||
# (eine Aenderung an der Stempelregel muss selbst einen Neubau ausloesen).
|
||||
# `pnpm-lock.yaml` steht bewusst NICHT in der Liste: die Tauri-CLI-Version
|
||||
# haengt an apps/desktop/package.json (darin enthalten), und der Desktop-Bau
|
||||
# liest ausserhalb von apps/desktop keine Werkstatt-Datei -- frontendDist ist
|
||||
# ../src innerhalb von apps/desktop, keine Abhaengigkeit auf packages/*.
|
||||
#
|
||||
# Dieses Skript kennt kein Secret.
|
||||
set -eu
|
||||
|
||||
DESKTOP_PATHS="apps/desktop .gitea/scripts/desktop-version.sh .gitea/scripts/desktop-collect.sh .gitea/scripts/desktop-stamp.sh .gitea/workflows/ci.yml"
|
||||
|
||||
out() {
|
||||
printf '%s=%s\n' "$1" "$2"
|
||||
if [ -n "${GITHUB_OUTPUT:-}" ]; then
|
||||
printf '%s=%s\n' "$1" "$2" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
}
|
||||
|
||||
cmd_stamp() {
|
||||
VERSION="$("$(dirname "$0")/desktop-version.sh" --print)"
|
||||
|
||||
# Bewusst ungequotet: Wortaufteilung der leerzeichengetrennten Pfadliste.
|
||||
LAST="$(git log -1 --format=%H -- $DESKTOP_PATHS)"
|
||||
if [ -z "$LAST" ]; then
|
||||
echo "Keine Historie zu den Desktop-Pfaden -- im CI ist fetch-depth: 0 Pflicht." >&2
|
||||
exit 1
|
||||
fi
|
||||
SHA7="$(git rev-parse --short=7 "$LAST")"
|
||||
SUBJECT="$(git log -1 --format=%s "$LAST")"
|
||||
|
||||
SKIP=false
|
||||
REF="${GITHUB_REF:-}"
|
||||
if [ "$REF" = "refs/heads/main" ]; then
|
||||
SKIP=true
|
||||
echo "Stempel $VERSION-$LAST ($SHA7: $SUBJECT) -- Ueberspringen erlaubt (main)."
|
||||
else
|
||||
echo "Stempel $VERSION-$LAST ($SHA7: $SUBJECT) -- Tag oder fremder Zweig, es wird immer gebaut."
|
||||
fi
|
||||
|
||||
out stamp "$VERSION-$LAST"
|
||||
out version "$VERSION"
|
||||
out sha7 "$SHA7"
|
||||
out skip_allowed "$SKIP"
|
||||
}
|
||||
|
||||
cmd_check() {
|
||||
CACHE_HIT="${CACHE_HIT:-}"
|
||||
STAMP_VERSION="${STAMP_VERSION:-}"
|
||||
STAMP_SHA7="${STAMP_SHA7:-}"
|
||||
DESKTOP_DIST="${DESKTOP_DIST:-desktop-dist}"
|
||||
MANIFEST="$DESKTOP_DIST/manifest.json"
|
||||
|
||||
no_reuse() {
|
||||
echo "Kein uebernehmbarer Stand ($1) -- Desktop wird gebaut."
|
||||
rm -f "$DESKTOP_DIST"/*.AppImage "$DESKTOP_DIST"/*.exe "$MANIFEST"
|
||||
out reuse false
|
||||
exit 0
|
||||
}
|
||||
|
||||
check_file() {
|
||||
# $1 = Manifest-Schluessel (linux|windows), $2 = Dateiname
|
||||
FPATH="$DESKTOP_DIST/$2"
|
||||
if [ ! -f "$FPATH" ]; then
|
||||
no_reuse "Datei $2 fehlt"
|
||||
fi
|
||||
SIZE="$(stat -c %s "$FPATH")"
|
||||
EXP_SIZE="$(jq -r ".files.$1.size" "$MANIFEST")"
|
||||
if [ "$SIZE" != "$EXP_SIZE" ]; then
|
||||
no_reuse "Groesse von $2 weicht ab ($SIZE statt $EXP_SIZE)"
|
||||
fi
|
||||
SHA="$(sha256sum "$FPATH" | cut -d' ' -f1)"
|
||||
EXP_SHA="$(jq -r ".files.$1.sha256" "$MANIFEST")"
|
||||
if [ "$SHA" != "$EXP_SHA" ]; then
|
||||
no_reuse "Pruefsumme von $2 weicht ab"
|
||||
fi
|
||||
}
|
||||
|
||||
if [ "$CACHE_HIT" != "true" ]; then
|
||||
no_reuse "kein Zwischenspeicher zum Stempel"
|
||||
fi
|
||||
|
||||
if [ ! -f "$MANIFEST" ] || ! jq -e . "$MANIFEST" >/dev/null 2>&1; then
|
||||
no_reuse "Manifest fehlt oder ist kein gueltiges JSON"
|
||||
fi
|
||||
|
||||
CHANNEL="$(jq -r .channel "$MANIFEST")"
|
||||
if [ "$CHANNEL" != "beta" ]; then
|
||||
no_reuse "Kanal $CHANNEL statt beta"
|
||||
fi
|
||||
|
||||
MVERSION="$(jq -r .version "$MANIFEST")"
|
||||
if [ "$MVERSION" != "$STAMP_VERSION" ]; then
|
||||
no_reuse "Version $MVERSION statt $STAMP_VERSION"
|
||||
fi
|
||||
|
||||
LINUX_NAME="$(jq -r '.files.linux.name // empty' "$MANIFEST")"
|
||||
WINDOWS_NAME="$(jq -r '.files.windows.name // empty' "$MANIFEST")"
|
||||
if [ -z "$LINUX_NAME" ] || [ -z "$WINDOWS_NAME" ]; then
|
||||
no_reuse "Dateiname fehlt im Manifest"
|
||||
fi
|
||||
|
||||
check_file linux "$LINUX_NAME"
|
||||
check_file windows "$WINDOWS_NAME"
|
||||
|
||||
COMMIT="$(jq -r .commit "$MANIFEST")"
|
||||
BUILD_TIME="$(jq -r .buildTime "$MANIFEST")"
|
||||
echo "Desktop unveraendert seit $STAMP_SHA7: Pakete $LINUX_NAME, $WINDOWS_NAME aus dem Zwischenspeicher (gebaut aus $COMMIT am $BUILD_TIME)"
|
||||
out reuse true
|
||||
out files "$LINUX_NAME,$WINDOWS_NAME"
|
||||
}
|
||||
|
||||
case "${1:-}" in
|
||||
stamp)
|
||||
cmd_stamp
|
||||
;;
|
||||
check)
|
||||
cmd_check
|
||||
;;
|
||||
*)
|
||||
echo "Aufruf: $0 stamp|check" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
@@ -9,6 +9,11 @@
|
||||
# in der Pipeline. `tauri.conf.json`/`Cargo.toml` bleiben dabei immer rein
|
||||
# numerisch (X.Y.Z), weil NSIS' Windows-Ressourcenfelder das verlangen; die
|
||||
# Beta-Kennzeichnung lebt ausschliesslich im Dateinamen-Suffix.
|
||||
# quick-260917-jdh: Job `desktop` ueberspringt den Bau auf `main`, wenn zum
|
||||
# Stempel (Version aus dem letzten Freigabe-Tag + letzter Commit an den
|
||||
# Desktop-Pfaden, siehe .gitea/scripts/desktop-stamp.sh) bereits fertige
|
||||
# Pakete im Zwischenspeicher des Runners liegen; Tags v* bauen immer neu;
|
||||
# `publish` bleibt unveraendert.
|
||||
name: Tessera CI/CD
|
||||
|
||||
on:
|
||||
@@ -78,17 +83,46 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
# Die folgenden drei Schritte stehen bewusst vor setup-node/apt/rustup:
|
||||
# Sie sollen beim Ueberspringen (Desktop-Stand unveraendert) gar nicht
|
||||
# erst die teuren Werkzeuge installieren (quick-260917-jdh).
|
||||
- name: Desktop-Stempel berechnen
|
||||
id: stamp
|
||||
run: sh .gitea/scripts/desktop-stamp.sh stamp
|
||||
|
||||
- name: Fertige Pakete zum Stempel suchen
|
||||
id: stamp-cache
|
||||
if: steps.stamp.outputs.skip_allowed == 'true'
|
||||
uses: actions/cache/restore@v4
|
||||
with:
|
||||
path: desktop-dist
|
||||
key: desktop-dist-stamp-${{ steps.stamp.outputs.stamp }}
|
||||
# Bewusst OHNE restore-keys: act_runner sucht auch zum Hauptschluessel
|
||||
# per Praefix -- ein aelterer Stand darf nie als Treffer gelten.
|
||||
|
||||
- name: Gefundene Pakete pruefen
|
||||
id: reuse
|
||||
env:
|
||||
CACHE_HIT: ${{ steps.stamp-cache.outputs.cache-hit }}
|
||||
STAMP_VERSION: ${{ steps.stamp.outputs.version }}
|
||||
STAMP_SHA7: ${{ steps.stamp.outputs.sha7 }}
|
||||
run: sh .gitea/scripts/desktop-stamp.sh check
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
if: steps.reuse.outputs.reuse != 'true'
|
||||
with:
|
||||
node-version: 24
|
||||
|
||||
- name: Enable pnpm via corepack
|
||||
if: steps.reuse.outputs.reuse != 'true'
|
||||
run: corepack enable && corepack prepare pnpm@9.15.0 --activate
|
||||
|
||||
- name: Install dependencies
|
||||
if: steps.reuse.outputs.reuse != 'true'
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Systemabhaengigkeiten
|
||||
if: steps.reuse.outputs.reuse != 'true'
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y --no-install-recommends \
|
||||
@@ -98,12 +132,14 @@ jobs:
|
||||
lld llvm clang nsis
|
||||
|
||||
- name: Rust-Toolchain
|
||||
if: steps.reuse.outputs.reuse != 'true'
|
||||
run: |
|
||||
curl -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --default-toolchain stable
|
||||
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
|
||||
"$HOME/.cargo/bin/rustup" component add clippy
|
||||
|
||||
- name: Cargo-Zwischenspeicher
|
||||
if: steps.reuse.outputs.reuse != 'true'
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
@@ -118,33 +154,53 @@ jobs:
|
||||
restore-keys: desktop-cargo-
|
||||
|
||||
- name: Windows-Werkzeuge
|
||||
if: steps.reuse.outputs.reuse != 'true'
|
||||
run: |
|
||||
rustup target add x86_64-pc-windows-msvc
|
||||
command -v cargo-xwin >/dev/null 2>&1 || cargo install --locked cargo-xwin
|
||||
|
||||
- name: Version setzen
|
||||
if: steps.reuse.outputs.reuse != 'true'
|
||||
run: sh .gitea/scripts/desktop-version.sh
|
||||
|
||||
- name: Rust pruefen
|
||||
if: steps.reuse.outputs.reuse != 'true'
|
||||
working-directory: apps/desktop/src-tauri
|
||||
run: |
|
||||
cargo check
|
||||
cargo clippy
|
||||
|
||||
- name: Alte Bundles entfernen
|
||||
if: steps.reuse.outputs.reuse != 'true'
|
||||
run: |
|
||||
rm -rf apps/desktop/src-tauri/target/release/bundle
|
||||
rm -rf apps/desktop/src-tauri/target/x86_64-pc-windows-msvc/release/bundle
|
||||
|
||||
- name: Linux-AppImage bauen
|
||||
if: steps.reuse.outputs.reuse != 'true'
|
||||
run: pnpm --filter @tessera/desktop exec tauri build --bundles appimage
|
||||
|
||||
- name: Windows-Installer bauen (Cross-Bau)
|
||||
if: steps.reuse.outputs.reuse != 'true'
|
||||
run: pnpm --filter @tessera/desktop exec tauri build --runner cargo-xwin --target x86_64-pc-windows-msvc --bundles nsis
|
||||
|
||||
- name: Pakete einsammeln
|
||||
if: steps.reuse.outputs.reuse != 'true'
|
||||
run: sh .gitea/scripts/desktop-collect.sh --require linux,windows
|
||||
|
||||
- name: Pakete unter dem Stempel ablegen
|
||||
# Nur nach echtem Bau und nur auf main -- Tag-Pakete tragen keinen
|
||||
# Beta-Suffix und duerfen nie unter einem Stempel liegen. Ein bereits
|
||||
# vorhandener Schluessel loest bei actions/cache/save nur eine Info
|
||||
# aus, keinen Fehler.
|
||||
if: steps.reuse.outputs.reuse != 'true' && steps.stamp.outputs.skip_allowed == 'true'
|
||||
uses: actions/cache/save@v4
|
||||
with:
|
||||
path: desktop-dist
|
||||
key: desktop-dist-stamp-${{ steps.stamp.outputs.stamp }}
|
||||
|
||||
# Laeuft in beiden Faellen: im Skip-Fall sichert er den restaurierten
|
||||
# Stand unter dem neuen SHA, deshalb muss `publish` nichts wissen.
|
||||
- name: Uebergabe an publish
|
||||
uses: actions/cache/save@v4
|
||||
with:
|
||||
|
||||
Reference in New Issue
Block a user