← Back to Articles         
How do you implement CI/CD for Angular + ASP.NET Core?

How do you implement CI/CD for Angular + ASP.NET Core?

Published on 02 Oct 2026     12 min read Angular
Deployment

How do you implement CI/CD for Angular + ASP.NET Core?

For an Angular + ASP.NET Core Web API application, CI/CD automates the process of:

Developer pushes code
        ↓
Build Angular
        ↓
Build ASP.NET Core
        ↓
Run tests
        ↓
Create deployment artifacts
        ↓
Deploy automatically
        ↓
Azure / IIS / other hosting

A common implementation uses GitHub Actions or Azure DevOps Pipelines.


1. What is CI/CD?

CI/CD stands for:

  • CI — Continuous Integration
  • CD — Continuous Delivery / Continuous Deployment

Continuous Integration

Whenever developers push code:

Git Push
   ↓
Restore dependencies
   ↓
Build
   ↓
Run tests
   ↓
Validate application

The goal is to detect integration/build/test problems early.

Continuous Deployment

After CI succeeds:

Build successful
      ↓
Create artifact
      ↓
Deploy
      ↓
SIT / UAT / Production

Depending on the organization's process, production deployment may be automatic or require approval.


2. Example architecture

Suppose your application uses:

Angular
   ↓
Azure Static Web Apps

ASP.NET Core Web API
   ↓
Azure App Service

Database
   ↓
Azure SQL

The repository could be:

Portfolio/
│
├── frontend/
│   ├── src/
│   ├── package.json
│   └── angular.json
│
├── backend/
│   ├── Portfolio.Api/
│   ├── Portfolio.Application/
│   ├── Portfolio.Infrastructure/
│   └── Portfolio.sln
│
└── .github/
    └── workflows/

CI/CD:

GitHub
  |
  ├── frontend changed
  │       ↓
  │   Build Angular
  │       ↓
  │   Deploy Static Web App
  │
  └── backend changed
          ↓
      Build .NET
          ↓
      Test
          ↓
      Publish
          ↓
      Deploy App Service

3. Angular CI process

Angular normally requires:

Node.js
npm
Angular dependencies

Typical pipeline commands:

npm ci
npm run build -- --configuration production

If tests are configured:

npm test

The build produces something similar to:

dist/
└── my-app/
    └── browser/
        ├── index.html
        ├── main-XXXX.js
        ├── styles-XXXX.css
        └── chunk-XXXX.js

That becomes the frontend deployment artifact.


4. Why use npm ci instead of npm install?

In CI pipelines, you'll commonly see:

npm ci

instead of:

npm install

npm ci uses the lock file to perform a clean, reproducible dependency installation.

Typically:

package.json
      +
package-lock.json
      ↓
npm ci
      ↓
Dependencies installed
      ↓
Angular build

This makes it well suited to automated build servers.


5. ASP.NET Core CI process

The backend typically uses:

dotnet restore

then:

dotnet build --configuration Release

then:

dotnet test --configuration Release

and finally:

dotnet publish --configuration Release --output ./publish

Flow:

ASP.NET Core source
        ↓
dotnet restore
        ↓
dotnet build
        ↓
dotnet test
        ↓
dotnet publish
        ↓
publish/

The publish directory becomes the deployable backend artifact.


6. Full GitHub Actions Example

Let's implement a simple pipeline using GitHub Actions.

Create:

.github/
└── workflows/
    └── ci-cd.yml

ci-cd.yml

name: Angular + ASP.NET Core CI/CD

on:
  push:
    branches:
      - main

  pull_request:
    branches:
      - main

jobs:

  build-angular:
    runs-on: ubuntu-latest

    defaults:
      run:
        working-directory: frontend

    steps:

      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup Node
        uses: actions/setup-node@v4
        with:
          node-version: '22'
          cache: 'npm'
          cache-dependency-path: frontend/package-lock.json

      - name: Install dependencies
        run: npm ci

      - name: Build Angular
        run: npm run build -- --configuration production

      - name: Upload Angular artifact
        uses: actions/upload-artifact@v4
        with:
          name: angular-app
          path: frontend/dist/


  build-api:
    runs-on: ubuntu-latest

    steps:

      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup .NET
        uses: actions/setup-dotnet@v4
        with:
          dotnet-version: '8.0.x'

      - name: Restore
        run: dotnet restore backend/Portfolio.sln

      - name: Build
        run: >
          dotnet build
          backend/Portfolio.sln
          --configuration Release
          --no-restore

      - name: Test
        run: >
          dotnet test
          backend/Portfolio.sln
          --configuration Release
          --no-build

      - name: Publish API
        run: >
          dotnet publish
          backend/Portfolio.Api/Portfolio.Api.csproj
          --configuration Release
          --output ./api-publish

      - name: Upload API artifact
        uses: actions/upload-artifact@v4
        with:
          name: api
          path: ./api-publish

