firmware(mini): 3s boot home-hold before entering boot source #55
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI/CD | |
| on: | |
| push: | |
| branches: [ phoenix, main ] | |
| tags: | |
| - 'v*.*.*' | |
| paths: | |
| - 'Controller/**' | |
| - 'mini/**' | |
| - 'app/**' | |
| - 'stewart-core' # shared submodule gitlink — a bump must trigger firmware + SIL | |
| - '.github/workflows/ci.yml' | |
| pull_request: | |
| branches: [ phoenix, main ] | |
| paths: | |
| - 'Controller/**' | |
| - 'mini/**' | |
| - 'app/**' | |
| - 'stewart-core' # shared submodule gitlink — a bump must trigger firmware + SIL | |
| - '.github/workflows/ci.yml' | |
| jobs: | |
| version: | |
| name: Determine Version | |
| runs-on: ubuntu-latest | |
| outputs: | |
| version: ${{ steps.version.outputs.version }} | |
| is_release: ${{ steps.version.outputs.is_release }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Calculate version | |
| id: version | |
| run: | | |
| # Check if this is a tag push | |
| if [[ $GITHUB_REF == refs/tags/* ]]; then | |
| VERSION=${GITHUB_REF#refs/tags/} | |
| IS_RELEASE=true | |
| else | |
| # Auto-increment version based on commit count since last tag | |
| LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "") | |
| if [ -z "$LAST_TAG" ]; then | |
| # No tags exist yet, use total commit count | |
| COMMIT_COUNT=$(git rev-list --count HEAD) | |
| MAJOR=0 | |
| MINOR=1 | |
| PATCH=0 | |
| else | |
| # Count commits since last tag | |
| COMMIT_COUNT=$(git rev-list --count ${LAST_TAG}..HEAD) | |
| # Parse last tag (expecting vMAJOR.MINOR.PATCH) | |
| if [[ $LAST_TAG =~ ^v([0-9]+)\.([0-9]+)\.([0-9]+) ]]; then | |
| MAJOR=${BASH_REMATCH[1]} | |
| MINOR=${BASH_REMATCH[2]} | |
| PATCH=${BASH_REMATCH[3]} | |
| else | |
| MAJOR=0 | |
| MINOR=1 | |
| PATCH=0 | |
| fi | |
| fi | |
| # Auto-increment patch version | |
| NEW_PATCH=$((PATCH + 1)) | |
| VERSION="v${MAJOR}.${MINOR}.${NEW_PATCH}-dev.${COMMIT_COUNT}+${GITHUB_SHA:0:7}" | |
| IS_RELEASE=false | |
| fi | |
| echo "version=$VERSION" >> $GITHUB_OUTPUT | |
| echo "is_release=$IS_RELEASE" >> $GITHUB_OUTPUT | |
| echo "Calculated version: $VERSION (Release: $IS_RELEASE)" | |
| firmware-build: | |
| name: Build ESP32-S3 Firmware (ESP-IDF) | |
| needs: version | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| submodules: 'recursive' | |
| - name: Install ESP-IDF prerequisites | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y git wget flex bison gperf python3 python3-pip python3-venv \ | |
| cmake ninja-build ccache libffi-dev libssl-dev dfu-util libusb-1.0-0 | |
| - name: Set up ESP-IDF and Build | |
| uses: espressif/esp-idf-ci-action@v1 | |
| with: | |
| esp_idf_version: v5.5.2 | |
| target: esp32s3 | |
| path: 'Controller' | |
| command: idf.py build | |
| - name: Package firmware with version | |
| run: | | |
| VERSION="${{ needs.version.outputs.version }}" | |
| cp Controller/build/stewart_platform.bin "firmware-${VERSION}.bin" | |
| cp Controller/build/stewart_platform.elf "firmware-${VERSION}.elf" | |
| cp Controller/build/bootloader/bootloader.bin "bootloader-${VERSION}.bin" | |
| cp Controller/build/partition_table/partition-table.bin "partition-table-${VERSION}.bin" | |
| - name: Upload firmware artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: firmware-${{ needs.version.outputs.version }} | |
| path: | | |
| firmware-*.bin | |
| firmware-*.elf | |
| bootloader-*.bin | |
| partition-table-*.bin | |
| retention-days: 90 | |
| mini-firmware-build: | |
| name: Build Mini Firmware (ESP-IDF) | |
| needs: version | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| submodules: 'recursive' # root stewart-core supplies the shared math | |
| - name: Install ESP-IDF prerequisites | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y git wget flex bison gperf python3 python3-pip python3-venv \ | |
| cmake ninja-build ccache libffi-dev libssl-dev dfu-util libusb-1.0-0 | |
| - name: Set up ESP-IDF and Build | |
| uses: espressif/esp-idf-ci-action@v1 | |
| with: | |
| esp_idf_version: v5.5.2 | |
| target: esp32 | |
| path: 'mini' | |
| command: idf.py build | |
| - name: Package mini firmware with version | |
| run: | | |
| VERSION="${{ needs.version.outputs.version }}" | |
| cp mini/build/mini_6dof.bin "mini-firmware-${VERSION}.bin" | |
| cp mini/build/mini_6dof.elf "mini-firmware-${VERSION}.elf" | |
| cp mini/build/bootloader/bootloader.bin "mini-bootloader-${VERSION}.bin" | |
| cp mini/build/partition_table/partition-table.bin "mini-partition-table-${VERSION}.bin" | |
| - name: Upload mini firmware artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: mini-firmware-${{ needs.version.outputs.version }} | |
| path: | | |
| mini-firmware-*.bin | |
| mini-firmware-*.elf | |
| mini-bootloader-*.bin | |
| mini-partition-table-*.bin | |
| retention-days: 90 | |
| desktop-app-build: | |
| name: Build Desktop App (CMake) | |
| needs: version | |
| runs-on: windows-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| submodules: 'recursive' | |
| - name: Configure CMake | |
| run: cmake -S app -B app/build -DCMAKE_BUILD_TYPE=Release | |
| - name: Build | |
| run: cmake --build app/build --config Release | |
| - name: Upload desktop app artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: desktop-app-windows-${{ needs.version.outputs.version }} | |
| path: app/build/Release/stewart-platform.exe | |
| retention-days: 90 | |
| create-release: | |
| name: Create GitHub Release | |
| needs: [version, firmware-build, desktop-app-build] | |
| runs-on: ubuntu-latest | |
| if: startsWith(github.ref, 'refs/tags/') | |
| permissions: | |
| contents: write | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Download firmware artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: firmware-${{ needs.version.outputs.version }} | |
| - name: Download desktop app artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: desktop-app-windows-${{ needs.version.outputs.version }} | |
| continue-on-error: true | |
| - name: Generate changelog | |
| id: changelog | |
| run: | | |
| VERSION="${{ needs.version.outputs.version }}" | |
| IS_RELEASE="${{ needs.version.outputs.is_release }}" | |
| LAST_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "") | |
| if [ -n "$LAST_TAG" ]; then | |
| CHANGELOG=$(git log ${LAST_TAG}..HEAD --pretty=format:"- %s (%h)" --no-merges) | |
| else | |
| CHANGELOG=$(git log --pretty=format:"- %s (%h)" --no-merges -n 20) | |
| fi | |
| # Determine release type messaging | |
| if [ "$IS_RELEASE" = "true" ]; then | |
| RELEASE_TYPE="## 🎯 Official Release" | |
| RELEASE_WARNING="" | |
| else | |
| RELEASE_TYPE="## 🚧 Development Build (Pre-Release)" | |
| RELEASE_WARNING=" | |
| **⚠️ NOT AN OFFICIAL RELEASE** | |
| This is an automated development build from commit ${GITHUB_SHA:0:7}. | |
| - Use for testing and development only | |
| - May contain unstable or incomplete features | |
| - Official releases use version tags without '-dev' suffix | |
| " | |
| fi | |
| # Write changelog to file | |
| cat > CHANGELOG.txt <<EOF | |
| # $VERSION | |
| $RELEASE_TYPE | |
| $RELEASE_WARNING | |
| ## Changes | |
| $CHANGELOG | |
| ## Firmware Files | |
| - \`firmware-${VERSION}.bin\`: Main application binary | |
| - \`bootloader-${VERSION}.bin\`: ESP32-S3 bootloader | |
| - \`partition-table-${VERSION}.bin\`: Partition table | |
| - \`firmware-${VERSION}.elf\`: Debug symbols for GDB | |
| ## Installation | |
| Flash all components to ESP32-S3: | |
| \`\`\`bash | |
| esptool.py --chip esp32s3 --port COM3 --baud 460800 \\ | |
| --before default_reset --after hard_reset write_flash \\ | |
| --flash_mode dio --flash_freq 80m --flash_size 8MB \\ | |
| 0x0 bootloader-${VERSION}.bin \\ | |
| 0x8000 partition-table-${VERSION}.bin \\ | |
| 0x10000 firmware-${VERSION}.bin | |
| \`\`\` | |
| Or use ESP-IDF tooling: | |
| \`\`\`bash | |
| idf.py -p COM3 flash monitor | |
| \`\`\` | |
| ## Safety Notice | |
| ⚠️ This firmware controls a motion platform capable of causing serious injury. Verify E-stop functionality before energizing actuators. See docs/hardware/servo_driver_interface.md for safety checklist. | |
| EOF | |
| echo "changelog<<EOF" >> $GITHUB_OUTPUT | |
| cat CHANGELOG.txt >> $GITHUB_OUTPUT | |
| echo "EOF" >> $GITHUB_OUTPUT | |
| - name: Create Release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: ${{ needs.version.outputs.version }} | |
| name: ${{ needs.version.outputs.is_release == 'true' && format('Release {0}', needs.version.outputs.version) || format('Development Build {0}', needs.version.outputs.version) }} | |
| body: ${{ steps.changelog.outputs.changelog }} | |
| draft: false | |
| prerelease: ${{ needs.version.outputs.is_release != 'true' }} | |
| files: | | |
| firmware-*.bin | |
| firmware-*.elf | |
| bootloader-*.bin | |
| partition-table-*.bin | |
| stewart-platform.exe | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |