Introduce Azure Pipelines
The Gallery of Azure DevOps pipelines, where I share experience about some approaching automation in this platform.
Documentation
Feature
Deploy React application to Azure SWA
Pipelines will help you deploy and release react application to swa
of Azure Cloud
Plugins:
Tools:
First of all, you need to provide this json
file for purpose set up swa-cli
what use to provide configuration and deploy your application
swa-cli.config.json {
"$schema" : "https://aka.ms/azure/static-web-apps-cli/schema" ,
"configurations" : {
"wiki" : {
"appLocation" : "." ,
"outputLocation" : "public" ,
"appBuildCommand" : "npm run build" ,
"run" : "npm run start" ,
"appDevserverUrl" : "http://localhost:8080" ,
"env" : "production"
}
}
}
azure-pipelines.yaml trigger : none
pool : $(PoolName)
stages :
- stage : build_publish_artifacts
displayName : Build and publish
jobs :
- job : setup_environment_and_publish_artifacts
displayName : Setup environemnts, build and publish artifacts
steps :
- task : UseNode@1
displayName : Setup Node
inputs :
version : '18.14'
- script : |
npm ci
npx quartz build
workingDirectory : "./src"
displayName : Install dependencies and build
- task : PublishBuildArtifacts@1
inputs :
ArtifactName : public
PathtoPublish : "./src/public"
- stage : deploy_to_swa
displayName : Deploy Page
jobs :
- job : pull_and_deploy_web
displayName : Deploy the web page
steps :
- task : DownloadBuildArtifacts@0
inputs :
artifactName : public
downloadPath : "./src/"
displayName : Download build artifacts
- task : UseNode@1
displayName : Setup Node
inputs :
version : '18.14'
- script : |
npm install -g @azure/static-web-apps-cli
swa --version
swa deploy --deployment-token=$(token_release)
workingDirectory : $(System.DefaultWorkingDirectory)/src
displayName : Install swa and deploy application
Just create a pipeline on Azure DevOps
and trigger the pipeline by manually, and provide some require environment variables for pipeline, like token_release
(Token of Azure SWA) and PoolName
(Name of agent to perform pipeline)
Click Run
to trigger pipeline, last state will announce your deployment completely with your web application domain
Setup CI/CD for React Native
Read more about React Native build with fastlane on CI/CD at Build mobile with fastlane
Status: Does not completely, continuous integrate next step build android 😢 😢 😢
Setup CI for setup environment, build tools for test and build APK
and IPA
file for both Android
and IOS
. Let digest !!!
Plugins:
Tools:
react-native.yaml trigger : none
stages :
- stage : setup_and_test
displayName : Setup environment and test
pool :
vmImage : 'ubuntu-latest'
jobs :
- job : setup_and_test
displayName : Setup environment
steps :
- task : UseNode@1
displayName : Setup Node
inputs :
version : '18.20'
- script : |
npm i -g yarn
yarn install
displayName : Install Package
workingDirectory : "./app"
- script : |
yarn lint
displayName : Syntax Check ESlint
workingDirectory : "./app"
- script : |
yarn add -D jest-junit
yarn test --ci --reporters=jest-junit --reporters=default
displayName : Unit test jest
workingDirectory : "./app"
- task : PublishTestResults@2
displayName : Publish Test Result
inputs :
testResultsFormat : 'JUnit'
testResultsFiles : '**/junit.xml'
searchFolder : "./app"
- stage : build_android
displayName : Build Android Applications
jobs :
- job : build_android
displayName : Build Android Jobs
steps :
- task : UseNode@1
displayName : Setup Node Environment
inputs :
version : "18.20"
- script : |
npm i -g yarn
yarn install
displayName : Install node package for project
- script : |
cd ./android || exit 1
fastlane build
displayName : Build the APK for Android Project
- task : PublishBuildArtifacts@1
displayName : Publish APK file to Repository
inputs :
ArtifactName : APK Package
PathtoPublish : ./android/app/build/outputs/apk/release
Troubleshoot
When you set up the azure-agent for running job, remember set .env
variables for specify agent because it will not read Linux $PROFILE
, just read only environment in runsvc.sh
. Read more at: StackOverFlow - ANDROID_HOME not set (VSTS agent running as service on OS X)
Setup CICD for build Container Applications
You can use this pipeline for deploy application Azure Container Application with self-hosted VM via systemassign
identity
Plugins:
Tools (Require install to VM)
# Non trigger automation trigger, but base on policy
trigger: none
# Trigger when open PR to main
pr:
branches:
include:
- main
pool:
vmImage: 'ubuntu-latest'
stages:
- stage: test_and_build
displayName: Test and Build Applications
condition: ne ( variables[ 'Build.SourceBranchName' ], 'main' )
variables:
buildConfiguration: 'Release'
jobs :
- job: test_and_build
displayName: Test and Build Applications
steps:
- task: UseDotNet@2
displayName: 'Install .NET Core SDK'
inputs:
version: 8.0 .300
- task: DotNetCoreCLI@2
displayName: 'Restore Dependencies'
inputs:
command : 'restore'
projects: '**/*.csproj'
- task: DotNetCoreCLI@2
displayName: "Build Project"
inputs:
command : 'build'
arguments: '-c $buildConfiguration -o ./build'
modifyOutputPath: true
workingDirectory: './src'
- task: DotNetCoreCLI@2
displayName: "Published Project"
inputs:
command : 'publish'
arguments: '-c $buildConfiguration -o ./publish'
zipAfterPublish: false
workingDirectory: './src'
- task: PublishBuildArtifacts@1
displayName: 'Published Artifact'
inputs:
PathtoPublish: './src/publish'
ArtifactName: public-artifact - stage: build_image
- stage: build_image
displayName: Build Docker Image
# Run when merge code into main
condition: eq ( variables[ 'build.sourceBranch' ], 'refs/heads/main' )
jobs :
- job: build_image
displayName: Build Docker Image and Push to registry
steps:
- task: Docker@2
displayName: Login to ACR
inputs:
command : login
# Manage service connections
# Documentation: https://learn.microsoft.com/en-us/azure/devops/pipelines/library/service-endpoints?view=azure-devops&tabs=yaml
containerRegistry: "Dockerserviceconnection"
- task: Docker@2
displayName: Build and Push Image
inputs:
command : buildAndPush
Dockerfile: ./src/Dockerfile
repository: app-dev
buildContext: ./src/
tags: |
latest
$(Build.SourceVersion )
- stage: deploy
displayName: Deploy Applications
dependsOn: build_image
condition: and ( succeeded( 'build_image' ) , eq ( variables[ 'build.sourceBranch' ], 'refs/heads/main' ))
jobs :
- deployment: deploy
# Set rule to permit running this job or pending
# Documentation: https://learn.microsoft.com/en-us/azure/devops/pipelines/process/environments?view=azure-devops
environment: $( environmentDeployment )
strategy:
runOnce:
deploy:
steps:
- script: |
az login --identity
az containerapp update --name mindfull-app-$( environmentDeployment ) \
--resource-group rg-$( environmentDeployment ) \
--image example.azurecr.io/app-$( environmentDeployment ):$( Build.SourceVersion ) \
--set-env-vars "ASPNETCORE_ENVIRONMENT=$( environmentApplication )" \
"ConnectionStrings__Default=secretref:ConnectionStrings"
displayName: Deploy Applications to Container App
Policy on auto trigger, just work with main
branch. So if you work with another branch, like production
,develop
, … Thus we need, change trigger
value to your specify branch. Issue: StackOverFlow - Using CI triggers and PR build validation together: Prevent that build runs twice
# Just work with main, if you push the pr
trigger : none
# If you want to use both pr and trigger (For another branch)
trigger :
branches :
include :
- develop
pr :
branches :
include :
- develop
Optional
To help PR event occur trigger CI automation, you need to configure Policy
for branch, for example
You want trigger for main
branch, so you need choose Branch polices
option, It will bring you to another page for setup policy
On the Build Validation
, you can choose +
button for adding build validation with trigger automation your pipeline
For example, I have react-native
pipeline, It will automation trigger this one when I create PR.
You can choose Manual for instead but if you want,
Others optional, you can clarify Required or Optional to accept build failed
pipeline, that cause block
Choose the Build expiration to set time line of Build events to validate
When trigger, your pipeline will set PR automated for
instead of Individual CI
Troubleshoot
When you use succeeded()
expression, remember import name branch you need to check on on the single quote bracket like succeeded('build')
, it mean this task will read-only the status state of build
stage, if not it will read all values of stage or job in pipeline, and make a decision
Setup agent
The SSL connection could not be established, and No usable version of libssl was found
With the sentence No usable version of libssl was found
, usually meet on Ubuntu 22.04, you can fix by install openssl
Ubuntu: Ubuntu Package
Issue: Github
wget -c http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.0g-2ubuntu4_amd64.deb
sudo dpkg -i libssl1.1_1.1.0g-2ubuntu4_amd64.deb
After that, you can run ./config.sh
, but next sentence will problems The SSL connection could not be established
. You can resolve that one with ENV AZP
variables
First export to environment variable AZP_AGENT_USE_LEGACY_HTTP
and run ./config.sh
export AZP_AGENT_USE_LEGACY_HTTP = true
./config.sh
After that, you need set to environment to agent to bypass the SSL issue in runsvc.sh
file
runsvc.sh #!/bin/bash
# convert SIGTERM signal to SIGINT
# for more info on how to propagate SIGTERM to a child process see: http://veithen.github.io/2014/11/16/sigterm-propagation.html
trap 'kill -INT $PID' TERM INT
if [ -f ".path" ]; then
# configure
export PATH = ` cat .path`
echo ".path=${ PATH }"
fi
# insert anything to setup env when running as a service
export AZP_AGENT_USE_LEGACY_HTTP = true
# run the host process which keep the listener alive
./externals/node10/bin/node ./bin/AgentService.js &
PID = $!
wait $PID
trap - TERM INT
wait $PID
And that all, trigger svc.sh
file to setup and connect the agent to pool
sudo ./svc.sh install
sudo ./svc.sh start