P0–P2 polish + reposition as fundraising / exit-prep document (#1) #2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Validate | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| jobs: | |
| validate: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: LICENSE exists | |
| run: test -s LICENSE || (echo "::error::LICENSE missing or empty" && exit 1) | |
| - name: CHANGELOG.md exists | |
| run: test -s CHANGELOG.md || (echo "::error::CHANGELOG.md missing or empty" && exit 1) | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - name: examples/*.json files are parseable | |
| run: | | |
| set -e | |
| fail=0 | |
| for f in $(git ls-files 'examples/*.json'); do | |
| if ! python -c "import json; json.load(open('$f'))" 2>/dev/null; then | |
| echo "::error file=$f::invalid JSON" | |
| fail=1 | |
| fi | |
| done | |
| exit $fail | |
| - name: SVG files are well-formed XML | |
| run: | | |
| set -e | |
| fail=0 | |
| for f in $(git ls-files 'docs/*.svg' '*.svg'); do | |
| if ! python -c "import xml.etree.ElementTree as ET; ET.parse('$f')" 2>/dev/null; then | |
| echo "::error file=$f::malformed SVG XML" | |
| fail=1 | |
| fi | |
| done | |
| exit $fail | |
| - name: Every docs/* asset referenced from README exists | |
| run: | | |
| set -e | |
| fail=0 | |
| for ref in $(grep -hoE 'docs/[a-zA-Z0-9_/-]+\.(svg|png|jpg|jpeg|gif|md)' README.md README.ru.md | sort -u); do | |
| if [ ! -f "$ref" ]; then | |
| echo "::error file=README.md::missing referenced asset $ref" | |
| fail=1 | |
| fi | |
| done | |
| exit $fail | |
| - name: Every examples/* file referenced from README exists | |
| run: | | |
| set -e | |
| fail=0 | |
| for ref in $(grep -hoE 'examples/[a-zA-Z0-9_./-]+' README.md README.ru.md | sort -u); do | |
| if [ ! -f "$ref" ]; then | |
| echo "::error file=README.md::missing referenced asset $ref" | |
| fail=1 | |
| fi | |
| done | |
| exit $fail | |
| - name: Internal Markdown links resolve | |
| run: | | |
| set -e | |
| fail=0 | |
| for src in README.md README.ru.md CHANGELOG.md docs/ARCHITECTURE.md docs/FEATURES.md; do | |
| [ -f "$src" ] || continue | |
| base="$(dirname "$src")" | |
| for tgt in $(grep -hoE '\]\([^)]+\)' "$src" | sed 's/](\(.*\))/\1/' | sed 's/#.*$//'); do | |
| case "$tgt" in | |
| http*|mailto:*|"") continue ;; | |
| esac | |
| [ "$base" = "." ] && resolved="$tgt" || resolved="$base/$tgt" | |
| if [ ! -e "$resolved" ] && [ ! -e "$tgt" ]; then | |
| echo "::error file=$src::broken internal link → $tgt" | |
| fail=1 | |
| fi | |
| done | |
| done | |
| exit $fail |