Skip to content
Open
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
108 changes: 108 additions & 0 deletions .github/workflows/workstation-gnome-ext.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
name: workstation-gnome-ext

on:
pull_request:
paths:
- 'profiles/linux-dev/workstation-v0/gnome/check-gnome-extensions.sh'
- 'profiles/linux-dev/workstation-v0/gnome/extensions-install.sh'
- 'profiles/linux-dev/workstation-v0/gnome/README.md'
- '.github/workflows/workstation-gnome-ext.yml'
push:
branches:
- main
paths:
- 'profiles/linux-dev/workstation-v0/gnome/check-gnome-extensions.sh'
- 'profiles/linux-dev/workstation-v0/gnome/extensions-install.sh'
- 'profiles/linux-dev/workstation-v0/gnome/README.md'
- '.github/workflows/workstation-gnome-ext.yml'

jobs:
gnome-ext-smoke:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Syntax check
run: |
set -euo pipefail
bash -n profiles/linux-dev/workstation-v0/gnome/check-gnome-extensions.sh
bash -n profiles/linux-dev/workstation-v0/gnome/extensions-install.sh

- name: Smoke: key presence in non-GNOME environment
run: |
set -euo pipefail
helper='profiles/linux-dev/workstation-v0/gnome/check-gnome-extensions.sh'
out=$(bash "$helper")
grep -F 'gnome_detected=' <<<"$out" >/dev/null
grep -F 'gnome_extensions_cli=' <<<"$out" >/dev/null
grep -F 'gsettings=' <<<"$out" >/dev/null
grep -F 'dash_to_dock=' <<<"$out" >/dev/null
grep -F 'appindicator=' <<<"$out" >/dev/null
grep -F 'favorite_apps=' <<<"$out" >/dev/null
grep -F 'dock_position=' <<<"$out" >/dev/null
grep -F 'dock_autohide=' <<<"$out" >/dev/null
grep -F 'dock_intellihide=' <<<"$out" >/dev/null
# Non-GNOME CI runner: detected=no, extension status=unknown
grep -F 'gnome_detected=no' <<<"$out" >/dev/null
grep -F 'dash_to_dock=unknown' <<<"$out" >/dev/null
grep -F 'appindicator=unknown' <<<"$out" >/dev/null

- name: Smoke: stub gnome-extensions CLI detects enabled extensions
run: |
set -euo pipefail
helper='profiles/linux-dev/workstation-v0/gnome/check-gnome-extensions.sh'
stub_bin=$(mktemp -d)
# Both --enabled and plain list return the extensions (they are installed and enabled)
cat > "$stub_bin/gnome-extensions" <<'STUB'
#!/usr/bin/env bash
if [[ "${1:-}" == "list" && "${2:-}" == "--enabled" ]]; then
printf 'dash-to-dock@micxgx.gmail.com\n'
printf 'appindicatorsupport@rgcjonas.gmail.com\n'
elif [[ "${1:-}" == "list" ]]; then
printf 'dash-to-dock@micxgx.gmail.com\n'
printf 'appindicatorsupport@rgcjonas.gmail.com\n'
fi
STUB
chmod +x "$stub_bin/gnome-extensions"
out=$(PATH="$stub_bin:$PATH" bash "$helper")
grep -F 'gnome_extensions_cli=present' <<<"$out" >/dev/null
grep -F 'dash_to_dock=enabled' <<<"$out" >/dev/null
grep -F 'appindicator=enabled' <<<"$out" >/dev/null

- name: Smoke: stub gnome-extensions CLI detects present-but-not-enabled
run: |
set -euo pipefail
helper='profiles/linux-dev/workstation-v0/gnome/check-gnome-extensions.sh'
stub_bin=$(mktemp -d)
# --enabled returns nothing; plain list returns both
cat > "$stub_bin/gnome-extensions" <<'STUB'
#!/usr/bin/env bash
if [[ "${1:-}" == "list" && "${2:-}" == "--enabled" ]]; then
exit 0
elif [[ "${1:-}" == "list" ]]; then
printf 'dash-to-dock@micxgx.gmail.com\n'
printf 'appindicatorsupport@rgcjonas.gmail.com\n'
fi
STUB
chmod +x "$stub_bin/gnome-extensions"
out=$(PATH="$stub_bin:$PATH" bash "$helper")
grep -F 'dash_to_dock=present' <<<"$out" >/dev/null
grep -F 'appindicator=present' <<<"$out" >/dev/null

- name: Smoke: stub gnome-extensions CLI detects missing extensions
run: |
set -euo pipefail
helper='profiles/linux-dev/workstation-v0/gnome/check-gnome-extensions.sh'
stub_bin=$(mktemp -d)
# Empty list — nothing installed
cat > "$stub_bin/gnome-extensions" <<'STUB'
#!/usr/bin/env bash
exit 0
STUB
chmod +x "$stub_bin/gnome-extensions"
out=$(PATH="$stub_bin:$PATH" bash "$helper")
grep -F 'dash_to_dock=missing' <<<"$out" >/dev/null
grep -F 'appindicator=missing' <<<"$out" >/dev/null
25 changes: 25 additions & 0 deletions profiles/linux-dev/workstation-v0/gnome/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,31 @@ This lane adds bounded visual/workflow polish without replacing GNOME Shell or l
- `files-sidebar.sh` seeds GTK/Nautilus bookmarks for Desktop, Documents, Downloads, Pictures, Screenshots, Music, Videos, and Public.
- The workstation installer runs both helpers best-effort after the extension pinset and before input/gesture setup.

## Extension/dock validation helper

