Skip to content

feat: add just recipes to run the current checkout in an isolated dev device - #4387

Open
jarhodes314 wants to merge 5 commits into
thin-edge:mainfrom
jarhodes314:jarhodes314/run-prs-easily-in-demo-container
Open

jarhodes314 wants to merge 5 commits into
thin-edge:mainfrom
jarhodes314:jarhodes314/run-prs-easily-in-demo-container

Conversation

@jarhodes314

@jarhodes314 jarhodes314 commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Proposed changes

Adds just recipes to try out the current checkout (e.g. a PR branch) on a throwaway device: build it, run it in an isolated debian-systemd-based container named after the branch, and optionally register it with Cumulocity or switch it to tedge run all. Cargo features can be passed to the build, so feature-gated changes such as mapper-config can be tried too.

just dev-device-up [NAME] [BUILD_ARGS]  # build, start tedge-dev-<NAME>, bootstrap, start tedge-agent
just dev-device-c8y [NAME]              # register it with c8y via `c8y tedge bootstrap-container`
just dev-device-run-all [NAME]          # swap tedge-agent + tedge-mapper-* for one `tedge` service running `tedge run all`
just dev-device-shell [NAME]            # bash inside the container
just dev-device-down [NAME]             # remove it and its image
just dev-device-list                    # list all tedge-dev-* containers
just dev-device-prune                   # remove all tedge-dev-* containers and images

NAME defaults to the current branch (or short commit when detached) with non-alphanumerics replaced by -, so several devices can run side by side. If the first argument to dev-device-up starts with -, the arguments are assumed to be cargo arguments:

just dev-device-up --features tedge/mapper-config        # device named after the branch
just dev-device-up my-pr --features tedge/mapper-config  # explicit name

dev-device-up builds with the dev-stripped profile unless BUILD_PROFILE is given, as an unstripped debug tedge binary is ~600 MB. Since release is also the justfile's default, a release dev device needs BUILD_PROFILE=release just dev-device-up.

Each device gets its own tedge-dev-<name> image rather than the shared debian-systemd tag, so a build in another worktree can't retag the image between dev-device-up building it and running it.

 ci/build_scripts/
-├── build.sh                    # cargo flags fixed by --profile/--bin
+├── build.sh                    # + --features <list>; warns that `debug` keeps debug info
-└── package.sh                  # xz for every profile
+└── package.sh                  # no compression unless BUILD_PROFILE is release
 justfile
-  build-integration-test: build
-    invoke build
+  build-integration-test *ARGS: (build "--package-types deb" ARGS)
+    invoke build --name "${INTTEST_IMAGE:-debian-systemd}"
+  dev-device-{up,c8y,run-all,shell,down,list,prune}
 tests/images/debian-systemd/
 ├── debian-systemd.dockerfile   # copies the script into /setup
 └── files/
+    └── use-tedge-run-all.sh    # writes tedge.service, masks the per-component services

The features need the package prefix (tedge/…) because the workspace root isn't a package. The run-all script masks the per-component services rather than only disabling them, so tedge connect can't start them alongside tedge run all.

Packages built with debug or dev-stripped are only used locally, so package.sh skips xz for them. nfpm doesn't expand env vars in compression, so it builds from a copy of the manifest with compression: none. With an unstripped debug binary (~600 MB), deb packaging went from 80 s to 2.8 s. build-integration-test now only builds debs, which is all invoke build uses; the other formats took another ~50 s. build.sh also warns when debug is used, since dev-stripped is usually what's wanted.

Types of changes

  • Bugfix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Improvement (general improvements like code refactoring that doesn't explicitly fix a bug or add any new functionality)
  • Documentation Update (if none of the other choices apply)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)

Paste Link to the issue

None

Checklist

  • I have read the CONTRIBUTING doc
  • I have signed the CLA (in all commits with git commit -s. You can activate automatic signing by running just prepare-dev once)
  • I ran just format as mentioned in CODING_GUIDELINES
  • I used just check as mentioned in CODING_GUIDELINES
  • I have added tests that prove my fix is effective or that my feature works
  • I have added necessary documentation (if appropriate)

Further comments

Merge Danger

Door: two-way

Dev-only recipes, opt-in build behaviour and one extra file in the test image; reverting removes them.

Blast Radius: small

build.sh, package.sh and the debian-systemd image are shared with CI. Release packages are unchanged: with BUILD_PROFILE=release or unset, debs are still built with data.tar.xz. Builds without --features pass the same cargo flags as before, integration-test still builds the debian-systemd image (now from debs only, which is all it ever used), and the extra COPY only adds a script that nothing runs unless someone calls just dev-device-run-all.

🤖 Generated with Claude Code

