Search code examples
c#asp.net-coreazure-devopsazure-functionsazure-pipelines

How to properly use Azure Function Build and Deploy in Azure DevOps with multiple projects


I am working with Azure and a C# based application. I have 2 App Services, a web app, and a function app. My web app use dotnet 9.0, and my function app uses dotnet 9.0 too. I selected a timer-trigger with an isolated worker, and have used the Consumption based plan. Additionally, my Web App has 4 deployment slots: development, uat, staging, production. My Function app has 2 deployment slots: development, production.

I split my Web App into 2 projects, a Web App and a Shared Library. My migrations, dbcontext, models, and the function to be referenced and run in the Azure Function, are all in the Shared Library. The 3rd project is my Azure function. All of these are stored in a single repo in Azure DevOps. When I run the below pipeline script, everything works perfectly and passes. However, it appears that the pipeline does not correctly build or deploy the Azure function.

When I load the Kudu console, I see that a zipped folder is uploaded to the ~/wwwroot dir. However, the name of this zipped folder is the webapp project zipped, and not the azure function project zipped. How can I fix this? My azure-pipelines.yml is below.

Edit 2: Updated .yml to the actual version being used.


trigger:
  branches:
    include:
      - development-cs
      - main
      - uat

variables:
  buildConfiguration: 'Release'
  azureSubscription: 'RandomAzureConnection'        # Name of your Azure Service Connection
  appName: 'RandomWebApp'                             # Name of your Azure Web App
  functionAppName: 'RandomFunctionApp'                # Name of your Azure Function App
  resourceGroupName: 'Random_ResourceGroup'           # Name of your Resource Group
  sqlServerName: 'randomsqlserver.database.windows.net'  # Azure SQL Server FQDN
  runtimeStack: 'DOTNETCORE|9.0'
  ResourceGroupLocation: 'East US'

  # Database names
  devSqlDatabaseName: 'randomdevdb'
  uatSqlDatabaseName: 'randomuatdb'
  mainSqlDatabaseName: 'RandomMainDB'

  # Deployment Slots for Web App
  devSlotName: 'devSlot'
  uatSlotName: 'uatSlot'
  stagingSlotName: 'stagingSlot'
  productionSlotName: 'productionSlot'

stages:
- stage: BuildAndDeploy
  displayName: 'Build and Deploy Stage'
  jobs:

  - job: Build
    displayName: 'Build Job'
    pool:
      vmImage: 'ubuntu-latest'
    steps:
      # Checkout code and set up environment
      - checkout: self
        fetchDepth: 0
        persistCredentials: true
        clean: true

      - script: |
          echo "Build Sources Directory: $(Build.SourcesDirectory)"
        displayName: 'Print Build Sources Directory'

      - script: |
          echo '{ "sdk": { "version": "9.0.100" } }' > global.json
        displayName: 'Create global.json'

      - task: UseDotNet@2
        displayName: 'Install .NET 9.0.100 SDK in Build Job'
        inputs:
          packageType: 'sdk'
          version: '9.0.100'

      - script: |
          echo "Installing necessary tools..."
          sudo apt-get update
          sudo apt-get install -y azure-cli powershell
        displayName: 'Install Azure CLI and PowerShell'

      - script: |
          echo "Installing dotnet-ef tool..."
          dotnet tool install --global dotnet-ef --version 9.0.0-preview.6.24327.4
          echo '##vso[task.prependpath]$HOME/.dotnet/tools'
        displayName: 'Install dotnet-ef Tool in Build Job'

      # Restore and Build all projects
      - task: DotNetCoreCLI@2
        displayName: 'Restore NuGet Packages'
        inputs:
          command: 'restore'
          projects: '**/*.csproj'

      - task: DotNetCoreCLI@2
        displayName: 'Build Projects'
        inputs:
          command: 'build'
          projects: '**/*.csproj'
          arguments: '--configuration $(buildConfiguration) --no-restore'

      # Publish the Web App package
      - task: DotNetCoreCLI@2
        displayName: 'Publish Web App'
        inputs:
          command: 'publish'
          projects: 'RandomApp/WebApp.csproj'
          arguments: '--configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory)/web --no-restore'

      # Publish the Function App package into its own folder
      - task: DotNetCoreCLI@2
        displayName: 'Publish Function App'
        inputs:
          command: 'publish'
          projects: 'RandomApp/RandomFunctions.csproj'
          arguments: '--configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory)/functions --no-restore'

      # Archive the Function App folder into a zip file
      - task: ArchiveFiles@2
        displayName: 'Archive Function App Package'
        inputs:
          rootFolderOrFile: '$(Build.ArtifactStagingDirectory)/functions'
          includeRootFolder: false
          archiveFile: '$(Build.ArtifactStagingDirectory)/functionapp.zip'
          replaceExistingArchive: true

      # (Optional) Cleanup the unzipped Function App folder so only the zip remains
      - script: |
          echo "Cleaning up unzipped Function App folder..."
          rm -rf "$(Build.ArtifactStagingDirectory)/functions"
        displayName: 'Cleanup Function App Folder'

      # (Optional) Generate EF Core migration SQL script
      - script: |
          echo "Generating EF Core migration script..."
          dotnet ef migrations script --idempotent \
              --project "RandomApp/RandomShared.csproj" \
              --startup-project "RandomApp/WebApp.csproj" \
              --output $(Build.ArtifactStagingDirectory)/migration.sql
        displayName: 'Generate EF Core Migration Script'

      # List files for debugging purposes
      - script: |
          echo "Listing contents of the Artifact Staging Directory:"
          ls -la "$(Build.ArtifactStagingDirectory)"
        displayName: 'List Artifact Files'

      # Publish build artifacts (both the web folder and the Function App zip)
      - task: PublishBuildArtifacts@1
        displayName: 'Publish Build Artifacts'
        inputs:
          # Change the path to publish both the web folder and the functionapp.zip file
          pathToPublish: '$(Build.ArtifactStagingDirectory)'
          artifactName: 'drop'
          publishLocation: 'Container'

  - job: Deploy
    displayName: 'Deploy Job'
    dependsOn: Build
    pool:
      vmImage: 'ubuntu-latest'
    steps:
      - checkout: self
        fetchDepth: 0
        persistCredentials: true
        clean: true

      - download: current
        artifact: drop

      # Install required tools in the Deploy Job
      - task: UseDotNet@2
        displayName: 'Install .NET 9.0.100 SDK in Deploy Job'
        inputs:
          packageType: 'sdk'
          version: '9.0.100'

      - script: |
          echo "Installing Azure CLI..."
          sudo apt-get update
          sudo apt-get install -y azure-cli
        displayName: 'Install Azure CLI'

      - script: |
          echo "Installing dotnet-ef tool..."
          dotnet tool install --global dotnet-ef --version 9.0.0-preview.6.24327.4
          echo '##vso[task.prependpath]$HOME/.dotnet/tools'
        displayName: 'Install dotnet-ef Tool in Deploy Job'

      - script: |
          echo "Verifying dotnet-ef installation..."
          dotnet ef --version
        displayName: 'Verify dotnet-ef Installation in Deploy Job'

      - script: |
          echo "Testing connectivity to SQL Server..."
          sudo apt-get install -y netcat
          nc -zv $(sqlServerName) 1433
        displayName: 'Test SQL Server Connectivity'

      # Set slot and database variables based on branch
      - script: |
          branchName=$(Build.SourceBranchName)
          if [ "$branchName" == "main" ]; then
              echo "##vso[task.setvariable variable=slotName]$(stagingSlotName)"
              echo "##vso[task.setvariable variable=sqlDatabaseName]$(mainSqlDatabaseName)"
              echo "##vso[task.setvariable variable=functionSlot]''"
          elif [ "$branchName" == "uat" ]; then
              echo "##vso[task.setvariable variable=slotName]$(uatSlotName)"
              echo "##vso[task.setvariable variable=sqlDatabaseName]$(uatSqlDatabaseName)"
              echo "##vso[task.setvariable variable=functionSlot]none"
          elif [ "$branchName" == "development-cs" ]; then
              echo "##vso[task.setvariable variable=slotName]$(devSlotName)"
              echo "##vso[task.setvariable variable=sqlDatabaseName]$(devSqlDatabaseName)"
              echo "##vso[task.setvariable variable=functionSlot]development"
          else
              echo "##vso[task.setvariable variable=slotName]$(devSlotName)"
              echo "##vso[task.setvariable variable=sqlDatabaseName]$(devSqlDatabaseName)"
              echo "##vso[task.setvariable variable=functionSlot]development"
          fi
          echo "Branch: $branchName"
          echo "Web App Slot Name: $(slotName)"
          echo "SQL Server Name: $(sqlServerName)"
          echo "SQL Database Name: $(sqlDatabaseName)"
          echo "Function App Slot: $(functionSlot)"
        displayName: 'Set Web App Slot, Function App Slot, and DB Based on Branch'

      # Apply EF Core migrations for main and uat branches only
      - script: |
          echo "Applying EF Core Migrations using Service Principal..."
          dotnet ef database update \
              --project "RandomApp/RandomShared.csproj" \
              --startup-project "RandomApp/WebApp.csproj" \
              --connection "Server=tcp:$(sqlServerName),1433;Database=$(sqlDatabaseName);Authentication=Active Directory Service Principal;User ID=$(sqlClientId);Password=$(sqlClientSecret);Encrypt=True;TrustServerCertificate=False;MultipleActiveResultSets=True;Connection Timeout=30;"
        displayName: 'Apply EF Core Migrations'
        condition: or(eq(variables['Build.SourceBranchName'], 'main'), eq(variables['Build.SourceBranchName'], 'uat'))

      # Deploy the Web App package to Azure App Service
      - task: AzureWebApp@1
        displayName: 'Deploy to Azure Web App'
        inputs:
          azureSubscription: '$(azureSubscription)'
          appName: '$(appName)'
          # Adjust the package path if your web app requires a zip package or folder.
          package: '$(Pipeline.Workspace)/drop/web'
          appType: 'webApp'
          slotName: '$(slotName)'

      # Update Web App settings using Azure CLI
      - task: AzureCLI@2
        displayName: 'Update Web App Settings'
        inputs:
          azureSubscription: '$(azureSubscription)'
          scriptType: 'bash'
          scriptLocation: 'inlineScript'
          inlineScript: |
            echo "Updating Web App settings..."
            az webapp config appsettings set \
              --name "$(appName)" \
              --resource-group "$(resourceGroupName)" \
              --slot "$(slotName)" \
              --settings ConnectionStrings__DefaultConnection="Server=tcp:$(sqlServerName),1433;Initial Catalog=$(sqlDatabaseName);Authentication=Active Directory Managed Identity;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;" \
                        AzureAd__Instance="https://login.microsoftonline.com/" \
                        AzureAd__Domain="randomdomain.com" \
                        AzureAd__TenantId="$(tenantId)" \
                        AzureAd__ClientId="$(clientId)" \
                        AzureAd__ClientSecret="$(clientSecret)"

      # Update Function App settings (only for main and development-cs branches)
      - task: AzureCLI@2
        displayName: 'Update Function App Settings'
        condition: or(eq(variables['Build.SourceBranchName'], 'main'), eq(variables['Build.SourceBranchName'], 'development-cs'))
        inputs:
          azureSubscription: '$(azureSubscription)'
          scriptType: 'bash'
          scriptLocation: 'inlineScript'
          inlineScript: |
            if [ "$(functionSlot)" = "development" ]; then
              echo "Updating Function App settings for development slot (RandomFunctionApp/development)..."
              az functionapp config appsettings set \
                --name "$(functionAppName)" \
                --resource-group "$(resourceGroupName)" \
                --slot "development" \
                --settings MyDbConnectionString="Server=tcp:$(sqlServerName),1433;Initial Catalog=$(sqlDatabaseName);Authentication=Active Directory Managed Identity;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;"
            else
              echo "Updating Function App settings for production Function App (RandomFunctionApp)..."
              az functionapp config appsettings set \
                --name "$(functionAppName)" \
                --resource-group "$(resourceGroupName)" \
                --settings MyDbConnectionString="Server=tcp:$(sqlServerName),1433;Initial Catalog=$(sqlDatabaseName);Authentication=Active Directory Managed Identity;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;"
            fi

      # Deploy the Function App package (only for main and development-cs branches)
      - task: AzureFunctionApp@2
        displayName: 'Deploy Function App to Azure'
        condition: or(eq(variables['Build.SourceBranchName'], 'main'), eq(variables['Build.SourceBranchName'], 'development-cs'))
        inputs:
          connectedServiceNameARM: 'RandomAzureConnection'
          appType: 'functionApp'
          appName: '$(functionAppName)'
          deployToSlotOrASE: true
          resourceGroupName: '$(resourceGroupName)'
          slotName: 'development'
          package: '$(Pipeline.Workspace)/drop/functionapp.zip'
          deploymentMethod: 'zipDeploy'


