Skip to content

Feature/luxonis apps release workflow - #857

Open
PetrNovota wants to merge 21 commits into
mainfrom
feature/luxonis_apps_release_workflow
Open

PetrNovota wants to merge 21 commits into
mainfrom
feature/luxonis_apps_release_workflow

Conversation

@PetrNovota

@PetrNovota PetrNovota commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

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

  • Add the manually triggered Publish OAK Apps workflow in .github/workflows/publish_oakapps.yaml, alongside the existing single-app publishing workflow.
  • Define the initial 14 release targets in .github/publish_oakapps.txt: seven apps under apps/, open-vocabulary object detection, lossless zooming, general OCR, age/gender estimation, depth crop, hand pose, and spatial detections.
  • Support comma-separated exclude_apps and a dry_run that validates and displays the publish plan without reserving hardware or publishing.
  • Validate app directories, oakapp.toml files, identifier prefixes, app versions, unique target identifiers, and exclusion inputs before creating the publish matrix. Reject an empty selection.
  • Build and publish through the existing HIL runner and publishing container on OAK4 Pro or OAK4 D testbeds. Run up to three apps in parallel, let other apps finish when one fails, serialize bulk workflow runs, and record the plan and per-app results in the Actions summary.

Identifier conventions and repository paths

  • Normalize example identifiers to include their top-level repository category, correcting inconsistent names and typos across app configurations.
  • Update the shared publishing script to map com.example.<top-level-folder>.<app-suffix> to com.luxonis.<app-suffix>. For example, com.example.neural-networks.ocr.general-ocr publishes as com.luxonis.ocr.general-ocr.
  • Preserve the explicit NEW_IDENTIFIER override, validate its characters, leave identifiers already in the com.luxonis namespace unchanged, and reject unexpected source prefixes.
  • Replace in-place sed editing with a temporary-file replacement and extend cleanup to remove that temporary file. Preserve restoration of the original oakapp.toml when the script exits.
  • Rename depth-measurement/3d-measurement/ to depth-measurement/measurement-3d/ and neural-networks/3D-detection/ to neural-networks/detection-3d/.
  • Update category READMEs, example guidance, the generated index, and affected known-failing test paths for these changes. Update publishing documentation and the single-app workflow's identifier help text.

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:

    entrypoint = ["/entrypoint.sh", "python3", "-u", "/app/backend/src/main.py"]
  • 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_MODELS from the removed launcher into [env] as the string "False", preserving the classic ONNX Runtime inference path.

Pipeline startup reporting and standalone tests

  • Standardize Pipeline created. before startup and Pipeline started. after pipeline.start() returns across the affected examples. Enable INFO logging in focused vision so its startup marker is visible to tests.
  • Change the standalone test's run timer to begin on Pipeline started. rather than the generic App output: header. Container log attachment alone no longer counts as successful pipeline startup.
  • Keep reading the app output after startup instead of closing the stream and waiting for the foreground command to exit before monitoring app status.
  • Print the collected recent log lines after monitoring on both successful and failed runs, and add diagnostics to the background output reader.
  • Stop the develop app explicitly with oakctl app stop, allowing up to 60 seconds for the stop command to complete.
  • Replace blocking 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.
  • Start an initial default WebRTC pipeline when the server starts, allowing startup to be observed before a browser connects; offers continue to rebuild the pipeline for the selected options.

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 FrameCropper the matching device timestamps it needs to synchronize crop configurations with source frames, addressing stalled OCR processing caused by zero device timestamps.

Dependencies & Potential Impact

  • Publishing requires a self-hosted testbed runner, the HIL framework, an available OAK4 Pro or OAK4 D, GITLAB_TOKEN, and OAKCTL_HUB_TOKEN. It reuses the existing oakctl build/publish tooling. Runtime tests are separate from the publishing workflow.
  • Identifier changes can change which Hub app a package targets. Existing installations and external references to previous identifiers do not automatically migrate; review the identifier plan before publishing.
  • Scripts and links using the renamed example directories need the new paths.
  • Entrypoint migration relies on the configured OAK App base images' /entrypoint.sh lifecycle behavior. Startup markers confirm that pipeline startup returned; they do not by themselves prove that frames or inference outputs continue flowing.

Deployment Plan

  1. Complete the peripheral and standalone runnability checks, including output flow and termination behavior for the changed lifecycle loops and OCR pipeline.
  2. Review the curated manifest and each target's version and Hub identifier.
  3. Run Publish OAK Apps with dry_run=true and any required exclusions, then inspect the generated plan.
  4. Run with dry_run=false to 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

  • At description update, head 5e8c1ee passes the agents-index and pre-commit CI jobs, plus the runnability workflow's precheck, setup, and change detection. CI run.
  • Peripheral tests for RVC2 and RVC4 and the standalone test job are still in progress at this update. Runnability test run.
  • Local review of the earlier head 3d0e2e2 passed 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.
  • Hardware-free DepthAI 3.8.0 reproductions identified lifecycle issues during review. The current MJPEG and Rerun loops still use blocking processTasks(waitForTasks=True); their threading and Ctrl-C behavior remain to be verified. A sleep after that call does not bound the wait itself.
  • Full on-device builds, end-to-end publishing, and OCR output progression were not validated locally during this review.

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

@PetrNovota PetrNovota added the testable PR is ready to be tested label Aug 26, 2026
@PetrNovota
PetrNovota force-pushed the feature/luxonis_apps_release_workflow branch 3 times, most recently from 813f55c to 43ddc40 Compare September 2, 2026 09:27
@PetrNovota
PetrNovota force-pushed the feature/luxonis_apps_release_workflow branch from 727ce7a to fd6cbdf Compare September 9, 2026 07:48
@PetrNovota
PetrNovota force-pushed the feature/luxonis_apps_release_workflow branch from 60f553e to b6d090b Compare September 10, 2026 09:19

@klemen1999 klemen1999 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The renaming of depth-measurement/3d-measurementdepth-measurement/measurement-3d and neural-networks/3D-detectionneural-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-content repo) with corrected links since old ones won't be reachable anymore

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

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:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

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

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Nitpick: Perhaps we can validate app version structure as well (major.minor.patch).

if [[ ! "$app_version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then

Comment thread neural-networks/README.md
- [Object Detection](#object-detection)
- [Face Detection](#face-detection)
- [3D Detection](#3d-detection)
- [Detection 3D](#detection-3d)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

testable PR is ready to be tested

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants