MakotoE
MakotoE

Reputation: 2099

How do I create a Release pipeline for a Node.js web app in Azure DevOps?

I want to enable continuous deployment on Azure DevOps for a Node.js app, by creating a Release pipeline. How do I make this happen?

Upvotes: 4

Views: 5126

Answers (2)

MakotoE
MakotoE

Reputation: 2099

See my newer answer for a better solution.

I spent several hours trying to figure out how to get CI/CD working for a Node.js app, on Azure DevOps, because there is very little documentation that I could reference. I finally got it working, so I hope these steps will help you. Note: the UI may change over time. This is written in October of 2018.

Prerequisites:

  • An Azure Web App service to deploy to
  • An Azure subscription
  • A Node.js project on Azure DevOps with a working build pipeline
  • You have been able to deploy your app through other means, such as ftp or Git

There are two ways to add a deploy step to your pipeline, and those are: through the YAML script in the build pipeline, or with a release pipeline. These steps are for creating a release pipeline. I choose this so that I can manually choose which commit to deploy, but it can also be triggered automatically.

  1. Generate an artifact of your repo directory in your build pipeline. If your build pipeline is done through a YAML script, add this to the YAML file (more info):
- task: PublishBuildArtifacts@1
  inputs:
    PathtoPublish: '$(System.DefaultWorkingDirectory)'
  1. Run the build pipeline and wait for it to finish. Confirm that an artifact was generated.
  2. Go to the Releases tab and create a new release pipeline.
  3. In the templates menu, find "Deploy a Node.js app to Azure App Service" and click Apply.
  4. Open Stage 1 by clicking the link that says "1 job, 1 task".
  5. In the "Azure subscription" field, click the + New button. The "Add an Azure Resource Manager service connection" modal pops up.
  6. This part was incredibly frusturating, but this Medium article helped out a lot. At first it didn't work, but that was because I didn't read everything. Make sure to read every sentence, and it should work. When the connection shows "verified", click OK.
    • There is the option to "use the automated version of the service connection dialog", but that interface was not working for me.
    • What makes this step hard is the fact that DevOps and Portal use different terms for each variable. Azure services, please come together and agree on a single naming system.
  7. Select the app type.
  8. Find your App service name.
  9. Go to the Deploy Azure App Service task. Most settings don't need to be changed, but you will need to specify the build artifact to use. This is done under "Package or folder". Click on "..." and find your build artifact. If there are no artifacts showing, your build pipeline isn't working.
  10. Save the release pipeline.
  11. Open your latest CI build and click the Release button.
  12. All default settings in the "Create a new release" modal should be fine. Hit "Create". Now you can open your Release pipeline and watch the progress. If it fails due to a connection problem, edit your Release pipeline and confirm that your Azure Resource Manager connection is verified and the correct app type and app service is selected.
  13. Go to your site and confirm that your app has successfully deployed.

Upvotes: 3

MakotoE
MakotoE

Reputation: 2099

When I wrote the previous answer I made one year ago, Azure DevOps didn't have the web app deployment task for build pipelines, so it had to be done using a release pipeline. Deploying through a build pipeline is much better and I highly recommend it because it allows you to commit all your CI/CD jobs to the repo. (Build pipelines are labeled "Pipelines" in the sidebar and release pipelines are in "Releases".)

Thus, this answer is for deploying your web app through your build pipeline. See my older answer if you would like to use a release pipeline.

  1. Create a service connection.
  2. Assuming you have a service connection for your web app and you have a Node.js project in DevOps, create a package.json and main.js for your project. Run this locally to make sure it works on your computer.
{
  "name": "test-project",
  "version": "0.0.0",
  "scripts": {
    "start": "node main.js",
    "test": ""
  },
  "dependencies": {
    "express": "^4.17.1"
  }
}
const express = require('express');
const app = express();
const port = process.env.PORT || 3000; // You can see your app's env variables in Kudu: https://<your app>.scm.azurewebsites.net/

app.get('/', (req, res) => res.send('Hello World!'));

app.listen(port, () => console.log(`Example app listening on port ${port}!`));
  1. Now you need a YAML file for the pipeline. Name this file azure-pipelines.yml. The YAML schema documentation is here.
trigger:
  - '*' # Run pipeline when a commit is pushed to any branch
  - 'refs/tags/*' # Run pipeline when a tag is pushed

jobs:
- job: test
  pool:
    vmImage: ubuntu-latest
  steps:
  - script: npm install
    displayName: npm install
  - script: npm run test
    displayName: npm run test

- job: deploy
  condition: startsWith(variables['Build.SourceBranch'], 'refs/tags/') # Run deploy job only if triggered by tag
  pool:
    vmImage: ubuntu-latest
  steps:
  - script: npm install
    displayName: npm install
#  - script: npm run build # If you are using TypeScript
#    displayName: npm run build
  - task: AzureWebApp@1 # https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/deploy/azure-rm-web-app?view=azure-devops
    inputs:
      azureSubscription: <service connection name> # Replace this with the service connection name
      appName: test-project # Replace this with the web app name
      package: $(Build.SourcesDirectory)
      customWebConfig: -Handler iisnode -NodeStartFile main.js -appType node # https://learn.microsoft.com/en-us/azure/devops/pipelines/targets/webapp?view=azure-devops&tabs=yaml
  1. Replace the project-specific values in the AzureWebApp@1 task and push this file to your repo.
  2. Go to the Pipelines page and click New pipeline. The pipelines options (It's really simple):
  • "Where is your code?" Azure Repos Git
  • "Select a repository" Select your repo
  • "Configure your pipeline" Existing Azure Pipelines YAML file
  • "Select an existing YAML file" Path to azure-pipelines.yml
  • Click Run
  • On the first run, it may say that the service connection is unauthorized. Clicking "Authorize resources" then running the build again manually with the Queue button will resolve this.
  1. To run the build job, create a tag and push it. Go back to the builds list, you will see your deployment job running.
  • To do this through the web interface: Go to the Tags page under Repos and click New Tag. For some reason it requires a tag description, so I just copy the tag name.
  1. When the build finishes successfully, go to your site, and you should see the hello world message.
  • If your site displays an application error message, you can check the error log by going to your web app in the Azure portal, then Log stream page in the sidebar. Note that the app container is started only after someone visits the web page. Therefore, to test app initialization, you must first visit your web page.

Upvotes: 3

Related Questions