Skip to content

Sync GitHub Desktop FMA install script with current quit/relaunch helpers - #49030

Merged
allenhouchins merged 1 commit into
mainfrom
48639-github-desktop-fleet-maintained-app-relaunches-the-app-after-a-patch-even-when-it-had-no-open-window-macos
Jul 9, 2026
Merged

Sync GitHub Desktop FMA install script with current quit/relaunch helpers#49030
allenhouchins merged 1 commit into
mainfrom
48639-github-desktop-fleet-maintained-app-relaunches-the-app-after-a-patch-even-when-it-had-no-open-window-macos

Conversation

@allenhouchins

@allenhouchins allenhouchins commented Jul 9, 2026

Copy link
Copy Markdown
Member

Related issue: Resolves #48639

Checklist for submitter

If some of the following don't apply, delete the relevant line.

  • Input data is properly validated, SELECT * is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters.
  • Timeouts are implemented and retries are limited to avoid infinite loops

Testing

  • QA'd all new/changed functionality manually

Details

The GitHub Desktop FMA uses a custom install script (ee/maintained-apps/inputs/homebrew/scripts/github-desktop-install.sh) that embeds its own copies of quit_and_track_application and relaunch_application. Those copies were frozen before two fixes landed in the generated helpers in ee/maintained-apps/ingesters/homebrew/scripts.go:

This PR replaces both embedded functions with the current scripts.go constants (verified byte-for-byte identical) and regenerates ee/maintained-apps/outputs/github/darwin.json via go run ./cmd/maintained-apps -slug github. The manifest diff is script-ref-only (98ab6ed8c91ea2b5); version and uninstall script are unchanged. The other five custom scripts (Docker Desktop, OpenVPN Connect, Webex, Max, Pd) already carry the updated helpers — GitHub Desktop was the only one missed.

Manual QA

Tested the updated quit_and_track_application / relaunch_application functions on macOS against GitHub Desktop itself (com.github.GitHubClient):

  • Fully quit (the bug scenario): verified is running returns false and zero GitHub Desktop.app processes. Fixed functions set APP_WAS_RUNNING=0 and the app stays closed. Running the old shipped check (if ! osascript ...) against the same state misclassifies the app as running (osascript exits 0 with output false) and would have relaunched it.
  • Running: quit succeeds, APP_WAS_RUNNING=1, app relaunches successfully afterward.
  • bash -n passes on the updated script.

Note: hosts where the FMA was already added keep the baked 98ab6ed8 script until their instance refreshes the manifest. The by-design behavior "app running with dock icon but no visible window → relaunched with a window" is unchanged; window-aware relaunching would be a separate enhancement.

Summary by CodeRabbit

  • Bug Fixes
    • Improved GitHub Desktop installation behavior on macOS so the app is more reliably closed and reopened after install.
    • Better handles login/session edge cases, helping ensure the app relaunches in the correct user’s desktop session.
    • Reduces failed or missed relaunches when the installer is run with elevated permissions.

