release prep: rc.1 baseline and gating updates

This commit is contained in:
2026-03-02 15:54:55 -05:00
parent 97a42c8802
commit f43b2b24b6
168 changed files with 14708 additions and 982 deletions

130
.github/workflows/aur-publish.yml vendored Normal file
View File

@@ -0,0 +1,130 @@
name: AUR Publish
on:
workflow_call:
inputs:
tag:
description: "Release tag to publish (for example: v0.0.1-rc.1)"
required: true
type: string
workflow_dispatch:
inputs:
tag:
description: "Release tag to publish (for example: v0.0.1-rc.1)"
required: true
type: string
permissions:
contents: read
jobs:
publish-aur:
if: vars.AUR_PUBLISH_ENABLED == '1'
runs-on: ubuntu-latest
container: archlinux:base
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAG: ${{ inputs.tag }}
steps:
- uses: actions/checkout@v4
- name: Install AUR packaging dependencies
run: |
pacman -Sy --noconfirm --needed base-devel git openssh curl github-cli
- name: Wait for release assets
run: |
set -euo pipefail
for attempt in $(seq 1 30); do
if gh release view "$TAG" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then
echo "release ${TAG} is available"
exit 0
fi
sleep 10
done
echo "release ${TAG} was not found after waiting" >&2
exit 1
- name: Render AUR metadata from released assets
run: |
set -euo pipefail
mkdir -p /tmp/release-input /tmp/release-metadata
gh release download "$TAG" --repo "$GITHUB_REPOSITORY" \
--pattern "openbitdo-${TAG}-linux-x86_64.tar.gz" \
--pattern "openbitdo-${TAG}-linux-aarch64.tar.gz" \
--pattern "openbitdo-${TAG}-macos-arm64.tar.gz" \
--dir /tmp/release-input
gh api -H "Accept: application/octet-stream" "repos/${GITHUB_REPOSITORY}/tarball/${TAG}" \
> "/tmp/release-input/openbitdo-${TAG}-source.tar.gz"
bash packaging/scripts/render_release_metadata.sh \
"$TAG" \
"$GITHUB_REPOSITORY" \
/tmp/release-input \
/tmp/release-metadata
useradd -m builder
chown -R builder:builder /tmp/release-metadata
su builder -s /bin/bash -c "set -euo pipefail; \
cd /tmp/release-metadata/aur/openbitdo; \
makepkg --printsrcinfo > .SRCINFO; \
cd /tmp/release-metadata/aur/openbitdo-bin; \
makepkg --printsrcinfo > .SRCINFO"
- name: Upload rendered metadata (audit)
uses: actions/upload-artifact@v4
with:
name: aur-rendered-metadata-${{ inputs.tag }}
path: |
/tmp/release-metadata/aur/openbitdo/PKGBUILD
/tmp/release-metadata/aur/openbitdo/.SRCINFO
/tmp/release-metadata/aur/openbitdo-bin/PKGBUILD
/tmp/release-metadata/aur/openbitdo-bin/.SRCINFO
/tmp/release-metadata/checksums.env
- name: Configure SSH for AUR
run: |
if [[ -z "${{ secrets.AUR_USERNAME }}" ]]; then
echo "missing required secret: AUR_USERNAME" >&2
exit 1
fi
if [[ -z "${{ secrets.AUR_SSH_PRIVATE_KEY }}" ]]; then
echo "missing required secret: AUR_SSH_PRIVATE_KEY" >&2
exit 1
fi
mkdir -p ~/.ssh
echo "${{ secrets.AUR_SSH_PRIVATE_KEY }}" > ~/.ssh/aur
chmod 600 ~/.ssh/aur
ssh-keyscan -H aur.archlinux.org >> ~/.ssh/known_hosts
- name: Publish openbitdo
env:
GIT_SSH_COMMAND: ssh -i ~/.ssh/aur
AUR_USER: ${{ secrets.AUR_USERNAME }}
run: |
set -euo pipefail
TMP="$(mktemp -d)"
git clone "ssh://${AUR_USER}@aur.archlinux.org/openbitdo.git" "$TMP/openbitdo"
cp /tmp/release-metadata/aur/openbitdo/PKGBUILD "$TMP/openbitdo/PKGBUILD"
cp /tmp/release-metadata/aur/openbitdo/.SRCINFO "$TMP/openbitdo/.SRCINFO"
cd "$TMP/openbitdo"
git config user.name "openbitdo-ci"
git config user.email "actions@users.noreply.github.com"
git add PKGBUILD .SRCINFO
git commit -m "Update openbitdo package for ${TAG}" || exit 0
git push
- name: Publish openbitdo-bin
env:
GIT_SSH_COMMAND: ssh -i ~/.ssh/aur
AUR_USER: ${{ secrets.AUR_USERNAME }}
run: |
set -euo pipefail
TMP="$(mktemp -d)"
git clone "ssh://${AUR_USER}@aur.archlinux.org/openbitdo-bin.git" "$TMP/openbitdo-bin"
cp /tmp/release-metadata/aur/openbitdo-bin/PKGBUILD "$TMP/openbitdo-bin/PKGBUILD"
cp /tmp/release-metadata/aur/openbitdo-bin/.SRCINFO "$TMP/openbitdo-bin/.SRCINFO"
cd "$TMP/openbitdo-bin"
git config user.name "openbitdo-ci"
git config user.email "actions@users.noreply.github.com"
git add PKGBUILD .SRCINFO
git commit -m "Update openbitdo-bin package for ${TAG}" || exit 0
git push

