name: Firmware at GHA on: push: pull_request: schedule: - cron: '0 0 * * *' workflow_dispatch: inputs: lts: description: 'LTS Build' required: false type: boolean jobs: build-firmware: runs-on: ubuntu-latest strategy: # Let all builds finish even if one fails early fail-fast: false matrix: # What boards should we build for? In the 'include' section below, # set up what each of these boards needs to build. # # see also gen_config where we have a similar list for all boards! # see also build-primary-bundle where default/primary bundle is build separately # build-target: [ alphax-2chan, alphax-4chan, alphax-8chan, m74_9, s105, harley81, hellen72, hellen81, hellen88bmw, hellen88bmw_avr, hellen-nb1, hellen-gm-e67, hellenNA8_96, hellenNA6, hellen128, hellen121vag, hellen-honda-k, hellen121nissan, cypress, frankenso_na6, kinetis, mre_f4, mre_f4_no_openblt, mre_f4_debug, mre_f4_recovery, mre_f4_hardware_QC_special_build, mre_f7, prometheus_405, prometheus_469, proteus_f4, proteus_f4_hardware_QC_special_build, proteus_f7, proteus_f7_hardware_QC_special_build, proteus_h7, proteus_legacy, stm32f429_nucleo, stm32f767_nucleo, stm32h743_nucleo, subaru_eg33_f7, f407-discovery, f429-discovery, core8, 48way, atlas, tdg-pdm8, ] include: # Board configurations - build-target: hellen72 folder: config/boards/hellen/hellen72 ini-file: rusefi_hellen72.ini skip-rate: 90 - build-target: hellen81 folder: config/boards/hellen/hellen81 ini-file: rusefi_hellen81.ini skip-rate: 90 - build-target: alphax-2chan folder: config/boards/hellen/alphax-2chan ini-file: rusefi_alphax-2chan.ini skip-rate: 0 - build-target: alphax-4chan folder: config/boards/hellen/alphax-4chan ini-file: rusefi_alphax-4chan.ini - build-target: alphax-8chan folder: config/boards/hellen/alphax-8chan ini-file: rusefi_alphax-8chan.ini - build-target: s105 folder: config/boards/s105 ini-file: rusefi_s105.ini skip-rate: 90 - build-target: m74_9 folder: config/boards/m74_9 ini-file: rusefi_m74_9.ini skip-rate: 0 - build-target: harley81 folder: config/boards/hellen/harley81 ini-file: rusefi_harley81.ini skip-rate: 90 - build-target: hellen88bmw folder: config/boards/hellen/hellen88bmw ini-file: rusefi_hellen88bmw.ini skip-rate: 90 - build-target: hellen88bmw_avr folder: config/boards/hellen/hellen88bmw ini-file: rusefi_hellen88bmw.ini skip-rate: 90 - build-target: hellen-nb1 folder: config/boards/hellen/hellen-nb1 ini-file: rusefi_hellen-nb1.ini skip-rate: 90 - build-target: hellen-gm-e67 folder: config/boards/hellen/hellen-gm-e67 ini-file: rusefi_hellen-gm-e67.ini skip-rate: 90 - build-target: hellenNA8_96 folder: config/boards/hellen/hellenNA8_96 ini-file: rusefi_hellenNA8_96.ini skip-rate: 90 - build-target: hellenNA6 folder: config/boards/hellen/hellen64_miataNA6_94 ini-file: rusefi_hellenNA6.ini skip-rate: 90 - build-target: hellen128 folder: config/boards/hellen/hellen128 ini-file: rusefi_hellen128mercedes.ini skip-rate: 50 - build-target: hellen121vag folder: config/boards/hellen/hellen121vag ini-file: rusefi_hellen121vag.ini skip-rate: 90 - build-target: hellen121nissan folder: config/boards/hellen/hellen121nissan ini-file: rusefi_hellen121nissan.ini - build-target: hellen-honda-k folder: config/boards/hellen/hellen-honda-k ini-file: rusefi_hellen-honda-k.ini - build-target: hellen154hyundai folder: config/boards/hellen/hellen154hyundai ini-file: rusefi_hellen154hyundai.ini skip-rate: 90 - build-target: cypress folder: config/boards/cypress ini-file: rusefi_cypress.ini - build-target: frankenso_na6 folder: config/boards/frankenso ini-file: rusefi_frankenso_na6.ini skip-rate: 90 - build-target: kinetis folder: config/boards/kinetis ini-file: rusefi_kin.ini skip-rate: 0 - build-target: mre_f4 folder: config/boards/microrusefi ini-file: rusefi_mre_f4.ini - build-target: mre_f4_no_openblt folder: config/boards/microrusefi ini-file: rusefi_mre_f4.ini - build-target: mre_f4_debug folder: config/boards/microrusefi ini-file: rusefi_mre_f4.ini skip-rate: 95 - build-target: mre_f4_recovery folder: config/boards/microrusefi ini-file: rusefi_mre_f4.ini skip-rate: 95 - build-target: mre_f4_hardware_QC_special_build folder: config/boards/microrusefi ini-file: rusefi_mre_f4.ini skip-rate: 90 - build-target: mre_f7 folder: config/boards/microrusefi ini-file: rusefi_mre_f7.ini skip-rate: 90 - build-target: prometheus_405 folder: config/boards/prometheus ini-file: rusefi_prometheus_405.ini skip-rate: 90 - build-target: prometheus_469 folder: config/boards/prometheus ini-file: rusefi_prometheus_469.ini skip-rate: 90 - build-target: proteus_f4 folder: config/boards/proteus ini-file: rusefi_proteus_f4.ini - build-target: proteus_f4_hardware_QC_special_build folder: config/boards/proteus ini-file: rusefi_proteus_f4.ini - build-target: proteus_f7 folder: config/boards/proteus ini-file: rusefi_proteus_f7.ini - build-target: proteus_f7_hardware_QC_special_build folder: config/boards/proteus ini-file: rusefi_proteus_f7.ini skip-rate: 90 - build-target: proteus_h7 folder: config/boards/proteus ini-file: rusefi_proteus_h7.ini skip-rate: 90 - build-target: proteus_legacy folder: config/boards/proteus ini-file: rusefi_proteus_f7.ini skip-rate: 90 - build-target: stm32f429_nucleo folder: config/boards/nucleo_f429 ini-file: rusefi_stm32f429_nucleo.ini - build-target: stm32f767_nucleo folder: config/boards/nucleo_f767 ini-file: rusefi_stm32f767_nucleo.ini skip-rate: 95 - build-target: stm32h743_nucleo folder: config/boards/nucleo_h743 ini-file: rusefi_stm32h743_nucleo.ini skip-rate: 95 - build-target: subaru_eg33_f7 folder: config/boards/subaru_eg33 ini-file: rusefi_subaru_eg33_f7.ini skip-rate: 50 - build-target: f407-discovery folder: config/boards/f407-discovery ini-file: rusefi_f407-discovery.ini skip-rate: 0 - build-target: f429-discovery folder: config/boards/f429-discovery ini-file: rusefi_f429-discovery.ini skip-rate: 95 - build-target: core8 folder: config/boards/core8 ini-file: rusefi_core8.ini skip-rate: 95 - build-target: 48way folder: config/boards/48way ini-file: rusefi_48way.ini skip-rate: 95 - build-target: atlas folder: config/boards/atlas ini-file: rusefi_atlas.ini skip-rate: 95 - build-target: tdg-pdm8 folder: config/boards/tdg-pdm8 ini-file: rusefi_tdg-pdm8.ini skip-rate: 95 steps: - name: Check branch name if: ${{ contains(github.ref_name, '.') }} run: echo '::error::Branch names must not contain ".", this breaks firmware autoupdates.' && exit 1 - name: Execution throttle early exit # Don't skip any jobs if this workflow was run manually, # or if the commit contains `only:`, signifying that only one bundle should be built. if: ${{ matrix.skip-rate && github.event_name != 'workflow_dispatch' && github.event_name != 'schedule' || contains(github.event.head_commit.message, 'only:') }} run: | # if the commit message contains `only:`, get the part after the semicolon and check if it matches the build target. read -d ' ' MSG << EOM || true ${{ github.event.head_commit.message }} EOM if echo $MSG | grep "only:"; then if [ "$(echo $MSG | grep -Po '(?<=only:)[^\s]*')" = "${{ matrix.build-target }}" ]; then exit 0 else # if it doesn't match, skip this job. echo "skip=true" >> $GITHUB_ENV exit 0 fi fi if (($(($RANDOM % 100)) < ${{ matrix.skip-rate }})); then echo "skip=true" >> $GITHUB_ENV; fi - name: Set run condition variables run: | if [ "${{github.event_name}}" = "schedule" ]; then echo "full=true" >> $GITHUB_ENV echo "upload=release" >> $GITHUB_ENV echo "date=$(date +'%Y-%m-%d')" >> $GITHUB_ENV elif [ "${{github.event_name}}" = "push" ]\ && [ "${{github.ref}}" = "refs/heads/master" ]\ && [ "${{env.skip}}" != "true" ]\ || [ "${{toJSON(inputs.lts)}}" = "true" ]; then echo "full=true" >> $GITHUB_ENV echo "upload=server" >> $GITHUB_ENV elif [ "${{env.skip}}" != "true" ]; then echo "partial=true" >> $GITHUB_ENV fi - uses: actions/checkout@v3 if: ${{ env.skip != 'true' }} - name: Checkout Submodules if: ${{ env.skip != 'true' }} run: | git submodule update --init --depth=1 firmware/ChibiOS git submodule update --init --depth=1 firmware/ChibiOS-Contrib git submodule update --init --depth=1 firmware/libfirmware git submodule update --init --depth=1 firmware/ext/lua git submodule update --init --depth=1 firmware/ext/uzlib git submodule update --init --depth=1 firmware/ext/openblt git submodule update --init --depth=1 firmware/controllers/lua/luaaa git submodule update --init --depth=1 firmware/controllers/can/wideband_firmware git submodule update --init --depth=1 java_console/luaformatter - uses: actions/setup-java@v3 if: ${{ env.skip != 'true' }} with: distribution: 'zulu' java-version: '8' - name: Install multilib, mingw, sshpass and mtools if: ${{ env.skip != 'true' }} run: | sudo bash misc/actions/add-ubuntu-latest-apt-mirrors.sh sudo apt-get install gcc-multilib g++-multilib g++-mingw-w64 gcc-mingw-w64 sshpass mtools zip dosfstools - name: Generate Live Documentation if: ${{ env.skip != 'true' }} working-directory: ./firmware/ run: ./gen_live_documentation.sh # live_data_ids.h is generated above so order of operations is important here! - name: Generate Enum Strings if: ${{ env.skip != 'true' }} working-directory: ./firmware/ run: ./gen_enum_to_string.sh - name: Generate Configs for build-target if: ${{ env.skip != 'true' }} working-directory: ./firmware/ # todo: we have code duplication with gen_config.sh here :( run: | if [ "${{ matrix.build-target }}" = "kinetis" ]; then config/boards/kinetis/config/gen_kinetis_config.sh [ $? -eq 0 ] || { echo "ERROR generating board kinetis kin"; exit 1; } elif [ "${{ matrix.build-target }}" = "cypress" ]; then config/boards/cypress/config/gen_cypress_config.sh [ $? -eq 0 ] || { echo "ERROR generating board cypress cypress"; exit 1; } elif [ "${{ matrix.build-target }}" = "subaru_eg33_f7" ]; then bash config/boards/subaru_eg33/config/gen_subaru_config.sh [ $? -eq 0 ] || { echo "ERROR generating board subaru_eg33 subaru_eg33_f7"; exit 1; } elif [ "${{ matrix.ini-file }}" = "" ]; then echo "ERROR: ${{ matrix.build-target }} is missing ini-file attribute" exit -1 else bash gen_config_board.sh ${{matrix.folder}} ${{matrix.build-target}} ${{matrix.ini-file}} fi # Build machines don't have arm-none-eabi gcc, so let's download it and put it on the path - name: Download & Install GCC if: ${{ env.skip != 'true' }} env: ACTIONS_ALLOW_UNSECURE_COMMANDS: 'true' run: | ./firmware/provide_gcc.sh echo "::add-path::`pwd`/gcc-arm-none-eabi/bin" # Make sure the compiler we just downloaded works - just print out the version - name: Test Compiler if: ${{ env.skip != 'true' }} run: arm-none-eabi-gcc -v - name: Configs Set SSH variables if: ${{ env.full == 'true' && env.upload == 'server' }} env: ACTIONS_ALLOW_UNSECURE_COMMANDS: 'true' run: | echo "::set-env name=RUSEFI_SSH_SERVER::${{secrets.RUSEFI_SSH_SERVER}}"; echo "::set-env name=RUSEFI_SSH_USER::${{secrets.RUSEFI_SSH_USER}}"; echo "::set-env name=RUSEFI_SSH_PASS::${{secrets.RUSEFI_SSH_PASS}}"; # Build rusEFI console - name: Build console if: ${{ env.full == 'true' }} run: bash misc/jenkins/build_java_console.sh # Build the simulator - name: Build simulator if: ${{ env.full == 'true' }} # 'OS="Windows_NT"' allows us to build Windows executable on unix run: OS="Windows_NT" bash misc/jenkins/build_simulator.sh # Build the firmware! - name: Build Firmware if: ${{ env.skip != 'true' }} run: bash misc/jenkins/compile_other_versions/compile.sh ${{matrix.folder}} ${{matrix.build-target}} - name: Package Bundle if: ${{ env.full == 'true' }} run: bash misc/jenkins/compile_other_versions/prepare_bundle.sh ${{matrix.build-target}} "${{matrix.ini-file}}" ${{ github.ref_name }} ${{ toJSON(inputs.lts) }} - name: Fetch tags if: ${{ env.full == 'true' && env.upload == 'release' }} run: git fetch --depth=1 origin +refs/tags/*:refs/tags/* - name: Check if tag exists if: ${{ env.full == 'true' && env.upload == 'release' }} run: git show-ref --tags --verify --quiet -- "refs/tags/v${{ env.date }}" && echo "tagged=false" >> $GITHUB_ENV || echo "tagged=true" >> $GITHUB_ENV - name: Create Release Tag if: ${{ env.full == 'true' && env.upload == 'release' && env.tagged == 'false' }} id: tag uses: mathieudutour/github-tag-action@v6.1 with: github_token: ${{ secrets.ACCESS_TOKEN }} custom_tag: ${{ env.date }} - name: Create Release if: ${{ env.full == 'true' && env.upload == 'release' }} uses: ncipollo/release-action@v1.12.0 with: tag: ${{ env.date }} name: "Nightly ${{ env.date }}" artifacts: "artifacts/rusefi_bundle_*.zip" replacesArtifacts: false token: ${{ secrets.ACCESS_TOKEN }} allowUpdates: true prerelease: true - name: Upload .ini files if: ${{ env.full == 'true' }} working-directory: ./firmware/tunerstudio/generated run: ../upload_ini.sh ${{matrix.ini-file}} ${{ secrets.RUSEFI_ONLINE_FTP_USER }} ${{ secrets.RUSEFI_ONLINE_FTP_PASS }} ${{ secrets.RUSEFI_FTP_SERVER }} - name: Upload build elf if: ${{ env.partial == 'true' }} uses: actions/upload-artifact@v3 with: name: rusefi_${{matrix.build-target}}.elf path: ./firmware/build/rusefi.elf - name: Upload build bin if: ${{ env.partial == 'true' }} uses: actions/upload-artifact@v3 with: name: rusefi_${{matrix.build-target}}.bin path: ./firmware/deliver/rusefi*.bin - name: Upload build hex if: ${{ env.partial == 'true' }} uses: actions/upload-artifact@v3 with: name: rusefi_${{matrix.build-target}}.hex path: ./firmware/deliver/rusefi*.hex - name: Upload build dfu if: ${{ env.partial == 'true' }} uses: actions/upload-artifact@v3 with: name: rusefi_${{matrix.build-target}}.dfu path: ./firmware/deliver/rusefi*.dfu - name: Upload bundle if: ${{ env.full == 'true' }} uses: actions/upload-artifact@v3 with: name: rusefi_bundle_${{matrix.build-target}}.zip path: ./artifacts/rusefi_bundle*.zip - name: Upload autoupdate bundle if: ${{ env.full == 'true' }} uses: actions/upload-artifact@v3 with: name: rusefi_bundle_${{matrix.build-target}}_autoupdate.zip path: ./artifacts/rusefi_bundle_${{matrix.build-target}}_autoupdate.zip