Skip to content
Closed
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
106 changes: 74 additions & 32 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,65 +16,107 @@ jobs:
NUGET_PACKAGES: D:\nuget\packages

steps:
- name: Checkout
uses: actions/checkout@v6
with:
submodules: 'recursive'
- name: Checkout
uses: actions/checkout@v6
with:
submodules: "recursive"

- name: Test
run: dotnet test
- name: Test
run: dotnet test

- name: Build
run: dotnet publish RLBotCS -r win-x64
- name: Build
run: dotnet publish RLBotCS -r win-x64

- name: Upload build artifact
uses: actions/upload-artifact@v7
with:
name: RLBotServer-windows
path: ./**/publish/RLBotServer.exe
- name: Upload build artifact
uses: actions/upload-artifact@v7
with:
name: RLBotServer-windows
path: ./**/publish/RLBotServer.exe

build-linux:
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v6
with:
submodules: 'recursive'
- name: Checkout
uses: actions/checkout@v6
with:
submodules: "recursive"

- name: Test
run: dotnet test

- name: Formatting
run: |
dotnet tool restore
dotnet csharpier check .

- name: Build
run: dotnet publish RLBotCS -r linux-x64

- name: Upload build artifact
uses: actions/upload-artifact@v7
with:
name: RLBotServer-ubuntu
path: ./**/publish/RLBotServer

package-linux:
name: Package Linux
runs-on: ubuntu-latest
needs: [build-linux]

steps:
- name: Checkout
uses: actions/checkout@v6
with:
submodules: "recursive"
fetch-depth: 0

- name: Test
run: dotnet test
- uses: actions/download-artifact@v8
with:
merge-multiple: "true"

- name: Formatting
run: |
dotnet tool restore
dotnet csharpier check .
- name: Install packaging dependencies
run: |
sudo apt-get update
sudo apt-get install -y rpm

- name: Build
run: dotnet publish RLBotCS -r linux-x64
- name: Generate packages
run: |
chmod +x ./package-rlbot.sh
BIN_PATH="$(find . -type f -name RLBotServer | head -n 1)"
if [ -z "$BIN_PATH" ]; then
echo "RLBotServer binary not found in downloaded artifacts" >&2
exit 1
fi
chmod +x "$BIN_PATH"
OUTPUT_DIR=dist ./package-rlbot.sh "$BIN_PATH"

