/
Sangak
/
inav
Обзор
Документация
Войти
/
Sangak
/
inav
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
.github/workflows/ci.yml
382 строки
16 KB
Ray Morris
CI: build only the affected target for single-target PRs
22 мар 2026, 22:19
22 мар 2026, 22:19
4b9137c
Код
Авторство
О чём код?
name: Build firmware # Don't enable CI on push, just on PR. If you # are working on the main repo and want to trigger # a CI build submit a draft PR. on: push: branches: - '!maintenance-8.x.x' pull_request: paths: - 'src/**' - '.github/**' - 'cmake/**' - 'lib/**' - 'docs/Settings.md' - 'CMakeLists.txt' - '*.sh' workflow_call: #inputs: # release_build: # description: 'Specifies if it is a build that should include commit hash in hex file names or not' # default: false # required: false # type: boolean jobs: detect: runs-on: ubuntu-latest outputs: single_target: ${{ steps.check.outputs.single_target }} target_names: ${{ steps.check.outputs.target_names }} steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Detect single-target PR id: check run: | if [ "${{ github.event_name }}" != "pull_request" ]; then echo "single_target=false" >> $GITHUB_OUTPUT exit 0 fi CHANGED=$(git diff --name-only origin/${{ github.base_ref }}...HEAD) if [ -z "$CHANGED" ]; then echo "single_target=false" >> $GITHUB_OUTPUT exit 0 fi # Fail fast if any changed file is outside src/main/target/<dir>/ NON_TARGET=$(echo "$CHANGED" | grep -Ev '^src/main/target/[^/]+/.+' | head -1) if [ -n "$NON_TARGET" ]; then echo "Non-target file changed: $NON_TARGET — full build required" echo "single_target=false" >> $GITHUB_OUTPUT exit 0 fi # Count how many distinct target directories were touched TARGET_DIRS=$(echo "$CHANGED" | sed -n 's|^src/main/target/\([^/]*\)/.*|\1|p' | sort -u) DIR_COUNT=$(echo "$TARGET_DIRS" | wc -l) if [ "$DIR_COUNT" != "1" ]; then echo "$DIR_COUNT target directories changed — full build required" echo "single_target=false" >> $GITHUB_OUTPUT exit 0 fi TARGET_DIR="$TARGET_DIRS" CMAKE="src/main/target/${TARGET_DIR}/CMakeLists.txt" if [ ! -f "$CMAKE" ]; then echo "No CMakeLists.txt for $TARGET_DIR — full build required" echo "single_target=false" >> $GITHUB_OUTPUT exit 0 fi TARGET_NAMES=$(grep -oP '(?<=\()[^)]+' "$CMAKE" | tr '\n' ' ' | xargs) if [ -z "$TARGET_NAMES" ]; then echo "No target names in CMakeLists.txt — full build required" echo "single_target=false" >> $GITHUB_OUTPUT exit 0 fi echo "Single-target PR: building $TARGET_NAMES" echo "single_target=true" >> $GITHUB_OUTPUT echo "target_names=$TARGET_NAMES" >> $GITHUB_OUTPUT build: needs: [detect] if: needs.detect.outputs.single_target != 'true' runs-on: ubuntu-latest strategy: matrix: id: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] steps: - uses: actions/checkout@v4 - name: Install dependencies run: sudo apt-get update && sudo apt-get -y install ninja-build - name: Setup environment env: ACTIONS_ALLOW_UNSECURE_COMMANDS: true run: | # This is the hash of the commit for the PR # when the action is triggered by PR, empty otherwise COMMIT_ID=${{ github.event.pull_request.head.sha }} # This is the hash of the commit when triggered by push # but the hash of refs/pull/<n>/merge, which is different # from the hash of the latest commit in the PR, that's # why we try github.event.pull_request.head.sha first COMMIT_ID=${COMMIT_ID:-${{ github.sha }}} BUILD_SUFFIX=ci-$(date '+%Y%m%d')-$(git rev-parse --short ${COMMIT_ID}) VERSION=$(grep project CMakeLists.txt|awk -F VERSION '{ gsub(/[ \t)]/, "", $2); print $2 }') echo "BUILD_SUFFIX=${BUILD_SUFFIX}" >> $GITHUB_ENV echo "BUILD_NAME=inav-${VERSION}-${BUILD_SUFFIX}" >> $GITHUB_ENV echo "NUM_CORES=$(grep processor /proc/cpuinfo | wc -l)" >> $GITHUB_ENV - uses: actions/cache@v4 with: path: downloads key: ${{ runner.os }}-downloads-${{ hashFiles('CMakeLists.txt') }}-${{ hashFiles('**/cmake/*')}} - name: Build targets (${{ matrix.id }}) run: mkdir -p build && cd build && cmake -DWARNINGS_AS_ERRORS=ON -DCI_JOB_INDEX=${{ matrix.id }} -DCI_JOB_COUNT=${{ strategy.job-total }} -DBUILD_SUFFIX=${{ env.BUILD_SUFFIX }} -DMAIN_COMPILE_OPTIONS=-pipe -G Ninja .. && ninja -j${{ env.NUM_CORES }} ci - name: Upload artifacts uses: actions/upload-artifact@v4 with: name: matrix-${{ env.BUILD_NAME }}.${{ matrix.id }} path: ./build/*.hex retention-days: 1 build-single-target: needs: [detect] if: needs.detect.outputs.single_target == 'true' runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Install dependencies run: sudo apt-get update && sudo apt-get -y install ninja-build - name: Setup environment env: ACTIONS_ALLOW_UNSECURE_COMMANDS: true run: | COMMIT_ID=${{ github.event.pull_request.head.sha }} COMMIT_ID=${COMMIT_ID:-${{ github.sha }}} BUILD_SUFFIX=ci-$(date '+%Y%m%d')-$(git rev-parse --short ${COMMIT_ID}) VERSION=$(grep project CMakeLists.txt|awk -F VERSION '{ gsub(/[ \t)]/, "", $2); print $2 }') echo "BUILD_SUFFIX=${BUILD_SUFFIX}" >> $GITHUB_ENV echo "BUILD_NAME=inav-${VERSION}-${BUILD_SUFFIX}" >> $GITHUB_ENV echo "NUM_CORES=$(grep processor /proc/cpuinfo | wc -l)" >> $GITHUB_ENV - uses: actions/cache@v4 with: path: downloads key: ${{ runner.os }}-downloads-${{ hashFiles('CMakeLists.txt') }}-${{ hashFiles('**/cmake/*')}} - name: Build targets (${{ needs.detect.outputs.target_names }}) run: mkdir -p build && cd build && cmake -DWARNINGS_AS_ERRORS=ON -DBUILD_SUFFIX=${{ env.BUILD_SUFFIX }} -DMAIN_COMPILE_OPTIONS=-pipe -G Ninja .. && ninja -j${{ env.NUM_CORES }} ${{ needs.detect.outputs.target_names }} - name: Upload artifacts uses: actions/upload-artifact@v4 with: name: matrix-${{ env.BUILD_NAME }}.single path: ./build/*.hex retention-days: 1 upload-artifacts: runs-on: ubuntu-latest needs: [build, build-single-target] if: always() && !cancelled() && (needs.build.result == 'success' || needs.build-single-target.result == 'success') steps: - uses: actions/checkout@v4 - name: Setup environment env: ACTIONS_ALLOW_UNSECURE_COMMANDS: true run: | # This is the hash of the commit for the PR # when the action is triggered by PR, empty otherwise COMMIT_ID=${{ github.event.pull_request.head.sha }} # This is the hash of the commit when triggered by push # but the hash of refs/pull/<n>/merge, which is different # from the hash of the latest commit in the PR, that's # why we try github.event.pull_request.head.sha first COMMIT_ID=${COMMIT_ID:-${{ github.sha }}} BUILD_SUFFIX=ci-$(date '+%Y%m%d')-$(git rev-parse --short ${COMMIT_ID}) VERSION=$(grep project CMakeLists.txt|awk -F VERSION '{ gsub(/[ \t)]/, "", $2); print $2 }') echo "BUILD_SUFFIX=${BUILD_SUFFIX}" >> $GITHUB_ENV echo "BUILD_NAME=inav-${VERSION}-${BUILD_SUFFIX}" >> $GITHUB_ENV echo "NUM_CORES=$(grep processor /proc/cpuinfo | wc -l)" >> $GITHUB_ENV - name: Download artifacts uses: actions/download-artifact@v4 with: pattern: matrix-inav-* merge-multiple: true path: binaries - name: Build target list run: | ls -1 binaries/*.hex | cut -d/ -f2 > targets.txt - name: Upload firmware images uses: actions/upload-artifact@v4 with: name: ${{ env.BUILD_NAME }} path: binaries/*.hex - name: Upload firmware images uses: actions/upload-artifact@v4 with: name: targets path: targets.txt - name: Save PR number if: github.event_name == 'pull_request' run: echo "${{ github.event.pull_request.number }}" > pr_number.txt - name: Upload PR number if: github.event_name == 'pull_request' uses: actions/upload-artifact@v4 with: name: pr-number path: pr_number.txt retention-days: 1 build-SITL-Linux-arm64: runs-on: ubuntu-22.04-arm steps: - uses: actions/checkout@v4 - name: Install dependencies run: sudo apt-get update && sudo apt-get -y install ninja-build - name: Setup environment env: ACTIONS_ALLOW_UNSECURE_COMMANDS: true run: | # This is the hash of the commit for the PR # when the action is triggered by PR, empty otherwise COMMIT_ID=${{ github.event.pull_request.head.sha }} # This is the hash of the commit when triggered by push # but the hash of refs/pull/<n>/merge, which is different # from the hash of the latest commit in the PR, that's # why we try github.event.pull_request.head.sha first COMMIT_ID=${COMMIT_ID:-${{ github.sha }}} BUILD_SUFFIX=ci-$(date '+%Y%m%d')-$(git rev-parse --short ${COMMIT_ID}) VERSION=$(grep project CMakeLists.txt|awk -F VERSION '{ gsub(/[ \t)]/, "", $2); print $2 }') echo "BUILD_SUFFIX=${BUILD_SUFFIX}" >> $GITHUB_ENV echo "BUILD_NAME=inav-${VERSION}-${BUILD_SUFFIX}" >> $GITHUB_ENV echo "NUM_CORES=$(grep processor /proc/cpuinfo | wc -l)" >> $GITHUB_ENV - name: Build SITL run: mkdir -p build_SITL && cd build_SITL && cmake -DSITL=ON -DWARNINGS_AS_ERRORS=ON -G Ninja .. && ninja -j${{ env.NUM_CORES }} - name: Strip version number run: | for f in build_SITL/*_SITL; do mv $f $(echo $f | sed -e 's/_[0-9]\+\.[0-9]\+\.[0-9]\+//') done - name: Upload artifacts uses: actions/upload-artifact@v4 with: name: ${{ env.BUILD_NAME }}_SITL-Linux-aarch64 path: ./build_SITL/*_SITL build-SITL-Linux: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Install dependencies run: sudo apt-get update && sudo apt-get -y install ninja-build - name: Setup environment env: ACTIONS_ALLOW_UNSECURE_COMMANDS: true run: | # This is the hash of the commit for the PR # when the action is triggered by PR, empty otherwise COMMIT_ID=${{ github.event.pull_request.head.sha }} # This is the hash of the commit when triggered by push # but the hash of refs/pull/<n>/merge, which is different # from the hash of the latest commit in the PR, that's # why we try github.event.pull_request.head.sha first COMMIT_ID=${COMMIT_ID:-${{ github.sha }}} BUILD_SUFFIX=ci-$(date '+%Y%m%d')-$(git rev-parse --short ${COMMIT_ID}) VERSION=$(grep project CMakeLists.txt|awk -F VERSION '{ gsub(/[ \t)]/, "", $2); print $2 }') echo "BUILD_SUFFIX=${BUILD_SUFFIX}" >> $GITHUB_ENV echo "BUILD_NAME=inav-${VERSION}-${BUILD_SUFFIX}" >> $GITHUB_ENV echo "NUM_CORES=$(grep processor /proc/cpuinfo | wc -l)" >> $GITHUB_ENV - name: Build SITL run: mkdir -p build_SITL && cd build_SITL && cmake -DSITL=ON -DWARNINGS_AS_ERRORS=ON -G Ninja .. && ninja -j${{ env.NUM_CORES }} - name: Strip version number run: | for f in build_SITL/*_SITL; do mv $f $(echo $f | sed -e 's/_[0-9]\+\.[0-9]\+\.[0-9]\+//') done - name: Upload artifacts uses: actions/upload-artifact@v4 with: name: ${{ env.BUILD_NAME }}_SITL-Linux path: ./build_SITL/*_SITL build-SITL-Mac: runs-on: macos-latest steps: - uses: actions/checkout@v4 - name: Install dependencies run: | brew install ruby - name: Setup environment env: ACTIONS_ALLOW_UNSECURE_COMMANDS: true run: | # This is the hash of the commit for the PR # when the action is triggered by PR, empty otherwise COMMIT_ID=${{ github.event.pull_request.head.sha }} # This is the hash of the commit when triggered by push # but the hash of refs/pull/<n>/merge, which is different # from the hash of the latest commit in the PR, that's # why we try github.event.pull_request.head.sha first COMMIT_ID=${COMMIT_ID:-${{ github.sha }}} BUILD_SUFFIX=ci-$(date '+%Y%m%d')-$(git rev-parse --short ${COMMIT_ID}) VERSION=$(grep project CMakeLists.txt|awk -F VERSION '{ gsub(/[ \t)]/, "", $2); print $2 }') echo "BUILD_SUFFIX=${BUILD_SUFFIX}" >> $GITHUB_ENV echo "BUILD_NAME=inav-${VERSION}-${BUILD_SUFFIX}" >> $GITHUB_ENV echo "NUM_CORES=$(grep processor /proc/cpuinfo | wc -l)" >> $GITHUB_ENV - name: Build SITL run: | mkdir -p build_SITL && cd build_SITL cmake -DSITL=ON -DWARNINGS_AS_ERRORS=ON -DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" -G Ninja .. ninja -j4 - name: Strip version number run: | for f in build_SITL/*_SITL; do mv -v $f $(echo $f | sed -Ee 's/_[0-9]+\.[0-9]+\.[0-9]+//') done - name: Upload artifacts uses: actions/upload-artifact@v4 with: name: ${{ env.BUILD_NAME }}_SITL-MacOS path: ./build_SITL/*_SITL build-SITL-Windows: runs-on: windows-latest defaults: run: shell: C:\tools\cygwin\bin\bash.exe -o igncr '{0}' steps: - uses: actions/checkout@v4 - name: Setup Cygwin uses: egor-tensin/setup-cygwin@v4 with: packages: cmake ruby ninja gcc-g++ rubygems - name: Setup environment env: ACTIONS_ALLOW_UNSECURE_COMMANDS: true run: | # This is the hash of the commit for the PR # when the action is triggered by PR, empty otherwise COMMIT_ID=${{ github.event.pull_request.head.sha }} # This is the hash of the commit when triggered by push # but the hash of refs/pull/<n>/merge, which is different # from the hash of the latest commit in the PR, that's # why we try github.event.pull_request.head.sha first COMMIT_ID=${COMMIT_ID:-${{ github.sha }}} BUILD_SUFFIX=ci-$(date '+%Y%m%d')-$(git rev-parse --short ${COMMIT_ID}) VERSION=$( grep project CMakeLists.txt|awk -F VERSION '{ gsub(/[ \t)]/, "", $2); print $2 }' ) echo "BUILD_SUFFIX=${BUILD_SUFFIX}" >> $GITHUB_ENV echo "BUILD_NAME=inav-${VERSION}-${BUILD_SUFFIX}" >> $GITHUB_ENV - name: Build SITL run: gem install getoptlong && mkdir -p build_SITL && cd build_SITL && cmake -DSITL=ON -DWARNINGS_AS_ERRORS=ON -G Ninja .. && ninja -j4 - name: Strip version number run: | for f in ./build_SITL/*_SITL.exe; do mv $f $(echo $f | sed -e 's/_[0-9]\+\.[0-9]\+\.[0-9]\+//') done - name: Copy cygwin1.dll run: cp /bin/cygwin1.dll ./build_SITL/ - name: Upload artifacts uses: actions/upload-artifact@v4 with: name: ${{ env.BUILD_NAME }}_SITL-WIN path: | ./build_SITL/*.exe ./build_SITL/cygwin1.dll test: #needs: [build] runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Install dependencies run: sudo apt-get update && sudo apt-get -y install ninja-build - name: Run Tests run: mkdir -p build && cd build && cmake -DTOOLCHAIN=none -G Ninja .. && ninja check