This is the CI/build portion.


7. What happens when code is pushed?

Suppose you run:

git add .
git commit -m "Add products feature"
git push

GitHub sees:

on:
  push:
    branches:
      - main

and starts the workflow.

Developer
   ↓
git push
   ↓
GitHub main branch
   ↓
GitHub Actions
   |
   ├───────────────┐
   ↓               ↓
Angular CI      ASP.NET CI
   ↓               ↓
npm ci         dotnet restore
   ↓               ↓
Build          Build
   ↓               ↓
Test           Test
   ↓               ↓
Artifact       Publish
                   ↓
                Artifact

8. What is a pipeline artifact?

An artifact is the output produced by the build pipeline that can later be deployed.

For Angular:

angular-app artifact
        ↓
dist/

For ASP.NET Core:

api artifact
        ↓
publish/

This separation is useful because:

Build
  ↓
Artifact
  ↓
Deploy SIT
  ↓
Deploy UAT
  ↓
Deploy Production

Ideally, especially in enterprise pipelines, the same tested artifact progresses through environments rather than recompiling source code differently at every deployment stage.


9. Add ASP.NET Core deployment to Azure App Service

After building the API, you can add a deployment job.

Conceptually:

deploy-api:
  needs: build-api
  runs-on: ubuntu-latest

  steps:

    - name: Download API artifact
      uses: actions/download-artifact@v4
      with:
        name: api
        path: api-publish

    - name: Deploy API
      uses: azure/webapps-deploy@v3
      with:
        app-name: my-portfolio-api
        publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }}
        package: api-publish

Now:

Build API
    ↓
Upload artifact
    ↓
deploy-api
    ↓
Download artifact
    ↓
Azure App Service

10. Where should Azure credentials be stored?

Never put deployment credentials directly into the YAML.

Wrong:

password: MyAzurePassword123

Instead, use the CI/CD platform's protected secrets or, preferably where supported, workload/federated identity.

For a GitHub secret example:

GitHub Repository
      ↓
Settings
      ↓
Secrets and variables
      ↓
Actions

Then your workflow can reference:

${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }}

The principle is:

Pipeline file
     ↓
References secret
     ↓
GitHub protected secret / identity
     ↓
Azure authentication

11. Angular deployment

If Angular is separately hosted, you can deploy it to a static hosting service such as Azure Static Web Apps.

Architecture:

GitHub
   ↓
Angular Pipeline
   ↓
npm ci
   ↓
Production build
   ↓
dist/
   ↓
Azure Static Web Apps

The backend can independently follow:

GitHub
   ↓
.NET Pipeline
   ↓
dotnet publish
   ↓
Azure App Service

So you get:

             GitHub
                |
       ┌────────┴────────┐
       ↓                 ↓
    Angular          ASP.NET Core
       ↓                 ↓
 Static Web Apps      App Service
       |                 |
       └──── HTTPS ─────→|
                         ↓
                     Azure SQL

12. Environment configuration

Suppose you have:

Development
SIT
UAT
Production

API URLs might be:

SIT
https://sit-api.example.com/api

UAT
https://uat-api.example.com/api

Production
https://api.example.com/api

With Angular build-time configuration, you might have:

environment.sit.ts
environment.uat.ts
environment.production.ts

and build using:

ng build --configuration sit

or:

ng build --configuration uat

or:

ng build --configuration production

However, this produces different Angular artifacts.


13. Build once, deploy many

Enterprise CI/CD often prefers:

Build once
    ↓
Artifact
    ├──→ SIT
    ├──→ UAT
    └──→ Production

rather than:

Build for SIT
Build again for UAT
Build again for Production

Why?

Because rebuilding can technically create different artifacts.

A stronger deployment model is:

Source
   ↓
CI
   ↓
Build + Test
   ↓
Versioned Artifact
   ↓
SIT
   ↓
Testing
   ↓
UAT
   ↓
Approval
   ↓
Production

For Angular, this often means using runtime public configuration rather than compiling environment-specific URLs into every build.

For example:

{
  "apiUrl": "https://api.example.com/api"
}

