Files
discord-geodata/.gitea/workflows/build.yml
T
Workflow config file is invalid. Please check your config file: resolve aliases: yaml: line 137: could not find expected ':'
Leonid PershinandClaude Opus 5 61c0ea3558 feat: geosite/geoip для Discord со сборкой из апстримов
Домены и сети Discord в geosite.dat и geoip.dat для Xray/3x-ui, плюс
sing-box, Clash/mihomo, AdGuard, текст и готовый фрагмент routing.

Рукописная база живёт в data/discord-base.txt и data/ip/discord-base.txt,
остальное tools/sync.py тянет из пяти публичных апстримов: JSON-исходники
парсятся напрямую, скомпилированные .srs распаковываются через sing-box.
Каждый источник кладётся в свою категорию, недоступный источник не
обнуляет данные, файлы без шапки GENERATED скрипт не трогает.

Ограничения по протоколу и портам (директивы !network / !port) доезжают
до sing-box rule-set и до xray/routing.json. Такие категории намеренно
не входят в сводную discord: там сети вроде 172.64.0.0/13, и без привязки
к UDP-портам правило утащило бы в туннель чужой трафик.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-10 09:24:08 +03:00

188 lines
7.5 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
name: build
on:
push:
branches: [main]
paths:
- "data/**"
- "tools/**"
- ".gitea/workflows/build.yml"
pull_request:
paths:
- "data/**"
- "tools/**"
- ".gitea/workflows/build.yml"
schedule:
- cron: "17 3 * * *"
workflow_dispatch:
env:
GITEA_URL: ${{ github.server_url }}
GITEA_REPO: ${{ github.repository }}
# Автоматического токена обычно хватает. Если у раннера нет прав на push
# или на релизы — заведите секрет RELEASE_TOKEN с правами repo:write.
AUTO_TOKEN: ${{ github.token }}
RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }}
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Окружение
run: |
set -eu
missing=""
for cmd in python3 curl unzip tar git; do
command -v "$cmd" >/dev/null 2>&1 || missing="$missing $cmd"
done
if [ -n "$missing" ]; then
echo "не хватает:$missing — доустанавливаем"
sudo=""; [ "$(id -u)" -eq 0 ] || sudo=sudo
$sudo apt-get update -qq
$sudo apt-get install -y -qq python3 curl unzip tar git ca-certificates
fi
python3 --version
# Раньше сборки: sing-box нужен не только для .srs, но и синхронизации —
# три из пяти апстримов отдают уже скомпилированный rule-set.
- name: Внешние инструменты
run: |
sh tools/fetch-tools.sh "$GITHUB_WORKSPACE/bin"
echo "$GITHUB_WORKSPACE/bin" >> "$GITHUB_PATH"
- name: Синхронизация апстримов
run: python3 tools/sync.py
- name: Проверка исходников
run: python3 tools/build.py --check
- name: Тесты
run: python3 -m unittest discover -s tools -t tools
- name: Сборка
run: |
SOURCE_DATE_EPOCH=$(git log -1 --format=%ct) python3 tools/build.py
- name: Проверка .dat настоящим Xray
run: |
# Роутинг-правило заставляет Xray реально распарсить оба файла:
# битый .dat или отсутствующий тег дают ненулевой код возврата.
cat > /tmp/xray-test.json <<'EOF'
{
"inbounds": [{"port": 10800, "protocol": "socks"}],
"outbounds": [{"protocol": "freedom", "tag": "direct"}],
"routing": {
"rules": [
{"type": "field", "domain": ["ext:discord-geosite.dat:discord"], "outboundTag": "direct"},
{"type": "field", "ip": ["ext:discord-geoip.dat:discord"], "outboundTag": "direct"},
{"type": "field", "ip": ["ext:geoip.dat:discord-base"], "outboundTag": "direct"}
]
}
}
EOF
XRAY_LOCATION_ASSET="$GITHUB_WORKSPACE/dist" xray run -test -c /tmp/xray-test.json
- name: Проверка rule-set для sing-box
run: |
set -eu
sing-box rule-set decompile --output /tmp/site.json dist/sing-box/site/discord.srs
grep -q '"discord.com"' /tmp/site.json
sing-box rule-set decompile --output /tmp/ip.json dist/sing-box/ip/discord.srs
grep -q 'ip_cidr' /tmp/ip.json
# Ограниченные категории обязаны донести протокол и порты до .srs.
for src in dist/sing-box/ip/*-udp*.json; do
[ -e "$src" ] || continue
sing-box rule-set decompile --output /tmp/udp.json "${src%.json}.srs"
grep -q '"udp"' /tmp/udp.json
grep -q 'port_range' /tmp/udp.json
done
- name: Обновление data/ в main
if: github.event_name != 'pull_request'
run: |
set -eu
if git diff --quiet -- data; then
echo "апстримы не изменились"
exit 0
fi
token="${RELEASE_TOKEN:-$AUTO_TOKEN}"
[ -n "$token" ] || { echo "нет токена для push" >&2; exit 1; }
host="${GITEA_URL#*://}"
scheme="${GITEA_URL%%://*}"
git config user.name "gitea-actions"
git config user.email "gitea-actions@noreply.local"
git add data
git commit -q -m "sync: обновление списков из апстримов"
git push -q "$scheme://gitea-actions:$token@$host/$GITEA_REPO.git" HEAD:main
echo "data/ обновлён в main"
- name: Описание релиза
id: notes
run: |
set -eu
tag=$(date -u '+%Y.%m.%d-%H%M')
echo "tag=$tag" >> "$GITHUB_OUTPUT"
{
echo "Собрано из \`$(git rev-parse --short HEAD)\`."
echo
echo '| Категория | Доменов |'
echo '| --- | ---: |'
python3 -c "import json; [print(f'| {k} | {v} |') for k, v in json.load(open('dist/metadata.json'))['categories'].items()]"
echo
echo '| IP-категория | Сетей | Ограничения |'
echo '| --- | ---: | --- |'
python3 -c "
import json
for k, v in json.load(open('dist/metadata.json'))['ip_categories'].items():
limits = ' '.join(filter(None, ['/'.join(v.get('network', [])), v.get('ports', '')])) or '—'
print(f\"| {k} | {v['count']} | {limits} |\")
"
echo
echo "sha256(discord-geosite.dat) = \`$(cut -d' ' -f1 dist/discord-geosite.dat.sha256sum)\`"
echo "sha256(discord-geoip.dat) = \`$(cut -d' ' -f1 dist/discord-geoip.dat.sha256sum)\`"
} > /tmp/notes.md
cat /tmp/notes.md
- name: Публикация в ветку release
if: github.event_name != 'pull_request'
run: |
set -eu
token="${RELEASE_TOKEN:-$AUTO_TOKEN}"
[ -n "$token" ] || { echo "нет токена для push" >&2; exit 1; }
host="${GITEA_URL#*://}"
scheme="${GITEA_URL%%://*}"
cp README.md LICENSE dist/
cd dist
git init -q -b release
git config user.name "gitea-actions"
git config user.email "gitea-actions@noreply.local"
git add .
git commit -q -m "build $(date -u '+%Y-%m-%d %H:%M UTC') ($GITHUB_SHA)"
git push -qf "$scheme://gitea-actions:$token@$host/$GITEA_REPO.git" release
cd ..
rm -f dist/README.md dist/LICENSE
echo "ветка release обновлена"
- name: Релиз в Gitea
if: github.event_name != 'pull_request'
run: |
set -eu
export GITEA_TOKEN="${RELEASE_TOKEN:-$AUTO_TOKEN}"
# Собираем архив вне dist/, иначе tar пакует сам себя на лету.
tar -czf /tmp/discord-geodata-all.tar.gz -C dist .
mv /tmp/discord-geodata-all.tar.gz dist/
sh tools/gitea-release.sh "${{ steps.notes.outputs.tag }}" /tmp/notes.md \
dist/discord-geosite.dat \
dist/discord-geosite.dat.sha256sum \
dist/discord-geoip.dat \
dist/discord-geoip.dat.sha256sum \
dist/xray/routing.json \
dist/sing-box/site/discord.srs \
dist/sing-box/ip/discord.srs \
dist/metadata.json \
dist/SHA256SUMS \
dist/discord-geodata-all.tar.gz