I have ASP.NET Core web app (VS2017) and I develop Angular 4 front-end project (VS Code) which should be part of that Core web app. And I need to set up CI for the whole thing. So, when anything changes in either of those projects, it builds Angular 4 first, gets the artifacts and puts them into ASP.NET Core project, then build it and publish it to Azure.
At this moment, I have my Angular 4 project in a separate repo. So, ideally, I can set up CI on that repo and make it publish its artifacts to Azure Storage (for example). Then, I'd like to have another CI setup for ASP.NET Core repo to trigger the build, with the very first step to be 'get those Angular 4 artifacts and put them in here'. Something like this:
- if any file changes in NG4 repo => build it and yield the build
- it should trigger a build of ASPNETCore repo
- grab NG4 build and copy it inside ASPNETCore folder structure (like wwwroot)
- build ASPNETCore repo
- ...
- Test, Deploy, etc
So the question is - how can I do this with VSTS?
ok, so as I said I have 2 projects - ASP.NET Core MVC project (Core-P) and Angular 4 project (NG-P). They reside in separate repo's in VSTS. The goal is to automate build and publishing of the whole project to Azure App Service.
Here's how I made it work:
First. NG-P
Build tasks:
- 'npm install @angular/cli@latest -g' - add NPM task, set
npm command
to install, set arguments
to @angular/cli@latest -g.
- 'npm install' - this installs everything that's needed by your ng project.
- build your Angular 4 project for production. I made a simple build.cmd which is simply runs
ng build --aot --output-path dist --base-href work
. Notice --output-path dist: the project output will be put into 'dist' folder (which is a default for Angular-CLI I guess, but I just want to make sure). Besides, I use --base-href work option here, so this my angular 4 app will be available as [mydomain.com]/work in Core-P project.
- Archive files - this will archive everything in dist folder (the compiled app). Tick a Replace existing archive.
- Put this archive to Azure Blob Storage. I find it convenient to use Azure Blob Storage to make the artifact available for Cope-P build definition. First, Blob Storage is just always ready, so no set up is required (except you need to have Azure Storage Account). Besides, it's pretty secure, so my dist.zip is not publicly available. You can use any other method for sharing artifacts between builds.
Azure File Copy task has all required params - your Storage Acc Name, Key, destination Container Name. Set them accordingly, you'll need them in corresponding task for Core-P build.
- Trigger Core-P build - when NG-P has its artifact uploaded to Azure Blob Storage, we need to trigger the build of Core-P. In order to do that, you need to install Trigger Build Task extension from VSTS Marketplace.
Second. Core-P
So, we have built NG-P and it's available for Core-P build process as a dist.zip file sitting in Azure Blob Storage (or any other place you choose). Now, I created this build definition from the ASP.NET Core (PREVIEW)
template. So just go and create the one for your project and change to the following.
Tasks:
- Restore (.NET Core PREVIEW) - this one is created from the template. Do not change it.
- Build (.NET Core PREVIEW) - same
Now, we need to grab that dist.zip. In my case, to grab it from Azure Blob Storage somehow (if you used any other way to share dist.zip, you'll need to use your own task for it). I managed to used Azure PowerShell inline script for this:
$an = "[your_azure_storage_acc_name]"
$ak = "[storage_acc_key]"
$Ctx = New-AzureStorageContext -StorageAccountName $an -StorageAccountKey $ak
$blobs = Get-AzureStorageBlob -Container "ng-p-dist" -Context $Ctx
$destFolder = "$env:BUILD_ARTIFACTSTAGINGDIRECTORY"
New-Item -Path $destFolder -ItemType Directory -Force
$blobs | Get-AzureStorageBlobContent -Destination $destFolder -Context $Ctx
This will download dist.zip and puts in into Build.ArtifactStagingDirectory
directory.
Extract files - the task extracts dist.zip into $(Build.ArtifactStagingDirectory)/$(Build.Repository.Name)/wwwroot/js/app
. So Archive file patterns param is set to $(Build.ArtifactStagingDirectory)/dist.zip
, and Destination folder to $(Build.ArtifactStagingDirectory)/$(Build.Repository.Name)/wwwroot/js/app
PowerShell script - remove dist.zip, we don't need it anymore. This is a one-liner:
Remove-Item "$(Build.ArtifactStagingDirectory)/dist.zip"
- Test .NET Core PREVIEW - from the original template.
- Publish .NET Core PREVIEW - same
- Publish Artifact - same
So, this creates your ASP.NET Core MVC project with Angular 4 app inside. Now, I have to add 2 things to this setup:
- Cope-P should have a trigger based on dist.zip change. So, whenever NG-P changes, it creates a new dist.zip. And this should automagically trigger Cope-P build. I guess there will be some web hooks involved. I'll add it when I figure this out.
- Since I'm new to all this Build/Release pipeline, I have to actually publish the project to Azure App Service. This should be easy, since it's a standard task for VSTS. I just haven't had a change to get there.
So, HTH