spurce variable #68
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
| 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 |