Skip to content

Commit bd70bf2

Browse files
committed
ci: add SITL container image workflow
Build and publish multi-arch Docker runtime images for PX4 SITL on git tags, matching the px4-dev container pattern. Pipeline: setup -> build-deb (Noble only) -> build-docker -> deploy Images: px4io/px4-sitl-sih and px4io/px4-sitl-gazebo (+ GHCR) Architectures: linux/amd64 + linux/arm64 via native runners Uses runs-on with S3 cache for ccache and apt packages. Reuses the existing build-deb composite action. Signed-off-by: Ramon Roche <mrpollo@gmail.com>
1 parent 1cdabea commit bd70bf2

File tree

1 file changed

+255
-0
lines changed

1 file changed

+255
-0
lines changed
Lines changed: 255 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,255 @@
1+
name: SITL Container Images
2+
3+
on:
4+
push:
5+
tags: ['v*']
6+
pull_request:
7+
paths:
8+
- '.github/workflows/sitl_containers.yml'
9+
- 'Tools/packaging/Dockerfile.*'
10+
- 'Tools/packaging/px4-entrypoint.sh'
11+
- 'cmake/package.cmake'
12+
workflow_dispatch:
13+
inputs:
14+
px4_version:
15+
description: 'Image tag (e.g. v1.17.0)'
16+
required: true
17+
type: string
18+
deploy_to_registry:
19+
description: 'Push images to registry'
20+
required: false
21+
type: boolean
22+
default: false
23+
24+
concurrency:
25+
group: ${{ github.workflow }}-${{ github.ref }}
26+
cancel-in-progress: true
27+
28+
permissions:
29+
contents: read
30+
packages: write
31+
32+
env:
33+
RUNS_IN_DOCKER: true
34+
35+
jobs:
36+
setup:
37+
name: Set Tags and Variables
38+
runs-on: [runs-on,"runner=1cpu-linux-x64","image=ubuntu24-full-x64","run-id=${{ github.run_id }}",extras=s3-cache,spot=false]
39+
outputs:
40+
px4_version: ${{ steps.px4_version.outputs.px4_version }}
41+
should_push: ${{ steps.push_check.outputs.should_push }}
42+
steps:
43+
- uses: runs-on/action@v1
44+
- uses: actions/checkout@v4
45+
with:
46+
fetch-tags: true
47+
submodules: false
48+
fetch-depth: 0
49+
50+
- name: Set PX4 version
51+
id: px4_version
52+
run: |
53+
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
54+
echo "px4_version=${{ github.event.inputs.px4_version }}" >> $GITHUB_OUTPUT
55+
else
56+
echo "px4_version=$(git describe --tags --match 'v[0-9]*')" >> $GITHUB_OUTPUT
57+
fi
58+
59+
- name: Check if we should push
60+
id: push_check
61+
run: |
62+
if [[ "${{ startsWith(github.ref, 'refs/tags/') }}" == "true" ]] || \
63+
[[ "${{ github.event_name }}" == "workflow_dispatch" && "${{ github.event.inputs.deploy_to_registry }}" == "true" ]]; then
64+
echo "should_push=true" >> $GITHUB_OUTPUT
65+
else
66+
echo "should_push=false" >> $GITHUB_OUTPUT
67+
fi
68+
69+
build-deb:
70+
name: "Build .deb (${{ matrix.target }}/${{ matrix.arch }})"
71+
needs: setup
72+
runs-on: [runs-on,"runner=4cpu-linux-${{ matrix.runner }}","image=ubuntu24-full-${{ matrix.runner }}","run-id=${{ github.run_id }}",extras=s3-cache,spot=false]
73+
container:
74+
image: ubuntu:24.04
75+
volumes:
76+
- /github/workspace:/github/workspace
77+
strategy:
78+
fail-fast: false
79+
matrix:
80+
include:
81+
- { target: sih, arch: amd64, runner: x64, setup_flags: "--no-sim-tools" }
82+
- { target: sih, arch: arm64, runner: arm64, setup_flags: "--no-sim-tools" }
83+
- { target: default, arch: amd64, runner: x64, setup_flags: "" }
84+
- { target: default, arch: arm64, runner: arm64, setup_flags: "" }
85+
steps:
86+
- name: Fix git in container
87+
run: |
88+
apt-get update && apt-get install -y git
89+
git config --global --add safe.directory $(realpath .)
90+
91+
- uses: actions/checkout@v4
92+
with:
93+
fetch-depth: 0
94+
fetch-tags: true
95+
96+
- name: Cache apt packages
97+
uses: actions/cache@v4
98+
with:
99+
path: /var/cache/apt/archives
100+
key: apt-${{ matrix.target }}-${{ matrix.arch }}-${{ hashFiles('Tools/setup/ubuntu.sh') }}
101+
restore-keys: apt-${{ matrix.target }}-${{ matrix.arch }}-
102+
103+
- name: Install dependencies
104+
run: ./Tools/setup/ubuntu.sh --no-nuttx ${{ matrix.setup_flags }}
105+
106+
- name: Build and package .deb
107+
uses: ./.github/actions/build-deb
108+
with:
109+
target: ${{ matrix.target }}
110+
artifact-name: sitl-deb-${{ matrix.target }}-${{ matrix.arch }}
111+
ccache-key-prefix: sitl-docker-ccache-${{ matrix.target }}-${{ matrix.arch }}
112+
113+
build-docker:
114+
name: "Build Image (${{ matrix.image }}/${{ matrix.arch }})"
115+
needs: [setup, build-deb]
116+
runs-on: [runs-on,"runner=4cpu-linux-${{ matrix.runner }}","image=ubuntu24-full-${{ matrix.runner }}","run-id=${{ github.run_id }}",extras=s3-cache,spot=false]
117+
strategy:
118+
fail-fast: false
119+
matrix:
120+
include:
121+
- { image: sih, target: sih, arch: amd64, runner: x64, platform: "linux/amd64", dockerfile: Dockerfile.sih }
122+
- { image: sih, target: sih, arch: arm64, runner: arm64, platform: "linux/arm64", dockerfile: Dockerfile.sih }
123+
- { image: gazebo, target: default, arch: amd64, runner: x64, platform: "linux/amd64", dockerfile: Dockerfile.gazebo }
124+
- { image: gazebo, target: default, arch: arm64, runner: arm64, platform: "linux/arm64", dockerfile: Dockerfile.gazebo }
125+
steps:
126+
- uses: runs-on/action@v1
127+
- uses: actions/checkout@v4
128+
with:
129+
submodules: false
130+
fetch-depth: 1
131+
132+
- name: Download .deb artifact
133+
uses: actions/download-artifact@v4
134+
with:
135+
name: sitl-deb-${{ matrix.target }}-${{ matrix.arch }}
136+
path: docker-context
137+
138+
- name: Prepare build context
139+
run: |
140+
cp Tools/packaging/px4-entrypoint.sh docker-context/
141+
ls -lh docker-context/
142+
143+
- name: Login to Docker Hub
144+
uses: docker/login-action@v3
145+
if: needs.setup.outputs.should_push == 'true'
146+
with:
147+
username: ${{ secrets.DOCKERHUB_USERNAME }}
148+
password: ${{ secrets.DOCKERHUB_TOKEN }}
149+
150+
- name: Login to GitHub Container Registry
151+
uses: docker/login-action@v3
152+
if: needs.setup.outputs.should_push == 'true'
153+
with:
154+
registry: ghcr.io
155+
username: ${{ github.actor }}
156+
password: ${{ secrets.GITHUB_TOKEN }}
157+
158+
- name: Set up Docker Buildx
159+
uses: docker/setup-buildx-action@v3
160+
with:
161+
driver: docker-container
162+
platforms: ${{ matrix.platform }}
163+
164+
- name: Cache apt packages for Docker build
165+
uses: actions/cache@v4
166+
id: apt-cache
167+
with:
168+
path: /tmp/apt-cache
169+
key: docker-apt-${{ matrix.image }}-${{ matrix.arch }}-${{ hashFiles(format('Tools/packaging/{0}', matrix.dockerfile)) }}
170+
restore-keys: docker-apt-${{ matrix.image }}-${{ matrix.arch }}-
171+
172+
- name: Inject apt cache into Docker build
173+
if: matrix.image == 'gazebo'
174+
run: |
175+
mkdir -p /tmp/apt-cache
176+
# Mount apt cache as a build arg directory if it exists
177+
if [ -d /tmp/apt-cache ] && [ "$(ls -A /tmp/apt-cache 2>/dev/null)" ]; then
178+
echo "APT_CACHE_AVAILABLE=true" >> $GITHUB_ENV
179+
fi
180+
181+
- name: Build and push container image
182+
uses: docker/build-push-action@v6
183+
with:
184+
context: docker-context
185+
file: Tools/packaging/${{ matrix.dockerfile }}
186+
tags: |
187+
px4io/px4-sitl-${{ matrix.image }}:${{ needs.setup.outputs.px4_version }}-${{ matrix.arch }}
188+
ghcr.io/px4/px4-sitl-${{ matrix.image }}:${{ needs.setup.outputs.px4_version }}-${{ matrix.arch }}
189+
platforms: ${{ matrix.platform }}
190+
load: false
191+
push: ${{ needs.setup.outputs.should_push == 'true' }}
192+
provenance: false
193+
cache-from: type=gha,scope=sitl-${{ matrix.image }}-${{ matrix.arch }}
194+
cache-to: type=gha,mode=max,scope=sitl-${{ matrix.image }}-${{ matrix.arch }}
195+
196+
deploy:
197+
name: Create Multi-Arch Manifests
198+
needs: [setup, build-docker]
199+
if: needs.setup.outputs.should_push == 'true'
200+
runs-on: [runs-on,"runner=1cpu-linux-x64","image=ubuntu24-full-x64","run-id=${{ github.run_id }}",extras=s3-cache,spot=false]
201+
strategy:
202+
matrix:
203+
image: [sih, gazebo]
204+
steps:
205+
- uses: runs-on/action@v1
206+
207+
- name: Login to Docker Hub
208+
uses: docker/login-action@v3
209+
with:
210+
username: ${{ secrets.DOCKERHUB_USERNAME }}
211+
password: ${{ secrets.DOCKERHUB_TOKEN }}
212+
213+
- name: Login to GitHub Container Registry
214+
uses: docker/login-action@v3
215+
with:
216+
registry: ghcr.io
217+
username: ${{ github.actor }}
218+
password: ${{ secrets.GITHUB_TOKEN }}
219+
220+
- name: Verify per-arch images exist
221+
run: |
222+
for registry in px4io ghcr.io/px4; do
223+
for arch in amd64 arm64; do
224+
docker manifest inspect ${registry}/px4-sitl-${{ matrix.image }}:${{ needs.setup.outputs.px4_version }}-${arch} \
225+
|| echo "Warning: ${registry}/px4-sitl-${{ matrix.image }}:${{ needs.setup.outputs.px4_version }}-${arch} not found"
226+
done
227+
done
228+
229+
- name: Create and push multi-arch manifest (Docker Hub)
230+
run: |
231+
VERSION="${{ needs.setup.outputs.px4_version }}"
232+
IMAGE="px4io/px4-sitl-${{ matrix.image }}"
233+
234+
docker manifest create ${IMAGE}:${VERSION} \
235+
--amend ${IMAGE}:${VERSION}-arm64 \
236+
--amend ${IMAGE}:${VERSION}-amd64
237+
238+
docker manifest annotate ${IMAGE}:${VERSION} ${IMAGE}:${VERSION}-arm64 --arch arm64
239+
docker manifest annotate ${IMAGE}:${VERSION} ${IMAGE}:${VERSION}-amd64 --arch amd64
240+
241+
docker manifest push ${IMAGE}:${VERSION}
242+
243+
- name: Create and push multi-arch manifest (GHCR)
244+
run: |
245+
VERSION="${{ needs.setup.outputs.px4_version }}"
246+
IMAGE="ghcr.io/px4/px4-sitl-${{ matrix.image }}"
247+
248+
docker manifest create ${IMAGE}:${VERSION} \
249+
--amend ${IMAGE}:${VERSION}-arm64 \
250+
--amend ${IMAGE}:${VERSION}-amd64
251+
252+
docker manifest annotate ${IMAGE}:${VERSION} ${IMAGE}:${VERSION}-arm64 --arch arm64
253+
docker manifest annotate ${IMAGE}:${VERSION} ${IMAGE}:${VERSION}-amd64 --arch amd64
254+
255+
docker manifest push ${IMAGE}:${VERSION}

0 commit comments

Comments
 (0)