Het project met een oude degelijke winformsapplicatie is geslaagd, ik heb een paar unittest die de basis consolideren, en tada… de code werkt, dus: doe de release build, copieer bestandjes uit de bin en zet deze op de externe locatie waar de applicatie gebruikt wordt.
Maar dat moet makkelijker, en betrouwbaarder en geautomatiseerderer.
Mijn ‘ambachtelijke’ CI/CD
In dit geval nog vooral het CD aspect: het opzetten en verbeteren van de Continuous Delivery.
De Basis
Mijn eigen buildscript voeg ik toe in een mapje ‘Install’ onder de root van het project. Hierin staat een CMD bestandje met dezelfde naam als het project (ik kom zodirect terug op de reden).
project \install -[projectnaam].cmd
Het script maakt een applicatieoplever- of publishmapje aan en kopieert de relevante bestanden (alleen de .dll, .exe en .config) van de releasebuild naar dit publishmapje.
SET CURRENTDIRECTORY=%~dp0%..\bin\Release\ SET OUTPUTDIRECTORY=c:\projecten\_publish\solutionnaam\ IF exist %OUTPUTDIRECTORY% ( echo '%OUTPUTDIRECTORY%' already exists but will be removed rd /s %OUTPUTDIRECTORY% ) mkdir %OUTPUTDIRECTORY%\release cd %CURRENTDIRECTORY% copy *.exe %OUTPUTDIRECTORY%\release copy *.dll %OUTPUTDIRECTORY%\release copy *.config %OUTPUTDIRECTORY%\release echo Copyprocess finished start %OUTPUTDIRECTORY%
Met de laatste regel wordt een verkenner geopend, zodat ik meteen de bestanden zie en kan gebruiken.
Meerdere toepassingen of klanten = meerdere configs
De applicatie wordt op meerdere plekken gebruikt maar ik beheer de applicatie en wil niet dat dit door elkaar gaat lopen. Eigenlijk wil ik dan ‘install klant1’ of ‘install toepassing1’ kunnen invoeren waarbij de specifieke config van die context wordt gebruikt en in een eigen publish wordt gezet.
project \install \context1 -[projectnaam].config -log4net.config \context2 -[projectnaam].config -log4net.config -[projectnaam].cmd
De install pas ik aan: bovenaan voeg ik een controle toe, %~1 is de eerste parameter en die mag niet leeg zijn. Als dat zo is dan moet ik naar een stukje script genaamd syntax
IF "%~1"=="" GOTO Syntax
Het scriptgedeelte voor ‘syntax’ voeg ik toe aan het eind van de huidige code. De eerste regel zorgt ervoor dat de reguliere uitvoering hier overheen springt (ga naar End Of File)
GOTO:EOF :Syntax CLS echo Package creator echo ================================== echo missing environmentparameter (context1 or context2) echo QUIT echo.
Tot slot het echte werk om de opgegeven parameter te gebruiken.
SET OUTPUTDIRECTORY=c:\projecten\_publish\solutionnaam\%1\
De regel met ‘copy *.config %OUTPUTDIRECTORY%\release’ vervang ik door het volgende:
rem copy environment specific configs cd %CURRENTDIRECTORY%..\..\install\%1 copy *.config %OUTPUTDIRECTORY%\release
Projectnaam
In een solution zitten meerdere projecten. De meeste zijn libraries, maar ik heb bijvoorbeeld een windows form (wif) voor de gebruiker, en een schoonmaak batch (bat) in een ander project in dezelfde solution. Nu heb ik dit install script onder het project van de wif, maar als ik een install script voor de batch ga toevoegen moeten ze elkaar niet overschrijven omdat ze dezelfde outputdirectory hebben.
Ik heb het cmd bestandje de project naam gegeven, dus die wil ik nu gebruiken:
SET PROJECTNAME=%~n0
En dat wil ik terug laten komen in mijn OUTPUTDIRECTORY:
SET OUTPUTDIRECTORY=c:\projecten\_publish\solutionnaam\%PROJECTNAME%\%1\
Versienummer
Dan wil ik eigenlijk ook iets hebben waarbij ik een unieke versie kan bewaren en herkennen. Om verwarring te voorkomen of voor als ik terug moet naar een vorige versie. In dit geval zet ik deze als parameter boven in het CMD bestand:
SET RELEASEVERSIE=0.156
Daarna voeg ik het toe aan mijn output directory:
SET OUTPUTDIRECTORY=c:\projecten\_publish\solutionnaam\%PROJECTNAME%\%1\%RELEASEVERSIE%\
ZIP
Nu wil ik dat het hele pakketje meteen als ZIP wordt verpakt. Hiervoor heb ik in ieder geval het gratis ‘7-Zip’ geïnstalleerd.
Het path voeg ik ergens bovenin toe bij de andere ‘SET’ opdrachten:
SET ZIPEXE="C:\Program Files\7-Zip\7z.exe"
Onder ‘echo Copyprocess finished’ kan ik een zip maken van de folder met bestanden:
cd %OUTPUTDIRECTORY%\release %ZIPEXE% a -tzip %OUTPUTDIRECTORY%%PROJECTNAME%_%RELEASEVERSIE%_%1.zip * cd %CURRENTDIRECTORY%../../install
Builden
Nu is het wel zaak dat ik een release build heb gemaakt. Het is me al eens gebeurd dat ik de vorige releasebuild heb uitgerold. Dus ik wil expliciet een release build toevoegen. Dat doe ik met het aanroepen van ‘devenv’. Dat is wel afhankelijk van je beschikbare en/of gebruikte Visual Studio versie. In dit geval wordt de 2017 Communityversie gebruikt.
SET DEVENVEXE="D:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\devenv.exe" echo Begin build release %DEVENVEXE% ..\..\%SOLUTIONNAME%.sln /ReBuild release /project ..\%PROJECTNAME%.csproj /projectconfig release echo Finished build release
Een toekomstige wens is nog om ook de unittest aan de CMD toe te voegen, da’s iets met vstest.console.exe myTestProject.dll.
Maar mijn volgende avontuur is het overzetten van mijn applicatie naar een buildpipeline in Azure Devops