Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 18 additions & 4 deletions .github/workflows/integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,27 @@ concurrency:
cancel-in-progress: false

jobs:
gitlink-freshness:
# Gate: every tracked gitlink must be at the tip of its sibling repo's
# default branch, so the workspace pointers can't silently drift behind
# merged work. Uses ls-remote (no sibling checkout needed).
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Check gitlinks are at their default-branch tips
env:
GH_TOKEN: ${{ secrets.SIBLING_CHECKOUT_TOKEN || secrets.GITHUB_TOKEN }}
run: |
git config --global url."https://x-access-token:${GH_TOKEN}@github.com/personalrobotics/".insteadOf "https://github.com/personalrobotics/"
./scripts/check_gitlink_freshness.sh

integration:
runs-on: ubuntu-latest
timeout-minutes: 45
strategy:
fail-fast: false
matrix:
python-version: ["3.10", "3.12"]
python-version: ["3.11", "3.12"]
steps:
- name: Checkout robot-code
uses: actions/checkout@v4
Expand Down Expand Up @@ -74,7 +88,7 @@ jobs:
run: |
set +e
fail=0
for d in asset_manager geodude geodude_assets mj_environment mj_manipulator mj_viser prl_assets pycbirrt tsr; do
for d in ada_assets ada_mj asset_manager geodude geodude_assets mj_environment mj_manipulator mj_viser prl_assets pycbirrt tsr; do
if [ -d "$d/tests" ]; then
echo "::group::$d tests"
(cd "$d" && uv run pytest tests/ -q) || fail=1
Expand All @@ -88,10 +102,10 @@ jobs:

- name: Import smoke check
run: |
uv run python -c "import asset_manager, geodude, geodude_assets, mj_environment, mj_manipulator, mj_viser, prl_assets, pycbirrt, tsr; print('all imports OK')"
uv run python -c "import ada_assets, ada_mj, asset_manager, geodude, geodude_assets, mj_environment, mj_manipulator, mj_viser, prl_assets, pycbirrt, tsr; print('all imports OK')"

notify-on-nightly-failure:
needs: integration
needs: [integration, gitlink-freshness]
if: failure() && github.event_name == 'schedule'
runs-on: ubuntu-latest
permissions:
Expand Down
54 changes: 54 additions & 0 deletions scripts/check_gitlink_freshness.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#!/usr/bin/env bash
# Fail if any tracked gitlink (submodule-style commit pointer) is not at the
# tip of its sibling repo's DEFAULT branch. This is what keeps the workspace
# pointers from silently drifting behind merged work.
#
# It compares the committed gitlink SHA against `git ls-remote <url> HEAD`, the
# remote's default-branch tip -- so it is correct for repos whose default is not
# `main` (e.g. ada_feeding -> ros2-devel) without any per-repo configuration.
#
# No sibling checkout is required (uses ls-remote), so it is cheap to run in CI.
# Sibling URLs are derived by convention: github.com/personalrobotics/<dir>.
#
# Usage: scripts/check_gitlink_freshness.sh
# Exit: 0 = all current; 1 = drift or lookup failure (fail closed).
set -euo pipefail

cd "$(git rev-parse --show-toplevel)"

ORG_URL="https://github.com/personalrobotics"
stale=0
errors=0

printf "%-22s %-12s %-12s %s\n" "GITLINK" "RECORDED" "REMOTE-TIP" "STATUS"
printf -- "%.0s-" {1..64}; printf "\n"

# Each gitlink: mode 160000, "<sha> <path>".
while read -r sha path; do
url="$ORG_URL/$(basename "$path")"
tip="$(git ls-remote "$url" HEAD 2>/dev/null | awk 'NR==1{print $1}')"
if [ -z "$tip" ]; then
printf "%-22s %-12s %-12s %s\n" "$path" "${sha:0:11}" "??" "LOOKUP-FAILED"
errors=1
continue
fi
if [ "$sha" = "$tip" ]; then
printf "%-22s %-12s %-12s %s\n" "$path" "${sha:0:11}" "${tip:0:11}" "ok"
else
printf "%-22s %-12s %-12s %s\n" "$path" "${sha:0:11}" "${tip:0:11}" "STALE"
stale=1
fi
done < <(git ls-tree -r HEAD | awk '$2=="commit"{print $3, $4}')

echo
if [ "$errors" -ne 0 ]; then
echo "ERROR: could not resolve one or more sibling default branches (see LOOKUP-FAILED)."
exit 1
fi
if [ "$stale" -ne 0 ]; then
echo "Gitlinks are behind their default-branch tips. To fix, for each STALE repo:"
echo " (cd <repo> && git fetch origin && git checkout \"\$(git rev-parse origin/HEAD)\")"
echo " git add <repo> && git commit"
exit 1
fi
echo "All gitlinks are at their default-branch tips."
11 changes: 11 additions & 0 deletions setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,18 @@
# the shared Python environment.
set -euo pipefail

# Every sibling repo the workspace tracks. The ADA repos (ada_assets, ada_mj)
# are uv workspace members, so omitting them breaks `uv sync` on a fresh clone;
# the ROS 2 repos (ada_ros2, ada_feeding, articutool_ros2) are not Python
# packages but are part of the workspace. This list must stay in sync with the
# tracked gitlinks — scripts/check_gitlink_freshness.sh gates that they are not
# stale. ada_feeding's default branch is ros2-devel (git clone picks it up).
REPOS=(
"https://github.com/personalrobotics/ada_assets"
"https://github.com/personalrobotics/ada_feeding"
"https://github.com/personalrobotics/ada_mj"
"https://github.com/personalrobotics/ada_ros2"
"https://github.com/personalrobotics/articutool_ros2"
"https://github.com/personalrobotics/asset_manager"
"https://github.com/personalrobotics/geodude"
"https://github.com/personalrobotics/geodude_assets"
Expand Down
Loading