| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198 |
- name: Release
- on:
- push:
- branches:
- - main
- tags:
- - '[0-9]*.[0-9]*.[0-9]*'
- release:
- types:
- - published
- permissions:
- contents: write
- jobs:
- bump-version-tag:
- if: github.event_name == 'push' && github.ref == 'refs/heads/main'
- runs-on: ubuntu-latest
- steps:
- - name: Check out repository
- uses: actions/checkout@v4
- with:
- fetch-depth: 0
- - name: Tag next patch version
- run: |
- set -eu
- git fetch --force --tags origin
- SEMVER_RE='^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$'
- if git tag --points-at "$GITHUB_SHA" | grep -Eq "$SEMVER_RE"; then
- echo "semver tag already exists on this commit; skipping bump"
- echo "Tag already present on ${GITHUB_SHA}; release build runs from the tag event." >> "$GITHUB_STEP_SUMMARY"
- exit 0
- fi
- LAST="$(
- git tag --list \
- | grep -E "$SEMVER_RE" \
- | sort -V \
- | tail -n1 || true
- )"
- if [ -z "$LAST" ]; then
- # Seed semver history at the requested public baseline.
- NEXT="0.9.1"
- else
- MAJOR="${LAST%%.*}"
- REST="${LAST#*.}"
- MINOR="${REST%%.*}"
- PATCH="${LAST##*.}"
- NEXT="${MAJOR}.${MINOR}.$((PATCH + 1))"
- fi
- git tag "$NEXT" "$GITHUB_SHA"
- git push origin "$NEXT"
- build-release:
- if: github.event_name == 'release' || (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/'))
- runs-on: ubuntu-latest
- steps:
- - name: Check out repository
- uses: actions/checkout@v4
- with:
- fetch-depth: 0
- - name: Resolve release version
- id: release_version
- run: |
- if [ "${{ github.event_name }}" = "release" ]; then
- VERSION="${{ github.event.release.tag_name }}"
- else
- VERSION="${GITHUB_REF_NAME}"
- fi
- echo "version=$VERSION" >> "$GITHUB_OUTPUT"
- - name: Set up Arduino CLI
- uses: arduino/setup-arduino-cli@v2
- - name: Set up Python
- uses: actions/setup-python@v5
- with:
- python-version: '3.x'
- - name: Install adafruit-nrfutil
- run: pip install adafruit-nrfutil
- - name: Install Adafruit nRF52 core
- run: |
- arduino-cli config init --overwrite
- arduino-cli config set board_manager.additional_urls https://adafruit.github.io/arduino-board-index/package_adafruit_index.json
- arduino-cli core update-index
- arduino-cli core install adafruit:nrf52
- - name: Generate version header
- env:
- OPK_BUILD_VERSION: ${{ steps.release_version.outputs.version }}
- run: ./gen_version.sh
- - name: Compile OpenPuck
- run: |
- mkdir -p build/openpuck build/cache/openpuck
- arduino-cli compile \
- -b adafruit:nrf52:feather52840 \
- --clean \
- --build-path build/cache/openpuck \
- --output-dir build/openpuck \
- --build-property "build.extra_flags=-DNRF52840_XXAA {build.flags.usb} -DCFG_TUD_HID=4 -DCFG_TUD_TASK_QUEUE_SZ=64 -DCFG_TUD_VENDOR_TX_BUFSIZE=256" \
- OpenPuck
- - name: Generate UF2 (standard)
- run: ./gen_uf2.sh build/openpuck/OpenPuck.ino.hex build/openpuck/OpenPuck.ino.uf2
- - name: Compile ReversePuckFirmware
- run: |
- mkdir -p build/reversepuck build/cache/reversepuck
- arduino-cli compile \
- -b adafruit:nrf52:feather52840 \
- --clean \
- --build-path build/cache/reversepuck \
- --output-dir build/reversepuck \
- --build-property "build.extra_flags=-DNRF52840_XXAA {build.flags.usb}" \
- ReversePuckFirmware
- - name: Generate UF2 (ReversePuckFirmware)
- run: ./gen_uf2.sh build/reversepuck/ReversePuckFirmware.ino.hex build/reversepuck/ReversePuckFirmware.ino.uf2
- - name: Compile recovery build
- run: |
- mkdir -p build/openpuck-recovery build/cache/openpuck-recovery
- arduino-cli compile \
- -b adafruit:nrf52:feather52840 \
- --clean \
- --build-path build/cache/openpuck-recovery \
- --output-dir build/openpuck-recovery \
- --build-property "build.extra_flags=-DNRF52840_XXAA {build.flags.usb} -DCFG_TUD_HID=4 -DCFG_TUD_TASK_QUEUE_SZ=64 -DCFG_TUD_VENDOR_TX_BUFSIZE=256 -DOPK_FACTORY_RESET=1" \
- OpenPuck
- - name: Generate UF2 (recovery)
- run: ./gen_uf2.sh build/openpuck-recovery/OpenPuck.ino.hex build/openpuck-recovery/OpenPuck.ino.uf2
- - name: Collect artifacts
- env:
- VERSION: ${{ steps.release_version.outputs.version }}
- run: |
- mkdir -p release_assets
- find build/openpuck build/openpuck-recovery \
- -maxdepth 1 -type f \
- \( -name '*.uf2' -o -name '*.zip' \) \
- -print | while read -r f; do
- # Keep only the extension; the arduino base name (OpenPuck.ino.*)
- # is redundant once we prefix with OpenPuck-<version>-<flavor>.
- ext="${f##*.}"
- dir="$(basename "$(dirname "$f")")"
- if [ "$dir" = "openpuck-recovery" ]; then
- flavor="factory-reset"
- else
- flavor="standard"
- fi
- cp "$f" "release_assets/OpenPuck-${VERSION}-${flavor}.${ext}"
- done
- find build/reversepuck \
- -maxdepth 1 -type f \
- \( -name '*.uf2' -o -name '*.zip' \) \
- -print | while read -r f; do
- ext="${f##*.}"
- cp "$f" "release_assets/ReversePuckFirmware-${VERSION}.${ext}"
- done
- test -n "$(find release_assets -maxdepth 1 -type f -print -quit)"
- ls -la release_assets
- - name: Create GitHub Release
- uses: softprops/action-gh-release@v2
- with:
- tag_name: ${{ steps.release_version.outputs.version }}
- name: ${{ format('OpenPuck {0}', steps.release_version.outputs.version) }}
- prerelease: false
- files: release_assets/*
- body: |
- OpenPuck Firmware Release
- Version: ${{ steps.release_version.outputs.version }}
- Commit: ${{ github.sha }}
- ### Files included:
- - `OpenPuck-*-standard.*` — puck firmware (standard)
- - `OpenPuck-*-factory-reset.*` — puck firmware (factory reset)
- - `ReversePuckFirmware-*.*` — reverse-puck firmware (controller emulator)
- - `.zip` files for Adafruit DFU tool
- - `.uf2` files for drag-and-drop flashing (BOOT/UF2 drive)
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|