Skip to content
Open
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
19 changes: 17 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,22 @@
FROM ubuntu:20.04
FROM ubuntu:24.04

RUN apt-get update
RUN apt-get install --yes bzip2 wget libxext6 libllvm6.0 mesa-utils unzip rsync
RUN apt-get install --yes bzip2 wget libxext6 mesa-utils unzip rsync jq tree openjdk-21-jdk

# Android SDK location inside container
ENV ANDROID_SDK_ROOT=/opt/android-sdk
ENV ANDROID_HOME=/opt/android-sdk
ENV PATH="${ANDROID_SDK_ROOT}/cmdline-tools/latest/bin:${ANDROID_SDK_ROOT}/platform-tools:${PATH}"

# Install Android cmdline tools (sdkmanager) then required SDK packages
RUN mkdir -p ${ANDROID_SDK_ROOT}/cmdline-tools \
&& cd /tmp \
&& wget -q -O cmdline-tools.zip https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip \
&& unzip -q cmdline-tools.zip \
&& mv cmdline-tools ${ANDROID_SDK_ROOT}/cmdline-tools/latest \
&& rm -f cmdline-tools.zip \
&& yes | sdkmanager --licenses >/dev/null \
&& sdkmanager --install "platform-tools"

COPY build.sh /build.sh

Expand Down
32 changes: 28 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@ This GitHub action allows you to make distributable builds of a Ren'Py visual no
- name: Build VN project
uses: ProjectAliceDev/renpy-build-action@master
with:
sdk-version: '6.99.12.4'
sdk-version: '8.5.2'
project-dir: '.'
package: 'linux win mac'
add-steam-lib: false
output-dir: './dist'
env:
SDL_AUDIODRIVER: dummy
SDL_VIDEODRIVER: dummy
Expand All @@ -25,11 +28,32 @@ This GitHub action allows you to make distributable builds of a Ren'Py visual no

**Optional Parameters:**

- `package`: Specific package to build for. Must be one of the following: `pc`, `win`, `mac`, `linux`, `market`, `web`, `android` or an array of options such as `['win','mac','linux']` Will build for all packages if value is not supported.
- `package`: Specific package(s) to build for. Supported values: `pc`, `win`, `mac`, `linux`, `market`, `web`, `android`.
You can provide multiple targets as a space-separated string (e.g. `linux win mac`). If omitted, it will build the default distribution.

- `add-steam-lib`: Whether to include Steam lib. This is necessary if you want your build to work with Steam achievements. Defaults to `false`.

- `output-dir`: The directory where the built files will be placed. Defaults to `./dist`.

### Outputs

- `dir`: The directory where the files were built to.
- `version`: The name of the project and version that was built. Often useful in cases where you don't know the version.
- `dir`: The directory where the files were built to (the `output-dir`).
- `version`: The project version detected from Ren'Py (from `build.version` or `config.version`).

### Android Example

This action automatically installs the Android SDK and all required packages for building Android apps, so you don't need to set up java JDK or Android SDK manually.

```yml
- name: Build Android APK
id: build
uses: ProjectAliceDev/renpy-build-action@master
with:
sdk-version: '8.5.2'
package: android
env:
SDL_AUDIODRIVER: dummy
SDL_VIDEODRIVER: dummy
```

> :warning: In order to sign the Android APK, you must provide an `android.keystore` file in the project directory. The keystore file should be stored in GitHub Secrets and copied to a file in the project directory before building. See: https://www.renpy.org/doc/html/android.html
5 changes: 5 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ inputs:
required: false
default: false
type: boolean
output-dir:
description: "The directory where the built files will be placed"
required: false
default: './dist'
outputs:
dir:
description: "The directory where the distributed files exist"
Expand All @@ -32,6 +36,7 @@ runs:
- ${{ inputs.project-dir }}
- ${{ inputs.package }}
- ${{ inputs.add-steam-lib }}
- ${{ inputs.output-dir }}
branding:
color: 'gray-dark'
icon: 'archive'
179 changes: 108 additions & 71 deletions build.sh
Original file line number Diff line number Diff line change
@@ -1,94 +1,131 @@
#!/bin/sh
#!/usr/bin/env bash

sdk_version="$1"
project_dir="$2"
targets="$3"
add_steam_lib="$4"
output_dir="$5"

sdk_name="renpy-$sdk_version-sdk"
renpy_dir="../renpy"
renpy_sh="$renpy_dir/renpy.sh"
renpy_launcher="$renpy_dir/launcher"

sdk_name=renpy-$1-sdk
echo "Downloading the specified SDK (${sdk_name})..."
wget -q https://www.renpy.org/dl/$1/${sdk_name}.tar.bz2
clear
wget -q "https://www.renpy.org/dl/$sdk_version/${sdk_name}.tar.bz2"

echo "Downloaded SDK version (${sdk_name})."
echo "Setting up the specified SDK (${sdk_name})..."
tar -xf ./${sdk_name}.tar.bz2
rm ./${sdk_name}.tar.bz2
mv ./${sdk_name} ../renpy
mv ./${sdk_name} "$renpy_dir"
echo "Setup SDK version (${sdk_name})."

# Get the project version by using renpy's json-dump command
tmp="$(mktemp)"
"$renpy_sh" --json-dump "$tmp" "$project_dir" quit >/dev/null
project_version="$(jq -r '.build.version // .config.version // empty' "$tmp")"
rm -f "$tmp"

