jsonlinuxshellhttpazure-devops

Preserving line breaks and tabs when sending data using JSON via HTTP PUT


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.


Solution

  • 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
    

    enter image description here

    enter image description here