Skip to content

fix source venv

fix source venv #79

name: Build and Push Kyon Docker Images
on:
push:
tags:
- 'v[0-9]+.[0-9]+.[0-9]+'
branches:
- master
- main
pull_request:
branches:
- master
- main
env:
DOCKER_REGISTRY: hhcmhub
TAG_NAME: ${{ github.ref_name }}
jobs:
detect-changes:
runs-on: ubuntu-latest
outputs:
ros1: ${{ steps.changes.outputs.ros1 == 'true' || steps.manual-check.outputs.ros1-manual == 'true' }}
ros2: ${{ steps.changes.outputs.ros2 == 'true' || steps.manual-check.outputs.ros2-manual == 'true' }}
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: recursive
- name: Detect changed files
uses: dorny/paths-filter@v3
id: changes
with:
# For submodules, compare against a more reliable base
base: ${{ github.event_name == 'pull_request' && 'HEAD' || github.event.before }}
# Enable submodule tracking explicitly
list-files: shell
filters: |
ros1:
- 'docker-base/robot-template/_build/robot-focal-ros1/**'
ros2:
- 'docker-base/robot-template/_build/robot-noble-ros2/**'
- name: Manual submodule change detection
id: manual-check
run: |
echo "=== Manual Submodule Check ==="
# Initialize outputs
ROS1_CHANGED=false
ROS2_CHANGED=false
# Check if docker-base submodule was updated (we know it was from debug)
if git diff --name-only ${{ github.event.before }}..${{ github.sha }} | grep -q "^docker-base$"; then
echo "✅ docker-base submodule was updated - checking internal changes"
# Get the submodule commit hashes
cd docker-base
# Get the previous submodule commit hash
cd ..
SUBMODULE_BEFORE=$(git rev-parse ${{ github.event.before }}:docker-base)
SUBMODULE_CURRENT=$(git rev-parse HEAD:docker-base)
echo "Submodule before: $SUBMODULE_BEFORE"
echo "Submodule current: $SUBMODULE_CURRENT"
if [[ "$SUBMODULE_BEFORE" != "$SUBMODULE_CURRENT" ]]; then
cd docker-base
# Check what files changed in the submodule between commits
echo "Checking what changed in submodule..."
CHANGED_FILES=$(git diff --name-only $SUBMODULE_BEFORE..$SUBMODULE_CURRENT)
echo "Changed files in submodule:"
echo "$CHANGED_FILES"
# Check for ROS1 changes
if echo "$CHANGED_FILES" | grep -q "robot-template/_build/robot-focal-ros1/"; then
echo "✅ ROS1 files changed in submodule"
ROS1_CHANGED=true
fi
# Check for ROS2 changes
if echo "$CHANGED_FILES" | grep -q "robot-template/_build/robot-noble-ros2/"; then
echo "✅ ROS2 files changed in submodule"
ROS2_CHANGED=true
fi
cd ..
fi
else
echo "❌ No docker-base submodule update detected"
fi
# Output results for use in job conditions
echo "ros1-manual=$ROS1_CHANGED" >> $GITHUB_OUTPUT
echo "ros2-manual=$ROS2_CHANGED" >> $GITHUB_OUTPUT
echo "🎯 Final manual detection - ROS1: $ROS1_CHANGED, ROS2: $ROS2_CHANGED"
- name: Debug submodule and change detection
run: |
echo "=== Git Status ==="
git status
echo ""
echo "=== Submodule Status ==="
git submodule status
echo ""
echo "=== Recent Commits ==="
echo "Last 3 commits:"
git log --oneline -3
echo ""
echo "=== Changed Files Since Base ==="
echo "Base SHA: ${{ github.event.before }}"
echo "Current SHA: ${{ github.sha }}"
if [[ -n "${{ github.event.before }}" ]]; then
echo "Files changed:"
git diff --name-only ${{ github.event.before }}..${{ github.sha }} || echo "No diff available"
echo ""
echo "Submodule changes:"
git diff --name-only ${{ github.event.before }}..${{ github.sha }} | grep docker-base || echo "No docker-base changes detected"
fi
echo ""
echo "=== Check if submodule files exist ==="
ls -la docker-base/robot-template/_build/robot-focal-ros1/ || echo "Path doesn't exist"
build-ros1:
needs: detect-changes
# Build on tags or when ROS1 changes detected
if: |
startsWith(github.ref, 'refs/tags/v') ||
needs.detect-changes.outputs.ros1 == 'true'
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
submodules: recursive
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Docker Hub
if: |
startsWith(github.ref, 'refs/tags/v') ||
github.ref == 'refs/heads/main' ||
github.ref == 'refs/heads/master'
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Setup .netrc for Docker build
run: |
cat > ~/.netrc << EOF
machine github.com
login ${{ secrets.GH_USERNAME }}
password ${{ secrets.GH_TOKEN }}
EOF
chmod 600 ~/.netrc
echo "✅ .netrc file created for Docker build authentication"
- name: Build & push ROS1 images
env:
TAGNAME: ${{ env.TAG_NAME }}
SHOULD_PUSH: ${{ startsWith(github.ref, 'refs/tags/') || github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master' }}
run: |
cd docker
export TAGNAME="${TAGNAME}"
if [[ "${SHOULD_PUSH}" == "true" ]]; then
./build-kyon.bash --ros1 --push
else
./build-kyon.bash --ros1
fi
build-ros2:
needs: detect-changes
# Build on tags or when ROS2 changes detected
if: |
startsWith(github.ref, 'refs/tags/v') ||
needs.detect-changes.outputs.ros2 == 'true'
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
submodules: recursive
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Docker Hub
if: |
startsWith(github.ref, 'refs/tags/v') ||
github.ref == 'refs/heads/main' ||
github.ref == 'refs/heads/master'
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Setup .netrc for Docker build
run: |
cat > ~/.netrc << EOF
machine github.com
login ${{ secrets.GH_USERNAME }}
password ${{ secrets.GH_TOKEN }}
EOF
chmod 600 ~/.netrc
echo "✅ .netrc file created for Docker build authentication"
- name: Build & push ROS2 images
env:
TAGNAME: ${{ env.TAG_NAME }}
SHOULD_PUSH: ${{ startsWith(github.ref, 'refs/tags/') || github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master' }}
run: |
cd docker
export TAGNAME="${TAGNAME}"
if [[ "${SHOULD_PUSH}" == "true" ]]; then
./build-kyon.bash --ros2 --push
else
./build-kyon.bash --ros2
fi
summary:
needs: [detect-changes, build-ros1, build-ros2]
if: always()
runs-on: ubuntu-latest
steps:
- name: Build Summary
run: |
echo "## Build and Push Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
# Display the trigger information
echo "### Trigger Information" >> $GITHUB_STEP_SUMMARY
echo "**Branch/Tag:** ${{ env.TAG_NAME }}" >> $GITHUB_STEP_SUMMARY
echo "**Event:** ${{ github.event_name }}" >> $GITHUB_STEP_SUMMARY
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
echo "**PR:** #${{ github.event.pull_request.number }}" >> $GITHUB_STEP_SUMMARY
fi
echo "" >> $GITHUB_STEP_SUMMARY
# Track what actually happened
ROS1_BUILT=false
ROS2_BUILT=false
ANYTHING_BUILT=false
PUSH_ATTEMPTED=false
# Display detected changes
echo "### Changes Detected" >> $GITHUB_STEP_SUMMARY
if [[ "${{ needs.detect-changes.outputs.ros1 }}" == "true" ]]; then
echo "- ✅ ROS1 files changed" >> $GITHUB_STEP_SUMMARY
else
echo "- ⚪ No ROS1 changes" >> $GITHUB_STEP_SUMMARY
fi
if [[ "${{ needs.detect-changes.outputs.ros2 }}" == "true" ]]; then
echo "- ✅ ROS2 files changed" >> $GITHUB_STEP_SUMMARY
else
echo "- ⚪ No ROS2 changes" >> $GITHUB_STEP_SUMMARY
fi
echo "" >> $GITHUB_STEP_SUMMARY
# Build Results section
echo "### Build Results" >> $GITHUB_STEP_SUMMARY
# ROS1 Build Status
if [[ "${{ needs.build-ros1.result }}" == "success" ]]; then
echo "- ✅ **ROS1**: All images built successfully" >> $GITHUB_STEP_SUMMARY
ROS1_BUILT=true
ANYTHING_BUILT=true
elif [[ "${{ needs.build-ros1.result }}" == "failure" ]]; then
echo "- ❌ **ROS1**: Build failed (check logs)" >> $GITHUB_STEP_SUMMARY
elif [[ "${{ needs.build-ros1.result }}" == "skipped" ]]; then
# Check if it was skipped due to no changes or due to tag trigger
if [[ "${{ github.ref }}" == refs/tags/* ]]; then
echo "- ⚪ **ROS1**: Skipped (tag trigger but no ROS1 changes)" >> $GITHUB_STEP_SUMMARY
else
echo "- ⚪ **ROS1**: Skipped (no changes detected)" >> $GITHUB_STEP_SUMMARY
fi
fi
# ROS2 Build Status
if [[ "${{ needs.build-ros2.result }}" == "success" ]]; then
echo "- ✅ **ROS2**: All images built successfully" >> $GITHUB_STEP_SUMMARY
ROS2_BUILT=true
ANYTHING_BUILT=true
elif [[ "${{ needs.build-ros2.result }}" == "failure" ]]; then
echo "- ❌ **ROS2**: Build failed (check logs)" >> $GITHUB_STEP_SUMMARY
elif [[ "${{ needs.build-ros2.result }}" == "skipped" ]]; then
if [[ "${{ github.ref }}" == refs/tags/* ]]; then
echo "- ⚪ **ROS2**: Skipped (tag trigger but no ROS2 changes)" >> $GITHUB_STEP_SUMMARY
else
echo "- ⚪ **ROS2**: Skipped (no changes detected)" >> $GITHUB_STEP_SUMMARY
fi
fi
echo "" >> $GITHUB_STEP_SUMMARY
# Push Status section - only show if builds occurred
echo "### Registry Push Status" >> $GITHUB_STEP_SUMMARY
# Determine if push was attempted based on ref and build success
if [[ "$ANYTHING_BUILT" == "true" ]]; then
if [[ "${{ github.ref }}" == refs/tags/* ]] || \
[[ "${{ github.ref }}" == "refs/heads/main" ]] || \
[[ "${{ github.ref }}" == "refs/heads/master" ]]; then
PUSH_ATTEMPTED=true
fi
fi
# Display push status
if [[ "$PUSH_ATTEMPTED" == "true" ]]; then
echo "**Status:** Images pushed to registry" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "Images pushed:" >> $GITHUB_STEP_SUMMARY
if [[ "$ROS1_BUILT" == "true" ]]; then
echo "- ROS1 images → \`${{ env.DOCKER_REGISTRY }}/kyon-cetc-focal-ros1-*:${{ env.TAG_NAME }}\`" >> $GITHUB_STEP_SUMMARY
fi
if [[ "$ROS2_BUILT" == "true" ]]; then
echo "- ROS2 images → \`${{ env.DOCKER_REGISTRY }}/kyon-cetc-noble-ros2-*:${{ env.TAG_NAME }}\`" >> $GITHUB_STEP_SUMMARY
fi
elif [[ "$ANYTHING_BUILT" == "true" ]]; then
echo "**Status:** Images built locally only (not pushed)" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
echo "_Note: Images are not pushed for pull requests_" >> $GITHUB_STEP_SUMMARY
else
echo "_Note: Images are only pushed from main/master branches or tags_" >> $GITHUB_STEP_SUMMARY
fi
else
echo "**Status:** No images built or pushed" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "_No changes detected that require rebuilding images_" >> $GITHUB_STEP_SUMMARY
fi
echo "" >> $GITHUB_STEP_SUMMARY
# Add helpful next steps based on the outcome
echo "### Next Steps" >> $GITHUB_STEP_SUMMARY
if [[ "$ANYTHING_BUILT" == "false" ]]; then
echo "No action needed - no relevant changes detected." >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "If you expected builds to occur, check that your changes are in the monitored paths:" >> $GITHUB_STEP_SUMMARY
echo "- ROS1: \`docker/kyon-config_ros1.env\`, \`docker/kyon-cetc-focal-ros1*/\`, \`gui/ros1/\`" >> $GITHUB_STEP_SUMMARY
echo "- ROS2: \`docker/kyon-config_ros2.env\`, \`docker/kyon-cetc-noble-ros2*/\`, \`gui/ros2/\`" >> $GITHUB_STEP_SUMMARY
elif [[ "$PUSH_ATTEMPTED" == "true" ]]; then
echo "✅ Images have been pushed to the registry and are ready for use." >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "To use these images:" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`bash" >> $GITHUB_STEP_SUMMARY
echo "docker pull ${{ env.DOCKER_REGISTRY }}/kyon-cetc-focal-ros1-base:${{ env.TAG_NAME }}" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
else
echo "Images were built but not pushed. To use them:" >> $GITHUB_STEP_SUMMARY
echo "- Merge this PR to main/master to trigger automatic push" >> $GITHUB_STEP_SUMMARY
echo "- Or create a release tag to push images" >> $GITHUB_STEP_SUMMARY
fi