The environment supplies the appropriate public configuration.


14. ASP.NET Core environment configuration

ASP.NET Core is particularly suited to environment-specific runtime configuration.

You might have:

appsettings.json
appsettings.SIT.json
appsettings.UAT.json
appsettings.Production.json

But production secrets should normally come from secure external configuration such as:

Azure App Service Configuration
Environment Variables
Azure Key Vault

For example:

ASP.NET Core
      ↓
IConfiguration
      ↓
App Service configuration
      ↓
Key Vault
      ↓
Connection String / Secrets

This allows the same published API artifact to run in multiple environments with different runtime settings.


15. SIT → UAT → Production pipeline

A real-world flow could be:

Developer
   ↓
Feature Branch
   ↓
Pull Request
   ↓
CI
   ├── Angular Build
   ├── Angular Tests
   ├── .NET Build
   └── .NET Tests
   ↓
Code Review
   ↓
Merge main
   ↓
Create artifacts
   ↓
Deploy SIT
   ↓
Automated / Integration Tests
   ↓
Deploy UAT
   ↓
UAT Testing
   ↓
Approval
   ↓
Deploy Production

This is much closer to the way CI/CD is discussed in senior/lead-level interviews.


16. Production approval

You don't necessarily want every commit to immediately deploy to production.

For example:

main
 ↓
Build
 ↓
SIT
 ↓
UAT
 ↓
Manual Approval
 ↓
Production

GitHub Environments or Azure DevOps environments can be used to implement deployment controls and approvals.


17. Database deployment

The database requires special attention.

Avoid treating a production database exactly like replaceable application files.

A common architecture is:

Application Artifact
       ↓
Deployment Pipeline
       |
       ├── Deploy Angular
       ├── Deploy API
       └── Apply controlled DB migration

For EF Core, migrations might be generated/deployed through a controlled process.

Production database migrations should consider:

  • backups/recovery
  • backward compatibility
  • deployment ordering
  • long-running migrations
  • locking/downtime
  • rollback strategy

For important production systems, blindly running database changes on every application startup is often undesirable.


18. CI vs CD responsibilities

CI CD
Checkout code Download/use artifact
Restore dependencies Deploy SIT
Compile Angular Deploy UAT
Compile .NET Deploy Production
Run unit tests Environment configuration
Static analysis Smoke tests
Create artifacts Approvals
Validate code Release/rollback

Think:

CI
"Can I safely produce a deployable artifact?"

CD
"How do I release that artifact?"

19. What happens if tests fail?

Suppose:

git push
   ↓
CI starts
   ↓
Build
   ↓
Tests
   ↓
FAIL

Then deployment should not continue.

Test failed
    ↓
Pipeline failed
    ↓
No deployment

This is one of the major benefits of CI/CD.


20. Rollback

Production pipelines should also consider rollback.

For example:

Version 1.5
   ↓
Deploy
   ↓
Problem detected
   ↓
Rollback
   ↓
Version 1.4

This is easier when you keep versioned immutable artifacts.

For example:

portfolio-ui-1.4
portfolio-ui-1.5

portfolio-api-1.4
portfolio-api-1.5

Then you're not rebuilding old source code during an emergency rollback.


21. Branch strategy example

A simple approach:

feature/product-search
          ↓
      Pull Request
          ↓
         main
          ↓
         CI
          ↓
      Build/Test
          ↓
       Artifact
          ↓
         SIT
          ↓
         UAT
          ↓
      Production

The exact branch model varies by organization. CI/CD does not require a particular branching strategy.


22. Separate frontend/backend pipelines

For a larger application, I would usually avoid one huge pipeline that redeploys everything for every small change.

For example:

angular-ci-cd.yml

api-ci-cd.yml

Angular changes:

