Du entwickelst eine PCF-Komponente, baust sie, deployest sie – und stellst dann fest, dass die alte Version noch aktiv ist, weil du vergessen hast, die Versionsnummer zu erhöhen. Frustrierend, oder?
Heute zeige ich dir eine elegante Lösung, mit der du die Versionsverwaltung deiner PCF-Komponenten vollständig automatisieren kannst. Ein Mal konfigurieren, nie wieder manuell anpassen müssen.
Das Problem mit der PCF-Versionsverwaltung
Bei der Entwicklung von PCF-Komponenten müssen normalerweise zwei Versionen synchron gehalten werden:
- PCF-Version in der
ControlManifest.Input.xml
- Solution-Version in der
Solution.xml
Vergisst man eine der beiden zu aktualisieren, wird die neue Version nicht korrekt deployed. Besonders ärgerlich wird es, wenn man die alte Solutions.zip
überschreibt und dann nicht mehr weiß, welche Version gerade aktiv ist.
Die Lösung: Automatisierte Versionssynchronisation
Die Lösung liegt in der intelligenten Konfiguration der Solutions.cdsproj
-Datei. Mit den richtigen MSBuild-Targets können wir:
- ✅ Die Version automatisch von der
ControlManifest.Input.xml
zurSolution.xml
synchronisieren - ✅ Die generierte ZIP-Datei automatisch mit der Versionsnummer benennen
- ✅ Nie wieder eine veraltete Version überschreiben
Die Implementierung
Hier ist der Code, den du in deine Solutions.cdsproj
am Ende einfügen musst:
<!-- Eigenschaften für Zeitstempel (wenn gewünscht) -->
<PropertyGroup>
<BuildTimestamp>$([System.DateTime]::Now.ToString("yyyyMMddHHmmss"))</BuildTimestamp>
</PropertyGroup>
<!-- Versionen zwischen ControlManifest und Solution synchronisieren -->
<Target Name="SyncVersions" BeforeTargets="Build">
<!-- Version aus ControlManifest.Input.xml auslesen -->
<XmlPeek XmlInputPath="$(MSBuildProjectDirectory)\..\SelectableDraggableSVG\ControlManifest.Input.xml"
Query="/manifest/control/@version">
<Output TaskParameter="Result" PropertyName="ControlVersion" />
</XmlPeek>
<Message Text="Control Version: $(ControlVersion)" Importance="high" />
<!-- Solution.xml aktualisieren -->
<XmlPoke XmlInputPath="$(MSBuildProjectDirectory)\src\Other\Solution.xml"
Query="/ImportExportXml/SolutionManifest/Version"
Value="$(ControlVersion)" />
<Message Text="Solution Version auf $(ControlVersion) aktualisiert" Importance="high" />
</Target>
<!-- Benutzerdefiniertes Target nach dem Build -->
<Target Name="RenameOutputFile" AfterTargets="Build">
<!-- Version aus Solution.xml auslesen -->
<XmlPeek XmlInputPath="$(MSBuildThisFileDirectory)src\Other\Solution.xml"
Query="/ImportExportXml/SolutionManifest/Version/text()">
<Output TaskParameter="Result" PropertyName="SolutionVersion" />
</XmlPeek>
<PropertyGroup>
<OriginalZipFile>$(OutputPath)Solutions.zip</OriginalZipFile>
<NewZipFileName>novaCaptaSvgComponent_$(SolutionVersion).zip</NewZipFileName>
</PropertyGroup>
<Copy SourceFiles="$(OriginalZipFile)"
DestinationFiles="$(OutputPath)$(NewZipFileName)"
OverwriteReadOnlyFiles="true" />
<Message Text="ZIP-Datei umbenannt: $(NewZipFileName)" Importance="high" />
</Target>
Wie funktioniert es?
1. Versionssynchronisation (SyncVersions
Target)
Das SyncVersions
-Target wird vor dem Build ausgeführt und:
- Liest die Version aus der
ControlManifest.Input.xml
aus - Schreibt diese Version automatisch in die
Solution.xml
- Gibt eine Bestätigungsmeldung aus
2. Automatische Dateibenennung (RenameOutputFile
Target)
Das RenameOutputFile
-Target wird nach dem Build ausgeführt und:
- Liest die aktuelle Version aus der
Solution.xml
- Kopiert die
Solutions.zip
zu einer versionierten Datei - Beispiel:
novaCaptaSvgComponent_1.2.3.zip
Die Vorteile im Überblick
✅ Single Source of Truth
Du musst nur noch die Version in der ControlManifest.Input.xml
anpassen – alles andere passiert automatisch.
✅ Keine überschriebenen Versionen
Jede Version wird als separate ZIP-Datei gespeichert. Du verlierst nie eine funktionierende Version.
✅ Klare Versionierung
Der Dateiname zeigt sofort, welche Version du vor dir hast.
✅ Weniger Fehlerquellen
Keine manuellen Schritte = weniger Möglichkeiten für Fehler.
Anpassungen für dein Projekt
Du musst nur zwei Pfade in der Konfiguration anpassen:
- Pfad zur ControlManifest.Input.xml:
XmlInputPath="$(MSBuildProjectDirectory)\..\DeinKomponentenName\ControlManifest.Input.xml"
- Name der ZIP-Datei:
<NewZipFileName>DeinKomponentenName_$(SolutionVersion).zip</NewZipFileName>
Best Practices für PCF-Versionierung
Basierend auf den Erkenntnissen der Community solltest du folgende Regeln beachten:
Versionsformat
- ✅ Verwende das Format
MAJOR.MINOR.PATCH
(z.B.1.2.3
) - ❌ Vermeide Zusätze wie
-beta
oder vierte Versionsnummern
Deployment-Strategien
- Entwicklung: Nutze
pac pcf push
für schnelle Tests - Produktion: Verwende immer Solution-basierte Deployments mit
msbuild
Versionsinkrementierung
- PATCH (z.B. 1.0.0 → 1.0.1): Bugfixes, kleine Änderungen
- MINOR (z.B. 1.0.0 → 1.1.0): Neue Features, größere Änderungen
- MAJOR (z.B. 1.0.0 → 2.0.0): Breaking Changes
Der Workflow in der Praxis
Mit dieser Konfiguration sieht dein Entwicklungsworkflow so aus:
- Entwicklung: Code in der PCF-Komponente anpassen
- Versionierung: Nur die Version in
ControlManifest.Input.xml
erhöhen - Build:
dotnet build
ausführen - Ergebnis: Automatisch versionierte ZIP-Datei im Output-Ordner
Fazit
Diese Automatisierung spart nicht nur Zeit, sondern reduziert auch Fehlerquellen erheblich. Einmal konfiguriert, musst du dir nie wieder Gedanken über die Versionssynchronisation machen.
Die Lösung ist besonders wertvoll für:
- Teams, die gemeinsam an PCF-Komponenten arbeiten
- CI/CD-Pipelines, die automatisierte Builds benötigen
- Entwickler, die mehrere PCF-Komponenten parallel entwickeln
Hast du diese Lösung bereits implementiert? Welche Erfahrungen hast du mit der PCF-Versionsverwaltung gemacht? Teile deine Gedanken in den Kommentaren!