mirror of
https://github.com/bybrooklyn/openbitdo.git
synced 2026-03-19 04:12:56 -04:00
release prep: rc.1 baseline and gating updates
This commit is contained in:
59
.github/ISSUE_TEMPLATE/dirtyroom-evidence.yml
vendored
Normal file
59
.github/ISSUE_TEMPLATE/dirtyroom-evidence.yml
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
name: Dirty-Room Evidence (Sanitized)
|
||||
description: Submit sanitized protocol evidence for unconfirmed devices/operations.
|
||||
title: "[dirtyroom] <vid:pid> <operation-group>"
|
||||
labels:
|
||||
- protocol
|
||||
body:
|
||||
- type: input
|
||||
id: vidpid
|
||||
attributes:
|
||||
label: VID/PID
|
||||
placeholder: 0x2dc8:0x5200
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: firmware
|
||||
attributes:
|
||||
label: Firmware version
|
||||
placeholder: 1.00
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: operation_group
|
||||
attributes:
|
||||
label: Operation group
|
||||
placeholder: CoreDiag / Firmware / Mapping
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: request_shape
|
||||
attributes:
|
||||
label: Sanitized request shape
|
||||
description: Structural description only. No copied vendor/decompiled snippets.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: response_shape
|
||||
attributes:
|
||||
label: Sanitized response shape
|
||||
description: Structural description and validator cues.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: failure_signatures
|
||||
attributes:
|
||||
label: Failure signatures
|
||||
description: Timeout/malformed/invalid signatures observed.
|
||||
- type: textarea
|
||||
id: reproducibility
|
||||
attributes:
|
||||
label: Reproducibility notes
|
||||
description: Steps, environment, and confidence.
|
||||
validations:
|
||||
required: true
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
**Clean-room reminder**
|
||||
- Do not include raw decompiled code.
|
||||
- Submit sanitized protocol structure only.
|
||||
54
.github/ISSUE_TEMPLATE/hardware-report.yml
vendored
Normal file
54
.github/ISSUE_TEMPLATE/hardware-report.yml
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
name: Hardware Report
|
||||
description: Report tested device behavior for OpenBitdo compatibility.
|
||||
title: "[hardware] <device> <vid:pid>"
|
||||
labels:
|
||||
- hardware
|
||||
body:
|
||||
- type: input
|
||||
id: device_name
|
||||
attributes:
|
||||
label: Device name
|
||||
placeholder: Ultimate2 / JP108 / etc.
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: vidpid
|
||||
attributes:
|
||||
label: VID/PID
|
||||
description: Use hex format `0xVVVV:0xPPPP`
|
||||
placeholder: 0x2dc8:0x6012
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: firmware
|
||||
attributes:
|
||||
label: Firmware version
|
||||
placeholder: 1.02
|
||||
- type: textarea
|
||||
id: operations
|
||||
attributes:
|
||||
label: Operations tested
|
||||
description: identify, diag probe, mode read, profile read/write, firmware preflight, etc.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: sanitized_structure
|
||||
attributes:
|
||||
label: Sanitized request/response structure
|
||||
description: Structural shape only. Do not paste vendor/decompiled snippets.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: behavior
|
||||
attributes:
|
||||
label: Observed behavior
|
||||
description: Include expected vs actual.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: env
|
||||
attributes:
|
||||
label: Environment
|
||||
description: OS, transport (USB/BT), and reproducibility notes.
|
||||
validations:
|
||||
required: true
|
||||
73
.github/ISSUE_TEMPLATE/release-blocker.yml
vendored
Normal file
73
.github/ISSUE_TEMPLATE/release-blocker.yml
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
name: Release Blocker
|
||||
description: Report a problem that must be resolved before public RC release.
|
||||
title: "[release-blocker] <short summary>"
|
||||
labels:
|
||||
- release-blocker
|
||||
- severity:p1
|
||||
body:
|
||||
- type: dropdown
|
||||
id: severity
|
||||
attributes:
|
||||
label: Severity
|
||||
description: Select the impact level for this blocker.
|
||||
options:
|
||||
- severity:p0 (critical)
|
||||
- severity:p1 (high)
|
||||
- severity:p2 (medium)
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: vidpid
|
||||
attributes:
|
||||
label: VID/PID
|
||||
description: Required for triage. Use format `0xVVVV:0xPPPP`.
|
||||
placeholder: 0x2dc8:0x6012
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: firmware_version
|
||||
attributes:
|
||||
label: Firmware version
|
||||
description: Required for triage.
|
||||
placeholder: 1.02
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: openbitdo_version
|
||||
attributes:
|
||||
label: OpenBitdo version
|
||||
placeholder: v0.0.1-rc.1
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: summary
|
||||
attributes:
|
||||
label: What is broken?
|
||||
description: One concise paragraph describing the blocker.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: reproduction
|
||||
attributes:
|
||||
label: Reproduction steps
|
||||
description: Provide deterministic steps from app launch to failure.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: expected
|
||||
attributes:
|
||||
label: Expected behavior
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: actual
|
||||
attributes:
|
||||
label: Actual behavior
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: attachments
|
||||
attributes:
|
||||
label: Attachments (optional but strongly recommended)
|
||||
description: Attach TOML report/logs/screenshots if available to speed up triage.
|
||||
placeholder: "Attach report TOML and logs if possible."
|
||||
130
.github/workflows/aur-publish.yml
vendored
Normal file
130
.github/workflows/aur-publish.yml
vendored
Normal 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
|
||||
203
.github/workflows/ci.yml
vendored
203
.github/workflows/ci.yml
vendored
@@ -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
287
.github/workflows/release.yml
vendored
Normal 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
|
||||
Reference in New Issue
Block a user