Skip to content

Commit 07054f9

Browse files
committed
fix(release): publish mod platform packages
1 parent b2e269d commit 07054f9

3 files changed

Lines changed: 158 additions & 25 deletions

File tree

.github/workflows/publish-github-release.yml

Lines changed: 117 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,31 @@ on:
1010
description: Existing release tag to publish or refresh
1111
required: true
1212
type: string
13+
publish_nexus:
14+
description: Upload the release package to Nexus Mods
15+
required: false
16+
default: true
17+
type: boolean
18+
publish_thunderstore:
19+
description: Upload the Thunderstore package to Thunderstore
20+
required: false
21+
default: true
22+
type: boolean
1323

1424
permissions:
1525
contents: write
1626

27+
env:
28+
NEXUSMODS_API_KEY: ${{ secrets.NEXUSMODS_API_KEY }}
29+
NEXUSMODS_FILE_GROUP_ID: ${{ secrets.NEXUSMODS_FILE_GROUP_ID || vars.NEXUSMODS_FILE_GROUP_ID }}
30+
RELEASE_DESCRIPTION: S1API is an open source collaboration project to help standardize Schedule One modding processes. The goal is to provide a standard place for common functionalities so you can focus on making content versus reverse engineering the game.
31+
THUNDERSTORE_COMMUNITY: schedule-i
32+
THUNDERSTORE_TOKEN: ${{ secrets.THUNDERSTORE_TOKEN }}
33+
THUNDERSTORE_NAMESPACE: ifBars
34+
THUNDERSTORE_PACKAGE_NAME: S1API_Forked
35+
THUNDERSTORE_CATEGORIES: libraries
36+
THUNDERSTORE_WEBSITE: https://github.com/ifBars/S1API
37+
1738
jobs:
1839
publish-release:
1940
runs-on: ubuntu-latest
@@ -213,35 +234,77 @@ jobs:
213234
dotnet build S1API/S1API.csproj --no-restore -c Il2CppMelon -v minimal /p:AutomateLocalDeployment=false
214235
cp S1API/bin/Il2CppMelon/net6.0/S1API.dll artifacts/build/S1API.Il2Cpp.MelonLoader.dll
215236
216-
- name: Package release asset
237+
- name: Package release assets
217238
id: package
218239
shell: bash
219240
run: |
220241
set -euo pipefail
221242
222243
package_dir="artifacts/S1API-Forked-${{ steps.metadata.outputs.base_version }}"
223244
zip_path="artifacts/S1API-Forked-${{ steps.metadata.outputs.base_version }}.zip"
245+
thunderstore_dir="artifacts/S1API-TS-${{ steps.metadata.outputs.base_version }}"
246+
thunderstore_zip_path="artifacts/S1API-TS-${{ steps.metadata.outputs.base_version }}.zip"
224247
225-
mkdir -p "${package_dir}/mods" "${package_dir}/plugins"
226-
cp artifacts/build/S1API.Mono.MelonLoader.dll "${package_dir}/mods/S1API.Mono.MelonLoader.dll"
227-
cp artifacts/build/S1API.Il2Cpp.MelonLoader.dll "${package_dir}/mods/S1API.Il2Cpp.MelonLoader.dll"
228-
cp artifacts/build/S1APILoader.MelonLoader.dll "${package_dir}/plugins/S1APILoader.MelonLoader.dll"
248+
mkdir -p "${package_dir}/Mods" "${package_dir}/Plugins"
249+
cp artifacts/build/S1API.Mono.MelonLoader.dll "${package_dir}/Mods/S1API.Mono.MelonLoader.dll"
250+
cp artifacts/build/S1API.Il2Cpp.MelonLoader.dll "${package_dir}/Mods/S1API.Il2Cpp.MelonLoader.dll"
251+
cp artifacts/build/S1APILoader.MelonLoader.dll "${package_dir}/Plugins/S1APILoader.MelonLoader.dll"
229252
230253
(
231254
cd "${package_dir}"
232-
zip -r "../$(basename "${zip_path}")" mods plugins
255+
zip -r "../$(basename "${zip_path}")" Mods Plugins
233256
)
234257
235258
unzip -l "${zip_path}"
236259
237260
for entry in \
238-
"mods/S1API.Mono.MelonLoader.dll" \
239-
"mods/S1API.Il2Cpp.MelonLoader.dll" \
240-
"plugins/S1APILoader.MelonLoader.dll"; do
261+
"Mods/S1API.Mono.MelonLoader.dll" \
262+
"Mods/S1API.Il2Cpp.MelonLoader.dll" \
263+
"Plugins/S1APILoader.MelonLoader.dll"; do
241264
unzip -Z1 "${zip_path}" | grep -Fx "${entry}" >/dev/null
242265
done
243266
267+
mkdir -p "${thunderstore_dir}/Mods" "${thunderstore_dir}/Plugins"
268+
cp artifacts/build/S1API.Mono.MelonLoader.dll "${thunderstore_dir}/Mods/S1API.Mono.MelonLoader.dll"
269+
cp artifacts/build/S1API.Il2Cpp.MelonLoader.dll "${thunderstore_dir}/Mods/S1API.Il2Cpp.MelonLoader.dll"
270+
cp artifacts/build/S1APILoader.MelonLoader.dll "${thunderstore_dir}/Plugins/S1APILoader.MelonLoader.dll"
271+
cp Public/logo_compressed.png "${thunderstore_dir}/icon.png"
272+
cp Public/README.md "${thunderstore_dir}/README.md"
273+
274+
jq -n \
275+
--arg name "${THUNDERSTORE_PACKAGE_NAME}" \
276+
--arg version "${{ steps.metadata.outputs.base_version }}" \
277+
--arg website "${THUNDERSTORE_WEBSITE}" \
278+
--arg description "${RELEASE_DESCRIPTION}" \
279+
'{
280+
name: $name,
281+
version_number: $version,
282+
website_url: $website,
283+
description: $description,
284+
dependencies: ["LavaGang-MelonLoader-0.7.2"]
285+
}' > "${thunderstore_dir}/manifest.json"
286+
287+
(
288+
cd "${thunderstore_dir}"
289+
zip -r "../$(basename "${thunderstore_zip_path}")" icon.png README.md manifest.json Mods Plugins
290+
)
291+
292+
unzip -l "${thunderstore_zip_path}"
293+
294+
for entry in \
295+
"icon.png" \
296+
"README.md" \
297+
"manifest.json" \
298+
"Mods/S1API.Mono.MelonLoader.dll" \
299+
"Mods/S1API.Il2Cpp.MelonLoader.dll" \
300+
"Plugins/S1APILoader.MelonLoader.dll"; do
301+
unzip -Z1 "${thunderstore_zip_path}" | grep -Fx "${entry}" >/dev/null
302+
done
303+
304+
jq -e --arg version "${{ steps.metadata.outputs.base_version }}" '.version_number == $version' "${thunderstore_dir}/manifest.json" >/dev/null
305+
244306
echo "zip_path=${zip_path}" >> "$GITHUB_OUTPUT"
307+
echo "thunderstore_zip_path=${thunderstore_zip_path}" >> "$GITHUB_OUTPUT"
245308
246309
- name: Publish or update GitHub release
247310
uses: actions/github-script@v7
@@ -336,7 +399,50 @@ jobs:
336399
const created = await github.rest.repos.createRelease(payload);
337400
core.notice(`Published GitHub release ${created.data.html_url}`);
338401
339-
- name: Upload release asset
402+
- name: Upload GitHub release assets
340403
env:
341404
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
342-
run: gh release upload "${{ steps.metadata.outputs.tag }}" "${{ steps.package.outputs.zip_path }}" --clobber
405+
run: |
406+
gh release upload "${{ steps.metadata.outputs.tag }}" "${{ steps.package.outputs.zip_path }}" --clobber
407+
gh release upload "${{ steps.metadata.outputs.tag }}" "${{ steps.package.outputs.thunderstore_zip_path }}" --clobber
408+
409+
- name: Upload Nexus Mods release
410+
if: ${{ (github.event_name != 'workflow_dispatch' || inputs.publish_nexus) && env.NEXUSMODS_API_KEY != '' && env.NEXUSMODS_FILE_GROUP_ID != '' }}
411+
uses: Nexus-Mods/upload-action@v1.0.0-beta.7
412+
with:
413+
api_key: ${{ env.NEXUSMODS_API_KEY }}
414+
file_group_id: ${{ env.NEXUSMODS_FILE_GROUP_ID }}
415+
filename: ${{ steps.package.outputs.zip_path }}
416+
version: ${{ steps.metadata.outputs.base_version }}
417+
display_name: S1API Forked ${{ steps.metadata.outputs.base_version }}
418+
description: ${{ env.RELEASE_DESCRIPTION }}
419+
file_category: main
420+
archive_existing_file: true
421+
primary_mod_manager_download: true
422+
allow_mod_manager_download: true
423+
show_requirements_pop_up: false
424+
425+
- name: Skip Nexus Mods upload
426+
if: ${{ (github.event_name != 'workflow_dispatch' || inputs.publish_nexus) && (env.NEXUSMODS_API_KEY == '' || env.NEXUSMODS_FILE_GROUP_ID == '') }}
427+
shell: bash
428+
run: echo "::notice::Skipping Nexus Mods upload because NEXUSMODS_API_KEY or NEXUSMODS_FILE_GROUP_ID is not configured."
429+
430+
- name: Upload Thunderstore release
431+
if: ${{ (github.event_name != 'workflow_dispatch' || inputs.publish_thunderstore) && env.THUNDERSTORE_TOKEN != '' }}
432+
uses: GreenTF/upload-thunderstore-package@v4.3
433+
with:
434+
token: ${{ env.THUNDERSTORE_TOKEN }}
435+
community: ${{ env.THUNDERSTORE_COMMUNITY }}
436+
namespace: ${{ env.THUNDERSTORE_NAMESPACE }}
437+
name: ${{ env.THUNDERSTORE_PACKAGE_NAME }}
438+
description: ${{ env.RELEASE_DESCRIPTION }}
439+
version: ${{ steps.metadata.outputs.base_version }}
440+
file: ${{ steps.package.outputs.thunderstore_zip_path }}
441+
repo: https://thunderstore.io
442+
website: ${{ env.THUNDERSTORE_WEBSITE }}
443+
categories: ${{ env.THUNDERSTORE_CATEGORIES }}
444+
445+
- name: Skip Thunderstore upload
446+
if: ${{ (github.event_name != 'workflow_dispatch' || inputs.publish_thunderstore) && env.THUNDERSTORE_TOKEN == '' }}
447+
shell: bash
448+
run: echo "::notice::Skipping Thunderstore upload because THUNDERSTORE_TOKEN is not configured."

