From 2bd19f17e759b8a1bb1e1c42ab225ac591caac6b Mon Sep 17 00:00:00 2001 From: Tobias Fischer Date: Mon, 9 Nov 2026 16:42:01 +1000 Subject: [PATCH] robostack-bot: build:none on the update-vinca and update-build-timings PRs They touch files outside distros/, so CI would build every distribution, but they change no package directly (the build times only change how jobs are packed). Only the checks run now; a maintainer removes the label, or swaps it for build: labels, to build. testpr reads the labels when its plan job runs, so the label the bot adds right after opening the PR counts for the first run. Co-Authored-By: Claude Opus 5.5 --- README.md | 6 ++++-- tools/maintenance.py | 15 +++++++++++++-- tools/tests/test_build_timings.py | 1 + 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 3e9e04305..7e738a5b4 100644 --- a/README.md +++ b/README.md @@ -147,9 +147,11 @@ waiting for the macOS runners; remove them for a full build before merging. | `update-conda-forge-pinning [... \| all]` | maintainers | Moves the distribution's conda-forge pinning (`conda_forge_pinning_version` / `conda_forge_migrations` in `distro.yaml`, or `shared/pinning/conda_forge.yaml` for distributions that follow it) to the latest version, with the migrations that are done for the distribution's dependencies, and re-renders `conda_build_config.yaml`. Only packages that use a changed pin, and everything depending on them, are rebuilt (per-package build numbers); more than half affected means a full rebuild. The PR lists the rebuilt packages, the migrations used and those waiting for feedstocks, and the dependency check; it is labelled `dependency-conflict` when the pins can't be installed together. Runs daily, one PR per distribution. Its commits carry `[ci skip]`, so the daily update of the PR (a force push) doesn't start a build: to build it, push a commit without the marker (e.g. `git commit --allow-empty -m "Build"`). | | `rebuild ... [... \| all] [--with-dependents]` | maintainers | New builds of ROS packages (dashes or underscores, `ros--` / `ros2-` prefixes accepted) in the given distributions (default: every one that builds them): per-package build numbers in `distros//pkg_additional_info.yaml`, above every released build. `--with-dependents` also rebuilds every package that depends on them (host or run, transitively; vinca's rebuild planner). Opens a PR listing the rebuilt packages. | | `rebuild-dependents` | maintainers | Only as a comment on a pull request: commits the build-number entries the ABI check's comment suggests (its `yaml` blocks per distribution) to the pull request's branch, keeping existing entries' other keys. Pull requests from forks can't be pushed to: the bot replies with the entries to add instead. | -| `update-vinca []` | maintainers | Moves the vinca pin in `pixi.toml` to the newest commit of the pinned repository's branch (`robostack-integration` for Tobias-Fischer/vinca, else its default branch) or of ``, runs `pixi lock`, re-renders the pinning and runs `rs check`. The PR links the comparison and lists the vinca commits. | +| `update-vinca []` | maintainers | Moves the vinca pin in `pixi.toml` to the newest commit of the pinned repository's branch (`robostack-integration` for Tobias-Fischer/vinca, else its default branch) or of ``, runs `pixi lock`, re-renders the pinning and runs `rs check`. The PR links the comparison and lists the vinca commits. Labelled `build:none` (see below). | | `dependency-report [... \| all]` | maintainers | Runs the dependency check (`check-deps`, linux-64) and keeps one issue per distribution, *``: dependency report* (label `dependency-report`), up to date with the conflicts, notes and conda-forge migration status; the issue is closed when nothing conflicts. Runs weekly (Mondays). | -| `update-build-timings` | maintainers | Merges the build times the last week's build-branch runs recorded (`rs build-ci`, kept as each job's artifact) into `shared/build_timings/.json` and opens a PR. The build workflows pack each stage's recipes into jobs by these times. Runs weekly (Mondays). | +| `update-build-timings` | maintainers | Merges the build times the last week's build-branch runs recorded (`rs build-ci`, kept as each job's artifact) into `shared/build_timings/.json` and opens a PR. The build workflows pack each stage's recipes into jobs by these times. Runs weekly (Mondays). Labelled `build:none` (see below). | + +The PRs of `update-vinca` and `update-build-timings` don't change packages directly, but touch files outside `distros/`, which would build every distribution: they are labelled `build:none`, so only the checks run (and nothing is built while a build is under way). To build one, remove the label, or replace it with `build:` labels. There are three ways to trigger a command: - a *Package request* or *robostack-bot command* issue; diff --git a/tools/maintenance.py b/tools/maintenance.py index aa9b3bd3f..ed48dcb33 100644 --- a/tools/maintenance.py +++ b/tools/maintenance.py @@ -50,6 +50,14 @@ ALLOWED_ASSOCIATIONS = {"OWNER", "MEMBER", "COLLABORATOR"} +# The bot's PRs that don't change packages get build:none (only the checks run), so that +# they don't build every distribution (they change files outside distros/) while a +# build is under way; a maintainer removes the label (or adds build:... after +# removing it) to build them. +NO_BUILD_NOTE = ("Labelled `build:none` ({what}): only the checks run. Remove the label to build " + "every distribution, or replace it with `build:` labels to build some.") + + @dataclass class Result: title: str @@ -1046,7 +1054,8 @@ def update_vinca(ref: str | None = None) -> Result: checked = subprocess.run(["pixi", "run", "rs", "check"], cwd=rs.ROOT, capture_output=True, text=True) lines += ["", "`pixi run rs check`: " + ("✅ ok" if checked.returncode == 0 else f"❌ problems:\n\n```\n{tail(checked.stdout + checked.stderr, 40)}\n```")] - return Result(f"Update vinca to {new[:10]}", "\n".join(lines), changed=True) + lines += ["", NO_BUILD_NOTE.format(what="a new vinca regenerates the recipes of every distribution")] + return Result(f"Update vinca to {new[:10]}", "\n".join(lines), changed=True, labels=[rs.NO_BUILD_LABEL]) REPORT_LABEL = "dependency-report" @@ -1172,7 +1181,9 @@ def update_build_timings() -> Result: return Result("Build times are up to date", "No new build times in the last week's build-branch runs.") return Result("Update the build times", f"{count} build times from the last week's build-branch runs, in " + ", ".join(f"`shared/build_timings/{name}`" for name in changed) - + ". `rs gha` packs each stage's recipes into jobs by them.", changed=True) + + ". `rs gha` packs each stage's recipes into jobs by them.\n\n" + + NO_BUILD_NOTE.format(what="the times only change how the build jobs are packed"), + changed=True, labels=[rs.NO_BUILD_LABEL]) def _default_ci_yaml() -> str: diff --git a/tools/tests/test_build_timings.py b/tools/tests/test_build_timings.py index 3ace74f16..9123b933b 100644 --- a/tools/tests/test_build_timings.py +++ b/tools/tests/test_build_timings.py @@ -69,6 +69,7 @@ def collect(): monkeypatch.setattr(build_timings, "collect", collect) result = maintenance.update_build_timings() assert result.changed and "linux-64.json" in result.summary + assert result.labels == ["build:none"] # only the checks: no package changes assert not maintenance.update_build_timings().changed # nothing new: no PR