`check-gnome-extensions.sh` emits `key=value` status for the GNOME extension and dock lane so that `doctor`, `status`, and CI can reason about it without a live GNOME session.

Keys emitted:

| Key | Values |
|-----|--------|
| `gnome_detected` | `yes` / `no` |
| `gnome_extensions_cli` | `present` / `missing` |
| `gsettings` | `present` / `missing` |
| `dash_to_dock` | `enabled` / `present` / `missing` / `unknown` |
| `appindicator` | `enabled` / `present` / `missing` / `unknown` |
| `favorite_apps` | gsettings value or `unknown` |
| `dock_position` | gsettings value or `unknown` |
| `dock_autohide` | gsettings value or `unknown` |
| `dock_intellihide` | gsettings value or `unknown` |

**Known gaps:** extension status is `unknown` when `gnome-extensions` CLI is absent (e.g. on a CI runner or server). Dock gsettings keys are `unknown` when the Dash-to-Dock schema is not installed.

```bash
bash -n gnome/check-gnome-extensions.sh # syntax check
bash gnome/check-gnome-extensions.sh # emit status
```

## Keyboard/remap policy v1

The workstation keeps keyboard remapping explicit and policy-gated:
Expand Down
72 changes: 72 additions & 0 deletions profiles/linux-dev/workstation-v0/gnome/check-gnome-extensions.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#!/usr/bin/env bash
set -euo pipefail

# Lightweight GNOME extension/dock status helper for workstation-v0.
# Emits key=value lines so doctor/status/CI can reason about the dock and
# extension lane without broad GNOME rewrites.
# Safe to run outside a GNOME session; degrades gracefully to "unknown".

have(){ command -v "$1" >/dev/null 2>&1; }

is_gnome(){
[[ "${XDG_CURRENT_DESKTOP:-}" == *GNOME* ]] && return 0
[[ "${DESKTOP_SESSION:-}" == *gnome* ]] && return 0
return 1
}

# Returns: enabled | present | missing | unknown
ext_status(){
local uuid=$1
if ! have gnome-extensions; then
printf 'unknown\n'
return
fi
if gnome-extensions list --enabled 2>/dev/null | grep -qx "$uuid"; then
printf 'enabled\n'
return
fi
if gnome-extensions list 2>/dev/null | grep -qx "$uuid"; then
printf 'present\n'
return
fi
printf 'missing\n'
}

gsetting_get(){
local schema=$1 key=$2
if have gsettings; then
gsettings get "$schema" "$key" 2>/dev/null || printf 'unknown\n'
else
printf 'unknown\n'
fi
}

main(){
if is_gnome; then
printf 'gnome_detected=yes\n'
else
printf 'gnome_detected=no\n'
fi

if have gnome-extensions; then
printf 'gnome_extensions_cli=present\n'
else
printf 'gnome_extensions_cli=missing\n'
fi

if have gsettings; then
printf 'gsettings=present\n'
else
printf 'gsettings=missing\n'
fi

printf 'dash_to_dock=%s\n' "$(ext_status 'dash-to-dock@micxgx.gmail.com')"
printf 'appindicator=%s\n' "$(ext_status 'appindicatorsupport@rgcjonas.gmail.com')"

printf 'favorite_apps=%s\n' "$(gsetting_get org.gnome.shell favorite-apps)"
printf 'dock_position=%s\n' "$(gsetting_get org.gnome.shell.extensions.dash-to-dock dock-position)"
printf 'dock_autohide=%s\n' "$(gsetting_get org.gnome.shell.extensions.dash-to-dock autohide)"
printf 'dock_intellihide=%s\n' "$(gsetting_get org.gnome.shell.extensions.dash-to-dock intellihide)"
}

main "$@"
43 changes: 43 additions & 0 deletions tests/workstation-gnome-ext-contract.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{ pkgs ? import <nixpkgs> {} }:
pkgs.runCommand "workstation-gnome-ext-contract" {
nativeBuildInputs = [ pkgs.bash pkgs.gnugrep ];
} ''
helper=${../profiles/linux-dev/workstation-v0/gnome/check-gnome-extensions.sh}

# File must exist and be non-empty
test -f "$helper"
test -s "$helper"

# Syntax check
bash -n "$helper"

# Static: required keys must be referenced in the script
grep -q 'gnome_detected' "$helper"
grep -q 'gnome_extensions_cli' "$helper"
grep -q 'gsettings' "$helper"
grep -q 'dash_to_dock' "$helper"
grep -q 'appindicator' "$helper"
grep -q 'favorite_apps' "$helper"
grep -q 'dock_position' "$helper"
grep -q 'dock_autohide' "$helper"
grep -q 'dock_intellihide' "$helper"

# Static: pinned extension UUIDs must be present
grep -q 'dash-to-dock@micxgx.gmail.com' "$helper"
grep -q 'appindicatorsupport@rgcjonas.gmail.com' "$helper"

# Runtime: run helper in non-GNOME sandbox (no GNOME session, no dbus)
helper_out=$(bash "$helper")
grep -F 'gnome_detected=' <<<"$helper_out"
grep -F 'gnome_extensions_cli=' <<<"$helper_out"
grep -F 'gsettings=' <<<"$helper_out"
grep -F 'dash_to_dock=' <<<"$helper_out"
grep -F 'appindicator=' <<<"$helper_out"
grep -F 'favorite_apps=' <<<"$helper_out"
grep -F 'dock_position=' <<<"$helper_out"
grep -F 'dock_autohide=' <<<"$helper_out"
grep -F 'dock_intellihide=' <<<"$helper_out"

mkdir -p $out
echo validated > $out/result.txt
''