Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions guest/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,15 @@ direct-boot kernel and matching headers are held, while the packaged
repository. A separate migration channel is required before those
Try-Omarchy-specific revisions can advance on an existing disk without reset.

New guests show a normal-priority first-login **Update packages and finish setup**
invitation: "Update supported Linux packages and discover optional features such
as dictation." It launches the Omarchy updater once networking is ready, without
claiming that updates are available or that the pinned runtime and boot files
can advance. The reviewed `first-run-update-notification` patch changes only
that invitation when the Try Omarchy build spec is present. Wi-Fi setup, welcome
and other notifications, the update indicator, and user-initiated update commands
remain available.

The kernel reboot check recognizes package-owned `modules.builtin` metadata as
well as `vmlinuz` under `/usr/lib/modules/<release>/`. Arch Linux ARM does not
place `vmlinuz` there, so requiring that file alone produces a false kernel-update
Expand Down
16 changes: 16 additions & 0 deletions guest/patches/omarchy/first-run-update-notification.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
diff --git a/install/user/first-run/wifi.sh b/install/user/first-run/wifi.sh
--- a/install/user/first-run/wifi.sh
+++ b/install/user/first-run/wifi.sh
@@ -1,4 +1,12 @@
notify_update() {
+ # Try Omarchy's updater handles supported packages and optional first-run setup.
+ if [[ -f /usr/share/try-omarchy/build-spec.json ]]; then
+ omarchy-notification-send -u normal -g  "Update packages and finish setup" \
+ "Update supported Linux packages and discover optional features such as dictation." \
+ --exec omarchy-launch-floating-terminal-with-presentation omarchy-update
+ return 0
+ fi
+
omarchy-notification-send -u critical -g  "Update System" "Click to update the system." \
--exec omarchy-launch-floating-terminal-with-presentation omarchy-update
}
14 changes: 14 additions & 0 deletions guest/spec.json
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,20 @@
}
]
},
{
"id": "first-run-update-notification",
"description": "Clarify the first-login invitation for supported package updates and optional setup in the pinned Try Omarchy guest.",
"reference": "https://github.com/basecamp/omarchy/blob/c668141e9c42b13c80c9ca4ea108e11708c5e8a5/install/user/first-run/wifi.sh",
"patch": "patches/omarchy/first-run-update-notification.patch",
"patchSha256": "05d95049f1a6dd3efaa59c429d6922835e1c54b1d3b0286db30378f60eb7847f",
"targets": [
{
"path": "install/user/first-run/wifi.sh",
"beforeSha256": "4cc2621157be1efe6d449d1daa7b28d588e4a8e46127de493da03749af1ae5a7",
"afterSha256": "cbbffcfd2685c0b9853ee144a7acba64dfa9340cc65a3d144a925055810f0f66"
}
]
},
{
"id": "pkg-add-aarch64-unavailable",
"description": "Refuse known aarch64-unavailable packages from omarchy-pkg-add with the shared message.",
Expand Down
30 changes: 30 additions & 0 deletions guest/tests/fixtures/first-run-wifi.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
notify_update() {
omarchy-notification-send -u critical -g  "Update System" "Click to update the system." \
--exec omarchy-launch-floating-terminal-with-presentation omarchy-update
}

notify_wifi() {
omarchy-notification-send -u critical -g 󰖩 "Setup Wi-Fi" "Click to configure the wireless network." \
--exec omarchy-shell shell toggle omarchy.network
}

announce_network() {
# Ethernet is still negotiating DHCP when the session starts, so probing
# right away calls a working machine offline. NetworkManager reports startup
# complete once it has tried every connection it could auto-activate, which
# is the first moment the answer means anything.
nm-online -q -s -t 30

# -x takes that answer as it stands rather than waiting out the timeout, so
# a laptop with nothing to connect to gets prompted immediately.
if ! nm-online -q -x -t 30; then
notify_wifi
# Nothing to update against until a link lands, so hold that prompt.
nm-online -q -t 3600 || return
fi

notify_update
}

# Detached, so a slow or absent connection never holds up the rest of first run.
announce_network &
86 changes: 86 additions & 0 deletions guest/tests/test_first_run_update_notification.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
from __future__ import annotations

import importlib.util
import json
import os
from pathlib import Path
import subprocess
import tempfile
import unittest


GUEST = Path(__file__).resolve().parents[1]
MODULE = importlib.util.spec_from_file_location(
"backports", GUEST / "scripts/apply-omarchy-backports.py"
)
backports = importlib.util.module_from_spec(MODULE)
MODULE.loader.exec_module(backports)


class FirstRunUpdateNotificationTests(unittest.TestCase):
def run_first_run(self, *, try_omarchy=True, online=True, reconnect=True):
with tempfile.TemporaryDirectory() as temporary:
root = Path(temporary)
spec = json.loads((GUEST / "spec.json").read_text())
backport = next(b for b in spec["authenticity"]["backports"]
if b["id"] == "first-run-update-notification")
omarchy = root / "usr/share/omarchy"
command = omarchy / backport["targets"][0]["path"]
command.parent.mkdir(parents=True)
command.write_bytes((GUEST / "tests/fixtures/first-run-wifi.sh").read_bytes())
backports.apply_backport(GUEST, root, omarchy, backport)
marker = root / "build-spec.json"
if try_omarchy:
marker.touch()
# Execute the complete first-run script, redirecting only its guest
# identity check and stubbing network and desktop side effects.
script = command.read_text().replace(
"/usr/share/try-omarchy/build-spec.json", str(marker)
)
stubs = '''
nm-online() {
case "$*" in
*"-s"*) return 0 ;;
*"-x"*) return "$OFFLINE" ;;
*) return "$NO_RECONNECT" ;;
esac
}
omarchy-notification-send() { printf '%s\n' "$*"; }
'''
result = subprocess.run(
["bash", "-c", stubs + script + "\nwait\n"],
env={**os.environ, "OFFLINE": str(int(not online)),
"NO_RECONNECT": str(int(not reconnect))},
text=True, capture_output=True, check=True, timeout=5,
)
return result.stdout

def test_online_guest_invites_package_updates_and_optional_setup(self):
self.assertEqual(
self.run_first_run(),
"-u normal -g  Update packages and finish setup "
"Update supported Linux packages and discover optional features such as dictation. "
"--exec omarchy-launch-floating-terminal-with-presentation omarchy-update\n",
)

def test_wifi_invitation_survives_reconnection(self):
output = self.run_first_run(online=False)
self.assertIn("Setup Wi-Fi", output)
self.assertIn("omarchy-shell shell toggle omarchy.network", output)
self.assertIn("Update packages and finish setup", output)
self.assertNotIn("Update System", output)

def test_offline_guest_still_invites_wifi_setup(self):
output = self.run_first_run(online=False, reconnect=False)
self.assertIn("Setup Wi-Fi", output)
self.assertNotIn("Update packages and finish setup", output)
self.assertNotIn("Update System", output)

def test_non_try_omarchy_keeps_upstream_invitation(self):
output = self.run_first_run(try_omarchy=False)
self.assertIn("Update System", output)
self.assertIn("omarchy-launch-floating-terminal-with-presentation omarchy-update", output)


if __name__ == "__main__":
unittest.main()
1 change: 1 addition & 0 deletions guest/tests/verify.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ def main() -> None:
"notification-screen-privacy",
"update-free-space-message",
"update-restart-arm-kernel",
"first-run-update-notification",
"pkg-add-aarch64-unavailable",
"pkg-aur-add-aarch64-unavailable",
"dropbox-aarch64-unavailable",
Expand Down
Loading