name: Custom Firmware Build on: workflow_dispatch: inputs: target: description: 'Target board (e.g. rak4631)' required: true type: string flags: description: 'Build flags (e.g. -DMESHTASTIC_EXCLUDE_MQTT)' required: false type: string version: description: 'Firmware Version (Tag/Branch)' required: true build_id: description: 'Convex Build ID' required: true type: string build_hash: description: 'Build hash for artifact naming' required: true type: string convex_url: description: 'Convex Site URL' required: true type: string jobs: build: runs-on: ubuntu-latest steps: - name: Log - Build Started run: | curl -X POST "${{ inputs.convex_url }}/api/logs" \ -H "Content-Type: application/json" \ -d '{"buildId": "${{ inputs.build_id }}", "logs": "🚀 Build started for ${{ inputs.target }}\n"}' - name: Checkout Web Flasher (this repo) uses: actions/checkout@v4 - name: Log - Checked out web flasher run: | curl -X POST "${{ inputs.convex_url }}/api/logs" \ -H "Content-Type: application/json" \ -d '{"buildId": "${{ inputs.build_id }}", "logs": "✓ Checked out web flasher repo\n"}' - name: Checkout Firmware uses: actions/checkout@v4 with: repository: meshtastic/firmware ref: ${{ inputs.version }} path: firmware submodules: recursive fetch-depth: 1 - name: Log - Checked out firmware run: | curl -X POST "${{ inputs.convex_url }}/api/logs" \ -H "Content-Type: application/json" \ -d '{"buildId": "${{ inputs.build_id }}", "logs": "✓ Checked out firmware ${{ inputs.version }}\n"}' - name: Cache PlatformIO uses: actions/cache@v4 with: path: | ~/.platformio firmware/.pio/libdeps key: ${{ runner.os }}-pio-${{ hashFiles('firmware/platformio.ini') }} restore-keys: | ${{ runner.os }}-pio- - name: Set up Python uses: actions/setup-python@v4 with: python-version: '3.x' - name: Log - Installing PlatformIO run: | curl -X POST "${{ inputs.convex_url }}/api/logs" \ -H "Content-Type: application/json" \ -d '{"buildId": "${{ inputs.build_id }}", "logs": "📦 Installing PlatformIO...\n"}' - name: Install PlatformIO run: | python -m pip install --upgrade pip pip install platformio - name: Log - Building firmware run: | curl -X POST "${{ inputs.convex_url }}/api/logs" \ -H "Content-Type: application/json" \ -d '{"buildId": "${{ inputs.build_id }}", "logs": "🔨 Building firmware for ${{ inputs.target }}...\n"}' - name: Build Firmware working-directory: firmware run: | echo "Building for target: ${{ inputs.target }}" echo "Flags: ${{ inputs.flags }}" # Inject flags into platformio.ini or environment export PLATFORMIO_BUILD_FLAGS="${{ inputs.flags }}" echo "PLATFORMIO_BUILD_FLAGS set to: $PLATFORMIO_BUILD_FLAGS" pio run -e ${{ inputs.target }} - name: Log - Build complete if: success() run: | curl -X POST "${{ inputs.convex_url }}/api/logs" \ -H "Content-Type: application/json" \ -d '{"buildId": "${{ inputs.build_id }}", "logs": "✅ Build completed successfully!\n"}' - name: Install AWS CLI (for R2) if: success() run: | pip install awscli - name: Upload to R2 if: success() env: AWS_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }} AWS_ENDPOINT_URL: ${{ secrets.R2_ENDPOINT_URL }} run: | # Determine file extension based on target (most are .bin, some might be .uf2) BUILD_FILE="firmware/.pio/build/${{ inputs.target }}/firmware.bin" if [ ! -f "$BUILD_FILE" ]; then BUILD_FILE="firmware/.pio/build/${{ inputs.target }}/firmware.uf2" fi # Upload to R2 with hash as filename aws s3 cp "$BUILD_FILE" "s3://${{ secrets.R2_BUCKET_NAME }}/${{ inputs.build_hash }}.uf2" \ --endpoint-url "$AWS_ENDPOINT_URL" echo "✅ Uploaded to R2: ${{ inputs.build_hash }}.uf2" - name: Log - Artifact uploaded to R2 if: success() run: | curl -X POST "${{ inputs.convex_url }}/api/logs" \ -H "Content-Type: application/json" \ -d '{"buildId": "${{ inputs.build_id }}", "logs": "📤 Artifact uploaded to R2: ${{ inputs.build_hash }}.uf2\n"}' - name: Log - Build failed if: failure() run: | curl -X POST "${{ inputs.convex_url }}/api/logs" \ -H "Content-Type: application/json" \ -d '{"buildId": "${{ inputs.build_id }}", "logs": "❌ Build failed - check GitHub Actions logs for details\n"}' - name: Update Build Status if: always() run: | STATUS="${{ job.status }}" if [ "$STATUS" = "success" ]; then STATUS_MSG="success" else STATUS_MSG="failure" fi curl -X POST "${{ inputs.convex_url }}/github-webhook" \ -H "Content-Type: application/json" \ -d "{\"action\": \"completed\", \"build_id\": \"${{ inputs.build_id }}\", \"status\": \"$STATUS_MSG\"}"