AZURE DEVOPS CI/CD FOR ANGULAR 20.3

 

AZURE DEVOPS CI/CD FOR ANGULAR 20.3

 ðŸ¤” What is CI/CD for Angular?

Continuous Integration (CI) is a development practice where developers frequently merge code changes into a central repository, triggering automated builds and tests to catch integration issues early. For an Angular project, this means automatically running ng build and ng test whenever code is pushed.

Continuous Delivery/Deployment (CD) extends CI by automating the deployment of your built Angular application to various environments, including production. This ensures your application is always in a deployable state.

🤔 Why Implement CI/CD for Angular?

  • Early Issue Detection: Catches integration problems and bugs early, reducing the cost and effort of fixing them

  • Faster Value Delivery: Enables teams to release new features and bug fixes more frequently

  • Consistent Deployments: Ensures a uniform deployment process across all environments

  • Reduced Manual Errors: Automates the entire process from code commit to production

  • Rapid Feedback: Frequent releases facilitate quicker user feedback and prompt improvements

🛠️ How It Works

The CI/CD pipeline consists of several stages:

  1. Source Code Management – Code is pushed to a Git repository (Azure Repos)

  2. Build – Angular application is compiled using Angular CLI

  3. Test – Unit and end-to-end tests are executed

  4. Deploy – Built artifacts are deployed to Azure hosting services


Part 2: Prerequisites

Before setting up the pipeline, ensure you have:

RequirementDetails
Angular ProjectAngular CLI version 20.3.x confirmed (check package.json)
Azure AccountActive Azure subscription
Azure DevOps OrganizationCreate one at dev.azure.com
Node.jsVersion 20.19.x or higher (required by Angular 20)
GitInstalled and configured locally
Azure Static Web AppsOr Azure App Service resource created

Part 3: Step-by-Step Pipeline Setup

Step 1: Configure Your Angular Project

What: Ensure your Angular project is production-ready.

Why: The production build optimizes your application for performance and security through AOT compilation, minification, and environment configuration.

How:

bash
# Verify Angular CLI version
ng version

# Build production version locally to test
ng build --configuration production

Note: For Angular 20.3, the production build outputs to dist/ directory. If using the default builder, artifacts are at dist/<project-name>/browser.

Step 2: Create Azure DevOps Repository

What: Set up a Git repository in Azure DevOps to host your code.

Why: Azure Repos integrates natively with Azure Pipelines, simplifying the CI/CD setup.

How:

  1. Navigate to Azure DevOps → Your Project → Repos

  2. Create a new repository

  3. Push your Angular project to the remote repository:

bash
git init
git remote add origin <your-azure-repo-url>
git add .
git commit -m "Initial commit"
git push -u origin main

Step 3: Create the Pipeline YAML File

What: Define the CI/CD pipeline configuration in azure-pipelines.yml.

Why: YAML pipelines are version-controlled, repeatable, and provide full automation of the CI/CD process.

How: Create a file named azure-pipelines.yml in your project root.


Part 4: Complete Pipeline YAML Configuration

Here is a comprehensive pipeline for Angular 20.3 without Docker:

yaml
# azure-pipelines.yml
trigger:
  - main
  - develop

pool:
  vmImage: 'ubuntu-latest'

variables:
  npm_cache: $(Pipeline.Workspace)/.npmcache
  project_name: 'angular-frontend'  # Change to your project name

stages:
  - stage: Build
    displayName: 'Build and Test Stage'
    jobs:
      - job: Build
        steps:
          # 1. Install Node.js
          - task: NodeTool@0
            inputs:
              versionSpec: '20.x'
            displayName: 'Install Node.js'

          # 2. Cache npm dependencies for faster builds
          - task: Cache@2
            inputs:
              key: 'npm | "$(Agent.OS)" | package-lock.json'
              restoreKeys: 'npm | "$(Agent.OS)"'
              path: $(npm_cache)
            displayName: 'Cache npm dependencies'

          # 3. Install dependencies
          - script: |
              npm ci --cache $(npm_cache)
              npm install -g @angular/cli@20.3.x
            displayName: 'Install dependencies'

          # 4. Run unit tests
          - script: |
              ng test --watch=false --browsers=ChromeHeadless
            displayName: 'Run unit tests'

          # 5. Build production bundle
          - script: |
              ng build --configuration production
            displayName: 'Build Angular application'

          # 6. Publish build artifacts for deployment
          - publish: $(System.DefaultWorkingDirectory)/dist/$(project_name)/browser
            artifact: release
            displayName: 'Publish build artifacts'

  - stage: Deploy_Development
    displayName: 'Deploy to Development'
    dependsOn: Build
    condition: succeeded()
    jobs:
      - deployment: DeploymentDev
        environment: 'dev'
        strategy:
          runOnce:
            deploy:
              steps:
                # 1. Download built artifacts
                - download: current
                  artifact: release
                  displayName: 'Download artifacts'

                # 2. Deploy to Azure Static Web App
                - task: AzureStaticWebApp@0
                  inputs:
                    azure_static_web_apps_api_token: $(deployment_token_dev)
                    app_location: '/'
                    output_location: '$(Pipeline.Workspace)/release'
                    skip_api_build: true
                    verbose: true
                  displayName: 'Deploy to Azure Static Web App (Dev)'

  - stage: Deploy_Production
    displayName: 'Deploy to Production'
    dependsOn: Deploy_Development
    condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
    jobs:
      - deployment: DeploymentProd
        environment: 'production'
        strategy:
          runOnce:
            deploy:
              steps:
                - download: current
                  artifact: release
                  displayName: 'Download artifacts'

                - task: AzureStaticWebApp@0
                  inputs:
                    azure_static_web_apps_api_token: $(deployment_token_prod)
                    app_location: '/'
                    output_location: '$(Pipeline.Workspace)/release'
                    skip_api_build: true
                    verbose: true
                  displayName: 'Deploy to Azure Static Web App (Prod)'

