Stamp builds and release guidance with UTC date-time

This commit is contained in:
baketnk committed 2026-09-24 12:35:03 -04:00
1 parent a19d95a353
commit 04b404a653
3 files changed
+68 -13

No files matched your search

+29 -3
View File
@@ -1,5 +1,31 @@
cmake_minimum_required(VERSION 3.20) cmake_minimum_required(VERSION 3.20)
project(frameyap VERSION 0.1.0 LANGUAGES C CXX) project(frameyap LANGUAGES C CXX)
if(NOT DEFINED FRAMEYAP_VERSION OR FRAMEYAP_VERSION STREQUAL "")
# An ISO-like UTC build stamp is both readable and safe in archive filenames.
# SOURCE_DATE_EPOCH is honored by CMake's TIMESTAMP for reproducible builds.
string(TIMESTAMP FRAMEYAP_VERSION "%Y-%m-%dT%H%M%SZ" UTC)
find_package(Git QUIET)
if(GIT_FOUND)
execute_process(COMMAND "${GIT_EXECUTABLE}" -C "${CMAKE_CURRENT_SOURCE_DIR}" rev-parse --show-toplevel
OUTPUT_VARIABLE FRAMEYAP_GIT_ROOT OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET)
if(FRAMEYAP_GIT_ROOT STREQUAL CMAKE_CURRENT_SOURCE_DIR)
execute_process(COMMAND "${GIT_EXECUTABLE}" -C "${CMAKE_CURRENT_SOURCE_DIR}" rev-parse --short=8 HEAD
OUTPUT_VARIABLE FRAMEYAP_GIT_SHA OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET)
if(FRAMEYAP_GIT_SHA MATCHES "^[0-9a-f]+$")
string(APPEND FRAMEYAP_VERSION "-g${FRAMEYAP_GIT_SHA}")
endif()
execute_process(COMMAND "${GIT_EXECUTABLE}" -C "${CMAKE_CURRENT_SOURCE_DIR}" status --porcelain --untracked-files=no
OUTPUT_VARIABLE FRAMEYAP_GIT_DIRTY OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET)
if(FRAMEYAP_GIT_DIRTY)
string(APPEND FRAMEYAP_VERSION "-dirty")
endif()
endif()
endif()
endif()
if(NOT FRAMEYAP_VERSION MATCHES "^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9][0-9][0-9][0-9][0-9]Z(-g[0-9a-f]+)?(-dirty)?$")
message(FATAL_ERROR "FRAMEYAP_VERSION must be an ISO-like UTC timestamp: YYYY-MM-DDTHHMMSSZ[-gHASH][-dirty]")
endif()
message(STATUS "FrameYap build version: ${FRAMEYAP_VERSION}")
set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_CXX_EXTENSIONS OFF)
@@ -16,7 +42,7 @@ add_library(frameyap_core src/core.cpp)
target_include_directories(frameyap_core PUBLIC src) target_include_directories(frameyap_core PUBLIC src)
add_executable(frameyap src/main.cpp) add_executable(frameyap src/main.cpp)
target_link_libraries(frameyap PRIVATE frameyap_core) target_link_libraries(frameyap PRIVATE frameyap_core)
target_compile_definitions(frameyap PRIVATE FRAMEYAP_VERSION="${PROJECT_VERSION}") target_compile_definitions(frameyap PRIVATE FRAMEYAP_VERSION="${FRAMEYAP_VERSION}")
if(CMAKE_SYSTEM_NAME STREQUAL "Linux") if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
add_library(frameyap_mount src/mount.cpp) add_library(frameyap_mount src/mount.cpp)
target_include_directories(frameyap_mount PUBLIC src) target_include_directories(frameyap_mount PUBLIC src)
@@ -69,7 +95,7 @@ install(DIRECTORY python/frameyap DESTINATION python FILES_MATCHING PATTERN "*.p
include(CTest) include(CTest)
if(BUILD_TESTING AND NOT CMAKE_CROSSCOMPILING) if(BUILD_TESTING AND NOT CMAKE_CROSSCOMPILING)
add_test(NAME frameyap.cli COMMAND "${CMAKE_COMMAND}" "-DAPP=$<TARGET_FILE:frameyap>" add_test(NAME frameyap.cli COMMAND "${CMAKE_COMMAND}" "-DAPP=$<TARGET_FILE:frameyap>"
"-DEXPECTED_VERSION=${PROJECT_VERSION}" -P "${CMAKE_CURRENT_SOURCE_DIR}/tests/cli.cmake") "-DEXPECTED_VERSION=${FRAMEYAP_VERSION}" -P "${CMAKE_CURRENT_SOURCE_DIR}/tests/cli.cmake")
add_test(NAME frameyap.install_preflight COMMAND sh "${CMAKE_CURRENT_SOURCE_DIR}/tests/install-preflight.sh" add_test(NAME frameyap.install_preflight COMMAND sh "${CMAKE_CURRENT_SOURCE_DIR}/tests/install-preflight.sh"
"${CMAKE_CURRENT_SOURCE_DIR}/scripts/install-preflight.sh") "${CMAKE_CURRENT_SOURCE_DIR}/scripts/install-preflight.sh")
add_executable(frameyap_core_test tests/core_test.cpp) add_executable(frameyap_core_test tests/core_test.cpp)
+6
View File
@@ -48,6 +48,8 @@ ctest --test-dir build --output-on-failure
Default build has no hardware backends. It never downloads packages/models or Default build has no hardware backends. It never downloads packages/models or
initializes SteamVR, a microphone or input injection. Native dependencies and initializes SteamVR, a microphone or input injection. Native dependencies and
explicit launch/check commands are documented in [the POC guide](docs/poc.md). explicit launch/check commands are documented in [the POC guide](docs/poc.md).
`--version` uses an ISO-like UTC build timestamp (with Git hash when available),
not a numbered release; use that same tag when packaging the binary.
## Installation ## Installation
@@ -66,6 +68,10 @@ Autolaunch is opt-in. An installed desktop entry can be selected manually as a
non-Steam shortcut. A basic launch from Steam's Non-Steam section opened the non-Steam shortcut. A basic launch from Steam's Non-Steam section opened the
panel on one Frame; registration alone did not show an entry in the first checked panel on one Frame; registration alone did not show an entry in the first checked
dashboard menu. See [packaging and lifecycle](docs/packaging.md). dashboard menu. See [packaging and lifecycle](docs/packaging.md).
For a native-only install, menu-driven inference needs a separately authorized
Python runtime and pinned model. Configure their absolute paths in
`~/.config/frameyap/paths.conf` as described in the packaging guide; they are
never fetched or bundled implicitly.
A pinned GitHub one-command route is implemented in `install.sh --version TAG`, A pinned GitHub one-command route is implemented in `install.sh --version TAG`,
but **do not advertise or run it as a working public installation until a vetted but **do not advertise or run it as a working public installation until a vetted
+33 -10
View File
@@ -31,10 +31,18 @@ prefix. ARM64/glibc packaging is not a claim of compatibility with arbitrary Lin
```sh ```sh
python3 scripts/package-release.py --stage /path/to/stage --output /existing/output \ python3 scripts/package-release.py --stage /path/to/stage --output /existing/output \
--version v0.1.0-poc --arch linux-aarch64 \ --version 2026-09-24T162712Z-g417f81c --arch linux-aarch64 \
--model-revision fad622f25f303105c20d70e201bcc477c88b620c --external-runtime --model-revision fad622f25f303105c20d70e201bcc477c88b620c --external-runtime
``` ```
Use the actual binary's UTC build stamp (`frameyap --version`) for the archive
tag, not this illustrative timestamp. CMake generates `YYYY-MM-DDTHHMMSSZ`
at configuration time (plus `-gSHORTSHA` for a Git checkout and `-dirty` for
uncommitted tracked changes); producers may pin `-DFRAMEYAP_VERSION=...` to
embed a vetted release stamp. A timestamp distinguishes same-day archives;
the installer still refuses a reused tag whose contents have changed. Historic
`v0.1.0-poc*` local artifacts remain valid for reinstall/rollback.
`--external-runtime` refuses a runtime directory and records `--external-runtime` refuses a runtime directory and records
`runtime: external-authorized-python` in `release.json`. The installer explicitly `runtime: external-authorized-python` in `release.json`. The installer explicitly
reports that ASR is not supplied. Without that flag, a complete independently reports that ASR is not supplied. Without that flag, a complete independently
@@ -71,9 +79,22 @@ same version is refused. External model provisioning is always deliberate.
The installed launcher defaults to `--run`. For a native-only package, supply The installed launcher defaults to `--run`. For a native-only package, supply
`FRAMEYAP_PYTHON=/absolute/authorized/python` and `FRAMEYAP_MODEL=/absolute/model`, `FRAMEYAP_PYTHON=/absolute/authorized/python` and `FRAMEYAP_MODEL=/absolute/model`,
or override `--python`/`--model` on an explicit `--run`. No pip/bootstrap/fallback or override `--python`/`--model` on an explicit `--run`. For menu launches, create
is invoked by the launcher. Missing runtime means visible failure, not recording. `$XDG_CONFIG_HOME/frameyap/paths.conf` (default `~/.config/frameyap/paths.conf`):
Environment configuration is not automatically persisted for SteamVR autolaunch.
```text
python=/absolute/path/to/independently-authorized/runtime/bin/python3
model=/absolute/path/to/pinned/local/model
```
The launcher reads these as **literal absolute paths**, not shell code, and does
not follow a symlink to the config file. Environment variables override either
setting for an explicit launch. This user-owned config survives upgrade/uninstall;
the installer does not populate it or bundle an unauthorized runtime. No
pip/bootstrap/model download or fallback is invoked by the launcher. Without
paths, the native-only artifact cannot perform voice inference; its default
runtime and model locations do not exist. A new installer accepts only the exact
previous managed launcher bytes for migration; a modified launcher is refused.
Without any ASR runtime, these checks work directly through the installed launcher: Without any ASR runtime, these checks work directly through the installed launcher:
@@ -128,10 +149,11 @@ exit; no owned process remained. This establishes a basic menu-driven launch on
that device, **not** that OpenVR registration alone creates a Steam shortcut or that device, **not** that OpenVR registration alone creates a Steam shortcut or
that the new desktop entry was the sole discovery path. The manifest points to that the new desktop entry was the sole discovery path. The manifest points to
`~/.local/bin/frameyap`, which starts `--run` if launched. A native-only install `~/.local/bin/frameyap`, which starts `--run` if launched. A native-only install
without a model or authorized runtime should show an **Unavailable** overlay without configured model/runtime cannot transcribe; it should show **Unavailable**
rather than record or run inference. Only perform this check on that native-only (possibly after a brief Warming transition), rather than record or infer.
installation: verify that `current/runtime/bin/python3` and `current/model` are Only perform this check on an unconfigured native-only installation: verify
absent first, and do not press Record, Insert or Enter. that `current/runtime/bin/python3` and `current/model` are absent and no
user-local paths are configured; do not press Record, Insert or Enter.
The installer also provides a desktop entry; where Steam's UI supports adding a The installer also provides a desktop entry; where Steam's UI supports adding a
non-Steam app, the user may select that entry or browse to the installed launcher. non-Steam app, the user may select that entry or browse to the installed launcher.
Shortcut discovery/persistence after a normal restart is not yet verified. Do Shortcut discovery/persistence after a normal restart is not yet verified. Do
@@ -150,8 +172,9 @@ not hand-edit Steam's shortcut database.
This check does not validate microphone capture, transcription, controller input, This check does not validate microphone capture, transcription, controller input,
text delivery or cold SteamVR startup. With a configured inference runtime, the text delivery or cold SteamVR startup. With a configured inference runtime, the
menu launch attempts to load the model; defer that test until runtime licensing is menu launch attempts to load the model; defer that test until runtime licensing is
resolved. If an environment/configuration unexpectedly supplies a runtime/model, resolved or independent authorization is established. If an
do not perform this check. environment/configuration unexpectedly supplies a runtime/model, do not perform
this inert launcher check.
Before uninstall, explicitly `frameyap --unregister /absolute/manifest/path` and Before uninstall, explicitly `frameyap --unregister /absolute/manifest/path` and
verify success, then run `sh install.sh --uninstall --unregistered`. The latter is verify success, then run `sh install.sh --uninstall --unregistered`. The latter is