Jak zbudować i zdiplojować paczkę na Azure przy pomocy Cake
Dzisiaj przedstawiam jak zbudować i zdiplojować paczkę na Azure przy pomocy Cake. Ten blogpost składa się z dwóch logicznych części. Po pierwsze przedstawiam i opisuję skrypt budujący paczkę. W drugiej natomiast pokazuję jak wygląda skrypt publikujący aplikację na Azure Web App. Zapraszam najserdeczniej.
Przygotowanie paczki
Aby przygotować paczkę należy wykonać kilka kroków, ale najpierw skrypt:
var target = Argument("target", "Default");
var configuration = Argument("configuration", "Release");
var packageDir = MakeAbsolute(Directory("./packages"));
Task("Restore-NuGet-Packages")
.Does(()=>
{
NuGetRestore("../src/IsTableBusy/IsTableBusy.sln");
});
Task("Clean-Package-Dir")
.Does(()=>
{
CleanDirectory(packageDir);
});
Task("Prepare-Api-Package")
.Does(()=>
{
var csprojPath = "../src/IsTableBusy/IsTableBusy.App.Api/IsTableBusy.App.Api.csproj";
var apiPackageDir = MakeAbsolute(Directory("./packages/Api")).ToString();
BuildPackage(csprojPath, apiPackageDir);
});
Task("Copy-Deploy-Scripts")
.Does(()=>
{
CopyFiles("./deployScripts/*", packageDir.ToString());
});
Task("Default")
.IsDependentOn("Restore-NuGet-Packages")
.IsDependentOn("Clean-Package-Dir")
.IsDependentOn("Prepare-Api-Package")
.IsDependentOn("Copy-Deploy-Scripts");
RunTarget(target);
private void BuildPackage(string csprojPath, string packagePath)
{
MSBuild(csprojPath,
settings => settings
.SetConfiguration(configuration)
.WithTarget("Package")
.WithProperty("PackageLocation", new string[]{ packagePath })
);
}
Przygotowanie
Na początek przygotowałem dwa taski:
- Restore-NuGet-Packages – do pobrania nugetów. Pisałem już o tym przy okazji budowania solucji i odpalania testów
- Clean-Package-Dir – w celu wyczyszczenia katalogu, gdzie paczka będzie przygotowywana, aby nie zaplątały się tam jakieś stare pliki
Budowanie projektu
Przygotowanie mamy za sobą, zatem pora na przyjemniejsze rzeczy. Następnym krokiem jest przygotowanie paczki przy pomocy MsBuild. Przygotowałem metodę prywatną BuildPackage przyjmującą dwa parametry: ścieżkę do pliku csProj oraz docelowe miejsce gdzie paczka ma zostać stworzona. Fragmentem na który warto zwrócić uwagę jest linia z `.WithTarget(„Package”)`. To właśnie tam definiowany jest tryb przygotowania paczki. Posiadając już taką funkcję możesz spojrzeć na task Prepare-Api-Package przygotowujący odpowiednie ścieżki i przekazujący je do metody BuildPackage.
Kopiowanie skryptów deplojująych
Wszystkie skrypty związane z CI umieściłem w katalogu Deployment w repozytorium. Przy czym budowanie paczki to jedno, a jej późniejsza publikacja ta drugie. W związku z tym stworzyłem również podkatalog deployScripts w którym leżą skrypty używane do diploja. Które opiszę w drugiej części wpisu. W każdym razie powinny one zostać skopiowane do katalogu z paczką, aby była ona kompletna i gotowe do użycia. Dokładnie to jest wykonane w tasku Copy-Deploy-Scripts.
Deploy Script
Jak wspomniałem wyżej skrypty publikujące, a konkretnej skrypt, umieściłem w katalogu deployScripts. Ma on za zadaniu odpowiednie skonfigurowanie paczki i wypchnięcie jej na serwer. Wygląda on tak:
#addin "Cake.MsDeploy"
var target = Argument("target", "Default");
var apiSiteName = Argument("apiSiteName");
var apiSitePassword = Argument("apiSitePassword");
var dbServer = Argument("dbServer");
var dbInitialCatalog = Argument("dbInitialCatalog");
var dbUserID = Argument("dbUserID");
var dbPassword = Argument("dbPassword");
var connectionString = $"Server=tcp:{dbServer}.database.windows.net,1433;Initial Catalog={dbInitialCatalog};Persist Security Info=False;User ID={dbUserID};Password={dbPassword};MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;";
Task("DeployApiApp")
.Does(()=>
{
var apiPackagePath = MakeAbsolute(File("./Api/IsTableBusy.App.Api.zip")).ToString();
var parameters = new List
{
new SetParameter()
{
Name = "IIS Web Application Name",
Value = apiSiteName
},
new SetParameter()
{
Name = "DefaultConnection-Web.config Connection String",
Value = connectionString
}
};
DeployToAzure(apiPackagePath, apiSiteName, apiSitePassword, parameters);
});
Task("Default")
.IsDependentOn("DeployApiApp"));
RunTarget(target);
private void DeployToAzure(string packagePath, string siteName, string sitePassword, List parameters)
{
var settings = new MsDeploySettings
{
Source = new PackageProvider
{
Direction = Direction.source,
Path = packagePath
},
Verb = Operation.Sync,
RetryAttempts = 5,
RetryInterval = 5000,
Destination = new AutoProvider
{
Direction = Direction.dest,
AuthenticationType = AuthenticationScheme.Basic,
ComputerName = "https://" + siteName + ".scm.azurewebsites.net:443/msdeploy.axd?site=" + siteName,
TempAgent = false,
Username = "$" + siteName,
Password = sitePassword
},
SetParams = parameters
};
MsDeploy(settings);
}
Powyższy skrypt działa. Patrząc na niego możesz go podzielić na trzy części:
- Argumenty, jakie powinny być przekazane, aby aplikacja mogła zostać opublikowana i poprawnie skonfigurowana.
- Task DeployApiApp odpowiednio przekazujący dane do prywatnej metody DeployToAzure
- Metoda DeployToAzure, odpowiedzialna za wypchnięcie paczki na podstawie dostarczonych parametrówprzy pomocy MsDeploy
Publish profile
Mam wrażenie, że jedyna niewiadoma, to skąd wziąć wartości parametrów „apiSiteName” i „apiSitePassword”. Pokazuje i objaśniam ;). Po zalogowaniu się na Azure Portal, stworzeniu komponentu WebApp i wejściu w jego szczegóły. Jest widoczny przycisk „Get publish profile”
Po kliknięciu w niego, zostanie pobrany plik xml. Zawiera on wiele zmiennych, natomiast do działania powyższego skryptu potrzeba tylko dwóch `msdeploySite` oraz `userPWD`. Mając te wartości możesz je przekazać do powyższego skryptu i wszystko powinno chulać.
Zakończenie
To wszystko na dziś. Kompletując wiedzę z tego wpisu oraz dwóch starszych o budowaniu paczki wraz z odpalaniem testów oraz o tym jak dodać dodatkowe parametry do SetParameters.xml masz już gotowy, może skromny, ale działający zaczątek do CI w Twoim projekcie. Czy post ten jest dla Ciebie wartościowy? Czy automatyzujesz takie rzeczy w Twoich projektach? Jeżeli nie to dlaczego?
0 Komentarzy