8.5 KiB
Azure DevOps REST API Reference for vcpkg CI
Base URL
https://dev.azure.com/vcpkg/public/_apis
All endpoints below are appended to this base. The vcpkg/public project is publicly readable — no Authorization header is required.
API Version
Always append ?api-version=7.0 (or include it in query strings).
Build Endpoints
Get Build Details
GET https://dev.azure.com/{org}/{project}/_apis/build/builds/{buildId}?api-version=7.0
Response fields:
{
"id": 129315,
"buildNumber": "20240315.1",
"status": "completed",
"result": "failed",
"reason": "pullRequest",
"sourceBranch": "refs/pull/12345/merge",
"sourceVersion": "abc123def456...",
"requestedFor": { "displayName": "Jane Developer" },
"startTime": "2024-03-15T10:00:00Z",
"finishTime": "2024-03-15T14:30:00Z",
"definition": { "name": "vcpkg.CI" },
"_links": {
"web": { "href": "https://dev.azure.com/vcpkg/public/_build/results?buildId=129315" }
}
}
result values: succeeded | failed | partiallySucceeded | canceled
reason values: pullRequest | schedule | manual | individualCI | batchedCI
Get Build Timeline
GET https://dev.azure.com/{org}/{project}/_apis/build/builds/{buildId}/timeline?api-version=7.0
Returns all stages, jobs, tasks and their results.
Response structure:
{
"records": [
{
"id": "guid",
"parentId": "parent-guid-or-null",
"type": "Job",
"name": "x64_windows",
"displayName": "x64_windows",
"state": "completed",
"result": "failed",
"startTime": "2024-03-15T10:05:00Z",
"finishTime": "2024-03-15T12:15:00Z",
"log": {
"id": 42,
"type": "Container",
"url": "https://dev.azure.com/vcpkg/public/_apis/build/builds/129315/logs/42"
},
"errorCount": 1,
"warningCount": 0
}
]
}
type values: Stage | Phase | Job | Task
result values: succeeded | failed | skipped | canceled | succeededWithIssues
To find failed jobs:
failed_jobs = [r for r in records if r['type'] == 'Job' and r['result'] == 'failed']
Job names map to triplets (underscores in job names, hyphens in triplets):
x64_windows→x64-windowsx64_windows_static→x64-windows-staticarm64_osx→arm64-osxx64_linux→x64-linuxarm_neon_android→arm-neon-android
Get a Specific Log
GET https://dev.azure.com/{org}/{project}/_apis/build/builds/{buildId}/logs/{logId}?api-version=7.0
Returns plain text of the log. Use this to read the "*** Test Modified Ports" task log, which contains REGRESSION: lines for all failures including those without artifact logs (e.g., FILE_CONFLICTS).
Finding the right log ID: Look up the task record in the timeline response — the log.id field on the "*** Test Modified Ports" task record gives the log ID. Alternatively, use log.url directly.
Scanning for REGRESSION lines:
$logText = Invoke-RestMethod "https://dev.azure.com/{org}/{project}/_apis/build/builds/{buildId}/logs/{logId}?api-version=7.0"
$logText -split "`n" | Where-Object { $_ -match '^REGRESSION:' }
Example output:
REGRESSION: kf6i18n:x64-windows failed with FILE_CONFLICTS. If expected, add kf6i18n:x64-windows=fail to .../ci.baseline.txt.
REGRESSION: kf6itemmodels:x64-windows failed with FILE_CONFLICTS. If expected, add kf6itemmodels:x64-windows=fail to .../ci.baseline.txt.
REGRESSION: v8:x64-windows failed with BUILD_FAILED. If expected, add v8:x64-windows=fail to .../ci.baseline.txt.
⚠️
FILE_CONFLICTSfailures do NOT produce failure log artifacts. The only record of them is in this step log. Always scan all "Test Modified Ports" task logs before relying on artifacts alone.
List All Logs
GET https://dev.azure.com/{org}/{project}/_apis/build/builds/{buildId}/logs?api-version=7.0
Artifact Endpoints
List All Artifacts
GET https://dev.azure.com/{org}/{project}/_apis/build/builds/{buildId}/artifacts?api-version=7.0
Response:
{
"count": 39,
"value": [
{
"id": 1107682,
"name": "failure logs for x64-windows",
"source": "7922e5c4-...",
"resource": {
"type": "PipelineArtifact",
"data": "DCCD3D9C96CE79A758B255BD87397A07371B8394EE52F6BFF35346C144D63F3501",
"properties": {
"RootId": "196FDE3B...",
"artifactsize": "8586850",
"HashType": "DEDUP1024K",
"DomainId": "0"
},
"url": "https://dev.azure.com/vcpkg/.../_apis/build/builds/129315/artifacts?artifactName=failure%20logs%20for%20x64-windows&api-version=7.0",
"downloadUrl": "https://artprodwus21.artifacts.visualstudio.com/.../_apis/artifact/{base64hash}/content?format=zip"
}
}
]
}
⚠️
resource.typeis"PipelineArtifact", not"Container". The Container listing API (GET /_apis/resources/Containers/{id}) does not work for these artifacts. Useresource.downloadUrldirectly to download the ZIP.
Artifact naming conventions:
| Artifact Name Pattern | Contents | Priority |
|---|---|---|
failure logs for {triplet} |
Per-port build failure log directories | High — primary source |
file lists for {triplet} |
Installed file manifests | Low — skip unless needed |
format.diff |
Formatting/manifest diff | Medium — indicates PR format issues |
z azcopy logs for {triplet} |
Binary cache transfer logs | Low — infrastructure only |
Download Artifact ZIP (Confirmed Working)
Use the downloadUrl from the artifact listing. It resolves to an artprodwus21.artifacts.visualstudio.com URL. web_fetch cannot download binary ZIPs — use PowerShell:
# $downloadUrl = value from resource.downloadUrl in the artifacts list response
Invoke-WebRequest -Uri $downloadUrl -OutFile "$tmpDir\{triplet}.zip" -UseBasicParsing
Expand-Archive "$tmpDir\{triplet}.zip" -DestinationPath "$tmpDir\{triplet}" -Force
# List failing ports — each is a subdirectory inside the artifact folder
$root = "$tmpDir\{triplet}\failure logs for {triplet}"
Get-ChildItem $root -Directory | Select-Object -ExpandProperty Name
The ZIP always contains one top-level folder named exactly "failure logs for {triplet}".
Inside that folder, each failing port has its own subdirectory named after the port.
❌ The Container API (
GET /_apis/resources/Containers/{containerId}) does not work forPipelineArtifacttype. Do not attempt to use it.
Test Results Endpoints
List Test Runs for a Build
GET https://dev.azure.com/{org}/{project}/_apis/test/runs?buildId={buildId}&api-version=7.0
Response:
{
"value": [
{
"id": 9876,
"name": "x64-windows",
"state": "Completed",
"totalTests": 500,
"passedTests": 497,
"failedTests": 3
}
]
}
Get Test Run Results
GET https://dev.azure.com/{org}/{project}/_apis/test/runs/{runId}/results?api-version=7.0&outcomes=Failed
Filter by outcomes=Failed to get only failures.
Response includes:
testCaseName— usuallyportname:tripletoutcome—FailederrorMessage— short error descriptionstackTrace— full failure output
URL Parsing
Given https://dev.azure.com/vcpkg/public/_build/results?buildId=129315&view=results:
| Component | Value | How to Extract |
|---|---|---|
| Organization | vcpkg |
4th path segment |
| Project | public |
5th path segment |
| Build ID | 129315 |
buildId query parameter |
# Python example
from urllib.parse import urlparse, parse_qs
url = "https://dev.azure.com/vcpkg/public/_build/results?buildId=129315&view=results"
parts = urlparse(url)
segments = parts.path.strip('/').split('/')
org = segments[0] # "vcpkg"
project = segments[1] # "public"
build_id = parse_qs(parts.query)['buildId'][0] # "129315"
Rate Limits and Auth
- Public projects (like
vcpkg/public): No authentication needed; anonymous access is allowed - Rate limit: ~200 requests per minute for anonymous; increase by adding a PAT as Bearer token if needed
- PAT header:
Authorization: Basic {base64(":pat_token")}