Skip to content

Commit b6528de

Browse files
authored
Merge pull request #9771 from decentraland/release/2026-08-17
release: 2026-08-17
2 parents 7d55245 + 1bd63e7 commit b6528de

152 files changed

Lines changed: 5838 additions & 1626 deletions

File tree

Some content is hidden

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

.github/actions/resolve-explorer-build/action.yml

Lines changed: 425 additions & 0 deletions
Large diffs are not rendered by default.

.github/workflows/create-release-branch.yml

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,3 +136,128 @@ jobs:
136136
echo "[badge]: https://img.shields.io/badge/Build-Success!-3fb950?logo=github&style=for-the-badge"
137137
} > comment.md
138138
post_comment
139+
140+
# The PR above was opened with GITHUB_TOKEN, whose events start no workflow
141+
# runs — the same suppression the build-links step exists to work around.
142+
# So the InWorld gate has to be started explicitly, by a token that can.
143+
#
144+
# Dispatching against the release branch is what puts the gate on the PR:
145+
# a workflow_dispatch run attaches its checks to the dispatched ref's tip,
146+
# and that tip is the PR head. Without this the required check on main
147+
# never reports and the release cannot merge.
148+
- name: Start the InWorld gate on the release branch
149+
env:
150+
GH_TOKEN: ${{ secrets.ORG_ACCESS_TOKEN }}
151+
run: |
152+
set -euo pipefail
153+
154+
# On the dispatch path the gate resolves this commit's build with
155+
# wait-minutes 0, so it fails within seconds unless both zips are
156+
# already up. Ask it the same question — did both build legs conclude
157+
# success — rather than whether a run went green: build-unitycloud.yml
158+
# also concludes green having built nothing, when the commit touches
159+
# no Explorer/** file and the matrix never expands, and green having
160+
# built one platform, when a windows-only/macos-only label narrows it.
161+
# Either would dispatch a gate that immediately reds a brand-new
162+
# release PR with nothing wrong in it.
163+
#
164+
# Runs come back newest first, and only the newest few are worth
165+
# asking about — the same candidate cap resolve-explorer-build uses.
166+
HEAD_SHA=$(git rev-parse HEAD)
167+
168+
# The helper resolve-explorer-build defines, duplicated because a
169+
# composite action cannot export a shell function to its caller. Same
170+
# justification, more sharply: this step decides on one answer and
171+
# then the workflow ends, so a single 5xx must not settle a release
172+
# cut. Three attempts five seconds apart cover a transport failure —
173+
# a 5xx, a connection reset — and only that; a spent rate limit
174+
# refills on an hour boundary, which is why the flags below record
175+
# whether the API answered rather than trusting the retry to make it.
176+
# stderr is kept on the last attempt so a permanent failure (this
177+
# workflow file renamed, say) says what it was instead of vanishing
178+
# into "the API did not answer".
179+
gh_api_retry() {
180+
local out attempt
181+
for attempt in 1 2 3; do
182+
if [ "$attempt" -lt 3 ]; then
183+
if out=$(gh api "$@" 2>/dev/null); then printf '%s' "$out"; return 0; fi
184+
sleep 5
185+
else
186+
if out=$(gh api "$@"); then printf '%s' "$out"; return 0; fi
187+
fi
188+
done
189+
return 1
190+
}
191+
192+
# Absorbed rather than left to set -e, here and on the jobs call
193+
# below: an API blip must not red a cut whose branch, PR, labels and
194+
# build-links comment have all landed. But it must not be reported as
195+
# "no build" either — that is the conflation LISTED/LISTED_NOW exist
196+
# to stop in resolve-explorer-build, and it costs more here, because
197+
# this message is the operator's only instruction and the workflow
198+
# ends after it. LISTED is "the run listing answered at all";
199+
# UNEXAMINED is "a candidate's jobs call did not", which leaves that
200+
# run neither green nor known to be anything else.
201+
LISTED=0
202+
UNEXAMINED=0
203+
if RUN_IDS=$(gh_api_retry "repos/${GITHUB_REPOSITORY}/actions/workflows/build-unitycloud.yml/runs?head_sha=${HEAD_SHA}&per_page=50" \
204+
--jq '[.workflow_runs[] | select(.event == "pull_request" or .event == "push") | .id]'); then
205+
LISTED=1
206+
else
207+
RUN_IDS=''
208+
fi
209+
if [ -z "$RUN_IDS" ]; then RUN_IDS='[]'; fi
210+
LIMIT=$(jq 'length' <<< "$RUN_IDS")
211+
if [ "$LIMIT" -gt 5 ]; then LIMIT=5; fi
212+
213+
LEGS_GREEN=false
214+
for (( i = 0; i < LIMIT; i++ )); do
215+
RUN_ID=$(jq -r ".[$i]" <<< "$RUN_IDS")
216+
if LEGS_GREEN=$(gh_api_retry "repos/${GITHUB_REPOSITORY}/actions/runs/${RUN_ID}/jobs?per_page=50" \
217+
--jq '[.jobs[] | select(.conclusion == "success") | .name] | any(startswith("Build (macos")) and any(startswith("Build (windows64"))'); then
218+
if [ "$LEGS_GREEN" = "true" ]; then break; fi
219+
else
220+
LEGS_GREEN=false
221+
UNEXAMINED=1
222+
fi
223+
done
224+
225+
# Three ways to end up not dispatching, and only the last is a build
226+
# problem — so they get three messages. All three are `::error::`:
227+
# each one ends with the gate unreported and the release unmergeable,
228+
# which is not a line in a green log, and the dispatch failure below
229+
# already annotates for exactly that outcome.
230+
#
231+
# None of them says "re-run this workflow". Re-running re-enters the
232+
# `Create or update branch` step above, which force-pushes
233+
# ${BRANCH_NAME} from dev's current tip — quietly re-cutting the
234+
# release from newer commits than the one that was reviewed. Starting
235+
# `In-World Tests` by hand is the remedy in every case, and it is the
236+
# same instruction the dispatch failure below gives.
237+
if [ "$LISTED" = "0" ]; then
238+
echo "::error::Could not list build-unitycloud.yml runs for ${HEAD_SHA:0:7} — the GitHub Actions API did not answer, so no build was ever looked at and the InWorld gate was not started. This says nothing about whether a build exists. The release branch and its PR are fine: start \`In-World Tests\` by hand from the Actions tab against ${BRANCH_NAME}. Do not re-run this workflow — it force-pushes ${BRANCH_NAME} and would re-cut the release from a newer dev tip."
239+
exit 0
240+
fi
241+
if [ "$LEGS_GREEN" != "true" ] && [ "$UNEXAMINED" = "1" ]; then
242+
echo "::error::The GitHub Actions API did not answer for at least one build run of ${HEAD_SHA:0:7}, so whether its legs are green is unknown and the InWorld gate was not started. This is not evidence that no build exists. The release branch and its PR are fine: start \`In-World Tests\` by hand from the Actions tab against ${BRANCH_NAME}. Do not re-run this workflow — it force-pushes ${BRANCH_NAME} and would re-cut the release from a newer dev tip."
243+
exit 0
244+
fi
245+
if [ "$LEGS_GREEN" != "true" ]; then
246+
echo "::error::No build of ${HEAD_SHA:0:7} has both Build (macos) and Build (windows64) green, so the InWorld gate was not started — it would fail on its first poll. Build the commit: label the release PR \`force-build\` if build-unitycloud.yml built nothing, or remove a \`windows-only\`/\`macos-only\` label that narrowed its targets. Then start \`In-World Tests\` by hand against ${BRANCH_NAME}. Do not re-run this workflow — it force-pushes ${BRANCH_NAME} and would re-cut the release from a newer dev tip."
247+
exit 0
248+
fi
249+
250+
# Loud but deliberately not fatal. `gh workflow run` needs
251+
# `actions: write`, which ORG_ACCESS_TOKEN's other uses in this repo
252+
# (org membership, PR reviews) do not require, so it may not have it —
253+
# and a secret's scopes cannot be inspected from here. Failing the job
254+
# would invite a re-run, and re-running this workflow force-pushes the
255+
# release branch, quietly re-cutting the release from a newer dev tip.
256+
# The branch, PR, labels and build-links comment have all landed by
257+
# now; the annotation is what makes the missing gate visible, and the
258+
# required check staying unreported is what keeps the release blocked.
259+
if ! gh workflow run in-world-tests.yml --ref "$BRANCH_NAME"; then
260+
echo "::error::Could not dispatch the InWorld gate against ${BRANCH_NAME}. The likeliest cause is that ORG_ACCESS_TOKEN lacks \`actions: write\` on this repository, which \`gh workflow run\` requires. The release branch and its PR are fine — start \`In-World Tests\` by hand from the Actions tab against ${BRANCH_NAME}, or its required check will sit unreported and the release will not be mergeable."
261+
exit 0
262+
fi
263+
echo "::notice::InWorld gate dispatched against ${BRANCH_NAME}."

0 commit comments

Comments
 (0)