Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
162 changes: 162 additions & 0 deletions .github/workflows/validate-plugin-smoke.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
name: Validate Plugin Smoke

on:
pull_request:
paths:
- "plugins.json"
- "scripts/validate_plugins/**"
- ".github/workflows/validate-plugin-smoke.yml"
workflow_dispatch:
inputs:
plugin_names:
description: "Comma-separated plugin keys from plugins.json"
required: false
default: ""
plugin_limit:
description: "Validate the first N plugins when plugin_names is empty. Leave blank or use -1 for all plugins"
required: false
default: ""
astrbot_ref:
description: "AstrBot git ref to validate against"
required: false
default: "master"

jobs:
validate-plugin-smoke:
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Set manual validation inputs
if: github.event_name == 'workflow_dispatch'
run: |
echo "ASTRBOT_REF=${{ inputs.astrbot_ref }}" >> "$GITHUB_ENV"
echo "PLUGIN_NAME_LIST=${{ inputs.plugin_names }}" >> "$GITHUB_ENV"
echo "PLUGIN_LIMIT=${{ inputs.plugin_limit }}" >> "$GITHUB_ENV"
echo "SHOULD_VALIDATE=true" >> "$GITHUB_ENV"

- name: Detect changed plugins from pull request
if: github.event_name == 'pull_request'
run: |
python - <<'PY'
import json
import os
import subprocess
import sys
from pathlib import Path

base_ref = os.environ["GITHUB_BASE_REF"]
subprocess.run(["git", "fetch", "origin", base_ref, "--depth", "1"], check=True)

validation_note = ""

try:
base_raw = subprocess.check_output(
["git", "show", f"origin/{base_ref}:plugins.json"],
text=True,
stderr=subprocess.DEVNULL,
)
base = json.loads(base_raw)
if not isinstance(base, dict):
base = {}
except (subprocess.CalledProcessError, json.JSONDecodeError):
Comment thread
sourcery-ai[bot] marked this conversation as resolved.
Outdated
base = {}

try:
head = json.loads(Path("plugins.json").read_text(encoding="utf-8"))
if not isinstance(head, dict):
raise ValueError("plugins.json must contain a JSON object")
except (json.JSONDecodeError, ValueError) as exc:
print(
f"plugins.json is invalid on the PR head; smoke validation cannot continue: {exc}",
file=sys.stderr,
)
raise SystemExit(1)
else:
changed = [
name
for name, payload in head.items()
if base.get(name) != payload
]
should_validate = bool(changed)
if not should_validate:
validation_note = "No plugin entries changed in plugins.json; skipping smoke validation."

astrbot_ref = "master"
try:
default_head = subprocess.check_output(
["git", "ls-remote", "--symref", "https://github.com/AstrBotDevs/AstrBot", "HEAD"],
text=True,
stderr=subprocess.DEVNULL,
)
for line in default_head.splitlines():
if line.startswith("ref: refs/heads/") and line.endswith("\tHEAD"):
astrbot_ref = line.split("refs/heads/", 1)[1].split("\t", 1)[0]
break
except subprocess.CalledProcessError:
pass

with open(os.environ["GITHUB_ENV"], "a", encoding="utf-8") as handle:
handle.write(f"ASTRBOT_REF={astrbot_ref}\n")
handle.write(f"PLUGIN_NAME_LIST={','.join(changed)}\n")
handle.write("PLUGIN_LIMIT=\n")
handle.write(f"SHOULD_VALIDATE={'true' if should_validate else 'false'}\n")
handle.write(f"VALIDATION_NOTE={validation_note}\n")
PY

- name: Show PR diff selection
if: github.event_name == 'pull_request'
run: |
if [ "$SHOULD_VALIDATE" != "true" ]; then
printf '%s\n' "${VALIDATION_NOTE:-Smoke validation skipped.}"
else
printf 'Selected plugins: %s\n' "$PLUGIN_NAME_LIST"
fi

- name: Set up Python
if: env.SHOULD_VALIDATE == 'true'
uses: actions/setup-python@v5
with:
python-version: "3.12"

- name: Install validator dependencies
if: env.SHOULD_VALIDATE == 'true'
run: python -m pip install --upgrade pip pyyaml

- name: Clone AstrBot
if: env.SHOULD_VALIDATE == 'true'
run: git clone --depth 1 --branch "$ASTRBOT_REF" "https://github.com/AstrBotDevs/AstrBot" ".cache/AstrBot"

- name: Install AstrBot dependencies
if: env.SHOULD_VALIDATE == 'true'
run: python -m pip install -r ".cache/AstrBot/requirements.txt"

- name: Run plugin smoke validator
if: env.SHOULD_VALIDATE == 'true'
run: |
args=(
--astrbot-path ".cache/AstrBot"
--report-path "validation-report.json"
)

if [ -n "${PLUGIN_NAME_LIST:-}" ]; then
args+=(--plugin-name-list "$PLUGIN_NAME_LIST")
fi

if [ -n "${PLUGIN_LIMIT:-}" ]; then
args+=(--limit "$PLUGIN_LIMIT")
fi

python scripts/validate_plugins/run.py "${args[@]}"

- name: Upload validation report
if: always()
uses: actions/upload-artifact@v4
with:
name: validation-report
path: validation-report.json
if-no-files-found: warn
Empty file.
Loading
Loading