Azure DevOps Release Pipeline Web.Config Edit
P

3

5

I know that when creating a release pipeline in Azure DevOps you can have the web.config of an app updated with variables from the pipeline and that works great for all the appSettings values.

But, during the release pipeline I'd like to update a different section of the web.config, specifically the sessionState provider node. I've tried a few plugins for the release pipeline like Config Transform by Magic Chunks but the problem is it needs you to specify the path of the configuration file to edit but by the time it gets to the release pipeline the source files are in a zip archive. Somehow the normal transformations of the appSettings are able to work off the unzipped version but I can't get other transformations to happen after the file is unzipped.

I know you can make changes in the build pipeline but there are reasons we want to do it in the release pipeline.

Anyone know a way to make changes to the web.config outside of the appSettings grouping in a release pipeline for an Azure App Service?

Prakrit answered 2/10, 2019 at 22:37 Comment(1)
Hi,@Nick Olsen What is your test result? Can you share it with us :)Fanchon
B
5

You can use PowerShell to do the transformation within the zip file.

For example, I have this node in the web.config:

<configuration>
  <sessionstate 
      mode="__mode__"
      cookieless="false" 
      timeout="20" 
      sqlconnectionstring="data source=127.0.0.1;user id=<user id>;password=<password>"
      server="127.0.0.1" 
      port="42424" 
  />
</configuration>

I use this script:

# cd to the agent artifcats direcory (where the zip file exist)
cd $env:Agent_ReleaseDirectory
$fileToEdit = "web.config"

[Reflection.Assembly]::LoadWithPartialName("System.IO.Compression.FileSystem");
# Open zip and find the particular file (assumes only one inside the Zip file)
$zipfileName = dir -filter '*.zip'
$zip =  [System.IO.Compression.ZipFile]::Open($zipfileName.FullName,"Update")

$configFile = $zip.Entries.Where({$_.name -like $fileToEdit})

# Read the contents of the file
$desiredFile = [System.IO.StreamReader]($configFile).Open()
$text = $desiredFile.ReadToEnd()
$desiredFile.Close()
$desiredFile.Dispose()
$text = $text -replace  '__mode__',"stateserver"
#update file with new content
$desiredFile = [System.IO.StreamWriter]($configFile).Open()
$desiredFile.BaseStream.SetLength(0)

# Insert the $text to the file and close
$desiredFile.Write($text)
$desiredFile.Flush()
$desiredFile.Close()

# Write the changes and close the zip file
$zip.Dispose()

Before:

enter image description here

After (inside the zip file, without unzip and re-zip):

enter image description here

Beatrice answered 3/10, 2019 at 12:23 Comment(4)
Great idea. I'll try that out today and see if I can get it to work. Thanks.Prakrit
@NickOlsen Did you check it?Beatrice
You are the man. I could not find any existing task that would replace arbitrary values inside an XML file inside a ZIP file. Thanks very much!!!Tetrapody
In my release pipeline I have "IIS Web App Manage" and "IIS Web App Deploy". I have put this below "IIS Web App Deploy" and even tho it executes, it does not update the file. Tried placing it above and it fails. Can you tell me if this won't work on IIS preset or I should use YAML config?Sacellum
H
3

I was looking to do something similar, but found that there is a built-in task called File Transform [https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/utility/file-transform?view=azure-devops] by Microsoft. With it, all you have to do is define a variable with the key in web.config if it is a simple substitute. If you need more involved transformation you can specify that too.

Henotheism answered 10/3, 2020 at 4:7 Comment(1)
I also need to replace values in webconfig file and also used replace token task for that, but still I have a little confusion, after tokenization implemented on actual main web.Config file which is also used by developers and also added token, if i add test = '#{token}#' than developers will not able to run the application because values changed with #{}# Is their any way that we can replace values without 'Replace token'Auramine
S
1

Since I had edge case, where I got 405 status on PUT and DELETE as seen here: WebAPI Delete not working - 405 Method Not Allowed

which required me to change web.config file that is created only when project is released. So I needed to insert couple of lines of code in web.config like:

    <modules>
        <remove name="WebDAVModule" />
    </modules>

and few more.

My answer is based on @Shayki Abramczyk one, I think it offers another, updated, take on this issue. As his answer did not work fully for me, and for someone who is not professional in field of DevOps, rather programmer that wanted to automate the CI-CD stuff.

Issue I think is present nowadays is that line:

cd $env:Agent_ReleaseDirectory

is not navigating to proper folder. You still need to navigate to the folder and drop where your zip file is like so: cd _Your.Project-CI\drop

So start by adding another PowerShell component in your release pipeline like so:

enter image description here

And add following code to it:

# cd to the agent artifacts directory (where the zip file exist)
cd $env:Agent_ReleaseDirectory
cd _Your.Project-CI\drop
$fileToEdit = "web.config"


[Reflection.Assembly]::LoadWithPartialName("System.IO.Compression.FileSystem");
# Open zip and find the particular file (assumes only one inside the Zip file)
$zipfileName = dir -filter '*.zip'

$zip =  [System.IO.Compression.ZipFile]::Open($zipfileName.FullName,"Update")


$configFile = $zip.Entries.Where({$_.name -like $fileToEdit})

# Read the contents of the file
$desiredFile = [System.IO.StreamReader]($configFile).Open()
$text = $desiredFile.ReadToEnd()
$desiredFile.Close()
$desiredFile.Dispose()

$contentToAdd1 = @'
    <system.webServer>
    <modules>
    <remove name="WebDAVModule" />
    </modules>
'@
#$text[3] = $text[3] -replace '<system.webServer>',$contentToAdd1
$text = $text -replace '<system.webServer>',$contentToAdd1
 
$contentToAdd2 = @'
    <handlers>
    <remove name="WebDAV" />
    <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
    <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,PUT,DELETE,DEBUG" type="System.Web.Handlers.TransferRequestHandler" resourceType="Unspecified" requireAccess="Script" preCondition="integratedMode,runtimeVersionv4.0" responseBufferLimit="0" />
'@
# $text[4] = $text[4] -replace '<handlers>',$contentToAdd2
$text = $text -replace '<handlers>',$contentToAdd2


#update file with new content
$desiredFile = [System.IO.StreamWriter]($configFile).Open()
$desiredFile.BaseStream.SetLength(0)

# Insert the $text to the file and close
$desiredFile.Write($text)
$desiredFile.Flush()
$desiredFile.Close()

# Write the changes and close the zip file
$zip.Dispose()

Only thing that is left to do is to replace: cd _Your.Project-CI\drop with your project name e.g. cd _Weather.Front-CI\drop.

Sacellum answered 15/8, 2022 at 12:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.