Skip to content
This repository was archived by the owner on Sep 8, 2026. It is now read-only.

cleanup: remove dead keyboard/language/timezone wizard steps - #194

Open
castrojo wants to merge 1 commit into
mainfrom
feature/187-remove-dead-locale-steps
Open

castrojo wants to merge 1 commit into
mainfrom
feature/187-remove-dead-locale-steps

Conversation

@castrojo

Copy link
Copy Markdown
Collaborator

Removes defaults/{keyboard,language,timezone}.py and related core helpers, Blueprint UI files, and data (dinosaurs.json). These implemented full wizard steps but were never registered in builder.py and never applied to the installed system.

Tests: 398 passed, 2 skipped. Ruff clean on changed files.

Closes #187

@hanthor hanthor left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Merge conflicts — needs rebase on main. The cleanup itself (removing ~650 lines of dead wizard code) is correct and well-scoped. Please rebase and re-push to trigger CI.

These modules implemented full wizard steps but were never registered
in builder.py and never applied to the installed system. Removing to
reduce maintenance surface and confusion.

Closes #187

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@castrojo
castrojo force-pushed the feature/187-remove-dead-locale-steps branch from e43e482 to 0e11e90 Compare June 30, 2026 02:22
castrojo pushed a commit that referenced this pull request Jun 30, 2026
…, branch note

