mirror of
https://github.com/space-syndicate/space-station-14.git
synced 2026-10-09 10:21:18 +03:00
467 lines
17 KiB
YAML
467 lines
17 KiB
YAML
name: Update Wiki
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
push:
|
|
branches: [ master, jsondump ]
|
|
paths:
|
|
- '.github/workflows/update-wiki.yml'
|
|
- 'Content.Shared/**'
|
|
- 'Content.Server/**'
|
|
- 'Content.Client/**'
|
|
- 'Resources/**'
|
|
- 'RobustToolbox/'
|
|
|
|
jobs:
|
|
update-wiki:
|
|
name: Build and Publish JSON blobs to wiki
|
|
runs-on: ubuntu-latest
|
|
|
|
steps:
|
|
- name: Checkout Master
|
|
uses: actions/checkout@v4.2.2
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: Detect changed paths
|
|
id: changes
|
|
uses: dorny/paths-filter@v3
|
|
with:
|
|
filters: |
|
|
general:
|
|
- '.github/workflows/update-wiki.yml'
|
|
- 'Content.Shared/**'
|
|
- 'Content.Server/**'
|
|
- 'Content.Client/**'
|
|
- 'Resources/Prototypes/**'
|
|
- 'RobustToolbox/**'
|
|
|
|
prototypes:
|
|
- '.github/workflows/update-wiki.yml'
|
|
- 'Resources/Prototypes/**'
|
|
|
|
textures:
|
|
- '.github/workflows/update-wiki.yml'
|
|
- 'Resources/Textures/**'
|
|
|
|
locale:
|
|
- '.github/workflows/update-wiki.yml'
|
|
- 'Resources/Locale/**'
|
|
|
|
- name: Setup Submodule
|
|
run: |
|
|
git submodule update --init --recursive
|
|
|
|
- name: Pull Engine Updates
|
|
uses: space-wizards/submodule-dependency@v0.1.5
|
|
|
|
- name: Update Engine Submodules
|
|
run: |
|
|
cd RobustToolbox/
|
|
git submodule update --init --recursive
|
|
|
|
- name: Setup .NET Core
|
|
uses: actions/setup-dotnet@v4.1.0
|
|
with:
|
|
dotnet-version: 9.0.x
|
|
|
|
- name: Install Dependencies
|
|
run: dotnet restore
|
|
|
|
- name: Build Project
|
|
run: dotnet build --configuration Release --no-restore /p:WarningsAsErrors=nullable /m
|
|
|
|
- name: Generate JSON blobs for prototypes
|
|
run: dotnet ./bin/Content.Server/Content.Server.dll --cvar autogen.destination_file=prototypes.json
|
|
continue-on-error: true
|
|
|
|
- name: Upload loc to wiki
|
|
if: ${{ github.event_name == 'workflow_dispatch' || steps.changes.outputs.locale == 'true' }}
|
|
continue-on-error: true
|
|
uses: jtmullen/mediawiki-edit-action@v0.1.1
|
|
with:
|
|
wiki_text_file: ./bin/Content.Server/data/loc.json
|
|
edit_summary: Update loc.json via GitHub Actions
|
|
page_name: "${{ secrets.WIKI_PAGE_ROOT }}/loc.json"
|
|
api_url: ${{ secrets.WIKI_ROOT_URL }}/api.php
|
|
username: ${{ secrets.WIKI_BOT_USER }}
|
|
password: ${{ secrets.WIKI_BOT_PASS }}
|
|
|
|
- name: Update meta license
|
|
if: ${{ github.event_name == 'workflow_dispatch' || steps.changes.outputs.textures == 'true' }}
|
|
continue-on-error: true
|
|
uses: jtmullen/mediawiki-edit-action@v0.1.1
|
|
with:
|
|
wiki_text_file: ./bin/Content.Server/data/meta_license.json
|
|
edit_summary: Update meta_license.json via GitHub Actions
|
|
page_name: "${{ secrets.WIKI_PAGE_ROOT }}/meta_license.json"
|
|
api_url: ${{ secrets.WIKI_ROOT_URL }}/api.php
|
|
username: ${{ secrets.WIKI_BOT_USER }}
|
|
password: ${{ secrets.WIKI_BOT_PASS }}
|
|
|
|
# Проходит по всем JSON-файлам в директории BASE и загружает каждый файл как страницу в MediaWiki.
|
|
# Имя страницы формируется из относительного пути к файлу.
|
|
- name: Upload JSON files to wiki
|
|
if: ${{ github.event_name == 'workflow_dispatch' || steps.changes.outputs.general == 'true' }}
|
|
continue-on-error: true
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
|
|
BASE="./bin/Content.Server/data"
|
|
ROOT="${{ secrets.WIKI_PAGE_ROOT }}"
|
|
NAMESPACE="${{ secrets.WIKI_BOT_NAMESPACE }}"
|
|
API="${{ secrets.WIKI_ROOT_URL }}/api.php"
|
|
USER="${{ secrets.WIKI_BOT_USER }}"
|
|
PASS="${{ secrets.WIKI_BOT_PASS }}"
|
|
|
|
API="$(printf "%s" "$API" | tr -d '\r\n' | sed 's/[[:space:]]*$//')"
|
|
USER="$(printf "%s" "$USER" | tr -d '\r\n')"
|
|
PASS="$(printf "%s" "$PASS" | tr -d '\r\n')"
|
|
ROOT="$(printf "%s" "$ROOT" | tr -d '\r\n' | sed 's/[[:space:]]*$//')"
|
|
NAMESPACE="$(printf "%s" "$NAMESPACE" | tr -d '\r\n')"
|
|
|
|
if [[ -n "$NAMESPACE" ]]; then
|
|
MODULE_ROOT="Модуль:IanComradeBot/$NAMESPACE"
|
|
else
|
|
MODULE_ROOT="Модуль:IanComradeBot"
|
|
fi
|
|
|
|
cookiejar="$(mktemp)"
|
|
trap 'rm -f "$cookiejar"' EXIT
|
|
|
|
curl_api() {
|
|
curl --silent --show-error \
|
|
--retry 3 \
|
|
--retry-delay 5 \
|
|
--retry-all-errors \
|
|
--connect-timeout 20 \
|
|
--max-time 180 \
|
|
"$@"
|
|
}
|
|
|
|
login_token=$(curl_api -c "$cookiejar" \
|
|
--data "action=query&meta=tokens&type=login&format=json" "$API" | jq -r '.query.tokens.logintoken')
|
|
|
|
curl_api -c "$cookiejar" -b "$cookiejar" \
|
|
--data-urlencode "action=login" \
|
|
--data-urlencode "lgname=$USER" \
|
|
--data-urlencode "lgpassword=$PASS" \
|
|
--data-urlencode "lgtoken=$login_token" \
|
|
--data-urlencode "format=json" \
|
|
"$API" > /dev/null
|
|
|
|
token=$(curl_api -b "$cookiejar" \
|
|
--data "action=query&meta=tokens&format=json" "$API" | jq -r '.query.tokens.csrftoken')
|
|
|
|
edit_page_file() {
|
|
local title="$1"
|
|
local summary="$2"
|
|
local textfile="$3"
|
|
local token="$4"
|
|
|
|
curl_api -b "$cookiejar" \
|
|
--data-urlencode "action=edit" \
|
|
--data-urlencode "title=$title" \
|
|
--data-urlencode "summary=$summary" \
|
|
--data-urlencode "text@${textfile}" \
|
|
--data-urlencode "token=$token" \
|
|
--data-urlencode "bot=true" \
|
|
--data-urlencode "minor=true" \
|
|
--data-urlencode "format=json" \
|
|
"$API" | jq -r '.edit.result // "null"'
|
|
}
|
|
|
|
edit_page() {
|
|
local title="$1"
|
|
local summary="$2"
|
|
local text="$3"
|
|
local token="$4"
|
|
|
|
curl_api -b "$cookiejar" \
|
|
--data-urlencode "action=edit" \
|
|
--data-urlencode "title=$title" \
|
|
--data-urlencode "summary=$summary" \
|
|
--data-urlencode "text=$text" \
|
|
--data-urlencode "token=$token" \
|
|
--data-urlencode "bot=true" \
|
|
--data-urlencode "minor=true" \
|
|
--data-urlencode "format=json" \
|
|
"$API" | jq -r '.edit.result // "null"'
|
|
}
|
|
|
|
query_page_linecounts() {
|
|
local -n titles_ref=$1
|
|
local -n linecounts_ref=$2
|
|
linecounts_ref=()
|
|
|
|
(( ${#titles_ref[@]} == 0 )) && return 0
|
|
|
|
local titles
|
|
titles=$(printf '%s|' "${titles_ref[@]}")
|
|
titles="${titles%|}"
|
|
|
|
local resp
|
|
resp=$(curl_api -b "$cookiejar" \
|
|
--data-urlencode "action=query" \
|
|
--data-urlencode "format=json" \
|
|
--data-urlencode "formatversion=2" \
|
|
--data-urlencode "prop=revisions" \
|
|
--data-urlencode "rvprop=content" \
|
|
--data-urlencode "rvslots=main" \
|
|
--data-urlencode "titles=$titles" \
|
|
"$API")
|
|
|
|
while IFS=$'\t' read -r title linecount; do
|
|
[[ -z "${title:-}" ]] && continue
|
|
[[ -z "${linecount:-}" ]] && continue
|
|
linecounts_ref["$title"]="$linecount"
|
|
done < <(
|
|
jq -r '
|
|
.query.pages[]
|
|
| [.title, ((.revisions[0].slots.main.content? // "")| split("\n")| length)]
|
|
| @tsv
|
|
' <<< "$resp"
|
|
)
|
|
}
|
|
|
|
files=()
|
|
while IFS= read -r -d '' file; do
|
|
files+=("$file")
|
|
done < <(find "$BASE" -type f -name '*.json' -print0)
|
|
|
|
batch_size=25
|
|
|
|
for ((i=0; i<${#files[@]}; i+=batch_size)); do
|
|
batch_files=("${files[@]:i:batch_size}")
|
|
|
|
declare -a json_titles=()
|
|
declare -a module_titles=()
|
|
|
|
for file in "${batch_files[@]}"; do
|
|
rel="${file#$BASE/}"
|
|
rel="$(printf "%s" "$rel" | tr -d '\r\n' | sed 's/:/_/g')"
|
|
json_titles+=("$ROOT/$rel")
|
|
module_titles+=("$MODULE_ROOT/$rel/data")
|
|
done
|
|
|
|
declare -A json_lines=()
|
|
declare -A module_lines=()
|
|
|
|
query_page_linecounts json_titles json_lines
|
|
query_page_linecounts module_titles module_lines
|
|
|
|
for file in "${batch_files[@]}"; do
|
|
rel="${file#$BASE/}"
|
|
rel="$(printf "%s" "$rel" | tr -d '\r\n' | sed 's/:/_/g')"
|
|
|
|
json_title="$ROOT/$rel"
|
|
module_title="$MODULE_ROOT/$rel/data"
|
|
|
|
echo "Processing $rel → $json_title"
|
|
|
|
local_lines=$(awk 'END { print NR }' "$file")
|
|
remote_lines="${json_lines[$json_title]:-}"
|
|
|
|
if [[ -n "$remote_lines" && "$remote_lines" == "$local_lines" ]]; then
|
|
echo "Skipping unchanged page: $json_title"
|
|
else
|
|
echo "Uploading $rel → $json_title"
|
|
edit_page_file "$json_title" "Update $rel via GitHub Actions" "$file" "$token"
|
|
fi
|
|
|
|
lua_content=$'local loader = require("Module:JsonLoader")\nreturn loader.getFromTitle("'"$json_title"'")'
|
|
|
|
local_lines=$(printf '%s' "$lua_content" | awk 'END { print NR }')
|
|
remote_lines="${module_lines[$module_title]:-}"
|
|
|
|
if [[ -n "$remote_lines" && "$remote_lines" == "$local_lines" ]]; then
|
|
echo "Skipping unchanged module: $module_title"
|
|
else
|
|
echo "Creating/updating module → $module_title"
|
|
edit_page "$module_title" "Auto-create loader module for $rel" "$lua_content" "$token"
|
|
fi
|
|
done
|
|
done
|
|
|
|
# Создает страницы по каждому id подходящей сущности.
|
|
# Имя страницы формируется из имени сущности в entity_name.json.
|
|
- name: Create entity pages
|
|
if: ${{ github.event_name == 'workflow_dispatch' || steps.changes.outputs.prototypes == 'true' }}
|
|
continue-on-error: true
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
|
|
FILE="./bin/Content.Server/data/entity_name.json"
|
|
API="${{ secrets.WIKI_ROOT_URL }}/api.php"
|
|
USER="${{ secrets.WIKI_BOT_USER }}"
|
|
PASS="${{ secrets.WIKI_BOT_PASS }}"
|
|
NAMESPACE="${{ secrets.WIKI_BOT_NAMESPACE }}"
|
|
|
|
API="$(printf "%s" "$API" | tr -d '\r\n')"
|
|
USER="$(printf "%s" "$USER" | tr -d '\r\n')"
|
|
PASS="$(printf "%s" "$PASS" | tr -d '\r\n')"
|
|
NAMESPACE="$(printf "%s" "$NAMESPACE" | tr -d '\r\n')"
|
|
|
|
if [[ -n "$NAMESPACE" && "${NAMESPACE: -1}" != ":" ]]; then
|
|
NAMESPACE="${NAMESPACE}:"
|
|
fi
|
|
|
|
cookiejar="$(mktemp)"
|
|
trap 'rm -f "$cookiejar"' EXIT
|
|
|
|
login_token=$(curl -sS -c "$cookiejar" \
|
|
--data "action=query&meta=tokens&type=login&format=json" "$API" | jq -r '.query.tokens.logintoken')
|
|
|
|
curl -sS -c "$cookiejar" -b "$cookiejar" \
|
|
--data-urlencode "action=login" \
|
|
--data-urlencode "lgname=$USER" \
|
|
--data-urlencode "lgpassword=$PASS" \
|
|
--data-urlencode "lgtoken=$login_token" \
|
|
--data-urlencode "format=json" \
|
|
"$API" > /dev/null
|
|
|
|
token=$(curl -sS -b "$cookiejar" \
|
|
--data "action=query&meta=tokens&format=json" "$API" | jq -r '.query.tokens.csrftoken')
|
|
|
|
mapfile -t pages < <(
|
|
jq -r '
|
|
to_entries[]
|
|
| "\(.key)|\(.value | if type == "array" then .[0] else . end)"
|
|
' "$FILE" | grep -v '|$'
|
|
)
|
|
|
|
batch_size=50
|
|
|
|
for ((i=0; i<${#pages[@]}; i+=batch_size)); do
|
|
batch=("${pages[@]:i:batch_size}")
|
|
|
|
prefix=""
|
|
if [[ -n "$NAMESPACE" ]]; then
|
|
prefix="$NAMESPACE"
|
|
fi
|
|
|
|
titles=$(
|
|
printf '%s\n' "${batch[@]}" |
|
|
cut -d'|' -f1 |
|
|
awk -v p="$prefix" '{print p $0}' |
|
|
paste -sd'|' -
|
|
)
|
|
|
|
existing_titles=$(
|
|
curl -sS -b "$cookiejar" \
|
|
--data-urlencode "action=query" \
|
|
--data-urlencode "format=json" \
|
|
--data-urlencode "titles=$titles" \
|
|
"$API" | jq -r '
|
|
.query.pages[]
|
|
| select(has("missing") | not)
|
|
| .title
|
|
'
|
|
)
|
|
|
|
while IFS='|' read -r name id; do
|
|
[[ -z "${name:-}" ]] && continue
|
|
[[ -z "${id:-}" ]] && continue
|
|
|
|
if grep -Fxq "$NAMESPACE$name" <<< "$existing_titles"; then
|
|
echo "Skipping existing page: $NAMESPACE$name"
|
|
continue
|
|
fi
|
|
|
|
content="{{сущность|$id}}"
|
|
echo "Creating page: $NAMESPACE$name → $id"
|
|
|
|
curl -sS -b "$cookiejar" \
|
|
--data-urlencode "action=edit" \
|
|
--data-urlencode "createonly=true" \
|
|
--data-urlencode "title=$NAMESPACE$name" \
|
|
--data-urlencode "text=$content" \
|
|
--data-urlencode "summary=Create $id via GitHub Actions" \
|
|
--data-urlencode "token=$token" \
|
|
--data-urlencode "bot=true" \
|
|
--data-urlencode "minor=true" \
|
|
--data-urlencode "format=json" \
|
|
"$API" | jq -r '.edit.result // "null"' || true
|
|
done < <(printf '%s\n' "${batch[@]}")
|
|
done
|
|
|
|
# Добавляет предупреждение дубликатам страниц сущностей.
|
|
- name: Duplicates entity pages
|
|
if: ${{ github.event_name == 'workflow_dispatch' || steps.changes.outputs.prototypes == 'true' }}
|
|
continue-on-error: true
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
|
|
FILE="./bin/Content.Server/data/entity_name_wiki.json"
|
|
API="${{ secrets.WIKI_ROOT_URL }}/api.php"
|
|
USER="${{ secrets.WIKI_BOT_USER }}"
|
|
PASS="${{ secrets.WIKI_BOT_PASS }}"
|
|
|
|
API="$(printf "%s" "$API" | tr -d '\r\n')"
|
|
USER="$(printf "%s" "$USER" | tr -d '\r\n')"
|
|
PASS="$(printf "%s" "$PASS" | tr -d '\r\n')"
|
|
|
|
cookiejar="$(mktemp)"
|
|
trap 'rm -f "$cookiejar"' EXIT
|
|
warning="{{сущность/infobox|тип=дубликат}}"
|
|
|
|
login_token=$(curl -sS -c "$cookiejar" \
|
|
--data "action=query&meta=tokens&type=login&format=json" "$API" | jq -r '.query.tokens.logintoken')
|
|
|
|
curl -sS -c "$cookiejar" -b "$cookiejar" \
|
|
--data-urlencode "action=login" \
|
|
--data-urlencode "lgname=$USER" \
|
|
--data-urlencode "lgpassword=$PASS" \
|
|
--data-urlencode "lgtoken=$login_token" \
|
|
--data-urlencode "format=json" \
|
|
"$API" > /dev/null
|
|
|
|
token=$(curl -sS -b "$cookiejar" \
|
|
--data "action=query&meta=tokens&format=json" "$API" | jq -r '.query.tokens.csrftoken')
|
|
|
|
jq -r '.[]' "$FILE" |
|
|
xargs -r -d '\n' -P 1 -I{} bash -c '
|
|
set -uo pipefail
|
|
title="$1"
|
|
api="$2"
|
|
token="$3"
|
|
cookiejar="$4"
|
|
warning="$5"
|
|
|
|
if [[ -z "$title" ]]; then
|
|
exit 0
|
|
fi
|
|
|
|
page_json=$(curl -sS -b "$cookiejar" \
|
|
--data-urlencode "action=query" \
|
|
--data-urlencode "prop=revisions" \
|
|
--data-urlencode "rvprop=content" \
|
|
--data-urlencode "rvslots=main" \
|
|
--data-urlencode "format=json" \
|
|
--data-urlencode "titles=$title" \
|
|
"$api")
|
|
|
|
content=$(printf "%s" "$page_json" | jq -r \
|
|
".query.pages | to_entries[0].value.revisions[0].slots.main[\"*\"] // \"\"")
|
|
|
|
if printf "%s" "$content" | grep -Fq "$warning"; then
|
|
echo "Skipping (already has warning): $title"
|
|
exit 0
|
|
fi
|
|
|
|
echo "Prepending Infobox to: $title"
|
|
|
|
curl -sS -b "$cookiejar" \
|
|
--data-urlencode "action=edit" \
|
|
--data-urlencode "title=$title" \
|
|
--data-urlencode "prependtext=${warning}" \
|
|
--data-urlencode "summary=Add Warning via GitHub Actions" \
|
|
--data-urlencode "token=$token" \
|
|
--data-urlencode "bot=true" \
|
|
--data-urlencode "minor=true" \
|
|
--data-urlencode "format=json" \
|
|
"$api" | jq -r ".edit.result // \"null\"" || true
|
|
' _ "{}" "$API" "$token" "$cookiejar" "$warning"
|