azure-devopsazure-pipelines

Azure Pipeline - update to wiki page


I'm trying to update a wiki page in DevOps API via a pipeline. Here's my code:

            $fullUrl = "https://dev.azure.com/$(organization)/$(project)/_apis/wiki/wikis/$(wikiIdentifier)/pages/769?includeContent=True&api-version=7.1"

            Write-Host "Full URL: $fullUrl"
            try {

              Write-Host "`n--- Step 1: Fetch Page Metadata and Current Version ---"
              Write-Host "GET URL: $fullUrl"

                $encodedToken = "Basic " + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$(token)"))

                $response = Invoke-WebRequest -Uri $fullUrl `
                          -Headers @{ 
                              Authorization = "Basic " + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$(token)"))
                              Accept = "application/json"
                          } `
                          -Method Get

                            $etag = $response.Headers["ETag"]
                
                Write-Host "Status Code: $($response.StatusCode)"

                # Fix: Ensure ETag is a string (grab first element if array)
                if ($etag -is [System.Array]) {
                    $etag = $etag[0]
                }

                Write-Host "eTag: $etag"

                # $pageDetails = $response.Content | ConvertFrom-Json
                $currentVersion = $pageDetails.version

                Write-Host "currentVersion: $currentVersion"

                --- New Content ---
                $newContent = @"
                  ## This text was written during a pipeline run.
                "@

                Write-Host "`n--- Step 2: Prepare Request Body ---"

                # Build the request body
                $requestBody = @{
                    content = $newContent
                } | ConvertTo-Json -Depth 10 -Compress
                
                Write-Host "Request body: $requestBody"

                # --- Perform the PUT (Update) ---
                Write-Host "`n--- Step 3: Update the Page ---"

                try {
                    $pg="%2FBranch%+auditor%2FDevelop"

                    Write-Host "Updating wiki page..."

                    $upsertCommand = Invoke-RestMethod -Uri "https://dev.azure.com/$(organization)/$(project)/_apis/wiki/wikis/$(wikiIdentifier)/pages?path=$pg&api-version=7.1" `
                        -Headers @{ 
                            Authorization = "Basic $encodedToken"
                            Accept        = "application/json"
                            "Content-Type" = "application/json"
                            "If-Match"     = $etag
                        } `
                        -Method Put -Body $requestBody

                    Write-Host "Page upsert status code: 200 (Assuming success if no exception)"
                } catch {
                    Write-Host "Failed to update page: $($_.Exception.Message)"
                    if ($_.Exception.Response) {
                        $responseStream = $_.Exception.Response.GetResponseStream()
                        $reader = New-Object System.IO.StreamReader($responseStream)
                        $responseBody = $reader.ReadToEnd()
                        Write-Host "Response body: $responseBody"
                    }
                    throw
                }

The output of the pipeline run is:

--- Step 3: Update the Page ---
Updating wiki page...
Page upsert status code: 200 (Assuming success if no exception)

Point is that my page does not get updated. If I run the same block code in PowerShell ISE, the page gets updated.

I get the etag back after fetching the page and I really don't understand what am I missing here? Can anyone indicate what might be wrong and needs improvement/adjustment? Thanks


Solution

  • The reason for the issue is that the REST API in your step3 failed to authenticate.

    In your step3, your Authorization is defined as Authorization = "Basic $encodedToken". However, Authorization can't read the value of $encodedToken. If you print the response $upsertCommand, you will see the result as shown below: enter image description here

    Modify the Authorization header in your step3 to Authorization = $($encodedToken), then it should work as expected.

                        $upsertCommand = Invoke-RestMethod -Uri "https://dev.azure.com/$(organization)/$(project)/_apis/wiki/wikis/$(wikiIdentifier)/pages?path=$pg&api-version=7.1" `
                            -Headers @{ 
                                Authorization = $($encodedToken)
                                Accept        = "application/json"
                                "Content-Type" = "application/json"
                                "If-Match"     = $etag
                            } `
                            -Method Put -Body $requestBody
    

    You can also change the Authorization in your step1 to Authorization = $($encodedToken).