fix(release): outrank the App Store, and fail when the upload does not land - #593
Merged
Conversation
…t land Two defects, both of which made a broken release look like a good one. 1. The version could be lower than what the store already serves. The baseline came from the newest stable git tag and, since #589, the branch's own info.xml. Neither can see a prerelease line that ran ahead somewhere else, and the fleet spent June and July releasing from Codeberg where the beta line had walked up a minor: pipelinq 0.4.0-beta.2, decidesk 1.1.0-beta.1, larpingapp 0.2.0-beta.1. Those are prerelease tags, so the ^v[0-9]+\.[0-9]+\.[0-9]+$ filter is blind to them by construction. Back on GitHub the baseline fell back to the old stable patch line, and pipelinq has been computing 0.3.2-beta against a store holding 0.4.0-beta.2. Measured 2026-08-27: 14 of 21 fleet apps were computing a downgrade. Nothing rejected it. _check_permission in the appstore validates that the app exists and that you own it; there is no version ordering rule at all. A lower version uploads with a 200 and is then never offered to anyone already on a higher one, so the only place this is visible is here, before the number is chosen. Read /api/v1/apps.json and fold its max into the baseline, then assert under real semver that what we are about to publish outranks it. The assertion is separate arithmetic on the full version string rather than the stripped cores the baseline works in, so it can disagree with the step it checks. Verified that apps.json agrees with the union of three per-platform files across 18 fleet ids -- the per-platform endpoint drops releases that do not match that platform and would reintroduce the downgrade. A failed fetch fails the job; falling back to "the store has nothing" is indistinguishable from an unregistered app. A major bump is now refused unless it is a stable release carrying the `major` label, so the arithmetic can adopt a higher minor but never invent a major on its own. Renamed apps are a new store entry starting from nothing, so their line would restart below what the app already shipped: filinq was about to publish 0.0.40 against docudesk's 0.1.0-beta.3. previous-app-id folds the old entry in. Simulated over all 21 apps: every one now outranks both its own entry and its pre-rename entry, and none crosses a major. 2. A failed App Store upload was a ::warning:: and an exit 0. On 2026-08-27 eighteen of the twenty-one fleet apps failed this call -- 400 for an id that is not registered, 403 for a token that does not own the app -- and every one of those runs is recorded as a green release. The step advised a manual retry that nobody was ever told to perform. Publishing to the store is the job; if it did not happen, the job did not succeed. The two failures the fleet actually hits now name what to do rather than what went wrong. Registration also stops running on every release. POST /api/v1/apps is the certificate-update endpoint and is rate limited hard; it was returning 429 with a 17-hour lockout, bought for nothing since the app was already registered. The catalogue fetched above says whether the id exists, so registration runs only when it actually needs to.
This was referenced Aug 27, 2026
Merged
Merged
Merged
Open
Merged
Merged
Merged
Merged
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this fixes
Measured across all 21 fleet apps on 2026-08-27.
1. The computed version could be lower than what the store already serves
The baseline came from the newest stable git tag plus the branch's own
info.xml. Neither can see a prerelease line that ran ahead elsewhere. The fleet released from Codeberg through June/July, where the beta line had walked up a minor —pipelinq 0.4.0-beta.2,decidesk 1.1.0-beta.1,larpingapp 0.2.0-beta.1. Those are prerelease tags, so^v[0-9]+\.[0-9]+\.[0-9]+$is blind to them by construction.Back on GitHub the baseline fell back to the old stable patch line. 14 of 21 apps were computing a downgrade — pipelinq proposes
0.3.2-betaagainst a store holding0.4.0-beta.2.Nothing rejected it:
nextcloudappstore/api/v1/views.py::_check_permissionvalidates existence and ownership and has no version ordering rule. A lower version uploads with a 200 and is then never offered to anyone on a higher one.Fix: read
/api/v1/apps.json, fold its max into the baseline, then assert under real semver that the new version outranks it.2. A failed App Store upload was a
::warning::and an exit 018 of 21 apps failed the upload on 2026-08-27 — HTTP 400 (id not registered) or 403 (token does not own the app) — and every one of those runs is recorded as a green release.
Fix: the upload failing fails the job, and the two failures the fleet actually hits name what to do.
3. Registration ran on every release and was getting rate limited
POST /api/v1/appsis the certificate-update endpoint. It was returning429 {"detail":"Request was throttled. Expected available in 62877 seconds."}— a 17-hour lockout bought for nothing, since the app was already registered. It now runs only when the catalogue says the id is absent.Verification
apps.jsonvs union of 3 per-platform files0.3.2-beta < 0.4.0-beta.2and1.0.10-beta.2 < 1.0.10majorlabelbash -non everyrun:Heads-up
This will turn ~18 apps' release runs red. That is the existing breakage becoming visible, not new breakage — those releases were already not reaching the store. Causes are tracked separately: 13 renamed ids await certificates (nextcloud/app-certificate-requests#1197–#1209), and openregister / zaakafhandelapp / pipelinq / shillinq need App Store ownership on the token account.
Follow-up
previous-app-idneeds setting on the 11 renamed apps whose old entry is on the store, so their line picks up instead of restarting below it (filinq was about to publish0.0.40against docudesk's0.1.0-beta.3).