Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
31f7183
Split upstream and target workspace
christophfroehlich Mar 2, 2026
7e1707b
Add stack build for debian and rhel
christophfroehlich Mar 2, 2026
70302a8
Use working-directory instead of base paths arguments
christophfroehlich Mar 2, 2026
4e57b2f
Add ccache
christophfroehlich Mar 2, 2026
38e708e
Skip mujoco and gz packages
christophfroehlich Mar 2, 2026
b858b59
fix(rhel8): enable powertools before installing ccache
christophfroehlich Mar 2, 2026
f981c87
Don't trigger stack builds if images will change
christophfroehlich Mar 2, 2026
8aad46a
Fix step gate
christophfroehlich Mar 2, 2026
1f5430b
Also skip ros2_control_demo_example_9
christophfroehlich Mar 2, 2026
81dcd64
Checkout repo in job
christophfroehlich Mar 2, 2026
8a7201d
Add concurrency settings
christophfroehlich Mar 2, 2026
85ef4e1
Fix action input parser
christophfroehlich Mar 2, 2026
157ba91
Also skip ros2_control_demos meta package
christophfroehlich Mar 2, 2026
00d9600
Enable caching and dont replace default tags on PRs
christophfroehlich Mar 2, 2026
e9ed293
Fix push event
christophfroehlich Mar 2, 2026
297fa08
Set the labels from the build-push-action instead
christophfroehlich Mar 2, 2026
7bab173
Run stack builds only on pull_requests
christophfroehlich Mar 2, 2026
4df7919
Deactivate provenance and sbom
christophfroehlich Mar 2, 2026
290b21c
Also exlcude ign_ packages
christophfroehlich Mar 2, 2026
86854d8
Cleanup labels in dockerfiles because setting it from the build action
christophfroehlich Mar 3, 2026
15c1b02
Disable cache-from on schedule
christophfroehlich Mar 3, 2026
c24c1ce
Add ign_ros2_control to skip packages
christophfroehlich Mar 3, 2026
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
62 changes: 62 additions & 0 deletions .github/actions/stack-build-gate/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
name: "Stack Build Gate"
description: "Determine whether stack build should be skipped on pull requests based on changed paths."
inputs:
blocked_paths:
description: "Multiline list of paths/globs that should block stack build when changed."
required: true
outputs:
skip_stack_build:
description: "true when stack build should be skipped"
value: ${{ steps.compute.outputs.skip_stack_build }}
runs:
using: "composite"
steps:
# blocked_paths is passed as multiline text from callers. We cannot inject it directly
# into the YAML mapping expected by dorny/paths-filter, so we normalize it here into
# a valid YAML list under the "blocked" filter.
- name: Prepare filters
if: ${{ github.event_name == 'pull_request' }}
id: prepare
shell: bash
run: |
FILTERS="blocked:"
while IFS= read -r raw_line; do
line="${raw_line#${raw_line%%[![:space:]]*}}"
if [[ -z "$line" ]]; then
continue
fi
if [[ "$line" == -* ]]; then
line="${line#-}"
line="${line#${line%%[![:space:]]*}}"
fi
if [[ "$line" =~ ^\'.*\'$ ]]; then
line="${line#\'}"
line="${line%\'}"
elif [[ "$line" =~ ^\".*\"$ ]]; then
line="${line#\"}"
line="${line%\"}"
fi
FILTERS+=$'\n'" - ${line}"
done <<< "${{ inputs.blocked_paths }}"

{
echo "filters<<EOF"
echo "$FILTERS"
echo "EOF"
} >> "$GITHUB_OUTPUT"

- name: Check changed files
if: ${{ github.event_name == 'pull_request' }}
id: filter
uses: dorny/paths-filter@v3
with:
filters: ${{ steps.prepare.outputs.filters }}
- name: Compute gate result
id: compute
shell: bash
run: |
if [[ "${{ github.event_name }}" == "pull_request" && "${{ steps.filter.outputs.blocked }}" == "true" ]]; then
echo "skip_stack_build=true" >> "$GITHUB_OUTPUT"
else
echo "skip_stack_build=false" >> "$GITHUB_OUTPUT"
fi
47 changes: 45 additions & 2 deletions .github/workflows/build_and_publish_debian_docker.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,24 @@ name: Build and publish debian docker images

on:
workflow_dispatch:
push:
branches:
- master
paths:
- '.github/workflows/build_and_publish_debian_docker.yaml'
- 'ros2_debian/**'
pull_request:
paths:
- '.github/workflows/build_and_publish_debian_docker.yaml'
- 'ros2_debian/**'
schedule:
- cron: '0 1 * * MON'

concurrency:
# cancel previous runs of the same workflow, except for pushes on given branches
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ !startsWith(github.ref, 'refs/heads') }}

jobs:
build_images:
runs-on: ubuntu-latest
Expand All @@ -36,17 +47,49 @@ jobs:
steps:
- uses: actions/checkout@v6
- uses: docker/setup-buildx-action@v3
- name: Set image tag
id: image_meta
run: |
tag_suffix=""
if [ "${{ github.event_name }}" = "pull_request" ]; then
tag_suffix="-pr-${{ github.event.pull_request.number }}"
fi
echo "image_tag=${{ matrix.ros_distro }}-debian${tag_suffix}" >> "$GITHUB_OUTPUT"
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/build-push-action@v6
- name: Build and push image
uses: docker/build-push-action@v6
with:
context: ros2_debian
push: true
provenance: false
sbom: false
file: ros2_debian/Dockerfile.${{ matrix.debian_version }}
tags: ghcr.io/${{ github.repository_owner }}/ros:${{ matrix.ros_distro }}-debian
tags: ghcr.io/${{ github.repository_owner }}/ros:${{ steps.image_meta.outputs.image_tag }}
labels: |
org.opencontainers.image.source=https://github.com/ros-controls/ros2_control_ci
org.opencontainers.image.description=${{ matrix.debian_version }} for ros-controls CI
org.opencontainers.image.licenses=Apache-2.0
cache-from: ${{ github.event_name != 'schedule' && format('type=gha,scope=debian-{0}', matrix.ros_distro) || '' }}
cache-to: type=gha,scope=debian-${{ matrix.ros_distro }},mode=max
build-args: |
ROS_DISTRO=${{ matrix.ros_distro }}
SOURCE_PACKAGES=${{ matrix.source_packages }}

stack-build:
if: ${{ github.event_name == 'pull_request' }}
needs: build_images
uses: ./.github/workflows/reusable-debian-build.yml
strategy:
fail-fast: false
matrix:
ROS_DISTRO: [rolling, humble, jazzy, kilted]
with:
ros_distro: ${{ matrix.ROS_DISTRO }}
target_workspace: ros_controls.${{ matrix.ROS_DISTRO }}.repos
skip_packages_regex: '^mujoco_ros2_control.*$|^gz_ros2_control.*$|^ros2_control_demo_example_9$|^ros2_control_demos$|^ign_ros2_control.*$'
ref_for_scheduled_build: master
docker_image_tag_suffix: ${{ format('-pr-{0}', github.event.pull_request.number) }}
47 changes: 45 additions & 2 deletions .github/workflows/build_and_publish_rhel_docker.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,24 @@ name: Build and publish RHEL docker images

on:
workflow_dispatch:
push:
branches:
- master
paths:
- '.github/workflows/build_and_publish_rhel_docker.yaml'
- 'ros2_rhel/**'
pull_request:
paths:
- '.github/workflows/build_and_publish_rhel_docker.yaml'
- 'ros2_rhel/**'
schedule:
- cron: '1 0 * * MON'

concurrency:
# cancel previous runs of the same workflow, except for pushes on given branches
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ !startsWith(github.ref, 'refs/heads') }}

