Вместо GitHub Actions — .gitea/workflows/build.yml: проверка, тесты, сборка, валидация настоящими Xray и sing-box, публикация в ветку release и релиз через Gitea API (tools/gitea-release.sh). Ни gh CLI, ни GitHub-only экшенов. Для серверов — tools/update-geosite.sh: сверяет sha256 до закачки и выходит молча, если файл не менялся, проверяет сумму до подмены, подменяет атомарно и дёргает перезапуск только когда файл реально обновился. Едет в dist/, поэтому на сервере нужен один базовый URL. В README — cron и systemd timer. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
f905a76caf
commit
c05f6aa0d7
@@ -0,0 +1,141 @@
|
||||
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
|
||||
|
||||
- name: Проверка исходников
|
||||
run: python3 tools/build.py --check
|
||||
|
||||
- name: Тесты
|
||||
run: python3 -m unittest discover -s tools -t tools
|
||||
|
||||
- name: Внешние инструменты
|
||||
run: |
|
||||
sh tools/fetch-tools.sh "$GITHUB_WORKSPACE/bin"
|
||||
echo "$GITHUB_WORKSPACE/bin" >> "$GITHUB_PATH"
|
||||
|
||||
- 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:ipcheck.dat:ipcheck"], "outboundTag": "direct"},
|
||||
{"type": "field", "domain": ["ext:geosite.dat:leak-test"], "outboundTag": "direct"}
|
||||
]
|
||||
}
|
||||
}
|
||||
EOF
|
||||
XRAY_LOCATION_ASSET="$GITHUB_WORKSPACE/dist" xray run -test -c /tmp/xray-test.json
|
||||
|
||||
- name: Проверка rule-set для sing-box
|
||||
run: |
|
||||
sing-box rule-set decompile --output /tmp/ipcheck.json dist/sing-box/ipcheck.srs
|
||||
grep -q '"2ip.ru"' /tmp/ipcheck.json
|
||||
|
||||
- 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 "sha256(ipcheck.dat) = \`$(cut -d' ' -f1 dist/ipcheck.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/ipcheck-domains-all.tar.gz -C dist .
|
||||
mv /tmp/ipcheck-domains-all.tar.gz dist/
|
||||
sh tools/gitea-release.sh "${{ steps.notes.outputs.tag }}" /tmp/notes.md \
|
||||
dist/ipcheck.dat \
|
||||
dist/ipcheck.dat.sha256sum \
|
||||
dist/geosite.dat \
|
||||
dist/geosite.dat.sha256sum \
|
||||
dist/sing-box/ipcheck.srs \
|
||||
dist/mihomo/ipcheck.mrs \
|
||||
dist/metadata.json \
|
||||
dist/SHA256SUMS \
|
||||
dist/ipcheck-domains-all.tar.gz
|
||||
Reference in New Issue
Block a user