Part 5: Deployment Options Without Docker

Option A: Azure Static Web Apps (Recommended)

What: A serverless hosting service that automatically builds and deploys web apps from a code repository.

Why: Azure Static Web Apps offers built-in CI/CD integration, global CDN distribution, and custom domain support.

How:

  1. Create Azure Static Web App in Azure Portal

  2. In the pipeline, use the AzureStaticWebApp@0 task

  3. Provide the deployment token from the Azure Static Web App overview page

Key Configuration:

yaml
- task: AzureStaticWebApp@0
  inputs:
    azure_static_web_apps_api_token: $(deployment_token)
    app_location: '/'
    output_location: 'dist/angular-frontend/browser'
    skip_api_build: true

Option B: Azure App Service (Web App)

What: A managed service for hosting web applications, supporting multiple languages and frameworks.

Why: Offers more flexibility with configurations, custom containers, and integration with other Azure services.

How:

yaml
- task: AzureRmWebAppDeployment@4
  inputs:
    ConnectionType: 'AzureRM'
    azureSubscription: '$(azureSubscription)'
    appType: 'webAppLinux'
    WebAppName: '$(webAppName)'
    packageForLinux: '$(Pipeline.Workspace)/release/**/*'

Part 6: Testing Strategy

Unit Tests

What: Tests that verify individual components function correctly.

Why: Essential for maintaining code quality and catching regressions.

How: Angular projects use Karma and Jasmine by default.

yaml
- script: |
    ng test --watch=false --browsers=ChromeHeadless
  displayName: 'Run unit tests'

End-to-End Tests

What: Tests that verify the complete application flow from a user perspective.

Why: Catches integration issues that unit tests may miss.

How: Angular CLI supports Cypress, Protractor, or Playwright.

yaml
- script: |
    ng e2e
  displayName: 'Run E2E tests'

Part 7: Environment Configuration

What: Manage environment-specific variables.

Why: Different environments (development, staging, production) require different configurations like API endpoints.

How:

  1. Create environment files in src/environments/:

    • environment.ts (development)

    • environment.prod.ts (production)

    • environment.staging.ts (optional)

  2. In the pipeline, choose the appropriate configuration:

yaml
- script: |
    ng build --configuration production
  displayName: 'Build Angular application'

Part 8: Security Best Practices

What: Protect sensitive information like API tokens and deployment credentials.

Why: Never hardcode secrets in YAML files.

How:

  1. In Azure DevOps, go to Pipelines → Library → Variable Groups

  2. Create variables like deployment_token_dev, deployment_token_prod

  3. Reference them as $(variable_name) in the pipeline

Example:

yaml
variables:
- group: 'angular-deployment-secrets'

Part 9: Trigger Mechanisms

What: Define when the pipeline automatically runs.

Why: Automating triggers ensures consistent and timely builds.

How:

yaml
# Run on push to these branches
trigger:
  - main
  - develop

# Run on pull request to main
pr:
  - main

Part 10: Monitoring and Feedback

What: Track application performance and pipeline health.

Why: Provides visibility into deployment success/failure and application performance in production.

How:

  1. Azure Pipeline Notifications: Configure email or Slack notifications for build failures

  2. Azure Application Insights: Add monitoring to your Angular app for real-user metrics

  3. Pipeline Logs: Access detailed logs from the Azure DevOps portal


Summary Checklist

TaskStatus
✅ Angular 20.3 project confirmed
✅ Azure DevOps organization created
✅ Azure Static Web App / App Service created
✅ Code pushed to Azure Repos
azure-pipelines.yml created
✅ Test commands verified
✅ Environment variables configured
✅ Deployment tokens secured
✅ Pipeline triggered and tested

Troubleshooting Common Issues

IssueSolution
Build fails with Node versionEnsure Node 20.19.x+ is used
Deployment detects no platformSet app_location and output_location correctly in Static Web App task
Cache not workingVerify package-lock.json exists and cache path is correct
Tests failing in CIUse ChromeHeadless browser for headless test execution

Comments

Popular posts from this blog

Interview Tips: Dot NET Framework vs Net CORE

OOP Concept in real-time scenario: Mobile Device Management Software

PRACTICE ASSIGNMENTS