Add README and fix CI/CD pipeline for release builds
Some checks failed
Build & Release / build (push) Failing after 39s
Some checks failed
Build & Release / build (push) Failing after 39s
- README with features, config docs, build instructions, project structure - Pipeline: add Docker CLI install step, fix DinD volume pattern, fix token generation flags (--user git -u calic --raw), proper token cleanup by name instead of fragile ID grep - .gitignore: add dist/ and *.zip Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
name: Build VS Mod
|
name: Build & Release
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
@@ -12,13 +12,21 @@ jobs:
|
|||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Build and package mod
|
- name: Install Docker CLI
|
||||||
|
run: |
|
||||||
|
apt-get update -qq && apt-get install -y -qq ca-certificates curl >/dev/null
|
||||||
|
install -m 0755 -d /etc/apt/keyrings
|
||||||
|
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
|
||||||
|
echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu noble stable" > /etc/apt/sources.list.d/docker.list
|
||||||
|
apt-get update -qq && apt-get install -y -qq docker-ce-cli >/dev/null
|
||||||
|
|
||||||
|
- name: Build mod
|
||||||
run: |
|
run: |
|
||||||
VERSION=$(grep -oPm1 '"version":\s*"\K[^"]+' resources/modinfo.json)
|
VERSION=$(grep -oPm1 '"version":\s*"\K[^"]+' resources/modinfo.json)
|
||||||
MODID="welcomescreen"
|
MODID="welcomescreen"
|
||||||
OUTPUT="${MODID}_${VERSION}.zip"
|
echo "Building ${MODID} v${VERSION}..."
|
||||||
|
|
||||||
# Build inside .NET SDK container using docker cp (DinD — bind mounts don't work)
|
# DinD: bind mounts don't work — use docker cp with a volume
|
||||||
docker volume create mod-build
|
docker volume create mod-build
|
||||||
docker pull alpine:3 >/dev/null 2>&1
|
docker pull alpine:3 >/dev/null 2>&1
|
||||||
HELPER=$(docker create -v mod-build:/src alpine:3 true)
|
HELPER=$(docker create -v mod-build:/src alpine:3 true)
|
||||||
@@ -28,50 +36,50 @@ jobs:
|
|||||||
docker run --rm -v mod-build:/src -w /src mcr.microsoft.com/dotnet/sdk:8.0 \
|
docker run --rm -v mod-build:/src -w /src mcr.microsoft.com/dotnet/sdk:8.0 \
|
||||||
dotnet build -c Release
|
dotnet build -c Release
|
||||||
|
|
||||||
# Extract artifacts from volume
|
# Extract build output from volume
|
||||||
HELPER=$(docker create -v mod-build:/src alpine:3 true)
|
HELPER=$(docker create -v mod-build:/src alpine:3 true)
|
||||||
docker cp $HELPER:/src/bin/Release/WelcomeScreen.dll ./WelcomeScreen.dll
|
docker cp $HELPER:/src/bin/Release/WelcomeScreen.dll ./WelcomeScreen.dll
|
||||||
docker rm $HELPER >/dev/null
|
docker rm $HELPER >/dev/null
|
||||||
docker volume rm mod-build >/dev/null
|
docker volume rm mod-build >/dev/null
|
||||||
|
|
||||||
# Package ZIP
|
# Package mod ZIP
|
||||||
mkdir -p dist
|
mkdir -p dist
|
||||||
cp WelcomeScreen.dll dist/
|
cp WelcomeScreen.dll dist/
|
||||||
cp resources/modinfo.json dist/
|
cp resources/modinfo.json dist/
|
||||||
cd dist && zip -j "../${OUTPUT}" WelcomeScreen.dll modinfo.json
|
cd dist && zip -j "../${MODID}_${VERSION}.zip" WelcomeScreen.dll modinfo.json
|
||||||
cd ..
|
cd ..
|
||||||
|
|
||||||
echo "MOD_ZIP=${OUTPUT}" >> $GITHUB_ENV
|
echo "MOD_ZIP=${MODID}_${VERSION}.zip" >> $GITHUB_ENV
|
||||||
echo "MOD_VERSION=${VERSION}" >> $GITHUB_ENV
|
echo "MOD_VERSION=${VERSION}" >> $GITHUB_ENV
|
||||||
echo "Built ${OUTPUT}"
|
echo "Built: ${MODID}_${VERSION}.zip"
|
||||||
|
|
||||||
- name: Create release
|
- name: Create release
|
||||||
if: startsWith(github.ref, 'refs/tags/v')
|
if: startsWith(github.ref, 'refs/tags/v')
|
||||||
run: |
|
run: |
|
||||||
TAG="${GITHUB_REF#refs/tags/}"
|
TAG="${GITHUB_REF#refs/tags/}"
|
||||||
# Generate a temporary token for the API call
|
TOKEN_NAME="ci-release-$$"
|
||||||
TOKEN=$(docker exec gitea gitea admin user generate-access-token \
|
|
||||||
--user git --username calic --scopes write 2>&1 | grep -oPm1 '(?<=: ).*')
|
|
||||||
|
|
||||||
# Create release with artifact
|
# Generate temporary Gitea API token
|
||||||
|
# --user git = container OS user; -u calic = Gitea account
|
||||||
|
TOKEN=$(docker exec --user git gitea gitea admin user generate-access-token \
|
||||||
|
-u calic -t "$TOKEN_NAME" --scopes all --raw 2>/dev/null)
|
||||||
|
|
||||||
|
# Create release
|
||||||
RELEASE_ID=$(curl -sf \
|
RELEASE_ID=$(curl -sf \
|
||||||
-H "Authorization: token ${TOKEN}" \
|
-H "Authorization: token ${TOKEN}" \
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
-d "{\"tag_name\":\"${TAG}\",\"name\":\"Welcome Screen ${MOD_VERSION}\",\"body\":\"Release ${MOD_VERSION}\"}" \
|
-d "{\"tag_name\":\"${TAG}\",\"name\":\"Welcome Screen ${MOD_VERSION}\",\"body\":\"Release ${MOD_VERSION}\"}" \
|
||||||
"http://gitea:3000/api/v1/repos/calic/vs-welcome-screen/releases" | grep -oPm1 '"id":\K[0-9]+')
|
"http://gitea:3000/api/v1/repos/calic/vs-welcome-screen/releases" \
|
||||||
|
| grep -oPm1 '"id":\K[0-9]+')
|
||||||
|
|
||||||
# Upload artifact
|
# Attach mod ZIP to release
|
||||||
curl -sf \
|
curl -sf \
|
||||||
-H "Authorization: token ${TOKEN}" \
|
-H "Authorization: token ${TOKEN}" \
|
||||||
-F "attachment=@${MOD_ZIP}" \
|
-F "attachment=@${MOD_ZIP}" \
|
||||||
"http://gitea:3000/api/v1/repos/calic/vs-welcome-screen/releases/${RELEASE_ID}/assets"
|
"http://gitea:3000/api/v1/repos/calic/vs-welcome-screen/releases/${RELEASE_ID}/assets"
|
||||||
|
|
||||||
# Clean up token
|
echo "Release ${TAG} created with ${MOD_ZIP}"
|
||||||
TOKEN_ID=$(curl -sf \
|
|
||||||
-H "Authorization: token ${TOKEN}" \
|
|
||||||
"http://gitea:3000/api/v1/users/calic/tokens" | grep -oPm1 '"id":\K[0-9]+')
|
|
||||||
curl -sf -X DELETE \
|
|
||||||
-H "Authorization: token ${TOKEN}" \
|
|
||||||
"http://gitea:3000/api/v1/users/calic/tokens/${TOKEN_ID}"
|
|
||||||
|
|
||||||
echo "Release ${TAG} created with artifact ${MOD_ZIP}"
|
# Clean up token
|
||||||
|
curl -sf -X DELETE -u "calic:${TOKEN}" \
|
||||||
|
"http://gitea:3000/api/v1/users/calic/tokens/${TOKEN_NAME}" >/dev/null 2>&1 || true
|
||||||
|
|||||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,5 +1,7 @@
|
|||||||
bin/
|
bin/
|
||||||
obj/
|
obj/
|
||||||
|
dist/
|
||||||
*.user
|
*.user
|
||||||
*.suo
|
*.suo
|
||||||
.vs/
|
.vs/
|
||||||
|
*.zip
|
||||||
|
|||||||
97
README.md
Normal file
97
README.md
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
# Welcome Screen — Vintage Story Mod
|
||||||
|
|
||||||
|
Server-side configurable welcome dialog that opens automatically when players join. Displays Markdown content rendered as VTML (Vintage Text Markup Language) in a scrollable GUI window.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- **Auto-open on join** — dialog appears when a player connects
|
||||||
|
- **Markdown content** — write `welcome.md` in the server data directory, rendered as rich text (headings, bold, italic, links, lists, blockquotes, code)
|
||||||
|
- **Mod checker** — server compares client's installed mods against a recommended/blacklisted list and shows the result in the dialog
|
||||||
|
- **Reopen with HOME** — players can press HOME to reopen the dialog at any time
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
Download the latest `welcomescreen_x.x.x.zip` from [Releases](../../releases) and place it in your server's `Mods/` directory. Do **not** extract the ZIP.
|
||||||
|
|
||||||
|
This is a **universal** mod — it must be installed on both server and client.
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
All config files are auto-generated on first run in the server's `ModConfig/` directory.
|
||||||
|
|
||||||
|
### `WelcomeScreenConfig.json`
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"Title": "Welcome",
|
||||||
|
"WelcomeFile": "welcome.md"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- `Title` — dialog window title
|
||||||
|
- `WelcomeFile` — path to the Markdown file (relative to server data dir)
|
||||||
|
|
||||||
|
### `WelcomeScreenModCheck.json`
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"Enabled": true,
|
||||||
|
"RecommendedMods": [
|
||||||
|
{ "ModId": "rpvoicechat", "DisplayName": "RPVoiceChat", "Reason": "Proximity voice chat" }
|
||||||
|
],
|
||||||
|
"BlacklistedMods": []
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- `RecommendedMods` — mods the server suggests clients should have
|
||||||
|
- `BlacklistedMods` — mods the server disallows (shown as warning)
|
||||||
|
|
||||||
|
### `welcome.md`
|
||||||
|
|
||||||
|
Place this file in the server's data directory. Standard Markdown syntax is supported:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
# Server Name
|
||||||
|
|
||||||
|
Welcome to our server!
|
||||||
|
|
||||||
|
## Rules
|
||||||
|
1. Be respectful
|
||||||
|
2. No griefing
|
||||||
|
|
||||||
|
**Have fun!**
|
||||||
|
```
|
||||||
|
|
||||||
|
## Building
|
||||||
|
|
||||||
|
Requires .NET 8 SDK and the Vintage Story API DLLs in `lib/`.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Build locally
|
||||||
|
./build.sh
|
||||||
|
|
||||||
|
# Build and install to server
|
||||||
|
./build.sh --install
|
||||||
|
```
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
src/
|
||||||
|
WelcomeScreenMod.cs Main mod — server/client logic, network packets, config
|
||||||
|
WelcomeScreenDialog.cs GUI dialog with scrollable VTML content
|
||||||
|
MarkdownToVtml.cs Markdown → VTML converter
|
||||||
|
resources/
|
||||||
|
modinfo.json Mod metadata (version, dependencies)
|
||||||
|
lib/
|
||||||
|
VintagestoryAPI.dll VS API reference (not distributed)
|
||||||
|
protobuf-net.dll Protobuf serialization (not distributed)
|
||||||
|
```
|
||||||
|
|
||||||
|
## CI/CD
|
||||||
|
|
||||||
|
Push a tag (`v*`) to trigger the build pipeline, which compiles the mod, packages the ZIP, and creates a Gitea release with the artifact attached.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
Private mod — not publicly distributed.
|
||||||
Reference in New Issue
Block a user