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() }