- name: Upload build artifact
uses: actions/upload-artifact@v7
with:
name: RLBotServer-ubuntu
path: ./**/publish/RLBotServer
- name: Upload package artifacts
uses: actions/upload-artifact@v7
with:
name: RLBotServer-linux-packages
path: dist/*

release:
name: Release
runs-on: ubuntu-latest
if: "startsWith(github.ref, 'refs/tags/')"
needs: [build-linux, build-windows]
needs: [build-linux, build-windows, package-linux]
permissions:
contents: write

steps:
- uses: actions/download-artifact@v8
with:
merge-multiple: "true"

- name: Publish to GitHub Releases
uses: softprops/action-gh-release@v2
with:
files: ./RLBotCS/**/publish/RLBotServer*
files: |
./RLBotCS/**/publish/RLBotServer*
./*.deb
./*.rpm
generate_release_notes: true
body: |
Pre-built binaries that allows bots to interface with Rocket League via the RLBot v5 spec
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,7 @@ dlldata.c
*.sln.iml

# FlatBuffers
FlatBuffer/
FlatBuffer/

# Potential build artifacts
dist/
244 changes: 244 additions & 0 deletions package-rlbot.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,244 @@
#!/usr/bin/env bash
set -euo pipefail

# package-rlbot.sh - Package RLBotServer binary for multiple Linux distributions
#
# Usage: ./package-rlbot.sh <binary_path> [distro_list]
#
# If no distribution list is provided, it defaults to packaging for ubuntu and fedora
# Supported distributions: ubuntu, fedora
#
# Examples:
# ./package-rlbot.sh ./RLBotServer ubuntu
# ./package-rlbot.sh ./RLBotServer # Defaults to ubuntu and fedora
#
# This script packages the RLBotServer binary for various Linux distributions,
# creating appropriate metadata and package structures.

DEFAULT_DISTROS=("ubuntu" "fedora")

usage() {
cat <<'EOF'
Usage: ./package-rlbot.sh <binary_path> [distro_list]

If no distribution list is provided, it defaults to packaging all supported distributions.
Supported distributions: ubuntu, fedora.

Examples:
./package-rlbot.sh ./RLBotServer ubuntu
./package-rlbot.sh ./RLBotServer # Defaults to ubuntu and fedora

Environment overrides:
OUTPUT_DIR Output directory for packages (default: ./dist)
EOF
}

require_cmd() {
if ! command -v "$1" >/dev/null 2>&1; then
echo "Missing required command: $1" >&2
return 1
fi
}

get_git_version() {
require_cmd git

local repo_root="$1"
local latest_tag

latest_tag="$(git -C "$repo_root" describe --tags --abbrev=0 2>/dev/null || true)"
if [[ -z "$latest_tag" ]]; then
echo "Unable to determine version: no git tags found in $repo_root" >&2
return 1
fi

echo "${latest_tag#v}"
}

normalize_rpm_version() {
local input="$1"

if [[ -z "$input" ]]; then
echo "RPM version is empty" >&2
return 1
fi

echo "${input//-/.}"
}

resolve_path() {
local input_path="$1"
local dir
dir="$(cd "$(dirname "$input_path")" && pwd)"
echo "${dir}/$(basename "$input_path")"
}

ensure_x86_64() {
local arch_raw="$1"
case "$arch_raw" in
x86_64|amd64)
return 0
;;
*)
echo "Unsupported architecture: ${arch_raw}. Only x86-64 is supported." >&2
return 1
;;
esac
}

package_deb() {
require_cmd dpkg-deb

local pkg_name="rlbotserver"
local pkg_dir="${tmp_root}/deb/${pkg_name}_${version}"
local deb_path="${out_dir}/${pkg_name}_${version}_${deb_arch}.deb"

rm -rf "$pkg_dir"
mkdir -p "$pkg_dir/DEBIAN" "$pkg_dir/usr/bin"

install -m 0755 "$binary_path" "$pkg_dir/usr/bin/$binary_name"

cat > "$pkg_dir/DEBIAN/control" <<EOF
Package: ${pkg_name}
Version: ${version}
Section: utils
Priority: optional
Architecture: ${deb_arch}
Maintainer: RLBot Contributors
Description: RLBotServer binary
RLBotServer is the backend server for RLBot v5, allowing custom bots and scripts to interface with Rocket League.
EOF

dpkg-deb --build "$pkg_dir" "$deb_path" >/dev/null
echo "Created ${deb_path}"
}

package_rpm() {
require_cmd rpmbuild
require_cmd tar

local pkg_name="rlbotserver"
local rpm_root="${tmp_root}/rpm"
local src_dir="${tmp_root}/${pkg_name}-${rpm_version}"
local spec_file="${rpm_root}/SPECS/${pkg_name}.spec"

mkdir -p "${rpm_root}"/{BUILD,RPMS,SOURCES,SPECS,SRPMS}
rm -rf "$src_dir"
mkdir -p "$src_dir"

install -m 0755 "$binary_path" "$src_dir/$binary_name"
tar -C "$tmp_root" -czf "$rpm_root/SOURCES/${pkg_name}-${rpm_version}.tar.gz" "${pkg_name}-${rpm_version}"

cat > "$spec_file" <<EOF
Name: ${pkg_name}
Version: ${rpm_version}
Release: 1%{?dist}
Summary: RLBotServer binary

License: MIT
BuildArch: ${rpm_arch}
Source0: %{name}-%{version}.tar.gz

%description
RLBotServer is the backend server for RLBot v5, allowing custom bots and scripts to interface with Rocket League.

%prep
%setup -q

%build

%install
mkdir -p %{buildroot}/usr/bin
install -m 0755 ${binary_name} %{buildroot}/usr/bin/${binary_name}

%files
/usr/bin/${binary_name}

%changelog
* $(date -u "+%a %b %d %Y") RLBot Contributors - ${version}-1
- Packaged RLBotServer binary
EOF

rpmbuild --define "_topdir ${rpm_root}" -bb "$spec_file" >/dev/null 2>&1

local rpm_file
rpm_file="$(find "$rpm_root/RPMS" -type f -name "*.rpm" | head -n 1)"
if [[ -z "$rpm_file" ]]; then
echo "RPM build failed: no package found in ${rpm_root}/RPMS" >&2
return 1
fi

cp "$rpm_file" "$out_dir/"
echo "Created ${out_dir}/$(basename "$rpm_file")"
}

main() {
if [[ ${1:-} == "-h" || ${1:-} == "--help" ]]; then
usage
exit 0
fi

if [[ $# -lt 1 ]]; then
usage
exit 1
fi

binary_path="$1"
shift

script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

if [[ $# -eq 0 ]]; then
distros=("${DEFAULT_DISTROS[@]}")
else
if [[ $# -eq 1 && "$1" == *","* ]]; then
IFS=',' read -r -a distros <<< "$1"
else
distros=("$@")
fi
fi

binary_path="$(resolve_path "$binary_path")"
if [[ ! -f "$binary_path" ]]; then
echo "Binary not found: $binary_path" >&2
exit 1
fi
if [[ ! -x "$binary_path" ]]; then
echo "Binary is not executable: $binary_path" >&2
exit 1
fi

binary_name="$(basename "$binary_path")"

version="$(get_git_version "$script_dir")"
rpm_version="$(normalize_rpm_version "$version")"
out_dir="${OUTPUT_DIR:-dist}"
mkdir -p "$out_dir"

arch_raw="$(uname -m)"
ensure_x86_64 "$arch_raw"
deb_arch="amd64"
rpm_arch="x86_64"

tmp_root="$(mktemp -d)"
trap 'rm -rf "$tmp_root"' EXIT

for distro in "${distros[@]}"; do
distro="${distro,,}"
case "$distro" in
ubuntu)
package_deb
;;
fedora)
package_rpm
;;
*)
echo "Unknown distribution: $distro" >&2
echo "Supported distributions: ubuntu, fedora" >&2
exit 1
;;
esac
done
}

main "$@"
Loading