====== 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]]