Azure DevOps针对Angular项目创建build版本的yaml,并通过变量控制相应job的执行与否。
注意事项:代码前面的空格是通过Tab控制的而不是通过Space控制的。
yaml文件中包含一下内容:
1. 自动触发build
通过指定code branch使提交到此代码库的代码自动build
trigger:
- "main"
- "rc/*"
- "hf/*"
2. 指定build的code branch
如指定main、master,即只有main、master代码库才支持发布Artificats。
variables:
ROOT_PATH: refs/heads
system.debug: 'true'
COMPONENT_PROJ: 'corpro-ui'
ShouldPublish: $[or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), contains(variables['Build.SourceBranch'], 'refs/heads/rc'), contains(variables['Build.SourceBranch'], 'refs/heads/hf'))]
3. 集成Veracode Scan
用于检测包版本的缺陷。 可通过参数启用或者禁止。
- job: veracode_scan
displayName: Veracode Scan
#dependsOn: format_linting_check
#condition: and(not(failed()), ne(variables['skip.veracode.scan'], 'true'))
condition: ne(variables['skip.veracode.scan'], 'true') # skip.veracode.scan参数用于控制收否执行ceracode_scan这个Job
Veracode Scan是收费的。
4. 编译和发布到Artifacts
variables.ShouldPublish控制是否要发布到Artifacts
#------------------------------
# Build & Publish
#------------------------------
- job: build_publish
pool: AD.US.AgentPools.WNP
displayName: Build & Publish
dependsOn: veracode_scan
condition: and(succeeded(), eq(variables.ShouldPublish, true))
steps:
- task: NodeTool@0
inputs:
versionSpec: '20.x'
displayName: 'Install node.js'
- task: Npm@1
displayName: npm install
inputs:
command: custom
customCommand: 'install -force'
- task: Npm@1
displayName: npm run build
inputs:
command: 'custom'
customCommand: 'run build'
- task: Npm@1
displayName: 'Run Unit Test'
inputs:
command: custom
verbose: false
customCommand: 'run test-headless'
continueOnError: true
- task: PublishTestResults@2
displayName: 'Publish Test Results'
inputs:
testResultsFormat: 'JUnit'
testResultsFiles: '$(Build.SourcesDirectory)/TESTS-*.xml'
5. 完整yaml代码
完整yaml文件如下:
# Node.js with Angular
# Build a Node.js project that uses Angular.
# Add steps that analyze code, save build artifacts, deploy, and more:
# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript
trigger:
- "main"
- "rc/*"
- "hf/*"
#----- Pipeline run description
name: $(Build.SourceBranchName).UI.$(Date:yyyyMMdd)$(Rev:.r)
variables:
ROOT_PATH: refs/heads
system.debug: 'true'
COMPONENT_PROJ: 'corpro-ui'
ShouldPublish: $[or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), contains(variables['Build.SourceBranch'], 'refs/heads/rc'), contains(variables['Build.SourceBranch'], 'refs/heads/hf'))]
jobs:
#-------------------------------------
# Code Format & Linting Check
#-------------------------------------
# - job: format_linting_check
# displayName: Code Format & Linting Check
# # condition: eq(variables['Build.Reason'], 'PullRequest')
# steps:
# - task: Npm@1
# displayName: npm install
# inputs:
# command: custom
# customCommand: 'install -force'
# - task: Npm@1
# displayName: 'Perform prettier format check'
# inputs:
# command: custom
# verbose: false
# customCommand: 'run prettier'
# - task: Npm@1
# displayName: 'Perform eslint linting check'
# inputs:
# command: custom
# verbose: false
# customCommand: 'run lint'
#-----------------------
# Veracode Scan
#-----------------------
- job: veracode_scan
displayName: Veracode Scan
#dependsOn: format_linting_check
#condition: and(not(failed()), ne(variables['skip.veracode.scan'], 'true'))
condition: ne(variables['skip.veracode.scan'], 'true')
#----- Job variables
variables:
scanFileName: $(COMPONENT_PROJ)_scan
Sandbox_Name: a360-corpro-ui
steps:
- task: CopyFiles@2
displayName: Stage code
inputs:
SourceFolder: '$(Build.SourcesDirectory)'
Contents: |
src/**
TargetFolder: '$(Build.ArtifactStagingDirectory)'
CleanTargetFolder: true
OverWrite: true
- task: ArchiveFiles@2
displayName: Compress code (zip)
inputs:
rootFolderOrFile: "$(Build.ArtifactStagingDirectory)"
includeRootFolder: true
archiveType: "zip"
archiveFile: "$(Build.ArtifactStagingDirectory)/$(scanFileName).zip"
replaceExistingArchive: true
- task: Bash@3
displayName: List zip file and contents
inputs:
targetType: "inline"
script: |
cd $(Build.ArtifactStagingDirectory)
ls -altrR
- task: PowerShell@2
displayName: 'Veracode - check for sandbox'
condition: ne(variables['skip.veracode.scan'], 'true')
inputs:
targetType: 'inline'
script: |
if ("${env:BUILD_SOURCEBRANCH}" -ne "$(ROOT_PATH)/main"){
Write-Host "Set to sandbox Veracode scanning"
Write-Host "##vso[task.setvariable variable=scanTosandbox;]true"
Write-Host "##vso[task.setvariable variable=sboxName]"$(Build.DefinitionName)
}
else{
Write-Host "Set to actual Veracode scanning"
Write-Host "##vso[task.setvariable variable=scanTosandbox]false"
Write-Host "##vso[task.setvariable variable=sboxName]"
}
- task: Veracode@3
displayName: Request veracode scan
inputs:
ConnectionDetailsSelection: "Service Connection"
AnalysisService: "Veracode-azdoagency"
veracodeAppProfile: "$(system.teamProject)"
version: "$(build.buildNumber)"
filepath: "$(Build.ArtifactStagingDirectory)/$(scanFileName).zip"
#sandboxName: '$(sboxName)'
sandboxName: "a360-corpro-ui"
createSandBox: $(scanTosandbox)
maximumWaitTime: "60"
#------------------------------
# Build & Publish
#------------------------------
- job: build_publish
pool: Build.Pool
displayName: Build & Publish
dependsOn: veracode_scan
condition: and(succeeded(), eq(variables.ShouldPublish, true))
steps:
- task: NodeTool@0
inputs:
versionSpec: '20.x'
displayName: 'Install node.js'
- task: Npm@1
displayName: npm install
inputs:
command: custom
customCommand: 'install -force'
- task: Npm@1
displayName: npm run build
inputs:
command: 'custom'
customCommand: 'run build'
- task: Npm@1
displayName: 'Run Unit Test'
inputs:
command: custom
verbose: false
customCommand: 'run test-headless'
continueOnError: true
- task: PublishTestResults@2
displayName: 'Publish Test Results'
inputs:
testResultsFormat: 'JUnit'
testResultsFiles: '$(Build.SourcesDirectory)/TESTS-*.xml'
- task: PublishCodeCoverageResults@1
displayName: 'Publish code coverage'
inputs:
codeCoverageTool: 'Cobertura'
summaryFileLocation: '$(Build.SourcesDirectory)/coverage/**/*.xml'
# Copy files from build agent to container
- task: CopyFiles@2
displayName: 'Copy Files'
inputs:
SourceFolder: '$(Build.SourcesDirectory)/dist'
Contents: '**'
TargetFolder: '$(Build.ArtifactStagingDirectory)'
#Publish container in the pipeline
- task: PublishPipelineArtifact@1
displayName: 'Publish UI Artifacts'
inputs:
targetPath: '$(Build.ArtifactStagingDirectory)'
artifactName: 'drop'
publishLocation: pipeline