From 012a018e3536d84fba2587887a6ed163ddf84407 Mon Sep 17 00:00:00 2001 From: "guys-inc-ops[bot]" <321481384+guys-inc-ops[bot]@users.noreply.github.com> Date: Thu, 27 Aug 2026 15:05:23 +0000 Subject: [PATCH] Prepare 3.4.10: version, release notes, and the sign-in docs Four things that all have to be true before a release can be cut, and none of which are true today. **The version.** The .deb version comes from app/package.json, so a release built from 3.4.9 declares 3.4.9 again. apt only upgrades on a higher version, so no existing user would ever receive it - and since the pool rebuild landed, reprepro now skips the incoming package entirely and the repository keeps serving the old binary. 3.4.10 rather than 3.4.9-linux2 because the latter is greater to dpkg but a *semver prerelease*, so it sorts below 3.4.9 for any comparison the application itself makes. Verified both ways round rather than reasoned about. **The release notes.** generate-release-notes.ts requires an entry in changelog.json for the upstream version behind an initial tag, and exits 1 without one - so the release job fails before it publishes anything. Adding 3.4.10 fixes that, but exposed a second problem: every fork-authored entry was silently dropped, because the entry regex requires a "- #1234" tail naming an upstream issue. Our changes have no upstream issue, and a fork PR number in that position would render as a link to an unrelated issue in desktop/desktop. Entries may now omit the tail. Confirmed by rendering both 3.4.10 and 3.4.9 - the upstream notes still produce issue links and contributor credit. **The sign-in change.** The device flow is the most visible change in this release and nothing documented it. A user who sees a one-time code where a sign-in page used to be has no way to tell whether it is working as intended. **Signing out.** It no longer revokes the token on github.com, because revoking one requires the client secret this application deliberately no longer ships. That is a security-relevant regression and it needs to be written down where someone handing over a machine will find it. While there: the organization-access entry described this as an OAuth App and linked the OAuth App approval flow. It is a GitHub App, so those are the wrong screens - the application does not appear in them at all. Already wrong before this release; corrected now that the release puts sign-in in front of people. Both replacement links checked. --- app/package.json | 2 +- changelog.json | 10 ++++++ docs/known-issues.md | 58 +++++++++++++++++++++++++++----- script/generate-release-notes.ts | 21 ++++++++++-- 4 files changed, 79 insertions(+), 12 deletions(-) diff --git a/app/package.json b/app/package.json index 03aa8b1ad0..3bdbd3ac7b 100644 --- a/app/package.json +++ b/app/package.json @@ -3,7 +3,7 @@ "productName": "GitHub Desktop", "bundleID": "com.github.GitHubClient", "companyName": "GitHub, Inc.", - "version": "3.4.9", + "version": "3.4.10", "main": "./main.js", "repository": { "type": "git", diff --git a/changelog.json b/changelog.json index 068d040ab8..a0f24edb6e 100644 --- a/changelog.json +++ b/changelog.json @@ -1,5 +1,15 @@ { "releases": { + "3.4.10": [ + "[Added] Sign in to GitHub.com using the OAuth device flow: Desktop shows a one-time code to enter in your browser, instead of handing off through a redirect", + "[Fixed] The published packages no longer contain an OAuth client secret. Desktop authenticates as a public client, so no secret is built into the application", + "[Improved] Upgrade Electron to v39.8.10, from v32.1.2, picking up seven major versions of Chromium security fixes", + "[Improved] Upgrade DOMPurify to v3, which sanitises rendered Markdown in the application", + "[Improved] Pin patched versions of tar-fs, cross-spawn, ansi-regex and @babel/runtime in the packaged application", + "[Improved] Release binaries now carry a build provenance attestation, so a download can be traced to the workflow run that produced it", + "[Improved] The APT repository is signed with a rotated key, and published under a per-project prefix at apt.guysinc.pub/github-desktop", + "[Removed] Signing out no longer revokes the token on github.com. Revoking a server-side token required a client secret, which is no longer shipped; sign out now discards the token locally. Revoke access at github.com/settings/applications" + ], "3.4.9": [ "[Fixed] App no longer crash for first time users going through the welcome flow and attempting to sign in more than once - #19442", "[Fixed] Files configured to use the binary merge driver are now treated as binary files when resolving conflicts - #9846", diff --git a/docs/known-issues.md b/docs/known-issues.md index 89fe08d722..fec5577099 100644 --- a/docs/known-issues.md +++ b/docs/known-issues.md @@ -14,6 +14,8 @@ - [Linux](#linux) - [I get a white screen when launching Desktop](#i-get-a-white-screen-when-launching-desktop) - [I cannot access repositories under my organization](#i-cannot-access-repositories-under-my-organization) + - [Signing in asks for a code instead of opening a sign-in page](#signing-in-asks-for-a-code-instead-of-opening-a-sign-in-page) + - [Signing out does not revoke access on github.com](#signing-out-does-not-revoke-access-on-githubcom) - [My shell/terminal is not detected and is stuck on "GNOME Terminal"](#my-shellterminal-is-not-detected-and-is-stuck-on-gnome-terminal) # Known Issues @@ -258,22 +260,60 @@ Electron enables hardware accelerated graphics by default, but some graphics car ### I cannot access repositories under my organization -The GitHub Desktop application is an OAuth application, but this fork does not -have the same permissions as the app does on Windows and macOS, which manifests -in a couple of different ways: +This fork signs in through its own GitHub App, which does not hold the same +permissions the official app has on Windows and macOS. That shows up in a couple +of ways: - the "Clone a Repository" view does not show all organization repositories - pushes to a repository owned by an organization may be rejected with a generic error message -The root cause of this is organizations by default will have "OAuth App access -restrictions" enabled, which blocks the GitHub Desktop development app that is -used by this fork. +The cause is that an organization has not authorized this application to access +its resources. Note that this is a GitHub *App*, not an OAuth App, so the +organization setting involved is **not** "OAuth App access restrictions" and the +approval flow is a different one — a point worth making because the two are +easily confused and the OAuth App screens will not list this application. -**Workaround:** ask your organization admin to [approve access](https://docs.github.com/en/organizations/restricting-access-to-your-organizations-data/approving-oauth-apps-for-your-organization) -to the GitHub Desktop development app. +**Workaround:** request access from your organization owner, then ask them to +approve it under the organization's **Settings → Third-party Access → GitHub +Apps**. GitHub's guide is +[requesting a GitHub App from your organization owner](https://docs.github.com/en/apps/using-github-apps/requesting-a-github-app-from-your-organization-owner); +[authorizing GitHub Apps](https://docs.github.com/en/apps/using-github-apps/authorizing-github-apps) +covers what you are granting. -If you have not requested the GitHub Desktop development app for this organization, [follow these instructions first](https://docs.github.com/en/account-and-profile/setting-up-and-managing-your-personal-account-on-github/managing-your-membership-in-organizations/requesting-organization-approval-for-oauth-apps). +### Signing in asks for a code instead of opening a sign-in page + +This is expected from 3.4.10 onwards, and is not an error. + +Desktop now signs in using the OAuth **device flow**: it shows a one-time code, +you open the link in a browser, enter the code, and approve the request. The +sign-in page no longer opens automatically and hands a token back to the +application. + +The reason is that the previous flow required the application to hold an OAuth +client secret, and a desktop application cannot keep a secret — anything shipped +inside a `.deb` is readable by whoever downloads it. Earlier builds did ship +one. The device flow needs no secret, so there is nothing in the package worth +extracting. + +If the code expires before you finish, Desktop will issue a new one; codes are +short-lived by design. + +### Signing out does not revoke access on github.com + +Signing out removes the token from your machine. It does **not** revoke that +token on github.com, so the authorization remains listed in your account until +you remove it there. + +This is a consequence of the change described above. Revoking a token through +the API requires the client secret that this application deliberately no longer +has. The same limitation applies to the GitHub CLI, for the same reason. + +**To revoke access properly:** go to +[github.com/settings/applications](https://github.com/settings/applications), +find the application, and revoke it. Do this rather than relying on sign-out if +you are handing the machine to someone else, or if you believe the token has +been exposed. ### My shell/terminal is not detected and is stuck on GNOME Terminal diff --git a/script/generate-release-notes.ts b/script/generate-release-notes.ts index 31183e51bd..6e515bde0b 100644 --- a/script/generate-release-notes.ts +++ b/script/generate-release-notes.ts @@ -142,6 +142,11 @@ function getReleaseGroups(version: string): ReleaseNotesGroups { const releaseEntryExternalContributor = /\[(.*)\](.*)- (.*)\. Thanks (.*)!/ const releaseEntryRegex = /\[(.*)\](.*)- (.*)/ + // An entry describing a change made in this fork has no upstream issue to + // point at, so it carries no "- #1234" tail. Without this it matches nothing + // and the note is dropped with only a warning, which means a release can be + // published with an empty body and a green run. + const releaseEntryNoIds = /^\[([^\]]+)\]\s*(.+)$/ for (const entry of changelogForVersion) { const externalMatch = releaseEntryExternalContributor.exec(entry) @@ -175,7 +180,16 @@ function getReleaseGroups(version: string): ReleaseNotesGroups { }) } } else { - console.warn(`release entry does not match any format: '${entry}'`) + const plain = releaseEntryNoIds.exec(entry) + const plainCategory = plain ? parseCategory(plain[1]) : null + if (plain && plainCategory) { + releaseNotesByGroup[plainCategory].push({ + text: plain[2].trim(), + ids: [], + }) + } else { + console.warn(`release entry does not match any format: '${entry}'`) + } } } } @@ -191,7 +205,10 @@ function formatReleaseNote(note: ReleaseNoteEntry): string { ? `. Thanks ${note.contributor}!` : '' - const template = ` - ${note.text} - ${idsAsUrls}${contributorNote}` + const template = + note.ids.length === 0 + ? ` - ${note.text}${contributorNote}` + : ` - ${note.text} - ${idsAsUrls}${contributorNote}` return template.trim() }