You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure Pipeline调用DevOps API更新Wiki页面失败求助

问题分析与修复方案

核心问题排查

  1. 路径编码错误导致更新目标不匹配
    你在更新请求中使用了硬编码的URL编码路径$pg="%2FBranch%+auditor%2FDevelop",这种编码方式和Azure DevOps API期望的格式不一致(尤其是空格的%+编码与标准%20编码差异),导致API未找到目标页面,反而静默创建了新页面(PUT请求在路径不存在时会执行创建),但你误以为是更新原页面。

  2. 注释导致变量未初始化(潜在问题)
    代码中$pageDetails = $response.Content | ConvertFrom-Json被注释,导致$currentVersion = $pageDetails.version完全无效,虽未直接影响更新操作,但会干扰调试信息准确性,后续扩展代码时可能引发问题。

  3. ETag未处理引号
    Azure DevOps返回的ETag通常带有双引号(例如"xxxxxx"),直接传入If-Match头会导致ETag匹配失败,触发PUT请求的创建逻辑而非更新逻辑。

  4. 未验证实际操作结果
    仅通过Invoke-RestMethod无异常判断成功,但实际可能执行的是创建操作而非更新,需要验证响应中的页面ID是否为目标ID(769)。


修复后的代码

$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 = $encodedToken
                  Accept = "application/json"
              } `
              -Method Get

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

    # 处理ETag的数组格式和引号
    if ($etag -is [System.Array]) {
        $etag = $etag[0]
    }
    $etag = $etag.Trim('"') # 移除ETag的双引号
    Write-Host "eTag: $etag"

    # 解析页面详情,验证目标路径
    $pageDetails = $response.Content | ConvertFrom-Json
    $currentVersion = $pageDetails.version
    Write-Host "currentVersion: $currentVersion"
    Write-Host "Target Page Path: $($pageDetails.path)"

    # 新内容
    $newContent = @"
## This text was written during a pipeline run.
"@

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

    # 构建请求体
    $requestBody = @{
        content = $newContent
    } | ConvertTo-Json -Depth 10 -Compress
    
    Write-Host "Request body: $requestBody"

    # --- 执行更新操作 ---
    Write-Host "`n--- Step 3: Update the Page ---"

    try {
        # 使用GET请求返回的原始路径,进行标准URL编码
        $pg = $pageDetails.path
        $encodedPath = [Uri]::EscapeDataString($pg)
        $updateUrl = "https://dev.azure.com/$(organization)/$(project)/_apis/wiki/wikis/$(wikiIdentifier)/pages?path=$encodedPath&api-version=7.1"
        Write-Host "Update URL: $updateUrl"

        Write-Host "Updating wiki page..."

        # 使用Invoke-WebRequest获取明确响应信息
        $updateResponse = Invoke-WebRequest -Uri $updateUrl `
            -Headers @{ 
                Authorization = $encodedToken
                Accept        = "application/json"
                "Content-Type" = "application/json"
                "If-Match"     = $etag
            } `
            -Method Put -Body $requestBody

        Write-Host "Page update status code: $($updateResponse.StatusCode)"
        $updateResult = $updateResponse.Content | ConvertFrom-Json
        Write-Host "Updated Page ID: $($updateResult.id)"
        
        # 验证是否更新了目标页面
        if ($updateResult.id -eq 769) {
            Write-Host "Successfully updated target page (ID: 769)"
        } else {
            Write-Host "Warning: Updated page ID ($($updateResult.id)) does not match target ID (769) - check if new page was created"
        }
    } 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
    }
}

关键调整说明

  • 路径验证与编码:直接使用GET请求返回的$pageDetails.path作为目标路径,并用[Uri]::EscapeDataString进行标准URL编码,确保路径完全匹配目标页面。
  • ETag处理:添加$etag = $etag.Trim('"')移除ETag的双引号,保证If-Match头格式符合API要求。
  • 响应验证:改用Invoke-WebRequest获取明确的响应状态码和结果,验证更新的页面ID是否为目标ID(769),避免误判操作类型。
  • 修复变量初始化:取消注释页面详情解析代码,确保调试信息完整,同时验证获取的页面路径与硬编码路径是否一致。

内容的提问来源于stack exchange,提问作者cdrrr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 03:28:12