jobs:
build_images:
runs-on: ubuntu-latest
Expand All @@ -35,17 +46,49 @@ jobs:
steps:
- uses: actions/checkout@v6
- uses: docker/setup-buildx-action@v3
- name: Set image tag
id: image_meta
run: |
tag_suffix=""
if [ "${{ github.event_name }}" = "pull_request" ]; then
tag_suffix="-pr-${{ github.event.pull_request.number }}"
fi
echo "image_tag=${{ matrix.ros_distro }}-rhel${tag_suffix}" >> "$GITHUB_OUTPUT"
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/build-push-action@v6
- name: Build and push image
uses: docker/build-push-action@v6
with:
context: ros2_rhel
push: true
provenance: false
sbom: false
file: ros2_rhel/Dockerfile.${{ matrix.rhel_version }}
tags: ghcr.io/${{ github.repository_owner }}/ros:${{ matrix.ros_distro }}-rhel
tags: ghcr.io/${{ github.repository_owner }}/ros:${{ steps.image_meta.outputs.image_tag }}
labels: |
org.opencontainers.image.source=https://github.com/ros-controls/ros2_control_ci
org.opencontainers.image.description=${{ matrix.rhel_version }} for ros-controls CI
org.opencontainers.image.licenses=Apache-2.0
cache-from: ${{ github.event_name != 'schedule' && format('type=gha,scope=rhel-{0}', matrix.ros_distro) || '' }}
cache-to: type=gha,scope=rhel-${{ matrix.ros_distro }},mode=max
build-args: |
ROS_DISTRO=${{ matrix.ros_distro }}
SOURCE_PACKAGES=${{ matrix.source_packages }}

stack-build:
if: ${{ github.event_name == 'pull_request' }}
needs: build_images
uses: ./.github/workflows/reusable-rhel-binary-build.yml
strategy:
fail-fast: false
matrix:
ROS_DISTRO: [rolling, humble, jazzy, kilted]
with:
ros_distro: ${{ matrix.ROS_DISTRO }}
target_workspace: ros_controls.${{ matrix.ROS_DISTRO }}.repos
skip_packages_regex: '^mujoco_ros2_control.*$|^gz_ros2_control.*$|^ros2_control_demo_example_9$|^ros2_control_demos$|^ign_ros2_control.*$'
ref_for_scheduled_build: master
docker_image_tag_suffix: ${{ format('-pr-{0}', github.event.pull_request.number) }}
40 changes: 38 additions & 2 deletions .github/workflows/build_and_publish_ubuntu_docker.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,24 @@ name: Build and publish Ubuntu docker images

