Skip to content

Merge pull request #428 from MissouriMRDT/hotfix/cmake-optimization #446

Merge pull request #428 from MissouriMRDT/hotfix/cmake-optimization

Merge pull request #428 from MissouriMRDT/hotfix/cmake-optimization #446

Workflow file for this run

name: Build and Publish Docker Images
on:
# Run this workflow every time a pull request is opened or updated with the development branch as the base
# and there is a change to the dockerfiles or any of the package build scripts.
pull_request:
branches: ["development"]
paths:
- ".devcontainer/Jammy.dockerfile"
- ".devcontainer/JetPack.dockerfile"
- ".github/workflows/deploy_docker.yml"
- "tools/package-builders/**/*.sh"
# Or, run this workflow every time a push/merge is made to the development branch and there is a change to
# the dockerfiles or any of the package build scripts.
push:
branches: ["development"]
paths:
- ".devcontainer/Jammy.dockerfile"
- ".devcontainer/JetPack.dockerfile"
- ".github/workflows/deploy_docker.yml"
- "tools/package-builders/**/*.sh"
# Or, run this manually from the Actions tab in GitHub. This will run the workflow on the development branch.
workflow_dispatch:
# This workflow has concurrency protection enabled. This means that if the workflow is already running, it will
# wait until the previous run is complete before starting a new run. This is to prevent multiple runs from
# happening at the same time and causing conflicts. If there are more than (2) runs waiting in the queue, the
# workflow will be cancelled. This is to prevent the queue from getting too long and causing delays in the
# workflow. It will not cancel a run that is already in progress.
concurrency:
group: "docker"
cancel-in-progress: false
# This workflow is split into multiple jobs. Each job is run on a different runner. This allows multiple jobs to
# run at the same time. The jobs are run in parallel unless they have a dependency on another job. If a job has
# a dependency on another job, it will wait until the other job is complete before starting.
jobs:
# This job is used to get the current date and time. This is used to tag the docker images. The date and time
# job is run first so that all of the docker images are tagged with the same date and time. And is a dependency
# for the other jobs.
time-and-date:
runs-on: [ubuntu-latest]
timeout-minutes: 360
# This outputs the current date and time to the GitHub output. This is used to tag the docker images.
outputs:
date: ${{ steps.date.outputs.date }}
steps:
# This step is used to get the current date and time. And outputs it to the GitHub output.
- name: Get Current Date and Time
id: date
run: echo "date=$(date +'%Y-%m-%d-%H-%M-%S')" >> $GITHUB_OUTPUT
# This job is used to check if any of the packages for AMD64 need to be rebuilt. If any of the package build
# scripts have been updated, then the packages need to be rebuilt in the next job. This job is run on a self-
# hosted runner because there is not an NVIDIA GPU available on the GitHub runners. It outputs a variable for
# each package that is set to true if the package needs to be rebuilt. This job is only run on pull requests.
check-amd64-packages:
needs: [time-and-date]
runs-on: [self-hosted, linux, X64]
timeout-minutes: 1440
if: github.event_name == 'pull_request'
# This outputs a variable for each package that is set to true if the package needs to be rebuilt. This is
# used to determine if the docker images need to be rebuilt.
outputs:
geolib-amd64: ${{ steps.changes.outputs.geolib-amd64 }}
libdatachannel-amd64: ${{ steps.changes.outputs.libdatachannel-amd64 }}
matplotplusplus-amd64: ${{ steps.changes.outputs.matplotplusplus-amd64 }}
ffmpeg-amd64: ${{ steps.changes.outputs.ffmpeg-amd64 }}
gtest-amd64: ${{ steps.changes.outputs.gtest-amd64 }}
opencv-amd64: ${{ steps.changes.outputs.opencv-amd64 }}
pytorch-amd64: ${{ steps.changes.outputs.pytorch-amd64 }}
abseil-amd64: ${{ steps.changes.outputs.abseil-amd64 }}
tensorflow-amd64: ${{ steps.changes.outputs.tensorflow-amd64 }}
quill-amd64: ${{ steps.changes.outputs.quill-amd64 }}
pcl-amd64: ${{ steps.changes.outputs.pcl-amd64 }}
steps:
- name: Setup Action Environment
if: always()
run: |
cd /opt
if [ ! -d "Autonomy_Software" ]; then git clone -j8 https://github.com/MissouriMRDT/Autonomy_Software.git; fi
# This step is used to checkout the repository. It is needed so that the package build scripts can be
# checked for changes.
- name: Checkout Repository
uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: false
# This step is used to check if any of the package build scripts have been updated. If any of the package
# build scripts have been updated, then the packages need to be rebuilt in the next job. This step outputs
# a variable for each package that is set to true if the package needs to be rebuilt.
- name: Check for Updated Files
id: changes
uses: dorny/paths-filter@v3
with:
filters: |
geolib-amd64:
- 'tools/package-builders/geolib/geolib-amd64-pkg.sh'
libdatachannel-amd64:
- 'tools/package-builders/libdatachannel/libdatachannel-amd64-pkg.sh'
matplotplusplus-amd64:
- 'tools/package-builders/matplotplusplus/matplotplusplus-amd64-pkg.sh'
ffmpeg-amd64:
- 'tools/package-builders/ffmpeg/ffmpeg-amd64-pkg.sh'
gtest-amd64:
- 'tools/package-builders/gtest/gtest-amd64-pkg.sh'
opencv-amd64:
- 'tools/package-builders/opencv/opencv-amd64-pkg.sh'
pytorch-amd64:
- 'tools/package-builders/pytorch/pytorch-amd64-pkg.sh'
abseil-amd64:
- 'tools/package-builders/abseil/abseil-amd64-pkg.sh'
tensorflow-amd64:
- 'tools/package-builders/tensorflow/tensorflow-amd64-pkg.sh'
quill-amd64:
- 'tools/package-builders/quill/quill-amd64-pkg.sh'
pcl-amd64:
- 'tools/package-builders/pcl/pcl-amd64-pkg.sh'
- name: Cleanup Action Environment
if: always()
run: |
cd /opt
rm -rf /opt/Autonomy_Software
# This job is to rebuild the updated AMD64 packages and push them to the package repository. It is run on a
# self-hosted runner because there is not an NVIDIA GPU available on the GitHub runners. It gets the list of
# packages that need to be rebuilt from the previous job. It outputs a variable for each package that is set
# to true if the package was rebuilt. This runs in a development matrix so that each package is rebuilt in a
# separate job. This allows multiple packages to be rebuilt at the same time. This job is only run on pull
# requests.
build-updated-amd64-packages:
needs: [time-and-date, check-amd64-packages]
runs-on: [self-hosted, linux, X64]
timeout-minutes: 1440
environment:
name: docker-packages
url: https://github.com/MissouriMRDT/Autonomy_Packages
if: github.event_name == 'pull_request'
# This strategy is used to run the job for each package that needs to be rebuilt. This allows multiple
# packages to be rebuilt at the same time. The job will fail if any of the packages fail to build. But the
# other packages will continue to build. This is so that the packages can be rebuilt in parallel, if
# there are enough action runners in service. OpenCV and FFmpeg are not included in the matrix because
# they are built in a separate job, due to dependencies.
strategy:
fail-fast: false
matrix:
package:
- geolib
- libdatachannel
- matplotplusplus
- gtest
- pytorch
- abseil
- tensorflow
- quill
- pcl
steps:
- name: Setup Action Environment
if: always()
run: |
cd /opt
if [ ! -d "Autonomy_Software" ]; then git clone -j8 https://github.com/MissouriMRDT/Autonomy_Software.git; fi
# This step is used to checkout the repository. It is needed so that the package build scripts can be
# checked for changes.
- name: Checkout Repository
uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: false
# This step is used to rebuild the updated package. It gets the list of packages that need to be rebuilt
# from the previous job. It runs the package build script for the package that is being built.
- name: Rebuild ${{ matrix.package }} Package
id: rebuild_pkg
if: needs.check-amd64-packages.outputs.${{ matrix.package }}-amd64 == 'true'

Check warning on line 189 in .github/workflows/deploy_docker.yml

View workflow run for this annotation

GitHub Actions / Build and Publish Docker Images

Workflow syntax warning

.github/workflows/deploy_docker.yml (Line: 189, Col: 13): Conditional expression contains literal text outside replacement tokens. This will cause the expression to always evaluate to truthy. Did you mean to put the entire expression inside ${{ }}?
run: |
cd tools/package-builders/${{ matrix.package }}
chmod +x ${{ matrix.package }}-amd64-pkg.sh
./${{ matrix.package }}-amd64-pkg.sh
# This step is used to push the updated package to the package repository. It clones the package
# repository using SSH. It copies the new package into the repository. And then, commits and pushes
# the changes.
- name: Push Packages
if: steps.rebuild_pkg.outputs.rebuilding_pkg == 'true'
run: |
# Find Debian Package
debfile=$(find /tmp/pkg/deb/ -name "*.deb" -type f -print -quit)
# Set up Git configuration
git config --global user.email "mrdt.autonomy@gmail.com"
git config --global user.name "MRDT-Software"
# Set up SSH key
mkdir -p ~/.ssh
echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan github.com >> ~/.ssh/known_hosts
# Clone the destination repository using SSH
git clone git@github.com:MissouriMRDT/Autonomy_Packages.git
cd Autonomy_Packages
# Copy the new AMD64 packages into the repository
mkdir -p ${{ matrix.package }}/amd64/
cp -r /tmp/pkg/deb/*amd64*.deb ${{ matrix.package }}/amd64/
# Set up Git LFS
git lfs install
# Commit and push changes
git lfs track '*.deb'
git add .gitattributes
git add .
git commit -m "Upgrade ${{ matrix.package }} Package for AMD64"
git push origin main
env:
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
# This step is used to remove the package from the temporary directory. It gets the list of packages that
# need to be rebuilt from the previous job. It removes the package from the temporary directory. This is
# done so that the next package can be built without having to worry about the previous package causing
# conflicts.
- name: Remove ${{ matrix.package }} Package
if: steps.rebuild_pkg.outputs.rebuilding_pkg == 'true'
run: rm -rf /tmp/pkg/*
- name: Cleanup Action Environment
if: always()
run: |
cd /opt
rm -rf /opt/Autonomy_Software
build-updated-amd64-ffmpeg-and-opencv-packages:
needs: [time-and-date, check-amd64-packages]
runs-on: [self-hosted, linux, X64]
timeout-minutes: 1440
environment:
name: docker-packages
url: https://github.com/MissouriMRDT/Autonomy_Packages
if: github.event_name == 'pull_request'
steps:
- name: Setup Action Environment
if: always()
run: |
cd /opt
if [ ! -d "Autonomy_Software" ]; then
git clone -j8 https://github.com/MissouriMRDT/Autonomy_Software.git
fi
- name: Checkout Repository
uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: false
# --- Check if FFmpeg rebuild is needed. ---
- name: Check if FFmpeg Rebuild is Needed
id: check_ffmpeg
run: |
SCRIPT_PATH="tools/package-builders/ffmpeg/ffmpeg-amd64-pkg.sh"
# If the script is missing, mark for rebuild.
if [ ! -f "$SCRIPT_PATH" ]; then
echo "FFMPEG_NEEDS_REBUILD=true" >> $GITHUB_ENV
echo "ffmpeg script not found – marking for rebuild."
else
# Use git diff to determine if the build script was changed.
if ! git diff --quiet HEAD~1 "$SCRIPT_PATH"; then
echo "FFMPEG_NEEDS_REBUILD=true" >> $GITHUB_ENV
echo "ffmpeg script has changed – marking for rebuild."
else
# Execute the script with the --check flag.
if ! bash "$SCRIPT_PATH" --check; then
echo "FFMPEG_NEEDS_REBUILD=true" >> $GITHUB_ENV
echo "ffmpeg check failed – marking for rebuild."
else
echo "FFMPEG_NEEDS_REBUILD=false" >> $GITHUB_ENV
echo "ffmpeg check passed – no rebuild needed."
fi
fi
fi
# --- Check if OpenCV rebuild is needed. ---
- name: Check if OpenCV Rebuild is Needed
id: check_opencv
run: |
SCRIPT_PATH="tools/package-builders/opencv/opencv-amd64-pkg.sh"
if [ ! -f "$SCRIPT_PATH" ]; then
echo "OPENCV_NEEDS_REBUILD=true" >> $GITHUB_ENV
echo "opencv script not found – marking for rebuild."
else
if ! git diff --quiet HEAD~1 "$SCRIPT_PATH"; then
echo "OPENCV_NEEDS_REBUILD=true" >> $GITHUB_ENV
echo "opencv script has changed – marking for rebuild."
else
# Execute the script with the --check flag.
if ! bash "$SCRIPT_PATH" --check; then
echo "OPENCV_NEEDS_REBUILD=true" >> $GITHUB_ENV
echo "opencv check failed – marking for rebuild."
else
echo "OPENCV_NEEDS_REBUILD=false" >> $GITHUB_ENV
echo "opencv check passed – no rebuild needed."
fi
fi
fi
# --- Rebuild FFmpeg. (if needed) ---
- name: Rebuild FFmpeg Package
id: rebuild_pkg_ffmpeg
if: env.FFMPEG_NEEDS_REBUILD == 'true'
run: |
cd tools/package-builders/ffmpeg
chmod +x ffmpeg-amd64-pkg.sh
./ffmpeg-amd64-pkg.sh
# Check if build succeeded by verifying the .deb file exists
if ls /tmp/pkg/deb/ffmpeg*amd64*.deb 1> /dev/null 2>&1; then
mkdir -p /tmp/archive-pkg/
cp /tmp/pkg/deb/ffmpeg*amd64*.deb /tmp/archive-pkg
echo "FFMPEG_REBUILT_AMD64=true" >> $GITHUB_ENV
else
echo "Build failed; attempting to download latest..."
./ffmpeg-amd64-pkg.sh --download-latest
if ls /tmp/pkg/deb/ffmpeg*amd64*.deb 1> /dev/null 2>&1; then
mkdir -p /tmp/archive-pkg/
cp /tmp/pkg/deb/ffmpeg*amd64*.deb /tmp/archive-pkg
echo "FFMPEG_REBUILT_AMD64=false" >> $GITHUB_ENV
else
echo "Error: FFmpeg build/download failed. No .deb file found."
exit 1
fi
fi
# --- Rebuild OpenCV ---
# This step uses the opencv rebuild script.
# Note: The script itself checks via a HEAD request whether the package exists and uses the --force flag
# when ffmpeg was rebuilt.
- name: Rebuild OpenCV Package
id: rebuild_pkg_opencv
if: env.FFMPEG_NEEDS_REBUILD == 'true' || env.OPENCV_NEEDS_REBUILD == 'true'
run: |
# If ffmpeg was rebuilt, install the new ffmpeg package first.
if [[ "$FFMPEG_REBUILT_AMD64" == "true" ]]; then
apt remove -y ffmpeg-mrdt || true
apt remove -y ffmpeg || true
apt install -y /tmp/archive-pkg/ffmpeg*amd64*.deb
else
echo "Skipping FFmpeg installation (not rebuilt)."
fi
cd tools/package-builders/opencv
chmod +x opencv-amd64-pkg.sh
# If ffmpeg was rebuilt, force OpenCV rebuild to ensure compatibility.
if [[ "$FFMPEG_REBUILT_AMD64" == "true" ]]; then
echo "FFmpeg was rebuilt. Forcing OpenCV rebuild."
./opencv-amd64-pkg.sh --force
else
echo "Building OpenCV normally."
./opencv-amd64-pkg.sh
fi
# Check for the OpenCV .deb file (you can also capture the script's output via $GITHUB_OUTPUT)
if ls /tmp/pkg/deb/opencv*amd64*.deb 1> /dev/null 2>&1; then
mkdir -p /tmp/archive-pkg/
cp /tmp/pkg/deb/opencv*amd64*.deb /tmp/archive-pkg
echo "OPENCV_REBUILT_AMD64=true" >> $GITHUB_ENV
else
echo "OPENCV_REBUILT_AMD64=false" >> $GITHUB_ENV
echo "No new OpenCV .deb file found, assuming no rebuild was needed."
fi
# --- Push updated packages if any were rebuilt. ---
- name: Push Packages
if: env.FFMPEG_REBUILT_AMD64 == 'true' || env.OPENCV_REBUILT_AMD64 == 'true'
run: |
# Configure Git and SSH
git config --global user.email "mrdt.autonomy@gmail.com"
git config --global user.name "MRDT-Software"
mkdir -p ~/.ssh
echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan github.com >> ~/.ssh/known_hosts
# Clone the package repository
git clone git@github.com:MissouriMRDT/Autonomy_Packages.git
cd Autonomy_Packages
# Copy FFmpeg package if rebuilt
if [[ "$FFMPEG_REBUILT_AMD64" == "true" ]]; then
mkdir -p ffmpeg/amd64/
cp -v /tmp/archive-pkg/ffmpeg*amd64*.deb ffmpeg/amd64/
else
echo "Skipping FFmpeg copy (not rebuilt)."
fi
# Copy OpenCV package if rebuilt
if [[ "$OPENCV_REBUILT_AMD64" == "true" ]]; then
mkdir -p opencv/amd64/
cp -v /tmp/archive-pkg/opencv*amd64*.deb opencv/amd64/
else
echo "Skipping OpenCV copy (not rebuilt)."
fi
# Use Git LFS for .deb files and push changes
git lfs install
git lfs track '*.deb'
git add .gitattributes
git add .
git commit -m "Upgrade FFmpeg and/or OpenCV Package for AMD64"
git push origin main
env:
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
# --- Clean up temporary directories. ---
- name: Remove Package Artifacts
if: always()
run: rm -rf /tmp/pkg/* /tmp/archive-pkg/*
- name: Cleanup Action Environment
if: always()
run: |
cd /opt
rm -rf Autonomy_Software
# This job is used to check if any of the packages for ARM64 need to be rebuilt. If any of the package build
# scripts have been updated, then the packages need to be rebuilt in the next job. This job is run on a self-
# hosted runner because there is not an NVIDIA GPU available on the GitHub runners. It outputs a variable for
# each package that is set to true if the package needs to be rebuilt. This job is only run on pull requests.
check-arm64-packages:
needs: [time-and-date]
runs-on: [self-hosted, linux, ARM64]
timeout-minutes: 1440
if: github.event_name == 'pull_request'
# This outputs a variable for each package that is set to true if the package needs to be rebuilt. This is
# used to determine if the docker images need to be rebuilt.
outputs:
geolib-arm64: ${{ steps.changes.outputs.geolib-arm64 }}
libdatachannel-arm64: ${{ steps.changes.outputs.libdatachannel-arm64 }}
matplotplusplus-arm64: ${{ steps.changes.outputs.matplotplusplus-arm64 }}
ffmpeg-arm64: ${{ steps.changes.outputs.ffmpeg-arm64 }}
gtest-arm64: ${{ steps.changes.outputs.gtest-arm64 }}
opencv-arm64: ${{ steps.changes.outputs.opencv-arm64 }}
pytorch-arm64: ${{ steps.changes.outputs.pytorch-arm64 }}
abseil-arm64: ${{ steps.changes.outputs.abseil-arm64 }}
tensorflow-arm64: ${{ steps.changes.outputs.tensorflow-arm64 }}
quill-arm64: ${{ steps.changes.outputs.quill-arm64 }}
pcl-arm64: ${{ steps.changes.outputs.pcl-arm64 }}
steps:
- name: Setup Action Environment
if: always()
run: |
cd /opt
if [ ! -d "Autonomy_Software" ]; then git clone -j8 https://github.com/MissouriMRDT/Autonomy_Software.git; fi
# This step is used to checkout the repository. It is needed so that the package build scripts can be
# checked for changes.
- name: Checkout Repository
uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: false
# This step is used to check if any of the package build scripts have been updated. If any of the package
# build scripts have been updated, then the packages need to be rebuilt in the next job. This step outputs
# a variable for each package that is set to true if the package needs to be rebuilt.
- name: Check for Updated Files
id: changes
uses: dorny/paths-filter@v3
with:
filters: |
geolib-arm64:
- 'tools/package-builders/geolib/geolib-arm64-pkg.sh'
libdatachannel-arm64:
- 'tools/package-builders/libdatachannel/libdatachannel-arm64-pkg.sh'
matplotplusplus-arm64:
- 'tools/package-builders/matplotplusplus/matplotplusplus-arm64-pkg.sh'
ffmpeg-arm64:
- 'tools/package-builders/ffmpeg/ffmpeg-arm64-pkg.sh'
gtest-arm64:
- 'tools/package-builders/gtest/gtest-arm64-pkg.sh'
opencv-arm64:
- 'tools/package-builders/opencv/opencv-arm64-pkg.sh'
pytorch-arm64:
- 'tools/package-builders/pytorch/pytorch-arm64-pkg.sh'
abseil-arm64:
- 'tools/package-builders/abseil/abseil-arm64-pkg.sh'
tensorflow-arm64:
- 'tools/package-builders/tensorflow/tensorflow-arm64-pkg.sh'
quill-arm64:
- 'tools/package-builders/quill/quill-arm64-pkg.sh'
pcl-arm64:
- 'tools/package-builders/pcl/pcl-arm64-pkg.sh'
- name: Cleanup Action Environment
if: always()
run: |
cd /opt
rm -rf /opt/Autonomy_Software
# This job is to rebuild the updated ARM64 packages and push them to the package repository. It is run on a
# self-hosted runner because there is not an NVIDIA GPU available on the GitHub runners. It gets the list of
# packages that need to be rebuilt from the previous job. It outputs a variable for each package that is set
# to true if the package was rebuilt. This runs in a development matrix so that each package is rebuilt in a
# separate job. This allows multiple packages to be rebuilt at the same time. This job is only run on pull
# requests.
build-updated-arm64-packages:
needs: [time-and-date, check-arm64-packages]
runs-on: [self-hosted, linux, ARM64]
timeout-minutes: 1440
environment:
name: docker-packages
url: https://github.com/MissouriMRDT/Autonomy_Packages
if: github.event_name == 'pull_request'
# This strategy is used to run the job for each package that needs to be rebuilt. This allows multiple
# packages to be rebuilt at the same time. The job will fail if any of the packages fail to build. But the
# other packages will continue to build. This is so that the packages can be rebuilt in parallel. OpenCV
# and FFmpeg are not included in the matrix because they are built in a separate job, due to dependencies.
strategy:
fail-fast: false
matrix:
package:
- geolib
- libdatachannel
- matplotplusplus
- gtest
- pytorch
- abseil
- tensorflow
- quill
- pcl
steps:
- name: Setup Action Environment
if: always()
run: |
cd /opt
if [ ! -d "Autonomy_Software" ]; then git clone -j8 https://github.com/MissouriMRDT/Autonomy_Software.git; fi
# This step is used to checkout the repository. It is needed so that the package build scripts can be
# checked for changes.
- name: Checkout Repository
uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: false
# This step is used to rebuild the updated package. It gets the list of packages that need to be rebuilt
# from the previous job. It runs the package build script for the package that is being built.
- name: Rebuild ${{ matrix.package }} Package
id: rebuild_pkg
if: needs.check-arm64-packages.outputs.${{ matrix.package }}-arm64 == 'true'

Check warning on line 576 in .github/workflows/deploy_docker.yml

View workflow run for this annotation

GitHub Actions / Build and Publish Docker Images

Workflow syntax warning

.github/workflows/deploy_docker.yml (Line: 576, Col: 13): Conditional expression contains literal text outside replacement tokens. This will cause the expression to always evaluate to truthy. Did you mean to put the entire expression inside ${{ }}?
run: |
cd tools/package-builders/${{ matrix.package }}
chmod +x ${{ matrix.package }}-arm64-pkg.sh
./${{ matrix.package }}-arm64-pkg.sh
# This step is used to push the updated package to the package repository. It clones the package
# repository using SSH. It copies the new package into the repository. And then, commits and pushes
# the changes.
- name: Push Packages
if: steps.rebuild_pkg.outputs.rebuilding_pkg == 'true'
run: |
# Find Debian Package
debfile=$(find /tmp/pkg/deb/ -name "*.deb" -type f -print -quit)
# Set up Git configuration
git config --global user.email "mrdt.autonomy@gmail.com"
git config --global user.name "MRDT-Software"
# Set up SSH key
mkdir -p ~/.ssh
echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan github.com >> ~/.ssh/known_hosts
# Clone the destination repository using SSH
git clone git@github.com:MissouriMRDT/Autonomy_Packages.git
cd Autonomy_Packages
# Copy the new ARM64 packages into the repository
mkdir -p ${{ matrix.package }}/arm64/
cp -r /tmp/pkg/deb/*arm64*.deb ${{ matrix.package }}/arm64/
# Set up Git LFS
git lfs install
# Commit and push changes
git lfs track '*.deb'
git add .gitattributes
git add .
git commit -m "Upgrade ${{ matrix.package }} Package for AMD64"
git push origin main
env:
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
# This step is used to remove the package from the temporary directory. It gets the list of packages that
# need to be rebuilt from the previous job. It removes the package from the temporary directory. This is
# done so that the next package can be built without having to worry about the previous package causing
# conflicts.
- name: Remove ${{ matrix.package }} Package
if: steps.rebuild_pkg.outputs.rebuilding_pkg == 'true'
run: rm -rf /tmp/pkg/*
- name: Cleanup Action Environment
if: always()
run: |
cd /opt
rm -rf /opt/Autonomy_Software
build-updated-arm64-ffmpeg-and-opencv-packages:
needs: [time-and-date, check-arm64-packages]
runs-on: [self-hosted, linux, ARM64]
timeout-minutes: 1440
environment:
name: docker-packages
url: https://github.com/MissouriMRDT/Autonomy_Packages
if: github.event_name == 'pull_request'
steps:
- name: Setup Action Environment
if: always()
run: |
cd /opt
if [ ! -d "Autonomy_Software" ]; then
git clone -j8 https://github.com/MissouriMRDT/Autonomy_Software.git
fi
- name: Checkout Repository
uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: false
# --- Check if FFmpeg rebuild is needed for ARM64 ---
- name: Check if FFmpeg Rebuild is Needed
id: check_ffmpeg_arm64
run: |
SCRIPT_PATH="tools/package-builders/ffmpeg/ffmpeg-arm64-pkg.sh"
if [ ! -f "$SCRIPT_PATH" ]; then
echo "FFMPEG_NEEDS_REBUILD_ARM64=true" >> $GITHUB_ENV
echo "ffmpeg-arm64 script not found – marking for rebuild."
else
if ! git diff --quiet HEAD~1 "$SCRIPT_PATH"; then
echo "FFMPEG_NEEDS_REBUILD_ARM64=true" >> $GITHUB_ENV
echo "ffmpeg-arm64 script has changed – marking for rebuild."
else
# Execute the script with the --check flag.
if ! bash "$SCRIPT_PATH" --check; then
echo "FFMPEG_NEEDS_REBUILD_ARM64=true" >> $GITHUB_ENV
echo "ffmpeg-arm64 check failed – marking for rebuild."
else
echo "FFMPEG_NEEDS_REBUILD_ARM64=false" >> $GITHUB_ENV
echo "ffmpeg-arm64 check passed – no rebuild needed."
fi
fi
fi
# --- Check if OpenCV rebuild is needed for ARM64 ---
- name: Check if OpenCV Rebuild is Needed
id: check_opencv_arm64
run: |
SCRIPT_PATH="tools/package-builders/opencv/opencv-arm64-pkg.sh"
if [ ! -f "$SCRIPT_PATH" ]; then
echo "OPENCV_NEEDS_REBUILD_ARM64=true" >> $GITHUB_ENV
echo "opencv-arm64 script not found – marking for rebuild."
else
if ! git diff --quiet HEAD~1 "$SCRIPT_PATH"; then
echo "OPENCV_NEEDS_REBUILD_ARM64=true" >> $GITHUB_ENV
echo "opencv-arm64 script has changed – marking for rebuild."
else
# Execute the script with the --check flag.
if ! bash "$SCRIPT_PATH" --check; then
echo "OPENCV_NEEDS_REBUILD_ARM64=true" >> $GITHUB_ENV
echo "opencv-arm64 check failed – marking for rebuild."
else
echo "OPENCV_NEEDS_REBUILD_ARM64=false" >> $GITHUB_ENV
echo "opencv-arm64 check passed – no rebuild needed."
fi
fi
fi
# --- Rebuild FFmpeg Package for ARM64 ---
- name: Rebuild FFmpeg Package
id: rebuild_pkg_ffmpeg_arm64
if: env.FFMPEG_NEEDS_REBUILD_ARM64 == 'true'
run: |
cd tools/package-builders/ffmpeg
chmod +x ffmpeg-arm64-pkg.sh
./ffmpeg-arm64-pkg.sh
if ls /tmp/pkg/deb/ffmpeg*arm64*.deb 1> /dev/null 2>&1; then
mkdir -p /tmp/archive-pkg/
cp /tmp/pkg/deb/ffmpeg*arm64*.deb /tmp/archive-pkg
echo "FFMPEG_REBUILT_ARM64=true" >> $GITHUB_ENV
else
echo "Build failed; attempting to download latest..."
./ffmpeg-arm64-pkg.sh --download-latest
if ls /tmp/pkg/deb/ffmpeg*arm64*.deb 1> /dev/null 2>&1; then
mkdir -p /tmp/archive-pkg/
cp /tmp/pkg/deb/ffmpeg*arm64*.deb /tmp/archive-pkg
echo "FFMPEG_REBUILT_ARM64=false" >> $GITHUB_ENV
else
echo "Error: FFmpeg ARM64 build/download failed. No .deb file found."
exit 1
fi
fi
# --- Rebuild OpenCV Package for ARM64 ---
- name: Rebuild OpenCV Package
id: rebuild_pkg_opencv_arm64
if: env.FFMPEG_NEEDS_REBUILD_ARM64 == 'true' || env.OPENCV_NEEDS_REBUILD_ARM64 == 'true'
run: |
if [[ "$FFMPEG_REBUILT_ARM64" == "true" ]]; then
apt remove -y ffmpeg-mrdt || true
apt remove -y ffmpeg || true
apt install -y /tmp/archive-pkg/ffmpeg*arm64*.deb
else
echo "Skipping FFmpeg installation (not rebuilt)."
fi
cd tools/package-builders/opencv
chmod +x opencv-arm64-pkg.sh
if [[ "$FFMPEG_REBUILT_ARM64" == "true" ]]; then
echo "FFmpeg was rebuilt. Forcing OpenCV rebuild."
./opencv-arm64-pkg.sh --force
else
echo "Building OpenCV normally."
./opencv-arm64-pkg.sh
fi
if ls /tmp/pkg/deb/opencv*arm64*.deb 1> /dev/null 2>&1; then
mkdir -p /tmp/archive-pkg/
cp /tmp/pkg/deb/opencv*arm64*.deb /tmp/archive-pkg
echo "OPENCV_REBUILT_ARM64=true" >> $GITHUB_ENV
else
echo "OPENCV_REBUILT_ARM64=false" >> $GITHUB_ENV
echo "No new OpenCV ARM64 .deb file found, assuming no rebuild was needed."
fi
# --- Push updated packages for ARM64 ---
- name: Push Packages
if: env.FFMPEG_REBUILT_ARM64 == 'true' || env.OPENCV_REBUILT_ARM64 == 'true'
run: |
git config --global user.email "mrdt.autonomy@gmail.com"
git config --global user.name "MRDT-Software"
mkdir -p ~/.ssh
echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan github.com >> ~/.ssh/known_hosts
git clone git@github.com:MissouriMRDT/Autonomy_Packages.git
cd Autonomy_Packages
if [[ "$FFMPEG_REBUILT_ARM64" == "true" ]]; then
mkdir -p ffmpeg/arm64/
cp -v /tmp/archive-pkg/ffmpeg*arm64*.deb ffmpeg/arm64/
else
echo "Skipping FFmpeg copy (not rebuilt)."
fi
if [[ "$OPENCV_REBUILT_ARM64" == "true" ]]; then
mkdir -p opencv/arm64/
cp -v /tmp/archive-pkg/opencv*arm64*.deb opencv/arm64/
else
echo "Skipping OpenCV copy (not rebuilt)."
fi
git lfs install
git lfs track '*.deb'
git add .gitattributes
git add .
git commit -m "Upgrade FFmpeg and/or OpenCV Package for ARM64"
git push origin main
env:
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
# --- Clean up temporary directories ---
- name: Remove Package Artifacts
if: always()
run: rm -rf /tmp/pkg/* /tmp/archive-pkg/*
- name: Cleanup Action Environment
if: always()
run: |
cd /opt
rm -rf Autonomy_Software
# This job is used to build and push the new jammy docker image. It is run on a self-hosted runner because
# there is not an NVIDIA GPU available on the GitHub runners. If this is being run on a pull request, then
# the image is tagged with the date and time. If this is being run on a push, then the image is tagged with
# the date and time and the latest tag. This job is run on both pushes and pull requests. And is allowed to run
# even if the previous job was skipped. This is because the previous job is only run on pull requests, but this
# job is run on pushes and pull requests.
build-and-push-jammy:
needs:
[
time-and-date,
check-amd64-packages,
build-updated-amd64-packages,
build-updated-amd64-ffmpeg-and-opencv-packages,
]
runs-on: [self-hosted, linux, X64]
timeout-minutes: 1440
if: ${{ always() && !failure() && !cancelled() }}
steps:
- name: Setup Action Environment
if: always()
run: |
cd /opt
if [ ! -d "Autonomy_Software" ]; then git clone -j8 https://github.com/MissouriMRDT/Autonomy_Software.git; fi
# This step is used to checkout the repository. It is needed so that the package build scripts can be
# checked for changes.
- name: Checkout Repository
uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: false
# This step is used to check if any of the package build scripts have been updated. If any of the package
# build scripts have been updated, then the packages need to be rebuilt in the next job. This step outputs
# a variable for each package that is set to true if the package needs to be rebuilt.
- name: Check for Updated Files
id: changes
uses: dorny/paths-filter@v3
with:
filters: |
dockerfile:
- '.devcontainer/Jammy.dockerfile'
- '.github/workflows/deploy_docker.yml'
# This step is used to setup the docker buildx. It is needed to build the docker images.
- name: Setup Docker Buildx
if: steps.changes.outputs.dockerfile == 'true'
id: buildx
uses: docker/setup-buildx-action@v3
# This step is used to login to the GitHub Packages. It is needed to push the docker images.
- name: Login to GitHub Packages
if: steps.changes.outputs.dockerfile == 'true'
id: login
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
# This step is used to build and push the new jammy docker image. It is run on a self-hosted runner because
# there is not an NVIDIA GPU available on the GitHub runners. This step is only run on a pull request or a
# manual run. In either case the image is tagged with the date and time. It also saves a build cache so
# that the next time the image is built, it has the potential to be faster.
- name: Build and Push Jammy Image with Date Tag
if: ${{ ( github.event_name == 'pull_request' || ( github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/development' )) && (steps.changes.outputs.dockerfile == 'true') }}
uses: docker/build-push-action@v5
with:
context: ".devcontainer/"
file: ".devcontainer/Jammy.dockerfile"
tags: |
"ghcr.io/missourimrdt/autonomy-jammy:buildcache"
"ghcr.io/missourimrdt/autonomy-jammy:${{ needs.time-and-date.outputs.date }}"
platforms: "linux/amd64"
push: true
cache-from: type=registry,ref=ghcr.io/missourimrdt/autonomy-jammy:buildcache
cache-to: type=registry,ref=ghcr.io/missourimrdt/autonomy-jammy:buildcache,mode=max
# This step is used to build and push the new jammy docker image. It is run on a self-hosted runner because
# there is not an NVIDIA GPU available on the GitHub runners. This step is only run on a push. In this case
# the image is tagged with the date and time and the latest tag. It also saves a build cache so that the
# next time the image is built, it has the potential to be faster.
- name: Build and Push Jammy Image with Latest Tag
if: ${{ github.event_name == 'push' && (steps.changes.outputs.dockerfile == 'true') }}
uses: docker/build-push-action@v5
with:
context: ".devcontainer/"
file: ".devcontainer/Jammy.dockerfile"
tags: |
"ghcr.io/missourimrdt/autonomy-jammy:buildcache"
"ghcr.io/missourimrdt/autonomy-jammy:${{ needs.time-and-date.outputs.date }}"
"ghcr.io/missourimrdt/autonomy-jammy:latest"
platforms: "linux/amd64"
push: true
cache-from: type=registry,ref=ghcr.io/missourimrdt/autonomy-jammy:buildcache
cache-to: type=registry,ref=ghcr.io/missourimrdt/autonomy-jammy:buildcache,mode=max
- name: Cleanup Action Environment
if: always()
run: |
cd /opt
rm -rf /opt/Autonomy_Software
# This job is used to build and push the new jetpack docker image. It is run on a self-hosted runner because
# there is not an NVIDIA GPU available on the GitHub runners. If this is being run on a pull request, then
# the image is tagged with the date and time. If this is being run on a push, then the image is tagged with
# the date and time and the latest tag. This job is run on both pushes and pull requests. And is allowed to run
# even if the previous job was skipped. This is because the previous job is only run on pull requests, but this
# job is run on pushes and pull requests.
build-and-push-jetpack:
needs:
[
time-and-date,
check-arm64-packages,
build-updated-arm64-packages,
build-updated-arm64-ffmpeg-and-opencv-packages,
]
runs-on: [self-hosted, linux, ARM64]
timeout-minutes: 1440
if: ${{ always() && !failure() && !cancelled() }}
steps:
- name: Setup Action Environment
if: always()
run: |
cd /opt
if [ ! -d "Autonomy_Software" ]; then git clone -j8 https://github.com/MissouriMRDT/Autonomy_Software.git; fi
# This step is used to checkout the repository. It is needed so that the package build scripts can be
# checked for changes.
- name: Checkout Repository
uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: false
# This step is used to check if any of the package build scripts have been updated. If any of the package
# build scripts have been updated, then the packages need to be rebuilt in the next job. This step outputs
# a variable for each package that is set to true if the package needs to be rebuilt.
- name: Check for Updated Files
id: changes
uses: dorny/paths-filter@v3
with:
filters: |
dockerfile:
- '.devcontainer/JetPack.dockerfile'
- '.github/workflows/deploy_docker.yml'
# This step is used to setup the docker buildx. It is needed to build the docker images.
- name: Setup Docker Buildx
if: steps.changes.outputs.dockerfile == 'true'
id: buildx
uses: docker/setup-buildx-action@v3
# This step is used to login to the GitHub Packages. It is needed to push the docker images.
- name: Login to GitHub Packages
if: steps.changes.outputs.dockerfile == 'true'
id: login
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
# This step is used to build and push the new jetpack docker image. It is run on a self-hosted runner
# because there is not an NVIDIA GPU available on the GitHub runners. This step is only run on a pull
# request or a manual run. In either case the image is tagged with the date and time. It also saves a
# build cache so that the next time the image is built, it has the potential to be faster.
- name: Build and Push JetPack Image with Date Tag
if: ${{ ( github.event_name == 'pull_request' || ( github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/development' )) && (steps.changes.outputs.dockerfile == 'true') }}
uses: docker/build-push-action@v5
with:
context: ".devcontainer/"
file: ".devcontainer/JetPack.dockerfile"
tags: |
"ghcr.io/missourimrdt/autonomy-jetpack:buildcache"
"ghcr.io/missourimrdt/autonomy-jetpack:${{ needs.time-and-date.outputs.date }}"
platforms: "linux/arm64"
push: true
cache-from: type=registry,ref=ghcr.io/missourimrdt/autonomy-jetpack:buildcache
cache-to: type=registry,ref=ghcr.io/missourimrdt/autonomy-jetpack:buildcache,mode=max
# This step is used to build and push the new jetpack docker image. It is run on a self-hosted runner
# because there is not an NVIDIA GPU available on the GitHub runners. This step is only run on a push. In
# this case the image is tagged with the date and time and the latest tag. It also saves a build cache so
# that the next time the image is built, it has the potential to be faster.
- name: Build and Push JetPack Image with Latest Tag
if: ${{ github.event_name == 'push' && (steps.changes.outputs.dockerfile == 'true') }}
uses: docker/build-push-action@v5
with:
context: ".devcontainer/"
file: ".devcontainer/JetPack.dockerfile"
tags: |
"ghcr.io/missourimrdt/autonomy-jetpack:buildcache"
"ghcr.io/missourimrdt/autonomy-jetpack:${{ needs.time-and-date.outputs.date }}"
"ghcr.io/missourimrdt/autonomy-jetpack:latest"
platforms: "linux/arm64"
push: true
cache-from: type=registry,ref=ghcr.io/missourimrdt/autonomy-jetpack:buildcache
cache-to: type=registry,ref=ghcr.io/missourimrdt/autonomy-jetpack:buildcache,mode=max
- name: Cleanup Action Environment
if: always()
run: |
cd /opt
rm -rf /opt/Autonomy_Software