…pers (#48639)

The custom install script embedded pre-#42951/#43842 copies of
quit_and_track_application and relaunch_application. The stale
'if ! osascript' check treats any non-erroring osascript call as
"app is running" (osascript exits 0 whether it prints true or false),
so the app was marked for relaunch on every install and launched
after every patch, even from a fully-quit state.

Replace both functions with the current scripts.go constants
(output-based running check, launchctl-asuser relaunch, updated
console-user guards) and regenerate the darwin manifest.
Copilot AI review requested due to automatic review settings July 9, 2026 14:28
@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Script Diff Results

ee/maintained-apps/outputs/github/darwin.json

=== Install // 98ab6ed8 -> c91ea2b5 ===

--- /tmp/old.gcdJNb	2026-07-09 14:30:00.720352821 +0000
+++ /tmp/new.FZeXt9	2026-07-09 14:30:00.721352824 +0000
@@ -12,14 +12,16 @@
   local timeout_duration=10
 
   # check if the application is running
-  if ! osascript -e "application id \"$bundle_id\" is running" 2>/dev/null; then
+  local app_running
+  app_running=$(osascript -e "application id \"$bundle_id\" is running" 2>/dev/null)
+  if [[ "$app_running" != "true" ]]; then
     eval "export $var_name=0"
     return
   fi
 
   local console_user
   console_user=$(stat -f "%Su" /dev/console)
-  if [[ $EUID -eq 0 && "$console_user" == "root" ]]; then
+  if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
     echo "Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'."
     eval "export $var_name=0"
     return
@@ -63,15 +65,28 @@
 
   local console_user
   console_user=$(stat -f "%Su" /dev/console)
-  if [[ $EUID -eq 0 && "$console_user" == "root" ]]; then
+  if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
     echo "Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'."
     return
   fi
 
   echo "Relaunching application '$bundle_id'..."
 
-  # Try to launch the application
-  if osascript -e "tell application id \"$bundle_id\" to activate" >/dev/null 2>&1; then
+  # Launch the app in the logged-in user's GUI session. Apps launched by root
+  # won't register with the user's Dock/GUI, so run 'open' as the console user.
+  # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace
+  # and GUI session — 'sudo -u' alone doesn't do this, which can cause
+  # LSOpenURLsWithRole() failures even when 'open' exits 0.
+  local open_status=0
+  if [[ $EUID -eq 0 ]]; then
+    local console_uid
+    console_uid=$(id -u "$console_user")
+    /bin/launchctl asuser "$console_uid" sudo -u "$console_user" open -b "$bundle_id" >/dev/null 2>&1 || open_status=$?
+  else
+    open -b "$bundle_id" >/dev/null 2>&1 || open_status=$?
+  fi
+
+  if [[ $open_status -eq 0 ]]; then
     echo "Application '$bundle_id' relaunched successfully."
   else
     echo "Failed to relaunch application '$bundle_id'."

=== Uninstall Script (no changes) ===

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the GitHub Desktop Fleet-maintained app (FMA) install flow on macOS to use the latest shared “quit + track running state” and “relaunch” helper logic, and regenerates the published manifest so managed instances receive the updated script ref.

Changes:

  • Update quit_and_track_application to check osascript output ("true"/"false") instead of exit status.
  • Update relaunch_application to relaunch via launchctl asuser … open -b in the console user’s GUI session, with expanded console-user guards.
  • Regenerate ee/maintained-apps/outputs/github/darwin.json to point to the new install_script_ref.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
ee/maintained-apps/outputs/github/darwin.json Updates GitHub Desktop’s published manifest to reference the new install script content by script ref.
ee/maintained-apps/inputs/homebrew/scripts/github-desktop-install.sh Syncs GitHub Desktop’s custom install script helpers to match the current shared Homebrew ingester helper implementations.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 14 to +17
# check if the application is running
if ! osascript -e "application id \"$bundle_id\" is running" 2>/dev/null; then
local app_running
app_running=$(osascript -e "application id \"$bundle_id\" is running" 2>/dev/null)
if [[ "$app_running" != "true" ]]; then
@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

The GitHub Desktop Homebrew install script (github-desktop-install.sh) was updated to refine app lifecycle handling on macOS. The running-app check in quit_and_track_application now captures osascript's result into a variable and broadens skip-quitting conditions to cover empty, root, or loginwindow console users. relaunch_application now uses open -b instead of AppleScript activate, tracking success via open_status, and when running as root, uses launchctl asuser combined with sudo -u to relaunch within the console user's GUI session. The corresponding darwin.json manifest was updated to reference the new script content via an updated install_script_ref and refs entry.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The fix updates helper scripts, but it still relaunches when the app is running without a visible window, which #48639 says should stay silent. Add window-aware state detection and skip relaunch unless GitHub Desktop had a visible window before patching.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: syncing GitHub Desktop's install script helpers.
Description check ✅ Passed The description includes the related issue, rationale, testing, and manual QA, matching the template well.
Out of Scope Changes check ✅ Passed All file changes are limited to the GitHub Desktop install script and its generated manifest, directly matching the stated fix.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 48639-github-desktop-fleet-maintained-app-relaunches-the-app-after-a-patch-even-when-it-had-no-open-window-macos

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@ee/maintained-apps/inputs/homebrew/scripts/github-desktop-install.sh`:
- Around line 15-24: In the GitHub Desktop install script, the current running
check in the helper around application id and APP_WAS_RUNNING_* only verifies
that the app process exists, which still includes hidden/background sessions.
Update the logic to also confirm there is a visible window before exporting the
relaunch marker, and keep the existing console user handling intact. Add or
adjust the check in the same flow that uses app_running so hidden sessions do
not trigger the relaunch path.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 288de736-ccab-4854-83bd-6ea91b427cfb

📥 Commits

Reviewing files that changed from the base of the PR and between 703dcf0 and 79aaf01.

📒 Files selected for processing (2)
  • ee/maintained-apps/inputs/homebrew/scripts/github-desktop-install.sh
  • ee/maintained-apps/outputs/github/darwin.json

Comment on lines +15 to +24
local app_running
app_running=$(osascript -e "application id \"$bundle_id\" is running" 2>/dev/null)
if [[ "$app_running" != "true" ]]; then
eval "export $var_name=0"
return
fi

local console_user
console_user=$(stat -f "%Su" /dev/console)
if [[ $EUID -eq 0 && "$console_user" == "root" ]]; then
if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf 'FILE: %s\n' ee/maintained-apps/inputs/homebrew/scripts/github-desktop-install.sh
wc -l ee/maintained-apps/inputs/homebrew/scripts/github-desktop-install.sh
sed -n '1,220p' ee/maintained-apps/inputs/homebrew/scripts/github-desktop-install.sh

printf '\nSEARCH APP_WAS_RUNNING / visible / hidden / window references:\n'
rg -n "APP_WAS_RUNNING|visible|hidden|window|osascript|bundle_id" ee/maintained-apps/inputs/homebrew/scripts/github-desktop-install.sh

Repository: fleetdm/fleet

Length of output: 5362


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf 'Search for visible-window predicates and relaunch markers in maintained-app scripts:\n'
rg -n "window 1|visible window|visible|hidden|APP_WAS_RUNNING|relaunch" ee/maintained-apps -g '*.sh'

printf '\nPotentially related GitHub Desktop scripts or docs:\n'
rg -n "GitHub Desktop|GitHubClient|github-desktop" ee/maintained-apps -g '*'

Repository: fleetdm/fleet

Length of output: 17511


Check for a visible window before exporting the relaunch marker. application id ... is running still matches hidden/background-only GitHub Desktop sessions, so APP_WAS_RUNNING_* gets set and the app is relaunched unnecessarily. Add coverage for the running-but-no-visible-window case.

🧰 Tools
🪛 ast-grep (0.44.1)

[error] 17-17: eval is invoked on a variable, parameter expansion, or command-substitution result, which re-parses the value as shell code. If any part of that value is attacker-controlled (arguments, environment, file contents, network output), it allows arbitrary command execution. Do not eval dynamic data: invoke the command directly with proper quoting (e.g. "$cmd" "$arg"), use arrays for argument lists (cmd=(prog --flag "$value"); "${cmd[@]}"), or restrict input to a validated allowlist before running it.
Context: eval "export $var_name=0"
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').

(eval-on-variable-bash)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ee/maintained-apps/inputs/homebrew/scripts/github-desktop-install.sh` around
lines 15 - 24, In the GitHub Desktop install script, the current running check
in the helper around application id and APP_WAS_RUNNING_* only verifies that the
app process exists, which still includes hidden/background sessions. Update the
logic to also confirm there is a visible window before exporting the relaunch
marker, and keep the existing console user handling intact. Add or adjust the
check in the same flow that uses app_running so hidden sessions do not trigger
the relaunch path.

@allenhouchins
allenhouchins merged commit 598f425 into main Jul 9, 2026
14 checks passed
@allenhouchins
allenhouchins deleted the 48639-github-desktop-fleet-maintained-app-relaunches-the-app-after-a-patch-even-when-it-had-no-open-window-macos branch July 9, 2026 14:36
allenhouchins added a commit that referenced this pull request Jul 9, 2026
**Related issue:** Resolves #48638, resolves #48225

# Checklist for submitter

If some of the following don't apply, delete the relevant line.

- [ ] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements), JS
inline code is prevented especially for url redirects, and untrusted
data interpolated into shell scripts/commands is validated against shell
metacharacters.
- [x] Timeouts are implemented and retries are limited to avoid infinite
loops

