mirror of
https://github.com/doukutsu-rs/doukutsu-rs.git
synced 2026-08-24 13:02:49 -07:00
Add CI for Switch port
This commit is contained in:
@@ -4,14 +4,13 @@ on:
|
||||
push:
|
||||
branches-ignore:
|
||||
- cpp-rewrite
|
||||
- horizon-os
|
||||
- refactor
|
||||
paths-ignore:
|
||||
- ".gitignore"
|
||||
- ".github/*"
|
||||
- "**.md"
|
||||
- "LICENSE"
|
||||
- "drshorizon/**"
|
||||
- "misc/**"
|
||||
- "res/**"
|
||||
workflow_dispatch:
|
||||
release:
|
||||
@@ -260,11 +259,87 @@ jobs:
|
||||
drsandroid/target
|
||||
key: android-cargo
|
||||
|
||||
build_horizon:
|
||||
name: Horizon build
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
RUSTSWITCH_IMAGE: "ghcr.io/doukutsu-rs/drshorizon-build-env:latest"
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
include:
|
||||
- name: Horizon
|
||||
os: ubuntu-latest
|
||||
channel: stable
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
- name: Restore cache
|
||||
uses: actions/cache/restore@v6
|
||||
with:
|
||||
path: |
|
||||
~/.cache
|
||||
~/.cargo
|
||||
drshorizon/target
|
||||
key: horizon-cargo
|
||||
|
||||
- name: Set version
|
||||
id: set_version
|
||||
run: |
|
||||
if [ "${{ github.ref_type }}" == "tag" ]; then
|
||||
echo "version=${{ github.ref_name }}" >> $GITHUB_OUTPUT
|
||||
echo "channel=stable" >> $GITHUB_OUTPUT
|
||||
elif [ "${{ github.ref_name }}" == "master" ]; then
|
||||
echo "version=${{ env.VERSION }}-$((${{ github.run_number }} + 654))" >> $GITHUB_OUTPUT
|
||||
echo "channel=nightly" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "version=${{ env.VERSION }}-${GITHUB_SHA:0:7}" >> $GITHUB_OUTPUT
|
||||
echo "channel=nightly" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
if [ -z "${{ steps.set_version.outputs.version }}" ]; then
|
||||
echo "version is not set"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
export DRS_BUILD_VERSION_OVERRIDE="${{ steps.set_version.outputs.version }}"
|
||||
export RUSTSWITCH_IMAGE="${{ env.RUSTSWITCH_IMAGE }}"
|
||||
|
||||
cd drshorizon
|
||||
./build.sh -r --ci --docker-mode compose
|
||||
|
||||
- name: Prepare artifact
|
||||
run: |
|
||||
mkdir release
|
||||
|
||||
# Artifacts generated during build in the container are owned by root,
|
||||
# so we cannot move the generated file as we do for other platforms
|
||||
cp drshorizon/target/aarch64-nintendo-switch/release/drshorizon.nro release/doukutsu-rs.nro
|
||||
cp LICENSE ./release
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: doukutsu-rs_horizon
|
||||
path: ./release/*
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Save cache
|
||||
if: ${{ github.ref_name == 'master' || github.ref_type == 'tag' }}
|
||||
uses: actions/cache/save@v6
|
||||
with:
|
||||
path: |
|
||||
~/.cache
|
||||
~/.cargo
|
||||
drshorizon/target
|
||||
key: horizon-cargo
|
||||
|
||||
update_metadata:
|
||||
name: Update metadata
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.ref_name == 'master' || github.ref_type == 'tag' }}
|
||||
needs: [build, build_android]
|
||||
needs: [build, build_android, build_horizon]
|
||||
permissions:
|
||||
contents: write
|
||||
env:
|
||||
@@ -390,6 +465,20 @@ jobs:
|
||||
node ./misc/ci/uploadBuild.js update --channel ${{ steps.set_version.outputs.channel }} --version "${{ steps.set_version.outputs.version }}" --platform android --arch universal --commit $GITHUB_SHA --file "temp-android/doukutsu-rs.apk"
|
||||
cp ./temp-android/doukutsu-rs.apk "./release-binaries/doukutsu-rs_android_${{ steps.set_version.outputs.version }}.universal.apk"
|
||||
|
||||
# Horizon build
|
||||
- name: Download Horizon artifact
|
||||
if: ${{ needs.build_horizon.result == 'success' }}
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: doukutsu-rs_horizon
|
||||
path: temp-horizon
|
||||
|
||||
- name: Process Horizon build
|
||||
if: ${{ needs.build_horizon.result == 'success' }}
|
||||
run: |
|
||||
node ./misc/ci/uploadBuild.js update --channel ${{ steps.set_version.outputs.channel }} --version "${{ steps.set_version.outputs.version }}" --platform horizon --arch arm64 --commit $GITHUB_SHA --file "temp-horizon/doukutsu-rs.nro" --experimental true
|
||||
cp ./temp-horizon/doukutsu-rs.nro "./release-binaries/doukutsu-rs_horizon_${{ steps.set_version.outputs.version }}.arm64.nro"
|
||||
|
||||
- name: Upload binaries to release
|
||||
uses: svenstaro/upload-release-action@v2
|
||||
if: ${{ github.ref_type == 'tag' }}
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
FROM devkitpro/devkita64:20260219
|
||||
|
||||
# We set the "maintainer" label just to override the value inherited from the devkitPro image
|
||||
LABEL maintainer="doukutsu-rs maintainers" \
|
||||
org.opencontainers.image.authors="doukutsu-rs maintainers" \
|
||||
org.opencontainers.image.description="Build environment for the Horizon port of doukutsu-rs." \
|
||||
org.opencontainers.image.source="https://github.com/doukutsu-rs/doukutsu-rs"
|
||||
|
||||
# Setup Rust environment vars
|
||||
ENV RUSTUP_HOME=/usr/local/rustup \
|
||||
CARGO_HOME=/usr/local/cargo \
|
||||
@@ -10,13 +16,11 @@ ENV RUSTUP_HOME=/usr/local/rustup \
|
||||
RUST_DEFAULT_TOOLCHAIN=nightly
|
||||
|
||||
# Install build dependencies
|
||||
RUN \
|
||||
apt update; \
|
||||
RUN apt update; \
|
||||
apt install -y clang libclang-dev zstd;
|
||||
|
||||
# Install Rust
|
||||
RUN \
|
||||
set -eux; \
|
||||
RUN set -eux; \
|
||||
curl --proto '=https' --tlsv1.2 -fSL https://sh.rustup.rs | sh -s -- --default-toolchain $RUST_DEFAULT_TOOLCHAIN --profile minimal -c rust-src -y; \
|
||||
chmod -R a+w $RUSTUP_HOME $CARGO_HOME; \
|
||||
rustup default $RUST_DEFAULT_TOOLCHAIN;
|
||||
@@ -26,7 +30,7 @@ RUN \
|
||||
curl -fSL https://github.com/doukutsu-rs/rust-hos/releases/download/${RUST_VERSION}-horizon/${RUST_VERSION}-switch_x86_64-unknown-linux-gnu.tar.zst | \
|
||||
tar -x --zstd -f - -C ${RUSTUP_HOME}/toolchains/;
|
||||
|
||||
# For testing local toolchains
|
||||
# For testing local toolchains (comment the previous `RUN` instruction)
|
||||
# COPY ${RUST_VERSION}-switch ${RUSTUP_HOME}/toolchains/${RUST_VERSION}-switch
|
||||
|
||||
WORKDIR /workspace/drshorizon
|
||||
|
||||
+48
-4
@@ -8,9 +8,12 @@ ld script and `.specs` taken from devkitPro (the linker script is modified).
|
||||
# Build
|
||||
More detailed build instructions can be found in the [docs](https://doukutsu-rs.gitbook.io/docs/modders-handbook/initial-setup-and-compiling/building-the-ports#nintendo-switch-horizon).
|
||||
|
||||
## Dependencies
|
||||
## Dependencies (for local build)
|
||||
> [!TIP]
|
||||
> If you're going to build the port in a Docker container, the only dependency is Docker itself. All the dependencies listed below are required for compiling the port on the host machine.
|
||||
|
||||
- Rust toolchain with the Switch patches ([link](https://github.com/doukutsu-rs/rust-hos/releases))
|
||||
- Rust nightly toolchain (the `nightly` channel). The `cargo` binary will be used from it, since the patched toolchain miss it. Any other toolchain, even if it's nightly (like `nightly-2025-10-24`), won't work
|
||||
- Rust nightly toolchain (the `nightly` channel). The `cargo` binary will be loaded from it, since the patched toolchain miss it. Any other toolchain, even if it's nightly (like `nightly-2025-10-24`), won't work
|
||||
- Switch toolchain by [devkitPro](https://devkitpro.org/wiki/Getting_Started#Setup) (install the `switch-dev` package)
|
||||
- `libclang-dev` (on Debian; for other distros, find a package that provides `libclang.so`)
|
||||
- Clang (it provides some header files, such as `stddef.h`)
|
||||
@@ -45,12 +48,53 @@ This will build the port in a Docker container. The cargo cache and project dire
|
||||
|
||||
If you have Docker Compose installed, the script will run it using config params from `composer.yaml`. The created container will be removed on exit.
|
||||
|
||||
Otherwise the script will build the container image with `docker build` and run it via `docker run`.
|
||||
Otherwise the script will build the container image with `docker build` and run it via `docker run`. If you want to use precompiled docker image, specify its name in the `RUSTSWITCH_IMAGE` environment variable (i.e. `ghcr.io/doukutsu-rs/drshorizon-build-env:latest`).
|
||||
|
||||
If you want to force build via Docker Compose, specify `--docker-mode`:
|
||||
```
|
||||
./build.sh --docker-mode compose
|
||||
```
|
||||
|
||||
# Notes for maintainers
|
||||
1. The dependency on Clang is caused by the `deko3d-sys` crate, which ignores the presence of GCC/glibc headers.
|
||||
2. The toolchain intended for use in a container should be built on a Debian Bookworm virtual machine, since this is the version used by the devkitPro container.
|
||||
2. The toolchain intended for use in a container should be built on a Debian Bookworm virtual machine, since this is the version used by the devkitPro image.
|
||||
|
||||
Building the toolchain on newer systems will result in the toolchain’s libraries being linked against a newer version of glibc than the one present in the container, which in turn will make it impossible to build the port using this toolchain, as it will crash with a segfault.
|
||||
|
||||
Attempting to build the toolchain inside the container results either in compilation errors or in the generation of artifacts that cannot be run/loaded properly (they crash with core dump).
|
||||
|
||||
## Maintaining Docker image
|
||||
Since the CI workflow for automatically building the Docker image and uploading it to the registry isn't configured yet, you'll need to do this manually.
|
||||
|
||||
### Versioning
|
||||
The Docker image version is independent of the version of doukutsu-rs and the Horizon port.
|
||||
|
||||
The **major version number** should be incremented only if the introduced changes make it impossible to compile previous versions with the updated image.
|
||||
|
||||
The **minor version number** should be incremented when updating container dependencies (the base image or a patched toolset), but previous versions of the port should still be compilable.
|
||||
|
||||
The **patch number** may be incremented when some metadata is changed or when other minor changes are made.
|
||||
|
||||
### Building image
|
||||
1. Ensure that [Docker Buildx plugin](https://github.com/docker/buildx#installing) is installed.
|
||||
2. Enter directory where the Dockerfile is located (currently it's `drshorizon`).
|
||||
3. Build the image and link it to the `latest` tag (replace `${VERSION}` with the new version of the image):
|
||||
```
|
||||
docker buildx build --provenance=false \
|
||||
-t ghcr.io/doukutsu-rs/drshorizon-build-env:latest \
|
||||
-t ghcr.io/doukutsu-rs/drshorizon-build-env:${VERSION} .
|
||||
```
|
||||
|
||||
The `--provencance=false` argument disables generation of provenance attestation, since this attestation generates useless `unknown/unknown` platform on Github Packages page of the image.
|
||||
|
||||
### Pushing image to registry
|
||||
1. Generate personal access token (classic) with at least `write:packages` permission.
|
||||
2. Authenticate into the Github Containers registry with your Github username and the access token:
|
||||
```
|
||||
docker login ghcr.io
|
||||
```
|
||||
3. Push the image (replace `${VERSION}` with the new version of the image):
|
||||
```
|
||||
docker push ghcr.io/doukutsu-rs/drshorizon-build-env:${VERSION}
|
||||
docker push ghcr.io/doukutsu-rs/drshorizon-build-env:latest
|
||||
```
|
||||
|
||||
+79
-10
@@ -3,12 +3,24 @@
|
||||
cd "$(dirname "$0")" || exit
|
||||
set -e
|
||||
|
||||
# In CI environments the $TERM var may be not set, but it's required for `tput`
|
||||
if [ -z $TERM ] || [ "${TERM}" = "dumb" ]; then
|
||||
export TERM=xterm
|
||||
fi
|
||||
|
||||
# Base version (in the major.minor.patch format, without any suffixes)
|
||||
BASE_VERSION="1.0.0"
|
||||
# Strip suffix after -
|
||||
VERSION=${DRS_BUILD_VERSION_OVERRIDE%%-*}
|
||||
VERSION=${VERSION:-BASE_VERSION}
|
||||
|
||||
DARK_GRAY=$(tput setaf 8)
|
||||
YELLOW=$(tput bold)$(tput setaf 3)
|
||||
RESET=$(tput sgr0)
|
||||
DIVIDER="===================="
|
||||
|
||||
function message() {
|
||||
echo "${DARK_GRAY}----${RESET} ${YELLOW}$*${RESET}"
|
||||
echo "${DARK_GRAY}----${RESET} ${YELLOW}$*${RESET}"
|
||||
}
|
||||
|
||||
function is_bin_avail() {
|
||||
@@ -22,20 +34,28 @@ function is_bin_avail() {
|
||||
set -e
|
||||
}
|
||||
|
||||
|
||||
|
||||
# Parse arguments
|
||||
BUILD_MODE="debug"
|
||||
CARGO_FLAGS=""
|
||||
FLAGS=""
|
||||
IS_CI=false
|
||||
IS_DOCKER=false
|
||||
DOCKER_MODE="auto"
|
||||
|
||||
# Check if Docker Compose is available
|
||||
IS_COMPOSE_AVAIL=$(is_bin_avail "docker-compose")
|
||||
|
||||
function print_help() {
|
||||
echo -e "$(basename "$0") [-h] [-r] [-V] [<cargo args>...]\n"
|
||||
echo -e "$(basename $BASH_SOURCE) [-h] [-r] [-V] [<cargo args>...]\n"
|
||||
echo -e "Build script for the doukutsu-rs Horizon port.\n"
|
||||
echo "Arguments:"
|
||||
echo " --ci Mark that the script is running in CI environment."
|
||||
echo " --docker Run build in the Docker container."
|
||||
echo " --docker-mode Run build via a specific tool: 'docker', 'compose', or 'auto'."
|
||||
echo " Default value: 'auto'."
|
||||
echo ""
|
||||
echo " -r, --release Build in release mode."
|
||||
echo " -V, --version Print version of build tools."
|
||||
echo " -?, -h, --help Prints help message."
|
||||
@@ -44,10 +64,21 @@ function print_help() {
|
||||
function print_mode() {
|
||||
echo "Build mode: ${BUILD_MODE}"
|
||||
if $IS_DOCKER && $IS_COMPOSE_AVAIL; then
|
||||
echo -e "Running via Docker Compose\n"
|
||||
echo -n "Running via Docker Compose"
|
||||
elif $IS_DOCKER; then
|
||||
echo -e "Running via Docker\n"
|
||||
echo -n "Running via Docker"
|
||||
fi
|
||||
|
||||
if [ "$DOCKER_MODE" != "auto" ]; then
|
||||
echo -n " (forcely)"
|
||||
fi
|
||||
echo -n -e "\n"
|
||||
|
||||
if $IS_CI; then
|
||||
echo -e "Environment: CI\n"
|
||||
fi
|
||||
|
||||
echo $DIVIDER
|
||||
}
|
||||
|
||||
function print_version() {
|
||||
@@ -72,7 +103,7 @@ function print_version() {
|
||||
echo -e "\n===DOCKER==="
|
||||
docker --version
|
||||
|
||||
if $(is_bin_avail "docker-compose"); then
|
||||
if $IS_COMPOSE_AVAIL; then
|
||||
docker-compose --version
|
||||
fi
|
||||
fi
|
||||
@@ -83,22 +114,58 @@ function run_docker() {
|
||||
if $IS_COMPOSE_AVAIL; then
|
||||
docker compose run --rm --remove-orphans rust-switch ./build.sh $FLAGS
|
||||
else
|
||||
docker build -t rust-switch .
|
||||
if [ -z $RUSTSWITCH_IMAGE ]; then
|
||||
echo "Building Docker image from the scratch"
|
||||
|
||||
RUSTSWITCH_IMAGE=rust-switch
|
||||
docker build -t $RUSTSWITCH_IMAGE .
|
||||
else
|
||||
echo "Using prebuilt docker image: $RUSTSWITCH_IMAGE"
|
||||
fi
|
||||
|
||||
PROJECT_DIR="$(dirname $PWD)"
|
||||
docker run -it \
|
||||
-v "../:/workspace" \
|
||||
-v "${PROJECT_DIR}":/workspace \
|
||||
-v "${CARGO_HOME:-${HOME}/.cargo}/registry:/usr/local/cargo/registry" \
|
||||
-v "${CARGO_HOME:-${HOME}/.cargo}/git:/usr/local/cargo/git" \
|
||||
rust-switch \
|
||||
./build.sh $FLAGS
|
||||
$RUSTSWITCH_IMAGE \
|
||||
$BASH_SOURCE \
|
||||
$FLAGS
|
||||
fi
|
||||
}
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
--ci)
|
||||
IS_CI=true
|
||||
shift
|
||||
;;
|
||||
--docker)
|
||||
IS_DOCKER=true
|
||||
shift
|
||||
;;
|
||||
--docker-mode)
|
||||
case $2 in
|
||||
auto)
|
||||
;;
|
||||
compose)
|
||||
DOCKER_MODE="compose"
|
||||
IS_DOCKER=true
|
||||
IS_COMPOSE_AVAIL=true
|
||||
;;
|
||||
docker)
|
||||
DOCKER_MODE="docker"
|
||||
IS_DOCKER=true
|
||||
IS_COMPOSE_AVAIL=false
|
||||
;;
|
||||
*)
|
||||
echo "Invalid value provided for argument \"--docker-mode\": $2" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
-r|--release)
|
||||
BUILD_MODE="release"
|
||||
CARGO_FLAGS+=" -r"
|
||||
@@ -127,6 +194,8 @@ if $IS_DOCKER; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
|
||||
|
||||
# Building the port
|
||||
message "Compiling shaders..."
|
||||
uam -s vert -o ../src/framework/shaders/deko3d/vertex_basic.dksh ../src/framework/shaders/deko3d/vertex_basic.glsl
|
||||
@@ -140,7 +209,7 @@ rm -f target/aarch64-nintendo-switch/$BUILD_MODE/drshorizon.nro
|
||||
rm -f target/aarch64-nintendo-switch/$BUILD_MODE/drshorizon.nacp
|
||||
|
||||
message "Creating NACP..."
|
||||
nacptool --create 'doukutsu-rs' 'doukutsu-rs contributors' '1.0.0' target/aarch64-nintendo-switch/$BUILD_MODE/drshorizon.nacp
|
||||
nacptool --create 'doukutsu-rs' 'doukutsu-rs contributors' $VERSION target/aarch64-nintendo-switch/$BUILD_MODE/drshorizon.nacp
|
||||
|
||||
message "Running elf2nro..."
|
||||
elf2nro target/aarch64-nintendo-switch/$BUILD_MODE/drshorizon.elf target/aarch64-nintendo-switch/$BUILD_MODE/drshorizon.nro \
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
services:
|
||||
rust-switch:
|
||||
image: ${RUSTSWITCH_IMAGE:-ghcr.io/doukutsu-rs/drshorizon-build-env:1.0.0}
|
||||
build:
|
||||
context: .
|
||||
|
||||
|
||||
Reference in New Issue
Block a user