latest-prerelease lookup strands users on 1.0.81-9: releases share created_at, so GitHub ranks -10 below -2 and the first listed prerelease is chosen
Personne n'a encore pris cette issue.
- Langage dominant
- Shell
- Étoiles
- 11.2k
- Forks
- 1.9k
- Merge moyen
- 14 h 16 min
- PR mergées (30 j)
- 6
Description
latest-prerelease lookup strands users on 1.0.81-9
Summary
copilot update prerelease refuses to advance from 1.0.81-9 to 1.0.81-10, reporting the older build as the latest available release:
> copilot --no-auto-update update prerelease
Checking for updates...
Checking GitHub for the latest release...
No update needed, current version is 1.0.81-9, fetched latest release is v1.0.81-9
At the time of that run, v1.0.81-10 had been published for ~1.5 hours and was not a draft:
> gh api repos/github/copilot-cli/releases/tags/v1.0.81-10 \
--jq '"tag=\(.tag_name) draft=\(.draft) prerelease=\(.prerelease) published=\(.published_at) assets=\(.assets|length)"'
tag=v1.0.81-10 draft=false prerelease=true published=2026-08-25T21:15:43Z assets=20
Root cause
Every 1.0.81-N release shares an identical created_at, so GitHub's list endpoint cannot order them by creation time and falls back to a lexicographic tiebreak. "10" sorts below "2", so -10 lands in the middle of the list rather than at the top:
> gh api "repos/github/copilot-cli/releases?per_page=12" \
--jq '.[] | "\(.tag_name) created=\(.created_at) published=\(.published_at)"'
v1.0.81-9 created=2026-08-14T20:20:00Z published=2026-08-24T17:42:32Z
v1.0.81-8 created=2026-08-14T20:20:00Z published=2026-08-23T14:46:46Z
v1.0.81-7 created=2026-08-14T20:20:00Z published=2026-08-21T18:39:24Z
v1.0.81-6 created=2026-08-14T20:20:00Z published=2026-08-20T17:59:54Z
v1.0.81-5 created=2026-08-14T20:20:00Z published=2026-08-19T23:16:31Z
v1.0.81-4 created=2026-08-14T20:20:00Z published=2026-08-19T18:23:39Z
v1.0.81-3 created=2026-08-14T20:20:00Z published=2026-08-19T08:46:57Z
v1.0.81-2 created=2026-08-14T20:20:00Z published=2026-08-19T04:28:01Z
v1.0.81-10 created=2026-08-14T20:20:00Z published=2026-08-25T21:15:43Z <-- newest, ranked 9th
v1.0.81-1 created=2026-08-14T20:20:00Z published=2026-08-18T18:30:50Z
v1.0.81-0 created=2026-08-14T20:20:00Z published=2026-08-14T23:47:01Z
v1.0.80 created=2026-08-10T16:19:17Z published=2026-08-14T02:28:39Z
The selection appears to take the first prerelease in that default ordering. In app.js, the update routine logs the message above from:
if (nR.lte(s.tag_name, Kh())) {
let u = `No update needed, current version is ${Kh()}, fetched latest release is ${s.tag_name}`;
...
}
where s originates from lx() → uht("latest-prerelease", ...) → native githubLookupRelease(...).
Worth emphasising: the comparison is not the bug. nR.lte is semver-aware and ranks 1.0.81-9 < 1.0.81-10 correctly (numeric prerelease identifiers compare numerically). The wrong value is the release that gets fetched. Since GitHub exposes no "latest prerelease" endpoint (/releases/latest returns v1.0.80, the newest stable), the native lookup must enumerate — and it trusts list order.
Impact
Any prerelease line that reaches -10 strands every user on -9 for the remainder of that line. This is not self-correcting: it persists until a new stable or minor version is published. It affects both explicit copilot update prerelease and the automatic startup update check, on all platforms.
Steps to reproduce
- Be on
1.0.81-9(or install it). - Run
copilot --no-auto-update update prerelease. - Observe
No update needed ... fetched latest release is v1.0.81-9, despitev1.0.81-10being published.
The --no-auto-update prefix matters for a clean repro: without it, the startup auto-update check inflates the reported running version, so a plain copilot update prerelease compares against an already-elevated value and no-ops for a second, unrelated reason.
Suggested fix
Don't rely on list ordering. After enumerating non-draft releases, select the maximum by semver (or by published_at) before comparing against the running version. A one-line jq equivalent that resolves correctly today:
[.[] | select(.draft == false)] | sort_by(.published_at) | reverse | .[0].tag_name
Separately, giving each release a distinct created_at at publish time would remove the ambiguity at the source, though the client-side sort is the durable fix.
Workaround
Download the release asset for the desired tag directly and replace the binary, bypassing the update check entirely.
Environment
- Windows 11,
win32-x64 - Copilot CLI
1.0.81-9(standalone exe), attempting to reach1.0.81-10
Guide de contribution
Ouvrir le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Piste de recherche
Commencez dans app.js, au niveau du chemin de mise à jour allant de lx() via uht("latest-prerelease", ...) jusqu’à native githubLookupRelease(). Reproduisez l’ordre des releases avec la requête de l’API GitHub indiquée, puis examinez comment les releases qui ne sont pas des brouillons sont énumérées et quelle release est sélectionnée. C’est terminé lorsque le tag de prerelease le plus récent est sélectionné de manière fiable et que la mise à jour passe de 1.0.81-9 à 1.0.81-10.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- github, javascript
- Domaine
- api, cli, release
- Type d'issue
- Bug
- Difficulté
- 3/5
- Temps estimé
- 1-2 jours
- Activité
- Active
- Clarté
- Clairement spécifiée
- Accessibilité débutants
- 68/100