View File

@@ -7,6 +7,10 @@ on:
pull_request:
paths:
- '**'
schedule:
# 07:30 UTC is 02:30 America/New_York during standard time.
# (GitHub cron does not support time zones/DST directly.)
- cron: '30 7 * * *'
workflow_dispatch:
jobs:
@@ -20,7 +24,42 @@ jobs:
- name: Clean-room guard
run: ./scripts/cleanroom_guard.sh
test:
aur-validate:
runs-on: ubuntu-latest
needs: guard
container: archlinux:base
steps:
- uses: actions/checkout@v4
- name: Install AUR packaging toolchain
run: |
pacman -Sy --noconfirm --needed base-devel git
- name: Ensure package metadata has pinned checksum fields
run: |
set -euo pipefail
if grep -nE 'SKIP|:no_check' \
packaging/aur/openbitdo/PKGBUILD \
packaging/aur/openbitdo-bin/PKGBUILD \
packaging/homebrew/Formula/openbitdo.rb; then
echo "Found placeholder checksum markers; release metadata must be pinned." >&2
exit 1
fi
test -f packaging/scripts/render_release_metadata.sh
test -f packaging/aur/openbitdo/PKGBUILD.tmpl
test -f packaging/aur/openbitdo-bin/PKGBUILD.tmpl
test -f packaging/homebrew/Formula/openbitdo.rb.tmpl
- name: Validate PKGBUILD and .SRCINFO
run: |
useradd -m builder
chown -R builder:builder "$GITHUB_WORKSPACE"
su builder -s /bin/bash -c "set -euo pipefail; \
cd '$GITHUB_WORKSPACE/packaging/aur/openbitdo'; \
makepkg --printsrcinfo > /tmp/openbitdo.srcinfo; \
diff -u .SRCINFO /tmp/openbitdo.srcinfo; \
cd '$GITHUB_WORKSPACE/packaging/aur/openbitdo-bin'; \
makepkg --printsrcinfo > /tmp/openbitdo-bin.srcinfo; \
diff -u .SRCINFO /tmp/openbitdo-bin.srcinfo"
tui-smoke-test:
runs-on: ubuntu-latest
needs: guard
defaults:
@@ -34,14 +73,80 @@ jobs:
sudo apt-get install -y libudev-dev pkg-config
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- name: Run TUI smoke tests
run: cargo test -p bitdo_tui --all-targets
build-macos-arm64:
runs-on: macos-14
needs: guard
defaults:
run:
working-directory: sdk
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: aarch64-apple-darwin
- name: Build/package macOS arm64 artifacts
run: ./scripts/package-macos.sh v0.0.0-ci arm64 aarch64-apple-darwin
- name: Upload macOS arm64 artifact sample
if: always()
uses: actions/upload-artifact@v4
with:
name: ci-macos-arm64-package
path: sdk/dist/openbitdo-v0.0.0-ci-macos-arm64*
hardware-paths:
runs-on: ubuntu-latest
outputs:
hardware: ${{ steps.filter.outputs.hardware }}
steps:
- uses: actions/checkout@v4
- uses: dorny/paths-filter@v3
id: filter
with:
filters: |
hardware:
- 'sdk/crates/bitdo_proto/**'
- 'sdk/crates/bitdo_app_core/**'
- 'sdk/crates/bitdo_tui/**'
- 'sdk/crates/openbitdo/**'
- 'sdk/tests/**'
- 'sdk/scripts/run_hardware_smoke.sh'
- 'spec/**'
- 'harness/lab/device_lab.yaml'
- '.github/workflows/ci.yml'
test:
runs-on: ubuntu-latest
needs:
- guard
- tui-smoke-test
- aur-validate
- build-macos-arm64
defaults:
run:
working-directory: sdk
steps:
- uses: actions/checkout@v4
- name: Install system deps
run: |
sudo apt-get update
sudo apt-get install -y libudev-dev pkg-config
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- name: Clippy (workspace strict)
run: cargo clippy --workspace --all-targets -- -D warnings
- name: Run tests
run: cargo test --workspace --all-targets
hardware-smoke:
hardware-dinput:
if: vars.BITDO_ENABLE_EXTRA_HARDWARE == '1'
runs-on: [self-hosted, linux, hid-lab]
if: (github.ref == 'refs/heads/main' || github.event_name == 'workflow_dispatch') && vars.HARDWARE_SMOKE_ENABLED == '1'
continue-on-error: true
needs: test
env:
BITDO_REQUIRED_FAMILIES: DInput
defaults:
run:
working-directory: sdk
@@ -55,5 +160,93 @@ jobs:
if: always()
uses: actions/upload-artifact@v4
with:
name: hardware-smoke-report
name: hardware-smoke-dinput
path: harness/reports/*.json
hardware-standard64:
if: vars.BITDO_ENABLE_EXTRA_HARDWARE == '1'
runs-on: [self-hosted, linux, hid-lab]
needs: test
env:
BITDO_REQUIRED_FAMILIES: Standard64
defaults:
run:
working-directory: sdk
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- name: Hardware smoke tests
run: ./scripts/run_hardware_smoke.sh
- name: Upload hardware smoke report
if: always()
uses: actions/upload-artifact@v4
with:
name: hardware-smoke-standard64
path: harness/reports/*.json
hardware-ultimate2:
if: github.event_name == 'schedule' || github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v') || needs.hardware-paths.outputs.hardware == 'true'
runs-on: [self-hosted, linux, hid-lab]
needs: [test, hardware-paths]
env:
BITDO_REQUIRED_SUITE: ultimate2
defaults:
run:
working-directory: sdk
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- name: Hardware smoke tests (Ultimate2)
run: ./scripts/run_hardware_smoke.sh
- name: Upload hardware smoke report
if: always()
uses: actions/upload-artifact@v4
with:
name: hardware-smoke-ultimate2
path: harness/reports/*.json
hardware-108jp:
if: github.event_name == 'schedule' || github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v') || needs.hardware-paths.outputs.hardware == 'true'
runs-on: [self-hosted, linux, hid-lab]
needs: [test, hardware-paths]
env:
BITDO_REQUIRED_SUITE: 108jp
defaults:
run:
working-directory: sdk
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- name: Hardware smoke tests (JP108)
run: ./scripts/run_hardware_smoke.sh
- name: Upload hardware smoke report
if: always()
uses: actions/upload-artifact@v4
with:
name: hardware-smoke-108jp
path: harness/reports/*.json
hardware-jphandshake:
if: vars.BITDO_ENABLE_JP_HARDWARE == '1'
runs-on: [self-hosted, linux, hid-lab]
needs: test
env:
BITDO_REQUIRED_FAMILIES: JpHandshake
defaults:
run:
working-directory: sdk
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- name: Hardware smoke tests
run: ./scripts/run_hardware_smoke.sh
- name: Upload hardware smoke report
if: always()
uses: actions/upload-artifact@v4
with:
name: hardware-smoke-jphandshake
path: harness/reports/*.json

287
.github/workflows/release.yml vendored Normal file
View File

@@ -0,0 +1,287 @@
name: Release
on:
push:
tags:
- "v*"
permissions:
contents: write
checks: read
issues: read
jobs:
preflight:
runs-on: ubuntu-latest
defaults:
run:
working-directory: sdk
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Ensure tag commit is on main
working-directory: ${{ github.workspace }}
run: |
set -euo pipefail
git fetch origin main
if ! git merge-base --is-ancestor "$GITHUB_SHA" origin/main; then
echo "Tag commit is not reachable from origin/main" >&2
exit 1
fi
- name: Ensure no open release blockers
working-directory: ${{ github.workspace }}
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -euo pipefail
blocker_count="$(gh api "repos/${GITHUB_REPOSITORY}/issues?state=open&labels=release-blocker&per_page=100" \
--jq '[.[] | select(.pull_request == null)] | length')"
if [[ "$blocker_count" != "0" ]]; then
echo "Open release-blocker issues detected: ${blocker_count}" >&2
gh issue list --repo "$GITHUB_REPOSITORY" --state open --label release-blocker
exit 1
fi
- name: Preflight required publish secrets
working-directory: ${{ github.workspace }}
env:
AUR_USERNAME: ${{ secrets.AUR_USERNAME }}
AUR_SSH_PRIVATE_KEY: ${{ secrets.AUR_SSH_PRIVATE_KEY }}
HOMEBREW_TAP_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}
run: |
set -euo pipefail
[[ -n "${AUR_USERNAME:-}" ]] || { echo "missing required secret: AUR_USERNAME" >&2; exit 1; }
[[ -n "${AUR_SSH_PRIVATE_KEY:-}" ]] || { echo "missing required secret: AUR_SSH_PRIVATE_KEY" >&2; exit 1; }
[[ -n "${HOMEBREW_TAP_TOKEN:-}" ]] || { echo "missing required secret: HOMEBREW_TAP_TOKEN" >&2; exit 1; }
- name: Require successful CI and hardware checks on tagged commit
working-directory: ${{ github.workspace }}
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -euo pipefail
required_checks=(
guard
aur-validate
tui-smoke-test
build-macos-arm64
test
hardware-ultimate2
hardware-108jp
)
check_runs_json="$(gh api "repos/${GITHUB_REPOSITORY}/commits/${GITHUB_SHA}/check-runs")"
failed=0
for check in "${required_checks[@]}"; do
conclusion="$(jq -r --arg name "$check" '[.check_runs[] | select(.name == $name) | .conclusion] | first // "missing"' <<<"$check_runs_json")"
if [[ "$conclusion" != "success" ]]; then
echo "required check '${check}' is not successful on ${GITHUB_SHA} (got: ${conclusion})" >&2
failed=1
fi
done
if [[ "$failed" -ne 0 ]]; then
exit 1
fi
- name: Install system deps
run: |
sudo apt-get update
sudo apt-get install -y libudev-dev pkg-config
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- name: Guard
run: ./scripts/cleanroom_guard.sh
- name: Tests
run: cargo test --workspace --all-targets
build-linux-x86_64:
runs-on: ubuntu-latest
needs: preflight
defaults:
run:
working-directory: sdk
steps:
- uses: actions/checkout@v4
- name: Install system deps
run: |
sudo apt-get update
sudo apt-get install -y libudev-dev pkg-config
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- name: Package linux x86_64
run: ./scripts/package-linux.sh "${GITHUB_REF_NAME}" x86_64
- name: Upload linux x86_64 assets
uses: actions/upload-artifact@v4
with:
name: release-linux-x86_64
path: sdk/dist/openbitdo-${{ github.ref_name }}-linux-x86_64*
build-linux-aarch64:
runs-on: ubuntu-24.04-arm
needs: preflight
defaults:
run:
working-directory: sdk
steps:
- uses: actions/checkout@v4
- name: Install system deps
run: |
sudo apt-get update
sudo apt-get install -y libudev-dev pkg-config
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- name: Package linux aarch64
run: ./scripts/package-linux.sh "${GITHUB_REF_NAME}" aarch64
- name: Upload linux aarch64 assets
uses: actions/upload-artifact@v4
with:
name: release-linux-aarch64
path: sdk/dist/openbitdo-${{ github.ref_name }}-linux-aarch64*
build-macos-arm64:
runs-on: macos-14
needs: preflight
defaults:
run:
working-directory: sdk
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: aarch64-apple-darwin
- name: Package macOS arm64
run: ./scripts/package-macos.sh "${GITHUB_REF_NAME}" arm64 aarch64-apple-darwin
- name: Upload macOS arm64 assets
uses: actions/upload-artifact@v4
with:
name: release-macos-arm64
path: sdk/dist/openbitdo-${{ github.ref_name }}-macos-arm64*
publish:
runs-on: ubuntu-latest
needs:
- build-linux-x86_64
- build-linux-aarch64
- build-macos-arm64
steps:
- uses: actions/checkout@v4
- name: Download packaged assets
uses: actions/download-artifact@v4
with:
path: release-assets
- name: Determine prerelease flag
id: prerelease
run: |
if [[ "${GITHUB_REF_NAME}" == *"-rc."* ]]; then
echo "value=true" >> "$GITHUB_OUTPUT"
else
echo "value=false" >> "$GITHUB_OUTPUT"
fi
- name: Publish GitHub release
uses: softprops/action-gh-release@v2
with:
prerelease: ${{ steps.prerelease.outputs.value }}
body_path: CHANGELOG.md
files: |
release-assets/**/openbitdo-${{ github.ref_name }}-linux-x86_64
release-assets/**/openbitdo-${{ github.ref_name }}-linux-x86_64.sha256
release-assets/**/openbitdo-${{ github.ref_name }}-linux-x86_64.tar.gz
release-assets/**/openbitdo-${{ github.ref_name }}-linux-x86_64.tar.gz.sha256
release-assets/**/openbitdo-${{ github.ref_name }}-linux-aarch64
release-assets/**/openbitdo-${{ github.ref_name }}-linux-aarch64.sha256
release-assets/**/openbitdo-${{ github.ref_name }}-linux-aarch64.tar.gz
release-assets/**/openbitdo-${{ github.ref_name }}-linux-aarch64.tar.gz.sha256
release-assets/**/openbitdo-${{ github.ref_name }}-macos-arm64
release-assets/**/openbitdo-${{ github.ref_name }}-macos-arm64.sha256
release-assets/**/openbitdo-${{ github.ref_name }}-macos-arm64.tar.gz
release-assets/**/openbitdo-${{ github.ref_name }}-macos-arm64.tar.gz.sha256
release-assets/**/openbitdo-${{ github.ref_name }}-macos-arm64.pkg
release-assets/**/openbitdo-${{ github.ref_name }}-macos-arm64.pkg.sha256
publish-homebrew:
if: vars.HOMEBREW_PUBLISH_ENABLED == '1'
runs-on: ubuntu-latest
needs: publish
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v4
- name: Wait for release assets
run: |
set -euo pipefail
for attempt in $(seq 1 30); do
if gh release view "${GITHUB_REF_NAME}" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then
exit 0
fi
sleep 10
done
echo "release ${GITHUB_REF_NAME} was not found after waiting" >&2
exit 1
- name: Render Homebrew formula with release checksums
run: |
set -euo pipefail
mkdir -p /tmp/release-input /tmp/release-metadata
gh release download "${GITHUB_REF_NAME}" --repo "$GITHUB_REPOSITORY" \
--pattern "openbitdo-${GITHUB_REF_NAME}-linux-x86_64.tar.gz" \
--pattern "openbitdo-${GITHUB_REF_NAME}-linux-aarch64.tar.gz" \
--pattern "openbitdo-${GITHUB_REF_NAME}-macos-arm64.tar.gz" \
--dir /tmp/release-input
gh api -H "Accept: application/octet-stream" "repos/${GITHUB_REPOSITORY}/tarball/${GITHUB_REF_NAME}" \
> "/tmp/release-input/openbitdo-${GITHUB_REF_NAME}-source.tar.gz"
bash packaging/scripts/render_release_metadata.sh \
"${GITHUB_REF_NAME}" \
"$GITHUB_REPOSITORY" \
/tmp/release-input \
/tmp/release-metadata
- name: Upload rendered Homebrew formula (audit)
uses: actions/upload-artifact@v4
with:
name: homebrew-rendered-formula-${{ github.ref_name }}
path: |
/tmp/release-metadata/homebrew/Formula/openbitdo.rb
/tmp/release-metadata/checksums.env
- name: Sync Homebrew tap
env:
HOMEBREW_PUBLISH_ENABLED: "1"
HOMEBREW_TAP_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}
HOMEBREW_TAP_REPO: ${{ vars.HOMEBREW_TAP_REPO }}
FORMULA_SOURCE: /tmp/release-metadata/homebrew/Formula/openbitdo.rb
run: |
set -euo pipefail
if [[ -z "${HOMEBREW_TAP_TOKEN:-}" ]]; then
echo "missing required secret: HOMEBREW_TAP_TOKEN" >&2
exit 1
fi
bash packaging/homebrew/sync_tap.sh
publish-aur:
if: vars.AUR_PUBLISH_ENABLED == '1'
needs: publish
uses: ./.github/workflows/aur-publish.yml
with:
tag: ${{ github.ref_name }}
secrets: inherit