While working on a React based static website recently, there was a need to see exactly what was deployed in the Dev/Test environments to reduce confusion amongst teams. I wanted to show something like this:
A quick look at the site's footer should show the Git Commit Hash and Build Number which was deployed and click through to actual commits and build results. Let's see how we achieved this using Azure DevOps.
Git Commit Hash
Azure DevOps exposes a variable called $(Build.SourceVersion) which contains the hash of the commit. So I defined a variable in the Build Pipeline using it.
Build Id and Build Number
Azure DevOps also exposes two release time variables $(Build.BuildId) and $(Build.BuildNumber) which can be used to define custom variables in the pipeline.
So we have a total of 3 variables defined:
Next we use these variables in our React App. I created 3 global variables in index.html and assigned a token value to them.
<script type="text/JavaScript">
window.REACT_APP_BUILD_ID="#{REACT_APP_BUILD_ID}#";
window.REACT_APP_BUILD_NUMBER="#{REACT_APP_BUILD_NUMBER}#";
window.REACT_APP_GIT_HASH="#{REACT_APP_GIT_HASH}#";
</script>
These variables are used in App.js to create the footer. Notice the use of hard-coded links as I like to keep things simple.
<footer className="App-footer">
<div>
Deployed from commit{" "}
<a
href={
"https://dev.azure.com/mayanktestharness/ReactBuild/_git/ReactBuild/commit/" +
window.REACT_APP_GIT_HASH
}
>
{shortHash}
</a>{" "}
via build{" "}
<a
href={
"https://dev.azure.com/mayanktestharness/ReactBuild/_build/results?buildId=" +
window.REACT_APP_BUILD_ID
}
>
{window.REACT_APP_BUILD_NUMBER}
</a>
.
</div>
</footer>
Next I used Azure DevOps Pipeline and excellent "Replace Tokens" task to replace the tokens. You may need to import this task in your Azure DevOps organization if you haven't used it before.
This is the complete YAML of my CI/CD pipeline.
# Node.js React Web App to Linux on Azure
# Build a Node.js React app and deploy it to Azure as a Linux web app.
# Add steps that analyze code, save build artifacts, deploy, and more:
# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript
trigger:
- main
variables:
# Azure Resource Manager connection created during pipeline creation
azureSubscription: 'xxxxx'
# Web app name
webAppName: 'reactbuildblog'
# Environment name
environmentName: 'reactbuildblog'
# Agent VM image name
vmImageName: 'ubuntu-latest'
stages:
- stage: Build
displayName: Build stage
jobs:
- job: Build
displayName: Build
pool:
vmImage: $(vmImageName)
steps:
- task: Npm@1
displayName: 'NPM Install'
inputs:
command: 'install'
- task: Npm@1
displayName: 'NPM Build'
inputs:
command: 'custom'
customCommand: 'run build'
- task: ArchiveFiles@2
displayName: 'Archive files'
inputs:
rootFolderOrFile: '$(System.DefaultWorkingDirectory)/build'
includeRootFolder: false
archiveType: zip
archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip
replaceExistingArchive: true
- upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip
artifact: drop
- stage: Deploy
displayName: Deploy stage
dependsOn: Build
condition: succeeded()
jobs:
- deployment: Deploy
displayName: Deploy
environment: $(environmentName)
pool:
vmImage: $(vmImageName)
strategy:
runOnce:
deploy:
steps:
- task: ExtractFiles@1
displayName: "Unzipping"
inputs:
archiveFilePatterns: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip'
destinationFolder: '$(System.DefaultWorkingDirectory)/release'
cleanDestinationFolder: true
overwriteExistingFiles: false
- task: replacetokens@3
displayName: "Replacing Tokens"
inputs:
rootDirectory: '$(System.DefaultWorkingDirectory)/release'
targetFiles: 'index.html'
encoding: 'auto'
writeBOM: true
actionOnMissing: 'warn'
keepToken: false
tokenPrefix: '#{'
tokenSuffix: '}#'
useLegacyPattern: false
enableTelemetry: true
- task: AzureRmWebAppDeployment@4
displayName: "Deploying"
inputs:
ConnectionType: 'AzureRM'
azureSubscription: 'MSDN Platforms (xxxxx)'
appType: 'webApp'
WebAppName: 'xxxx'
packageForLinux: '$(System.DefaultWorkingDirectory)/release'
That's it! You can now show your commit hash and build ids in your live static React website helping you test team to certify a particular build and reduce confusion.
Comments
Post a Comment
As far as possible, please refrain from posting Anonymous comments. I would really love to know who is interested in my blog! Also check out the FAQs section for the comment policy followed on this site.