From 42b1d432356cf4f4bbf7db97e15673a2917bcc7d Mon Sep 17 00:00:00 2001 From: VibTools Date: Thu, 20 Aug 2026 20:17:06 -0700 Subject: [PATCH] fix: restore device icons across admin UI in v5.8.2 --- .github/workflows/ci.yml | 14 ++-- BASELINE_v5.8.2.md | 24 +++++++ CHANGELOG.md | 13 +++- README.md | 7 +- RELEASE_COMMANDS_v5.8.2.md | 46 ++++++++++++++ RELEASE_NOTES_v5.8.2.md | 22 +++++++ REPOSITORY_METADATA.md | 17 ++++- ROADMAP.md | 5 +- admin/about.php | 2 +- admin/backup.php | 2 +- admin/device.php | 4 +- admin/includes/ui/navigation.php | 2 +- admin/license.php | 2 +- admin/settings.php | 2 +- audit/V5.8.2_DELTA_MANIFEST.md | 54 ++++++++++++++++ audit/V5.8.2_DELTA_SHA256SUMS.txt | 34 ++++++++++ audit/V5.8.2_DEVICE_ICON_HOTFIX_AUDIT.md | 81 ++++++++++++++++++++++++ config.sample.php | 2 +- docs/ACTUAL_IMPLEMENTATION_LEDGER.md | 8 +++ docs/CONFIGURATION.md | 4 +- docs/FEATURE_MATRIX.md | 1 + docs/INSTALLATION.md | 6 +- docs/RELEASE.md | 28 +++++++- docs/UI_DESIGN_SYSTEM.md | 4 ++ docs/UPGRADE_GUIDE.md | 13 +++- includes/config.php | 2 +- includes/installation.php | 12 ++-- install.php | 6 +- scripts/verify-local.py | 23 +++---- tests/compatibility_regression.php | 2 +- tests/installer_smoke.php | 6 +- tests/release_readiness.php | 29 +++++---- tests/ui_component_contract.php | 3 + tests/updater_state_machine.php | 2 +- update/release-spec.json | 5 +- 35 files changed, 418 insertions(+), 69 deletions(-) create mode 100644 BASELINE_v5.8.2.md create mode 100644 RELEASE_COMMANDS_v5.8.2.md create mode 100644 RELEASE_NOTES_v5.8.2.md create mode 100644 audit/V5.8.2_DELTA_MANIFEST.md create mode 100644 audit/V5.8.2_DELTA_SHA256SUMS.txt create mode 100644 audit/V5.8.2_DEVICE_ICON_HOTFIX_AUDIT.md diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b532d17..0216416 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -134,18 +134,18 @@ jobs: run: | short_sha="${GITHUB_SHA:0:12}" mkdir -p release - bash scripts/package-release.sh v5.8.1 "$GITHUB_SHA" "release/Licora-5.8.1-ci-${short_sha}.zip" - cp "release/Licora-5.8.1-ci-${short_sha}.zip" "release/Licora-5.8.1.zip" - python3 scripts/build-update-manifest.py --version 5.8.1 --ref "$GITHUB_SHA" --package "release/Licora-5.8.1.zip" --output release/licora-update-manifest.json - rm "release/Licora-5.8.1.zip" + bash scripts/package-release.sh v5.8.2 "$GITHUB_SHA" "release/Licora-5.8.2-ci-${short_sha}.zip" + cp "release/Licora-5.8.2-ci-${short_sha}.zip" "release/Licora-5.8.2.zip" + python3 scripts/build-update-manifest.py --version 5.8.2 --ref "$GITHUB_SHA" --package "release/Licora-5.8.2.zip" --output release/licora-update-manifest.json + rm "release/Licora-5.8.2.zip" - name: Upload CI release-candidate artifact uses: actions/upload-artifact@v6 with: - name: Licora-5.8.1-${{ github.sha }} + name: Licora-5.8.2-${{ github.sha }} path: | - release/Licora-5.8.1-ci-*.zip - release/Licora-5.8.1-ci-*.zip.sha256 + release/Licora-5.8.2-ci-*.zip + release/Licora-5.8.2-ci-*.zip.sha256 release/licora-update-manifest.json if-no-files-found: error retention-days: 14 diff --git a/BASELINE_v5.8.2.md b/BASELINE_v5.8.2.md new file mode 100644 index 0000000..542c6b9 --- /dev/null +++ b/BASELINE_v5.8.2.md @@ -0,0 +1,24 @@ +# Licora v5.8.2 Source Baseline Freeze + +## Parent authority + +- Published parent release: `v5.8.1` +- Parent commit: `f7b7fc2275a33a2aa29db5f464c2ffd0a6172045` +- Parent release ZIP: `Licora-5.8.1.zip` +- Parent release ZIP SHA-256: `710f2431f27bbb76c3b522ae9ca3d215bd647e4793623958573c77637db28c60` +- Target source version: `5.8.2` +- Release channel: stable candidate +- Database migrations: none +- Delete files: none +- Accepted updater source: `5.8.1` + +## Hotfix scope + +1. Replace all seven remaining Admin runtime `bi-devices` usages with Bootstrap Icons 1.8.1-compatible `bi-laptop`. +2. Cover the shared sidebar, Settings shortcut, Device Management header/empty state, License View Devices action, Backup Devices CSV action, and About Device Control card. +3. Add a recursive Admin runtime UI regression gate that rejects future `bi-devices` usage. +4. Align runtime/installer/CI/updater release identity and release documentation to v5.8.2. + +No database, API, license/device enforcement, authentication, Dashboard data/AJAX, Developer Guide behavior, Cron or updater runtime/protocol change is authorized or included. + +The final v5.8.2 baseline ZIP SHA-256 is recorded by the delivery package generated after verification. diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a32bd4..707e3b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,18 @@ All notable public-release changes are recorded here. Historical project notes r ### Planned -- No additional feature scope is approved beyond the verified v5.8.1 Developer Integration Guide correction. +- No additional feature scope is approved beyond the v5.8.2 global device-icon compatibility hotfix. + +## [5.8.2] - 2026-08-20 + +### Fixed +- Replaced all seven remaining Admin runtime `bi-devices` usages with the Bootstrap Icons 1.8.1-compatible `bi-laptop` glyph. +- Restored visible device icons in the shared sidebar, Settings shortcut, Device Management header/empty state, License View Devices action, Backup Devices CSV action and About Device Control card. +- Added a recursive Admin runtime UI regression check preventing `bi-devices` from returning in PHP, JavaScript or HTML UI sources. + +### Compatibility +- Signed update compatibility accepts the published `v5.8.1` baseline. +- No database migration, file deletion, API v1/v2 change, license/device behavior change, Dashboard data/AJAX change, Developer Guide behavior change, authentication/role change, Cron change or updater runtime/protocol change. ## [5.8.1] - 2026-08-20 diff --git a/README.md b/README.md index a856079..37d5fe6 100644 --- a/README.md +++ b/README.md @@ -125,7 +125,7 @@ The application accepts deployment-specific values through environment variables | Database password | `LICENSE_DB_PASS` | empty | | Application name | `APP_NAME` | `Licora` | | Application URL | `APP_URL` | `http://localhost` | -| Application version | `APP_VERSION` | `5.8.1` | +| Application version | `APP_VERSION` | `5.8.2` | | Environment | `APP_ENV` | `production` | | Encryption key | `LICENSE_ENCRYPTION_KEY` | empty fallback | | API limit | `API_RATE_LIMIT` | `1000` | @@ -156,6 +156,7 @@ The validation script checks PHP syntax, security behavior, compatibility invari - [Secure in-app updater](docs/UPDATER.md) - [UI design system](docs/UI_DESIGN_SYSTEM.md) - [Troubleshooting](docs/TROUBLESHOOTING.md) +- [v5.8.2 release notes](RELEASE_NOTES_v5.8.2.md) - [v5.8.1 release notes](RELEASE_NOTES_v5.8.1.md) - [v5.8.0 source-candidate notes](RELEASE_NOTES_v5.8.0.md) - [v5.7.1 release notes](RELEASE_NOTES_v5.7.1.md) @@ -179,6 +180,10 @@ The validation script checks PHP syntax, security behavior, compatibility invari +## Device icon compatibility hotfix (v5.8.2) + +Licora v5.8.2 replaces every remaining Admin runtime `bi-devices` glyph with the Bootstrap Icons 1.8.1-compatible `bi-laptop` glyph. The fix covers the shared sidebar and all remaining device-related UI surfaces without changing navigation, Dashboard behavior, APIs, licensing/device enforcement or updater runtime. A shared UI regression gate rejects future reintroduction of the unsupported class. + ## Developer Integration Guide (v5.8.1; introduced in v5.8.0 source candidate) The verified v5.8.1 authenticated **API & Clients → Developer Guide** provides a compact Secure API v2 Quick Start, the exact P-256 device-proof canonical contract, detected endpoint URLs, stable error codes and downloadable lifecycle references for Python, PowerShell/CMD, C, C++, C#/.NET, Java, Flutter, React Native, PHP and Node.js. Public-client examples never embed an API v1 shared/master key. Production clients must keep the P-256 private key and rotated refresh credential in platform-secure storage and verify pinned `LICORA-V2`/`RS256` access-token signatures before trusting claims locally. diff --git a/RELEASE_COMMANDS_v5.8.2.md b/RELEASE_COMMANDS_v5.8.2.md new file mode 100644 index 0000000..e268ff6 --- /dev/null +++ b/RELEASE_COMMANDS_v5.8.2.md @@ -0,0 +1,46 @@ +# Licora v5.8.2 Release Commands + +Run only after the v5.8.2 hotfix delta is applied and the exact staged scope is reviewed. + +## Local branch publication + +```cmd +git switch main +git pull --ff-only origin main +git status --short --branch +git switch -c hotfix/v5.8.2-device-icons +``` + +Apply the replace-ready delta, then: + +```cmd +git diff --check +git status --short +``` + +Stage only the explicit paths supplied with the final delta audit. Do not use `git add .`, `git add -A` or `git add --all`. + +After staged-scope review: + +```cmd +git diff --cached --check +git diff --cached --name-status +git commit -m "fix: restore device icons across admin UI in v5.8.2" +git push -u origin hotfix/v5.8.2-device-icons +``` + +Create/review the PR against `main`. Merge/tag/release require separate explicit authorization. + +## Tagged release after merge and authorization + +```cmd +git switch main +git pull --ff-only origin main +git status --short --branch +git rev-parse HEAD +git tag -a v5.8.2 -m "Licora v5.8.2 - Global Device Icon Compatibility Hotfix" +git show --no-patch --decorate v5.8.2 +git push origin v5.8.2 +``` + +The tag-triggered `release.yml` must build, sign and publish the exact tag. diff --git a/RELEASE_NOTES_v5.8.2.md b/RELEASE_NOTES_v5.8.2.md new file mode 100644 index 0000000..c2393e2 --- /dev/null +++ b/RELEASE_NOTES_v5.8.2.md @@ -0,0 +1,22 @@ +# Licora v5.8.2 — Global Device Icon Compatibility Hotfix + +Licora v5.8.2 is a no-migration UI compatibility hotfix over the published v5.8.1 release. + +## Fixed + +- Replaces every remaining runtime `bi-devices` reference with `bi-laptop`, which is available in the pinned Bootstrap Icons 1.8.1 dependency. +- Restores the device glyph in the shared sidebar, Settings shortcut, Device Management page header and empty state, License **View Devices** action, Backup **Devices CSV** export, and About **Device Control** capability card. +- Adds a shared UI regression gate that rejects `bi-devices` anywhere in Admin runtime PHP/JavaScript/HTML sources so the unsupported glyph cannot silently return. + +## Compatibility + +- Upgrade source: `5.8.1`. +- Database migrations: none. +- Deleted files: none. +- API v1/v2 behavior: unchanged. +- License/device enforcement: unchanged. +- Authentication/roles: unchanged. +- Dashboard data, AJAX refresh and charts: unchanged. +- Developer Guide and downloadable API v2 examples: unchanged. +- Cron behavior and updater runtime/protocol: unchanged. +- Sidebar/navigation structure: unchanged; only the Devices glyph class changes. diff --git a/REPOSITORY_METADATA.md b/REPOSITORY_METADATA.md index 8a08849..88196c2 100644 --- a/REPOSITORY_METADATA.md +++ b/REPOSITORY_METADATA.md @@ -27,10 +27,23 @@ Licora v5.1.0 adds a ten-step first-run installer, delimiter-aware schema execution, secure administrator and secret generation, atomic private configuration, installation locking, optional demo data, database-port support, safe installer diagnostics, and expanded regression validation. The release preserves the existing license engine, API contracts, database schema, routes, admin UI, cron entry points, and encrypted-data compatibility. -## v5.8.1 Developer Integration Guide verification candidate +## v5.8.2 global device icon compatibility hotfix candidate -- **Intended tag:** `v5.8.1` +- **Intended tag:** `v5.8.2` - **Publication status:** source candidate; GitHub publication requires separate authorization +- **Title:** `Licora v5.8.2 — Global Device Icon Compatibility Hotfix` +- **Release notes:** `RELEASE_NOTES_v5.8.2.md` +- **Database migration:** none +- **Delete list:** empty +- **Supported update source:** published `v5.8.1` + +Licora v5.8.2 changes only the remaining unsupported Admin device icon class from `bi-devices` to Bootstrap Icons 1.8.1-compatible `bi-laptop`, adds a regression gate for the unsupported class, and aligns release identity. Runtime API, database, licensing/device enforcement, Dashboard, Developer Guide, authentication, Cron and updater semantics remain unchanged. + +## v5.8.1 published Developer Integration Guide corrective release + +- **Tag:** `v5.8.1` +- **Commit:** `f7b7fc2275a33a2aa29db5f464c2ffd0a6172045` +- **Publication status:** published and release-verified - **Title:** `Licora v5.8.1 — Developer Integration Guide Verification Fix` - **Release notes:** `RELEASE_NOTES_v5.8.1.md` - **Database migration:** none diff --git a/ROADMAP.md b/ROADMAP.md index 5ccf691..31051c1 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -40,9 +40,10 @@ Roadmap items are proposals and must be implemented through reviewed, backward-c - v5.5.0: VibTools compact light UI refinement, truthful runtime-backed Settings, tracked Licora branding, About page and Windows builder-test portability; no database/API/updater protocol change. - v5.5.1: Settings layout, collapsible Settings submenu, and professional About Licora UI hotfix; no database/API/updater behavior change. -## Developer onboarding program (v5.8.0 → v5.8.1) +## Developer onboarding program (v5.8.0 → v5.8.2) - **Developer Integration Guide:** IMPLEMENTED in the v5.8.0 source candidate and re-audited/corrected in the v5.8.1 verification candidate. -- **v5.8.1 corrective gate:** CI package/manifest version coherence fixed; Dashboard device glyph compatibility fixed; no API/DB/runtime protocol expansion. +- **v5.8.1 corrective gate:** CI package/manifest version coherence fixed and Dashboard device glyph compatibility fixed. +- **v5.8.2 UI compatibility hotfix:** all remaining Admin `bi-devices` glyphs are replaced with Bootstrap Icons 1.8.1-compatible `bi-laptop`, with a shared regression gate; no API/DB/runtime protocol expansion. - Scope is limited to the authenticated guide route, API & Clients sidebar link, exact Secure API v2 protocol documentation, downloadable examples for the ten approved language/runtime targets, PowerShell test tool, tests/docs/version/release identity. - API v1/v2 behavior, database schema, licensing/device enforcement, Dashboard, authentication/roles, Cron and updater runtime/protocol remain frozen. diff --git a/admin/about.php b/admin/about.php index f5a6846..8648694 100644 --- a/admin/about.php +++ b/admin/about.php @@ -57,7 +57,7 @@

License Control

Create licenses with expiration periods, device limits, notes, application scopes and optional API-key binding.

- +

Device Control

Track registered devices, activity, revocation, blacklist state and license-bound device limits.

diff --git a/admin/backup.php b/admin/backup.php index ee9c6be..f2df9f5 100644 --- a/admin/backup.php +++ b/admin/backup.php @@ -61,6 +61,6 @@

Backup & Export

Licenses
Devices
Logs
Tables
-
CSV ExportManager+
+
CSV ExportManager+
Database BackupSuper Admin
SQL backups can contain sensitive data. Store downloaded files securely.
Download SQL Backup
\ No newline at end of file diff --git a/admin/device.php b/admin/device.php index b330e02..5db0412 100644 --- a/admin/device.php +++ b/admin/device.php @@ -93,7 +93,7 @@
-

Device Management

+

Device Management

Licenses
@@ -109,7 +109,7 @@
-
No devices found
+
No devices found
diff --git a/admin/includes/ui/navigation.php b/admin/includes/ui/navigation.php index 8831c9b..a2f1416 100644 --- a/admin/includes/ui/navigation.php +++ b/admin/includes/ui/navigation.php @@ -8,7 +8,7 @@ function licora_ui_navigation_groups(): array ], 'License Management' => [ ['file' => 'license.php', 'label' => 'Licenses', 'icon' => 'bi-key'], - ['file' => 'device.php', 'label' => 'Devices', 'icon' => 'bi-devices'], + ['file' => 'device.php', 'label' => 'Devices', 'icon' => 'bi-laptop'], ], 'API & Clients' => [ ['file' => 'api_keys.php', 'label' => 'API Keys', 'icon' => 'bi-key-fill'], diff --git a/admin/license.php b/admin/license.php index 415232f..81a1f9c 100644 --- a/admin/license.php +++ b/admin/license.php @@ -294,7 +294,7 @@
Suspend Activate - View Devices + View Devices Blacklist Delete diff --git a/admin/settings.php b/admin/settings.php index 15b7b03..eec6c76 100644 --- a/admin/settings.php +++ b/admin/settings.php @@ -75,7 +75,7 @@ function save_setting($db, $key, $value) {
-
Product: Licora   Version: 5.8.1   License: MIT   Database: MySQL/MariaDB
+
Product: Licora   Version: 5.8.2   License: MIT   Database: MySQL/MariaDB
@@ -353,7 +353,7 @@ function installer_render_locked(): void -

Licora will initialize database.sql, preserving the existing API v1 schema and adding only the Secure API v2 tables introduced in v5.2.0 and retained unchanged through v5.8.1.

+

Licora will initialize database.sql, preserving the existing API v1 schema and adding only the Secure API v2 tables introduced in v5.2.0 and retained unchanged through v5.8.2.

The target database must not already contain Licora tables. Unrelated existing tables are never removed. If installation fails, only installer-created objects are cleaned up.
Database
@@ -409,7 +409,7 @@ function installer_render_locked(): void Restart - + diff --git a/scripts/verify-local.py b/scripts/verify-local.py index ea957b3..db3b2f7 100644 --- a/scripts/verify-local.py +++ b/scripts/verify-local.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -"""Local source verifier for Licora v5.8.1. +"""Local source verifier for Licora v5.8.2. This verifier validates source and tests only. It never creates a Git tag, release, or GitHub artifact. Release packaging is intentionally owned by GitHub Actions and @@ -17,7 +17,7 @@ from pathlib import Path ROOT = Path(__file__).resolve().parents[1] -VERSION = "5.8.1" +VERSION = "5.8.2" V1_GIT_BLOBS = { "api/verify.php": "4dc549c2afea0772d3f2ffa8b330fd24b8b13ec2", @@ -28,6 +28,7 @@ REQUIRED = [ "README.md", "CHANGELOG.md", "SECURITY.md", "REPOSITORY_METADATA.md", + "RELEASE_NOTES_v5.8.2.md", "RELEASE_COMMANDS_v5.8.2.md", "BASELINE_v5.8.2.md", "RELEASE_NOTES_v5.8.1.md", "RELEASE_COMMANDS_v5.8.1.md", "BASELINE_v5.8.1.md", "RELEASE_NOTES_v5.8.0.md", "RELEASE_COMMANDS_v5.8.0.md", "BASELINE_v5.8.0.md", "RELEASE_NOTES_v5.7.1.md", "RELEASE_COMMANDS_v5.7.1.md", "BASELINE_v5.7.1.md", @@ -157,10 +158,10 @@ def require_action_minimum(text: str, action: str, minimum: tuple[int, ...], lab print("[3/12] Release/version consistency") config = read("includes/config.php") if f"env_value('APP_VERSION', '{VERSION}')" not in config: - fail("runtime APP_VERSION is not 5.8.1") -for rel in ["config.sample.php", "install.php", "includes/installation.php", "RELEASE_NOTES_v5.8.1.md", "CHANGELOG.md", "REPOSITORY_METADATA.md"]: + fail("runtime APP_VERSION is not 5.8.2") +for rel in ["config.sample.php", "install.php", "includes/installation.php", "RELEASE_NOTES_v5.8.2.md", "CHANGELOG.md", "REPOSITORY_METADATA.md"]: if VERSION not in read(rel): - fail(f"5.8.1 release marker missing from {rel}") + fail(f"5.8.2 release marker missing from {rel}") print("[4/12] API v2 protocol/security contract") v2_endpoint_text = "\n".join(read(f"api/v2/{name}.php") for name in ("activate", "refresh", "status", "deactivate")) @@ -214,17 +215,17 @@ def require_action_minimum(text: str, action: str, minimum: tuple[int, ...], lab if "-- Licora v5.3.0 Secure In-App Updater additive migration." not in read("database.sql"): fail("fresh-install database.sql does not contain updater additive schema") release_spec = read("update/release-spec.json") -for marker in ['\"protocol_version\": 1', '\"version\": \"5.8.1\"', '\"minimum_updater\": \"5.3.0\"', '\"upgrade_from\"']: +for marker in ['\"protocol_version\": 1', '\"version\": \"5.8.2\"', '\"minimum_updater\": \"5.3.0\"', '\"upgrade_from\"']: if marker not in release_spec: fail(f"updater release-spec marker missing: {marker}") if 'migration-v5.3.0-updater.sql' in release_spec: - fail('v5.8.1 Developer Guide verification release spec must not replay the v5.3.0 updater migration') + fail('v5.8.2 device icon hotfix release spec must not replay the v5.3.0 updater migration') import json as _json _release_spec_data = _json.loads(release_spec) -if _release_spec_data.get("upgrade_from") != ["5.7.1", "5.8.0"]: - fail("v5.8.1 release spec must accept published v5.7.1 and applied v5.8.0 baselines") +if _release_spec_data.get("upgrade_from") != ["5.8.1"]: + fail("v5.8.2 release spec must accept published v5.8.1 baseline") if _release_spec_data.get("migrations") != []: - fail("v5.8.1 Developer Guide verification release must not declare a database migration") + fail("v5.8.2 device icon hotfix must not declare a database migration") print("[6/12] Signing-key and secret hygiene") for rel in [ @@ -408,4 +409,4 @@ def require_action_minimum(text: str, action: str, minimum: tuple[int, ...], lab if marker not in packager: fail(f"release packaging marker missing: {marker}") -print("Licora v5.8.1 local verification passed.") +print("Licora v5.8.2 local verification passed.") diff --git a/tests/compatibility_regression.php b/tests/compatibility_regression.php index d8c25ec..1278666 100644 --- a/tests/compatibility_regression.php +++ b/tests/compatibility_regression.php @@ -97,7 +97,7 @@ } $config = $read('includes/config.php'); -$assert(strpos($config, "env_value('APP_VERSION', '5.8.1')") !== false, 'application version is v5.8.1'); +$assert(strpos($config, "env_value('APP_VERSION', '5.8.2')") !== false, 'application version is v5.8.2'); $assert(strpos($config, "if (!defined('DB_PORT'))") !== false, 'database port support is additive'); $assert(strpos($config, 'licora_enforce_installation_guard') !== false, 'first-run guard is enabled before application boot'); diff --git a/tests/installer_smoke.php b/tests/installer_smoke.php index 81d4088..847ad8a 100644 --- a/tests/installer_smoke.php +++ b/tests/installer_smoke.php @@ -89,7 +89,7 @@ ], ]; $config = licora_installer_build_config($data); -$assert(strpos($config, "define('APP_VERSION', '5.8.1')") !== false, 'generated configuration targets v5.8.1'); +$assert(strpos($config, "define('APP_VERSION', '5.8.2')") !== false, 'generated configuration targets v5.8.2'); $assert(strpos($config, "define('DB_PORT', 3306)") !== false, 'generated configuration includes database port'); $encrypted = licora_installer_encrypt('installer-secret-test', str_repeat('2', 64)); @@ -146,10 +146,10 @@ @unlink($v2InstallerKeys['private_tmp']); @unlink($v2InstallerKeys['public_tmp']); -$assert(licora_installation_write_flag($tempRoot, '5.8.1'), 'installation flag written atomically'); +$assert(licora_installation_write_flag($tempRoot, '5.8.2'), 'installation flag written atomically'); $flag = json_decode((string)file_get_contents($tempRoot . '/includes/.licora-installed'), true); $assert(($flag['product'] ?? '') === 'Licora', 'installation flag identifies Licora'); -$assert(($flag['version'] ?? '') === '5.8.1', 'installation flag records version'); +$assert(($flag['version'] ?? '') === '5.8.2', 'installation flag records version'); $assert(!isset($flag['database_password']) && !isset($flag['encryption_key']), 'installation flag contains no secrets'); $assert( diff --git a/tests/release_readiness.php b/tests/release_readiness.php index 802c14a..18e504f 100644 --- a/tests/release_readiness.php +++ b/tests/release_readiness.php @@ -19,14 +19,14 @@ $config = $read('includes/config.php'); $installer = $read('install.php'); $installation = $read('includes/installation.php'); -$releaseNotes = $read('RELEASE_NOTES_v5.8.1.md'); +$releaseNotes = $read('RELEASE_NOTES_v5.8.2.md'); $changelog = $read('CHANGELOG.md'); $configuration = $read('docs/CONFIGURATION.md'); $releaseGuide = $read('docs/RELEASE.md'); $packager = $read('scripts/package-release.sh'); $ci = $read('.github/workflows/ci.yml'); -$versionDefinition = "if (!defined('APP_VERSION')) define('APP_VERSION', env_value('APP_VERSION', '5.8.1'));"; +$versionDefinition = "if (!defined('APP_VERSION')) define('APP_VERSION', env_value('APP_VERSION', '5.8.2'));"; $localConfigRequire = 'require_once $localConfig;'; $versionPosition = strpos($config, $versionDefinition); $localConfigPosition = strpos($config, $localConfigRequire); @@ -37,7 +37,7 @@ 'runtime version resolves before preserved private configuration' ); $assert(strpos($config, "env_value('APP_NAME', 'Licora')") !== false, 'default application name is Licora'); -$assert(strpos($installation, "'APP_VERSION' => '5.8.1'") !== false, 'generated installer configuration targets v5.8.1'); +$assert(strpos($installation, "'APP_VERSION' => '5.8.2'") !== false, 'generated installer configuration targets v5.8.2'); $assert(strpos($installer, 'First-Run Installer') !== false, 'installer uses the compact Licora first-run branding'); $assert(strpos($installer, 'assets/brand/logos/logo-md.png') !== false, 'installer uses the supplied Licora logo asset'); $assert(strpos($installer, 'name="app_name" value="Licora"') !== false, 'installer fixes the visible product identity to Licora'); @@ -107,6 +107,9 @@ ); foreach ([ + 'RELEASE_NOTES_v5.8.2.md', + 'RELEASE_COMMANDS_v5.8.2.md', + 'BASELINE_v5.8.2.md', 'RELEASE_NOTES_v5.8.1.md', 'RELEASE_COMMANDS_v5.8.1.md', 'BASELINE_v5.8.1.md', @@ -140,10 +143,10 @@ $assert(is_file($root . '/' . $path), 'release documentation exists: ' . $path); } -$assert(strpos($releaseNotes, 'Licora v5.8.1') !== false, 'release notes identify v5.8.1'); -$assert(strpos($changelog, '## [5.8.1] - 2026-08-20') !== false, 'changelog contains the v5.8.1 release date'); -$assert(strpos($configuration, '`APP_VERSION` | `APP_VERSION` | `5.8.1`') !== false, 'configuration reference matches v5.8.1 runtime version'); -$assert(strpos($releaseGuide, 'scripts/package-release.sh v5.8.1 v5.8.1') !== false, 'release guide uses the v5.8.1 packager command'); +$assert(strpos($releaseNotes, 'Licora v5.8.2') !== false, 'release notes identify v5.8.2'); +$assert(strpos($changelog, '## [5.8.2] - 2026-08-20') !== false, 'changelog contains the v5.8.2 release date'); +$assert(strpos($configuration, '`APP_VERSION` | `APP_VERSION` | `5.8.2`') !== false, 'configuration reference matches v5.8.2 runtime version'); +$assert(strpos($releaseGuide, 'scripts/package-release.sh v5.8.2 v5.8.2') !== false, 'release guide uses the v5.8.2 packager command'); $assert(strpos($packager, 'git archive --format=zip') !== false, 'release package is created from a Git ref'); $assert(strpos($packager, 'git diff --quiet') !== false, 'release packager rejects tracked working-tree changes'); @@ -152,16 +155,16 @@ 'includes/installation.php', 'install.php', 'config.sample.php', - 'RELEASE_NOTES_v5.8.1.md', + 'RELEASE_NOTES_v5.8.2.md', ] as $path) { $content = $read($path); - $assert(strpos($content, '5.8.2') === false, 'v5.8.1 release file does not contain future version marker: ' . $path); + $assert(strpos($content, '5.8.3') === false, 'v5.8.2 release file does not contain future version marker: ' . $path); } -$assert(strpos($ci, 'package-release.sh v5.8.1') !== false, 'CI candidate packager targets v5.8.1'); -$assert(strpos($ci, 'Licora-5.8.1.zip') !== false, 'CI candidate canonical ZIP targets v5.8.1'); -$assert(strpos($ci, '--version 5.8.1') !== false, 'CI updater-manifest builder targets v5.8.1'); -$assert(strpos($ci, '--version 5.7.1') === false, 'CI candidate manifest does not use stale v5.7.1 version'); +$assert(strpos($ci, 'package-release.sh v5.8.2') !== false, 'CI candidate packager targets v5.8.2'); +$assert(strpos($ci, 'Licora-5.8.2.zip') !== false, 'CI candidate canonical ZIP targets v5.8.2'); +$assert(strpos($ci, '--version 5.8.2') !== false, 'CI updater-manifest builder targets v5.8.2'); +$assert(strpos($ci, '--version 5.8.1') === false, 'CI candidate manifest does not use stale v5.8.1 version'); if ($failures !== []) { fwrite(STDERR, "Release readiness test failed:\n- " . implode("\n- ", $failures) . "\n"); diff --git a/tests/ui_component_contract.php b/tests/ui_component_contract.php index bb06bf8..c9f0a27 100644 --- a/tests/ui_component_contract.php +++ b/tests/ui_component_contract.php @@ -23,6 +23,9 @@ function uc_ok($v,string $m):void{if(!$v){fwrite(STDERR,"FAIL: {$m}\n");exit(1); foreach(['.ui-sidebar','.ui-topbar','.admin-shell','@media (max-width: 899.98px)'] as $marker){uc_ok(strpos($shell,$marker)!==false,'shared app-shell marker missing '.$marker);} $pages=glob($root.'/admin/*.php')?:[]; foreach($pages as $path){if(basename($path)==='logout.php')continue;$text=(string)file_get_contents($path);uc_ok(stripos($text,'isFile()||!in_array(strtolower($file->getExtension()),['php','js','html'],true))continue;$text=(string)file_get_contents($file->getPathname());uc_ok(strpos($text,$unsupportedDeviceIcon)===false,'unsupported Bootstrap Icons 1.8.1 device glyph remains: '.str_replace($root.'/','',$file->getPathname()));} $install=(string)file_get_contents($root.'/install.php');uc_ok(stripos($install,'