Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/actionlint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
self-hosted-runner:
labels:
- blacksmith-2vcpu-ubuntu-2404
- blacksmith-4vcpu-ubuntu-2404
109 changes: 109 additions & 0 deletions .github/workflows/switch-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
name: Switch build and release

on:
push:
branches:
- main
pull_request:
workflow_dispatch:

permissions:
contents: read

concurrency:
group: switch-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
version:
name: Resolve next release version
runs-on: blacksmith-2vcpu-ubuntu-2404
outputs:
version: ${{ steps.release.outputs.version }}
steps:
- name: Check out source
uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262

- name: Increment latest GitHub release
id: release
shell: bash
env:
GH_TOKEN: ${{ github.token }}
run: |
existing_tag="$(
gh api --paginate "repos/$GITHUB_REPOSITORY/releases?per_page=100" \
--jq ".[] | select(.draft == false and .prerelease == false and .target_commitish == \"$GITHUB_SHA\") | .tag_name" \
| head -n 1
)"

if [[ "$existing_tag" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
version="${existing_tag#v}"
else
latest_tag="$(gh api "repos/$GITHUB_REPOSITORY/releases/latest" --jq .tag_name 2>/dev/null || printf 'v0.0.0')"
version="$(bash scripts/next-release-version.sh "$latest_tag")"
Comment thread
capy-ai[bot] marked this conversation as resolved.
fi

echo "version=$version" >> "$GITHUB_OUTPUT"
echo "Building OpenNOW Switch v$version"

build:
name: Build Switch NRO
needs: version
runs-on: blacksmith-4vcpu-ubuntu-2404
Comment thread
capy-ai[bot] marked this conversation as resolved.
container: devkitpro/devkita64@sha256:1fc388c3a0d34bd2045a6dadcb1020e069d5f876a187fd705de14b4440c00282
outputs:
version: ${{ needs.version.outputs.version }}
steps:
- name: Check out source
uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262

- name: Install generator dependencies
run: |
apt-get update -qq
apt-get install -y --no-install-recommends python3-jinja2 python3-jsonschema

- name: Build NRO
env:
OPENNOW_BUILD_JOBS: "4"
OPENNOW_VERSION: ${{ needs.version.outputs.version }}
run: bash scripts/build-switch-msys2.sh

- name: Package release files
run: bash scripts/package-release.sh "${{ needs.version.outputs.version }}"

- name: Upload build artifact
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
with:
name: SwitchNOW-${{ needs.version.outputs.version }}-${{ github.sha }}
path: |
dist/SwitchNOW-${{ needs.version.outputs.version }}.nro
dist/SwitchNOW-${{ needs.version.outputs.version }}.zip
if-no-files-found: error

release:
name: Publish GitHub release
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
needs:
- version
- build
runs-on: blacksmith-2vcpu-ubuntu-2404
permissions:
contents: write
steps:
- name: Download build artifact
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093
with:
name: SwitchNOW-${{ needs.build.outputs.version }}-${{ github.sha }}
path: dist

- name: Publish release with generated notes
uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65
with:
tag_name: v${{ needs.version.outputs.version }}
name: OpenNOW Switch v${{ needs.version.outputs.version }}
target_commitish: ${{ github.sha }}
generate_release_notes: true
fail_on_unmatched_files: true
files: |
dist/SwitchNOW-${{ needs.build.outputs.version }}.nro
dist/SwitchNOW-${{ needs.build.outputs.version }}.zip
16 changes: 13 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ set(CMAKE_TOOLCHAIN_FILE ${DEVKITPRO}/cmake/Switch.cmake CACHE FILEPATH "devkitP

project(SwitchNOW LANGUAGES C CXX)

set(OPENNOW_VERSION "0.0.6" CACHE STRING "OpenNOW application version")
if (NOT OPENNOW_VERSION MATCHES "^[0-9]+\\.[0-9]+\\.[0-9]+$")
message(FATAL_ERROR "OPENNOW_VERSION must use major.minor.patch format")
endif ()

set(PLATFORM_SWITCH ON)
# One Deko3D application supports both NVDEC zero-copy and software-decoded
# YUV uploads. Decoder selection is a runtime setting rather than a build type.
Expand All @@ -33,7 +38,7 @@ pkg_check_modules(JANSSON REQUIRED IMPORTED_TARGET jansson)
add_subdirectory(extern/borealis/library)
add_subdirectory(extern/libpeer)

target_include_directories(borealis PUBLIC ${DEVKITPRO}/portlibs/switch/include)
target_include_directories(borealis SYSTEM AFTER PUBLIC ${DEVKITPRO}/portlibs/switch/include)

file(GLOB_RECURSE APP_SOURCES CONFIGURE_DEPENDS
app/src/*.cpp
Expand Down Expand Up @@ -67,7 +72,12 @@ target_link_directories(${PROJECT_NAME}
${CMAKE_CURRENT_SOURCE_DIR}/extern/ffmpeg/lib
)

target_compile_definitions(${PROJECT_NAME} PRIVATE PLATFORM_SWITCH __SWITCH__ HAS_SOCKLEN_T=1)
target_compile_definitions(${PROJECT_NAME} PRIVATE
PLATFORM_SWITCH
__SWITCH__
HAS_SOCKLEN_T=1
OPENNOW_APP_VERSION="${OPENNOW_VERSION}"
)
if (PLATFORM_SWITCH)
target_compile_definitions(${PROJECT_NAME} PRIVATE USE_DK_RENDERER BOREALIS_USE_DEKO3D OPENNOW_ENABLE_NVDEC)
find_program(NX_UAM_EXE NAMES uam HINTS "${DEVKITPRO}/tools/bin")
Expand Down Expand Up @@ -122,7 +132,7 @@ target_link_libraries(${PROJECT_NAME}
)

set(PROJECT_AUTHOR "OpenCloudGaming")
set(PROJECT_VERSION_STRING "0.0.6")
set(PROJECT_VERSION_STRING "${OPENNOW_VERSION}")
set(PROJECT_TITLEID "05004F4E4F575358")
set(PROJECT_ICON ${CMAKE_CURRENT_SOURCE_DIR}/resources/icon/icon.jpg)
set(PROJECT_ROMFS_DIR ${CMAKE_BINARY_DIR}/romfs)
Expand Down
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,17 @@ Create a release archive with:
.\scripts\package-release.ps1 -Version 0.0.6
```

On Linux or in CI, use the equivalent shell entry point:

```bash
bash scripts/package-release.sh 0.0.6
```

After a change reaches `main`, the Blacksmith release workflow increments the
patch version from the latest GitHub release, embeds it in the app and NRO
metadata, publishes both files, and generates notes from the changes since the
previous release. Pull requests run the same build without publishing.

## Repository layout

```text
Expand Down
6 changes: 5 additions & 1 deletion app/src/app_version.hpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
#pragma once

#ifndef OPENNOW_APP_VERSION
#define OPENNOW_APP_VERSION "0.0.6"
#endif

namespace opennow
{

inline constexpr const char* kAppVersion = "0.0.6";
inline constexpr const char* kAppVersion = OPENNOW_APP_VERSION;

} // namespace opennow
4 changes: 3 additions & 1 deletion scripts/build-switch-msys2.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ detect_build_jobs() {
}

opennow_build_jobs="${OPENNOW_BUILD_JOBS:-$(detect_build_jobs)}"
opennow_version="${OPENNOW_VERSION:-$(bash scripts/read-version.sh)}"

cmake -B build/switch -G Ninja
cmake -B build/switch -G Ninja -DOPENNOW_VERSION="$opennow_version"
cmake --build build/switch --target cjson mbedtls srtp2 usrsctp -j"$opennow_build_jobs"
cmake --build build/switch --target SwitchNOW.nro -j"$opennow_build_jobs"

printf '\nBuilt: %s\n' "$(pwd)/build/switch/SwitchNOW.nro"
18 changes: 18 additions & 0 deletions scripts/next-release-version.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/usr/bin/env bash
set -euo pipefail

if [[ $# -ne 1 ]]; then
printf 'Usage: %s <latest-release-tag>\n' "$0" >&2
exit 2
fi

latest_tag="$1"
if [[ ! "$latest_tag" =~ ^v([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]; then
printf 'Latest release tag is not a semantic version: %s\n' "$latest_tag" >&2
exit 1
fi

printf '%s.%s.%s\n' \
"$((10#${BASH_REMATCH[1]}))" \
"$((10#${BASH_REMATCH[2]}))" \
"$((10#${BASH_REMATCH[3]} + 1))"
63 changes: 63 additions & 0 deletions scripts/package-release.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#!/usr/bin/env bash
set -euo pipefail

if [[ $# -lt 1 || $# -gt 2 ]]; then
printf 'Usage: %s <version> [build-directory]\n' "$0" >&2
exit 2
fi

version="$1"
build_directory="${2:-switch}"

if [[ ! "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+([.-][0-9A-Za-z.-]+)?$ ]]; then
printf 'Invalid release version: %s\n' "$version" >&2
exit 2
fi

repo="$(cd "$(dirname "$0")/.." && pwd)"
nro="$repo/build/$build_directory/SwitchNOW.nro"

if [[ ! -f "$nro" ]]; then
printf 'Missing build artifact: %s. Run the Switch build first.\n' "$nro" >&2
exit 1
fi

dist="$repo/dist"
package_name="SwitchNOW-$version"
package_root="$dist/$package_name"
switch_directory="$package_root/switch/SwitchNOW"
versioned_nro="$dist/$package_name.nro"
zip_path="$dist/$package_name.zip"

rm -rf "$package_root"
rm -f "$versioned_nro" "$zip_path"
mkdir -p "$switch_directory"

cp "$nro" "$switch_directory/SwitchNOW.nro"
cp "$nro" "$versioned_nro"
cp "$repo/resources/icon/icon.jpg" "$switch_directory/icon.jpg"
cp "$repo/resources/icon/icon.png" "$switch_directory/icon.png"
cp "$repo/README.md" "$package_root/README.md"

cat > "$package_root/INSTALL.txt" <<EOF
SwitchNOW $version

Install:
1. Copy the switch folder from this package to the root of the SD card.
2. Launch Homebrew Menu with title override/application mode.
3. Start SwitchNOW from hbmenu.

Included:
- switch/SwitchNOW/SwitchNOW.nro
- switch/SwitchNOW/icon.jpg
- switch/SwitchNOW/icon.png
- README.md
EOF

(
cd "$package_root"
zip -qr "$zip_path" switch README.md INSTALL.txt
)

printf 'Packaged: %s\n' "$zip_path"
printf 'Versioned NRO: %s\n' "$versioned_nro"
20 changes: 20 additions & 0 deletions scripts/read-version.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/usr/bin/env bash
set -euo pipefail

cd "$(dirname "$0")/.."

header_version="$(sed -n 's/^#define OPENNOW_APP_VERSION "\([^"]*\)"$/\1/p' app/src/app_version.hpp)"
cmake_version="$(sed -n 's/set(OPENNOW_VERSION "\([^"]*\)" CACHE.*/\1/p' CMakeLists.txt)"

if [[ -z "$header_version" || -z "$cmake_version" ]]; then
printf 'Unable to read the application version from app_version.hpp and CMakeLists.txt.\n' >&2
exit 1
fi

if [[ "$header_version" != "$cmake_version" ]]; then
printf 'Version mismatch: app_version.hpp has %s, CMakeLists.txt has %s.\n' \
"$header_version" "$cmake_version" >&2
exit 1
fi

printf '%s\n' "$header_version"
Loading