Skip to content

Imports: replace distro inputs consistently and use ros2 names - #41

Closed
tdejager wants to merge 36 commits into
RoboStack:mainfrom
tdejager:fix/distro-reimports
Closed

tdejager wants to merge 36 commits into
RoboStack:mainfrom
tdejager:fix/distro-reimports

Conversation

@tdejager

@tdejager tdejager commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

We still need to pull changes from the old distro repositories while moving to this one. Re-importing should mirror the source without leaving a mixture of old and new inputs, or deleting local build work.

Before

The importer updated the destination in place and could leave partial results on failure. Optional files removed upstream could survive a re-import. A destination-name override could also confuse legacy package-name conversion. Shared configuration generated legacy aliases even though the repository policy calls for ros2-* names.

After

The importer validates and stages the source before replacing the destination, and rolls back if replacement fails. It replaces its owned files and the patch directory, including upstream deletions, while preserving unrelated entries such as work/, tests/ and rendered pins. Preserved directories are moved rather than copied, so a large build directory does not get duplicated during import. Modern package lists retain scalar, nested and empty if/then/else branches instead of rejecting valid platform selectors.

Name conversion uses the source distro's identity even when --distro changes the destination. Shared configuration and imported distros use canonical ros2-* names without generating legacy aliases.

The README changes here cover import ownership and canonical naming. The other PRs carry their own build/CI and maintenance documentation. #24 remains separate.

Testing

All 22 import regression tests passed with this PR applied directly to main. They cover working trees and Git refs, repeat imports, optional-file removal, destination overrides, rollback failures, and scalar/nested selectors. An importer command smoke check resolved the retained branches for Linux, macOS and Windows and preserved an existing build artifact.

On the combined fixes, actual generation produced 23 Jazzy/osx-arm64 recipes and 34 Rolling/win-64 recipes, all with ros2-* names. Repository checks passed for all four distros. These are recipe-generation checks, not full ROS builds or a native Windows run.

Closes #30
Closes #34

Independent PR

This PR is based directly on main and can merge independently of #39 (build/CI) and #40 (maintenance). Its tests pass without either of those branches. Git merge checks verified all six merge orders: each combines without conflicts and produces the same intended tree. All 78 regression tests pass when the independent branches are combined.


PR description written by Astra on 2026-10-09. Sol reviewed the importer changes.

Follow-up updated by Astra on 2026-10-09. A separate gpt-6-astra:high agent reviewed all three PRs, found the additional auto-merge queue race in #39, and confirmed its fix. No actionable findings remained; the review was read-only.

Tobias-Fischer and others added 30 commits October 6, 2026 19:10
distros/<distro>/ holds only what is specific to a distribution; shared/ holds
the rosdep mapping, pinning and tests; tools/robostack.py runs every task for a
distribution (pixi run rs <distro> <task>); CI builds only the distributions a PR
touches. Data copied from RoboStack/ros-{rolling,humble,lyrical,kilted} main and
ros-jazzy codex/cross-distro-sync.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ings

shared/vinca.yaml (common settings and the 72 packages every distribution
selects), shared/pkg_additional_info.yaml (36 entries) and
shared/dependencies.yaml (61 entries) hold what all distributions agree on;
distros/<d>/ keeps the rest. tools/robostack.py assembles distros/<d>/work/
from both and runs every task there; skip_existing, conda_index and the
snapshot paths are derived. The full linux-64 recipe sets of rolling, humble
and lyrical are byte-identical before and after.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…anches

- tools/maintenance.py: check (sanity checks, run in CI), update-snapshot and
  find-stale per distribution, update-pinning (shared conda-forge pinning) and
  new-distro; parse-command for @robostack-bot comments and command issues.
- .github/workflows/bot.yml + issue template: weekly snapshot/pinning PRs,
  commands on demand.
- Staged builds: ROBOSTACK_UPLOAD_CHANNEL redirects uploads to a (test)
  prefix.dev channel, 'none' (default outside RoboStack) skips them;
  PUSH_BUILD_BRANCHES enables pushing build branches outside RoboStack.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…round trip); check it

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… work/); refuse the fallback

Without ./.scripts/build_win.bat in its working directory vinca-gha silently
falls back to an outdated built-in Windows script (boa build); found by pushing
a test build branch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Share vinca.yaml, pkg_additional_info.yaml and dependencies.yaml settings
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- tools/maintenance.py add-package PKG... [DISTRO...] [--preview]: adds the
  packages (normalising ros2-/ros-<distro>- names) to the selection of every
  given distribution that has them, in sorted position, in shared/vinca.yaml if
  that's all of them; generates the linux-64 recipes and lists what will be
  built and what is already published as a dependency.