frontend/**
      ↓
Angular pipeline

Backend changes:

backend/**
      ↓
API pipeline

This can reduce unnecessary builds and deployments.


23. Combined deployment alternative

If Angular is hosted from ASP.NET Core's wwwroot, the pipeline changes.

Angular source
      ↓
ng build
      ↓
dist/.../browser
      ↓
Copy into API/wwwroot
      ↓
dotnet publish
      ↓
Single artifact
      ↓
Azure App Service

For example:

wwwroot/
├── index.html
├── main-XXXX.js
├── styles-XXXX.css
└── chunk-XXXX.js

Then ASP.NET Core:

app.UseDefaultFiles();
app.UseStaticFiles();

app.MapControllers();

app.MapFallbackToFile("index.html");

Now there is only one deployable application artifact.


Separate vs Combined CI/CD

Separate Combined
Angular artifact One combined artifact
API artifact Angular inside wwwroot
Independent deployment Single deployment
Independent scaling Coupled scaling
More pipeline components Simpler release topology
Good for larger separated architectures Convenient for simpler applications

Recommended Pipeline Structure

For a separately deployed Angular + ASP.NET Core application:

                    GitHub
                       |
                       ↓
                Pull Request
                       |
                       ↓
                  CI Pipeline
                       |
            ┌──────────┴──────────┐
            ↓                     ↓
         Angular               .NET API
            ↓                     ↓
         npm ci              dotnet restore
            ↓                     ↓
          tests                  tests
            ↓                     ↓
          build                  build
            ↓                     ↓
       UI Artifact           API Artifact
            │                     │
            └──────────┬──────────┘
                       ↓
                  CD Pipeline
                       ↓
                      SIT
                       ↓
                     Tests
                       ↓
                      UAT
                       ↓
                    Approval
                       ↓
                  Production

Key Points

  1. CI builds, tests, and validates Angular and ASP.NET Core.
  2. CD deploys the resulting artifacts.
  3. Angular typically uses:
npm ci
npm run build -- --configuration production
  1. ASP.NET Core typically uses:
dotnet restore
dotnet build
dotnet test
dotnet publish
  1. Store deployable output as pipeline artifacts.
  2. Never hard-code deployment credentials in YAML.
  3. Use protected secrets or secure identity mechanisms.
  4. Keep environment-specific backend configuration outside the application artifact where practical.
  5. Build once, deploy many is a strong enterprise deployment model.
  6. SIT → UAT → Production can use the same versioned artifact.
  7. Production deployment can require approval.
  8. Database changes need a controlled migration strategy.
  9. Keep previous artifacts/releases available to support rollback.
  10. Angular and ASP.NET Core can have separate pipelines when independently deployed.

Interview Questions and Answers

1. What is CI/CD?

CI continuously integrates changes by automatically building and testing them. CD automates delivering or deploying the validated artifact to environments such as SIT, UAT, and Production.

2. How do you implement CI/CD for Angular + ASP.NET Core?

I configure a pipeline using GitHub Actions or Azure DevOps. The pipeline restores dependencies, builds and tests Angular and ASP.NET Core, publishes deployable artifacts, and then deploys those artifacts through the required environments.

3. What commands do you use for Angular CI?

Typically:

npm ci
npm run build -- --configuration production

along with the project's configured test command.

4. What commands do you use for ASP.NET Core?

Typically:

dotnet restore
dotnet build -c Release
dotnet test -c Release
dotnet publish -c Release

5. Why use npm ci in a pipeline?

It performs a clean dependency installation based on the lock file, making builds more reproducible for CI environments.

6. What is a pipeline artifact?

A pipeline artifact is the deployable output produced by CI, such as Angular's built static files or ASP.NET Core's dotnet publish output.

7. What does "build once, deploy many" mean?

The application is built and tested once, producing a versioned artifact. The same artifact is promoted through SIT, UAT, and Production while environment-specific configuration is supplied at deployment/runtime.

8. Where should production secrets be stored?

Not in Angular code, source control, or plain YAML. Backend secrets should be supplied through secure mechanisms such as Azure App Service configuration, protected pipeline secrets, environment variables, or Azure Key Vault.

9. What happens when unit tests fail?

The pipeline should fail and prevent the application from progressing to deployment.

10. How do you deploy Angular and ASP.NET Core separately?

A typical Azure setup is:

Angular
   ↓
Azure Static Web Apps

ASP.NET Core
   ↓
Azure App Service

Each can have an independent build/deployment pipeline.

11. How do you handle Production deployment?

Promote the tested artifact to the Production environment, optionally requiring manual approval, and run post-deployment validation/smoke tests.

12. How do you handle rollback?

Keep versioned deployment artifacts/releases so the previous known-good version can be redeployed without rebuilding source code.

Short interview answer

For Angular + ASP.NET Core CI/CD, I use a pipeline such as GitHub Actions or Azure DevOps. CI checks out the code, installs Angular dependencies with npm ci, builds/tests Angular, restores/builds/tests the .NET solution, and creates versioned deployment artifacts. CD then promotes those artifacts through environments such as SIT, UAT, and Production, using environment-specific runtime configuration, protected secrets, approvals, smoke tests, and a rollback strategy.

← Back to Articles