Skip to content

Commit fe91d9a

Browse files
author
kevyuu
committed
Merge branch 'master' into env_map_importance_sampling
2 parents 9657c66 + 2539522 commit fe91d9a

File tree

104 files changed

+5615
-2560
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

104 files changed

+5615
-2560
lines changed

.github/workflows/build-nabla.yml

Lines changed: 302 additions & 60 deletions
Large diffs are not rendered by default.
Lines changed: 390 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,390 @@
1+
name: Promote NSC Channel
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
run_id:
7+
description: "Workflow run id that produced the NSC payload and manifests artifacts"
8+
required: true
9+
source_repo:
10+
description: "Repository that owns the source workflow run"
11+
required: true
12+
default: "Devsh-Graphics-Programming/Nabla"
13+
source_branch:
14+
description: "Expected source branch for the workflow run"
15+
required: true
16+
default: "master"
17+
target_repo:
18+
description: "Repository that should receive the manifest update PR"
19+
required: true
20+
default: "Devsh-Graphics-Programming/Nabla"
21+
target_branch:
22+
description: "Nabla branch that should receive the manifest update PR"
23+
required: true
24+
default: "master"
25+
asset_repo:
26+
description: "Repository that stores the promoted NSC channel releases"
27+
required: true
28+
default: "Devsh-Graphics-Programming/Nabla-Asset-Manifests"
29+
channel:
30+
description: "NSC manifest channel to promote"
31+
required: true
32+
default: "nsc-windows-x64-release"
33+
34+
permissions:
35+
contents: write
36+
pull-requests: write
37+
38+
jobs:
39+
promote:
40+
runs-on: ubuntu-latest
41+
env:
42+
SOURCE_REPO: ${{ inputs.source_repo }}
43+
SOURCE_BRANCH: ${{ inputs.source_branch }}
44+
TARGET_REPO: ${{ inputs.target_repo }}
45+
ASSET_REPO: ${{ inputs.asset_repo }}
46+
HEAD_REPO: ${{ github.repository }}
47+
HEAD_OWNER: ${{ github.repository_owner }}
48+
CHANNEL: ${{ inputs.channel }}
49+
TARGET_BRANCH: ${{ inputs.target_branch }}
50+
RUN_ID: ${{ inputs.run_id }}
51+
52+
steps:
53+
- name: Checkout target branch
54+
uses: actions/checkout@v6
55+
with:
56+
repository: ${{ inputs.target_repo }}
57+
ref: ${{ inputs.target_branch }}
58+
fetch-depth: 1
59+
fetch-tags: false
60+
persist-credentials: false
61+
sparse-checkout: |
62+
tools/nsc/manifests
63+
sparse-checkout-cone-mode: false
64+
65+
- name: Resolve source run metadata
66+
id: source-run
67+
env:
68+
GH_TOKEN: ${{ secrets.READ_PAT }}
69+
run: |
70+
set -euo pipefail
71+
72+
run_json="$(gh api "repos/${SOURCE_REPO}/actions/runs/${RUN_ID}")"
73+
status="$(jq -r '.status' <<<"${run_json}")"
74+
conclusion="$(jq -r '.conclusion' <<<"${run_json}")"
75+
event="$(jq -r '.event' <<<"${run_json}")"
76+
head_sha="$(jq -r '.head_sha' <<<"${run_json}")"
77+
head_branch="$(jq -r '.head_branch' <<<"${run_json}")"
78+
html_url="$(jq -r '.html_url' <<<"${run_json}")"
79+
80+
if [[ "${status}" != "completed" || "${conclusion}" != "success" ]]; then
81+
echo "Run ${RUN_ID} is not promotable: status=${status} conclusion=${conclusion}" >&2
82+
exit 1
83+
fi
84+
if [[ "${head_branch}" != "${SOURCE_BRANCH}" ]]; then
85+
echo "Run ${RUN_ID} head branch ${head_branch} does not match expected ${SOURCE_BRANCH}" >&2
86+
exit 1
87+
fi
88+
89+
release_tag="${CHANNEL}-${head_sha}"
90+
target_branch_slug="$(printf '%s' "${TARGET_BRANCH}" | tr '/._' '-' | tr -cd '[:alnum:]-')"
91+
pr_branch="ci/nsc-promote-${CHANNEL}-${target_branch_slug}"
92+
93+
{
94+
echo "source_sha=${head_sha}"
95+
echo "source_branch=${head_branch}"
96+
echo "source_event=${event}"
97+
echo "run_url=${html_url}"
98+
echo "release_tag=${release_tag}"
99+
echo "pr_branch=${pr_branch}"
100+
} >> "${GITHUB_OUTPUT}"
101+
102+
- name: Download NSC payload artifact
103+
uses: actions/download-artifact@v8
104+
with:
105+
run-id: ${{ inputs.run_id }}
106+
name: ${{ inputs.channel }}-payload
107+
path: ${{ runner.temp }}/nsc-payload
108+
github-token: ${{ secrets.READ_PAT }}
109+
repository: ${{ inputs.source_repo }}
110+
111+
- name: Download NSC manifests artifact
112+
uses: actions/download-artifact@v8
113+
with:
114+
run-id: ${{ inputs.run_id }}
115+
name: ${{ inputs.channel }}-manifests
116+
path: ${{ runner.temp }}/nsc-manifests
117+
github-token: ${{ secrets.READ_PAT }}
118+
repository: ${{ inputs.source_repo }}
119+
120+
- name: Publish release to manifest backend
121+
env:
122+
CR_PAT: ${{ secrets.CR_PAT }}
123+
READ_PAT: ${{ secrets.READ_PAT }}
124+
RELEASE_TAG: ${{ steps.source-run.outputs.release_tag }}
125+
SOURCE_SHA: ${{ steps.source-run.outputs.source_sha }}
126+
SOURCE_BRANCH: ${{ steps.source-run.outputs.source_branch }}
127+
SOURCE_EVENT: ${{ steps.source-run.outputs.source_event }}
128+
RUN_URL: ${{ steps.source-run.outputs.run_url }}
129+
run: |
130+
set -euo pipefail
131+
132+
manifests_zip="$(find "${RUNNER_TEMP}/nsc-manifests" -maxdepth 1 -type f -name '*-manifests.zip' | head -n 1)"
133+
if [[ -z "${manifests_zip}" ]]; then
134+
echo "Failed to locate manifests zip in ${RUNNER_TEMP}/nsc-manifests" >&2
135+
exit 1
136+
fi
137+
138+
source_repo_url="https://github.com/${SOURCE_REPO}"
139+
source_commit_url="${source_repo_url}/commit/${SOURCE_SHA}"
140+
updated_at="$(date -u +'%Y-%m-%dT%H:%M:%SZ')"
141+
release_token_candidates=()
142+
if [[ -n "${CR_PAT}" ]]; then
143+
release_token_candidates+=("${CR_PAT}")
144+
fi
145+
if [[ -n "${READ_PAT}" && "${READ_PAT}" != "${CR_PAT}" ]]; then
146+
release_token_candidates+=("${READ_PAT}")
147+
fi
148+
if [[ "${#release_token_candidates[@]}" -eq 0 ]]; then
149+
echo "No token is available for manifest backend release operations." >&2
150+
exit 1
151+
fi
152+
153+
notes_file="${RUNNER_TEMP}/nsc-release-notes.md"
154+
cat > "${notes_file}" <<EOF
155+
Promoted NSC payload from [\`${SOURCE_REPO}\`](${source_repo_url}).
156+
157+
- source commit: [\`${SOURCE_SHA}\`](${source_commit_url})
158+
- source branch: \`${SOURCE_BRANCH}\`
159+
- source event: \`${SOURCE_EVENT}\`
160+
- source run: [\`${RUN_ID}\`](${RUN_URL})
161+
162+
Updated at \`${updated_at}\`.
163+
EOF
164+
165+
release_exists=false
166+
release_id=""
167+
release_token="${release_token_candidates[0]}"
168+
for candidate in "${release_token_candidates[@]}"; do
169+
if release_json="$(GH_TOKEN="${candidate}" gh api "repos/${ASSET_REPO}/releases/tags/${RELEASE_TAG}" 2>/dev/null)"; then
170+
release_exists=true
171+
release_id="$(jq -r '.id' <<<"${release_json}")"
172+
release_token="${candidate}"
173+
break
174+
fi
175+
done
176+
export GH_TOKEN="${release_token}"
177+
178+
if [[ "${release_exists}" == "false" ]]; then
179+
release_created=false
180+
for candidate in "${release_token_candidates[@]}"; do
181+
if GH_TOKEN="${candidate}" gh release create "${RELEASE_TAG}" \
182+
--repo "${ASSET_REPO}" \
183+
--title "${RELEASE_TAG}" \
184+
--notes-file "${notes_file}"; then
185+
release_token="${candidate}"
186+
export GH_TOKEN="${release_token}"
187+
release_created=true
188+
break
189+
fi
190+
done
191+
if [[ "${release_created}" != "true" ]]; then
192+
echo "Failed to create release ${RELEASE_TAG} in ${ASSET_REPO}." >&2
193+
exit 1
194+
fi
195+
196+
mapfile -d '' payload_assets < <(find "${RUNNER_TEMP}/nsc-payload" -maxdepth 1 -type f -print0)
197+
if [[ "${#payload_assets[@]}" -eq 0 ]]; then
198+
echo "No payload assets found in ${RUNNER_TEMP}/nsc-payload" >&2
199+
exit 1
200+
fi
201+
202+
payload_assets+=("${manifests_zip}")
203+
gh release upload "${RELEASE_TAG}" "${payload_assets[@]}" --repo "${ASSET_REPO}"
204+
else
205+
echo "Release ${RELEASE_TAG} already exists in ${ASSET_REPO}. Reusing immutable release."
206+
patch_file="${RUNNER_TEMP}/nsc-release-patch.json"
207+
jq -n \
208+
--arg name "${RELEASE_TAG}" \
209+
--rawfile body "${notes_file}" \
210+
'{name:$name, body:$body}' > "${patch_file}"
211+
release_refreshed=false
212+
for candidate in "${release_token_candidates[@]}"; do
213+
if GH_TOKEN="${candidate}" gh api \
214+
--method PATCH \
215+
"repos/${ASSET_REPO}/releases/${release_id}" \
216+
--input "${patch_file}" >/dev/null 2>&1; then
217+
release_token="${candidate}"
218+
export GH_TOKEN="${release_token}"
219+
release_refreshed=true
220+
break
221+
fi
222+
done
223+
if [[ "${release_refreshed}" != "true" ]]; then
224+
echo "Failed to refresh notes for existing ${RELEASE_TAG}. Provide a token with release edit permissions." >&2
225+
exit 1
226+
fi
227+
fi
228+
229+
- name: Update manifests and tag pin
230+
id: manifest-diff
231+
env:
232+
RELEASE_TAG: ${{ steps.source-run.outputs.release_tag }}
233+
run: |
234+
set -euo pipefail
235+
236+
manifests_zip="$(find "${RUNNER_TEMP}/nsc-manifests" -maxdepth 1 -type f -name '*-manifests.zip' | head -n 1)"
237+
if [[ -z "${manifests_zip}" ]]; then
238+
echo "Failed to locate manifests zip in ${RUNNER_TEMP}/nsc-manifests" >&2
239+
exit 1
240+
fi
241+
242+
extract_root="${RUNNER_TEMP}/nsc-manifests-extracted"
243+
rm -rf "${extract_root}"
244+
mkdir -p "${extract_root}"
245+
unzip -q "${manifests_zip}" -d "${extract_root}"
246+
247+
channel_root="${extract_root}/${CHANNEL}"
248+
if [[ ! -d "${channel_root}" ]]; then
249+
echo "Expected extracted channel root ${channel_root} does not exist" >&2
250+
exit 1
251+
fi
252+
253+
repo_manifest_root="tools/nsc/manifests"
254+
rm -rf "${repo_manifest_root:?}/${CHANNEL}"
255+
mkdir -p "${repo_manifest_root}"
256+
cp -R "${channel_root}" "${repo_manifest_root}/"
257+
printf '%s\n' "${RELEASE_TAG}" > "${repo_manifest_root}/${CHANNEL}.tag"
258+
259+
if git diff --quiet -- "${repo_manifest_root}"; then
260+
echo "has_changes=false" >> "${GITHUB_OUTPUT}"
261+
else
262+
echo "has_changes=true" >> "${GITHUB_OUTPUT}"
263+
fi
264+
265+
- name: Commit and push promotion branch
266+
if: steps.manifest-diff.outputs.has_changes == 'true'
267+
env:
268+
PUSH_BUILTIN_TOKEN: ${{ github.token }}
269+
PR_PAT: ${{ secrets.PR_PAT }}
270+
READ_PAT: ${{ secrets.READ_PAT }}
271+
CR_PAT: ${{ secrets.CR_PAT }}
272+
PR_BRANCH: ${{ steps.source-run.outputs.pr_branch }}
273+
SOURCE_SHA: ${{ steps.source-run.outputs.source_sha }}
274+
run: |
275+
set -euo pipefail
276+
277+
push_token="${PUSH_BUILTIN_TOKEN}"
278+
if [[ "${TARGET_REPO}" != "${HEAD_REPO}" ]]; then
279+
push_token="${PR_PAT}"
280+
if [[ -z "${push_token}" ]]; then
281+
push_token="${READ_PAT}"
282+
fi
283+
if [[ -z "${push_token}" ]]; then
284+
push_token="${CR_PAT}"
285+
fi
286+
if [[ -z "${push_token}" ]]; then
287+
echo "A token with contents and workflows write access is required when pushing a cross-repo promotion branch to ${HEAD_REPO}" >&2
288+
exit 1
289+
fi
290+
fi
291+
292+
git config user.name "github-actions[bot]"
293+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
294+
git remote rename origin upstream
295+
git remote add origin "https://x-access-token:${push_token}@github.com/${HEAD_REPO}.git"
296+
git checkout -B "${PR_BRANCH}"
297+
git add tools/nsc/manifests
298+
git commit -m "Promote NSC channel ${SOURCE_SHA}"
299+
git push --force origin "${PR_BRANCH}"
300+
301+
- name: Create or update promotion PR
302+
if: steps.manifest-diff.outputs.has_changes == 'true'
303+
id: pr
304+
env:
305+
GH_BUILTIN_TOKEN: ${{ github.token }}
306+
PR_PAT: ${{ secrets.PR_PAT }}
307+
READ_PAT: ${{ secrets.READ_PAT }}
308+
CR_PAT: ${{ secrets.CR_PAT }}
309+
PR_BRANCH: ${{ steps.source-run.outputs.pr_branch }}
310+
RELEASE_TAG: ${{ steps.source-run.outputs.release_tag }}
311+
SOURCE_SHA: ${{ steps.source-run.outputs.source_sha }}
312+
RUN_URL: ${{ steps.source-run.outputs.run_url }}
313+
run: |
314+
set -euo pipefail
315+
316+
if [[ "${TARGET_REPO}" == "${HEAD_REPO}" ]]; then
317+
export GH_TOKEN="${GH_BUILTIN_TOKEN}"
318+
pr_head="${PR_BRANCH}"
319+
else
320+
pr_token="${PR_PAT}"
321+
if [[ -z "${pr_token}" ]]; then
322+
pr_token="${READ_PAT}"
323+
fi
324+
if [[ -z "${pr_token}" ]]; then
325+
pr_token="${CR_PAT}"
326+
fi
327+
if [[ -z "${pr_token}" ]]; then
328+
echo "A token with pull request write access is required when opening a PR from ${HEAD_REPO} to ${TARGET_REPO}" >&2
329+
exit 1
330+
fi
331+
export GH_TOKEN="${pr_token}"
332+
pr_head="${HEAD_OWNER}:${PR_BRANCH}"
333+
fi
334+
335+
pr_title="CI: Promote NSC channel to ${SOURCE_SHA}"
336+
release_url="https://github.com/${ASSET_REPO}/releases/tag/${RELEASE_TAG}"
337+
commit_url="https://github.com/${SOURCE_REPO}/commit/${SOURCE_SHA}"
338+
body_file="${RUNNER_TEMP}/nsc-promote-pr.md"
339+
cat > "${body_file}" <<EOF
340+
Promote \`${CHANNEL}\`.
341+
342+
- source commit: [\`${SOURCE_SHA}\`](${commit_url})
343+
- source run: [\`${RUN_ID}\`](${RUN_URL})
344+
- manifest repo release: [\`${RELEASE_TAG}\`](${release_url})
345+
EOF
346+
347+
existing_pr_number="$(gh pr list \
348+
--repo "${TARGET_REPO}" \
349+
--base "${TARGET_BRANCH}" \
350+
--head "${pr_head}" \
351+
--json number \
352+
--jq '.[0].number')"
353+
354+
if [[ -n "${existing_pr_number}" && "${existing_pr_number}" != "null" ]]; then
355+
gh pr edit "${existing_pr_number}" \
356+
--repo "${TARGET_REPO}" \
357+
--title "${pr_title}" \
358+
--body-file "${body_file}"
359+
existing_pr_url="$(gh pr view "${existing_pr_number}" --repo "${TARGET_REPO}" --json url --jq '.url')"
360+
echo "url=${existing_pr_url}" >> "${GITHUB_OUTPUT}"
361+
exit 0
362+
fi
363+
364+
pr_url="$(gh pr create \
365+
--repo "${TARGET_REPO}" \
366+
--base "${TARGET_BRANCH}" \
367+
--head "${pr_head}" \
368+
--title "${pr_title}" \
369+
--body-file "${body_file}")"
370+
371+
echo "url=${pr_url}" >> "${GITHUB_OUTPUT}"
372+
373+
- name: Promotion summary
374+
run: |
375+
{
376+
echo "## NSC promotion summary"
377+
echo
378+
echo "- channel: \`${CHANNEL}\`"
379+
echo "- source repo: \`${SOURCE_REPO}\`"
380+
echo "- source run: \`${RUN_ID}\`"
381+
echo "- source commit: \`${{ steps.source-run.outputs.source_sha }}\`"
382+
echo "- release tag: \`${{ steps.source-run.outputs.release_tag }}\`"
383+
echo "- target repo: \`${TARGET_REPO}\`"
384+
echo "- target branch: \`${TARGET_BRANCH}\`"
385+
if [[ "${{ steps.manifest-diff.outputs.has_changes }}" == "true" ]]; then
386+
echo "- PR: ${{ steps.pr.outputs.url }}"
387+
else
388+
echo "- PR: no manifest changes"
389+
fi
390+
} >> "${GITHUB_STEP_SUMMARY}"

.github/workflows/run-nsc.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ jobs:
123123
& "nginx/nginx-1.24.0/nginx.exe" -t -p "nginx/nginx-1.24.0" -c "conf/nginx.conf"
124124

125125
- name: Download NSC Godbolt artifact
126-
uses: actions/download-artifact@v4
126+
uses: actions/download-artifact@v8
127127
with:
128128
run-id: ${{ inputs.run_id }}
129129
pattern: run-windows-*-msvc-${{ inputs.build_config }}-nsc-godbolt-image

0 commit comments

Comments
 (0)