jarhodes314 and others added 2 commits October 21, 2026 17:03
`just pr-device-up` builds the current checkout and starts a debian-systemd
container named after the branch, with recipes to register it with
Cumulocity, switch it to `tedge run all`, open a shell, list and remove it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: James Rhodes <jarhodes314@gmail.com>
`ci/build_scripts/build.sh --features <list>` enables cargo features for
every binary it builds. `just pr-device-up` forwards arguments starting
with `-` to the build, so a feature-gated change can be tried on a PR
device while keeping the device name derived from the branch:

    just pr-device-up --features tedge/mapper-config

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: James Rhodes <jarhodes314@gmail.com>
@jarhodes314
jarhodes314 requested review from a team, Bravo555 and reubenmiller as code owners October 22, 2026 08:14
@jarhodes314
jarhodes314 deployed to Test Pull Request October 22, 2026 08:14 — with GitHub Actions Active
@codecov

codecov Bot commented Oct 22, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Packages from the `debug` and `dev-stripped` profiles are only used
locally, and xz on an unstripped debug `tedge` binary (~600 MB) took
over a minute per package type. nfpm doesn't expand env vars in
`compression`, so package.sh builds from a copy of the manifest with
`compression: none` when BUILD_PROFILE isn't `release`.

build.sh also warns that the `debug` profile keeps debug info in the
packaged binaries, since `dev-stripped` is usually what's wanted.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: James Rhodes <jarhodes314@gmail.com>
The recipes run whatever is checked out, not a PR, so they are renamed
to `dev-device-*` and the containers to `tedge-dev-<name>`.

`dev-device-up` builds its own `tedge-dev-<name>` image instead of
retagging `debian-systemd`, so a build in another worktree can't change
which image the device starts from. `build-integration-test` takes the
image name from INTTEST_IMAGE (defaulting to `debian-systemd`), and
`dev-device-down`/`dev-device-prune` remove the images too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: James Rhodes <jarhodes314@gmail.com>
@jarhodes314
jarhodes314 deployed to Test Pull Request October 22, 2026 13:10 — with GitHub Actions Active
@jarhodes314 jarhodes314 changed the title feat: add just recipes to run a PR in an isolated demo container feat: add just recipes to run the current checkout in an isolated dev device Oct 22, 2026
@github-actions

github-actions Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Robot Results

✅ Passed ❌ Failed ⏭️ Skipped Total Pass % ⏱️ Duration
1047 0 8 1047 100 3h31m54.835987s

`dev-device-up` builds with the `dev-stripped` profile unless
BUILD_PROFILE is given, as an unstripped `debug` binary is ~600 MB.

`build-integration-test` only builds deb packages, which is all
`invoke build` copies into the image. Packaging the other formats took
~50 s on a debug build, against ~3 s for debs alone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: James Rhodes <jarhodes314@gmail.com>
@jarhodes314
jarhodes314 deployed to Test Pull Request October 22, 2026 13:38 — with GitHub Actions Active
@jarhodes314

Copy link
Copy Markdown
Contributor Author

Following the discussion in the daily, I've renamed the commands for this to dev-device-... rather than pr-device-... to make it clearer it is about the local checkout, not an automatic PR worktree creation tool. I've also made a few improvements to ensure it builds quickly (i.e. uses a debug build and strips symbols by default, only builds deb packages, and nfpm doesn't compress the packages).

I had a discussion with claude about the feasibility of reusing robot for setting up the device. It seems that it isn't terribly worthwhile. Between the container image and c8y tedge, the complex problems are solved for us, the justfile isn't duplicating a lot of logic. Here's what claude says:

What reusing robot would give

  • One source of truth for the container options, so the recipes' docker run can't drift from the test containers.
  • Cumulocity registration using the same .env credentials as the tests (c8y-ca), removing the dependency on go-c8y-cli and its tedge extension.

Why it doesn't seem worth it

  • It only replaces container creation and registration. bootstrap.sh is already shared, and shell/list/down/prune would still be docker commands, so the justfile stays anyway.
  • Robot runs suites, it doesn't hand you a device: we'd need a dummy suite calling Setup with cleanup=False.
  • Robot names devices after a serial (probably random), whereas the recipes name them after the branch.
  • Each run would pay for venv activation and robot startup, and failures would end up in output.xml rather than the terminal.
  • The duplication it removes is a single docker run line.

Possible middle ground

If the go-c8y-cli dependency or podman support matters, an invoke task in tests/RobotFramework/tasks.py could register the device using ThinEdgeIO's registration with the .env credentials, and reuse detect_container_cli() (which also handles podman). The justfile recipes would stay as thin wrappers around it.

This branch was successfully deployed

2 active deployments
Test Auto — b7bb44ec Deployed Oct 22, 2026 by jarhodes314 via Test x86_64 #8784
Test Pull Request — b7bb44ec Deployed Oct 22, 2026 by jarhodes314 via Approve #8784
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant