Skip to content

Commit 622aeed

Browse files
committed
ci: add workflow to create pipeline to test
1 parent 5aba541 commit 622aeed

File tree

1 file changed

+180
-0
lines changed

1 file changed

+180
-0
lines changed

.github/workflows/ci-pull-request.yml

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ on:
44
pull_request:
55
branches:
66
- main
7+
workflow_dispatch:
78

89
permissions:
910
contents: write
@@ -54,3 +55,182 @@ jobs:
5455
exit 1
5556
fi
5657
echo "new_version=$NEW_VERSION" >> "$GITHUB_OUTPUT"
58+
59+
60+
ado-pr-ephemeral:
61+
runs-on: ubuntu-latest
62+
env:
63+
YAML_PATH: .azure-pipelines.yml
64+
PR_NUMBER: ${{ github.event.pull_request.number }}
65+
PR_BRANCH: ${{ github.head_ref }}
66+
PR_SHA: ${{ github.event.pull_request.head.sha }}
67+
PIPELINE_NAME: pr-${{ github.event.pull_request.number }}-${{ github.run_id }}
68+
69+
steps:
70+
- uses: actions/checkout@v4
71+
72+
- name: Azure login (OIDC)
73+
uses: azure/login@v2
74+
with:
75+
client-id: ${{ secrets.AZURE_APPLICATION_CLIENT_ID }}
76+
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
77+
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
78+
79+
- name: Install jq & curl
80+
run: sudo apt-get update -y && sudo apt-get install -y jq curl
81+
82+
- name: Get Azure DevOps AAD token
83+
id: token
84+
run: |
85+
ADO_TOKEN=$(az account get-access-token --resource https://app.vssps.visualstudio.com/ --query accessToken -o tsv)
86+
if [ -z "$ADO_TOKEN" ]; then echo "No token for Azure DevOps"; exit 1; fi
87+
echo "::add-mask::$ADO_TOKEN"
88+
echo "ADO_TOKEN=$ADO_TOKEN" >> $GITHUB_ENV
89+
90+
- name: Autodetect Azure DevOps organization (if not provided)
91+
id: org
92+
env:
93+
ADO_TOKEN: ${{ env.ADO_TOKEN }}
94+
run: |
95+
if [ -n "${AZDO_ORG}" ]; then
96+
echo "Using AZDO_ORG=${AZDO_ORG} (provided)"; exit 0
97+
fi
98+
ACCOUNTS=$(curl -sS -H "Authorization: Bearer ${ADO_TOKEN}" \
99+
"https://app.vssps.visualstudio.com/_apis/accounts?api-version=7.1")
100+
echo "$ACCOUNTS"
101+
COUNT=$(echo "$ACCOUNTS" | jq '.count')
102+
if [ "$COUNT" -eq 0 ]; then
103+
echo "This user does not belong to any Azure DevOps org."; exit 1
104+
fi
105+
if [ "$COUNT" -gt 1 ]; then
106+
echo "Multiple orgs detected. Export AZDO_ORG with one of those and retry:"; \
107+
echo "$ACCOUNTS" | jq -r '.value[] | "\(.accountName) (\(.accountId))"'; exit 1
108+
fi
109+
AZDO_ORG_AUTO=$(echo "$ACCOUNTS" | jq -r '.value[0].accountName')
110+
echo "AZDO_ORG=$AZDO_ORG_AUTO" >> $GITHUB_ENV
111+
echo "Detected AZDO_ORG=${AZDO_ORG_AUTO}"
112+
113+
- name: Autodetect Azure DevOps project (if not provided)
114+
id: proj
115+
env:
116+
ADO_TOKEN: ${{ env.ADO_TOKEN }}
117+
run: |
118+
ORG="${AZDO_ORG:-${{ env.AZDO_ORG }}}"
119+
PROJS=$(curl -sS -H "Authorization: Bearer ${ADO_TOKEN}" \
120+
"https://dev.azure.com/${ORG}/_apis/projects?api-version=7.1")
121+
echo "$PROJS"
122+
COUNT=$(echo "$PROJS" | jq '.count')
123+
if [ "$COUNT" -eq 0 ]; then
124+
echo "No projects detected in org ${ORG}."; exit 1
125+
fi
126+
if [ -n "${AZDO_PROJECT}" ]; then
127+
echo "Using AZDO_PROJECT=${AZDO_PROJECT} (provided)"
128+
else
129+
if [ "$COUNT" -gt 1 ]; then
130+
echo "Multiple projects detected. Export AZDO_PROJECT with one of those and try again:"; \
131+
echo "$PROJS" | jq -r '.value[] | .name'; exit 1
132+
fi
133+
AZDO_PROJECT_AUTO=$(echo "$PROJS" | jq -r '.value[0].name')
134+
echo "AZDO_PROJECT=$AZDO_PROJECT_AUTO" >> $GITHUB_ENV
135+
echo "Detected AZDO_PROJECT=${AZDO_PROJECT_AUTO}"
136+
fi
137+
138+
- name: Find a GitHub Service Connection
139+
id: sc
140+
env:
141+
ADO_TOKEN: ${{ env.ADO_TOKEN }}
142+
run: |
143+
ORG="${AZDO_ORG:-${{ env.AZDO_ORG }}}"
144+
PROJ="${AZDO_PROJECT:-${{ env.AZDO_PROJECT }}}"
145+
LIST=$(curl -sS -H "Authorization: Bearer ${ADO_TOKEN}" \
146+
"https://dev.azure.com/${ORG}/${PROJ}/_apis/serviceendpoint/endpoints?api-version=7.1")
147+
echo "$LIST"
148+
echo "$LIST" | jq -r '.value[] | {id,type:.type,name:.name}'
149+
SC_ID=$(echo "$LIST" | jq -r '.value[] | select((.type|ascii_downcase|contains("github"))) | .id' | head -n1)
150+
if [ -z "$SC_ID" ] || [ "$SC_ID" = "null" ]; then
151+
echo "No Github Service Connection detected in ${PROJ}. Create one (GitHub/GitHub App) and retry."; exit 1
152+
fi
153+
echo "sc_id=${SC_ID}" >> "$GITHUB_OUTPUT"
154+
155+
- name: Create ephemeral pipeline
156+
id: create
157+
env:
158+
ADO_TOKEN: ${{ env.ADO_TOKEN }}
159+
run: |
160+
ORG="${AZDO_ORG:-${{ env.AZDO_ORG }}}"
161+
PROJ="${AZDO_PROJECT:-${{ env.AZDO_PROJECT }}}"
162+
SC_ID="${{ steps.sc.outputs.sc_id }}"
163+
BODY=$(jq -n \
164+
--arg name "${PIPELINE_NAME}" \
165+
--arg folder "pr-validation" \
166+
--arg path "${YAML_PATH}" \
167+
--arg repo "${GITHUB_REPOSITORY}" \
168+
--arg scid "${SC_ID}" \
169+
'{
170+
name:$name, folder:$folder,
171+
configuration:{
172+
type:"yaml", path:$path,
173+
repository:{ type:"github", name:$repo, connection:{id:$scid} }
174+
}
175+
}')
176+
RESP=$(curl -sS -X POST -H "Authorization: Bearer ${ADO_TOKEN}" -H "Content-Type: application/json" \
177+
-d "${BODY}" "https://dev.azure.com/${ORG}/${PROJ}/_apis/pipelines?api-version=7.1")
178+
echo "$RESP" | jq .
179+
PIPELINE_ID=$(echo "$RESP" | jq -r '.id')
180+
if [ -z "$PIPELINE_ID" ] || [ "$PIPELINE_ID" = "null" ]; then echo "Create failed"; exit 1; fi
181+
echo "PIPELINE_ID=$PIPELINE_ID" >> $GITHUB_ENV
182+
183+
- name: Run pipeline for exact PR commit
184+
id: run
185+
env:
186+
ADO_TOKEN: ${{ env.ADO_TOKEN }}
187+
run: |
188+
ORG="${AZDO_ORG:-${{ env.AZDO_ORG }}}"
189+
PROJ="${AZDO_PROJECT:-${{ env.AZDO_PROJECT }}}"
190+
PIPELINE_ID="${PIPELINE_ID}"
191+
BODY=$(jq -n --arg ref "refs/heads/${PR_BRANCH}" --arg ver "${PR_SHA}" \
192+
'{resources:{repositories:{self:{refName:$ref, version:$ver}}}}')
193+
RUN=$(curl -sS -X POST -H "Authorization: Bearer ${ADO_TOKEN}" -H "Content-Type: application/json" \
194+
-d "${BODY}" "https://dev.azure.com/${ORG}/${PROJ}/_apis/pipelines/${PIPELINE_ID}/runs?api-version=7.1")
195+
echo "$RUN" | jq .
196+
RUN_ID=$(echo "$RUN" | jq -r '.id')
197+
if [ -z "$RUN_ID" ] || [ "$RUN_ID" = "null" ]; then echo "Queue failed"; exit 1; fi
198+
echo "RUN_ID=$RUN_ID" >> $GITHUB_ENV
199+
200+
- name: Wait for completion
201+
env:
202+
ADO_TOKEN: ${{ env.ADO_TOKEN }}
203+
run: |
204+
ORG="${AZDO_ORG:-${{ env.AZDO_ORG }}}"
205+
PROJ="${AZDO_PROJECT:-${{ env.AZDO_PROJECT }}}"
206+
echo "Polling run ${RUN_ID}..."
207+
while true; do
208+
R=$(curl -sS -H "Authorization: Bearer ${ADO_TOKEN}" \
209+
"https://dev.azure.com/${ORG}/${PROJ}/_apis/pipelines/${PIPELINE_ID}/runs/${RUN_ID}?api-version=7.1")
210+
STATE=$(echo "$R" | jq -r '.state')
211+
RESULT=$(echo "$R" | jq -r '.result')
212+
echo "state=$STATE result=$RESULT"
213+
if [ "$STATE" = "completed" ]; then
214+
[ "$RESULT" = "succeeded" ] && exit 0 || exit 1
215+
fi
216+
sleep 10
217+
done
218+
219+
- name: Delete ephemeral pipeline (cleanup)
220+
if: ${{ !cancelled() }}
221+
env:
222+
ADO_TOKEN: ${{ env.ADO_TOKEN }}
223+
run: |
224+
ORG="${AZDO_ORG:-${{ env.AZDO_ORG }}}"
225+
PROJ="${AZDO_PROJECT:-${{ env.AZDO_PROJECT }}}"
226+
# Resuelve build definition por nombre y bórrala
227+
DEF=$(curl -sS -H "Authorization: Bearer ${ADO_TOKEN}" \
228+
"https://dev.azure.com/${ORG}/${PROJ}/_apis/build/definitions?name=${PIPELINE_NAME}&api-version=7.1")
229+
DEF_ID=$(echo "$DEF" | jq -r '.value[0].id')
230+
if [ -n "$DEF_ID" ] && [ "$DEF_ID" != "null" ]; then
231+
curl -sS -X DELETE -H "Authorization: Bearer ${ADO_TOKEN}" \
232+
"https://dev.azure.com/${ORG}/${PROJ}/_apis/build/definitions/${DEF_ID}?api-version=7.1" \
233+
-o /dev/null -w "Deleted definition ${DEF_ID} (HTTP %{http_code})\n"
234+
else
235+
echo "No build definition found for ${PIPELINE_NAME}; nothing to delete."
236+
fi

0 commit comments

Comments
 (0)