Tag Archives: ci

CI und CD für GitHub mit AppVeyor

In diesem Post zeige ich wie sich Continuous Integration und Continuous Delivery für ein GitHub Repository umsetzen lässt. Dabei soll ein .NET Projekt bei jeder Änderung gebuildet und auf manuelles zu tun released werden (neuer Git Release inkl. Tag und NuGet-Package auf NuGet.org). Dafür verwende ich AppVeyor. Als Beispiel Projekt dient https://github.com/msallin/SQLiteCodeFirst.

Continue reading

Build automation und deployment für CRM Solutions mit TFS

In meinem Post “CRM Customizations VS/TFS Integration” habe ich gezeigt wie sich eine CRM Solution in ein Visual Studio Projekt integrieren lässt.
Dafür wird sie entpackt und ihre Komponenten werden auf verschiedene Dateien aufgeteilt. Schlussendlich wird die default Build-Action überschrieben, damit die Solution beim “Build” wieder gepackt wird.

In diesem Post zeige ich, wie die Solution mit einem Buildjob gebuildet und automatisch auf ein CRM System deployt werden kann.
Continue reading

CRM Customizations VS/TFS Integration

Microsoft Dynamics CRM bietet die optimale Grundlage um schnell Projekte abwickeln zu können. Viele Anpassungen an der Applikation erfordern keinen Code. Die Anpassungen werden als „Solutions“, in Form einer ZIP-Datei, exportiert. In Enterprise Szenarien soll jedoch auch für diese Anpassungen die volle ALM Funktionalität von Visual Studio und TFS genutzt werden können.

Continue reading

Project default targets (build, rebuild & clean) überschreiben

Nicht immer möchte man als Output einer Build Action auf einem Project ein Assembly erhalten. Natürlich könnte man einen eigenen Projekttyp erstellen. Dafür muss jedoch jeder Entwickler diese Extension installiert haben.
Es ist viel einfacher die default targets eines CSProj Library Projects zu überschreiben.

Im folgenden Beispiel soll der Build Output eines Projektes ein ZIP File sein. Das Projekt enthält kein Code und muss daher nicht kompiliert werden. Die Ordnerstruktur im Project soll eins zu eins so in das ZIP File übernommen werden. Dabei sollen zwei Build Actions (auf den Items) berücksichtigt werden.
Dabei werden “Content” Items gemäss “Copy to Output Directory” kopiert und in das ZIP gepackt. “Content” Items werden ebenfalls gemäss “Copy to Output Directory” kopiert aber nicht in das ZIP gepackt sondern einfach in das Output Verzeichnis kopiert.
Projektstruktur
Wenn das Projekt keinen Code enthält, muss der Output type “Class Library” sein. Ansonsten wird eine “Main”-Methode verlangt.

Um das zu erreichen, sind drei Schritte notwendig.

  1. Eigenes Targets file erstellen
  2. Default Targets in CSProj löschen
  3. Eigenes Targets file importieren

Eigenes Targets file erstellen
Grundsätzlich lassen sich die Targets direkt im Project-File hinzufügen.
Damit die Targets für mehrer Projects wiederverwendet werden können, ist es ratsam, ein eigenständiges targets file zu erstellen.
Des weiteren ist auch das editieren direkt im Visual Studio möglich (ohne das Projekt schliessen zu müssen).

Es müssen Targets mit den folgenden Namen erstellt werden: “Build”, “Rebuild” und “Clean”. Wobei das “Clean” das Output Verzeichnis leert und “Rebuild” “Clean” und anschliessend “Build” aufruft.

<Target Name="Build">
  <!-- Run the copy for "None" items as usual -->
  SourceFiles="@(None)" Condition="%(None.CopyToOutputDirectory) == 'Always'" DestinationFolder="$(OutputPath)" SkipUnchangedFiles="false" />
  SourceFiles="@(None)" Condition="%(None.CopyToOutputDirectory) == 'PreserveNewest'" DestinationFolder="$(OutputPath)"  SkipUnchangedFiles="true" />

  <!-- The <span class="hiddenSpellError" pre="The " data-mce-bogus="1">Packager</span> needs the exact package structure -->
  <MakeDir Directories="@(Content -> '$(OutputPath)Temp%(RelativeDir)')" />
  SourceFiles="@(Content)" DestinationFolder="$(OutputPath)Temp%(RelativeDir)" />

  <Exec Command="%YOUR_ZIP_TOOL%" />

  <RemoveDir Directories="$(OutputPath)Temp" />
</Target>

Wenn das Project auch über einen TFS Build Agent gebuildet werden soll muss beachtet werden, dass nur Items welche nach “$(OutDir)” kopiert werden auch in den Dropfolder gelangen. Lokal hat “$(OutDir)” denselben Wert wie “$(OutputPath)”.

<PropertyGroup>
  <RebuildDependsOn>
    Clean;
    Build;
  </RebuildDependsOn>
</PropertyGroup>
<Target Name="Rebuild" DependsOnTargets="$(RebuildDependsOn)" />
<Target Name="Clean">
  <RemoveDir Directories="$(OutputPath)" />
</Target>

Default Targets in CSProj löschen
Die folgenden zwei Targets im Project File suchen und löschen.

MSBuildExtensionsPath)$(MSBuildToolsVersion)Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)$(MSBuildToolsVersion)Microsoft.Common.props')" />
MSBuildToolsPath)Microsoft.CSharp.targets" />

Eigenes Targets file importieren
Das erstellte targets File importieren. Wenn es für mehrere Projekt benötigt wird kann es auf Solution Ebene abgelegt und mit einem relativen Pfad referenziert werden.

<Import Project="..MyTargets.targets" />