- dev.sh -> run-dev.sh (renamed on main branch)
- Remove keymaps.py, keyboard.py, language.py, timezone.py from module map (removed by PR #194)
- Remove test_timezone.py from GTK test examples (removed by PR #194)
- Mark dead-code quality finding as resolved
- Add note: PRs targeting main bypass CI — check manually with gh pr checks

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions

Copy link
Copy Markdown

✅ Flatpak manifests validated successfully

  • GNOME: org.bootcinstaller.Installer

@hanthor hanthor left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Review: Approved ✅

Clean dead code removal. Verified:

  • 22 files deleted (2564 lines removed, 0 added) — correct pattern
  • BootcDefaultKeyboard, BootcDefaultLanguage, BootcDefaultTimezone are not imported anywhere
  • core/keymaps.py, core/languages.py, core/timezones.py have no remaining imports
  • dinosaurs.json only loaded by dead timezone module
  • All 6 Blueprint UI files, gresource.xml refs, and meson entries consistently removed
  • 4 dead test files removed
  • Zero remaining references across the repo

PR mergeable and conflict-free.

@castrojo castrojo added the 4-review A pull request is awaiting review. label Jul 29, 2026
hanthor added a commit to tuna-os/bootc-installer that referenced this pull request Aug 7, 2026
* docs(agents): update coverage baseline to 28%, add QR Companion files and CI gotchas

- Raise --cov-fail-under from 26 to 28 (measured: 28.07%, 405 tests, 5811 stmts)
- Add test_qr_companion.py to test suite layout table
- Add qr_companion.py and phone_companion.py to key files table
- Mark QR Phone Companion as Done (was 'landing')
- Add two new Known Issues: GitHub Actions silent skip on conflicting branches,
  and CompanionServer/get_local_ip must be mocked in any UI test navigating
  past the QR Companion step

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* docs: fix tuna-os org refs in install commands, add submodule init step, add CONTRIBUTING.md

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* docs: correct contributing demo command and PR target branch

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* trim CLAUDE.md: add Don'ts section, minor discoverable trim, ~100→~75 lines (projectbluefin#191)

* fix(test): resolve gi stub contamination regression from PR #50

- test_done.py: add Adw.Window to gi stubs, replace bare MagicMock Gio
  with proper stub (bus_get_sync, BusType, DBusCallFlags,
  ResourceLookupFlags, resources_lookup_data, File)
- test_branding_parity.py: patch pathlib.Path.read_text instead of
  builtins.open for __load_tracks dev-mode fallback

Fixes 11 failing tests across test_done.py and test_branding_parity.py.

Closes #61

* trim CLAUDE.md: add Don'ts section, minor discoverable trim, ~100→~75 lines

Per arXiv:2602.11988: keep context files minimal, only non-obvious requirements.

Added: Don'ts section (don't change 3-partition GPT, don't use /run/*
for scratch, don't skip submodule push sequence, don't pass recipe
from filesystem).

Removed: directory structure tree (discoverable), image catalog detail
(discoverable from data/images.json), diagnostic commands (task-specific).

Already the leanest file in the set — kept all critical constraints
and the non-obvious submodule workflow.

* replace AGENTS.md with redirect to CLAUDE.md (dedup)

Per arXiv:2602.11988: keep one context file per repo. CLAUDE.md is the
trimmed canonical version; AGENTS.md now redirects to it (same pattern
as Tavern/agents.md).

* chore(fisherman): update submodule — OCI layout path for non-composefs installs (projectbluefin#192)

* docs(agents): update coverage baseline to 28%, add QR Companion files and CI gotchas (projectbluefin#117)

- Raise --cov-fail-under from 26 to 28 (measured: 28.07%, 405 tests, 5811 stmts)
- Add test_qr_companion.py to test suite layout table
- Add qr_companion.py and phone_companion.py to key files table
- Mark QR Phone Companion as Done (was 'landing')
- Add two new Known Issues: GitHub Actions silent skip on conflicting branches,
  and CompanionServer/get_local_ip must be mocked in any UI test navigating
  past the QR Companion step

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* test(unit): harden test_done.py and test_run_async.py (projectbluefin#105) (projectbluefin#115)

test_done.py:
- Use SimpleNamespace for BusType/DBusCallFlags stubs so typos like
  .BusTyp raise AttributeError immediately instead of silently returning None
- Replace _fresh_done() helper with setUp() pattern: rebuild stubs and
  clear cached views.done attr (delattr pattern via __dict__.pop) each test
- Add Adw.Window, ResourceLookupFlags, File to gi stubs
- Add test_dbus_reboot_calls_correct_method: asserts bus name includes
  'login1', interface includes 'Manager', and method name is 'Reboot'

test_run_async.py:
- Replace sys.modules.setdefault() with _import_run_async_fresh() helper
  that always installs a clean GLib mock before reimporting the module,
  preventing stub contamination from other test files

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix: resolve install layout issues (projectbluefin#124) (projectbluefin#141)

- Make hostname field more prominent: move it into its own
  'Device Name' PreferencesGroup with a descriptive subtitle
  so users cannot easily overlook it during installation.

- Enable back navigation from confirm screen: split the
  is_final/is_confirm check so btn_back remains visible and
  sensitive on the confirm page, letting users review and
  correct settings (disk, hostname, encryption) before
  committing.

- Generate a unique hardware-derived hostname as the default:
  * When no image step is present, seed hostname_entry with
    Systeminfo.generate_hostname() instead of the generic
    'localhost' placeholder.
  * When an image provides a default_hostname (e.g. 'bluefin'),
    append the hardware suffix from generate_hostname() so each
    machine gets a distinct name like 'bluefin-7c90' rather than
    every install sharing the same hostname.

Fixes: projectbluefin#124

Signed-off-by: GitHub Copilot <copilot@github.com>
Co-authored-by: GitHub Copilot <copilot@github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* test(unit): add coverage for utils/finals.py and utils/builder.py (projectbluefin#136) (projectbluefin#142)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* test(unit): add coverage for utils/phone_companion.py (projectbluefin#131) (projectbluefin#143)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* test(unit): add coverage for defaults/disk.py pure logic (projectbluefin#138) (projectbluefin#144)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* test(unit): add coverage for defaults/timezone.py and defaults/language.py (projectbluefin#137) (projectbluefin#146)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* test(unit): add coverage for defaults/keyboard.py and defaults/encryption.py (projectbluefin#137) (projectbluefin#147)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* ci: raise unit coverage gate from 28% to 34% (measured 34.29%) (projectbluefin#145)

Closes projectbluefin#132

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* ci: raise unit coverage gate from 34% to 39% (measured 39.61%) (projectbluefin#148)

After merging timezone, language, keyboard, and encryption test PRs
(projectbluefin#146, projectbluefin#147), measured coverage is 39.61%.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* docs(agents): update coverage baseline, test layout, and GTK testing patterns (projectbluefin#149)

- Coverage baseline: 28% / 405 tests → 39.61% / 472 tests, gate 39%
- CI note: 400+ → 470+ unit tests
- Test suite layout: add test_finals, test_builder, test_phone_companion,
  test_disk, test_timezone, test_language, test_keyboard, test_encryption
- finals.py rule: now points to test_finals.py (dedicated file)
- disk/encryption get_finals() rule: points to dedicated test files
- Key files table: add all 8 new test files with descriptions
- Known issues: add __new__ + attribute injection GTK testing pattern

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* test(unit): add coverage improvements and fix all ruff quality issues (projectbluefin#163)

* test(unit): add coverage for processor, image helpers, system.py; raise gate to 42%

- TestManualPartitionLayout, TestDiskInfoVariants, TestImageFallbackPaths in
  test_processor.py (+141 lines) covering manual partition paths, disk dict
  variants, plain string disk, local_imgref, additionalImageStores
- TestImgrefToPrettyName, TestCountLeaves, TestFetchRemoteFlatpakList,
  TestLoadManifestOverrides in test_image_helpers.py (+~60 lines); fix
  _imgref_to_pretty_name for slashless input
- test_system.py expanded to 40 tests covering generate_hostname, has_nvidia_gpu,
  is_uefi, is_ram_enough, is_cpu_enough, _detect_display_devices (73% -> 96%)
- Raise CI unit coverage gate: --cov-fail-under=34 -> --cov-fail-under=42

534 tests passing, 42% total coverage.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* docs(agents): update coverage baseline to 42%, add test_image_helpers/test_system entries

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix: resolve all ruff quality issues across source and tests

- Remove unused imports (F401) in 20+ files
- Add missing gettext import to encryption.py (fixes F821 undefined _)
- Add logger definition to done.py (fixes F821 undefined logger)
- Remove/rename unused local variables (F841) in encryption.py, confirm.py, done.py
- Add # noqa: E402 to intentional GTK-init-ordered imports in main.py, progress.py, test UI files
- Rename ambiguous variable l → line in test_progress_parser.py, test_e2e_install.py (E741)
- Rewrite membership tests to use 'not in' form (E713)

All 534 unit tests pass. ruff check bootc_installer/ tests/ → clean.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* docs(agents): add ruff lint step to Python GUI workflow

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* quality: add codecov.yml, 131 new unit tests, raise coverage gate to 47% (projectbluefin#167)

* test(unit): expand coverage - manifest fallback chain, recovery key, welcome, vm/nvidia/theme

Fixes 5 failing TestLoadManifestOverrides tests by using _import_image_fresh()
to reload the module with proper gi stubs (avoids real Gio C-extension patching issue).

Coverage improvements:
- defaults/welcome.py: 56% → 68% (bluetooth detection edge cases, get_finals, should_show)
- views/recovery_key.py: 38% → 79% (set_recovery_key, ack_toggled, on_continue, on_copy)
- defaults/nvidia.py: 66% → 69% (show_info_popover)
- defaults/theme.py: 56% → 59% (get_finals)
- defaults/vm.py: 67% (get_finals with None)
- defaults/image.py: all 5 manifest fallback path tests now pass in full suite

Total: 42% → 46%, tests: 534 → 623

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* ci: raise coverage gate from 42% to 46%

Measured coverage after adding 89 new unit tests covering:
- manifest fallback chain (image.py)
- recovery key widget logic (recovery_key.py)
- bluetooth detection edge cases (welcome.py)
- vm/nvidia/theme step finals and actions

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* docs(agents): update coverage baseline to 46%, add Gio C-extension patch pitfall, new test files

- Coverage baseline: 42% → 46% / 534 → 623 tests / post-PR projectbluefin#164
- CI gate reference: 42% → 46%
- Key per-module baselines: processor/parser/codec at 100%, disks at 99%
- Test suite layout: add test_diskutils, test_recovery_key, test_welcome entries
- Key files table: add test_diskutils, test_recovery_key, test_welcome, test_defaults_misc
- Known issues: add 'patch(...Gio.method) fails when real GIO loaded first' pattern with fix

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* quality: add codecov.yml, 42 new unit tests, raise coverage gate to 47%

- Add codecov.yml with 45% project target and 70% informational patch
  coverage target; add codecov/codecov-action@v5 upload step to CI
- tests/unit/test_dialog_recovery.py: 6 tests for _host_binary_exists()
  (subprocess success/failure/exception/argument checks)
- tests/unit/test_layouts.py: 26 tests for BootcLayoutYesNo and
  BootcLayoutPreferences (get_finals, should_show, __on_response,
  __on_info, __next_step including _managed logic and toast/dialog paths)
- tests/unit/test_tour_helpers.py: 10 tests for BootcTour.__build_ui()
  asset URI routing (resource:///, resource://, absolute path, GResource)
- Raises CI gate from 46% to 47% (measured: 47.57%, 665 tests total)
- Update AGENTS.md coverage baseline and test layout tables

Closes projectbluefin#165
Closes projectbluefin#166

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* docs(agents): document dialog stub staleness and pytest-cov rounding pitfalls (projectbluefin#168)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* docs: complete agent setup (copilot-instructions, PR template, issue templates, README fixes, CI guide) (projectbluefin#172)

* docs(agents): document dialog stub staleness and pytest-cov rounding pitfalls

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* docs(agents): sync AGENTS.md and CLAUDE.md with current codebase reality

- Repository layout: add KDE/XFCE variants, widgets/, layouts/, kde/,
  confirm_data.py, recipe.py, run-dev.sh, BUILD_ALL_VARIANTS.sh,
  MULTI_VARIANT_BUILD.md, QUALIFY_SOFTWARE.sh, docs/
- Architecture: document three DE variants (GNOME/XFCE/KDE), their
  entry points, Flatpak IDs, and the meson -Dvariant= selector
- Dev workflow: add run-dev.sh loop, BUILD_ALL_VARIANTS.sh, toolbox
  pattern, BOOTC_DEMO=1 intercept point
- CI/releases: correct test count (665+, not 620+), coverage gate (47%, not 48%)
- Test suite: add 10 new test files (test_disks, test_main_window,
  test_meson_sources, test_network_helpers, test_progress,
  test_progress_parser, test_recipe, test_confirm_progress,
  test_e2e_install) with descriptions
- Integration tests: document tests/integration/ (root + QEMU/NBD,
  not in standard CI)
- Coverage baseline: update all per-module numbers (measured 2026-06-06)
- Key files: add all new modules (widgets, layouts, kde, additional
  windows/dialogs, progress_parser, recipe, confirm_data, run-dev.sh,
  docs/ subdirs)
- Sync rules: add test update rules for recipe.py, meson_sources,
  network_helpers, disks, progress_parser, progress.py, new .py files
- Future arch: add multi-variant installer as Done item
- CLAUDE.md: update project overview, build commands (variants),
  module layout, fisherman remote (projectbluefin, not tuna-os),
  testing section, known issues

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* docs: add copilot-instructions, PR template, issue templates; fix CI guide and README

- .github/copilot-instructions.md: concise agent guide (module map, CI table, constraints)
- .github/pull_request_template.md: standard PR template with agent accountability checkbox
- .github/ISSUE_TEMPLATE/config.yml + bug-report.yml: structured issue forms
- .github/CI_CD_GUIDE.md: complete rewrite covering all 6 workflows accurately
  (python-test, go-test, flatpak, build-flatpaks, validate-flatpak, nightly)
- README.md: fix icon path (org.bootcos → org.bootcinstaller), title, tuna-os → projectbluefin URLs

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* docs: add docs/skills/SKILL.md and PITFALLS.md

Canonical in-repo skill reference for AI agents working on bootc-installer.
Covers dev loop, testing patterns, GTK unit testing without a display,
fisherman submodule workflow, CI table, and engineering gotchas.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix(recipe): remove unreachable dead code in __detect_local_bootc_image (projectbluefin#174)

Lines 140-141 (logger.error + sys.exit) were after 'return ""' in
__detect_local_bootc_image() — they could never execute. Leftover
copy-paste artifact from the __load() method.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* docs: update skill — GNOME-only alpha, remove KDE/XFCE/libpastry refs (projectbluefin#176)

Remove the multi-variant GUI table (GNOME/XFCE/KDE), pastry_compat.py
from module map, and -Dvariant= from meson setup example. Update test
count (662) and coverage stmts (5673) to reflect post-PR-projectbluefin#175 state.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* chore: remove libpastry, KDE/XFCE stubs, and VanillaOS artifacts (projectbluefin#175)

* fix(recipe): remove unreachable dead code in __detect_local_bootc_image

Lines 140-141 (logger.error + sys.exit) were after 'return ""' in
__detect_local_bootc_image() — they could never execute. Leftover
copy-paste artifact from the __load() method.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* chore: remove libpastry, KDE/XFCE variants, and VanillaOS artifacts

Remove dead code and lineage artifacts to ship a clean GNOME alpha:

- Purge libpastry: delete pastry_compat.py and all 4 call-sites
  (done.py, progress.py, dialog_credits.py, main_window.py)
- Remove KDE variant stub (main_qt.py, kde/, kde-bootc-installer.in,
  flatpak manifest, data files)
- Remove XFCE variant stub (flatpak manifest, data files,
  xfce-bootc-installer.in)
- Remove VanillaOS branding artifacts (appdata, desktop, gschema, policy)
- Simplify meson.build: drop variant option (GNOME only)
- Simplify BUILD_ALL_VARIANTS.sh and MULTI_VARIANT_BUILD.md
- Update QUALIFY_SOFTWARE.sh to only validate GNOME manifests
- 662 unit tests pass, 48% coverage (gate: 47%)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* ci: remove XFCE/KDE variant checks from validate-flatpak workflow

GNOME-only now — validate only org.bootcinstaller.Installer.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix(ci): delete stale release before re-publishing to avoid immutable release error (projectbluefin#177)

GitHub marks pre-releases as immutable after initial publication, causing
asset uploads to fail with 'Cannot upload asset to an immutable release'.
Fix by deleting the existing continuous/continuous-dev release+tag before
softprops/action-gh-release recreates it fresh on every dev/prod push.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix(ci): rename release tags continuous→latest-stable/latest-dev (projectbluefin#178)

GitHub permanently flags tag names used by immutable releases and
refuses to recreate them even after the immutable-releases setting
is disabled. 'continuous' and 'continuous-dev' are stuck.

Rename to 'latest-stable' and 'latest-dev' to unblock the pipeline.
dakota-iso updated in the same fix to match.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* docs: rewrite README with full feature documentation (projectbluefin#179)

Cover the complete install pipeline, instant-boot features, Windows
data migration, phone companion, video playback, offline/live ISO mode,
and the 3-partition layout rationale. Update install commands to use
the new latest-stable/latest-dev release tags.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* test: add unit tests for windows, widgets, confirm; raise coverage gate to 51% (projectbluefin#173)

Add 50 new unit tests across three new test files:
- test_windows_dialogs.py (21 tests): dialog.py, dialog_output.py,
  dialog_poweroff.py, window_cpu.py, window_ram.py, window_unsupported.py
- test_page_header.py (12 tests): widgets/page_header.py GObject.Property
  getters/setters and subtitle set_visible logic
- test_confirm_view.py (17 tests): views/confirm.py process_keyboards()
  and update() dispatch

All modules previously had 0% unit coverage. Uses __new__ + attribute
injection pattern (no display required).

Raise --cov-fail-under from 47 to 51 (measured: 51%, 5825 stmts).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* docs: clarify boot stacks — highlight Dakota systemd-boot/composefs featureset (projectbluefin#180)

* docs: clarify boot stacks — highlight Dakota systemd-boot/composefs featureset

- Add boot stacks comparison table in intro (Dakota vs Bluefin/LTS/Bazzite)
- Update pipeline step 1 to describe both layouts: 2-partition for
  systemd-boot/Dakota (EFI + root, GPT auto-discovery) and 3-partition
  for GRUB2/Bluefin-LTS (EFI + ext4 /boot + root, XFS constraint)
- Add new 'Dakota / systemd-boot images' feature section with full
  stack details: systemd-boot + UKI, composefs, btrfs, 2-partition GPT,
  GPT auto-discovery, no user creation needed
- Promote Dakota recipe example to second position, add explanatory note
- Rename recipe examples to call out GRUB2/Bluefin-LTS vs Dakota clearly
- Remove misleading implication that 3-partition/GRUB is universal

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* ci: skip tests for docs-only PRs

Add a 'changes' detection job that inspects git diff on pull_request
events. If every changed file matches a docs pattern (*.md, docs/**),
skip the test matrix and report pass via lightweight pass-through jobs
with the same required-check names:
- 'Unit Tests (no display)'
- 'UI Integration Tests (offscreen GTK)'

Direct pushes to dev/prod and merge_group events always run the full
suite. This means README/AGENTS.md/docs/** PRs clear branch protection
without waiting for a 4-minute CI run.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix(ci): remove XFCE/KDE from build matrix, fix immutable release upload (projectbluefin#181)

- build-flatpaks.yml: remove xfce and kde variants (both removed in projectbluefin#175)
- build-flatpaks.yml: fix release tag names continuous→latest-stable/latest-dev
- flatpak.yml: replace softprops/action-gh-release with gh release create
  to avoid 'immutable release' upload error (one-shot create+upload)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* docs: add CONTRIBUTING.md — human contributor onboarding guide (projectbluefin#184)

All peer repos have a CONTRIBUTING.md; bootc-installer did not. Hive flagged
this ~25 times as the top contributor-friction item. Covers: submodule init
requirement (fisherman), build prerequisites, branch workflow (target: dev),
testing, all three variants (GNOME/XFCE/KDE) with install commands, and
architecture overview.

Addresses projectbluefin/common#557
Assisted-by: Claude Sonnet 4.5 via pi

* fix: post-install state lost on composefs-native systems (hostname, audio, WiFi, services) (projectbluefin#185)

* chore: update fisherman submodule (composefs deploy etc/var path fix)

Points to projectbluefin/fisherman@353f1b3 which fixes all post-install
writes silently discarded on composefs-native bootc systems: hostname,
WirePlumber audio config, WiFi connections, fstab, systemd service
enables, OEM setup, and WarmCaches var path.

Resolves: composefs-native installs showing default hostname, missing
audio renaming, missing WiFi, and no print service auto-discovery.

Assisted-by: Claude Sonnet 4.5 via pi

* docs(skills): add composefs-native path layout, INDEX.md, AGENTS.md pointer

Captures the critical composefs-native post-install path layout discovered
this session:
- Writable /etc = state/deploy/<COMPOSEFS_HASH>/etc/ (not $TARGET/etc/)
- Writable /var = state/os/default/var/ (not $TARGET/var/)
- WarmCaches /usr/ writes are correct no-ops (OCI image ships pre-built caches)
- Diagnostic commands for verifying post-install writes landed

Also adds docs/skills/INDEX.md (self-improvement onboarding: lists all skills,
key architectural facts, composefs layout summary) and adds a reference to it
from AGENTS.md so future agents load it as part of bootstrap.

Assisted-by: Claude Sonnet 4.5 via pi

* chore: bump fisherman submodule (fix ENOSPC on live ISO composefs install) (projectbluefin#188)

* fix: escape sequences, conn check, bootnext nil error

- keyboard.py: raw-string the Czech layout key name to silence
  SyntaxWarning (\| invalid escape → will become SyntaxError in Python 3.14+)
- conn_check.py: replace hardcoded github.com HTTPS check with
  socket.create_connection probing ghcr.io:443 then 8.8.8.8:53;
  prevents false-failures on corporate networks or any environment
  where github.com is blocked but the actual OCI registry is fine
- test_conn_check.py: update mocks from urllib.request to socket

Assisted-by: Claude Sonnet 4.5 via pi

* docs(skills): add pitfalls for conn_check, TPM2 preflight, loop devices, escape sequences

Session learnings from quality audit 2026-06-10:
- conn_check.py: never check github.com; probe ghcr.io:443 instead
- checkRequiredTools: always include late-stage tools before disk touches
- Loop devices in k8s containers: partition nodes don't appear (test gap)
- Python escape sequences in GTK strings: use raw strings for \| etc.

Assisted-by: Claude Sonnet 4.5 via pi

* docs(skills): update coverage baseline, add quality-audit findings and pitfalls

- AGENTS.md: coverage 48% → 52%, test count 665 → 712, stmts 5825 → 5675,
  CI gate --cov-fail-under=47 → 51
- docs/skills/SKILL.md: update coverage numbers + add quality findings table
- docs/skills/PITFALLS.md: add 4 new entries:
  * conn_check: probe ghcr.io:443, never github.com
  * checkRequiredTools: include all late-stage tools (systemd-cryptenroll)
  * loop devices in k8s containers: BLKRRPART fails, test infra limitation
  * Python escape sequences: use raw strings for \| etc.

Assisted-by: Claude Sonnet 4.5 via pi

* chore: bump fisherman submodule (fix ENOSPC on live ISO composefs install)

Updates fisherman to e6ea536 which fixes the CONTAINERS_STORAGE_CONF
tmpdir override for live ISO installs. containers/storage was using
/var/tmp regardless of $TMPDIR; the new approach writes a temporary
storage.conf with tmpdir redirected to the disk-backed scratch dir.

Fixes: ublue-os/bluefin#4754

---------

Co-authored-by: Jorge Castro <jorge@ublue.it>

* fix(ci): fix tagged release race condition (projectbluefin#182)

The production and devel Flatpak jobs ran concurrently for tagged
releases. Whichever finished first would create a published (immutable)
release, causing the other to fail with 'Cannot upload asset to an
immutable release'.

Fix:
- Both jobs now upload their bundles as short-lived artifacts (1 day)
  instead of directly creating a release
- New publish-tagged-release job runs after both builds complete,
  downloads both artifacts, and creates the release in one atomic step
- build-flatpaks.yml: skip release creation for tags (flatpak.yml owns
  tagged releases); use delete+recreate pattern for branch pre-releases

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix(image): use /run/host/etc for system override inside Flatpak sandbox (projectbluefin#183)

_load_manifest() was reading the system-wide images.json override from
/etc/bootc-installer/images.json unconditionally.  Inside a Flatpak
sandbox /etc is reserved by the runtime and the host /etc is exposed at
/run/host/etc instead — the same issue that was already fixed in
RecipeLoader (recipe.py lines 32-33).

Without this fix, a live-ISO distro that ships a custom images.json with
nvidia_imgref support would never have that catalog loaded when the
installer runs as a Flatpak.  _find_nvidia_imgref_for() would always
walk the bundled GResource manifest (which has no nvidia_imgref), return
an empty string, and skip NVIDIA GPU auto-detection entirely.

Apply the same /.flatpak-info detection pattern used by RecipeLoader:
  _etc = '/run/host/etc' if inside Flatpak else '/etc'

Add two unit tests covering both the Flatpak and non-Flatpak paths.

Assisted-by: Claude Sonnet 4.6 via GitHub Copilot

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* feat: remove soundtrack feature entirely

Remove the installation soundtrack feature including:
- Track carousel UI (progress.blp, progress.py)
- Video/Soundtrack toggle buttons
- Track QR codes and cover art assets (20 files)
- data/tracks.json track list
- scripts/generate_soundtrack_qrs.py build-time generator
- meson.build QR generation step
- GResource entries for qr/ and covers/ assets
- All related tests (TestSoundtrackQrAssets, TestProgressSoundtrackData)
- docs/features/soundtrack-qr-codes.md
- soundtrack_data recipe field documentation

* fix: keyboard escape sequences + conn_check github.com hardcode (projectbluefin#186)

Session learnings from quality audit 2026-06-10:
- conn_check.py: never check github.com; probe ghcr.io:443 instead
- checkRequiredTools: always include late-stage tools before disk touches
- Loop devices in k8s containers: partition nodes don't appear (test gap)
- Python escape sequences in GTK strings: use raw strings for \| etc.

Assisted-by: Claude Sonnet 4.5 via pi

* chore: add dev.sh flatpak dev loop, remove unused segno module

dev.sh: build + run via flatpak-builder --run, no user/system install needed
- Rebuilds only when sources change (ccache, fast subsequent builds)
- Launches with BOOTC_DEMO=1 and tails the debug log
- Supports --rebuild, --run, --screen <name>, --logs flags

Flatpak manifests: remove python3-segno module (unused since soundtrack removal)

* docs: update AGENTS.md, SKILL.md, INDEX.md, PITFALLS.md for current state

- AGENTS.md: replace run-dev.sh/toolbox workflow with dev.sh/flatpak-builder --run
  coverage baseline: 53%/707 tests/5421 stmts; remove soundtrack QR from future work
- SKILL.md: same dev loop update; coverage/test count sync; CI gate note corrected
- INDEX.md: add dev.sh, debug log path, branch ruleset facts; restore composefs fact
- PITFALLS.md: add three new entries:
  * flatpak-builder --run: /app/bin not in PATH
  * flatpak-builder --run: debug log goes to ~/.var/app/... not ~/.cache/
  * branch protection: rulesets vs classic protection + gh API to remove

* chore: bump fisherman (fix TMPDIR not forwarded via flatpak-spawn --env)

The previous ENOSPC fix set TMPDIR on cmd.Env for the flatpak-spawn
subprocess, but flatpak-spawn --host does not forward the Flatpak
sandbox environment to the host process. skopeo therefore used /var/tmp
(default) for OCI blob staging instead of the disk-backed scratch dir,
causing ENOSPC on 4 GiB RAM systems.

Fix: fisherman now uses runner.HostArgsWithEnv which injects
--env=TMPDIR=<scratch> directly into the flatpak-spawn args, so the
host skopeo process receives the correct TMPDIR.

Assisted-by: Claude Sonnet 4.5 via pi
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* chore: bump fisherman (two-stage skopeo export fixes ENOSPC)

Replaces containers-storage→oci skopeo copy with a podman save
(to OCI archive) + skopeo copy (oci-archive→oci) two-stage approach.
Eliminates ENOSPC on 4 GiB RAM systems where /var/tmp is too small
for 5-6 GiB blob staging. Root cause: containers/storage store.TmpDir()
returns /var/tmp regardless of TMPDIR env var.

Assisted-by: Claude Sonnet 4.5 via pi
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* chore: bump fisherman (bind-mount /var/tmp for OCI export ENOSPC fix)

Root cause: containers/image store.TmpDir() hardcodes /var/tmp regardless
of TMPDIR env var. Bind-mounting scratch dir over /var/tmp is the only
approach that works across all containers/storage versions.

Assisted-by: Claude Sonnet 4.5 via pi
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* chore: bump fisherman submodule (fix ostree --print-current-dir crash on fresh install)

* docs(skills): document DefaultDeploymentDir mock gap and wrapper-as-bug-report pattern

* fix(confirm): remove parentheses from Become Legend button

* fix(branding): rename Dakota → Bluefin throughout installer

* fix(branding): rename remaining Dakota display strings in phone_companion

* feat(confirm): make hostname field editable before install

* fix(confirm): init _hostname_entry_row in __init__; add hostname edit tests

* feat(progress): replace nerdy step labels with friendly copy

* feat(progress): realistic demo pacing and friendly substep messages

* fix(progress): handle Pulling container image, fix placement, add tests

* fix(confirm,progress): init _hostname_entry_row in __init__; deduplicate layer regex

* feat(progress): revamp video fallback panel with dino, copy, and store QR

- Fix missing inner padding: wrap content in a Box with 28px margins
- Replace TV icon with dakotaraptor (or bundled dakota.png fallback)
- Rename title to 'Installation Video Coming Soon!'
- Change body copy to 'Installation will continue normally. Feel free to browse around. Rawr.'
- Add store QR code + 'Get Bluefin gear' label so users see it during
  install (when there's nothing else to do) rather than only at the end

* chore: update fisherman (wipefs after sfdisk --no-reread)

* chore: update fisherman (fix composefs detection in isComposeFsNative)

* fix(tests): update UI tests for branding and hostname EntryRow changes

- _DummyWindow gets recipe={} so BootcProgress.__setup_fallback_panel
  doesn't crash on AttributeError
- Hostname row is now Adw.EntryRow (get_text not get_subtitle)
- Button label is 'Become Legend' not '( Become Legend )'
- Done screen title is 'Bluefin is installed' not 'Dakota is installed'
- Bump version to 3.0.0

* fix(tests): update progress label assertion for friendly substep format

* fix(flatpak): set CMAKE_INSTALL_LIBDIR=lib for md4c

On 64-bit CI runners cmake defaults CMAKE_INSTALL_LIBDIR to lib64,
installing md4c.pc to /app/lib64/pkgconfig/ where meson can't find it.
This causes libbge's meson build to fail with 'Dependency md4c not found'.
Explicitly set lib so the .pc file lands in /app/lib/pkgconfig/.

* fix(ci): use --clobber fallback when release tag is immutable

gh release create fails with 422 when the tag is protected by a
repository ruleset (immutable release). Fall back to deleting
all existing assets and re-uploading via gh release upload --clobber
so branch pushes can still update the latest-stable / latest-dev
continuous releases regardless of tag protection rules.

* fix(ci): add safe.directory and clobber fallback to all publish steps

- build-flatpaks.yml: add git safe.directory + same create-or-upload
  clobber pattern as flatpak.yml
- flatpak.yml: add git safe.directory to both publish steps (prod+dev)
  so gh CLI can introspect the repo when running as a different user

* fix(ci): show gh release create errors; fix fallback for missing release

* fix(ci): drop latest-stable rolling release, use versioned tags for stable channel

The latest-stable tag name is permanently banned by a GitHub ruleset
(left over from a deleted immutable release). The stable ISO channel
already uses /releases/latest/download/ which auto-resolves to the
newest versioned non-prerelease tag (currently v3.0.5) — no rolling
tag is needed. Removing all latest-stable creation/delete steps from
both workflows. The dev channel (latest-dev) is unaffected.

* fix(recovery-key): only show screen when fisherman emitted a key

The recovery key screen was shown for ALL encrypted installs, but
fisherman only emits a recovery_key event for tpm2-luks (random
passphrase). For luks-passphrase and tpm2-luks-passphrase the user
chose their own passphrase — no random key is generated, so
self.__install_recovery_key is always empty for those types and the
screen would show a placeholder forever.

Fix: gate the recovery key screen on self.__install_recovery_key being
non-empty in addition to the install being encrypted. This means:
- tpm2-luks: recovery key screen shows with the actual random key ✓
- luks-passphrase: goes directly to done screen (user knows their key) ✓
- tpm2-luks-passphrase: goes directly to done screen ✓

* chore: update fisherman (post-install: WiFi, BT audio, Flatpak metadata, wallpaper thumbnails)

* chore: update fisherman (flatpak appstream first-boot service)

* chore: update fisherman (stamp appstream-refreshed on live-session success)

* chore: update fisherman (move firstboot service to common)

* feat: XFS default filesystem for Bluefin/Dakota

- fisherman images.json: dakota filesystem=xfs, filesystems=[xfs,btrfs]
- recipe.json: default image filesystem=xfs, filesystems=[xfs,btrfs]

The UI picker shows XFS first (default) with Btrfs as an option.
ext4 removed from the Dakota/Bluefin picker.

* chore: resolve AGENTS.md merge conflict (keep dev version)

* fix(ci): handle pre-existing tag when publishing tagged release

If the tag was pushed manually before CI ran, gh release create fails
with 'a release with the same tag name already exists'. Fall back to
gh release upload --clobber to attach assets to the existing release.

* docs: require E2E install test for default filesystem changes

Closes projectbluefin#190 (projectbluefin#190)

Adds Verification Requirements section to AGENTS.md: changing default
filesystem/encryption/bootloader requires a complete installation test,
not just passing unit tests. Unit tests mock fisherman; they cannot catch
missing host tools or post-install failures.

Also adds PITFALLS entry for the xfsprogs lesson: any filesystem default
change must be verified against the live environment's installed tools.

* chore: update fisherman (fix empty ostree/deploy/ composefs detection)

* chore(fisherman): update submodule — OCI layout path for non-composefs installs

Pulls in 5 commits from projectbluefin/fisherman dev → prod merge:
- fix(install): OCI layout path for non-composefs ostree installs
- fix(disk): increase /boot partition from 1 GiB to 2 GiB
- fix(disk): 2 GiB ESP for all fleet images (grub2 512 MiB → 2 GiB)
- fix(install): remove dead else-if branch and double RemoveAll

Enables bluefin/bluefin-lts offline installs from OCI layout in squashfs.

Assisted-by: Claude Sonnet 4.5 via pi
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Signed-off-by: GitHub Copilot <copilot@github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: GitHub Copilot <copilot@github.com>
Co-authored-by: Jorge Castro <jorge@ublue.it>

* docs(skill): update for main branch — run-dev.sh, remove dead modules, branch note

- dev.sh -> run-dev.sh (renamed on main branch)
- Remove keymaps.py, keyboard.py, language.py, timezone.py from module map (removed by PR projectbluefin#194)
- Remove test_timezone.py from GTK test examples (removed by PR projectbluefin#194)
- Mark dead-code quality finding as resolved
- Add note: PRs targeting main bypass CI — check manually with gh pr checks

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* docs(agents): update agentic skills, clean out stale variants, and add workspace customizations

* Take the product name from the recipe instead of hardcoding Bluefin

This installer is designed to be rebranded — the recipe carries distro_name,
distro_logo and welcome_title, and RecipeLoader validates distro_name as an
essential key. Two user-visible strings ignored it and said Bluefin anyway, so
every downstream shipped an installer offering to install Bluefin.

Seen on TunaOS, whose recipe sets distro_name/welcome_title per variant:
the welcome screen renders 'Welcome to Skipjack' as the page title, and
directly beneath it 'Install Bluefin'.

1. defaults/welcome.py — the install row's title is hardcoded in
   default-welcome.blp and was never set at runtime, unlike welcome_title
   just above it. Now set from the recipe, using the same source and the same
   fallback as done.py's '{} is installed'.

   Note the key is 'name': builder.py's distro_info property maps
   recipe['distro_name'] onto 'name'. Reading 'distro_name' there compiles,
   runs, and silently always renders the fallback — indistinguishable from
   having no recipe at all.

2. utils/progress_parser.py — the 'Installing OS' step label read 'Installing
   Bluefin…'. This is the progress screen, which is the one a user watches for
   the entire install. It is now a {product} template filled at lookup.

   The parser keeps its no-GTK, no-file-IO contract: a module-level value with
   a setter, not a recipe import, so the unit tests can still import it alone.
   views/progress.py calls the setter at the first point the recipe is in
   hand. The default is 'the OS' rather than any distro's name — an unset
   product should read as generic, not as somebody else's brand. Only labels
   containing the placeholder are formatted, so a future label with a literal
   brace cannot raise.

Deliberately NOT changed, because they are Bluefin's own content rather than
the product name, and ripping them out would be a different decision: the
recovery dialog's links to Bluefin documentation and Dosu, the 'Get Bluefin
gear' store link, the phone-companion page title, and the About window's
copyright and developer_name — that last one is correct attribution and
should stay whatever the branding says.

Tests: the substep label assertion no longer asserts a distro name; two new
tests cover the configured-product path and that an empty value is ignored.
Suite goes 714 -> 716 passed with the same 5 pre-existing image-catalog
failures, which need the fisherman submodule and fail identically on a clean
checkout.

---------

Signed-off-by: GitHub Copilot <copilot@github.com>
Co-authored-by: Jorge O. Castro <jorge.castro@gmail.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: GitHub Copilot <copilot@github.com>
Co-authored-by: Jorge Castro <jorge@ublue.it>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

4-review A pull request is awaiting review.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants