Commit Graph

7 Commits

Author SHA1 Message Date
6c1a3364c4 ci: drop modules:'qtquickcontrols2' (rolled into base Qt 6)
Some checks failed
CI / Quality (push) Failing after 3m40s
Release / Linux AppImage (push) Has been cancelled
aqt's "modules" list is for *additional* modules beyond the base Qt
install (qt5compat, qtcharts, qtmultimedia, qtwebsockets, etc.).
QtQuick.Controls 2 was a separately-shipped Qt 5 module, but in Qt
6.0+ it was folded into qtdeclarative — part of every base install.

aqt 3.3 rejects the obsolete name with:
  ERROR: The packages ['qtquickcontrols2'] were not found while
         parsing XML of package information!

Project's CMakeLists request `Core Gui Quick QuickControls2 Network
Qml` — all in base Qt 6.5. No `modules:` line needed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 10:08:43 +02:00
badb5056c9 ci: pin Qt install dir for act-runner (runner.temp comes through empty)
Some checks failed
CI / Quality (push) Failing after 3m14s
Release / Linux AppImage (push) Has been cancelled
install-qt-action defaults `dir:` to `${{ runner.temp }}` if unset.
GitHub-hosted runners populate runner.temp; Gitea/Forgejo's act-runner
leaves it as the empty string. The action then rejects the empty path
with `TypeError: "dir" input may not be empty`.

Hardcoding `dir: ${{ github.workspace }}/qt` works on both — workspace
is always populated and writable, and the path is inside the job's
working tree so it's auto-cleaned with the workspace.

Same change in ci.yml and release.yml.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 10:03:31 +02:00
eac914d2d4 ci: work around install-qt-action propagating cache:true to setup-python
Some checks failed
CI / Quality (push) Failing after 3m13s
Release / Linux AppImage (push) Has been cancelled
jurplel/install-qt-action@v4 invokes actions/setup-python internally
with the same `cache:` value the user passes to the Qt action. Our
`cache: true` (intended for Qt's own install cache) gets propagated
verbatim, so setup-python receives `cache: 'true'` — which it rejects
with "Caching for 'true' is not supported" because the only valid
values are 'pip' / 'pipenv' / 'poetry'. Surfaces consistently on
Gitea/Forgejo's act-runner.

Workaround: provide our own actions/setup-python@v5 step (Python is
needed for aqtinstall, the tool install-qt-action uses to fetch Qt),
and set `setup-python: false` on the Qt action so it skips the
broken internal call. Qt's own install cache (the `cache: true` we
actually want) keeps working.

Applied to both .gitea/workflows/ci.yml and .gitea/workflows/release.yml.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 09:57:48 +02:00
3005815fe4 Phase 4a sub-commit 5: performance-smoke harness + 4a closure
examples/todo/tests/perfsmoke.sh asserts the PLAN.md §11 budgets
against the built AppImage:

  - Bundle size ≤ 200 MB (hard cap; ≤ 120 MB target)
  - Cold start ≤ 2000 ms from launch to first /healthz 200
  - Idle RSS (host + descendants in the process group) ≤ 200 MB after
    a 2 s settle.

Each budget is overridable via env (PERF_COLD_START_MS etc.) for slow
shared CI runners; defaults are the strict numbers from the plan. Runs
the AppImage under xvfb-run when DISPLAY is unset; falls back to
QT_QPA_PLATFORM=offscreen otherwise (the build script already bundles
libqoffscreen.so via EXTRA_PLATFORM_PLUGINS).

Wired into:
  - examples/todo/Makefile  → `make perf`
  - .gitea/workflows/release.yml → runs after AppImage build, before
    zsync + upload, with cold-start budget bumped to 4 s for CI.

CI now also installs zsync + xvfb in one step.

examples/todo/README.md gains an "AppImage packaging (Phase 4a)"
section walking through `make appimage`, bundled-mode behaviour, the
auto-update QML hooks (BackendConnection.checkForUpdates() / applyUpdate()),
and `make perf`.

PLAN.md §13 Phase 4 marked **4a closed**. 4b (macOS) and 4c (Windows)
stay stubs until their runners + certs exist.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 20:01:52 +02:00
fddb70f877 Phase 4a sub-commit 4: AppImageUpdate sidecar + appcast + checkForUpdates()
Wires in the option-(a) sidecar approach: the AppImage carries a
bundled AppImageUpdate AppImage and an embedded update-info string
in the .upd_info ELF section. BackendConnection drives both the
check and the apply via QProcess.

BackendConnection:
  - Q_INVOKABLE checkForUpdates()
        Bundled mode only. Spawns AppImageUpdate.AppImage with
        --check-for-update <APPIMAGE>. Exits 0 → noUpdatesAvailable,
        1 → updatesAvailable, anything else → updateCheckFailed.
        Dev mode: emits updateCheckFailed("…dev-mode only").
  - Q_INVOKABLE applyUpdate()
        Bundled mode only. Spawns AppImageUpdate.AppImage with
        --remove-old <APPIMAGE>. Replaces the running AppImage in
        place; user must restart. Emits updateApplied or
        updateApplyFailed.
  - Sidecar path resolves to applicationDirPath()/AppImageUpdate.AppImage
    by default, overridable via BRIDGE_APPIMAGEUPDATE_BIN.
  - APPIMAGE env (set by the AppImage runtime) determines the target
    file. Outside an AppImage both methods fail loudly.

build-appimage.sh:
  - Auto-downloads AppImageUpdate-x86_64.AppImage into the cached
    tools dir and copies it into AppDir/usr/bin/AppImageUpdate.AppImage.
  - New --update-info flag, forwarded to appimagetool's -u so the
    .upd_info ELF section carries an "zsync|<URL>" string the sidecar
    will fetch.

examples/todo Makefile forwards APPIMAGE_UPDATE_INFO env to the
script as --update-info.

release.yml:
  - Builds the AppImage with APPIMAGE_UPDATE_INFO set to the canonical
    Gitea Releases asset URL for this tag.
  - Installs zsync, runs zsyncmake to generate Todo-x86_64.AppImage.zsync.
  - Generates a JSON appcast (latest.json) with version / url / sha256 /
    size / zsync URL / released_at — useful as an HTTP-fetchable
    fallback for clients that prefer a structured manifest.
  - SHA256SUMS now covers AppImage + zsync + latest.json.
  - Uploads all four assets to the Gitea Release.

AppImage size grows from ~104 MB to ~152 MB with the sidecar bundled.
Embedding verified: objdump shows .upd_info populated with the
expected zsync URL after a local build.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 19:58:02 +02:00
d8726bac94 Fix CI: bump PHP requirement to ^8.4 (Symfony 8 enforces it)
CI was failing on the Install-bundle-dependencies step because
shivammathur/setup-php was installing 8.3 while Symfony 8.x dependencies
declare php >= 8.4. Local composer install worked because the dev box
runs PHP 8.5.5; CI doesn't.

Bumps:
  - framework/php/composer.json
  - framework/skeleton/symfony/composer.json
  - examples/todo/symfony/composer.json
  - .gitea/workflows/ci.yml         php-version: '8.3' → '8.4'
  - .gitea/workflows/release.yml    same
  - PLAN.md §13 Phase 1 *Detailed scope* PHP minimum row

PHPStan / cs-fixer / PHPUnit stay green locally.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 19:53:00 +02:00
03061f2f75 Phase 4a sub-commit 3: Linux release CI on v* tags
.gitea/workflows/release.yml builds the example's AppImage on every
v* tag push and uploads it to a Gitea Release together with a signed
SHA256SUMS:

  - Same PHP / Qt / FrankenPHP setup as the quality job (cached).
  - Reuses the AppImage recipe via `make appimage` (FRANKENPHP env
    points at the runner's installed binary; APPIMAGE_EXTRACT_AND_RUN=1
    to avoid FUSE inside CI).
  - sha256sum → SHA256SUMS.
  - When a GPG_KEY secret is present, imports it and emits
    SHA256SUMS.asc (--detach-sign --armor). Skipped silently if
    secrets aren't configured — CI red-lines for real failures, not
    for missing operational secrets.
  - Creates the Release via the Gitea API
    (POST /repos/{repo}/releases) and uploads
    AppImage + SHA256SUMS + SHA256SUMS.asc.

Workflow exists from this commit onward even before a Gitea runner is
provisioned; it'll just fail at the runner-needed steps if no runner
picks it up.

Required Gitea secrets (configurable when ready):
  - GITEA_TOKEN     — repo-scoped token, write:repository
  - GPG_KEY         — ASCII-armoured private key (optional)
  - GPG_PASSPHRASE  — the key's passphrase (optional)

Sub-commit 4 will append a zsync + appcast (latest.json) step here for
auto-update.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 19:50:42 +02:00