The script above is what I tried. Additionally, I attempted at using the Publish feature in VS Community which worked perfectly. No issues at all. It seems like the issues only occur when trying to use CI/CD with DevOps.

Edit 1: I also noticed that the web app would publish in the azure function app service, and my web app app service would no longer be published and display a page saying it is ready to be deployed to.

Edit 3: This is my current azure-pipelines.yml. The function app deploys perfectly, thank you. However, my web app no longer deploys. I tried referencing both zipped foldersin the published artifacts. I noticed that publishing them individually creates zipped folders and then publishing afterwards republishes all artifacts. Please see the code below:

trigger:
  branches:
    include:
      - development-cs
      - main
      - uat

variables:
  buildConfiguration: 'Release'
  
  # Azure Service Connection
  azureSubscription: 'AzureDevOpsConnection'  # Name of your Azure Service Connection
  
  # App Service Names
  webAppName: 'EnvisionCRM'                   # Name of your Azure Web App
  functionAppName: 'EnvisionCRM-Functions'    # Name of your Azure Function App
  resourceGroupName: 'EnvisionCRM_group'      # Name of your Resource Group

  # Example runtime settings - adjust as needed
  runtimeStack: 'DOTNETCORE|9.0'
  ResourceGroupLocation: 'East US'

  # Database names
  devSqlDatabaseName: 'eacdev'
  uatSqlDatabaseName: 'eacuat'
  mainSqlDatabaseName: 'Customer Database'

  # Deployment Slots (for Web App only)
  devSlotName: 'development'
  uatSlotName: 'uat'
  stagingSlotName: 'staging'
  productionSlotName: 'production'

