diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..32d5e31 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,8 @@ +version: 2 +updates: + - package-ecosystem: github-actions + directory: / + schedule: + interval: monthly + commit-message: + prefix: ci diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..f1d1525 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,93 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: ci-${{ github.ref }} + cancel-in-progress: true + +jobs: + host-tests: + name: Host tests + runs-on: ubuntu-24.04 + steps: + - name: Checkout + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + - name: Install toolchain + run: | + sudo apt-get update + sudo apt-get install -y cmake clang-18 + + - name: Configure + run: cmake -S . -B build-host -DCMAKE_BUILD_TYPE=Release + env: + CC: clang-18 + CXX: clang++-18 + + - name: Build + run: cmake --build build-host -j2 + + - name: Test + run: ctest --test-dir build-host --output-on-failure + + - name: Upstream source gate + run: python3 tools/check_v1_source_gate.py + + - name: Plugin wrapper test + run: python3 tests/test_plugin_wrapper.py + + ps5-build: + name: PS5 build + runs-on: ubuntu-24.04 + needs: host-tests + steps: + - name: Checkout + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + - name: Install host dependencies + run: | + sudo apt-get update + sudo apt-get install -y \ + git wget unzip cmake meson pkg-config \ + python3 python3-pyelftools \ + clang-18 lld-18 xxd + + - name: Prepare pinned dependencies + run: bash ./scripts/prepare_ps5_deps.sh + + - name: Build and verify + run: bash ./scripts/ps5_source_build.sh + + - name: Publish checksums + run: | + { + echo "### Build checksums" + echo '```text' + cat dist/SHA256SUMS.txt + echo '```' + } >> "$GITHUB_STEP_SUMMARY" + + - name: Upload build + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: ps5-dualsense-overlay-${{ github.sha }} + path: | + dist/Common_FPS_PS5_v1.2.1.elf + dist/Common_FPS_PS5_etaHEN_v1.2.1.plugin + dist/Common_FPS_ShellUI_v1.2.1.elf + dist/SHA256SUMS.txt + RESOLVED_BUILD_DEPENDENCIES.txt + if-no-files-found: error + retention-days: 30 diff --git a/BUILDING.md b/BUILDING.md index 59dc28b..600917a 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -16,9 +16,10 @@ identity and the release verifier. bash ./scripts/prepare_ps5_deps.sh ``` -The script installs the PS5 payload SDK pinned by upstream (v0.41) into `/opt/ps5-payload-sdk` -(it uses `sudo`) and clones the exact etaHEN and shsrv commits listed in `DEPENDENCIES.lock.json` into -`.deps/`. If you already have an SDK installed, export `PS5_PAYLOAD_SDK` and skip the SDK step. +The script installs PS5 payload SDK v0.43 — the version used to build the releases — into +`/opt/ps5-payload-sdk` (it uses `sudo`) and clones the exact etaHEN and shsrv commits listed in +`DEPENDENCIES.lock.json` into `.deps/`. If you already have SDK v0.43 installed, export +`PS5_PAYLOAD_SDK` and skip the SDK step. ## 2. Build the payloads @@ -64,12 +65,22 @@ Requires Pillow and Google Chrome or Chromium (headless). It regenerates `assets `assets/layout.json` and the embedded sprite tables in `src/ps5/shellui_payload/` from the source SVGs in `assets/source/`. `assets/preview.html` shows the result on a PC. +## Continuous integration + +Every push to `main` and every pull request runs [`.github/workflows/ci.yml`](.github/workflows/ci.yml): +host tests, the upstream source gate, the plugin wrapper test and the full PS5 build with +`tools/verify_release.py`. Each run publishes the build checksums in its summary and attaches the build +as an artifact. + ## Reproducing a release -Release v1.0.0 was built from its tag with ps5-payload-sdk v0.43 and the etaHEN and shsrv commits -pinned in `DEPENDENCIES.lock.json`. Building the tag with the same SDK produces a controller ELF with the -SHA-256 published in the release's `SHA256SUMS.txt`: +Release v1.0.0 was built with ps5-payload-sdk v0.43 and the etaHEN and shsrv commits pinned in +`DEPENDENCIES.lock.json`. Following the steps above from a clean checkout produces a controller ELF +identical to the published one: ```bash sha256sum dist/Common_FPS_PS5_v1.2.1.elf ``` + +Compare the result with the release's `SHA256SUMS.txt`. The dependency script at the `v1.0.0` tag still +points to SDK v0.41; when building that tag, install SDK v0.43 and export `PS5_PAYLOAD_SDK` first. diff --git a/CHANGELOG.md b/CHANGELOG.md index a7c6939..dfadc61 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,9 +11,13 @@ All notable changes to this project are documented in this file. The format foll - Screenshots of the overlay in the README, with attribution to the games shown. - Security policy with response times, coordinated disclosure and download verification; code owners file. +- Continuous integration: host tests, upstream source gate, plugin wrapper test and the PS5 build with + release verification on every push and pull request; Dependabot updates for the pinned actions. ### Changed +- The dependency script and `DEPENDENCIES.lock.json` pin PS5 payload SDK v0.43, the version used to + build the releases. - Usage documentation simplified to loading the `.elf` with a payload manager, through its web portal or from a USB drive. Releases ship the `.elf` only. - Documented that the overlay must not run together with Common FPS or SimpleFPS. diff --git a/DEPENDENCIES.lock.json b/DEPENDENCIES.lock.json index 3b6e905..448d160 100644 --- a/DEPENDENCIES.lock.json +++ b/DEPENDENCIES.lock.json @@ -1,23 +1,23 @@ -{ - "project": "Common FPS for PS5", - "version": "1.1.0", - "license": "GPL-3.0-or-later", - "ps5_payload_sdk": { - "repository": "https://github.com/ps5-payload-dev/sdk", - "version": "v0.41", - "commit": "d2e2e58", - "purpose": "PS5 payload toolchain and system libraries" - }, - "etahen": { - "repository": "https://github.com/etaHEN/etaHEN", - "version": "2.4B", - "commit": "d47f99bd37f349ae59b3c4b66e09e93ba69f56cd", - "purpose": "Pinned GPL source baseline used by the process/module sampling adapter. Runtime hardware test used etaHEN 2.6." - }, - "ps5_payload_shsrv": { - "repository": "https://github.com/ps5-payload-dev/shsrv", - "version": "v0.20", - "commit": "6f320637d56d344a0e7797753099e33238bbf146", - "purpose": "Pinned GPL ptrace and ELF-loader primitives used by the source-built ShellUI bootstrap." - } -} +{ + "project": "ps5-dualsense-overlay", + "version": "1.0.0", + "license": "GPL-3.0-or-later", + "ps5_payload_sdk": { + "repository": "https://github.com/ps5-payload-dev/sdk", + "version": "v0.43", + "commit": "d9c9519", + "purpose": "PS5 payload toolchain and system libraries" + }, + "etahen": { + "repository": "https://github.com/etaHEN/etaHEN", + "version": "2.4B", + "commit": "d47f99bd37f349ae59b3c4b66e09e93ba69f56cd", + "purpose": "Pinned GPL source baseline used by the process/module sampling adapter. Runtime hardware test used etaHEN 2.6." + }, + "ps5_payload_shsrv": { + "repository": "https://github.com/ps5-payload-dev/shsrv", + "version": "v0.20", + "commit": "6f320637d56d344a0e7797753099e33238bbf146", + "purpose": "Pinned GPL ptrace and ELF-loader primitives used by the source-built ShellUI bootstrap." + } +} diff --git a/README.md b/README.md index 2439b4e..b3e3b7e 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ [![License: GPL-3.0-or-later](https://img.shields.io/badge/license-GPL--3.0--or--later-blue.svg)](LICENSE) [![Latest release](https://img.shields.io/github/v/release/erickdavestech/ps5-dualsense-overlay)](https://github.com/erickdavestech/ps5-dualsense-overlay/releases/latest) +[![CI](https://github.com/erickdavestech/ps5-dualsense-overlay/actions/workflows/ci.yml/badge.svg)](https://github.com/erickdavestech/ps5-dualsense-overlay/actions/workflows/ci.yml) On-screen **DualSense controller overlay** for a PlayStation 5 running homebrew. A single payload runs entirely on the console and draws the controller over the running game, lighting up buttons, diff --git a/SECURITY.md b/SECURITY.md index 513a747..78ec7f5 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -49,5 +49,6 @@ includes `SHA256SUMS.txt`; check the file before loading it: sha256sum -c SHA256SUMS.txt ``` -Release tags (`v*`) are protected against deletion and modification, and every release can be rebuilt -from its tag to obtain the same binary (see [BUILDING.md](BUILDING.md)). +Release tags (`v*`) are protected against deletion and modification, commits on `main` are signed and +show as **Verified** on GitHub, and every release can be rebuilt from source to obtain the same binary +(see [BUILDING.md](BUILDING.md)). diff --git a/scripts/prepare_ps5_deps.sh b/scripts/prepare_ps5_deps.sh index ef2a439..6cc39fd 100644 --- a/scripts/prepare_ps5_deps.sh +++ b/scripts/prepare_ps5_deps.sh @@ -1,49 +1,49 @@ -#!/usr/bin/env bash -set -euo pipefail - -ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" -DEPS="${ROOT}/.deps" -SDK_ZIP="/tmp/ps5-payload-sdk-v0.41.zip" - -ETAHEN_VERSION="2.4B" -ETAHEN_COMMIT="d47f99bd37f349ae59b3c4b66e09e93ba69f56cd" - -mkdir -p "${DEPS}" - -echo "[1/4] PS5 Payload SDK v0.41" -wget -q \ - https://github.com/ps5-payload-dev/sdk/releases/download/v0.41/ps5-payload-sdk.zip \ - -O "${SDK_ZIP}" - -sudo rm -rf /opt/ps5-payload-sdk -sudo unzip -q "${SDK_ZIP}" -d /opt - -export PS5_PAYLOAD_SDK=/opt/ps5-payload-sdk -test -x "${PS5_PAYLOAD_SDK}/bin/prospero-cmake" - -echo "[2/4] etaHEN ${ETAHEN_VERSION} source (${ETAHEN_COMMIT})" -rm -rf "${DEPS}/etahen" -git clone -q https://github.com/etaHEN/etaHEN.git "${DEPS}/etahen" -git -C "${DEPS}/etahen" checkout -q "${ETAHEN_COMMIT}" - -RESOLVED_ETAHEN="$(git -C "${DEPS}/etahen" rev-parse HEAD)" -if [ "${RESOLVED_ETAHEN}" != "${ETAHEN_COMMIT}" ]; then - echo "ERROR: etaHEN revision mismatch" - echo "Expected: ${ETAHEN_COMMIT}" - echo "Actual: ${RESOLVED_ETAHEN}" - exit 1 -fi - -echo "[3/4] ps5-payload-dev/shsrv v0.20 source" -rm -rf "${DEPS}/shsrv" -git clone -q --branch v0.20 --depth 1 \ - https://github.com/ps5-payload-dev/shsrv.git "${DEPS}/shsrv" - -echo "[4/4] Record exact resolved revisions" -{ - echo "PS5 Payload SDK: v0.41" - echo "etaHEN: ${RESOLVED_ETAHEN} (${ETAHEN_VERSION})" - echo "shsrv: $(git -C "${DEPS}/shsrv" rev-parse HEAD)" -} > "${ROOT}/RESOLVED_BUILD_DEPENDENCIES.txt" - -cat "${ROOT}/RESOLVED_BUILD_DEPENDENCIES.txt" +#!/usr/bin/env bash +set -euo pipefail + +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +DEPS="${ROOT}/.deps" +SDK_ZIP="/tmp/ps5-payload-sdk-v0.43.zip" + +ETAHEN_VERSION="2.4B" +ETAHEN_COMMIT="d47f99bd37f349ae59b3c4b66e09e93ba69f56cd" + +mkdir -p "${DEPS}" + +echo "[1/4] PS5 Payload SDK v0.43" +wget -q \ + https://github.com/ps5-payload-dev/sdk/releases/download/v0.43/ps5-payload-sdk.zip \ + -O "${SDK_ZIP}" + +sudo rm -rf /opt/ps5-payload-sdk +sudo unzip -q "${SDK_ZIP}" -d /opt + +export PS5_PAYLOAD_SDK=/opt/ps5-payload-sdk +test -x "${PS5_PAYLOAD_SDK}/bin/prospero-cmake" + +echo "[2/4] etaHEN ${ETAHEN_VERSION} source (${ETAHEN_COMMIT})" +rm -rf "${DEPS}/etahen" +git clone -q https://github.com/etaHEN/etaHEN.git "${DEPS}/etahen" +git -C "${DEPS}/etahen" checkout -q "${ETAHEN_COMMIT}" + +RESOLVED_ETAHEN="$(git -C "${DEPS}/etahen" rev-parse HEAD)" +if [ "${RESOLVED_ETAHEN}" != "${ETAHEN_COMMIT}" ]; then + echo "ERROR: etaHEN revision mismatch" + echo "Expected: ${ETAHEN_COMMIT}" + echo "Actual: ${RESOLVED_ETAHEN}" + exit 1 +fi + +echo "[3/4] ps5-payload-dev/shsrv v0.20 source" +rm -rf "${DEPS}/shsrv" +git clone -q --branch v0.20 --depth 1 \ + https://github.com/ps5-payload-dev/shsrv.git "${DEPS}/shsrv" + +echo "[4/4] Record exact resolved revisions" +{ + echo "PS5 Payload SDK: v0.43" + echo "etaHEN: ${RESOLVED_ETAHEN} (${ETAHEN_VERSION})" + echo "shsrv: $(git -C "${DEPS}/shsrv" rev-parse HEAD)" +} > "${ROOT}/RESOLVED_BUILD_DEPENDENCIES.txt" + +cat "${ROOT}/RESOLVED_BUILD_DEPENDENCIES.txt"