Add scheduled subset sync workflow
This commit is contained in:
20
.gitea/workflows/sync-subset.yml
Normal file
20
.gitea/workflows/sync-subset.yml
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
name: sync-ios-rule-subset
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 */12 * * *'
|
||||||
|
jobs:
|
||||||
|
sync:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: Sync subset from upstream
|
||||||
|
env:
|
||||||
|
GITEA_REPO_OWNER: yuanzhen869
|
||||||
|
GITEA_REPO_NAME: ios-rule-script-subset
|
||||||
|
GITEA_SYNC_USERNAME: yuanzhen869
|
||||||
|
GITEA_SYNC_EMAIL: yuanzhen869@gmail.com
|
||||||
|
GITEA_SYNC_TOKEN: ${{ secrets.SYNC_TOKEN }}
|
||||||
|
run: |
|
||||||
|
bash ./scripts/sync_subset.sh
|
||||||
10
README.md
10
README.md
@@ -2,6 +2,10 @@
|
|||||||
|
|
||||||
这个仓库只同步 `blackmatrix7/ios_rule_script` 里当前本地 `surgio` 需要的少量 Surge 规则文件,不做全量镜像。
|
这个仓库只同步 `blackmatrix7/ios_rule_script` 里当前本地 `surgio` 需要的少量 Surge 规则文件,不做全量镜像。
|
||||||
|
|
||||||
|
当前 Gitea 仓库地址:
|
||||||
|
|
||||||
|
- [yuanzhen869/ios-rule-script-subset](https://git.halonice.com/yuanzhen869/ios-rule-script-subset)
|
||||||
|
|
||||||
当前同步目标:
|
当前同步目标:
|
||||||
|
|
||||||
- `rule/Surge/Lan.list` <- `rule/Surge/Lan/Lan.list`
|
- `rule/Surge/Lan.list` <- `rule/Surge/Lan/Lan.list`
|
||||||
@@ -17,6 +21,10 @@
|
|||||||
|
|
||||||
- [sync_subset.sh](/Users/yuan/Desktop/workspaces/docker/ios-rule-script-subset/scripts/sync_subset.sh)
|
- [sync_subset.sh](/Users/yuan/Desktop/workspaces/docker/ios-rule-script-subset/scripts/sync_subset.sh)
|
||||||
|
|
||||||
|
本地同步凭据放在未提交的:
|
||||||
|
|
||||||
|
- [`.sync.env`](/Users/yuan/Desktop/workspaces/docker/ios-rule-script-subset/.sync.env)
|
||||||
|
|
||||||
这个项目给本地 `surgio` 用作远程规则源:
|
这个项目给本地 `surgio` 用作远程规则源:
|
||||||
|
|
||||||
- `https://git.halonice.com/admin/ios-rule-script-subset/raw/branch/main/rule/Surge`
|
- `https://git.halonice.com/yuanzhen869/ios-rule-script-subset/raw/branch/main/rule/Surge`
|
||||||
|
|||||||
103
scripts/build_singbox_rules.py
Normal file
103
scripts/build_singbox_rules.py
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import json
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
ROOT = Path(__file__).resolve().parent.parent
|
||||||
|
SURGE_DIR = ROOT / "rule" / "Surge"
|
||||||
|
SINGBOX_DIR = ROOT / "rule" / "sing-box"
|
||||||
|
|
||||||
|
SINGBOX_DIR.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
UPSTREAM_TARGETS = {
|
||||||
|
"Lan": "Lan.list",
|
||||||
|
"Apple": "Apple.list",
|
||||||
|
"OpenAI": "OpenAI.list",
|
||||||
|
"Gemini": "Gemini.list",
|
||||||
|
"Claude": "Claude.list",
|
||||||
|
"China": "China.list",
|
||||||
|
"ChinaIPs": "ChinaIPs.list",
|
||||||
|
"Proxy": "Proxy.list",
|
||||||
|
}
|
||||||
|
|
||||||
|
FIELD_MAP = {
|
||||||
|
"DOMAIN": "domain",
|
||||||
|
"DOMAIN-SUFFIX": "domain_suffix",
|
||||||
|
"DOMAIN-KEYWORD": "domain_keyword",
|
||||||
|
"DOMAIN-REGEX": "domain_regex",
|
||||||
|
"IP-CIDR": "ip_cidr",
|
||||||
|
"IP-CIDR6": "ip_cidr",
|
||||||
|
"PROCESS-NAME": "process_name",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def build_rule_set(entries: dict[str, list[str]]) -> dict:
|
||||||
|
rules = []
|
||||||
|
for field in ("domain", "domain_suffix", "domain_keyword", "domain_regex", "ip_cidr", "process_name"):
|
||||||
|
values = entries.get(field, [])
|
||||||
|
if values:
|
||||||
|
rules.append({field: values})
|
||||||
|
return {"version": 3, "rules": rules}
|
||||||
|
|
||||||
|
|
||||||
|
def parse_surge_list(path: Path) -> dict:
|
||||||
|
entries: dict[str, list[str]] = {}
|
||||||
|
for raw in path.read_text(encoding="utf-8").splitlines():
|
||||||
|
line = raw.strip()
|
||||||
|
if not line or line.startswith("#"):
|
||||||
|
continue
|
||||||
|
parts = [part.strip() for part in line.split(",")]
|
||||||
|
if len(parts) < 2:
|
||||||
|
continue
|
||||||
|
kind = parts[0].upper()
|
||||||
|
field = FIELD_MAP.get(kind)
|
||||||
|
if not field:
|
||||||
|
continue
|
||||||
|
value = parts[1]
|
||||||
|
if not value:
|
||||||
|
continue
|
||||||
|
entries.setdefault(field, [])
|
||||||
|
if value not in entries[field]:
|
||||||
|
entries[field].append(value)
|
||||||
|
return build_rule_set(entries)
|
||||||
|
|
||||||
|
|
||||||
|
MANUAL_RULESETS = {
|
||||||
|
"ManualBackHome": {"version": 3, "rules": [{"ip_cidr": ["192.168.10.0/24"]}]},
|
||||||
|
"ManualReject": {"version": 3, "rules": [{"domain": ["www.axure.com"]}]},
|
||||||
|
"ManualAI": {"version": 3, "rules": [{"domain_keyword": ["macked"]}]},
|
||||||
|
"ManualDirect": {
|
||||||
|
"version": 3,
|
||||||
|
"rules": [
|
||||||
|
{
|
||||||
|
"domain_suffix": [
|
||||||
|
"umeng.com",
|
||||||
|
"umsns.com",
|
||||||
|
"umindex.com",
|
||||||
|
"nice.com",
|
||||||
|
"apple.com",
|
||||||
|
"alicdn.com",
|
||||||
|
"qujiangkeji.com",
|
||||||
|
"banxueketang.com",
|
||||||
|
"doubj.cn",
|
||||||
|
"local",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for name, filename in UPSTREAM_TARGETS.items():
|
||||||
|
data = parse_surge_list(SURGE_DIR / filename)
|
||||||
|
(SINGBOX_DIR / f"{name}.json").write_text(
|
||||||
|
json.dumps(data, ensure_ascii=False, indent=2) + "\n",
|
||||||
|
encoding="utf-8",
|
||||||
|
)
|
||||||
|
|
||||||
|
for name, payload in MANUAL_RULESETS.items():
|
||||||
|
(SINGBOX_DIR / f"{name}.json").write_text(
|
||||||
|
json.dumps(payload, ensure_ascii=False, indent=2) + "\n",
|
||||||
|
encoding="utf-8",
|
||||||
|
)
|
||||||
@@ -3,28 +3,34 @@ set -euo pipefail
|
|||||||
|
|
||||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||||
SURGE_DIR="$ROOT_DIR/rule/Surge"
|
SURGE_DIR="$ROOT_DIR/rule/Surge"
|
||||||
|
SINGBOX_DIR="$ROOT_DIR/rule/sing-box"
|
||||||
UPSTREAM_BASE="https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/Surge"
|
UPSTREAM_BASE="https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/Surge"
|
||||||
GITEA_ENV_FILE="$ROOT_DIR/../gitea/.env"
|
GITEA_ENV_FILE="$ROOT_DIR/../gitea/.env"
|
||||||
LOCAL_SYNC_ENV_FILE="$ROOT_DIR/.sync.env"
|
LOCAL_SYNC_ENV_FILE="$ROOT_DIR/.sync.env"
|
||||||
|
|
||||||
if [[ ! -f "$GITEA_ENV_FILE" ]]; then
|
if [[ -f "$GITEA_ENV_FILE" ]]; then
|
||||||
echo "missing Gitea env file: $GITEA_ENV_FILE" >&2
|
source "$GITEA_ENV_FILE"
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
source "$GITEA_ENV_FILE"
|
|
||||||
|
|
||||||
if [[ -f "$LOCAL_SYNC_ENV_FILE" ]]; then
|
if [[ -f "$LOCAL_SYNC_ENV_FILE" ]]; then
|
||||||
source "$LOCAL_SYNC_ENV_FILE"
|
source "$LOCAL_SYNC_ENV_FILE"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
GITEA_REPO_OWNER="${GITEA_REPO_OWNER:-admin}"
|
GITEA_REPO_OWNER="${GITEA_REPO_OWNER:-yuanzhen869}"
|
||||||
GITEA_REPO_NAME="${GITEA_REPO_NAME:-ios-rule-script-subset}"
|
GITEA_REPO_NAME="${GITEA_REPO_NAME:-ios-rule-script-subset}"
|
||||||
GITEA_SYNC_USERNAME="${GITEA_SYNC_USERNAME:-$GITEA_ADMIN_USERNAME}"
|
GITEA_SYNC_USERNAME="${GITEA_SYNC_USERNAME:-${GITEA_ADMIN_USERNAME:-yuanzhen869}}"
|
||||||
GITEA_SYNC_PASSWORD="${GITEA_SYNC_PASSWORD:-${GITEA_SYNC_TOKEN:-$GITEA_ADMIN_PASSWORD}}"
|
GITEA_SYNC_EMAIL="${GITEA_SYNC_EMAIL:-${GITEA_ADMIN_EMAIL:-yuanzhen869@gmail.com}}"
|
||||||
|
GITEA_SYNC_PASSWORD="${GITEA_SYNC_PASSWORD:-${GITEA_SYNC_TOKEN:-${GITEA_ADMIN_PASSWORD:-}}}"
|
||||||
|
|
||||||
|
if [[ -z "${GITEA_SYNC_PASSWORD}" ]]; then
|
||||||
|
echo "missing push credential: set GITEA_SYNC_TOKEN or GITEA_ADMIN_PASSWORD" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
GITEA_REMOTE_URL="https://${GITEA_SYNC_USERNAME}:${GITEA_SYNC_PASSWORD}@git.halonice.com/${GITEA_REPO_OWNER}/${GITEA_REPO_NAME}.git"
|
GITEA_REMOTE_URL="https://${GITEA_SYNC_USERNAME}:${GITEA_SYNC_PASSWORD}@git.halonice.com/${GITEA_REPO_OWNER}/${GITEA_REPO_NAME}.git"
|
||||||
|
|
||||||
mkdir -p "$SURGE_DIR"
|
mkdir -p "$SURGE_DIR"
|
||||||
|
mkdir -p "$SINGBOX_DIR"
|
||||||
|
|
||||||
while IFS='|' read -r target src; do
|
while IFS='|' read -r target src; do
|
||||||
[[ -z "$target" ]] && continue
|
[[ -z "$target" ]] && continue
|
||||||
@@ -42,6 +48,8 @@ ChinaIPs.list|ChinaIPs/ChinaIPs.list
|
|||||||
Proxy.list|Proxy/Proxy.list
|
Proxy.list|Proxy/Proxy.list
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
python3 "$ROOT_DIR/scripts/build_singbox_rules.py"
|
||||||
|
|
||||||
cd "$ROOT_DIR"
|
cd "$ROOT_DIR"
|
||||||
|
|
||||||
if [[ ! -d .git ]]; then
|
if [[ ! -d .git ]]; then
|
||||||
@@ -58,6 +66,6 @@ if git diff --cached --quiet; then
|
|||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
git -c user.name="$GITEA_ADMIN_USERNAME" -c user.email="$GITEA_ADMIN_EMAIL" commit -m "Sync subset from blackmatrix7/ios_rule_script" >/dev/null
|
git -c user.name="$GITEA_SYNC_USERNAME" -c user.email="$GITEA_SYNC_EMAIL" commit -m "Sync subset from blackmatrix7/ios_rule_script" >/dev/null
|
||||||
|
|
||||||
git push origin main
|
git push origin main
|
||||||
|
|||||||
Reference in New Issue
Block a user