Automate publish of Angular library as npm package with Azure DevOps

Reading time: 10 minutes

Description

In this post I will explain how to set up continuous deployment of Angular library as npm package with Azure DevOps.

This post will also contain instructions of how to configure the build pipeline, how to configure your Angular application as developer and as a consumer of this package.

I will build two Angular applications for this purpose, so it will be clear to distinguish between the library and consumer applications.

What is required

What’s good about it?

If you are using npm packages you need to host them somewhere. There are several options available. Normally if it’s for public use then it’s free if private or corporate then it obviously costs money. That is their business model.

If you already have an Azure subscription then you have an option to store and host them there. This might be more cost effective but it depends on your needs and availability.

For me it was handy to have an Azure DevOps repo that would have continuous integration trigger enabled, so when I commit a change it would build it and publish it for me.

Once I set up the build pipeline it would do the main stuff related to publishing for me. So the only thing that I would have left to do is set the correct version from my local machine.

Let’s start with initiating a repository for an Angular library on Azure DevOps

Prerequisite: you need a project on Azure DevOps. Go to your Azure DevOps main page.

Once the project is created select Repos from the left side menu. Clone this repo to your computer by copying the url link and using it with your choice of Git GUI.

If you haven’t configured your environment with Angular yet then please do so.

Install Visual Studio Code on your machine. Please use the link below.

https://code.visualstudio.com/download

Then you need to install an appropriate Node.js version that is compatible with your version of Angular.

https://nodejs.org/en/download/

Let’s create an Angular library

Open VS code and navigate to the root folder of the destination where you cloned your repo.

In VS code new terminal type ‘cd destination-of-your-repo’ for example ‘cd C:\Users\dmitr\source\frontend\AzureArtifactsNpmPublish’

Then type

ng new AzureArtifactsNpmPublish --directory=./ --skip-install --create-application=false

The name of this app should match the folder name. This way it will use the root folder and won’t nest it within an extra folder.

As a result you get minimum files created plus it is created straight away in the repo root folder. Pretty neat.

Open the project code files in new the window by typing ‘code .

Then type ‘ng g library your-library-name’ for example ng g library azure-npm-ng-lib

Once you have done this and you are happy with the output please commit-push to Azure DevOps repo.

Before we head on to create a pipeline we need to create the feed that we will be using to store and manage our packages

Select Artifacts from the left side menu of the project on Azure DevOps. Click on Create feed and type in the name for your feed. For Visibility it should be Members of name-of-your-organisation. Make sure Upstream sources Include packages from common publish sources is ticked. As for the Scope select Organization.

All of these settings are applicable to our current needs. If you want to limit who can use the feed then you need to select the appropriate Visibility and Scope.

We are ready to create a build pipeline

Go to the Pipelines section and click Create Pipeline. Then select Classic Editor.

Since we created our repo with Azure DevOps we need to select Azure Repos Git. As for the template, Empty Job will fit our needs.

Because we will use Angular Cli we need Node.js. So the first task will be Node.js Installer.

We also need angular cli install, npm install, npm build and npm publish tasks.

For angular cli install task we need to set Command as custom, in Command and arguments enter ‘install @angular/cli -g’

For the npm install task we will leave it as it is.

For the npm build task we need to set for ‘Working folder that contains package.json’ the location of the root of the library folder within the angular project e.g. ‘projects/azure-npm-ng-lib’
Also in here for ‘Command and arguments’ we need to type ‘run build your-library-name –prod’ e.g. run build azure-npm-ng-lib –prod

For npm publish task we need set ‘Working folder that contains package.json’ with the destination after the application was built. We know that build files are placed by default into the ‘dist/project-name’ folder (you can change this outputPath in angular.json). Hence the location of this library would be at ‘dist/azure-npm-ng-lib’ and the full path ‘$(System.DefaultWorkingDirectory)/dist/azure-npm-ng-lib’
As for ‘Registry Location’ we want to set ‘Registry’ and for ‘Target registry’ we need to pick a registry that is preferably organization scoped.

Additionally we need to set CI trigger and Agent Specification for this pipeline.

Different agent specifications would have different build processes and different paths. For our purpose we will use ubuntu-18.04 agent specification.

Click on the Pipeline section and set the appropriate agent specification for your needs.

Select dropdown of Save & Queue and select Save.

Before we can run it we need to allow this pipeline to make changes to Artifacts feed-registry that we selected in the npm publish task as Target registry.

Once this is done you need to go back to Pipelines and click Run Pipeline. Check the images for more info.

Click on the dropdown of Save & Queue.

If the build is successfull we can find our package under Artifacts side menu option.

*make sure tsconfig.lib.json library level enableIvy is set to false i.e. “angularCompilerOptions”: { “enableIvy”: false }
*and package.json contains scripts part with ng build i.e. “scripts”: { “ng”: “ng”, “build”: “ng build” }

Next we need to configure our machine to use artifacts feed-registry for our npm package

Since we will be storing our npm packages in Azure DevOps feed we need to configure our client machine to use this feed.

