Angular 8 with Azure DevOps Build Pipeline
Angular 8 is a very useful JavaScript framework for building applications. Being able to build these projects on Azure DevOps Pipelines is very useful.
This is an update from Angular 7 blog post here..
Angular Project
The repository on GitHub is here.
Following the Angular Quickstart here I created a new folder and put Angular 8 project in there.
> mkdir src
> cd src
> npm install -g @angular/cli
> ng new angular8
Packages to add
> npm install puppeteer --save-dev
> npm install karma-junit-reporter --save-dev
> npm install jasmine-reporters --save-dev
Code Changes
Here’s the overview of code changes.
Added Build Pipeline YAML definition:
trigger:
branches:
include:
- master
- releases/*
resources:
- repo: self
pool:
vmImage: 'Ubuntu 18.04'
variables:
buildConfiguration: 'Release'
ngBuildConfiguration: '--prod'
steps:
- task: DeleteFiles@1
displayName: 'Delete JUnit files'
inputs:
SourceFolder: src/angular8/junit
Contents: 'TEST*.xml'
- task: Npm@1
displayName: 'npm install'
inputs:
command: install
workingDir: src/angular8
- task: Npm@1
displayName: 'Build Angular'
inputs:
command: custom
customCommand: run build -- $(ngBuildConfiguration)
workingDir: src/angular8
- task: PublishPipelineArtifact@0
inputs:
artifactName: angular8PipelineArtifactProd
targetPath: 'src/angular8/dist'
- task: PublishBuildArtifacts@1
inputs:
PathtoPublish: 'src/angular8/dist'
ArtifactName: angular8BuildArtifactProd
- task: DeleteFiles@1
displayName: 'Delete Build files'
inputs:
Contents: 'src/angular8/dist'
- task: Npm@1
displayName: 'Test Angular'
inputs:
command: custom
customCommand: run test -- --watch=false --code-coverage
workingDir: src/angular8
- task: PublishCodeCoverageResults@1
displayName: 'Publish code coverage Angular results'
condition: succeededOrFailed()
inputs:
codeCoverageTool: Cobertura
summaryFileLocation: 'src/coverage/cobertura-coverage.xml'
reportDirectory: src/coverage
failIfCoverageEmpty: true
- task: PublishTestResults@2
displayName: 'Publish Angular test results'
condition: succeededOrFailed()
inputs:
searchFolder: $(System.DefaultWorkingDirectory)/src/junit
testRunTitle: Angular
testResultsFormat: JUnit
testResultsFiles: "**/TESTS*.xml"
- task: Npm@1
displayName: 'Lint Angular'
inputs:
command: custom
customCommand: run lint -- --format=stylish
workingDir: src/angular8
- task: Npm@1
displayName: 'E2E Test Angular'
inputs:
command: custom
customCommand: run e2e
workingDir: src/angular8
- task: PublishTestResults@2
displayName: 'Publish Angular E2E test results'
condition: succeededOrFailed()
inputs:
searchFolder: $(System.DefaultWorkingDirectory)/src/angular8/e2e/junit
testRunTitle: Angular_E2E
testResultsFormat: JUnit
testResultsFiles: "**/junit*.xml"
package.json scripts (in addition to whatever version of the above added packages):
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"install-puppeteer": "cd node_modules/puppeteer && npm run install",
"test": "npm run install-puppeteer && ng test",
"lint": "ng lint",
"e2e": "npm run install-puppeteer && ng e2e"
},
Final karma.conf.js:
module.exports = function (config) {
const puppeteer = require('puppeteer');
process.env.CHROME_BIN = puppeteer.executablePath();
console.log(process.env.CHROME_BIN)
config.set({
basePath: '',
frameworks: ['jasmine', '@angular-devkit/build-angular'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage-istanbul-reporter'),
require('@angular-devkit/build-angular/plugins/karma'),
require('karma-junit-reporter')
],
client: {
clearContext: false // leave Jasmine Spec Runner output visible in browser
},
coverageIstanbulReporter: {
dir: require('path').join(__dirname, '../coverage'),
reports: ['html', 'lcovonly', 'text-summary', 'cobertura'],
fixWebpackSourcePaths: true
},
reporters: ['progress', 'kjhtml', 'junit'],
junitReporter: {
outputDir: '../junit'
},
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['ChromeHeadless'],
singleRun: false
});
};
Final protractor.conf.js:
const { SpecReporter } = require('jasmine-spec-reporter');
const { JUnitXmlReporter } = require('jasmine-reporters');
const puppeteer = require('puppeteer');
process.env.CHROME_BIN = puppeteer.executablePath();
console.log(process.env.CHROME_BIN)
exports.config = {
allScriptsTimeout: 11000,
specs: [
'./src/**/*.e2e-spec.ts'
],
capabilities: {
'browserName': 'chrome',
chromeOptions: {
args: ["--headless", "--disable-gpu", "--window-size=1200,900"],
binary: process.env.CHROME_BIN
}
},
directConnect: true,
baseUrl: 'http://localhost:4200/',
framework: 'jasmine',
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 30000,
print: function () { }
},
onPrepare() {
require('ts-node').register({
project: require('path').join(__dirname, './tsconfig.json')
});
jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
var junitReporter = new JUnitXmlReporter({
savePath: require('path').join(__dirname, './junit'),
consolidateAll: true
});
jasmine.getEnv().addReporter(junitReporter);
}
};
Summary
My code is here. Azure DevOps makes builds easy.