Base solution for your next web application
Open Closed

Setting Up an Azure Pipeline for ASP.NET ZERO Core Angular #10178


User avatar
0
andry3ag created

Hi Team,

We have recently downloaded the ASP.Net Core 3x with Angular 9.x (version 8.6). I have been looking into adding Azure Devops Pipeline so when we push changes to source control it automatically runs a build and executes the units tested I created. I got it to work using pipeline yaml for just doing the builds after submission but having issues with executing the tests.I have followed the documnetation to create tests for my back end services (https://docs.aspnetzero.com/en/aspnet-core-angular/latest/Developing-Step-By-Step-Angular-Creating-Unit-Tests-for-Person-Application-Service). I can see the tests that I created are submitted to Azure Devops under the [Project Name].Tests but it seems that is not executing the added test. I cant even see the test under VSTest section on the Azure Pipeline as seen by screen shot below. On purpose I have made the test fail so I can verify the flow working but its actualy passing on Azure Pipeline. The test is failing on my local machine when I execute the test. On Azure Pipeline it seems that its not even running the test. I can see that you have documentation for ASP.NET ZERO Core MVC (https://docs.aspnetzero.com/en/aspnet-core-mvc/latest/Setting-Up-an-Azure-Pipeline-Mvc-Core) but I dont see documentation for ASP.NET Core and Angular. Can you provide some steps I need to follow or some documentation so I can configure the Azure Pipeline?


16 Answer(s)
  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @andry3ag

    Could you share the content of Test step ?

    Thanks,

  • User Avatar
    0
    Hammer created

    Is there any news for this? I would be very interested in it. I tried to setup a pipeline, managed to make the backend part work, but am currently stuck with the angular part.

    Here is what I have so far in my yml:

    `trigger: - release

    jobs:

    - job: Frontend displayName: Frontend Processing continueOnError: false

    pool:   vmImage: 'ubuntu-latest'   steps:   - task: NodeTool@0   inputs:   versionSpec: '12.x'   displayName: 'Install Node.js 12.x'   - task: Npm@1   displayName: 'Angular CLI'   inputs:   command: custom   verbose: false   customCommand: 'install @angular/[email protected]'   - task: Npm@1   displayName: 'npm install'   inputs:   verbose: false   - task: Npm@1   displayName: Build   inputs:   command: custom   verbose: false   customCommand: 'start'   - task: CopyPublishBuildArtifacts@1   displayName: 'Copy Publish Artifact: test'   inputs:   CopyRoot: dist   Contents: '**'   ArtifactName: test   ArtifactType: Container   - task: DownloadPipelineArtifact@2   displayName: 'Download Pipeline Artifact'   inputs:   targetPath: ' $(Build.ArtifactStagingDirectory)/dist/AngularTest'

    - job: Backend displayName: Backend Processing dependsOn: Frontend continueOnError: false`

  • User Avatar
    0
    4Matrix created

    Has there been any update on this? I want to be able to create pipelines in devops to build .Net Core & Angular sites but I can only find a guide for MVC https://docs.aspnetzero.com/en/aspnet-core-mvc/latest/Setting-Up-an-Azure-Pipeline-Mvc-Core ?

  • User Avatar
    0
    ismcagdas created
    Support Team
  • User Avatar
    0
    4Matrix created

    Hi @ismcagdas,

    This only covers copying the files, it does not cover the actual process of building the code from the repository like the MVC guide does

    Many Thanks

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @4Matrix

    For the Host app, you just need to publish it with dotnet publish command. For the Angular app, you need to run yarn and then npm run publish commands respectively to get output for the angular app.

    Please let me know if you need help with any other step.

  • User Avatar
    0
    sedulen created

    @Hammer & @ismcagdas

    I'd be willing to help with this. I've been using Azure CICD pipelines for several years now and they work great. My project last week took longer than anticipated, but I finished up over the weekend.

    I have a few things that I've offered to provide to others, so it may take me a day or two to get back to this, but I will try to get you a generic version of my pipeline that should work for you.

    -Brian

  • User Avatar
    0
    ismcagdas created
    Support Team

    Thanks @sedulen :)

    @4Matrix did you manage to run your pipeline successfully ?

  • User Avatar
    0
    4Matrix created

    @ismcagdas, no I have not, I have had it working in the past but since I upgraded to v11 it has stopped working. It was created by a previous developer and I am not sure it was setup right. It builds locally with no issue I would just prefer to be able to publish it with a pipeline if possible.

    @sedulen, that would be great if you could offer any guidance!

  • User Avatar
    1
    sedulen created

    @4Matrix - I'm wrapping up another feature request this morning so I should have time to get you a copy of my Azure pipeline shortly.

    To note - I use a lot of Variables in my pipelines, so that they can be used across my DEV, UAT, and PROD environments. Are you comfortable working with Azure Pipelines and variables?

    I should have something posted for you tomorrow. -Brian

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @4Matrix

    Could you share your pipeline and also which part is not working ?

    Thanks,

  • User Avatar
    0
    4Matrix created

    So I have 2 Resource Groups setup in azure SiteMain and SiteDev. Both have the following set of resources: siteangular / siteangulardev - Storage Account with Static Site enabled siteapi / siteapidev - .net 6 App Service sitepublic / sitepublicdev - .net 6 App Service

    I want Two releases in Devops, one for the Public project and one for main project (Angular and API). I would like to use variables to switch between building/releasing the Dev Branch and the Master branch to the relevant locations.

  • User Avatar
    1
    sedulen created

    Here is a scrubbed version of my DEV CI pipeline. I have a separate release pipeline that handles the CD aspect of my infrastructure.

    As I noted before, I use a lot of variables.

    # Variable 'BROWSERSLIST_IGNORE_OLD_DATA' was defined in the Variables tab
    # Variable 'BuildAngularCliVersion' was defined in the Variables tab
    # Variable 'BuildConfiguration' was defined in the Variables tab
    # Variable 'BuildDotNetCoreVersion' was defined in the Variables tab
    # Variable 'BuildEntityFrameworkVersion' was defined in the Variables tab
    # Variable 'BuildNodeVersion' was defined in the Variables tab
    # Variable 'BuildNugetVersion' was defined in the Variables tab
    # Variable 'BuildUseGulp' was defined in the Variables tab
    # Variable 'BuildUseNuGet' was defined in the Variables tab
    # Variable 'ProjectName' was defined in the Variables tab
    # Variable 'yarnSetVersionEnabled' was defined in the Variables tab
    # Variable 'yarnVersion' was defined in the Variables tab
    name: $(date:yyyyMMdd)$(rev:.r)
    resources:
      repositories:
      - repository: self
        type: git
        ref: refs/heads/develop
    jobs:
    - job: Phase_1
      displayName: Build and Package
      cancelTimeoutInMinutes: 1
      pool:
        vmImage: ubuntu-20.04
      steps:
      - checkout: self
      - task: YarnInstaller@3
        displayName: Install Yarn Version
        condition: and(succeeded(), eq(variables.yarnSetVersionEnabled, true))
        inputs:
          versionSpec: $(yarnVersion)
      - task: CmdLine@2
        displayName: Check Yarn Version
        condition: and(succeeded(), eq(variables.yarnSetVersionEnabled, true))
        inputs:
          script: yarn --version
      - task: UseDotNet@2
        displayName: Use .NET Core
        inputs:
          version: $(BuildDotNetCoreVersion)
      - task: NuGetToolInstaller@1
        displayName: Use NuGet
        condition: and(succeeded(), eq(variables.BuildUseNuGet, true))
        inputs:
          versionSpec: $(BuildNugetVersion)
      - task: NuGetCommand@2
        displayName: NuGet restore
        inputs:
          solution: $(ProjectName).Web.sln
      - task: NodeTool@0
        displayName: Use Node
        inputs:
          versionSpec: $(BuildNodeVersion)
      - task: DotNetCoreCLI@2
        displayName: Initialize EntityFrameworkCore
        inputs:
          command: custom
          custom: tool
          arguments: install dotnet-ef --global --version $(BuildEntityFrameworkVersion) --ignore-failed-sources
      - task: DotNetCoreCLI@2
        displayName: Build
        inputs:
          projects: $(ProjectName).Web.sln
          arguments: --configuration $(BuildConfiguration) --no-restore
      - task: Npm@1
        displayName: Install Angular CLI
        inputs:
          command: custom
          workingDir: src/$(ProjectName).Web.Host
          verbose: false
          customCommand: install -g @angular/cli@$(BuildAngularCliVersion)
      - task: Yarn@3
        displayName: Yarn Install
        inputs:
          projectDirectory: src/$(ProjectName).Web.Host
          arguments: install --verbose
      - task: Yarn@3
        displayName: Yarn Add Gulp
        condition: and(succeeded(), eq(variables.BuildUseGulp, true))
        inputs:
          projectDirectory: src/$(ProjectName).Web.Host
          arguments: add gulp --dev
      - task: CmdLine@2
        displayName: Check Node & Angular/CLI versions
        inputs:
          script: node ./node_modules/@angular/cli/bin/ng --version
          workingDirectory: src/$(ProjectName).Web.Host
          failOnStderr: true
      - task: CmdLine@2
        displayName: Check Gulp version
        condition: and(succeeded(), eq(variables.BuildUseGulp, true))
        inputs:
          script: node ./node_modules/gulp/bin/gulp --version
          workingDirectory: src/$(ProjectName).Web.Host
          failOnStderr: true
      - task: CmdLine@2
        displayName: Build Gulp
        condition: and(succeeded(), eq(variables.BuildUseGulp, true))
        inputs:
          script: node ./node_modules/gulp/bin/gulp build
          workingDirectory: src/$(ProjectName).Web.Host
          failOnStderr: true
      - task: CmdLine@2
        displayName: Build Angular
        inputs:
          script: node --max-old-space-size=8192 ./node_modules/@angular/cli/bin/ng build --progress=false --configuration=$(BuildConfiguration) --output-path=$(Build.ArtifactStagingDirectory)/temp/wwwroot --source-map=false
          workingDirectory: src/$(ProjectName).Web.Host
      - task: DotNetCoreCLI@2
        displayName: Publish Website
        inputs:
          command: publish
          publishWebProjects: false
          projects: src/$(ProjectName).Web.Host/$(ProjectName).Web.Host.csproj
          arguments: -c $(BuildConfiguration) -o $(Build.ArtifactStagingDirectory)/temp /p:PublishProfile=$(BuildConfiguration) --no-restore
          zipAfterPublish: false
          modifyOutputPath: false
      - task: ArchiveFiles@2
        displayName: Zip API
        inputs:
          rootFolderOrFile: $(Build.ArtifactStagingDirectory)/temp
          includeRootFolder: false
          sevenZipCompression: 5
          archiveFile: $(Build.ArtifactStagingDirectory)/$(ProjectName)_$(BuildConfiguration)_$(Build.BuildNumber).zip
      - task: DeleteFiles@1
        displayName: Delete Temp Folder
        inputs:
          SourceFolder: $(Build.ArtifactStagingDirectory)
          Contents: temp
      - task: PublishBuildArtifacts@1
        displayName: Publish Web Artifacts
        inputs:
          ArtifactName: Web
      - task: DotNetCoreCLI@2
        displayName: Create SQL Migration Scripts
        inputs:
          command: custom
          custom: ef
          arguments: migrations script -i -p src/$(ProjectName).EntityFrameworkCore/$(ProjectName).EntityFrameworkCore.csproj -o $(Build.ArtifactStagingDirectory)/Migrations/$(ProjectName).Core_$(BuildConfiguration)_migrations_$(Build.BuildNumber).sql
      - task: CopyFiles@2
        displayName: Copy SQL files into Sql Artifact
        inputs:
          SourceFolder: sql
          TargetFolder: $(Build.ArtifactStagingDirectory)/Migrations/
      - task: PublishBuildArtifacts@1
        displayName: Publish Sql Artifact
        inputs:
          PathtoPublish: $(Build.ArtifactStagingDirectory)/Migrations/
          ArtifactName: SQL
    ...
    
    

    The only thing that might not work out of the box for you would be the NuGet Restore command, if you happen to use a private Artifact Feed instead of all public NuGet repositories. It's fairly simple to wire those up as well, if you are using private Artifact Feeds.

    This framework has worked beautifully for me years. I have added to it to include building docker images and tagging + pushing docker images to an Azure ACR. I have also added 3rd party code scanning services, such as WhiteSource and Snyk.

    I can share more of those additions later if you would like, but those start to get into AZDO service connections and 3rd party service accounts, so it made sense to keep those out for now.

    I also do not build or publish the .Public or .Migrator projects. I could, I just decided not to use them for this project. Instead we generate the .sql files using the ef migrations script command.

    Lastly, I've been working on upgrading from v6.9.0 to a more current version for a while now. Sadly, I'm still on dotnet core 2.2. That is why you see many "Version" parameters and even executing the "gulp" command all being controlled by conditional variables.

    This same pipeline should work for you for both dev branch and your master branch. I haven't worked with 1 .yml file as a template for multiple pipelines, so I basically got this .yml file as I wanted it, and then uploaded it twice, once to my DEV pipeline and once to my PROD pipeline, and configured the variables and source repo.

    I hope this helps! Let me know if you have any question.

    -Brian

  • User Avatar
    0
    ismcagdas created
    Support Team

    Thanks @sedulen :)

  • User Avatar
    1
    4Matrix created

    Ok so I have now got my Pipeline working correctly, for anyone else that is interested, here is my YAML:

    pool:
      name: MyBuildPool - Self Hosted
      demands:
      - msbuild
      - visualstudio
      - npm
      - vstest
    
    steps:
    - task: UseDotNet@2
      displayName: 'Use .NET Core sdk 6.x'
      inputs:
        version: 6.x
        includePreviewVersions: true
    
    - task: NuGetToolInstaller@1
      displayName: 'Use NuGet 6.x'
      inputs:
        versionSpec: 6.x
    
    - task: NuGetCommand@2
      displayName: 'NuGet restore MyProject.Demo'
      inputs:
        restoreSolution: 'aspnet-core/MyProject.Demo.Web.sln'
    
    - task: VSBuild@1
      displayName: 'Build solution MyProject.Demo.Web.Host'
      inputs:
        solution: 'aspnet-core/src/MyProject.Demo.Web.Host/MyProject.Demo.Web.Host.csproj'
        msbuildArgs: '/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:PackageLocation="$(build.artifactstagingdirectory)\\"'
        platform: '$(BuildPlatform)'
        configuration: '$(BuildConfiguration)'
    
    - task: DeleteFiles@1
      displayName: 'Delete files from .dist/web'
      inputs:
        SourceFolder: '$(Build.SourcesDirectory)/angular'
        Contents: .dist/web
        RemoveSourceFolder: true
    
    - task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@3
      displayName: 'Yarn Install'
    
    - task: geeklearningio.gl-vsts-tasks-yarn.yarn-task.Yarn@3
      displayName: 'Yarn '
      inputs:
        projectDirectory: angular
    
    - task: Npm@1
      displayName: 'npm run publish'
      inputs:
        command: custom
        workingDir: angular
        verbose: false
        customCommand: 'run publish'
        publishRegistry: useFeed
    
    - task: CopyFiles@2
      displayName: 'Copy web.config to angular root'
      inputs:
        SourceFolder: '$(Build.SourcesDirectory)\angular'
        Contents: web.config
        TargetFolder: '$(Build.SourcesDirectory)\angular\.dist\web'
        OverWrite: true
    
    - task: ArchiveFiles@2
      displayName: 'Archive $(Build.SourcesDirectory)\angular\.dist\web'
      inputs:
        rootFolderOrFile: '$(Build.SourcesDirectory)\angular\.dist\web'
        archiveFile: '$(build.artifactstagingdirectory)\AngularUI.zip'
    
    - task: VSTest@2
      displayName: 'Test Assemblies'
      inputs:
        testAssemblyVer2: |
         **\$(BuildConfiguration)\*test*.dll
         !**\obj\**
        platform: '$(BuildPlatform)'
        configuration: '$(BuildConfiguration)'
    
    - task: PublishSymbols@1
      displayName: 'Publish symbols path'
      inputs:
        SearchPattern: '**\bin\**\*.pdb'
      continueOnError: true
    
    - task: PublishBuildArtifacts@1
      displayName: 'Publish Artifact'
      inputs:
        PathtoPublish: '$(build.artifactstagingdirectory)'
        ArtifactName: '$(Parameters.ArtifactName)'
    
    - task: mspremier.PostBuildCleanup.PostBuildCleanup-task.PostBuildCleanup@3
      displayName: 'Clean Agent Directories'
    
    

    I have also setup my release according to the documentation here https://docs.aspnetzero.com/en/aspnet-core-angular/latest/Step-by-step-publish-to-azure-angular-staticsite#publish-files-to-azure-storage and it deploys successfully but I cannot seem to access the site? Do i need to create any extra DNS records as currently I only have the API and CDN records on the DNS but not an actual link for viewing the site/login screen? Should it just be cdn.mysite.com?

  • User Avatar
    0
    ismcagdas created
    Support Team

    Thank you for sharing your pipeline @4Matrix. Do you host Angular app and the Host app under the same website ? If you are hosting only the Angular app on azure storage, you can cehck https://docs.microsoft.com/en-us/azure/storage/blobs/storage-blob-static-website