Azure DevOps Server流水线更新Wiki页面报错排查
问题背景
已在Azure DevOps Server流水线中实现通过kubectl生成VPA报告CSV文件,需求是将CSV转为Markdown表格并发布到Azure Wiki,且流水线每5分钟调度更新Wiki内容。但调用Wiki REST API更新时出现以下报错:
{"$id":"1","innerException":null,"message":"One or more ancestor pages of the page '/My-Project/Operations/Infra-Optimisation/VPA-Status' does not exist.","typeName":"Microsoft.TeamFoundation.Wiki.Server.WikiAncestorPageNotFoundException, Microsoft.TeamFoundation.Wiki.Server","typeKey":"WikiAncestorPageNotFoundException","errorCode":0,"eventId":3000}
相关脚本如下:
生成CSV任务
kubectl get vpa -A -o json | jq -r '["Namespace", "AppName", "ContainerName", "LowerBoundCPU","LowerBoundMemmory", "upperBoundCPU", "upperBoundmemmory", "TargetCPU", "TargetMem"], (.items[] | [.metadata.namespace, .metadata.name] +(.status.recommendation.containerRecommendations[] | [.containerName, .lowerBound.cpu, .lowerBound.memory, .upperBound.cpu, .upperBound.memory, .target.cpu, .target.memory])) | @csv' >output.csv
CSV转Markdown表格任务
# Convert CSV to Markdown Table awk -F, 'BEGIN { OFS = "|" } { print "| " $0 " |" }' output.csv > temp.md awk 'NR==1 {print; print "|---|---|---|---|---|---|---|---|---|"} NR>1 {print}' temp.md > output.md rm temp.md
更新Wiki任务
PAT=$(System.AccessToken) URI="https://<myadoserver url>/devops/<>Collectionname>/My-Project/_apis/wiki/wikis/MyProject.wiki/pages?path=/My-Project/Operations/Infra-Optimisation/VPA%2DStatus&api-version=6.0" CONTENT=$(<output.md) curl -u ":$PAT" -X PUT "$URI" -H "Content-Type: application/json" --data "{'content': '$CONTENT'}"
错误原因
Azure DevOps Wiki的REST API使用PUT更新页面时,要求路径中所有父级页面必须已存在。当前报错说明/My-Project/Operations/Infra-Optimisation这一级或其中某个父页面尚未创建,导致无法创建/更新子页面VPA-Status。
解决方案
1. 确保所有父页面存在
- 手动创建:登录Azure DevOps Server,打开
MyProject.wiki,依次创建My-Project→Operations→Infra-Optimisation页面(已存在则跳过)。 - API批量创建:若需自动化创建父页面,可使用Wiki API的POST接口依次创建每个父级页面,示例:
# 创建Infra-Optimisation页面(假设Operations已存在) PAT=$(System.AccessToken) PARENT_URI="https://<myadoserver url>/devops/<Collectionname>/My-Project/_apis/wiki/wikis/MyProject.wiki/pages?path=/My-Project/Operations/Infra-Optimisation&api-version=6.0" curl -u ":$PAT" -X POST "$PARENT_URI" -H "Content-Type: application/json" --data '{"content": "基础设施优化页面"}'
2. 修正更新Wiki脚本的问题
原脚本存在两个潜在问题:Markdown内容中的单引号会破坏JSON格式,直接读取文件内容的换行符不符合JSON要求。修正后的脚本:
PAT=$(System.AccessToken) URI="https://<myadoserver url>/devops/<Collectionname>/My-Project/_apis/wiki/wikis/MyProject.wiki/pages?path=/My-Project/Operations/Infra-Optimisation/VPA-Status&api-version=6.0" # 转义内容中的单引号和换行符 CONTENT=$(sed "s/'/\\\'/g; s/\n/\\\n/g" output.md) # 使用标准JSON格式(双引号包裹键值) curl -u ":$PAT" -X PUT "$URI" -H "Content-Type: application/json" --data "{\"content\": \"$CONTENT\"}"
3. 设置流水线每5分钟调度
在Azure DevOps Server流水线的触发器设置中,选择计划触发器,配置CRON表达式为*/5 * * * *,实现每5分钟自动执行流水线更新Wiki。
4. 优化CSV转Markdown脚本(可选)
原脚本中表头分隔符需与CSV列数严格匹配,改为动态生成分隔符可避免列数变化时出错:
# 动态生成Markdown表格分隔符 awk -F, ' BEGIN { OFS = "|" } NR == 1 { print "| " $0 " |"; sep = ""; for (i=1; i<=NF; i++) sep = sep "|---|"; print sep; } NR > 1 { print "| " $0 " |" } ' output.csv > output.md
内容的提问来源于stack exchange,提问作者Vowneee