stages:
- stage: BuildAndDeploy
  displayName: 'Build and Deploy Stage'
  jobs:
    # ------------------
    # 1) BUILD JOB
    # ------------------
  - job: Build
    displayName: 'Build Job'
    pool:
      vmImage: 'ubuntu-latest'
    steps:
      - checkout: self
        fetchDepth: 0
        persistCredentials: true
        clean: true

      - script: |
          echo "Build Sources Directory: $(Build.SourcesDirectory)"
        displayName: 'Print Build Sources Directory'

      - script: |
          echo '{ "sdk": { "version": "9.0.100" } }' > global.json
        displayName: 'Create global.json'

      - task: UseDotNet@2
        displayName: 'Install .NET 9.0.100 SDK in Build Job'
        inputs:
          packageType: 'sdk'
          version: '9.0.100'

      - script: |
          echo "Installing necessary tools..."
          sudo apt-get update
          sudo apt-get install -y azure-cli powershell zip
        displayName: 'Install Azure CLI, PowerShell and Zip'

      - script: |
          echo "Installing dotnet-ef tool..."
          dotnet tool install --global dotnet-ef --version 9.0.0-preview.6.24327.4
          echo '##vso[task.prependpath]$HOME/.dotnet/tools'
        displayName: 'Install dotnet-ef Tool in Build Job'

      - task: DotNetCoreCLI@2
        displayName: 'Restore NuGet Packages'
        inputs:
          command: 'restore'
          projects: '**/*.csproj'

      - task: DotNetCoreCLI@2
        displayName: 'Build Solution'
        inputs:
          command: 'build'
          projects: '**/*.csproj'
          arguments: '--configuration $(buildConfiguration) --no-restore'

      # Clean output folders to avoid carry-over from previous builds
      - script: |
          echo "Cleaning output folders..."
          rm -rf "$(Build.ArtifactStagingDirectory)/WebApp"
          rm -rf "$(Build.ArtifactStagingDirectory)/Functions"
        displayName: 'Clean Output Folders'

      # Publish the WebApp project into its own folder
      - task: DotNetCoreCLI@2
        displayName: 'Publish EnvisionCRM.WebApp'
        inputs:
          command: 'publish'
          publishWebProjects: false
          projects: 'EnvisionCRM.WebApp/EnvisionCRM.WebApp.csproj'
          arguments: '--configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory)/WebApp --no-restore'

      # Publish the Functions project into its own folder
      - task: DotNetCoreCLI@2
        displayName: 'Publish EnvisionCRM.Functions'
        inputs:
          command: 'publish'
          publishWebProjects: false
          projects: 'EnvisionCRM.Functions/EnvisionCRM.Functions.csproj'
          arguments: '--configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory)/Functions --no-restore'

      # List contents for debugging
      - script: |
          echo "Listing WebApp folder contents:"
          ls -R "$(Build.ArtifactStagingDirectory)/WebApp" || echo "WebApp folder is empty"
        displayName: 'List WebApp Files'
      
      - script: |
          echo "Listing Functions folder contents:"
          ls -R "$(Build.ArtifactStagingDirectory)/Functions" || echo "Functions folder is empty"
        displayName: 'List Functions Files'

      # Zip the published WebApp output from the artifact staging directory root
      - script: |
          rm -f "$(Build.ArtifactStagingDirectory)/EnvisionCRM.WebApp.zip"
          echo "Zipping WebApp folder..."
          cd "$(Build.ArtifactStagingDirectory)" && zip -r "EnvisionCRM.WebApp.zip" "WebApp"
        displayName: 'Zip WebApp Files'

      # Zip the published Functions output from the artifact staging directory root
      - script: |
          rm -f "$(Build.ArtifactStagingDirectory)/EnvisionCRM.Functions.zip"
          echo "Zipping Functions folder..."
          cd "$(Build.ArtifactStagingDirectory)" && zip -r "EnvisionCRM.Functions.zip" "Functions"
        displayName: 'Zip Functions Files'

      # (Optional) Generate EF Core migration SQL script for the WebApp
      - script: |
          echo "Generating EF Core migration script..."
          dotnet ef migrations script --idempotent --project "EnvisionCRM.WebApp/EnvisionCRM.WebApp.csproj" --output "$(Build.ArtifactStagingDirectory)/migration.sql"
        displayName: 'Generate EF Core Migration Script'

      # Publish build artifacts (the zipped files and any other outputs)
      - task: PublishBuildArtifacts@1
        displayName: 'Publish Build Artifacts'
        inputs:
          pathToPublish: '$(Build.ArtifactStagingDirectory)'
          artifactName: 'drop'
          publishLocation: 'Container'

    # ------------------
    # 2) DEPLOY JOB
    # ------------------
  - job: Deploy
    displayName: 'Deploy Job'
    dependsOn: Build
    pool:
      vmImage: 'ubuntu-latest'
    steps:
      - checkout: self
        fetchDepth: 0
        persistCredentials: true
        clean: true

      # Download the build artifacts
      - download: current
        artifact: drop

      - task: UseDotNet@2
        displayName: 'Install .NET 9.0.100 SDK in Deploy Job'
        inputs:
          packageType: 'sdk'
          version: '9.0.100'

      - script: |
          echo "Installing Azure CLI..."
          sudo apt-get update
          sudo apt-get install -y azure-cli
        displayName: 'Install Azure CLI'

      - script: |
          echo "Installing dotnet-ef tool..."
          dotnet tool install --global dotnet-ef --version 9.0.0-preview.6.24327.4
          echo '##vso[task.prependpath]$HOME/.dotnet/tools'
        displayName: 'Install dotnet-ef Tool in Deploy Job'

      - script: |
          echo "Verifying dotnet-ef installation..."
          dotnet ef --version
        displayName: 'Verify dotnet-ef Installation in Deploy Job'

      # Set slotName and sqlDatabaseName (used by the Web App only)
      - script: |
          branchName=$(Build.SourceBranchName)
          if [ "$branchName" == "main" ]; then
              echo "##vso[task.setvariable variable=slotName]$(stagingSlotName)"
              echo "##vso[task.setvariable variable=sqlDatabaseName]$(mainSqlDatabaseName)"
          elif [ "$branchName" == "uat" ]; then
              echo "##vso[task.setvariable variable=slotName]$(uatSlotName)"
              echo "##vso[task.setvariable variable=sqlDatabaseName]$(uatSqlDatabaseName)"
          elif [ "$branchName" == "development-cs" ]; then
              echo "##vso[task.setvariable variable=slotName]$(devSlotName)"
              echo "##vso[task.setvariable variable=sqlDatabaseName]$(devSqlDatabaseName)"
          else
              echo "##vso[task.setvariable variable=slotName]$(devSlotName)"
              echo "##vso[task.setvariable variable=sqlDatabaseName]$(devSqlDatabaseName)"
          fi

          echo "Branch: $branchName"
          echo "Slot Name: $(slotName)"
          echo "SQL Server Name: $(sqlServerName)"
          echo "SQL Database Name: $(sqlDatabaseName)"
        displayName: 'Set DB and Slot Variables'

      # (Optional) Apply EF Core migrations for the WebApp on main & uat branches
      - script: |
          echo "Applying EF Core Migrations using Service Principal..."
          dotnet ef database update --connection "Server=tcp:$(sqlServerName),1433;Database=$(sqlDatabaseName);Authentication=Active Directory Service Principal;User ID=$(sqlClientId);Password=$(sqlClientSecret);Encrypt=True;TrustServerCertificate=False;MultipleActiveResultSets=True;Connection Timeout=30;"
        displayName: 'Apply EF Core Migrations'
        condition: or(eq(variables['Build.SourceBranchName'], 'main'), eq(variables['Build.SourceBranchName'], 'uat'))

      # ---------------------------
      # DEPLOY THE WEB APP
      # ---------------------------
      - task: AzureWebApp@1
        displayName: 'Deploy to Azure Web App (EnvisionCRM)'
        inputs:
          azureSubscription: '$(azureSubscription)'
          appName: '$(webAppName)'
          deployToSlotOrASE: true
          package: '$(Pipeline.Workspace)/drop/WebApp/EnvisionCRM.WebApp.zip'
          appType: 'webApp'
          slotName: '$(slotName)'    # Use this only if your Web App uses deployment slots

      - task: AzureCLI@2
        displayName: 'Update Web App Settings'
        inputs:
          azureSubscription: '$(azureSubscription)'
          scriptType: 'bash'
          scriptLocation: 'inlineScript'
          inlineScript: |
            echo "Updating App Service settings for Web App..."
            az webapp config appsettings set \
              --name "$(webAppName)" \
              --resource-group "$(resourceGroupName)" \
              --slot "$(slotName)" \
              --settings \
                ConnectionStrings__DefaultConnection="Server=tcp:$(sqlServerName),1433;Initial Catalog=$(sqlDatabaseName);Authentication=Active Directory Managed Identity;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;" \
                AzureAd__Instance="https://login.microsoftonline.com/" \
                AzureAd__Domain="envisionafrica.co.za" \
                AzureAd__TenantId="$(tenantId)" \
                AzureAd__ClientId="$(clientId)" \
                AzureAd__ClientSecret="$(clientSecret)"

      # ---------------------------
      # DEPLOY THE FUNCTION APP
      # ---------------------------
      - task: AzureWebApp@1
        displayName: 'Deploy to Azure Function App (EnvisionCRM-Functions)'
        inputs:
          azureSubscription: '$(azureSubscription)'
          appName: '$(functionAppName)'
          package: '$(Pipeline.Workspace)/drop/Functions/EnvisionCRM.Functions.zip'
          appType: 'functionApp'
          slotName: '$(slotName)'

      - task: AzureCLI@2
        displayName: 'Update Function App Settings'
        inputs:
          azureSubscription: '$(azureSubscription)'
          scriptType: 'bash'
          scriptLocation: 'inlineScript'
          inlineScript: |
            echo "Updating App Service settings for Function App..."
            az functionapp config appsettings set \
              --name "$(functionAppName)" \
              --resource-group "$(resourceGroupName)" \
              --settings \
                ConnectionStrings__DefaultConnection="Server=tcp:$(sqlServerName),1433;Initial Catalog=$(sqlDatabaseName);Authentication=Active Directory Managed Identity;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;" \
                AzureAd__Instance="https://login.microsoftonline.com/" \
                AzureAd__Domain="envisionafrica.co.za" \
                AzureAd__TenantId="$(tenantId)" \
                AzureAd__ClientId="$(clientId)" \
                AzureAd__ClientSecret="$(clientSecret)"

Solution

  • Refer to this doc: DotNetCoreCLI@2 - .NET Core v2 task

    publishWebProjects - Publish web projects

    boolean. Optional. Use when command = publish. Default value: true.

    If this input is set to true, the projects property value is skipped, and the task tries to find the web projects in the repository and run the publish command on them.

    When you use the dotnet publish task to build your project, you need to set the publishWebProjects to false. Then the projects field value will work as expected. If the value is true, it will ignore the projects field and publish web projects in the repo. In your case, it will always build web projects.

    To solve your issue, you need to set publishWebProjects to false in your Dotnet Publish Task.

    For example:

          # Publish the Web App package
          - task: DotNetCoreCLI@2
            displayName: 'Publish Web App'
            inputs:
              command: 'publish'
              publishWebProjects: false
              projects: 'RandomApp/WebApp.csproj'
              arguments: '--configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory)/web --no-restore'
    
          # Publish the Function App package into its own folder
          - task: DotNetCoreCLI@2
            displayName: 'Publish Function App'
            inputs:
              command: 'publish'
              publishWebProjects: false
              projects: 'RandomApp/RandomFunctions.csproj'
              arguments: '--configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory)/functions --no-restore'
    

    In this case, the web app and function app projects will be output to the specified folders respectively.