One of my customers wanted to deploy an Angular application to Azure App Service. Azure DevOps was already used in another project so it was obvious to use it for this new one.
I work on MacOS so homebrew can help to install packages. If you are on Windows or Linux, you can find the last files to install there.
On MacOS when homebrew is already installed, you just have to run the command:
brew install node
Once node installed, you can get the last Angular CLI. This utility can help in various tasks. One of them is to create new Angular projects from scratch.
To install Angular CLI globally, you can use this command:
npm install -g @angular/cli
The CLI will be available anywhere on your system.
We can now create a new Angular project. The command is very simple :
ng new HelloWorld --strict false --routing false --style css
This command will create a new project called HelloWorld with default settings. It can take a little of time because of the number of modules to add.
Go in the folder of the project
You can try the application using the command:
This command will generate the application and create a node server on port 4200. Just launch your browser at http://localhost:4200/ to see the default page.
You can use Control C in the terminal to exit.
Congratulations, our application is ready to be deployed! It's time to add the CI/CD part.
I will not explain how to create an Azure DevOps project here. It's very simple and if you have doubts, you can read the documentation.
We have now to create a new pipeline.
The first part is building the application
- stage: Build displayName: Build stage jobs: - job: BuildJob pool: vmImage: 'ubuntu-20.04' steps: - task: NodeTool@0 inputs: versionSpec: '10.x' displayName: 'Install Node.js' - script: | cd '$(System.DefaultWorkingDirectory)/HelloWorld' npm install -g @angular/cli npm install ng build --prod displayName: 'npm install and build' - task: ArchiveFiles@2 displayName: 'Archive files' inputs: rootFolderOrFile: '$(System.DefaultWorkingDirectory)/HelloWorld/dist/HelloWorld/' includeRootFolder: false archiveType: zip archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip replaceExistingArchive: true - task: PublishBuildArtifacts@1 inputs: PathtoPublish: '$(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip' ArtifactName: 'drop' publishLocation: 'Container'
The code is pretty simple:
- We install node on the agent
- We install the Angular CLI
- We install the NPM packages
- We build the Angular application
- We zip the files
- We publish the zip as artifact
The second part is deploying the application:
- stage: Deploy displayName: 'Deploy Web App' dependsOn: Build condition: succeeded() jobs: - deployment: DeploymentJob pool: vmImage: 'ubuntu-20.04' environment: $(environmentName) strategy: runOnce: deploy: steps: - task: AzureWebApp@1 displayName: 'Deploy Azure Web App : $(webAppName)' inputs: azureSubscription: $(azureSubscription) appName: $(webAppName) appType: webAppLinux package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip
In this stage, we only have on action. We get the artifact as zip file and we publish it to Azure App Service with the zip deploy task.