There is a helpful section of how to do this under Artifacts. Click on Connect feed and then select npm. On the newly opened section click ‘Get the tools’. This should open a slide menu with description of how to do it.

Since we already configured Node.js and npm at the beginning we can skip to Step 2. Copy the command ‘npm install -g vsts-npm-auth –registry https://registry.npmjs.com –always-auth false’

Open a new terminal in VS code and run it. As an extra check if it was installed you can run this command ‘npm list -g –depth 0’ and see if it’s in the list.

There are more details as to how to set up authentication.

Let’s create another Angular app that would consume our npm package

Before that we need to initiate a repository at Azure DevOps. Select Repos in left side menu. Click a dropdown next to the name of your current repository. Select New Repository.

Clone it to your machine and keep in mind the location.

Open VS code and navigate to that location. Run this command

ng new AzureArtifactsNpmConsumer --directory=./ --skip-install

Make sure the name matches the name of the root folder. This way your app won’t be nested within an extra folder.

Next we need to set up our Angular project according to the provided instructions at Azure DevOps Connect to feed section

Add npmrc file to your root project. In my case this would be ‘C:\Users\dmitr\source\frontend\AzureArtifactsNpmConsumer\.npmrc’

Paste in the first command from Connect to feed description into project level npmrc file.

If you open a user level npmrc file which is located at ‘C:\Users\yourName\.npmrc’ and either take a screenshot or copy it somewhere as a backup before it is be modified.

Then run this command in the same project ‘vsts-npm-auth -config .npmrc’.
You will be prompted with a login window. Follow the onscreen instructions to complete the authentication process.

Now if you close and open again the user level npmrc file you would be able to see the difference.

There’s another thing you can do to assist the process of the authentication. Open package.json of the project you are working on and add this bit “refreshVSToken” : “vsts-npm-auth -config .npmrc” into the scripts section. So it would look like so “scripts”: {“refreshVSToken” : “vsts-npm-auth -config .npmrc”}

So in case you are required to refresh the token you can write in terminal ‘npm run refreshVSToken’ and it should reauthenticate you/refresh the token at user level npmrc file.

Basically what is happening behind the scene is every time we run npm install the authentication process kicks in. The token that is in the npmrc file at user lever location is exchanged with registry-feed, so that user machine gets authenticated.

Let’s test if we can install our library package to our Angular consumer app

Please go to the Artifacts at Azure DevOps from there into the package details page and copy the full command to install the package. For example ‘npm install azure-npm-ng-lib@0.0.1’

Use this command in the Angular app where you want to access this npm package.

Next let’s add some code to Angular app and test if we can use npm package code

Open app.component.ts and add this code.

constructor(private _azureNpmNgLibService: AzureNpmNgLibService) {
  }

  ngOnInit(): void {
    this.mainFunc();
  }

  mainFunc(){
    let message = this._azureNpmNgLibService.getMessage();
    console.log(message);
    console.log(123)
  }

So it would look like the image below. Then run ‘ng serve -o’ and open the developer tools. Check if the console/debugger tab contains our ng library npm package message.

Next let’s apply a change and increase the version of lib package

In terminal navigate into folder where library files live and type in ‘npm version 0.0.2’ e.g. C:\Users\dmitr\source\frontend\AzureArtifactsNpmPublish\projects\azure-npm-ng-lib> npm version 0.0.2
This way the package.json version of the library would be updated.

Optionally change the message.

export class AzureNpmNgLibService {

  constructor() { }
  
  getMessage(){
    return "wow what an update! is it the font or a colour :-D"
  }
}

Then commit-push these changes. This should trigger a new build.

This should update our existing package to 0.0.2. You can check this at the Artifacts section.

Next let’s update our Angular consumer app to the latest version of our npm package

In the terminal type in ‘npm outdated’. This would list all the packages that have updated versions.

To update the package to the latest version we need to use ‘npm i azure-npm-ng-lib@latest’ You can also target a particular the version then you need to write what version number like so ‘npm i azure-npm-ng-lib@2.0.0’

Once it is updated to the latest version it is removed from the outdated list. If it’s not the latest it will still be there. For instance if you have 3 versions and your app uses version number two.

Npm follows semantic versioning, more details here.

Conclusion

As you have noticed there are a lot of tips available on Azure DevOps that can guide you through the whole process. As long as you are aware of the process of how npm packages are published to the npm registry all of this should make sense.

If you want an original guide from Microsoft you can find it here.

In my opinion this combination of npm packages and build pipeline with Azure DevOps can be extremely helpful.

It’s one of those things you set up once and you can enjoy the effectiveness of it from then on. In essence you have moved the main heavy lifting(building and publishing) to a cloud based server, so it’s doing it for you.

Moreover you can see the history and related description of changes in a more familiar format.

You can find code for ng library package here and consumer app here.

Continuous Deployment of Net Core Web App to Azure App Service

Reading time: 15 minutes

Description