Public/README.md

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,44 @@
1-
![logo](https://github.com/KaBooMa/S1API/blob/stable/Public/logo.png?raw=true)
1+
![logo](https://github.com/ifBars/S1API/blob/stable/Public/logo.png?raw=true)
22

33
# A Schedule One Mono / Il2Cpp Cross Compatibility Layer
44
S1API is an open source collaboration project to help standardize Schedule One modding processes.
55
The goal is to provide a standard place for common functionalities so you can focus on making content versus reverse engineering the game.
66

7+
S1API was originally created by KaBooMa as an open source collaboration project to help standardize Schedule One modding processes.
8+
This fork continues development with updates, fixes, and improvements while keeping the same spirit and goals.
9+
710
## Do I need this?
8-
If you're using or plan to use any mods that depend on S1API, then yes.
11+
If you're using or plan to use any mods that depend on S1API, then yes.
912

1013
## How do I manually install this mod?
11-
Installation is pretty straight-forward.
14+
Installation is straight-forward.
1215
- Download the ZIP file from Nexus Mods or Thunderstore.
1316
- Extract all files locally so you have them in a folder.
14-
- Copy the `Plugins/` and `Mods/` folder into your `Schedule I` folder.
17+
- Copy the `Plugins/` and `Mods/` folders into your `Schedule I` folder.
1518
- This is typically found under `C:\Program Files (x86)\Steam\steamapps\common\Schedule I\`
1619

17-
**To uninstall, remove the associated plugins and mods files from the respective directories.**
20+
To uninstall, remove the associated plugins and mods files from the respective directories.
1821

1922
## How do I use this to make mods?
20-
Go check out the extremely helpful resources on our [GitHub](https://github.com/KaBooMa/S1API).
23+
Go check out the resources on our [GitHub](https://github.com/ifBars/S1API).
2124

2225
## I'm getting errors from S1API, what do I do?
23-
Please head over to the [GitHub](https://github.com/KaBooMa/S1API) page and create a new issue for us.
24-
This helps us keep track of what problems people are experiencing!
25-
26-
___
27-
28-
# Drop us an endorsement ❤️
29-
It's not easy being an API. Content is always king, not the backend glue!
30-
Endorsements are free and really helps drive our motivation for this project.
26+
Please head over to the [GitHub](https://github.com/ifBars/S1API) page and create a new issue for us.
27+
This helps us keep track of what problems people are experiencing.
28+
29+
## Credits
30+
Kaboomaz
31+
Akermi
32+
ifBars
33+
Max
34+
Chloe
35+
k0
36+
SkyeKoi
37+
Pranjal
38+
Any other S1API contributors I may have missed
39+
40+
---
41+
42+
# Drop us an endorsement
43+
It's not easy being an API. Content is always king, not the backend glue.
44+
Endorsements are free and really helps drive our motivation for this project.

VERSIONING.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,19 @@ Before expecting a NuGet package to publish:
9090
3. Confirm the branch name uses `releases/`, not `release/`.
9191
4. Confirm the publish workflow secrets are configured in GitHub.
9292

93+
## GitHub, Nexus Mods, and Thunderstore Publishing
94+
95+
The GitHub release workflow packages public mod archives and can publish the same release to mod distribution platforms.
96+
97+
- `publish-github-release.yml` runs from release tags and can also be rerun with `workflow_dispatch`.
98+
- The GitHub/Nexus archive is `S1API-Forked-x.y.z.zip` and contains `Mods/` and `Plugins/` at the archive root.
99+
- The Thunderstore archive is `S1API-TS-x.y.z.zip` and contains `icon.png`, `README.md`, `manifest.json`, `Mods/`, and `Plugins/` at the archive root.
100+
- The uppercase `Mods/` and `Plugins/` paths are intentional so case-sensitive filesystems do not create parallel lowercase install folders.
101+
- GitHub release assets are always uploaded by the workflow.
102+
- Nexus Mods upload runs when `NEXUSMODS_API_KEY` and `NEXUSMODS_FILE_GROUP_ID` are configured.
103+
- Thunderstore upload runs when `THUNDERSTORE_TOKEN` is configured.
104+
- `workflow_dispatch` exposes `publish_nexus` and `publish_thunderstore` toggles for refreshing GitHub assets without re-publishing external platforms.
105+
93106
## Backporting Rules
94107

95108
- Prefer cherry-picking specific commits instead of merging branches.

0 commit comments

Comments
 (0)