I am using Azure DevOps and try to update a mermaid diagram automatically on a wiki page. The issue is that basic formatting is important.
::: mermaid
graph LR
linkStyle default fill:#ffffff
subgraph diagram ["Software System - System Context"]
style diagram fill:#ffffff,stroke:#ffffff
1["<div style='font-weight: bold'>Person1</div><div style='font-size: 70%; margin-top: 0px'>[Person]</div>"]
style 1 fill:#05527d,stroke:#033957,color:#ffffff
2["<div style='font-weight: bold'>Person2</div><div style='font-size: 70%; margin-top: 0px'>[Person]</div>"]
style 2 fill:#05527d,stroke:#033957,color:#ffffff
3["<div style='font-weight: bold'>Software System</div><div style='font-size: 70%; margin-top: 0px'>[Software System]</div>"]
style 3 fill:#066296,stroke:#044469,color:#ffffff
1-. "<div>Interacts</div><div style='font-size: 70%'></div>" .->3
2-. "<div>Interacts</div><div style='font-size: 70%'></div>" .->3
end
:::
The diagram is generated using structurizr and written to the file diagrams/structurizr-Diagram1.mmd in the runner.
In the pipeline, I am then reading the file and then want to place that content on a wiki page.
Placing content on the wiki page already works using the Azure DevOps API.
I am not able to get de data across properly, only as a single line of text, and I also run into issues with special characters lik ' and ". The following message is expected by the API {"content": "new wiki content"}.
Here is my current code:
val =$(<diagrams/structurizr-Diagram1.mmd)
val2=$(printf %q "$val")
json="{ \"content\" : \""$val2"\" }"
responseCreate=$(curl -X PUT -H "Content-Type: application/json" -d "$json" \
"https://feedname:$(WIKI_TOKEN)@dev.azure.com/...)
I tried all solutions I could find online and am really hitting a wall right now. Is what I am trying possible?
Alternatively, I guess , I could render a picture and upload that, or upload the knewly created file somewhere automatically and insert a link in the wikipage.
When using bash script to call the Azure DevOps REST API "Pages - Create Or Update", it seems that you cannot pass the content read directly from the file 'diagrams/structurizr-Diagram1.mmd
' into the JSON request body. You might need to convert the multiple-lines content into a single line, and escape the line break to "\n
".
However, in the bash script, I tried using sed
command to replace line break with "\n
" in the whole content, and also tried to go through line by line using a loop, but none of them can work as expected.
Finally, I changed to use PowerShell, and it can easily to work. In the PowerShell script, I go through line by line of the file content in a loop, and add a line break (`n) to the end of each line, then store all the lines as a single line into a variable. Finally, pass the the variable to the request body.
Below is my PowerShell script which can work for me:
$filePath = "./diagrams/structurizr-Diagram1.mmd"
$jsonContent = ""
Get-Content -Path $filePath | ForEach-Object {
$jsonContent += "$_`n" # Add line break to the end of each line.
}
$organization = "xxxx"
$project = "xxxx"
$wikiName = "xxxx"
$pagePath = "xxxx"
$uri = "https://dev.azure.com/${organization}/${project}/_apis/wiki/wikis/${wikiName}/pages?path=${pagePath}&api-version=7.1"
$pat = "xxxx"
$base64Token = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f "", $pat)))
$headers = @{
Authorization = "Basic $base64Token"
"Content-Type" = "application/json"
}
$body = @{content = "$jsonContent"} | ConvertTo-Json -Depth 5
Invoke-RestMethod -Method PUT -Uri $uri -Headers $headers -Body $body