Streamlining Node.js Development with Azure DevOps YAML CI/CD Pipelines

Streamlining Node.js Development with Azure DevOps YAML CI/CD Pipelines

Introduction: In the fast-paced world of Node.js development, automating workflows is essential for efficiency and reliability. Azure DevOps provides a robust platform for Continuous Integration and Continuous Deployment (CI/CD). In this blog, we'll dive into the power of Azure DevOps YAML pipelines for Node.js projects.

Why Azure DevOps for Node.js? Azure DevOps offers an end-to-end solution for building, testing, and deploying Node.js applications. Its seamless integration with Git repositories, comprehensive build capabilities, and flexible release management make it an ideal choice for Node.js developers.

Setting Up Your Azure DevOps Project:

  1. Create a New Project:

    • Log in to Azure DevOps and create a new project for your Node.js application.
  2. Initialize a Git Repository:

    • Initialize a Git repository to manage your Node.js source code.
  3. Azure DevOps YAML Pipeline:

    • Embrace the power of YAML to define your CI/CD pipeline as code.

Defining the YAML Pipeline:

# Node.js
# Build a general Node.js project with npm.
# Add steps that analyze code, save build artifacts, deploy, and more:
# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript

trigger:
#- dev
- none
# Create Build Using Self Hosted Agent on DevOps Server  -- Start--
pool: 
   name: Default
# default is my agnet pool name
stages:
# Continous Integration Stage
- stage: CI
  displayName: CI
  jobs:
  - job: Build     
    steps:
    - task: NodeTool@0
      inputs:
        versionSpec: '18.13.0'
      displayName: 'Use Node 18.13.0'  
    - task: CmdLine@2
      inputs:
        script: 'npm i'
      displayName: 'Install Node Modules'
    - task: CmdLine@2
      inputs:
        script: 'if exist $(Build.SourcesDirectory)\.next\ rmdir /s /q $(Build.SourcesDirectory)\.next'
      displayName: 'Delete .next if Exists'
    - task: CmdLine@2
      inputs:
        script: 'npm run build'
      displayName: 'Build Source Code'

    - task: CopyFiles@2
      inputs:
        SourceFolder: '$(Build.SourcesDirectory)'
        Contents: |
          .next/**
          public/**
          package.json
        TargetFolder: '$(Build.SourcesDirectory)/temp'
        OverWrite: true
      displayName: 'Copy Files to temp directory'
    - task: ArchiveFiles@2
      inputs:
        rootFolderOrFile: '$(Build.SourcesDirectory)/temp/*'
        includeRootFolder: true
        archiveType: 'zip'
        archiveFile: '$(Build.ArtifactStagingDirectory)/$(Build.DefinitionName)-$(Build.BuildId).zip'
        replaceExistingArchive: true
      displayName: 'Zip Files'
    - task: PublishBuildArtifacts@1
      inputs:
        PathtoPublish: '$(Build.ArtifactStagingDirectory)'
        ArtifactName: '$(Build.DefinitionName)'
        publishLocation: 'Container'
      displayName: 'Publish Artifacts'
    - task: CmdLine@2
      inputs:
        script: 'if exist $(Build.SourcesDirectory)\temp\ rmdir /s /q $(Build.SourcesDirectory)\temp'
      displayName: 'Delete Temp Directory!'

# Create Build Using Self Hosted Agent on DevOps Server  -- End--
# Deploy on Dev-Server Using Self Hosted Agent on eComeServer  -- Start--
# "Dev-server is the server on which this will deploy and you can add a server in environment"
- stage: CD_Dev
  displayName: 'Dev'
  jobs:
    - deployment: Deployment
      environment:
        name: Dev-server
        resourceType: VirtualMachine
      strategy:
       runOnce:
         deploy:
           steps:
              - task: PowerShell@2
                inputs:
                  targetType: 'inline'
                  script: |
                    $applicationPoolName = 'myapp-pool'
                    if((Get-WebAppPoolState -Name $applicationPoolName).Value -ne 'Stopped'){
                        Write-Output ('Stopping Application Pool: {0}' -f $applicationPoolName)
                        Stop-WebAppPool -Name $applicationPoolName
                    }
                displayName: 'Stop IIS App Pool'
              - task: CmdLine@2
                inputs:
                  script: 'if exist $(pathToApp)\.next\ rmdir /s /q $(pathToApp)\.next'
                displayName: 'Deleting .next folder'

              - task: ExtractFiles@1
                inputs:
                  archiveFilePatterns: '$(Agent.BuildDirectory)/$(Build.DefinitionName)/$(Build.DefinitionName)-$(Build.BuildId).zip'
                  destinationFolder: '$(pathToApp)'
                  cleanDestinationFolder: false
                  overwriteExistingFiles: true
                displayName: 'Extract Files to App Path'
              - task: PowerShell@2
                inputs:
                  targetType: 'inline'
                  script: |
                    $applicationPoolName = 'myapp-pool'
                    if((Get-WebAppPoolState -Name $applicationPoolName).Value -ne 'Started'){
                        Write-Output ('Starting Application Pool: {0}' -f $applicationPoolName)
                        Start-WebAppPool -Name $applicationPoolName
                    }
                displayName: 'Start IIS App pool'
# Deploy on Dev-Server Using Self Hosted Agent on Dev-server  -- End-

Understanding the YAML Pipeline:

  • Trigger: The pipeline is triggered on changes to the main branch.

  • Jobs: Three jobs - Build, Test, and Deploy - defined for different stages of the pipeline.

  • Build Job: Installs Node.js, installs dependencies, and builds the Node.js application.

  • Test Job: Runs tests after the build job is successful.

  • Deploy Job: Deploys the application by copying build artifacts.

Benefits of YAML Pipelines:

  1. Version Control: YAML pipelines are stored in your version control system, providing transparency and traceability.

  2. Code Review: Changes to the pipeline can go through the same code review process as application code.

  3. Reusability: YAML pipelines can be reused across projects, promoting consistency.

Conclusion: Azure DevOps YAML pipelines empower Node.js developers to automate their CI/CD workflows efficiently. By defining pipelines as code, you gain transparency, version control, and the ability to manage your CI/CD process alongside your application code.

Integrate Azure DevOps YAML pipelines into your Node.js projects to enhance collaboration, streamline deployments, and ensure the reliability of your applications throughout their lifecycle. Happy coding!