In this post I will explain how to setup continuous deployment of Net Core Web App with Azure DevOps for the app that is hosted with Azure App Service.

What is required

  • Azure Subscription
  • Net Core Web App
  • Repository/Repo on Azure DevOps

Let’s start with initiating a repository on Azure DevOps

Prerequisite: you need a project on Azure DevOps. Go to your Azure DevOps main page.

Once you have clicked Create you should see similar screen.

We are interested in Repos section.

Look at the top section of the page where it says Initialize with README or gitignore. In my opinion it is a good practice to have both of these files with every repository you are creating.

With README you are deemed at some point to add some description of your app. This serves as an initial documentation. Whereas gitignore will prevent you from commiting unnecessary files to your repository. In a production environment this save your builds and time in case one or few files has slipped through.

At the end of the day you can always delete them or edit them according to your requirements.

Clone repository

Next thing is to Clone this newly created repository to your machine.

You can use any GUI for Git to do it or even Git Bash if you prefer command line type of application.

For this case I will use Sourcetree . It’s relatively easy to use. Gitextensions is similar in touch and feel. It also nicely connects with various comparison/diff and merge tools.

The main thing for us is to memorize the destination where we clone our reposity.

Create Net Core App

Let’s create Net Core web app with Visual Studio.

Since we already created a solution folder when we cloned the repository to our machine make sure in Location field we target the folder that contains the solution folder named NetCoreWebApp. Visual studio clever enough to place web app files into this folder.

Then we select ASP .Net Core 3.1 with Angular template.

The final folder structure should looke like so.

NetCoreWebApp inside has this structure.

Alternatively you can always create web application at one destination and then simply copy or move it over to the repository location.

In either way the result that we aiming for is for Git to track the changes to the repository.

As you can see Sourcetree on top of Git picked up the changes to your repository.

Steps that you need to do next are:

  • Good practice is to Build the solution but in this case it can be optional since it’s a pre-made template
  • Stage All
  • Write commit message
  • Commit
  • Push it to the remote server.

Once all of these steps are performed you would be able to see your changes on your repository at Azure DevOps.

Build pipeline

Select Pipelines from left menu and Use the classic editor.

Then select the repository you wish to setup the build pipeline.

Then you need to choose ASP.NET Core template.

The next screen should look like this.

The only thing that needs changing is on the Triggers tab.

This way we enable Continuous integration. Which means every time you commit changes to this branch it would trigger the build pipeline. As a result you would be able to see whether your changes integrate into the code of remote copy of the branch. In our case it’s master. Normally you would have build pipeline on develop branch before merging and building it on master branch.

Next step is to click on Save & queue. Then we need to add comment, check the branch and click Save and Run.

Next screen should look like this.

Next we need to create an App Service

For this we need to go to Azure Portal.

There we need to select Create Resource.

Then select Web and Web App.

Things to fill in on the next screen:

  • Resource Group -> Create new, choose whatever name you like since by it you will distonguish resource group that is related to particular project.
  • Name – which would be part of web app url
  • Way of publish – Code
  • Runtime stack that your app would use to run
  • Operating system – Windows
  • Region – whatever you like. Mind since we are using free subscription you need to make sure it is available in that region.
  • Windows Plan -> Create new
  • Free F1 tier which is part of free subscription from Azure for individual developers that want to research this platform

If you go to your newly created resource and there select App Service. From there you can check the app if it’s ok and running fine by clicking on it’s url.


Let’s go back to Azure DevOps and create Release pipeline.

…before getting into final part I think it’s a good time for a cup of beverage of your choice 😉

Create Release pipeline

Click on Releases from left pane menu. Then click on New pipeline in the area on the right.

Search for Azure app in the search box for templates. Click Apply.

From there you can edit stage details like name and owner. This could be develop stage with one of the testers being the owner. However in our case we will leave these as they are.

We are more interested in editing job/task section. So let’s click on section that is underneath Stage 1 in Stages on the left side.

In here we need to select our Subscription and App service name that we created at Azure portal.

Once we selected and Authorized our subscription we can then see our available App services.

Let’s go back to tab Pipeline and add an Artifact that was created by the build pipeline. Click on Add an artifact.

Select appropriate build pipeline Source. Check alias and edit it if needed. Click Add.

Last bit of setup. The Continuous deployment trigger.

Save and click Create release.

Select the Stage and build version that you want to release.

Once you are happy click Create.

Go to Releases on the left pane. In the right section click on Releases.

You would need to deploy the first release manually. On the next screen click Deploy and off it goes!

You can monitor the process in the next screen.

To check your newly released web app select Deploy Azure App Service.

For this purpose use App Service Application url.

Let’s check out the result! Our Hello, world app! Classic 🙂

Conclusion

Hope you enjoyed this post.

As you have noticed with Azure it is quite straight forward to deploy an app. From creating an App service in portal to creating build pipeline with Azure DevOps. When you have done it once or twice it makes sense. You can easily connect the dots to get the whole picture of modern deployment processes.

Stay tuned and have fun coding.