on:
workflow_dispatch:
push:
branches:
- master
paths:
- '.github/workflows/build_and_publish_ubuntu_docker.yaml'
- 'ros2_ubuntu/**'
pull_request:
paths:
- '.github/workflows/build_and_publish_ubuntu_docker.yaml'
- 'ros2_ubuntu/**'
schedule:
- cron: '1 2 * * MON'

concurrency:
# cancel previous runs of the same workflow, except for pushes on given branches
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ !startsWith(github.ref, 'refs/heads') }}

jobs:
build_images:
runs-on: ubuntu-latest
Expand Down Expand Up @@ -47,23 +58,45 @@ jobs:
steps:
- uses: actions/checkout@v6
- uses: docker/setup-buildx-action@v3
- name: Set image tag
id: image_meta
run: |
tag_suffix=""
if [ "${{ github.event_name }}" = "pull_request" ]; then
tag_suffix="-pr-${{ github.event.pull_request.number }}"
fi
if [ "${{ matrix.ros-repo-packages }}" = "-testing" ]; then
echo "image_tag=${{ matrix.ros_distro }}-ubuntu-testing${tag_suffix}" >> "$GITHUB_OUTPUT"
else
echo "image_tag=${{ matrix.ros_distro }}-ubuntu${tag_suffix}" >> "$GITHUB_OUTPUT"
fi
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/build-push-action@v6
- name: Build and push image
uses: docker/build-push-action@v6
with:
context: ros2_ubuntu
push: true
provenance: false
sbom: false
file: ros2_ubuntu/Dockerfile
tags: ghcr.io/${{ github.repository_owner }}/ros:${{ matrix.ros_distro }}-ubuntu${{ matrix.ros-repo-packages }}
tags: ghcr.io/${{ github.repository_owner }}/ros:${{ steps.image_meta.outputs.image_tag }}
labels: |
org.opencontainers.image.source=https://github.com/ros-controls/ros2_control_ci
org.opencontainers.image.description=${{ matrix.base_image }} with preinstalled ROS for ros-controls CI
org.opencontainers.image.licenses=Apache-2.0
cache-from: ${{ github.event_name != 'schedule' && format('type=gha,scope=ubuntu-{0}{1}', matrix.ros_distro, matrix.ros-repo-packages) || '' }}
cache-to: type=gha,scope=ubuntu-${{ matrix.ros_distro }}${{ matrix.ros-repo-packages }},mode=max
build-args: |
FROM=${{ matrix.base_image }}
ROS_DISTRO=${{ matrix.ros_distro }}
ROS_REPO_PACKAGES=${{ matrix.ros-repo-packages }}

stack-build:
if: ${{ github.event_name == 'pull_request' }}
needs: build_images
uses: ./.github/workflows/reusable-industrial-ci-with-cache.yml
strategy:
Expand All @@ -76,8 +109,10 @@ jobs:
ros_repo: ${{ matrix.ROS_REPO }}
target_workspace: ros_controls.${{ matrix.ROS_DISTRO }}.repos
ref_for_scheduled_build: master
docker_image_tag_suffix: ${{ format('-pr-{0}', github.event.pull_request.number) }}

compatibility-stack-build:
if: ${{ github.event_name == 'pull_request' }}
needs: build_images
uses: ./.github/workflows/reusable-industrial-ci-with-cache.yml
strategy:
Expand All @@ -90,3 +125,4 @@ jobs:
ros_repo: ${{ matrix.ROS_REPO }}
target_workspace: ros_controls.rolling-on-${{ matrix.ROS_DISTRO }}.repos
ref_for_scheduled_build: master
docker_image_tag_suffix: ${{ format('-pr-{0}', github.event.pull_request.number) }}
43 changes: 43 additions & 0 deletions .github/workflows/cleanup_pr_docker_images.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
name: Cleanup PR-tagged docker images

on:
pull_request:
types: [closed]
workflow_dispatch:
inputs:
pr_number:
description: 'PR number to clean up (required for manual runs)'
required: false
type: string

concurrency:
group: cleanup-pr-images-${{ github.event.pull_request.number || inputs.pr_number || github.run_id }}
cancel-in-progress: false

jobs:
cleanup-pr-images:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Resolve PR number
id: resolve_pr
shell: bash
run: |
PR_NUMBER="${{ github.event.pull_request.number || inputs.pr_number }}"
if [[ -z "$PR_NUMBER" ]]; then
echo "No PR number provided. Set workflow_dispatch input 'pr_number' or run on pull_request.closed."
exit 1
fi
echo "pr_number=$PR_NUMBER" >> "$GITHUB_OUTPUT"
- name: Delete PR-tagged GHCR versions
uses: dataaxiom/ghcr-cleanup-action@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
owner: ${{ github.repository_owner }}
repository: ${{ github.event.repository.name }}
packages: ros
delete-tags: '*-pr-${{ steps.resolve_pr.outputs.pr_number }}'
delete-untagged: false
Loading
Loading