Reputation: 1297
I'm attempting to deploy a Blazor WASM app to an Azure Static Web App. I've got a working pipeline that will Restore/Build/Test/Publish and a Release pipeline that will take the published artifact and deploy it to various development/test/stage environments. So far everything is working with the exception of one thing: I need to change the API URL in the appsettings.json for each targeted environment. This is how the appsettings.json is currently committed:
{
"HttpClient": {
"BaseAddress": ""
}
}
My Agent Job in the Release Pipeline has the following tasks:
Each task in the release pipeline is successful but the deployed code doesn't have the URL.
Here's the YML for the Release pipeline:
steps:
- task: ExtractFiles@1
displayName: 'Extract files '
inputs:
destinationFolder: '$(System.DefaultWorkingDirectory)/blazor'
overwriteExistingFiles: true
- task: FileTransform@2
displayName: 'Transform AppSettings'
inputs:
folderPath: '$(System.DefaultWorkingDirectory)/blazor'
jsonTargetFiles: '**/appsettings.json'
- powershell: |
Get-Content /home/vsts/work/r1/a/blazor/wwwroot/appsettings.json
displayName: 'PowerShell Script'
- task: AzureStaticWebApp@0
displayName: 'Static Web App: Blazor WASM'
inputs:
workingDirectory: '$(System.DefaultWorkingDirectory)/blazor'
app_location: /wwwroot
skip_app_build: true
skip_api_build: true
is_static_export: false
verbose: true
azure_static_web_apps_api_token: 'XXXXXXXXXX'
If I disable the Transform Appsettings step, commit a valid, working URL to the appsettings.json, and deploy that release, everything works. I've also tried swapping around the extract and transforms steps and that doesn't seem to work.
Upvotes: 2
Views: 1323
Reputation: 163
I ran into this exact same problem with Static Web Apps.
The issue is that when published, compressed versions of the appsettings file (i.e. appsettings.json.br / appsettings.json.gz) are also created. These compressed versions however cannot be transformed by the transform files task.
To test this, temporarily change your browser settings to disable accepting brotli and gzip compression (possible in Firefox via editing the network.http.accept-encoding.secure setting for https; type about:config into the browser address bar to access the advanced settings). If you then clear cache and reload appsettings.json from your site, you should then see the correct transformed values.
What to do about this is a little trickier. If you try to transform the compressed file (.br / .gz) as well in your pipeline you'll get an error:
2023-04-21T20:44:58.3530105Z Applying JSON variable substitution for **/appsettings.json.br
2023-04-21T20:44:58.4538803Z ##[warning]Can't find loc string for key: UnknownFileEncodeError
Of course, the file can't be read and transformed like a regular text file as it's compressed.
I ended up using a bash script step to simply delete the compressed files (I have a previous step that unzips the package into a directory called 'unzip'):
rm '$(System.DefaultWorkingDirectory)/unzip/wwwroot/appsettings.json.br'
rm '$(System.DefaultWorkingDirectory)/unzip/wwwroot/appsettings.json.gz'
Deleting the files feels like cheating, but my appsettings file is pretty small so not much gained by compressing it really. Once removed, the updated appsettings file is always served.
Upvotes: 2
Reputation: 1297
I'm not sure why the AzureStaticWebApp@0 isn't honoring the file transformations. I ended up deleting the Static Web App and created a Storage Account with a Static Site. In DevOps, I removed the AzureStaticWebApp@0 task and added a AzureFileCopy@3 Task in it's place. Everything is working great now and the file transformations are getting picked up.
Upvotes: 0
Reputation: 7482
The common way to manage different settings for different environments is to set the ASPNETCORE_ENVIRONMENT
or DOTNET_ENVIRONMENT
environment variable (docs). Then you can have multiple copies of appsettings.envName.json which automatically get substituted at runtime. You can set the environment variable (which might well be the well known "Production" value) via the ApplicationSettings in Azure
Variable substitution might be more appropriate for secret values such as passwords or api keys that you don't want in source control, but for URLs it is not really necessary. Looking at the FileTransform@2 docs it appears to you need to define a variable in your pipeline that corresponds to the JSON path of the value you want to set. This does not appear in your posted yml which might be your specific problem, variables can be passed in a number of different ways and I'm not familiar with the File Transform task, but my reading of the docs is that you need to define a variable named HttpClient.BaseAddress
at some point in your pipeline
Upvotes: 0