Skip to content

Commit 7b1a363

Browse files
Implemented Release Workflow (#21)
* Created Release Workflow * Fixed secret
1 parent b3f8052 commit 7b1a363

File tree

5 files changed

+371
-0
lines changed

5 files changed

+371
-0
lines changed
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
name: Prepare for Release
2+
on:
3+
workflow_dispatch:
4+
inputs:
5+
name:
6+
description: "Release name"
7+
required: true
8+
default: "ShinRyuModManager-CE 1.0.0"
9+
tag:
10+
description: "Tag for the release (example: 1.2.3)"
11+
required: true
12+
default: "1.0.0"
13+
updater_version:
14+
description: "Version for RyuUpdater (example: 1.2.3)"
15+
required: true
16+
default: "1.0.0"
17+
18+
jobs:
19+
release:
20+
runs-on: ubuntu-latest
21+
permissions: write-all
22+
23+
steps:
24+
- name: Checkout Repo
25+
uses: actions/checkout@v4
26+
27+
- name: Checkout AppCast Repo
28+
uses: actions/checkout@v4
29+
with:
30+
repository: 'TheTrueColonel/SRMM-AppCast'
31+
token: '${{ secrets.SRMM_APPCAST_TOKEN }}'
32+
path: AppcastRepo
33+
34+
- name: Install .NET SDK
35+
uses: actions/setup-dotnet@v4
36+
with:
37+
dotnet-version: 10.0.x
38+
39+
- name: Install Netsparkle Tool
40+
run: dotnet tool install --global NetSparkleUpdater.Tools.AppCastGenerator
41+
42+
- name: Add .NET tools to PATH
43+
run: echo "$HOME/.dotnet/tools" >> $GITHUB_PATH
44+
45+
- name: Create Draft Release
46+
id: create_release
47+
uses: actions/create-release@v1
48+
env:
49+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
50+
with:
51+
tag_name: ${{ github.event.inputs.tag }}
52+
release_name: ${{ github.event.inputs.name }}
53+
draft: true
54+
prerelease: false
55+
56+
- name: Run Scripts
57+
run: |
58+
./Scripts/build.sh
59+
./Scripts/package.sh -s ${{ github.event.inputs.tag }} -u ${{ github.event.inputs.updater_version }}
60+
env:
61+
SPARKLE_PRIVATE_KEY: ${{ secrets.SPARKLE_PRIVATE_KEY }}
62+
SPARKLE_PUBLIC_KEY: ${{ secrets.SPARKLE_PUBLIC_KEY }}
63+
64+
- name: Upload SRMM Release Assets
65+
env:
66+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
67+
UPLOAD_URL: ${{ steps.create_release.outputs.upload_url }}
68+
run: |
69+
for file in ${{ github.workspace }}/dist/srmm/out/*; do
70+
name=$(basename "$file")
71+
mime=$(file --brief --mime-type "$file")
72+
echo "Uploading $name ($mime)"
73+
curl \
74+
-X POST \
75+
-H "Authorization: Bearer $GITHUB_TOKEN" \
76+
-H "Content-Type: $mime" \
77+
--data-binary @"$file" \
78+
--no-progress-meter \
79+
"${UPLOAD_URL%%\{*}?name=$name" > /dev/null
80+
done
81+
82+
- name: Commit Appcasts and Updater
83+
run: |
84+
cd ${{ github.workspace }}/AppcastRepo
85+
branch="update-appcasts-${{ github.run_number }}"
86+
git checkout -b "${branch}"
87+
88+
git add .
89+
git commit -m "Update Appcasts and Updater for SRMM version ${{ github.event.inputs.tag }} and Updater version ${{ github.event.inputs.updater_version }}"
90+
git push origin "${branch}"
91+
env:
92+
GIT_AUTHOR_NAME: github-actions
93+
GIT_AUTHOR_EMAIL: github-actions@github.com
94+
GIT_COMMITTER_NAME: github-actions
95+
GIT_COMMITTER_EMAIL: github-actions@github.com
96+
97+
- name: Create Pull Request
98+
run: |
99+
cd ${{ github.workspace }}/AppcastRepo
100+
branch="update-appcasts-${{ github.run_number }}"
101+
102+
gh pr create \
103+
--title "Update Appcasts and Updater" \
104+
--body "Automated update for SRMM version ${{ github.event.inputs.tag }} and Updater version ${{ github.event.inputs.updater_version }}" \
105+
--head "${branch}" \
106+
--base main
107+
env:
108+
GITHUB_TOKEN: ${{ secrets.SRMM_APPCAST_TOKEN }}

Scripts/build.sh

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
#!/bin/bash
2+
3+
set -euo pipefail
4+
5+
### Variables
6+
SRMM_PROJECT="$GITHUB_WORKSPACE/ShinRyuModManager-CE/ShinRyuModManager-CE.csproj"
7+
UPDATER_PROJECT="$GITHUB_WORKSPACE/RyuUpdater/RyuUpdater.csproj"
8+
SRMM_OUTPUT_DIR="$GITHUB_WORKSPACE/dist/srmm"
9+
UPDATER_OUTPUT_DIR="$GITHUB_WORKSPACE/dist/updater"
10+
TEMP_DIR="$RUNNER_TEMP"
11+
PATTERN=".*\.zip$"
12+
13+
FRAMEWORK="net10.0"
14+
15+
DOWNLOAD_REPO="SRMM-Studio/ShinRyuModManager"
16+
17+
FILES_TO_COPY=(
18+
"dinput8.dll"
19+
"winmm.lj"
20+
"YakuzaParless.asi"
21+
)
22+
23+
# Declares runtime and known build params
24+
declare -A TARGET_ARGS=(
25+
["linux"]="linux-x64;--self-contained -p:BuildSuffix=linux"
26+
["linux-slim"]="linux-x64;--no-self-contained -p:BuildSuffix=linux-slim"
27+
["windows"]="win-x64;--self-contained -p:BuildSuffix=windows"
28+
["windows-slim"]="win-x64;--no-self-contained -p:BuildSuffix=windows-slim"
29+
)
30+
31+
declare -A UPDATER_TARGET_ARGS=(
32+
["linux"]="linux-x64;--self-contained"
33+
["windows"]="win-x64;--self-contained"
34+
)
35+
36+
### Get required files from SRMM release
37+
API_URL="https://api.github.com/repos/${DOWNLOAD_REPO}/releases/latest"
38+
39+
# Using `jq` to parse json response
40+
ASSET_URL=$(curl -s "${API_URL}" | jq -r \
41+
--arg pattern "${PATTERN}" '
42+
.assets[]
43+
| select(.name | test($pattern))
44+
| .browser_download_url
45+
')
46+
47+
if [[ -z "${ASSET_URL}" ]]; then
48+
echo "ERROR: No assets matching pattern '${PATTERN}' found."
49+
exit 1
50+
fi
51+
52+
echo "Downloading asset from: ${ASSET_URL}"
53+
54+
ASSET_FILE="${TEMP_DIR}/release.zip"
55+
curl -L "${ASSET_URL}" -o "${ASSET_FILE}"
56+
57+
echo "Extracting release to ${TEMP_DIR}/extracted"
58+
59+
mkdir -p "${TEMP_DIR}/extracted"
60+
unzip -q "${ASSET_FILE}" -d "${TEMP_DIR}/extracted"
61+
62+
### Build
63+
64+
# Build SRMM
65+
for TARGET in "${!TARGET_ARGS[@]}"; do
66+
OUT_DIR="${SRMM_OUTPUT_DIR}/${TARGET}"
67+
mkdir -p "${OUT_DIR}"
68+
69+
# Reads the target's arguments and split them into an array
70+
IFS=";" read -r -a arr <<< "${TARGET_ARGS[${TARGET}]}"
71+
72+
echo "Buidling SRMM ${TARGET}..."
73+
74+
dotnet publish "${SRMM_PROJECT}" \
75+
-c "Release" \
76+
-r "${arr[0]}" \
77+
-f "${FRAMEWORK}" \
78+
-o "${OUT_DIR}" \
79+
-p:PublishSingleFile=true \
80+
-p:IncludeNativeLibrariesForSelfExtract=true \
81+
-p:DebugType=None \
82+
-p:DebugSymbols=false \
83+
-p:DebugPortablePdb=false \
84+
${arr[1]}
85+
86+
for FILE in "${FILES_TO_COPY[@]}"; do
87+
SRC="${TEMP_DIR}/extracted/${FILE}"
88+
89+
if [[ -f "${SRC}" ]]; then
90+
cp "${SRC}" "${OUT_DIR}/${FILE}"
91+
echo " Copied: ${FILE}"
92+
else
93+
echo " Warning: Missing file in realease: ${FILE}"
94+
fi
95+
done
96+
97+
#TODO: Remove when merged. Ensures Parless can find the exe on Windows
98+
if [[ ${TARGET} =~ "windows" ]]; then
99+
mv "${OUT_DIR}/ShinRyuModManager-CE.exe" "${OUT_DIR}/ShinRyuModManager.exe"
100+
fi
101+
done
102+
103+
# Build Updater
104+
for TARGET in "${!UPDATER_TARGET_ARGS[@]}"; do
105+
OUT_DIR="${UPDATER_OUTPUT_DIR}/${TARGET}"
106+
mkdir -p "${OUT_DIR}"
107+
108+
# Reads the target's arguments and split them into an array
109+
IFS=";" read -r -a arr <<< "${TARGET_ARGS[${TARGET}]}"
110+
111+
echo "Buidling RyuUpdater ${TARGET}..."
112+
113+
dotnet publish "${UPDATER_PROJECT}" \
114+
-c "Release" \
115+
-r "${arr[0]}" \
116+
-f "${FRAMEWORK}" \
117+
-o "${OUT_DIR}" \
118+
-p:PublishSingleFile=true \
119+
-p:IncludeNativeLibrariesForSelfExtract=true \
120+
-p:DebugType=None \
121+
-p:DebugSymbols=false \
122+
-p:DebugPortablePdb=false \
123+
-p:PublishTrimmed=true \
124+
${arr[1]}
125+
done

Scripts/package.sh

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
#!/bin/bash
2+
3+
set -euo pipefail
4+
5+
### Check arguments
6+
if ! [[ "${#}" -gt 3 ]]; then
7+
echo "Not enough args! ${#}"
8+
echo "Usage: $0 -s <SRMM Version Number> -u <Updater Version Number>"
9+
exit 1
10+
fi
11+
12+
while getopts s:u: flag; do
13+
case "${flag}" in
14+
s) SRMM_VERSION="${OPTARG}";;
15+
u) UPDATER_VESION="${OPTARG}";;
16+
*) echo "Usage: $0 -s <SRMM Version Number> -u <Updater Version Number>"; exit 1;;
17+
esac
18+
done
19+
20+
if ! [[ "${SRMM_VERSION}" =~ ^v?[0-9]+\.[0-9]+\.[0-9]+(-[A-Za-z0-9_]+)?$ || "${UPDATER_VESION}" =~ ^v?[0-9]+\.[0-9]+\.[0-9]+(-[A-Za-z0-9_]+)?$ ]]; then
21+
echo "Incorrect format!"
22+
echo "Usage: $0 -s <SRMM Version Number> -u <Updater Version Number>"
23+
exit 1
24+
fi
25+
26+
# Strip leading "v"s
27+
if [[ "${SRMM_VERSION}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[A-Za-z0-9_]+)?$ ]]; then
28+
SRMM_VERSION=${SRMM_VERSION#v}
29+
fi
30+
31+
if [[ "${UPDATER_VESION}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[A-Za-z0-9_]+)?$ ]]; then
32+
UPDATER_VESION=${UPDATER_VESION#v}
33+
fi
34+
35+
### Variables
36+
SRMM_BASE_NAME="ShinRyuModManager-CE"
37+
UPDATER_BASE_NAME="RyuUpdater"
38+
DIST_SELECTOR="$GITHUB_WORKSPACE/dist"
39+
SRMM_SELECTOR="${DIST_SELECTOR}/srmm"
40+
UPDATER_SELECTOR="${DIST_SELECTOR}/updater"
41+
42+
SRMM_OUTPUT_DIR="${SRMM_SELECTOR}/out"
43+
UPDATER_OUTPUT_DIR="${UPDATER_SELECTOR}/out"
44+
45+
APPCAST_OUTPUT_DIR="${DIST_SELECTOR}/appcast"
46+
47+
SRMM_URL_BASE="https://github.com/TheTrueColonel/ShinRyuModManager-CE/releases/download/v"
48+
UPDATER_URL_BASE="https://thetruecolonel.github.io/SRMM-AppCast/updater/"
49+
50+
rm -rf "${SRMM_OUTPUT_DIR}"
51+
rm -rf "${UPDATER_OUTPUT_DIR}"
52+
53+
readarray -t SRMM_BUILD_DIRS < <(find "${SRMM_SELECTOR}" -mindepth 1 -maxdepth 1 -type d -printf '%f\n')
54+
readarray -t UPDATER_BUILD_DIRS < <(find "${UPDATER_SELECTOR}" -mindepth 1 -maxdepth 1 -type d -printf '%f\n')
55+
56+
mkdir -p "${SRMM_OUTPUT_DIR}"
57+
mkdir -p "${UPDATER_OUTPUT_DIR}"
58+
59+
for TARGET in "${SRMM_BUILD_DIRS[@]}"; do
60+
DIR="${SRMM_SELECTOR}/${TARGET}"
61+
OUTPUT_TARGET_STR=$(echo "${TARGET}" | sed -e "s/\b\(.\)/\u\1/g") # Capitalizes each target word: linux-slim -> Linux-Slim
62+
OUTPUT_FILE_BASE="${SRMM_BASE_NAME}-${OUTPUT_TARGET_STR}-${SRMM_VERSION}"
63+
64+
echo "Compressing ${OUTPUT_FILE_BASE}..."
65+
66+
7za a "${SRMM_OUTPUT_DIR}/${OUTPUT_FILE_BASE}.zip" -tzip -bd -y "${DIR}/*" > /dev/null
67+
tar czf "${SRMM_OUTPUT_DIR}/${OUTPUT_FILE_BASE}.tar.gz" --owner=0 --group=0 --numeric-owner -C "${DIR}/" .
68+
69+
### Create Appcast
70+
71+
# Really hate how this is done, but I can't think of anything better
72+
if [[ "${OUTPUT_FILE_BASE}" =~ -Linux- ]]; then
73+
OS_NAME="linux"
74+
EXEC_NAME="${SRMM_BASE_NAME}"
75+
elif [[ "${OUTPUT_FILE_BASE}" =~ -Windows- ]]; then
76+
OS_NAME="windows"
77+
EXEC_NAME="ShinRyuModManager.exe"
78+
fi
79+
80+
# Create only for .zip, as that's universally available
81+
netsparkle-generate-appcast \
82+
-a "${APPCAST_OUTPUT_DIR}" \
83+
--single-file "${SRMM_OUTPUT_DIR}/${OUTPUT_FILE_BASE}.zip" \
84+
-o "${OS_NAME}" \
85+
-n "${EXEC_NAME}" \
86+
--output-file-name "appcast_${TARGET}" \
87+
--use-ed25519-signature-attribute \
88+
--human-readable \
89+
--file-version "${SRMM_VERSION}-${TARGET}" \
90+
-u "${SRMM_URL_BASE}${SRMM_VERSION}/" > /dev/null
91+
done
92+
93+
for TARGET in "${UPDATER_BUILD_DIRS[@]}"; do
94+
DIR="${UPDATER_SELECTOR}/${TARGET}"
95+
OUTPUT_TARGET_STR=$(echo "${TARGET}" | sed -e "s/\b\(.\)/\u\1/g") # Capitalizes each target word: linux-slim -> Linux-Slim
96+
OUTPUT_FILE_BASE="${UPDATER_BASE_NAME}-${OUTPUT_TARGET_STR}-Latest"
97+
98+
echo "Compressing ${OUTPUT_FILE_BASE}..."
99+
100+
7za a "${UPDATER_OUTPUT_DIR}/${OUTPUT_FILE_BASE}.zip" -tzip -bd -y "${DIR}/*" > /dev/null
101+
tar czf "${UPDATER_OUTPUT_DIR}/${OUTPUT_FILE_BASE}.tar.gz" --owner=0 --group=0 --numeric-owner -C "${DIR}/" .
102+
103+
cp -r "${UPDATER_OUTPUT_DIR}/." $GITHUB_WORKSPACE/AppcastRepo/updater/
104+
105+
### Create Appcast
106+
107+
# Really hate how this is done, but I can't think of anything better
108+
if [[ "${OUTPUT_FILE_BASE}" =~ -Linux- ]]; then
109+
OS_NAME="linux"
110+
EXEC_NAME="${UPDATER_BASE_NAME}"
111+
elif [[ "${OUTPUT_FILE_BASE}" =~ -Windows- ]]; then
112+
OS_NAME="windows"
113+
EXEC_NAME="${UPDATER_BASE_NAME}.exe"
114+
fi
115+
116+
# Create only for .zip, as that's universally available
117+
netsparkle-generate-appcast \
118+
-a "${APPCAST_OUTPUT_DIR}" \
119+
--single-file "${UPDATER_OUTPUT_DIR}/${OUTPUT_FILE_BASE}.zip" \
120+
-o "${OS_NAME}" \
121+
-n "${EXEC_NAME}" \
122+
--output-file-name "appcast_ryuupdater-${TARGET}" \
123+
--use-ed25519-signature-attribute \
124+
--human-readable \
125+
--file-version "${SRMM_VERSION}" \
126+
-u "${UPDATER_URL_BASE}" > /dev/null
127+
done
128+
129+
### Copy AppCasts to repo
130+
131+
cp -r "${APPCAST_OUTPUT_DIR}/." $GITHUB_WORKSPACE/AppcastRepo/releases/
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
The slim version requires .NET 10.0 runtime to be installed on the machine.
2+
3+
https://dotnet.microsoft.com/en-us/download/dotnet/10.0

ShinRyuModManager-CE/ShinRyuModManager-CE.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,4 +88,8 @@
8888
</Compile>
8989
</ItemGroup>
9090

91+
<ItemGroup Condition="'$(SelfContained)' == 'false'">
92+
<None Update="BuildAssets\README" Link="README" CopyToOutputDirectory="Always" />
93+
</ItemGroup>
94+
9195
</Project>

0 commit comments

Comments
 (0)