====== Build-Pipeline ====== Build-Prozess für die WvdS FPC VSCode Extensions (Solution Manager, PAS2JS Studio, ISS Designer). ===== Übersicht ===== ┌─────────────────────────────────────────────────────────────┐ │ BUILD PIPELINE │ ├─────────────────────────────────────────────────────────────┤ │ │ │ 1. COMPILE (pas2js) │ │ ├── Unit Resolution (-Fu Pfade) │ │ ├── Pascal → JavaScript Transpilation │ │ └── Source Map Generierung + Repair │ │ │ │ 2. BUNDLE (esbuild) │ │ ├── npm Dependencies inlinen (@xmldom/xmldom) │ │ ├── Node.js Builtins externalisieren │ │ └── Minification (nur Release) │ │ │ │ 3. DEPLOY (manuell oder VSIX) │ │ ├── Copy dist/extension.js → ~/.vscode/extensions/ │ │ └── Oder: vsce package → .vsix │ │ │ └─────────────────────────────────────────────────────────────┘ ===== Build-Scripts ===== Jede Extension hat ein eigenes ''build.ps1'', orchestriert durch ''ci-build.ps1'': vsce/ ├── ci-build.ps1 ← CI-Orchestrator ├── wvds-fpc-solution-manager/ │ └── build.ps1 ← SM Build ├── wvds-fpc-pas2js-studio/ │ └── build.ps1 ← PAS2JS Build ├── wvds-fpc-iss-designer/ │ └── build.ps1 ← ISS Build └── wvds-fpc-tools/ └── package.json ← Extension Pack (kein Build) ===== Phase 1: Kompilierung (pas2js) ===== ==== Compiler-Aufruf ==== # Debug-Build pas2js -Tnodejs -Jm -Jminclude -O1 -vd -Fu -o dist\extension.pas2js.js src-pas\extension.pas # Release-Build pas2js -Tnodejs -O2 -Fu -o dist\extension.pas2js.js src-pas\extension.pas ==== Compiler-Flags ==== ^ Flag ^ Beschreibung ^ | ''-Tnodejs'' | Target: Node.js (CommonJS Module) | | ''-Jm'' | Source Maps generieren | | ''-Jminclude'' | Pascal-Quellen in Source Map einbetten | | ''-O1'' | Debug: minimale Optimierung | | ''-O2'' | Release: volle Optimierung | | ''-vd'' | Debug: Verbose-Ausgabe | | ''-Fu'' | Unit-Suchpfad hinzufügen | | ''-o'' | Ausgabedatei | **Verbotene Flags:** * **''-Jl''** (Lowercase Identifiers): Bricht ''asm''-Blöcke, die PascalCase-Parameter referenzieren (''ModuleName'', ''Value'', ''VSCodeMod''). * **terser %%--%%mangle**: Renamed Parameter, aber NICHT in ''asm''-Blöcken → ''ReferenceError''. ==== Unit-Suchpfade ==== Die Funktion ''Get-UnitPaths'' in ''build.ps1'' definiert alle Suchpfade: | Kategorie | Pfad (relativ zum Extension-Root) | Beschreibung | ^ pas2js Bindings | ''../../pas2js/NodeJS'' | Node.js API Wrapper | ^ | ''../../pas2js/VSCode'' | VSCode Extension API | ^ | ''../../pas2js/Browser'' | Browser/DOM API | ^ | ''../../pas2js/Components/Runtime'' | Runtime Renderer | ^ | ''../../pas2js/Components/Designer'' | Design-Time Renderer | ^ | ''../../pas2js/Components/GUI/*'' | GUI-Komponenten (30+ Ordner) | ^ fpc-core | ''../../fpc-core/core'' | Models, Parser | ^ | ''../../fpc-core/services'' | Platform, WebView, Logger | ^ | ''../../fpc-core/utils'' | Constants, Interop | ^ | ''../../fpc-core/build'' | Build-System Logik | ^ Extension-lokal | ''src-pas/tree'' | Tree View Provider | ^ | ''src-pas/services'' | Extension-spezifische Services | ^ | ''src-pas/editor'' | WebView Panels | ^ | ''src-pas/build'' | Build-Logik | ^ | ''src-pas/debug'' | Debug-Adapter | ^ | ''src-pas/tests'' | Unit-Tests | ==== Source Map Repair ==== pas2js hat einen Bug: Source-Map-Dateien enthalten manchmal Garbage-Bytes vor dem JSON. ''Repair-SourceMap'' entfernt alles vor dem ersten ''{'' Zeichen. ===== Phase 2: Bundling (esbuild) ===== Nach der pas2js-Kompilierung bündelt esbuild die npm-Dependencies: pas2js → extension.pas2js.js → esbuild → extension.js ==== esbuild-Konfiguration ==== esbuild extension.pas2js.js ` --bundle ` --platform=node ` # Node.js Builtins (fs, path, ...) externalisieren --format=cjs ` # CommonJS für VSCode Extension Host --external:vscode ` # VSCode API als externen require belassen --target=node18 ` # Minimale Node.js Version --outfile=extension.js # Debug: --sourcemap=external # Release: --minify ==== Warum esbuild? ==== * npm-Dependencies (z.B. ''@xmldom/xmldom'') werden in eine Datei gebundelt * Kein ''node_modules'' im deployed Extension nötig * ''%%--%%minify'' ist **safe** für pas2js ''asm''-Blöcke (anders als terser) * Schnell: ~50ms für das gesamte Bundle ==== Build-Output ==== dist/ ├── extension.pas2js.js # Intermediate (pas2js Output) ├── extension.pas2js.js.map # Source Map (Debug) ├── extension.js # Final Bundle (esbuild Output) └── extension.js.map # Bundled Source Map (Debug) ===== Phase 3: Deploy ===== ==== Lokales Deployment (Entwicklung) ==== # Manuell: dist/extension.js in die installierte Extension kopieren $extDir = "$env:USERPROFILE\.vscode\extensions\wvds.wvds-fpc-solution-manager-0.1.0" Copy-Item dist\extension.js "$extDir\dist\extension.js" Copy-Item dist\extension.js.map "$extDir\dist\extension.js.map" # Dann: VSCode → Developer: Reload Window (Ctrl+Shift+P) ==== VSIX-Paketierung ==== # Einzelne Extension .\build.ps1 -Vsix # Ergebnis: D:\Workspace\binaries\{extension}\vscode\{Release|Debug}\*.vsix ===== CI-Orchestrator (ci-build.ps1) ===== ''ci-build.ps1'' baut alle drei Extensions in einem Durchlauf: ==== Parameter ==== ^ Parameter ^ Beschreibung ^ | ''-Debug'' | Debug-Builds für alle Extensions | | ''-Release'' | Release-Builds für alle Extensions | | ''-Test'' | Unit-Tests ausführen | | ''-Vsix'' | VSIX-Pakete erstellen | | ''-Archive'' | VSIX in Nightly-Archiv kopieren | | ''-Nightly'' | Alias für ''-Debug -Release -Test -Vsix -Archive'' | | ''-Extension sm/pas2js/iss'' | Nur bestimmte Extension bauen | | ''-KeepDays 30'' | Nightly-Archive älter als N Tage löschen | ==== Ausführung ==== # Typischer Entwickler-Build powershell -ExecutionPolicy Bypass -File ci-build.ps1 -Debug # Vollständige Nightly-Pipeline powershell -ExecutionPolicy Bypass -File ci-build.ps1 -Nightly # Nur PAS2JS Studio Release + VSIX powershell -ExecutionPolicy Bypass -File ci-build.ps1 -Release -Vsix -Extension pas2js ==== Pipeline-Ablauf ==== Für jede Extension (SM → PAS2JS → ISS): 1. Prüfen ob build.ps1 existiert 2. Debug-Build ausführen (wenn -Debug) 3. Release-Build ausführen (wenn -Release) 4. Tests ausführen (wenn -Test und HasTest) 5. VSIX paketieren (wenn -Vsix) Danach (wenn -Archive): 6. VSIX in D:\Workspace\binaries\nightly\{yyyy-MM-dd}\ kopieren 7. Archive älter als KeepDays Tage löschen Abschluss: 8. Summary mit OK/FAIL pro Extension + Gesamtzeit ==== Beispiel-Output ==== ================================================ WvdS FPC Tools - CI Build Pipeline 2026-02-28 21:30:04 ================================================ [21:30:04] Pipeline: Debug [21:30:04] Extensions: ALL --- Solution Manager --- [21:30:04] Building Solution Manager [Debug]... ... [21:30:06] Solution Manager completed in 2.1s --- PAS2JS Studio --- ... --- ISS Designer --- ... ================================================ CI Summary ================================================ Solution Manager: Debug:OK PAS2JS Studio: Debug:OK ISS Designer: Debug:OK Total: 5.9s ================================================ PIPELINE SUCCESSFUL ===== Build-Modi ===== ^ Modus ^ Flag ^ Optimierung ^ Source Maps ^ Minification ^ | Debug | ''build.ps1 -Debug'' | ''-O1'' | Ja (eingebettet) | Nein | | Release | ''build.ps1'' | ''-O2'' | Nein | Ja (esbuild) | | Test | ''build.ps1 -Test'' | ''-O1'' | Ja | Nein | ===== Watch-Mode ===== Für die Entwicklung: automatisches Neukompilieren bei Änderungen: .\build.ps1 -Watch -Debug Überwacht ''src-pas\**\*.pas'' via ''FileSystemWatcher'' mit Debounce. ===== Qualitätsanforderungen ===== **Null-Toleranz-Policy:** Jeder Build MUSS mit **zero errors, zero warnings, zero hints** abschließen. Keine ''{$WARNINGS OFF}'' oder ''{$HINTS OFF}'' Direktiven erlaubt. ===== Fehlerbehebung ===== ==== "Unit not found" ==== * ''-Fu'' Pfad in ''Get-UnitPaths'' prüfen * Neues Unterverzeichnis in ''localDirs'' Array aufnehmen * ''pas2js.cfg'' prüfen (RTL-Pfade) ==== "identifier not found" in asm Block ==== * ''-Jl'' Flag entfernen (lowercased PascalCase-Bezeichner) * ''end'' Keyword → Bracket-Notation: ''r["end"].line'' * Regex-Literale → ''new RegExp('pattern', 'flags')'' * ''this'' in Interface-Prozeduren = ''$mod'', Implementation-Vars auf ''$impl'' ==== esbuild Bundling-Fehler ==== * ''require()'' muss statisch analysierbar sein (kein dynamischer String) * ''%%--%%external:vscode'' sicherstellen * ''%%--%%platform=node'' externalisiert Node.js Builtins automatisch ==== Source Map zeigt falschen Code ==== * Prüfen ob ''Repair-SourceMap'' lief (Garbage-Bytes) * ''-Jminclude'' für eingebettete Quellen nutzen ===== Dateien ===== | Datei | Beschreibung | ^ ''vsce/ci-build.ps1'' | CI-Orchestrator für alle Extensions | ^ ''vsce/{extension}/build.ps1'' | Extension-spezifisches Build-Script | ^ ''dist/extension.pas2js.js'' | Intermediate pas2js Output | ^ ''dist/extension.js'' | Final esbuild Bundle | ^ ''dist/extension.js.map'' | Source Map (nur Debug) | ===== Siehe auch ===== * [[.:targets|Build-Targets]] * [[.:release|Release-Prozess]] * [[.:testing|Testing]] * [[.:umgebung|Entwicklungsumgebung]]