Repository navigation
vinca-gha --timings (pack each stage's recipes into jobs by measured build time) and --keep-file - #179
Merged
Tobias-Fischer merged 4 commits intoOct 23, 2026
Conversation
…time Each stage of the staged build workflow is cut into jobs of --batch_size recipes in list order, so the heavy recipes of a stage often end up in one job that holds up the whole stage. In RoboStack's jazzy full rebuild one job ran alone 55% of the time on Linux (e.g. rviz_default_plugins and nav2_behavior_tree in a 25-minute job next to 3-minute ones). With --timings (a JSON file of measured seconds per recipe, a default for unmeasured ones and the per-job overhead) and --runners, each stage is packed longest-first into the number of jobs that gives the shortest stage on that many runners (fewer jobs when that costs at most 1% or one job's overhead), never more than --batch_size recipes per job, each job keeping the stage's order. Consecutive short stages (5 minutes) still share a job. Without --timings nothing changes. Simulated on the measured jazzy rebuild: 6.9 -> 2.6 h on linux-64, 5.8 -> 2.1 h on linux-aarch64, 9.0 -> 5.0 h on osx-arm64, for at most 3% more runner time. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…thresholds With package_name_mode: both, each ros-<distro>-<name> compatibility package only depends on ros2-<name> (and the mutex, which that needs too). With --timings it's now built right after it in the same job, its time counted towards it, instead of a stage later in another job; one whose ros2- package isn't being built stays where it was. batch_stages takes these as `followers`. Thresholds, from simulating the generated workflows with jazzy's measured linux-64 times (8 runners): consecutive single-job stages share a job up to 120 s (was 300), and a stage takes fewer jobs only when that costs at most 1% (no extra one-job-overhead slack): 2.68 h instead of 3.21 h, 233 jobs, 384 KiB. Today's workflow models at 6.96 h (the run took 6.93 h). Every recipe's ROS dependencies are in an earlier stage or earlier in its job. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rs says otherwise 20 jobs at once with GitHub-hosted runners, 5 on macOS (the Free plan). Simulated on jazzy linux-64: 283 jobs, 442 KiB, 2.47 h on 20 runners (3.00 h if only 8 are free). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Tobias-Fischer
added a commit
to RoboStack/robostack
that referenced
this pull request
Oct 23, 2026
…s by time The build jobs now record their times: `rs <distro> build-ci` times each recipe's build and `rs <distro> upload` each package's upload, appending to distros/<distro>/work/build_timings.jsonl, which every build-branch job keeps as an artifact (build-times-<job>, a step `rs gha` adds after the build). robostack-bot update-build-timings (weekly, with the dependency reports) merges the last week's artifacts into shared/build_timings/<platform>.json: each recipe's newest time per distribution; a distribution uses the average over all of them, so a recipe new to it still has a time. Compatibility recipes share one median per distribution. Once a platform has times and the pinned vinca supports it, `rs <distro> gha` passes them to vinca-gha --timings (RoboStack/vinca#179), which packs each stage's recipes into jobs by time and builds compatibility packages right after their package; until then nothing changes. A workflow over GitHub's size limit is retried with fewer runners first. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each build job (unix, macOS, Windows) then ends with an upload-artifact step for that file, also when the build failed; RoboStack keeps the build times its jobs record this way, for --timings. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Tobias-Fischer
added a commit
to RoboStack/robostack
that referenced
this pull request
Oct 23, 2026
…s by time
Each build-branch job records how long each recipe took to build (`rs
<distro> build-ci`, in distros/<distro>/work/build_timings.jsonl) and keeps
that file as an artifact (vinca-gha --keep-file). robostack-bot
update-build-timings (weekly, with the dependency reports) merges the last
week's into shared/build_timings/<platform>.json, {recipe: {distro: seconds}}.
With times for the platform, `rs <distro> gha` passes vinca-gha --timings
(each recipe's average over the distributions, so a recipe new to one
distribution still has a time): it packs each stage's recipes into jobs by
time and builds compatibility packages right after their package. Until then
the jobs are cut by count as before. A workflow over GitHub's size limit is
retried with fewer runners first.
The vinca pin moves to RoboStack/vinca#179 (--timings, --keep-file).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
Author
|
@baszalmstra - what do you think of this approach? Meant to replace / complement #149. @traversaro - do you mind having a look as well? RoboStack PR to save the timings in the first instance and then use the new functionality: RoboStack/robostack#139 |
Collaborator
|
this looks like a much better approach than what I tried! |
traversaro
approved these changes
Oct 23, 2026
Member
|
Great! How do we plan to maintain the timings file? Every full rebuild overwrites the timing file check in in the repo? |
Member
Never-ending, I now saw the corresponding robostack PR! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The staged GitHub Actions workflow cuts each stage into jobs of
--batch_sizerecipes in list order. The heavy recipes of a stage often end up in one job, which then holds up the whole stage.In RoboStack's jazzy full rebuild, a single job was running alone for 55% of the wall time on Linux. For example, rviz_default_plugins and nav2_behavior_tree shared a 25-minute job, while the other jobs of that stage took about 3 minutes.
vinca-gha --timings <file> [--runners N](opt-in; without--timingsnothing changes):{"recipes": {name: seconds}, "default": seconds, "job_overhead": seconds}.--batch_sizerecipes, and each job keeps the stage's order.package_name_mode: both, eachros-<distro>-<name>package only depends onros2-<name>(and the mutex, which that needs too). It is now built right after that package in the same job, and its time counts towards it, instead of a stage later in another job. One whoseros2-package isn't being built stays where it is (batch_stages(..., followers=...)).vinca-gha --keep-file <path>: every build job (unix, macOS, Windows) ends with anupload-artifactstep for that file, named after the job, also when the build failed. RoboStack uses it to keep the build times its jobs record, which become the--timingsinput.Checked against the real jazzy rebuild (linux-64, 2405 recipes, per-recipe times from its logs, simulated with 8 runners):
--timings --runners 8--timings(20 runners)--runnerswhen fewer can be counted on, e.g. when several workflows share the account's limit.BuildTimings.from_file,compatibility_followersand--keep-file. All 305 pass, and ruff is clean.RoboStack/robostack#139 records the times in its build jobs, keeps them with
--keep-file, and passes them back as--timings, averaged over its distributions.The measurements and the comparison with #149's scheduler are in the analysis behind this; in short, plain time-balancing within the existing stages captures most of the gain.
🤖 Claude (AI assistant), on behalf of @Tobias-Fischer
🤖 Generated with Claude Code