Browse Source
# Conflicts: # lgsm/modules/command_stop.sh # lgsm/modules/update_xnt.shpull/4860/head
371 changed files with 6017 additions and 1419 deletions
@ -1,30 +1,30 @@ |
|||
{ |
|||
"name": "BASH Dev Container", |
|||
"image": "mcr.microsoft.com/devcontainers/base:ubuntu", |
|||
"features": { |
|||
"ghcr.io/devcontainers-community/npm-features/prettier:1": { |
|||
"plugins": "prettier-plugin-sh" |
|||
}, |
|||
"ghcr.io/devcontainers-extra/features/actionlint:1": {}, |
|||
"ghcr.io/devcontainers-extra/features/checkov:1": {}, |
|||
"ghcr.io/devcontainers-extra/features/markdownlint-cli:1": {}, |
|||
"ghcr.io/devcontainers-extra/features/shellcheck:1": {}, |
|||
"ghcr.io/devcontainers-extra/features/yamllint:2": {}, |
|||
"ghcr.io/devcontainers/features/github-cli:1": {} |
|||
}, |
|||
"customizations": { |
|||
"vscode": { |
|||
"extensions": [ |
|||
"DavidAnson.vscode-markdownlint", |
|||
"editorconfig.editorconfig", |
|||
"esbenp.prettier-vscode", |
|||
"github.vscode-github-actions", |
|||
"GitHub.vscode-pull-request-github", |
|||
"redhat.vscode-yaml", |
|||
"timonwong.shellcheck", |
|||
"yzhang.markdown-all-in-one" |
|||
] |
|||
} |
|||
}, |
|||
"postCreateCommand": "npm init -y >/dev/null 2>&1 || true && npm install --no-save prettier prettier-plugin-sh prettier-plugin-jinja-template" |
|||
"name": "BASH Dev Container", |
|||
"image": "mcr.microsoft.com/devcontainers/base:ubuntu", |
|||
"features": { |
|||
"ghcr.io/devcontainers-community/npm-features/prettier:1": { |
|||
"plugins": "prettier-plugin-sh" |
|||
}, |
|||
"ghcr.io/devcontainers-extra/features/actionlint:1": {}, |
|||
"ghcr.io/devcontainers-extra/features/checkov:1": {}, |
|||
"ghcr.io/devcontainers-extra/features/markdownlint-cli:1": {}, |
|||
"ghcr.io/devcontainers-extra/features/shellcheck:1": {}, |
|||
"ghcr.io/devcontainers-extra/features/yamllint:2": {}, |
|||
"ghcr.io/devcontainers/features/github-cli:1": {} |
|||
}, |
|||
"customizations": { |
|||
"vscode": { |
|||
"extensions": [ |
|||
"DavidAnson.vscode-markdownlint", |
|||
"editorconfig.editorconfig", |
|||
"esbenp.prettier-vscode", |
|||
"github.vscode-github-actions", |
|||
"GitHub.vscode-pull-request-github", |
|||
"redhat.vscode-yaml", |
|||
"timonwong.shellcheck", |
|||
"yzhang.markdown-all-in-one" |
|||
] |
|||
} |
|||
}, |
|||
"postCreateCommand": "npm init -y >/dev/null 2>&1 || true && npm install --no-save prettier prettier-plugin-sh prettier-plugin-jinja-template" |
|||
} |
|||
|
|||
@ -0,0 +1,29 @@ |
|||
--- |
|||
title: "LinuxGSM PR Review Guidance" |
|||
applyTo: "**" |
|||
description: "Use when reviewing pull requests in LinuxGSM; prioritize regressions, behavior changes, shell safety, and missing tests over style-only feedback." |
|||
--- |
|||
|
|||
Focus review effort on correctness and operational safety first. |
|||
|
|||
Primary priorities: |
|||
|
|||
- Identify behavior regressions and compatibility risks. |
|||
- Flag unsafe shell patterns (`rm -rf`, unquoted vars, unchecked command failures). |
|||
- Verify workflow changes do not weaken permissions or secret handling. |
|||
- Check for missing tests/validation when logic changes. |
|||
- Confirm labels, templates, and automation rules stay internally consistent. |
|||
|
|||
Feedback expectations: |
|||
|
|||
- Give concrete, actionable findings with file and reason. |
|||
- Prefer high-signal issues over style nits. |
|||
- If no defects are found, state that clearly and mention residual risk areas. |
|||
- Suggest minimal, low-risk fixes before proposing broad refactors. |
|||
|
|||
LinuxGSM-specific checks: |
|||
|
|||
- Shell scripts should preserve robust defaults (`set -euo pipefail` where appropriate). |
|||
- Label/workflow updates should avoid duplicate or stale taxonomy. |
|||
- Automation should fail safe (log and continue for advisory AI; block on true CI errors). |
|||
- Keep issue/PR automation rules aligned with templates and existing labels. |
|||
@ -0,0 +1,11 @@ |
|||
[codespell] |
|||
# Skip data tables that contain many short server identifiers (e.g. "fof", "nd") |
|||
skip = |
|||
lgsm/data/*.csv, |
|||
package-lock.json, |
|||
*/package-lock.json, |
|||
node_modules, |
|||
*/node_modules/* |
|||
|
|||
# Ignore common identifiers/acronyms and extensions used throughout LinuxGSM |
|||
ignore-words-list = distroname,fof,nd,sav,parms,ThirdParty |
|||
@ -0,0 +1,2 @@ |
|||
[flake8] |
|||
max-line-length = 120 |
|||
@ -0,0 +1,9 @@ |
|||
title = "LinuxGSM Gitleaks Config" |
|||
|
|||
[allowlist] |
|||
description = "Known false positives" |
|||
regexes = [ |
|||
# Google Analytics 4 Measurement Protocol API secret - not a sensitive credential, |
|||
# it is intentionally embedded in client-side code and is safe to be public. |
|||
'''apisecret="[A-Za-z0-9_\-]+"''', |
|||
] |
|||
@ -0,0 +1,20 @@ |
|||
# Configuration for markdownlint (used by Super Linter) |
|||
|
|||
# MD041: README starts with HTML badges in this repo. |
|||
MD041: false |
|||
|
|||
# MD051: GitHub heading anchor generation can differ (emoji, punctuation). |
|||
MD051: false |
|||
|
|||
# MD013: The project documentation frequently contains long URLs/commands. |
|||
MD013: false |
|||
|
|||
# MD033: The main README uses inline HTML for badges. |
|||
MD033: false |
|||
|
|||
# MD007: Repo uses 2-space indentation for nested lists. |
|||
MD007: |
|||
indent: 2 |
|||
|
|||
# MD030: Repo mixes 1-space unordered and 2-space ordered list markers. |
|||
MD030: false |
|||
@ -0,0 +1 @@ |
|||
disable=SC2154,SC2034 |
|||
@ -0,0 +1,25 @@ |
|||
extends: default |
|||
|
|||
rules: |
|||
document-start: disable |
|||
truthy: disable |
|||
|
|||
line-length: |
|||
max: 200 |
|||
level: warning |
|||
allow-non-breakable-words: true |
|||
allow-non-breakable-inline-mappings: true |
|||
|
|||
braces: |
|||
min-spaces-inside: 0 |
|||
max-spaces-inside: 1 |
|||
min-spaces-inside-empty: 0 |
|||
max-spaces-inside-empty: 0 |
|||
|
|||
empty-lines: |
|||
max: 2 |
|||
max-start: 0 |
|||
max-end: 0 |
|||
|
|||
comments: |
|||
min-spaces-from-content: 1 |
|||
@ -0,0 +1,50 @@ |
|||
#!/bin/bash |
|||
|
|||
ref="${LGSM_REF:-${GITHUB_REF#refs/heads/}}" |
|||
curl "https://raw.githubusercontent.com/GameServerManagers/LinuxGSM/${ref}/lgsm/data/serverlist.csv" | grep -v '^[[:blank:]]*$' > serverlist.csv |
|||
|
|||
echo -n "{" > "shortnamearray.json" |
|||
echo -n "\"include\":[" >> "shortnamearray.json" |
|||
|
|||
while read -r line; do |
|||
shortname=$(echo "$line" | awk -F, '{ print $1 }') |
|||
# If TARGETED_SHORTNAMES is set, skip servers not in the list |
|||
if [ -n "${TARGETED_SHORTNAMES:-}" ]; then |
|||
if ! echo "${TARGETED_SHORTNAMES}" | grep -qw "${shortname}"; then |
|||
continue |
|||
fi |
|||
fi |
|||
export shortname |
|||
servername=$(echo "$line" | awk -F, '{ print $2 }') |
|||
export servername |
|||
gamename=$(echo "$line" | awk -F, '{ print $3 }') |
|||
export gamename |
|||
distro=$(echo "$line" | awk -F, '{ print $4 }') |
|||
export distro |
|||
# Legacy servers that require older Ubuntu/Debian versions due to glibc compatibility |
|||
case "${shortname}" in |
|||
bfv | bf1942) |
|||
# Requires Ubuntu <= 22.04 or Debian <= 12 (glibc 2.31 compatible) |
|||
runner="ubuntu-22.04" |
|||
;; |
|||
btl | onset) |
|||
# Requires Ubuntu <= 20.04 or Debian <= 11 (glibc 2.31 compatible) |
|||
runner="ubuntu-20.04" |
|||
;; |
|||
*) |
|||
runner="ubuntu-latest" |
|||
;; |
|||
esac |
|||
{ |
|||
echo -n "{" |
|||
echo -n "\"shortname\":" |
|||
echo -n "\"${shortname}\"" |
|||
echo -n ",\"runner\":" |
|||
echo -n "\"${runner}\"" |
|||
echo -n "}," |
|||
} >> "shortnamearray.json" |
|||
done < <(tail -n +2 serverlist.csv) |
|||
sed -i '$ s/.$//' "shortnamearray.json" |
|||
echo -n "]" >> "shortnamearray.json" |
|||
echo -n "}" >> "shortnamearray.json" |
|||
rm serverlist.csv |
|||
@ -0,0 +1,87 @@ |
|||
#!/usr/bin/env bash |
|||
# sync-game-labels.sh |
|||
# Reads lgsm/data/serverlist.csv and ensures a "game: <name>" label exists in |
|||
# the GitHub repo for every unique game name. Safe to run multiple times. |
|||
# |
|||
# Requires: gh CLI authenticated with issues:write scope. |
|||
# Usage: .github/scripts/sync-game-labels.sh [OWNER/REPO] |
|||
# |
|||
# The OWNER/REPO argument is optional; if omitted gh uses the current repo. |
|||
|
|||
set -euo pipefail |
|||
|
|||
REPO="${1:-}" |
|||
SERVERLIST="lgsm/data/serverlist.csv" |
|||
LABEL_COLOR="5b21b6" |
|||
LABEL_PREFIX="game: " |
|||
|
|||
normalize_label() { |
|||
printf '%s' "$1" | tr '[:upper:]' '[:lower:]' |
|||
} |
|||
|
|||
if [[ ! -f "${SERVERLIST}" ]]; then |
|||
echo "ERROR: ${SERVERLIST} not found. Run from the repository root." |
|||
exit 1 |
|||
fi |
|||
|
|||
declare -A EXISTING_COLORS=() |
|||
declare -A EXISTING_DESCRIPTIONS=() |
|||
declare -A EXISTING_NAMES=() |
|||
|
|||
# Fetch all existing game label metadata once (up to 1000) and cache locally. |
|||
echo "Fetching existing labels..." |
|||
while IFS=$'\t' read -r NAME COLOR DESCRIPTION; do |
|||
[[ -n "${NAME}" ]] || continue |
|||
EXISTING_COLORS["${NAME}"]="${COLOR}" |
|||
EXISTING_DESCRIPTIONS["${NAME}"]="${DESCRIPTION}" |
|||
EXISTING_NAMES["$(normalize_label "${NAME}")"]="${NAME}" |
|||
done < <( |
|||
gh label list --limit 1000 --json name,color,description ${REPO:+--repo "$REPO"} \ |
|||
| jq -r '.[] | select(.name | startswith("game: ")) | [.name, .color, (.description // "")] | @tsv' |
|||
) |
|||
|
|||
# Parse unique game names from the CSV (column 3, skip header). |
|||
mapfile -t GAMES < <( |
|||
tail -n +2 "${SERVERLIST}" \ |
|||
| cut -d',' -f3 \ |
|||
| sort -u |
|||
) |
|||
|
|||
CREATED=0 |
|||
UPDATED=0 |
|||
UNCHANGED=0 |
|||
|
|||
for GAME in "${GAMES[@]}"; do |
|||
LABEL="${LABEL_PREFIX}${GAME}" |
|||
DESCRIPTION="Issues related to ${GAME}" |
|||
NORMALIZED_LABEL="$(normalize_label "${LABEL}")" |
|||
|
|||
if [[ -v EXISTING_NAMES["${NORMALIZED_LABEL}"] ]]; then |
|||
CURRENT_LABEL="${EXISTING_NAMES["${NORMALIZED_LABEL}"]}" |
|||
CURRENT_COLOR="${EXISTING_COLORS["${CURRENT_LABEL}"]}" |
|||
CURRENT_DESCRIPTION="${EXISTING_DESCRIPTIONS["${CURRENT_LABEL}"]}" |
|||
|
|||
if [[ "${CURRENT_LABEL}" != "${LABEL}" || "${CURRENT_COLOR}" != "${LABEL_COLOR}" || "${CURRENT_DESCRIPTION}" != "${DESCRIPTION}" ]]; then |
|||
echo " update ${LABEL}" |
|||
gh label edit "${CURRENT_LABEL}" \ |
|||
--name "${LABEL}" \ |
|||
--color "${LABEL_COLOR}" \ |
|||
--description "${DESCRIPTION}" \ |
|||
${REPO:+--repo "$REPO"} |
|||
((UPDATED++)) || true |
|||
else |
|||
echo " ok ${LABEL}" |
|||
((UNCHANGED++)) || true |
|||
fi |
|||
else |
|||
echo " create ${LABEL}" |
|||
gh label create "${LABEL}" \ |
|||
--color "${LABEL_COLOR}" \ |
|||
--description "${DESCRIPTION}" \ |
|||
${REPO:+--repo "$REPO"} |
|||
((CREATED++)) || true |
|||
fi |
|||
done |
|||
|
|||
echo "" |
|||
echo "Done. Created: ${CREATED} Updated: ${UPDATED} Unchanged: ${UNCHANGED}" |
|||
@ -1,29 +0,0 @@ |
|||
name: Update copyright year(s) in license file |
|||
|
|||
on: |
|||
workflow_dispatch: |
|||
schedule: |
|||
- cron: "0 3 1 1 *" # 03:00 AM on January 1 |
|||
|
|||
permissions: |
|||
contents: write |
|||
|
|||
jobs: |
|||
update-license-year: |
|||
runs-on: ubuntu-latest |
|||
steps: |
|||
- name: Checkout |
|||
uses: actions/checkout@v5 |
|||
with: |
|||
fetch-depth: 0 |
|||
persist-credentials: false |
|||
- name: Action Update License Year |
|||
uses: FantasticFiasco/action-update-license-year@v3 |
|||
with: |
|||
token: ${{ secrets.GITHUB_TOKEN }} |
|||
path: LICENSE.md |
|||
- name: Merge pull request |
|||
env: |
|||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
|||
run: | |
|||
gh pr merge --merge --delete-branch |
|||
@ -0,0 +1,243 @@ |
|||
name: AI Issue Triage |
|||
on: |
|||
issues: |
|||
types: |
|||
- opened |
|||
- edited |
|||
|
|||
# Note: This workflow uses GitHub Models which may not be available |
|||
# in all environments. If GitHub Models API returns 401 or is unavailable, |
|||
# the workflow will skip gracefully and the issue will still be processed |
|||
# by other automation (labeler, etc.) |
|||
|
|||
permissions: |
|||
issues: write |
|||
contents: read |
|||
models: read |
|||
|
|||
jobs: |
|||
ai-triage: |
|||
if: github.repository_owner == 'GameServerManagers' |
|||
runs-on: ubuntu-latest |
|||
steps: |
|||
- name: Triage issue with GitHub Models |
|||
uses: actions/github-script@v7 |
|||
env: |
|||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
|||
with: |
|||
script: | |
|||
const title = context.payload.issue.title || ''; |
|||
const body = context.payload.issue.body || ''; |
|||
const number = context.payload.issue.number; |
|||
const owner = context.repo.owner; |
|||
const repo = context.repo.repo; |
|||
const AI_MARKER = '<!-- ai-triage -->'; |
|||
|
|||
function parseTriageResponse(raw) { |
|||
const input = (raw || '').trim(); |
|||
if (!input) return {}; |
|||
|
|||
const candidates = [input]; |
|||
const fenced = input.match(/```(?:json)?\s*([\s\S]*?)```/i); |
|||
if (fenced?.[1]) candidates.push(fenced[1].trim()); |
|||
|
|||
const firstBrace = input.indexOf('{'); |
|||
const lastBrace = input.lastIndexOf('}'); |
|||
if (firstBrace !== -1 && lastBrace > firstBrace) { |
|||
candidates.push(input.slice(firstBrace, lastBrace + 1)); |
|||
} |
|||
|
|||
for (const candidate of candidates) { |
|||
try { |
|||
return JSON.parse(candidate); |
|||
} catch (_err) { |
|||
// Continue trying fallbacks. |
|||
} |
|||
} |
|||
|
|||
return {}; |
|||
} |
|||
|
|||
// For short bodies, apply "needs: more info" label directly. |
|||
// Skip the AI call but still label the issue. |
|||
const isShortBody = body.trim().length < 80; |
|||
if (isShortBody) { |
|||
try { |
|||
await github.rest.issues.addLabels({ |
|||
owner, repo, issue_number: number, |
|||
labels: ['needs: more info'], |
|||
}); |
|||
} catch (err) { |
|||
console.log('Could not apply label for short body:', err.message); |
|||
} |
|||
return; |
|||
} |
|||
|
|||
// ── Call GitHub Models ──────────────────────────────────────── |
|||
// Note: GitHub Models access may not be available in all environments. |
|||
// If the API returns 401 (Unauthorized), it means GitHub Models is not |
|||
// enabled for this repository or the current token lacks access. |
|||
// The workflow will gracefully skip AI triage and continue. |
|||
let triage; |
|||
try { |
|||
const res = await fetch( |
|||
`https://models.github.ai/orgs/${owner}/inference/chat/completions`, |
|||
{ |
|||
method: 'POST', |
|||
headers: { |
|||
'Accept': 'application/vnd.github+json', |
|||
'Authorization': `Bearer ${process.env.GITHUB_TOKEN}`, |
|||
'X-GitHub-Api-Version': '2026-03-10', |
|||
'Content-Type': 'application/json', |
|||
}, |
|||
body: JSON.stringify({ |
|||
model: 'openai/gpt-4.1-mini', |
|||
temperature: 0.1, |
|||
max_tokens: 400, |
|||
messages: [ |
|||
{ |
|||
role: 'system', |
|||
content: |
|||
'You are a triage assistant for LinuxGSM, an open-source ' + |
|||
'Linux game server manager. Your role is to:\n' + |
|||
'1. Analyze issue quality (completeness, clarity)\n' + |
|||
'2. Extract game names mentioned in the issue, even if misspelled or abbreviated\n' + |
|||
'3. Suggest corrections for likely typos using fuzzy matching\n' + |
|||
'4. Respond ONLY with a valid JSON object — no markdown fences.\n\n' + |
|||
'Common game name variations and typos you should recognize:\n' + |
|||
'- "Valhiem" → "Valheim"\n' + |
|||
'- "Rrust" → "Rust"\n' + |
|||
'- "Conterstrike" / "CS" / "CSGO" → "Counter-Strike: Global Offensive"\n' + |
|||
'- "Garrys" / "GMod" → "Garrys Mod"\n' + |
|||
'- "ARK" / "Ark" → "ARK: Survival Evolved"\n' + |
|||
'- "DayZ" / "Dayz" → "DayZ"\n' + |
|||
'- "Insurgency Sandstorm" / "Insurgency 2" → "Insurgency: Sandstorm"', |
|||
}, |
|||
{ |
|||
role: 'user', |
|||
content: |
|||
`Title: ${title}\n\nBody:\n${body.slice(0, 3000)}\n\n` + |
|||
'Respond with this JSON schema:\n' + |
|||
'{\n' + |
|||
' "quality": "good" | "ok" | "poor",\n' + |
|||
' "missing_info": ["list of specific missing fields"],\n' + |
|||
' "detected_game": "canonical game name if one is mentioned, or null",\n' + |
|||
' "game_confidence": "high" | "medium" | "low" | null,\n' + |
|||
' "game_note": "correction suggestion if the user misspelled a game name, or empty string",\n' + |
|||
' "comment": "one or two sentence note to the reporter, or empty string"\n' + |
|||
'}', |
|||
}, |
|||
], |
|||
}), |
|||
} |
|||
); |
|||
|
|||
// GitHub Models may return 401 if not available for this repository. |
|||
// This is expected and not an error — the workflow simply skips AI triage. |
|||
if (!res.ok) { |
|||
console.log(`GitHub Models returned ${res.status} — skipping AI triage.`); |
|||
return; |
|||
} |
|||
|
|||
const data = await res.json(); |
|||
const raw = data.choices?.[0]?.message?.content || '{}'; |
|||
triage = parseTriageResponse(raw); |
|||
} catch (err) { |
|||
// Never fail the workflow if the AI call errors — it's advisory only. |
|||
console.log('AI triage skipped:', err.message); |
|||
return; |
|||
} |
|||
|
|||
if (!triage || typeof triage !== 'object') { |
|||
triage = {}; |
|||
} |
|||
|
|||
// ── Act on the result ──────────────────────────────────────── |
|||
const isPoor = triage.quality === 'poor'; |
|||
const missing = Array.isArray(triage.missing_info) ? triage.missing_info : []; |
|||
const hasIssues = isPoor || missing.length > 0; |
|||
|
|||
// Prepare labels to apply |
|||
const labelsToApply = []; |
|||
|
|||
// Check if a game was detected with high confidence |
|||
const detectedGame = triage.detected_game; |
|||
const gameConfidence = triage.game_confidence; |
|||
|
|||
if (detectedGame && gameConfidence === 'high') { |
|||
labelsToApply.push(`game: ${detectedGame}`); |
|||
} |
|||
|
|||
// Apply "needs: more info" label if quality issues detected |
|||
if (hasIssues) { |
|||
labelsToApply.push('needs: more info'); |
|||
} |
|||
|
|||
// Apply labels one-by-one so a single failure does not block all labels. |
|||
const uniqueLabels = [...new Set(labelsToApply)]; |
|||
for (const label of uniqueLabels) { |
|||
try { |
|||
await github.rest.issues.addLabels({ |
|||
owner, |
|||
repo, |
|||
issue_number: number, |
|||
labels: [label], |
|||
}); |
|||
} catch (err) { |
|||
console.log(`Could not apply label "${label}":`, err.message); |
|||
} |
|||
} |
|||
|
|||
// Post a comment only when there is something specific to say |
|||
const gameNote = triage.game_note || ''; |
|||
const reporterComment = triage.comment || ''; |
|||
|
|||
if (!hasIssues && !gameNote) return; |
|||
|
|||
const missingBlock = missing.length > 0 |
|||
? `\n\n**Missing information:**\n${missing.map(m => `- ${m}`).join('\n')}` |
|||
: ''; |
|||
|
|||
const gameBlock = gameNote |
|||
? `\n\n**Game name note:** ${gameNote}` |
|||
: ''; |
|||
|
|||
const triageCommentBody = |
|||
`${AI_MARKER}\n` + |
|||
`Thanks for opening this issue! 👋\n\n` + |
|||
`${reporterComment}` + |
|||
`${missingBlock}` + |
|||
`${gameBlock}\n\n` + |
|||
`_This note was generated automatically by AI triage and may not be perfect. ` + |
|||
`A maintainer will review shortly._`; |
|||
|
|||
try { |
|||
const comments = await github.rest.issues.listComments({ |
|||
owner, |
|||
repo, |
|||
issue_number: number, |
|||
per_page: 100, |
|||
}); |
|||
|
|||
const existingAiComment = comments.data.find( |
|||
(comment) => comment.user?.type === 'Bot' && comment.body?.includes(AI_MARKER) |
|||
); |
|||
|
|||
if (existingAiComment) { |
|||
await github.rest.issues.updateComment({ |
|||
owner, |
|||
repo, |
|||
comment_id: existingAiComment.id, |
|||
body: triageCommentBody, |
|||
}); |
|||
} else { |
|||
await github.rest.issues.createComment({ |
|||
owner, |
|||
repo, |
|||
issue_number: number, |
|||
body: triageCommentBody, |
|||
}); |
|||
} |
|||
} catch (err) { |
|||
console.log('Could not post comment:', err.message); |
|||
} |
|||
@ -1,25 +0,0 @@ |
|||
#!/bin/bash |
|||
|
|||
curl "https://raw.githubusercontent.com/GameServerManagers/LinuxGSM/${GITHUB_REF#refs/heads/}/lgsm/data/serverlist.csv" | grep -v '^[[:blank:]]*$' > serverlist.csv |
|||
|
|||
echo -n "{" > "shortnamearray.json" |
|||
echo -n "\"include\":[" >> "shortnamearray.json" |
|||
|
|||
while read -r line; do |
|||
shortname=$(echo "$line" | awk -F, '{ print $1 }') |
|||
export shortname |
|||
servername=$(echo "$line" | awk -F, '{ print $2 }') |
|||
export servername |
|||
gamename=$(echo "$line" | awk -F, '{ print $3 }') |
|||
export gamename |
|||
distro=$(echo "$line" | awk -F, '{ print $4 }') |
|||
export distro |
|||
echo -n "{" >> "shortnamearray.json" |
|||
echo -n "\"shortname\":" >> "shortnamearray.json" |
|||
echo -n "\"${shortname}\"" >> "shortnamearray.json" |
|||
echo -n "}," >> "shortnamearray.json" |
|||
done < <(tail -n +2 serverlist.csv) |
|||
sed -i '$ s/.$//' "shortnamearray.json" |
|||
echo -n "]" >> "shortnamearray.json" |
|||
echo -n "}" >> "shortnamearray.json" |
|||
rm serverlist.csv |
|||
@ -4,14 +4,24 @@ on: |
|||
types: |
|||
- opened |
|||
- edited |
|||
pull_request: |
|||
types: |
|||
- opened |
|||
- edited |
|||
- synchronize |
|||
- reopened |
|||
|
|||
permissions: |
|||
issues: write |
|||
pull-requests: write |
|||
contents: read |
|||
|
|||
env: |
|||
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true" |
|||
|
|||
jobs: |
|||
issue-labeler: |
|||
if: github.repository_owner == 'GameServerManagers' |
|||
if: github.repository_owner == 'GameServerManagers' && github.event_name == 'issues' |
|||
runs-on: ubuntu-latest |
|||
steps: |
|||
- name: Issue Labeler |
|||
@ -21,12 +31,28 @@ jobs: |
|||
configuration-path: .github/labeler.yml |
|||
enable-versioned-regex: 0 |
|||
include-title: 1 |
|||
sync-labels: 1 |
|||
|
|||
pr-labeler: |
|||
if: github.repository_owner == 'GameServerManagers' && github.event_name == 'pull_request' |
|||
runs-on: ubuntu-latest |
|||
steps: |
|||
- name: PR Labeler |
|||
uses: github/[email protected] |
|||
with: |
|||
repo-token: "${{ secrets.GITHUB_TOKEN }}" |
|||
configuration-path: .github/labeler.yml |
|||
enable-versioned-regex: 0 |
|||
include-title: 1 |
|||
include-body: 0 |
|||
sync-labels: 1 |
|||
|
|||
is-sponsor-label: |
|||
if: github.repository_owner == 'GameServerManagers' |
|||
if: github.repository_owner == 'GameServerManagers' && github.event_name == 'issues' |
|||
runs-on: ubuntu-latest |
|||
steps: |
|||
- name: Is Sponsor Label |
|||
if: github.event.action == 'opened' |
|||
uses: JasonEtco/is-sponsor-label-action@v2 |
|||
env: |
|||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
|||
|
|||
@ -0,0 +1,28 @@ |
|||
name: Sync Game Labels |
|||
on: |
|||
push: |
|||
branches: |
|||
- master |
|||
- develop |
|||
paths: |
|||
- "lgsm/data/serverlist.csv" |
|||
workflow_dispatch: {} |
|||
|
|||
permissions: |
|||
issues: write |
|||
contents: read |
|||
|
|||
jobs: |
|||
sync-game-labels: |
|||
if: github.repository_owner == 'GameServerManagers' |
|||
runs-on: ubuntu-latest |
|||
steps: |
|||
- name: Checkout |
|||
uses: actions/checkout@v5 |
|||
|
|||
- name: Sync game labels from serverlist |
|||
env: |
|||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
|||
run: | |
|||
chmod +x .github/scripts/sync-game-labels.sh |
|||
.github/scripts/sync-game-labels.sh |
|||
@ -6,6 +6,8 @@ on: |
|||
types: |
|||
- published |
|||
|
|||
permissions: {} |
|||
|
|||
jobs: |
|||
trigger_build_docker-linuxgsm: |
|||
if: github.repository_owner == 'GameServerManagers' |
|||
@ -13,12 +15,22 @@ jobs: |
|||
runs-on: ubuntu-latest |
|||
steps: |
|||
- name: Trigger Workflow and Wait (linuxgsm) |
|||
uses: convictional/[email protected] |
|||
with: |
|||
owner: GameServerManagers |
|||
repo: docker-linuxgsm |
|||
github_token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} |
|||
workflow_file_name: action-docker-publish.yml |
|||
env: |
|||
GH_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }} |
|||
run: | |
|||
before=$(date -u +%Y-%m-%dT%H:%M:%SZ) |
|||
gh workflow run action-docker-publish.yml --repo GameServerManagers/docker-linuxgsm |
|||
sleep 10 |
|||
run_id=$(gh run list \ |
|||
--workflow action-docker-publish.yml \ |
|||
--repo GameServerManagers/docker-linuxgsm \ |
|||
--created ">=${before}" \ |
|||
--limit 1 \ |
|||
--json databaseId \ |
|||
--jq '.[0].databaseId') |
|||
gh run watch "${run_id}" \ |
|||
--repo GameServerManagers/docker-linuxgsm \ |
|||
--exit-status |
|||
|
|||
trigger_build_docker-gameserver: |
|||
if: github.repository_owner == 'GameServerManagers' |
|||
@ -27,9 +39,19 @@ jobs: |
|||
runs-on: ubuntu-latest |
|||
steps: |
|||
- name: Trigger Workflow and Wait (gameserver) |
|||
uses: convictional/[email protected] |
|||
with: |
|||
owner: GameServerManagers |
|||
repo: docker-gameserver |
|||
github_token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} |
|||
workflow_file_name: action-docker-publish.yml |
|||
env: |
|||
GH_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }} |
|||
run: | |
|||
before=$(date -u +%Y-%m-%dT%H:%M:%SZ) |
|||
gh workflow run action-docker-publish.yml --repo GameServerManagers/docker-gameserver |
|||
sleep 10 |
|||
run_id=$(gh run list \ |
|||
--workflow action-docker-publish.yml \ |
|||
--repo GameServerManagers/docker-gameserver \ |
|||
--created ">=${before}" \ |
|||
--limit 1 \ |
|||
--json databaseId \ |
|||
--jq '.[0].databaseId') |
|||
gh run watch "${run_id}" \ |
|||
--repo GameServerManagers/docker-gameserver \ |
|||
--exit-status |
|||
|
|||
@ -0,0 +1,7 @@ |
|||
# Prettier auto-commit runs with GITHUB_TOKEN (GitHub App). |
|||
# GitHub blocks that token from creating/updating anything under .github/workflows. |
|||
.github/workflows/** |
|||
|
|||
# Machine-generated by npm; its format is owned by npm, not Prettier. |
|||
# Prettier reformatting it fights npm and makes the auto-commit run fail. |
|||
package-lock.json |
|||
@ -1,3 +1,3 @@ |
|||
{ |
|||
"plugins": ["prettier-plugin-sh"] |
|||
"plugins": ["prettier-plugin-sh"] |
|||
} |
|||
|
|||
@ -1,3 +1,3 @@ |
|||
{ |
|||
"plugins": ["prettier-plugin-sh"] |
|||
"plugins": ["prettier-plugin-sh"] |
|||
} |
|||
|
|||
@ -1 +1 @@ |
|||
disable=SC2154 |
|||
disable=SC2154,SC2034 |
|||
|
|||
@ -1,12 +1,12 @@ |
|||
{ |
|||
"recommendations": [ |
|||
"DavidAnson.vscode-markdownlint", |
|||
"editorconfig.editorconfig", |
|||
"esbenp.prettier-vscode", |
|||
"github.vscode-github-actions", |
|||
"GitHub.vscode-pull-request-github", |
|||
"redhat.vscode-yaml", |
|||
"timonwong.shellcheck", |
|||
"yzhang.markdown-all-in-one" |
|||
] |
|||
"recommendations": [ |
|||
"DavidAnson.vscode-markdownlint", |
|||
"editorconfig.editorconfig", |
|||
"esbenp.prettier-vscode", |
|||
"github.vscode-github-actions", |
|||
"GitHub.vscode-pull-request-github", |
|||
"redhat.vscode-yaml", |
|||
"timonwong.shellcheck", |
|||
"yzhang.markdown-all-in-one" |
|||
] |
|||
} |
|||
|
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue