name: Build and Deploy Firmware on: push: branches: - main tags: - 'v*' permissions: contents: write pages: write id-token: write jobs: build-and-deploy: runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v4 with: submodules: recursive - name: Set up Python uses: actions/setup-python@v5 with: python-version: '3.11' - name: Install PlatformIO run: pip install platformio - name: Build T-Deck firmware (NimBLE) run: pio run -e tdeck - name: Determine version string id: version run: | if [[ "$GITHUB_REF" == refs/tags/v* ]]; then echo "VERSION=${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT" else echo "VERSION=dev-${GITHUB_SHA::7}" >> "$GITHUB_OUTPUT" fi - name: Copy firmware binaries run: | mkdir -p docs/flasher/firmware cp .pio/build/tdeck/bootloader.bin docs/flasher/firmware/ cp .pio/build/tdeck/partitions.bin docs/flasher/firmware/ cp .pio/build/tdeck/firmware.bin docs/flasher/firmware/ BOOT_APP0=$(find ~/.platformio -name "boot_app0.bin" | head -1) cp "$BOOT_APP0" docs/flasher/firmware/ # For tagged releases, also deploy to a versioned path on GitHub Pages # so the flasher can fetch them same-origin (GitHub release downloads lack CORS) if [[ "$GITHUB_REF" == refs/tags/v* ]]; then TAG="${GITHUB_REF#refs/tags/}" mkdir -p "docs/flasher/firmware/releases/${TAG}" cp .pio/build/tdeck/bootloader.bin "docs/flasher/firmware/releases/${TAG}/" cp .pio/build/tdeck/partitions.bin "docs/flasher/firmware/releases/${TAG}/" cp .pio/build/tdeck/firmware.bin "docs/flasher/firmware/releases/${TAG}/" cp "$BOOT_APP0" "docs/flasher/firmware/releases/${TAG}/" fi - name: Download existing release assets for GitHub Pages run: | # Fetch all published releases and download their firmware assets # so versioned firmware is available same-origin on GitHub Pages. # With keep_files: true, each release only needs to be downloaded once. for tag in $(gh api repos/${{ github.repository }}/releases --jq '.[].tag_name'); do dir="docs/flasher/firmware/releases/${tag}" # Skip if we already have this version's firmware (e.g., current tagged build) if [ -f "${dir}/firmware.bin" ]; then echo "Skipping ${tag} — already present" continue fi mkdir -p "${dir}" echo "Downloading assets for ${tag}..." for asset in bootloader.bin partitions.bin boot_app0.bin firmware.bin; do url="https://github.com/${{ github.repository }}/releases/download/${tag}/${asset}" if curl -sL -o "${dir}/${asset}" -w '%{http_code}' "${url}" | grep -qx 200; then echo " ${asset} OK" else rm -f "${dir}/${asset}" echo " ${asset} not found" fi done done env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Generate manifest files run: | VERSION="${{ steps.version.outputs.VERSION }}" cat > docs/flasher/manifest-install.json << EOF { "name": "Pyxis T-Deck", "version": "${VERSION}", "new_install_prompt_erase": false, "builds": [ { "chipFamily": "ESP32-S3", "parts": [ { "path": "firmware/bootloader.bin", "offset": 0 }, { "path": "firmware/partitions.bin", "offset": 32768 }, { "path": "firmware/boot_app0.bin", "offset": 57344 }, { "path": "firmware/firmware.bin", "offset": 65536 } ] } ] } EOF cat > docs/flasher/manifest-update.json << EOF { "name": "Pyxis T-Deck", "version": "${VERSION}", "new_install_prompt_erase": false, "builds": [ { "chipFamily": "ESP32-S3", "parts": [ { "path": "firmware/firmware.bin", "offset": 65536 } ] } ] } EOF - name: Generate root landing page from README run: | mkdir -p docs/root pip install markdown python3 -c " import markdown, pathlib md = pathlib.Path('README.md').read_text() body = markdown.markdown(md, extensions=['fenced_code', 'tables']) html = '''