Skip to content

Commit da10cb7

Browse files
committed
Relax the failure mode for missing releases
1 parent 932a11d commit da10cb7

3 files changed

Lines changed: 79 additions & 15 deletions

File tree

.github/workflows/release-clang-tools.yml

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,14 +127,26 @@ jobs:
127127
df -h /
128128
129129
- name: Download clang-format and clang-tidy for ${{ matrix.llvm_tag }}
130+
id: fetch
130131
if: steps.precheck.outputs.skip != 'true'
131132
env:
132133
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
133134
LLVM_TAG: ${{ matrix.llvm_tag }}
134-
run: bash ./scripts/fetch-clang-tools.sh "${LLVM_TAG}" "artifacts/${LLVM_TAG}"
135+
run: |
136+
set +e
137+
bash ./scripts/fetch-clang-tools.sh "${LLVM_TAG}" "artifacts/${LLVM_TAG}"
138+
rc=$?
139+
set -e
140+
# Exit code 3 means upstream has not published this release yet. Not an
141+
# error: leave the tag unprocessed so a later run picks it up.
142+
if [ "${rc}" -eq 3 ]; then
143+
echo "nothing_to_publish=true" >> "$GITHUB_OUTPUT"
144+
exit 0
145+
fi
146+
exit "${rc}"
135147
136148
- name: Publish release ${{ matrix.llvm_tag }}
137-
if: steps.precheck.outputs.skip != 'true'
149+
if: steps.precheck.outputs.skip != 'true' && steps.fetch.outputs.nothing_to_publish != 'true'
138150
env:
139151
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
140152
LLVM_TAG: ${{ matrix.llvm_tag }}

README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,10 @@ and, for each new one, runs the extraction script and publishes a release.
104104
2. Matches each target platform against a list of archive-name patterns, most preferred first
105105
3. Downloads the first match and pulls just `bin/clang-format` and `bin/clang-tidy` out of it
106106

107-
A platform upstream never published is skipped quietly. A platform whose archive exists but
108-
yields no binary is a hard error, so a future rename fails the build loudly rather than
109-
producing an empty release.
107+
A platform upstream never published is skipped quietly.
108+
109+
Set `STRICT=true` or `STRICT=false` to override the age heuristic, or `STRICT_WINDOW_DAYS`
110+
to move the cutoff.
110111

111112
## Maintenance
112113

scripts/fetch-clang-tools.sh

Lines changed: 61 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@ VERSION=${LLVM_TAG#llvmorg-}
2626

2727
TOOLS=(clang-format clang-tidy)
2828

29+
# Distinct exit code when LLVM has not published a release yet
30+
EXIT_NO_RELEASE=3
31+
32+
# A release younger than this is held to the strict error standard
33+
STRICT_WINDOW_DAYS=${STRICT_WINDOW_DAYS:-30}
34+
2935
PLATFORMS=(linux-x64 linux-arm64 macos-x64 macos-arm64 windows-x64 windows-x86 windows-arm64)
3036

3137
# Archive name patterns per platform, most preferred first. Matched as shell globs
@@ -93,21 +99,57 @@ WORK_DIR=$(mktemp -d)
9399
trap 'rm -rf "${WORK_DIR}"' EXIT
94100

95101
echo "Reading asset list for ${LLVM_TAG}..."
102+
RELEASE_JSON="${WORK_DIR}/release.json"
96103
ASSET_LIST="${WORK_DIR}/assets.txt"
104+
97105
if command -v gh >/dev/null 2>&1; then
98-
gh api "repos/llvm/llvm-project/releases/tags/${LLVM_TAG}" -q '.assets[].name' > "${ASSET_LIST}"
106+
if ! gh api "repos/llvm/llvm-project/releases/tags/${LLVM_TAG}" > "${RELEASE_JSON}" 2>/dev/null; then
107+
echo "No GitHub release published for ${LLVM_TAG}; nothing to download."
108+
exit ${EXIT_NO_RELEASE}
109+
fi
99110
else
100-
curl -sSL -H 'Accept: application/vnd.github+json' \
101-
"https://api.github.com/repos/llvm/llvm-project/releases/tags/${LLVM_TAG}" |
102-
grep -oE '"name": *"[^"]+"' | sed 's/.*": *"//; s/"$//' > "${ASSET_LIST}"
111+
http_code=$(curl -sSL -H 'Accept: application/vnd.github+json' -w '%{http_code}' \
112+
-o "${RELEASE_JSON}" \
113+
"https://api.github.com/repos/llvm/llvm-project/releases/tags/${LLVM_TAG}")
114+
if [ "${http_code}" = "404" ]; then
115+
echo "No GitHub release published for ${LLVM_TAG}; nothing to download."
116+
exit ${EXIT_NO_RELEASE}
117+
fi
118+
fi
119+
120+
# jq emits CRLF on Windows, which would leave a stray \r on every asset name and
121+
# stop the glob matching below from ever hitting. Strip it on every path.
122+
if command -v jq >/dev/null 2>&1; then
123+
jq -r '.assets[].name' < "${RELEASE_JSON}" | tr -d '\r' > "${ASSET_LIST}"
124+
published_at=$(jq -r '.published_at // empty' < "${RELEASE_JSON}" | tr -d '\r')
125+
else
126+
# The download URL percent-encodes the + in clang+llvm-*, so decode it back.
127+
grep -oE '"browser_download_url": *"[^"]+"' < "${RELEASE_JSON}" |
128+
sed 's|.*/||; s/"$//; s/%2[Bb]/+/g' | tr -d '\r' > "${ASSET_LIST}"
129+
published_at=$(grep -oE '"published_at": *"[^"]+"' < "${RELEASE_JSON}" |
130+
head -1 | sed 's/.*": *"//; s/"$//' | tr -d '\r')
103131
fi
104132

105133
if [ ! -s "${ASSET_LIST}" ]; then
106-
echo "ERROR: no assets listed for ${LLVM_TAG}; is it a published release?" >&2
134+
echo "ERROR: release ${LLVM_TAG} exists but lists no assets" >&2
107135
exit 1
108136
fi
109137
echo "Found $(wc -l < "${ASSET_LIST}") assets."
110138

139+
# Severity depends on how recent the release is.
140+
if [ -z "${STRICT:-}" ]; then
141+
STRICT=false
142+
if [ -n "${published_at}" ]; then
143+
published_epoch=$(date -u -d "${published_at}" +%s 2>/dev/null || echo "")
144+
if [ -n "${published_epoch}" ]; then
145+
age_days=$(( ( $(date -u +%s) - published_epoch ) / 86400 ))
146+
echo "Release published ${age_days} day(s) ago."
147+
[ "${age_days}" -le "${STRICT_WINDOW_DAYS}" ] && STRICT=true
148+
fi
149+
fi
150+
fi
151+
echo "Partial extraction is $([ "${STRICT}" = true ] && echo "fatal (recent release)" || echo "a warning (older release)")."
152+
111153
# Pick the first asset matching one of the platform's patterns.
112154
select_asset() {
113155
local platform="$1" pattern asset
@@ -232,12 +274,21 @@ if [ -x "${OUTPUT_DIR}/clang-format-linux-x64" ] && [ "$(uname -s)-$(uname -m)"
232274
echo "smoke test: $("${OUTPUT_DIR}/clang-format-linux-x64" --version)"
233275
fi
234276

235-
if [ ${#failed_platforms[@]} -gt 0 ]; then
236-
echo "ERROR: archives existed but yielded no binaries for: ${failed_platforms[*]}" >&2
277+
if [ "${extracted_count}" -eq 0 ]; then
278+
echo "ERROR: release ${LLVM_TAG} lists assets but no binaries could be extracted;" >&2
279+
echo " the archive naming patterns most likely need updating." >&2
237280
exit 1
238281
fi
239282

240-
if [ "${extracted_count}" -eq 0 ]; then
241-
echo "ERROR: no binaries extracted for ${LLVM_TAG}" >&2
242-
exit 1
283+
if [ ${#failed_platforms[@]} -gt 0 ]; then
284+
message="archives existed but yielded no binaries for: ${failed_platforms[*]}"
285+
if [ "${STRICT}" = true ]; then
286+
echo "ERROR: ${message}" >&2
287+
echo " This release is recent, so treating it as a regression." >&2
288+
exit 1
289+
fi
290+
# A warning annotation still surfaces on the run without turning it red.
291+
echo "::warning title=Incomplete extraction for ${LLVM_TAG}::${message}"
292+
echo "WARNING: ${message}"
293+
echo " Release is older than ${STRICT_WINDOW_DAYS} days, publishing the ${extracted_count} binaries that did extract."
243294
fi

0 commit comments

Comments
 (0)