- Package request issue form (anyone): the bot replies with a preview;
  @robostack-bot add-package by a maintainer opens the PR, which closes the issue.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e, import tool

- main.yml pushes the staged build branches whenever the bot app (or GHA_PAT) is
  available, without an organisation check; the build workflows upload to each
  distribution's channel unless ROBOSTACK_UPLOAD_CHANNEL redirects them.
- robostack-bot add-package opens the PR for anyone (valid ROS package names
  only, at most 10 per request); the other commands stay with maintainers.
- tools/import_distro.py moves a distribution here from its own repository
  (re-importing lyrical reproduces distros/lyrical exactly).
- kilted keeps the pins its published packages were built with.
- README for users and maintainers, bug report template with a distribution field.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…resh plotjuggler Windows patch for 3.17.2

- humble: same fix as rolling/lyrical (windows.h min/max macros break
  rclcpp's duration.hpp/time.hpp in influx_component).
- jazzy: the old Windows patch targeted an older plotjuggler (its protobuf
  changes are upstream now); rebased rolling's 3.17.2 Windows patch (Qt link
  libraries, plotjuggler_base exports) onto jazzy's release.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…PI_KEY; don't build tl_expected/sophus under conda-forge names

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ing updates, fix linking the request

- update-rosdistro-snapshot and update-conda-forge-pinning bump build_number and the
  mutex minor version, drop per-package build numbers the new one catches up with, and
  (pinning) move plain mutex run_constraints to the new pins
- commands take several distributions or all; one job per distribution
- issue forms: no pre-filled title, multi-select distributions defaulting to all,
  add-package in the command form (anyone)
- fix the Link the request step (' #' started a YAML comment)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ci_config.py also matches plain (unprefixed) names, for packages vinca built under a
conda-forge name. Reset ci.yaml after merging.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ebuilds and package selection; fold long bot reports

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…brary/autoware_trajectory; distro-specific ros2cli test; drop a cancelled run's last package before caching

- parameter_traits and generate_parameter_library 0.7.6: use conda-forge's tl-expected
  (tl_expected is mapped to cpp-expected); autoware_trajectory takes humble's patch
- ros2cli test: only rolling's and lyrical's patches install a fish completion
- testpr: a cancelled build can package an empty build (seen on Windows); remove the
  newest artifact before saving the cache; evict jazzy's empty rmw_fastrtps_shared_cpp

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…umber from the channel; jazzy/humble/kilted robot_state_publisher test

- pyqt-builder 1.20 (conda-forge, 2026-10-07) defaults to sip ABI 12.20/13.13, which
  needs sip >=6.16; qt_gui_cpp keeps sip <6.16 and failed with a missing sip.h.in
- update-rosdistro-snapshot is no longer scheduled; its bump sets build_number to the
  highest build of the distribution's released packages + 1 and removes all
  per-package build numbers
- robot_state_publisher osx test: CycloneDDS 0.10 (humble, jazzy, kilted) doesn't know
  allow_multicast; use ROS_LOCALHOST_ONLY there as before

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ected patches for autoware_downsample_filters and pick_ik

- update-rosdistro-snapshot snapshots the distribution's latest sync tag in
  ros/rosdistro (e.g. jazzy/2026-10-05) instead of rosdistro master, which includes
  releases that are only in ros-testing; the sync is recorded as rosdistro_sync in
  distro.yaml and the PR links the rosdistro changes and the Discourse announcement
- the bot checks daily for new syncs (rs rosdistro-syncs) and opens or updates one PR
  per distribution; rolling (rosdistro_sync: manual) keeps reading master on request
- vinca from Tobias-Fischer/vinca feat/snapshot-rosdistro-ref (vinca-snapshot
  --rosdistro-ref) until it is merged upstream

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
All matrix jobs on a platform share the cache key, so they raced to save it
("Unable to reserve cache ... another job may be creating this cache").

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…/vinca#161)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…::tl_expected