## Testing

- [x] QA'd all new/changed functionality manually

## Details

Follow-up to #49030 (GitHub Desktop, #48639), which fixed one instance
of this bug. An audit for the raw pattern found **15 more custom FMA
scripts** carrying the same broken check that #42951 fixed in the
generated helpers: gating on the **exit status** of `osascript -e
'application id "..." is running'`. osascript exits 0 whether it prints
`true` or `false`, so a fully-quit app is misclassified as running
whenever the bundle id resolves.

Impact by script:

- **Relaunch after every patch (user-visible — the filed bugs):**
`zoom_install.sh` (#48638) and `google_chrome_install.sh` (#48225) set
`*_WAS_RUNNING=true` unconditionally and reopen the app after
`installer`, even when the user had nothing open.
- **Broken check, no relaunch step (needless quit attempts, misleading
logs):** install scripts for 1Password, Adobe CC, ExpressVPN, Grammarly,
LogiTune, Microsoft Edge, P4V, Slack; uninstall scripts for Adobe CC,
CleanMyMac, GPG Suite, Microsoft Word, P4V. Note `tell application id X
to quit` against a not-running app can briefly launch it to deliver the
quit event, so these aren't purely cosmetic either.

The fix is the same one-line pattern everywhere, style-matched to each
script (`local`/POSIX `[ ]`/top-level variants preserved): capture
osascript output and compare it to `"true"`. No other behavior changed —
this PR deliberately does not touch relaunch methods or console-user
guards.

Regenerated the 13 affected darwin manifests with `go run
./cmd/maintained-apps -slug <slug>`. All diffs are script-ref-only
except `google-chrome/darwin.json`, which also picked up the legitimate
upstream 150.0.7871.115 version bump during regeneration (the daily
ingest cron would publish it tonight regardless). An unrelated
`google-chrome/windows.json` winget bump was excluded.

## Manual QA

Reproduced the bug live on macOS with the shipped Zoom script logic (ref
`05e6a85c`) against a **fully-quit** Zoom (verified `is running` =
`false`, zero processes): the exit-status check set
`ZOOM_WAS_RUNNING=true` and the relaunch step launched Zoom — exactly
the customer report, no background helpers needed. The corrected
output-compare check on the same state correctly reported not running.
Equivalent verification for the shared-helper variant was done against
GitHub Desktop in #49030 (both the fully-quit and running→quit→relaunch
paths).

Verified for all 16 scripts: `bash -n` passes, no `if [!] osascript -e
"application id ...` pattern remains anywhere under
`inputs/homebrew/scripts/`, and every regenerated manifest ref carries
the output-compare check.

Remaining by-design behavior (unchanged): an app running with a dock
icon but no visible window is genuinely running and will still be quit
and relaunched; window-aware relaunching would be a separate
enhancement.


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Improved app detection before install/uninstall steps, reducing
unnecessary quit attempts and making setup flows more reliable.
* Updated several app install/uninstall workflows to better handle
running apps, cleanup, and restart behavior.
* Refined a few app package definitions to point to newer supported
versions.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

GitHub Desktop Fleet-maintained app relaunches the app after a patch even when it had no open window (macOS)

3 participants