# Single entrypoint for release automation. # # Triggers: # - push to master → auto-tag next patch from latest tag + -dev., # create prerelease, invoke build.yml # - push of v* tag → infer channel from tag, auto-tag next patch, # create release (or update), invoke build.yml # # Build steps live in build.yml (reusable). This file only owns versioning # + release creation. Every channel builds the kiosk binary and Pi image. name: release on: push: branches: - master tags: - "v*" workflow_dispatch: inputs: bump: description: "Force a tagged dev release (one-off)." type: boolean default: false concurrency: group: release-${{ github.ref }} cancel-in-progress: ${{ github.ref_type != 'tag' }} permissions: contents: write jobs: # ---- Tag + release record ------------------------------------------------- meta: runs-on: ubuntu-latest outputs: version: ${{ steps.compute.outputs.version }} tag: ${{ steps.compute.outputs.tag }} channel: ${{ steps.compute.outputs.channel }} ref: ${{ steps.compute.outputs.ref }} build_image: ${{ steps.compute.outputs.build_image }} steps: - uses: actions/checkout@v6 with: fetch-depth: 0 # need tags for git describe - name: Compute version / channel / tag id: compute shell: bash env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | set -e short=$(git rev-parse --short HEAD) if [[ "$GITHUB_REF" == refs/tags/v* ]]; then requested_tag="${GITHUB_REF#refs/tags/}" requested_version="${requested_tag#v}" if [[ "$requested_version" == *"-beta"* ]]; then channel=beta elif [[ "$requested_version" == *"-dev"* ]]; then channel=dev else channel=stable fi else channel=dev fi # Stable, beta, and dev all advance the patch number per build. latest=$(git tag --list 'v[0-9]*.[0-9]*.[0-9]*' --sort=-v:refname \ | head -1 || true) if [ -z "$latest" ]; then latest="v0.0.0"; fi base="${latest#v}" base="${base%%-*}" IFS=. read -r MAJ MIN PAT <<< "$base" PAT=$((PAT + 1)) case "$channel" in stable) version="${MAJ}.${MIN}.${PAT}" ;; beta) version="${MAJ}.${MIN}.${PAT}-beta.${short}" ;; dev) version="${MAJ}.${MIN}.${PAT}-dev.${short}" ;; esac tag="v${version}" build_image=true echo "version=$version" >> "$GITHUB_OUTPUT" echo "tag=$tag" >> "$GITHUB_OUTPUT" echo "channel=$channel" >> "$GITHUB_OUTPUT" echo "ref=$GITHUB_SHA" >> "$GITHUB_OUTPUT" echo "build_image=$build_image" >> "$GITHUB_OUTPUT" - name: Create / ensure release record (lightweight tag for master pushes) env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} TAG: ${{ steps.compute.outputs.tag }} CHANNEL: ${{ steps.compute.outputs.channel }} run: | set -e # The workflow computes the release tag for all channels so every # build bumps the patch version. A pushed tag only selects channel. if ! git rev-parse "$TAG" >/dev/null 2>&1; then git config user.email "actions@github.com" git config user.name "github-actions[bot]" git tag -a "$TAG" -m "Auto-tag $TAG ($CHANNEL)" git push origin "$TAG" fi # Create release if missing. Mark dev/beta as prerelease. if ! gh release view "$TAG" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then extra="" [[ "$CHANNEL" != "stable" ]] && extra="--prerelease" gh release create "$TAG" \ --repo "$GITHUB_REPOSITORY" \ --title "$TAG" \ --target "$GITHUB_SHA" \ --notes "Channel: ${CHANNEL}. Commit ${GITHUB_SHA}." \ $extra fi # ---- Build assets --------------------------------------------------------- build: needs: meta uses: ./.github/workflows/build.yml with: version: ${{ needs.meta.outputs.version }} tag: ${{ needs.meta.outputs.tag }} channel: ${{ needs.meta.outputs.channel }} ref: ${{ needs.meta.outputs.ref }} build-image: ${{ needs.meta.outputs.build_image == 'true' }} secrets: BF_AUTOIMPORT_URL: ${{ secrets.BF_AUTOIMPORT_URL }} BF_AUTOIMPORT_API_KEY: ${{ secrets.BF_AUTOIMPORT_API_KEY }}