ci: fail release if any expected artifacts are missing#16
Conversation
The previous check only verified that at least one artifact existed. This meant a release could be published with missing CUDA builds (as happened with b9549, which was missing all Windows CUDA artifacts and ubuntu-cuda-sm_90-x64). The updated check explicitly enumerates every expected artifact: - All 7 CUDA SM variants (sm_75/80/86/89/90/100/120) for each of: ubuntu x64, ubuntu arm64, windows x64 - ubuntu ROCm, ubuntu OpenVINO, Windows ROCm, Windows CPU If any are absent the step fails before the release is created, so a partially-populated release can never be tagged. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
fl0rianr
left a comment
There was a problem hiding this comment.
I don't think this should be the final fix. The artifact manifest check is useful, but this makes releases all-or-nothing: a transient Windows CUDA failure now blocks the entire release.
I'd prefer this as a first step only if we also add a recovery path: publish available artifacts with a clear missing-artifacts list, then allow a manual backfill workflow to rebuild/upload a missing sm_* target for the same tag.
|
Do you want to have a slight adaption? I'm just thinking if we have a major issue with either rocm or cuda not able to get the artifact out why hold of the other? Hence why I did this one: lemonade-sdk/lemonade#2518 |
A missing artifact in one backend family (e.g. a single failed CUDA sm_* build) no longer blocks publishing the artifacts from families that did build successfully. Each family (cuda, rocm, openvino, cpu) is checked independently; the release is still created and available artifacts are still uploaded, but the job fails afterward so the gap is still surfaced. Addresses review feedback on #16. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Good call — pushed 73fe29e which decouples the checks per backend family ( That should cover your second comment directly (rocm failure no longer holds back cuda, and vice versa). Didn't add the manual backfill workflow yet — happy to follow up with that in a separate PR if you think it's still needed on top of this, since re-running the whole nightly job is idempotent already (skips already-uploaded assets) but doesn't let you target just one missing |
fl0rianr
left a comment
There was a problem hiding this comment.
Thanks, this is much closer to the behavior I was hoping for.
One thing I would still keep as a blocker: please preserve a hard guard for the files == 0 case before creating or updating the release. If no artifacts made it into ./release, we should fail before touching the GitHub release, otherwise we could create an empty release.
Optional/nit: I’m okay with not publishing a given OS/backend family when one of its required pieces failed — for example, if the Windows side is incomplete, it’s fine for that part of the release to be absent. The main thing is that this should not accidentally create an empty release, and the final error should clearly say which family/artifacts were missing.
…essage Fail before touching the GitHub release if ./release ends up with zero artifacts, instead of relying on per-family checks alone. Also carry the per-family missing summary into the final failure message so it's self-contained instead of pointing back at an earlier step's log. Addresses review feedback on #16. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Pushed 34e6acd:
On the optional nit: I left individual working artifacts within a partially-broken family published (e.g. if one Windows CUDA |
Rather than publishing whichever individual files happened to build, a family (cuda, rocm, openvino, cpu) is now all-or-nothing: if any required artifact in a family is missing, every artifact for that family is dropped from the release. This guarantees that if a family is present in a release at all, it's a complete, internally-consistent set across every platform/variant — e.g. CUDA is never split across sm_* or platforms between two different backend versions. Other families are unaffected by a gap in one. Addresses review feedback on #16. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Pushed 33312dd: switched from "publish whatever built within a family" to strict all-or-nothing per family. If any required artifact in a family (
So: if CUDA shows up in a release, it's guaranteed to be the complete set for ubuntu x64/arm64 and windows, no mixed versions. |
fl0rianr
left a comment
There was a problem hiding this comment.
This is much closer and I like the strict all-or-nothing behavior per family: if CUDA is present, it must be complete across Ubuntu x64, Ubuntu arm64, and Windows x64; if not, CUDA should be dropped while ROCm/OpenVINO/CPU can still publish. Great!
One blocker remains: the release job still has normal needs: on all build jobs and no always(). If a CUDA matrix job actually fails, the release job may be skipped before this new family-drop logic can run. To make the intended behavior work, the release job should use something like:
if: ${{ always() && (github.event_name == 'schedule' || github.event.inputs.create_release == 'true') }}
Then the artifact check can decide what complete families to publish.
Also worth checking: Move artifacts still hard-fails if the Windows CPU artifact is missing before the family check runs. That may be intentional, but if the goal is true per-family independence, this should either be handled by the family logic or documented as a required global prerequisite.
Windows CPU artifact block unrelated families Two gaps that let the per-family completeness logic get bypassed entirely: - The release job had no always(), so GitHub Actions' default skip-if-a-needed-job-failed behavior meant a single failed build job (e.g. one CUDA sm_* matrix leg) could skip the release job outright, before the family checks ever ran. - The Windows CPU-backend merge step still hard-exited the whole job if the CPU zip was missing, which — since it runs before the Ubuntu/CUDA renaming loops — blocked Ubuntu ROCm/OpenVINO/CUDA from publishing too, for a reason that had nothing to do with them. Now the release job always runs when the workflow is a schedule/dispatch run, and a missing Windows CPU artifact just skips moving the Windows zip-based artifacts (which structurally require it merged in) into release/, leaving Ubuntu/CUDA .7z artifacts unaffected. The existing completeness check then correctly sees the missing cpu/rocm files and drops those families. Addresses review feedback on #16. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Both addressed in e8991e5:
Tested both changes locally (bash logic for the CPU-merge skip path, confirming Ubuntu artifacts still land in |
fl0rianr
left a comment
There was a problem hiding this comment.
This is basically there now.
One small remaining issue: the artifact/*.tar.gz move loop should also guard against an unmatched glob, like the CUDA .tar.xz and .7z loops already do.
If both .tar.gz producers are missing, the loop may try to move the literal artifact/*.tar.gz and fail before the family completeness check can drop ROCm/OpenVINO and still publish CUDA/Windows CPU.
Suggested fix:
for tar_file in artifact/*.tar.gz; do
[ -f "$tar_file" ] || continue
...
doneAfter that I’m good with approving.
The CUDA .tar.xz and .7z move loops already skip when their glob doesn't match any files; the tar.gz loop (ROCm/OpenVINO) was missing the same guard. If both tar.gz producers are absent, the loop would try to mv the literal artifact/*.tar.gz and fail before the family completeness check could run and drop ROCm/OpenVINO while still publishing CUDA/Windows CPU. Addresses review feedback on #16. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Fixed in 87f8d0f — added the same `[ -f "$tar_file" ] || continue` guard the CUDA loops already had. Verified locally that the loop now exits cleanly with zero iterations when no `.tar.gz` files are present, instead of attempting to `mv` the literal unmatched glob string. |
Same fix as lemonade-sdk/stable-diffusion.cpp#14: the release is reused across runs against the same tag (idempotent create-or-get). If a family (e.g. rocm) was complete and published in an earlier run but the current run finds it incomplete and drops it locally, its assets from that earlier run were never removed — the release would keep looking complete for a family this run couldn't actually reproduce. The upload step now reconciles existing release assets against the current ./release file set: anything not fully uploaded (a broken partial upload, as before) or not present in this run's file set (stale leftovers from a dropped family) gets deleted before uploading. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Proactively applied the same stale-asset fix that came up in review on lemonade-sdk/stable-diffusion.cpp#14, since this repo has the identical idempotent create-or-reuse-release pattern and is exposed to the same bug: if a family (e.g. rocm) was complete and published in an earlier run against a tag, but a later run against that same tag finds it incomplete and drops it locally, the earlier run's assets for that family were never cleaned up — the release would keep looking complete for something the current run couldn't reproduce. Pushed in f0883c9: the upload step now reconciles existing release assets against the current `./release` file set — anything not fully uploaded (broken partial upload, existing behavior) or not present in this run's file set (stale leftover from a dropped family) gets deleted before uploading, instead of just skipping re-upload of whatever's already there. |
|
Nice, all for go from my side |
Port the artifact-completeness gate from lemonade-sdk/llama.cpp#16 to this repo's release job, adapted to its build matrix: - cuda: 8 sm_* variants on ubuntu x64 + windows x64, plus sm_121-only on ubuntu arm64 (GB10) — 17 files total. - rocm-therock: TheRock nightly ROCm 7.13.0 on windows + ubuntu. - rocm-hipsdk: official/legacy HIP SDK ROCm on windows (7.1.1) + ubuntu (7.2.1) — kept separate from rocm-therock since they're different SDKs, not just different platforms of the same backend. - cpu: ubuntu + windows avx2 builds. - metal: macos-14 + macos-latest builds. Each family is all-or-nothing: if any artifact in a family is missing, every artifact for that family is dropped from the release so a release never contains a partial/inconsistent set (e.g. CUDA split across sm_* or platforms). Other families are unaffected by a gap in one. A release with zero artifacts overall is never created. Also brings the release/upload mechanism up to parity with llama.cpp's: an idempotent create-or-get-release step (safe to re-run after a partial failure) and a retrying, resumable asset upload, replacing the old anzz1/action-create-release + github-script@v3 flow. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Port the artifact-completeness gate from lemonade-sdk/llama.cpp#16 to this repo's release job, adapted to its build matrix: - cuda: 8 sm_* variants on ubuntu x64 + windows x64, plus sm_121-only on ubuntu arm64 (GB10) — 17 files total. - rocm-therock: TheRock nightly ROCm 7.13.0 on windows + ubuntu. - rocm-hipsdk: official/legacy HIP SDK ROCm on windows (7.1.1) + ubuntu (7.2.1) — kept separate from rocm-therock since they're different SDKs, not just different platforms of the same backend. - cpu: ubuntu + windows avx2 builds. - metal: macos-14 + macos-latest builds. Each family is all-or-nothing: if any artifact in a family is missing, every artifact for that family is dropped from the release so a release never contains a partial/inconsistent set (e.g. CUDA split across sm_* or platforms). Other families are unaffected by a gap in one. A release with zero artifacts overall is never created. Also brings the release/upload mechanism up to parity with llama.cpp's: an idempotent create-or-get-release step (safe to re-run after a partial failure) and a retrying, resumable asset upload, replacing the old anzz1/action-create-release + github-script@v3 flow. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Summary
Part of lemonade-sdk/lemonade#2163
The previous "Check release artifacts" step only verified that at least one artifact existed. This meant a release could be published with missing CUDA builds — as happened with b9549, which was missing all 7 Windows CUDA artifacts and
ubuntu-cuda-sm_90-x64.Changes
The check now explicitly enumerates every required artifact and fails with actionable error messages before a release is created:
sm_75,sm_80,sm_86,sm_89,sm_90,sm_100,sm_120) for each platform:.tar.xz).tar.xz).7z).tar.gz).tar.gz).zip).zip)If any artifact is absent, the step fails and lists exactly which files are missing — so a partially-populated release can never be tagged.