conda-forge's libroboplan-core 0.7.0 build 3 links the system tl-expected
(open-planning/roboplan#369), so the bundled roboplan::tl_expected target is gone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ted first

Carry open-planning/roboplan-ros#85 for jazzy, lyrical and rolling: conda-forge's
libroboplan-core 0.7.0 build 3 doesn't export roboplan::tl_expected.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…in rolling

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…RoboStack#5)

Ready for RoboStack: production defaults, package requests from anyone, import tool
pixi's task shell re-parsed it, so an apostrophe in a package request broke the
plan step (issue RoboStack#9).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
robostack-bot: pass the request text through the environment
…s2-* names, no kilted) (RoboStack#8)

See RoboStack#8 for the full description.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ect (RoboStack#16)

See RoboStack#16.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Tobias-Fischer and others added 5 commits October 9, 2026 15:06
…oboStack#17)

prefix.dev's Repository Access (OIDC) matches a GitHub workflow by exact file
name. Each build branch only carries its own workflow, so one fixed name lets
a single authorized source cover every distribution and platform. README:
how to set it up, and the canonical <namespace>/<channel> upload reference.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…oboStack#18)

The build workflows pass PREFIX_API_KEY from the (now deleted) secret, so the
variable is set but empty; rattler-build then refuses --generate-attestation
("cannot be used with an API key").

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…oboStack#21)

With ROBOSTACK_UPLOAD_CHANNEL set (the test channel), the packages earlier
stages build are uploaded there, but rattler-build only searched the
distribution's release channel and conda-forge, so later stages failed to
resolve them (e.g. humble's yasmin_editor). Put that channel first; reruns
then also skip what is already uploaded.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…Stack#22)

prefix.dev's sharded repodata, which rattler reads, lists a new upload a few
minutes after repodata.json does. A stage starting right after the previous
one uploaded then fails with "No candidates were found" for a package that
is on the channel (lyrical linux-64, plansys2_pddl_parser). build-ci now
retries that failure twice, 3 minutes apart; other failures aren't retried.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
@tdejager
tdejager force-pushed the fix/distro-reimports branch from 70cde98 to 59b1a4b Compare October 9, 2026 13:28
@Tobias-Fischer

Copy link
Copy Markdown
Collaborator

Thanks! One blocker:

  • package_name_mode: both → new breaks users. vinca only generates the ros-<distro>-<pkg> compatibility packages in both mode (naming.py), so pixi add ros-jazzy-desktop would stop resolving for new builds. They're deliberate, not legacy cruft: AGENTS.md's ros2-* rule is about recipe and patch names. Please revert this, the README line, and the importer forcing new (import_distro.py:226-229); the importer should inherit the shared value.
  • Size: for transitional tooling, ~190 lines of staging and rollback (plus a tomllib parse that is discarded) and ~390 lines of tests are a lot. The real fixes are small:
    • remove stale optional files;
    • use source_distro with --distro;
    • keep if/then selectors;
    • don't delete work/ and tests/.
  • Small regressions: a missing patch/ is now a hard error, and the README's byte-identical "Check:" note is gone.
  • CI: it didn't run on this PR.

🤖 Claude (AI assistant), on behalf of @Tobias-Fischer

Tobias-Fischer added a commit that referenced this pull request Oct 9, 2026
From Tim's PRs (the parts that fix real problems on main):
- automerge goes by the label the PR has now (events can arrive out of order)
  and refuses to turn on without the bot token (a GITHUB_TOKEN merge doesn't
  start the build workflow)
- CI installs with locked: the lock file must match pixi.toml
- one build-branch generation per distribution at a time
- check-patches includes shared/patch (a distribution's patches for a
  package replace the shared ones, like in vinca)
- rs check accepts build_number 0 and an empty migration list; the pinning
  renders `migrations: []`; update-pinning fails when render-pinning does
- import_distro: names follow the source distribution with --distro, files
  the old repository no longer has are removed, ci.yaml is kept

Uploads use prefix.dev trusted publishing only: PREFIX_API_KEY and the
anaconda.org upload (ANACONDA_API_TOKEN, also stripped from the generated
workflows) are gone. Distributions whose channel is still on anaconda.org
are read from there and upload to ROBOSTACK_UPLOAD_CHANNEL.

Co-Authored-By: Tim de Jager <tdejager89@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Tobias-Fischer added a commit that referenced this pull request Oct 9, 2026
From Tim's PRs (the parts that fix real problems on main):
- automerge goes by the label the PR has now (events can arrive out of order)
  and refuses to turn on without the bot token (a GITHUB_TOKEN merge doesn't
  start the build workflow)
- CI installs with locked: the lock file must match pixi.toml
- one build-branch generation per distribution at a time
- check-patches includes shared/patch (a distribution's patches for a
  package replace the shared ones, like in vinca)
- rs check accepts build_number 0 and an empty migration list; the pinning
  renders `migrations: []`; update-pinning fails when render-pinning does
- import_distro: names follow the source distribution with --distro, files
  the old repository no longer has are removed, ci.yaml is kept

Uploads use prefix.dev trusted publishing only: PREFIX_API_KEY and the
anaconda.org upload (ANACONDA_API_TOKEN, also stripped from the generated
workflows) are gone. Distributions whose channel is still on anaconda.org
are read from there and upload to ROBOSTACK_UPLOAD_CHANNEL.

Co-Authored-By: Tim de Jager <tdejager89@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Tobias-Fischer added a commit that referenced this pull request Oct 9, 2026
From Tim's PRs (the parts that fix real problems on main):
- automerge goes by the label the PR has now (events can arrive out of order)
  and refuses to turn on without the bot token (a GITHUB_TOKEN merge doesn't
  start the build workflow)
- CI installs with locked: the lock file must match pixi.toml
- one build-branch generation per distribution at a time
- check-patches includes shared/patch (a distribution's patches for a
  package replace the shared ones, like in vinca)
- rs check accepts build_number 0 and an empty migration list; the pinning
  renders `migrations: []`; update-pinning fails when render-pinning does
- import_distro: names follow the source distribution with --distro, files
  the old repository no longer has are removed, ci.yaml is kept

Uploads use prefix.dev trusted publishing only: PREFIX_API_KEY and the
anaconda.org upload (ANACONDA_API_TOKEN, also stripped from the generated
workflows) are gone. Distributions whose channel is still on anaconda.org
are read from there and upload to ROBOSTACK_UPLOAD_CHANNEL.

Co-Authored-By: Tim de Jager <tdejager89@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Tobias-Fischer

Copy link
Copy Markdown
Collaborator

This was closed automatically when we rewrote main's history into topic commits (GitHub closes PRs whose base history is replaced). The parts we're keeping from #39–#41 are in #46, with you as co-author. The reasons for leaving out the rest are in the review comments above. Thanks for the audit; it found several real bugs!

🤖 Claude (AI assistant), on behalf of @Tobias-Fischer

Tobias-Fischer added a commit that referenced this pull request Oct 10, 2026
From Tim's PRs (the parts that fix real problems on main):
- automerge goes by the label the PR has now (events can arrive out of order)
  and refuses to turn on without the bot token (a GITHUB_TOKEN merge doesn't
  start the build workflow)
- CI installs with locked: the lock file must match pixi.toml
- one build-branch generation per distribution at a time
- check-patches includes shared/patch (a distribution's patches for a
  package replace the shared ones, like in vinca)
- rs check accepts build_number 0 and an empty migration list; the pinning
  renders `migrations: []`; update-pinning fails when render-pinning does
- import_distro: names follow the source distribution with --distro, files
  the old repository no longer has are removed, ci.yaml is kept

Uploads use prefix.dev trusted publishing only: PREFIX_API_KEY and the
anaconda.org upload (ANACONDA_API_TOKEN, also stripped from the generated
workflows) are gone. Distributions whose channel is still on anaconda.org
are read from there and upload to ROBOSTACK_UPLOAD_CHANNEL.

Co-Authored-By: Tim de Jager <tdejager89@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Tobias-Fischer added a commit that referenced this pull request Oct 10, 2026
From Tim's PRs (the parts that fix real problems on main):
- automerge goes by the label the PR has now (events can arrive out of order)
  and refuses to turn on without the bot token (a GITHUB_TOKEN merge doesn't
  start the build workflow)
- CI installs with locked: the lock file must match pixi.toml
- one build-branch generation per distribution at a time
- check-patches includes shared/patch (a distribution's patches for a
  package replace the shared ones, like in vinca)
- rs check accepts build_number 0 and an empty migration list; the pinning
  renders `migrations: []`; update-pinning fails when render-pinning does
- import_distro: names follow the source distribution with --distro, files
  the old repository no longer has are removed, ci.yaml is kept

Uploads use prefix.dev trusted publishing only: PREFIX_API_KEY and the
anaconda.org upload (ANACONDA_API_TOKEN, also stripped from the generated
workflows) are gone. Distributions whose channel is still on anaconda.org
are read from there and upload to ROBOSTACK_UPLOAD_CHANNEL.

Co-authored-by: Tim de Jager <tdejager89@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
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.

Make distro reimports preserve consistency and mirror source deletions Make package naming match the documented new-name cutover

2 participants