PCF Versionsverwaltung automatisieren: Ein Mal konfigurieren, nie wieder vergessen

PCF Versionsverwaltung automatisieren: Ein Mal konfigurieren, nie wieder vergessen

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:

  1. PCF-Version in der ControlManifest.Input.xml
  2. 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 zur Solution.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:

  1. Pfad zur ControlManifest.Input.xml:
XmlInputPath="$(MSBuildProjectDirectory)\..\DeinKomponentenName\ControlManifest.Input.xml"
  1. 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:

  1. Entwicklung: Code in der PCF-Komponente anpassen
  2. Versionierung: Nur die Version in ControlManifest.Input.xml erhöhen
  3. Build: dotnet build ausführen
  4. 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!