Skip to content
Open
Changes from 7 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 108 additions & 5 deletions .pipeline/templates/validation-stages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,110 @@ parameters:
default: true

stages:
- stage: EvaluateDuplicate
displayName: Evaluate PR duplicate
condition: and(eq(variables['Build.Reason'], 'PullRequest'), eq('${{ parameters.RunFuzz }}', 'false'), eq('${{ parameters.RunLongHaul }}', 'false'))
jobs:
- job: Evaluate
displayName: Check prior successful PR validation
pool:
name: RUST-1ES-POOL-WUS3
demands:
- imageOverride -equals RUST-1ES-UBUSLIM
steps:
- bash: |
set -euo pipefail

if [ -z "${SYSTEM_ACCESSTOKEN:-}" ]; then
echo "##vso[task.logissue type=warning]System.AccessToken is unavailable; continuing with full validation."
echo "##vso[task.setvariable variable=skipDuplicate;isOutput=true]false"
exit 0
fi

python3 - <<'PY'
import json
import os
import urllib.parse
import urllib.request

collection_uri = os.environ["SYSTEM_COLLECTIONURI"]
team_project = os.environ["SYSTEM_TEAMPROJECT"]
definition_id = os.environ["SYSTEM_DEFINITIONID"]
current_build_id = int(os.environ["BUILD_BUILDID"])
source_branch = os.environ["SYSTEM_PULLREQUEST_SOURCEBRANCH"]
source_commit = os.environ["SYSTEM_PULLREQUEST_SOURCECOMMITID"]
token = os.environ["SYSTEM_ACCESSTOKEN"]
# 200 keeps API payloads small while covering repeated draft/ready transitions on busy PRs.
# If a PR exceeds this window, the guard falls back to full validation (safe false negative).
max_candidates = "200"

query = urllib.parse.urlencode(
{
"definitions": definition_id,
"reasonFilter": "pullRequest",
"statusFilter": "completed",
"resultFilter": "succeeded",
"branchName": source_branch,
"queryOrder": "finishTimeDescending",
"$top": max_candidates,
"api-version": "7.1",
}
)
url = f"{collection_uri}{team_project}/_apis/build/builds?{query}"
headers = {"Authorization": "Bearer " + token}
request = urllib.request.Request(url, headers=headers)
try:
with urllib.request.urlopen(request) as response:
payload = json.load(response)
except Exception as exc:
print(
f"##vso[task.logissue type=warning]Failed to query prior PR validation runs ({type(exc).__name__}: {exc}). Continuing with full validation."
)
print("##vso[task.setvariable variable=skipDuplicate;isOutput=true]false")
raise SystemExit(0)

matching_run = None
for build in payload.get("value", []):
build_id = int(build.get("id", 0))
if build_id == current_build_id:
continue

trigger_info = build.get("triggerInfo", {})
# Azure DevOps Build API reports the PR head commit SHA under triggerInfo.pr.sourceSha.
prior_source_commit = trigger_info.get("pr.sourceSha")
if prior_source_commit == source_commit:
matching_run = build
break

if matching_run:
matching_run_id = matching_run.get("id", "unknown")
print(
f"PR head {source_commit} already validated by run {matching_run_id}; skipping duplicate stages."
)
print("##vso[task.setvariable variable=skipDuplicate;isOutput=true]true")
else:
print(f"No successful prior validation run found for PR head {source_commit}; continuing.")
print("##vso[task.setvariable variable=skipDuplicate;isOutput=true]false")
PY
name: SetDuplicateState
displayName: Check duplicate PR head commit
env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)

- stage: Build
displayName: Build Stage
condition: and(eq('${{ parameters.RunFuzz }}', 'false'), eq('${{ parameters.RunLongHaul }}', 'false'))
dependsOn:
- EvaluateDuplicate
condition: >-
and(
succeeded(),
eq('${{ parameters.RunFuzz }}', 'false'),
eq('${{ parameters.RunLongHaul }}', 'false'),
or(
ne(variables['Build.Reason'], 'PullRequest'),
ne(stageDependencies.EvaluateDuplicate.Evaluate.outputs['SetDuplicateState.skipDuplicate'], 'true')
)
)
Comment thread
David-Engel marked this conversation as resolved.
jobs:
- job: Build_Windows
displayName: Build Windows
Expand Down Expand Up @@ -228,8 +329,9 @@ stages:
# Kerberos tests for PRs (fast - 2 distros: ubuntu22 + alpine318)
- stage: Kerberos_Test_PR
displayName: Kerberos Test (PR)
dependsOn: [] # Run in parallel with Build stage
condition: and(succeeded(), eq(variables['Build.Reason'], 'PullRequest'), eq('${{ parameters.RunFuzz }}', 'false'), eq('${{ parameters.RunLongHaul }}', 'false'))
dependsOn:
- EvaluateDuplicate
condition: and(succeeded(), eq(variables['Build.Reason'], 'PullRequest'), eq('${{ parameters.RunFuzz }}', 'false'), eq('${{ parameters.RunLongHaul }}', 'false'), ne(stageDependencies.EvaluateDuplicate.Evaluate.outputs['SetDuplicateState.skipDuplicate'], 'true'))
Comment thread
David-Engel marked this conversation as resolved.
Outdated
jobs:
- template: kerberos-test-template.yml
parameters:
Expand Down Expand Up @@ -355,8 +457,9 @@ stages:
fuzzTarget: fuzz_bulk_copy

- stage: Build_mssql_python
dependsOn: []
condition: and(eq(variables['Build.Reason'], 'PullRequest'), eq('${{ parameters.RunFuzz }}', 'false'), eq('${{ parameters.RunLongHaul }}', 'false'))
dependsOn:
- EvaluateDuplicate
condition: and(succeeded(), eq(variables['Build.Reason'], 'PullRequest'), eq('${{ parameters.RunFuzz }}', 'false'), eq('${{ parameters.RunLongHaul }}', 'false'), ne(stageDependencies.EvaluateDuplicate.Evaluate.outputs['SetDuplicateState.skipDuplicate'], 'true'))
Comment thread
David-Engel marked this conversation as resolved.
Outdated
displayName: Build mssql-python
jobs:
- job: Build_mssql_python_Linux
Expand Down
Loading