# used for steam and web
# used for steam, web, rapt
install_lib() {
version="$1"
lib="$2"
name="renpy-$version-$lib"

echo "Downloading ${lib} lib (${name})..."
wget -q "https://www.renpy.org/dl/${version}/${name}.zip"
clear

echo "Downloaded ${lib} lib (${name})..."
echo "Adding Steam lib to Renpy"
unzip -qq ./${name} -d ${name}
rsync -a ${name}/ ../renpy
rm -rf ${name} ${name}.zip
}
local lib="$1"
local name="renpy-$sdk_version-$lib"

if [ $4 = "true" ]; then
install_lib "$1" steam
fi
echo "Downloading '${lib}' lib (${name})..."
wget -q "https://www.renpy.org/dl/${sdk_version}/${name}.zip"

# Note: This will be checked regardless of the version of Ren'Py. Caution is
# advised.
if [ -d "$2/old-game" ]; then
echo "old-game directory detected."
if [ -z "$(ls -A "$2/old-game")" ]; then
echo "ERROR: old-game is empty. This will cause incompatibility issues."
echo "For more information on how the old-game directory works and why"
echo "this directory should not be empty, please refer to the documentation"
echo "at: https://www.renpy.org/doc/html/build.html#old-game."
exit 1
fi
fi
echo "Adding '${lib}' lib to Renpy..."
unzip -qq "./${name}.zip" -d "${name}"
rsync -a "${name}/" "$renpy_dir"
rm -rf "${name}" "${name}.zip"
echo "Added '${lib}' lib (${name})..."
}

if [[ "$(declare -p -- "$3")" == "declare -a "* ]]; then
for i in "${3[@]}"
do
if [ $i == 'android' ]; then
COMMAND="../renpy/renpy.sh ../renpy/launcher android_build $2"
elif [ $i == 'web' ]; then
install_lib "$1" web
COMMAND="../renpy/renpy.sh ../renpy/launcher web_build $2"
else
COMMAND="../renpy/renpy.sh ../renpy/launcher distribute --package $i $2"
fi
echo "Building $i"
if $COMMAND; then
built_dir=$(ls | grep '\-dists')
echo dir=$built_dir >> $GITHUB_OUTPUT
echo version=${built_dir%'-dists'} >> $GITHUB_OUTPUT
else
return 1
fi
done
else
case $3 in
# Builds a Ren'Py distribution for a target platform
#
# Args:
# $1: Target platform (pc|win|mac|linux|market|web|android). Default: All.
#
# Outputs:
# Writes `dir` and `version` to $GITHUB_OUTPUT on success
build_platform() {
local target="$1"
local COMMAND=("$renpy_sh" "$renpy_launcher")

case "$target" in
pc|win|mac|linux|market)
COMMAND="../renpy/renpy.sh ../renpy/launcher distribute --package $3 $2"
COMMAND+=(distribute --package "$target" "$project_dir")
;;
web)
install_lib "$1" web
COMMAND="../renpy/renpy.sh ../renpy/launcher web_build $2"
install_lib web
COMMAND+=(web_build "$project_dir")
;;
android)
COMMAND="../renpy/renpy.sh ../renpy/launcher android_build $2"
install_lib rapt
echo "${ANDROID_SDK_ROOT}" > $renpy_dir/rapt/sdk.txt
COMMAND+=(android_build "$project_dir")
;;
*)
COMMAND="../renpy/renpy.sh ../renpy/launcher distribute $2"
COMMAND+=(distribute "$project_dir")
;;
esac

echo "Building the project at $2..."
if $COMMAND; then
built_dir=$(ls | grep '\-dists')
echo dir=$built_dir >> $GITHUB_OUTPUT
echo version=${built_dir%'-dists'} >> $GITHUB_OUTPUT
else
return 1

echo "Building the project for platform '$target' at '$project_dir'..."
"${COMMAND[@]}"
}

# Moves compiled distribution files to a single, pre-defined location
#
# Args:
# $1: Output folder
#
# Outputs:
# Writes `dir` and `version` to $GITHUB_OUTPUT
collect_distributions() {
local output_dir="$1"
local built_dir="$(find . -maxdepth 1 -type d -name '*-dists' -print -quit || true)"

mkdir -p "$output_dir"

if [[ -n "$built_dir" ]]; then
rsync -a --remove-source-files "$built_dir/" "$output_dir/"
rmdir "$built_dir" 2>/dev/null || true
fi

if [[ -d "$renpy_dir/rapt/bin/" ]]; then
rsync -a -m --remove-source-files \
--include='*/' \
--include='*-release.apk' \
--exclude='*' \
"$renpy_dir/rapt/bin/" "$output_dir/"
fi

echo "dir=$output_dir" >> $GITHUB_OUTPUT
echo "version=$project_version" >> $GITHUB_OUTPUT
}

if [ "$add_steam_lib" = "true" ]; then
install_lib steam
fi

# Note: This will be checked regardless of the version of Ren'Py. Caution is advised.
if [ -d "$project_dir/old-game" ]; then
echo "old-game directory detected."
if [ -z "$(ls -A "$project_dir/old-game")" ]; then
echo "ERROR: old-game is empty. This will cause incompatibility issues."
echo "For more information on how the old-game directory works and why"
echo "this directory should not be empty, please refer to the documentation"
echo "at: https://www.renpy.org/doc/html/build.html#old-game."
exit 1
fi
fi

# Split $targets into an array of target platforms
[[ -n ${targets} ]] && read -r -a target_platforms <<<"$targets" || target_platforms=("all")

# Build for listed platforms
for i in "${target_platforms[@]}"; do
build_platform "$i"
done

collect_distributions "$output_dir"