Feature/luxonis apps release workflow - #857
PetrNovota wants to merge 21 commits into
Conversation
813f55c to
43ddc40
Compare
727ce7a to
fd6cbdf
Compare
create workflow for publishing all apps
…oakapp identifier convention
- detect pipline was created by checking `Pipeline created` log - always print last 10 lines of app logs to potentially catch issues otherwise not discoverable by tests, like Sync issues and others
60f553e to
b6d090b
Compare
klemen1999
left a comment
There was a problem hiding this comment.
The renaming of depth-measurement/3d-measurement → depth-measurement/measurement-3d and neural-networks/3D-detection → neural-networks/detection-3d needs to be coupled with:
- recheck on the whole oak-examples repo so that older links are corrected
- a PR on the docs side (
docs-contentrepo) with corrected links since old ones won't be reachable anymore
There was a problem hiding this comment.
Line 94 should be updated since USE_INFERENCE_MODELS is no in oakapp.toml and not backend-run.sh
| # Detect app start trigger | ||
| if "App output:" in line: | ||
| # Detect app start trigger only after Pipeline.start() returns successfully. | ||
| if "Pipeline started." in line: |
There was a problem hiding this comment.
This is example specific printout and kind of a hidden rule now that if example doesn't have it then this will stall. Whereas App output: AFAIK is always printed by oakctl.
We should add this Pipeline started. log requirement in EXAMPLE_CONTRIBUTING.md file.
And maybe we should be checking for both and if App output: happens but Pipeline started. doesn't we fail the test with a message essentially saying that "Pipeline started." wasn't detected and should be added to the example (if not already). If it is already added then this is an issue with pipeline being misconfigured most likely.
| for app in "${selected_apps[@]}"; do | ||
| identifier=$(sed -n -E 's/^[[:space:]]*identifier[[:space:]]*=[[:space:]]*"([^"]*)".*/\1/p' "$app/oakapp.toml" | head -n 1) | ||
| app_version=$(sed -n -E 's/^[[:space:]]*app_version[[:space:]]*=[[:space:]]*"([^"]*)".*/\1/p' "$app/oakapp.toml" | head -n 1) | ||
| if [[ -z "$app_version" ]]; then |
There was a problem hiding this comment.
Nitpick: Perhaps we can validate app version structure as well (major.minor.patch).
if [[ ! "$app_version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
| - [Object Detection](#object-detection) | ||
| - [Face Detection](#face-detection) | ||
| - [3D Detection](#3d-detection) | ||
| - [Detection 3D](#detection-3d) |
There was a problem hiding this comment.
Nitpick: I'd leave this as "3D Detection" as the "user facing text" and update just the link to the #detection-3d. "3D Detection" is IMO more used term and more logical than the other way around.
There was a problem hiding this comment.
Idea: Would it make sense to refactor the existing publish_oakapp.yaml and then reuse it inside the publish_oakapps.yaml (using uses: ./.github/workflows/publish_oakapp.yaml inside it's job)? Because conceptually it would make sense but not sure if there is some blocker or something I didn't take into account.
Purpose
Add a repeatable release workflow for publishing a curated set of OAK Apps to Luxonis Hub, and align the examples' identifiers, standalone entrypoints, and startup reporting with that workflow. This also fixes device timestamp propagation in general OCR and updates standalone runnability tests to wait for successful pipeline startup.
Specification
Bulk publishing to Luxonis Hub
.github/workflows/publish_oakapps.yaml, alongside the existing single-app publishing workflow..github/publish_oakapps.txt: seven apps underapps/, open-vocabulary object detection, lossless zooming, general OCR, age/gender estimation, depth crop, hand pose, and spatial detections.exclude_appsand adry_runthat validates and displays the publish plan without reserving hardware or publishing.oakapp.tomlfiles, identifier prefixes, app versions, unique target identifiers, and exclusion inputs before creating the publish matrix. Reject an empty selection.Identifier conventions and repository paths
com.example.<top-level-folder>.<app-suffix>tocom.luxonis.<app-suffix>. For example,com.example.neural-networks.ocr.general-ocrpublishes ascom.luxonis.ocr.general-ocr.NEW_IDENTIFIERoverride, validate its characters, leave identifiers already in thecom.luxonisnamespace unchanged, and reject unexpected source prefixes.sedediting with a temporary-file replacement and extend cleanup to remove that temporary file. Preserve restoration of the originaloakapp.tomlwhen the script exits.depth-measurement/3d-measurement/todepth-measurement/measurement-3d/andneural-networks/3D-detection/toneural-networks/detection-3d/.Standalone application lifecycle
Migrate affected apps from running their main backend under runit to passing the application command directly to the base image's
/entrypoint.sh, for example:Remove obsolete backend service installation steps and launcher contents/files. The base entrypoint manages helper services, forwards termination to the main app, and propagates its exit status, allowing oak-agent to observe backend failure and request shutdown.
Apply the same entrypoint pattern to affected script examples and the C++ camera stream example, using their corresponding commands.
Bump data collection and open-vocabulary object detection to app version
1.1.0.Keep Roboflow Workflow on Python 3.12, matching its base image and dependency installation commands. Move
USE_INFERENCE_MODELSfrom the removed launcher into[env]as the string"False", preserving the classic ONNX Runtime inference path.Pipeline startup reporting and standalone tests
Pipeline created.before startup andPipeline started.afterpipeline.start()returns across the affected examples. Enable INFO logging in focused vision so its startup marker is visible to tests.Pipeline started.rather than the genericApp output:header. Container log attachment alone no longer counts as successful pipeline startup.oakctl app stop, allowing up to 60 seconds for the stop command to complete.pipeline.run()calls in barcode detection, MJPEG streaming, and Rerun with explicit startup and task-processing loops so they can emit the startup marker. MJPEG and Rerun also add a short sleep between processing iterations.General OCR synchronization fix
Propagate the source detections' device timestamp to every crop configuration, the enclosing configuration message group—including empty groups—and the filtered detections. Host timestamps and sequence numbers remain preserved. This gives
FrameCropperthe matching device timestamps it needs to synchronize crop configurations with source frames, addressing stalled OCR processing caused by zero device timestamps.Dependencies & Potential Impact
GITLAB_TOKEN, andOAKCTL_HUB_TOKEN. It reuses the existing oakctl build/publish tooling. Runtime tests are separate from the publishing workflow./entrypoint.shlifecycle behavior. Startup markers confirm that pipeline startup returned; they do not by themselves prove that frames or inference outputs continue flowing.Deployment Plan
dry_run=trueand any required exclusions, then inspect the generated plan.dry_run=falseto build and publish the selected apps. Publishing is manually triggered; merging this PR does not itself publish or install apps on end-user devices.Testing & Validation
5e8c1eepasses theagents-indexandpre-commitCI jobs, plus the runnability workflow's precheck, setup, and change detection. CI run.3d0e2e2passed syntax parsing of 84 changed Python files, publishing-script shell syntax, AGENTS.md validation for 92 examples, generated-index consistency,git diff --check, and validation of all 14 publish targets with unique identifiers.processTasks(waitForTasks=True); their threading and Ctrl-C behavior remain to be verified. A sleep after that call does not bound the wait itself.AI Usage
AI assistance was reported for implementation in the original description. Codex assisted with code review and this PR description update.
Submitted code was reviewed by a human: YES/NO
The author is taking the responsibility for the contribution: YES/NO