# GitLab-CI fuer den ThreadNet-Web-Fork (Lab-GitLab: git.lab). # Ersetzt die frueheren GitHub/Gitea-Actions-Workflows - Hintergrund: docs/axion1337-fork.md. # # Erkenntnisse aus den Gitea-CI-Versuchen (2026-07-30), hier eingeflossen: # - kein scripts/layered.sh: wuerde den gepinnten matrix-js-sdk-Stand aus pnpm-lock.yaml # mit Upstream-develop ueberschreiben (und braucht jq) -> frozen-lockfile-Install # - webpack braucht ~4 GB Heap -> NODE_OPTIONS # - Desktop-Build laeuft im dockerbuild-Image (rust:bullseye + node, glibc-2.31-Ziel) stages: - build - package # --- Windows-Runner-VM-Steuerung (Issue #5) --------------------------------- # Die Windows-Build-VM (dockur/windows-Fork, siehe git.lab/axion1337.chat/vendor/windows, # Runbook: docs/axion-runner.md dort) laeuft on-demand auf Overmind. Diese beiden Jobs # starten/stoppen sie vom Linux-Runner aus ueber den Docker-Socket - der # desktop_windows-Job wartet danach einfach in der Queue, bis der Runner online ist. start_windows_vm: stage: build image: docker:27-cli rules: - if: $CI_COMMIT_TAG =~ /^v/ when: manual allow_failure: true - if: $CI_COMMIT_BRANCH == "main" when: manual allow_failure: true script: - docker start windows-runner stop_windows_vm: stage: package image: docker:27-cli rules: - if: $CI_COMMIT_TAG =~ /^v/ when: manual allow_failure: true - if: $CI_COMMIT_BRANCH == "main" when: manual allow_failure: true script: - docker stop windows-runner # CVE-Scan des eigenen Prod-Images (gitops#31): woechentlich per Schedule und # manuell triggerbar. Bricht bewusst nicht hart ab (allow_failure) - Funde landen # als Artifact + Job-Log, die Bewertung bleibt menschlich. Lab-interne Images # (desktop-build, windows-vm) brauchen erst CA-Trust im Trivy-Container - notiert # in gitops#31 als Ausbaustufe. trivy_scan: stage: build image: name: aquasec/trivy:0.58.2 entrypoint: [""] rules: - if: $CI_PIPELINE_SOURCE == "schedule" allow_failure: true - if: $CI_COMMIT_BRANCH == "main" when: manual allow_failure: true variables: GIT_STRATEGY: none TRIVY_NO_PROGRESS: "true" script: - trivy image --severity HIGH,CRITICAL --format table --output trivy-web.txt rohana.axion1337.de/sorb/threadnet-web:latest-ci - grep -E "Total|CRITICAL|HIGH" trivy-web.txt | head -20 || true artifacts: paths: - trivy-web.txt expire_in: 30 days when: always web: stage: build image: node:24-bullseye rules: # Release-Tags bauen immer (docker_web/desktop_* brauchen web als needs) - if: $CI_COMMIT_TAG =~ /^v/ # Scheduled Pipelines gehoeren dem trivy_scan - kein wochentlicher Leerbuild - if: $CI_PIPELINE_SOURCE == "schedule" when: never # Pushes nur, wenn build-relevante Pfade betroffen sind - Doku-Commits kosten nichts - if: $CI_COMMIT_BRANCH changes: - apps/**/* - packages/**/* - patches/**/* - scripts/**/* - pnpm-lock.yaml - pnpm-workspace.yaml - .gitlab-ci.yml variables: NODE_OPTIONS: "--max-old-space-size=6144" CI_PACKAGE: "true" before_script: - corepack enable script: - pnpm install --frozen-lockfile - cp apps/web/element.io/develop/config.json apps/web/config.json - VERSION=$(scripts/get-version-from-git.sh) pnpm --dir apps/web build artifacts: paths: - apps/web/webapp expire_in: 1 day # Baut das kanonische Web-Image (apps/web/Dockerfile, Kontext = Monorepo-Root) und pusht # es in die rohana-Registry, aus der Flux/k8s zieht. Deploy bleibt ein manueller Tag-Bump # im gitops-Repo. Bewusster Doppel-Build (webpack laeuft im web-Job UND im Dockerfile) - # kanonisch/reproduzierbar vor schnell; Optimierung als Folgearbeit in Issue #2. docker_web: stage: package image: docker:27-cli needs: - job: web artifacts: false rules: # Nur bei Release-Tags (v*) - "releasen" ist ein bewusster Akt: # Tag pushen -> Image entsteht -> Tag-Bump im gitops-Repo deployt es - if: $CI_COMMIT_TAG =~ /^v/ variables: IMAGE: rohana.axion1337.de/sorb/threadnet-web DOCKER_BUILDKIT: "1" script: - echo "$REGISTRY_PASSWORD" | docker login rohana.axion1337.de -u "$REGISTRY_USER" --password-stdin - docker build -f apps/web/Dockerfile -t "$IMAGE:$CI_COMMIT_TAG" -t "$IMAGE:latest-ci" . - docker push "$IMAGE:$CI_COMMIT_TAG" - docker push "$IMAGE:latest-ci" # Einmalig/selten: Build-Image fuer den Desktop-Build (rust:bullseye + node + tcl/sqlcipher, # aus apps/desktop/dockerbuild). Manuell ausloesen, wenn sich .node-version oder das # Dockerfile aendert. desktop_image: stage: package image: docker:27-cli rules: - if: $CI_COMMIT_BRANCH == "main" when: manual allow_failure: true variables: # Lab-Registry statt rohana (OVERMIND-01): Konsument ist nur die Lab-CI selbst IMAGE: $CI_REGISTRY_IMAGE/desktop-build script: - echo "$CI_JOB_TOKEN" | docker login "$CI_REGISTRY" -u gitlab-ci-token --password-stdin - docker build -f apps/desktop/dockerbuild/Dockerfile -t "$IMAGE:bullseye" apps/desktop - docker push "$IMAGE:bullseye" # Electron-Linux-Build (amd64, static sqlcipher) - repliziert den am 2026-07-29 manuell # verifizierten Build-Weg. Automatisch bei Release-Tags, auf main manuell triggerbar. desktop_linux: stage: package image: registry.git.lab/axion1337.chat/threadnet-web/desktop-build:bullseye needs: - job: web artifacts: true rules: - if: $CI_COMMIT_TAG =~ /^v/ - if: $CI_COMMIT_BRANCH == "main" when: manual allow_failure: true variables: MAX_GLIBC: "2.31" USE_HARD_LINKS: "false" SQLCIPHER_BUNDLED: "1" # Eigene Build-Variante: Produktname ThreadNet statt Element. Ohne das nutzt # electron-builder element.io/release/build.json und die Pakete heissen weiter # "element-desktop" (real passiert 2026-08-02). VARIANT_PATH: axion1337/build.json script: - pnpm install --frozen-lockfile --filter element-desktop - cp -r apps/web/webapp apps/desktop/webapp # Produktions-Client-Config (getrackt seit diesem Commit, vorher nur im manuellen Build) - cp apps/desktop/axion1337/config.json apps/desktop/webapp/config.json - cd apps/desktop - pnpm run asar-webapp - pnpm run build:native # pnpm/npm setzen beim Install kein Executable-Bit auf 7za - bekannter Fix, # gleicher Schritt wie in der Upstream-CI ("Fix permissions") - chmod +x ../../node_modules/7zip-bin/linux/*/7za || true - pnpm run build --publish never -l tar.gz -l deb artifacts: paths: - apps/desktop/dist/*.deb - apps/desktop/dist/*.tar.gz expire_in: 1 week # Windows-Desktop-Build (x64, unsigniert - Signing siehe Issue #5). Laeuft NUR auf dem # Windows-Runner (tags), manuell: vorher start_windows_vm ausloesen. Uebersetzt aus dem # Upstream-Workflow build_desktop_windows.yaml (x64-Pfad; arm-only-Schritte entfallen). desktop_windows: stage: package tags: - windows needs: - job: web artifacts: true rules: - if: $CI_COMMIT_TAG =~ /^v/ when: manual allow_failure: true - if: $CI_COMMIT_BRANCH == "main" when: manual allow_failure: true variables: SQLCIPHER_BUNDLED: "1" ELECTRON_CACHE: C:\electron-cache ELECTRON_BUILDER_CACHE: C:\eb-cache # Eigene Build-Variante (Produktname ThreadNet) - siehe desktop_linux VARIANT_PATH: axion1337/build.json script: - pnpm install --frozen-lockfile --filter element-desktop # GitHub-CDN-Downloads (Electron-Binary, winCodeSign, NSIS) reissen im Gast # reproduzierbar ab und app-builder kann nicht fortsetzen (Jobs 415/416/424) - # das Skript laedt alles resumefaehig in die persistenten Caches vor. - powershell -ExecutionPolicy Bypass -File apps\desktop\axion1337\prefetch-buildcache.ps1 - Copy-Item -Recurse apps/web/webapp apps/desktop/webapp - Copy-Item apps/desktop/axion1337/config.json apps/desktop/webapp/config.json -Force - cd apps/desktop - pnpm run asar-webapp - '& "C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\Common7\Tools\Launch-VsDevShell.ps1" -Arch amd64 -SkipAutomaticLocation' - pnpm run build:native --target x86_64-pc-windows-msvc - pnpm run build --publish never -w nsis artifacts: paths: - apps/desktop/dist/*.exe expire_in: 1 week # Idempotente Werkzeug-Provisionierung im Windows-Gast (laeuft als SYSTEM ueber den # Runner selbst - kein noVNC/RDP noetig). Hintergrund: choco akzeptiert --version nicht # bei Mehrfach-Paketen, der urspruengliche Runbook-Einzeiler hat still nichts installiert. # Startet am Ende den Runner-Dienst verzoegert neu, damit der neue PATH fuer # Folge-Jobs greift (der Job selbst wird davon nicht mehr unterbrochen). windows_provision: stage: build tags: - windows rules: - if: $CI_COMMIT_BRANCH == "main" when: manual allow_failure: true variables: # Kein Checkout - der braeuchte git, das dieser Job erst installiert (Henne-Ei) GIT_STRATEGY: none script: - choco install -y git - choco install -y nasm - choco install -y magicsplat-tcl-tk - choco install -y nodejs --version=24.15.0 # Fuer den seshat-hak-Build (hak/matrix-seshat/check.ts): perl+patch (Strawberry # liefert beides, patch.exe in C:\Strawberry\c\bin), python (node-gyp), rustc. - choco install -y strawberryperl - choco install -y python3 # Rust maschinenweit statt Benutzerprofil: der Runner-Dienst laeuft als SYSTEM und # sieht nur die Maschinen-Umgebung - ein Default-rustup unter %USERPROFILE% waere # fuer Jobs unsichtbar. - $env:RUSTUP_HOME='C:\Rust\rustup'; $env:CARGO_HOME='C:\Rust\cargo'; Invoke-WebRequest -UseBasicParsing https://win.rustup.rs/x86_64 -OutFile "$env:TEMP\rustup-init.exe" - '& "$env:TEMP\rustup-init.exe" -y --profile minimal --default-toolchain stable --default-host x86_64-pc-windows-msvc' - '[Environment]::SetEnvironmentVariable(''RUSTUP_HOME'',''C:\Rust\rustup'',''Machine'')' - '[Environment]::SetEnvironmentVariable(''CARGO_HOME'',''C:\Rust\cargo'',''Machine'')' # choco-nasm traegt sich nicht selbst in den PATH ein (Upstream macht das auch # explizit via GITHUB_PATH) - zusammen mit cargo\bin hier maschinenweit nachziehen - $mp=[Environment]::GetEnvironmentVariable('Path','Machine'); if ($mp -notlike '*C:\Rust\cargo\bin*') { [Environment]::SetEnvironmentVariable('Path', "$mp;C:\Rust\cargo\bin;C:\Program Files\NASM", 'Machine') } - refreshenv; corepack enable - '& "C:\Program Files\Git\cmd\git.exe" --version' - '& "C:\Program Files\nodejs\node.exe" --version' - '& C:\Rust\cargo\bin\rustc.exe --version' # Windows-260-Zeichen-Pfadlimit: die Visual-Baseline-Pfade des Monorepos sprengen # MAX_PATH - beide Schalter noetig (git-seitig + OS-Policy) - '& "C:\Program Files\Git\cmd\git.exe" config --system core.longpaths true' - Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem' -Name LongPathsEnabled -Value 1 -Type DWord # Dienst-Neustart als Scheduled Task: ueberlebt das Prozessbaum-Cleanup des Runners # beim Job-Ende (der fruehere Start-Process-Trick wurde dabei gekillt und liess den # Dienst gestoppt zurueck - Vorfall 2026-07-31, siehe ThreadNet-Web#5). - schtasks /create /f /tn RunnerRestart /ru SYSTEM /sc once /st ((Get-Date).AddMinutes(1).ToString('HH:mm')) /tr "powershell -Command Restart-Service gitlab-runner -Force"