mirror of
https://github.com/QYG2297248353/appstore-1panel.git
synced 2026-06-16 01:02:14 +08:00
Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
67fbe2929f | ||
|
|
f5d3d69e17 |
@@ -30,11 +30,8 @@
|
||||
"**/rustfs/1.0.0-alpha.86/**"
|
||||
],
|
||||
"packageRules": [
|
||||
{
|
||||
"matchUpdateTypes": [
|
||||
"patch",
|
||||
"minor"
|
||||
],
|
||||
{
|
||||
"matchUpdateTypes": ["patch", "minor"],
|
||||
"automerge": true,
|
||||
"automergeType": "pr",
|
||||
"platformAutomerge": true,
|
||||
@@ -42,9 +39,7 @@
|
||||
"prCreation": "immediate"
|
||||
},
|
||||
{
|
||||
"matchUpdateTypes": [
|
||||
"major"
|
||||
],
|
||||
"matchUpdateTypes": ["major"],
|
||||
"automerge": false
|
||||
},
|
||||
{
|
||||
|
||||
@@ -2,7 +2,7 @@ name: Auto Process Renovate PRs
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [ opened, synchronize, reopened, ready_for_review ]
|
||||
types: [opened, synchronize, reopened, ready_for_review]
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '0 * * * *'
|
||||
@@ -36,6 +36,7 @@ jobs:
|
||||
import requests
|
||||
from typing import Optional, Dict, Any
|
||||
|
||||
# 从环境变量获取GitHub token和仓库信息
|
||||
GITHUB_TOKEN = os.getenv('GITHUB_TOKEN')
|
||||
REPOSITORY = os.getenv('GITHUB_REPOSITORY')
|
||||
HEADERS = {
|
||||
@@ -58,113 +59,99 @@ jobs:
|
||||
|
||||
def parse_version_update(pr_body: str) -> Optional[str]:
|
||||
"""解析PR正文,确定更新类型"""
|
||||
# 匹配Markdown表格格式
|
||||
# 示例格式:
|
||||
# | Package | Update | Change |
|
||||
# |---------|--------|--------|
|
||||
# | [uusec/openresty-manager](...) | patch | `2.3.4` -> `2.3.5` |
|
||||
|
||||
# 查找表格行
|
||||
lines = pr_body.split('\n')
|
||||
in_table = False
|
||||
|
||||
|
||||
for line in lines:
|
||||
# 检测表格开始
|
||||
if re.search(r'^\s*\|.*Package.*Update.*Change.*\|\s*$', line, re.IGNORECASE):
|
||||
in_table = True
|
||||
continue
|
||||
|
||||
|
||||
# 跳过表格分隔线
|
||||
if in_table and re.search(r'^\s*\|[-:|]+\|\s*$', line):
|
||||
continue
|
||||
|
||||
|
||||
# 处理表格数据行
|
||||
if in_table and line.strip().startswith('|'):
|
||||
# 提取单元格内容
|
||||
cells = [cell.strip() for cell in line.split('|') if cell.strip()]
|
||||
|
||||
|
||||
if len(cells) >= 3:
|
||||
update_type = cells[1].lower()
|
||||
|
||||
update_type = cells[1].lower() # 第二列是更新类型
|
||||
|
||||
# 检查更新类型
|
||||
if update_type == 'major':
|
||||
return 'major'
|
||||
elif update_type in ['minor', 'patch']:
|
||||
return update_type
|
||||
|
||||
change_cell = cells[2]
|
||||
|
||||
# 如果没有明确类型,尝试从版本变化中推断
|
||||
change_cell = cells[2] # 第三列是版本变化
|
||||
|
||||
# 提取版本号
|
||||
version_pattern = r'(\d+\.\d+\.\d+|\d+\.\d+|\d+)'
|
||||
versions = re.findall(version_pattern, change_cell)
|
||||
|
||||
|
||||
if len(versions) >= 2:
|
||||
old_parts = versions[0].split('.')
|
||||
new_parts = versions[1].split('.')
|
||||
|
||||
if old_parts[0] != new_parts[0]:
|
||||
return 'major'
|
||||
elif len(old_parts) > 1 and len(new_parts) > 1 and old_parts[1] != new_parts[1]:
|
||||
return 'minor'
|
||||
else:
|
||||
return 'patch'
|
||||
old_version = versions[0]
|
||||
new_version = versions[1]
|
||||
|
||||
# 分割版本号
|
||||
old_parts = old_version.split('.')
|
||||
new_parts = new_version.split('.')
|
||||
|
||||
if len(old_parts) > 0 and len(new_parts) > 0:
|
||||
if old_parts[0] != new_parts[0]:
|
||||
return 'major'
|
||||
elif len(old_parts) > 1 and len(new_parts) > 1 and old_parts[1] != new_parts[1]:
|
||||
return 'minor'
|
||||
else:
|
||||
return 'patch'
|
||||
elif in_table and not line.strip().startswith('|'):
|
||||
# 表格结束
|
||||
break
|
||||
|
||||
|
||||
return None
|
||||
|
||||
def is_rebase_checkbox_unchecked(pr_body: str) -> bool:
|
||||
"""
|
||||
检查 PR body 中的 rebase checkbox 是否存在且未勾选。
|
||||
Renovate 在 PR body 中插入如下格式的行:
|
||||
- [ ] <!-- rebase-check --> If you want to rebase/retry this PR, check this box.
|
||||
勾选后变为:
|
||||
- [x] <!-- rebase-check --> If you want to rebase/retry this PR, check this box.
|
||||
"""
|
||||
# 匹配未勾选状态
|
||||
unchecked_pattern = r'-\s*\[\s*\]\s*<!--\s*rebase-check\s*-->'
|
||||
return bool(re.search(unchecked_pattern, pr_body, re.IGNORECASE))
|
||||
|
||||
def trigger_renovate_rebase(pr_number: int, pr_body: str) -> bool:
|
||||
"""
|
||||
通过将 PR body 中的 rebase checkbox 从未勾选改为勾选,
|
||||
触发 Renovate 自动 rebase/retry。
|
||||
返回是否成功更新。
|
||||
"""
|
||||
unchecked_pattern = r'(-\s*\[)\s*(\]\s*<!--\s*rebase-check\s*-->)'
|
||||
new_body = re.sub(
|
||||
unchecked_pattern,
|
||||
r'\1x\2',
|
||||
pr_body,
|
||||
flags=re.IGNORECASE
|
||||
)
|
||||
|
||||
if new_body == pr_body:
|
||||
print(f"PR #{pr_number} 未找到可勾选的 rebase checkbox,无法触发 rebase")
|
||||
return False
|
||||
|
||||
url = f'https://api.github.com/repos/{REPOSITORY}/pulls/{pr_number}'
|
||||
data = {'body': new_body}
|
||||
response = requests.patch(url, headers=HEADERS, json=data)
|
||||
|
||||
if response.status_code == 200:
|
||||
print(f"PR #{pr_number} 已勾选 rebase checkbox,Renovate 将自动触发 rebase/retry")
|
||||
return True
|
||||
else:
|
||||
print(f"PR #{pr_number} 更新 body 失败: {response.status_code} {response.text}")
|
||||
return False
|
||||
|
||||
def is_pr_mergeable(pr_number: int) -> bool:
|
||||
"""检查PR是否可以合并"""
|
||||
url = f'https://api.github.com/repos/{REPOSITORY}/pulls/{pr_number}'
|
||||
response = requests.get(url, headers=HEADERS)
|
||||
response.raise_for_status()
|
||||
pr_data = response.json()
|
||||
|
||||
# 检查合并状态
|
||||
return pr_data.get('mergeable', False) and pr_data.get('mergeable_state', '') == 'clean'
|
||||
|
||||
def wait_for_checks(pr_number: int, max_wait: int = 600) -> bool:
|
||||
"""等待检查通过,最多等待max_wait秒"""
|
||||
start_time = time.time()
|
||||
|
||||
|
||||
while time.time() - start_time < max_wait:
|
||||
if is_pr_mergeable(pr_number):
|
||||
return True
|
||||
|
||||
# 等待30秒后再次检查
|
||||
time.sleep(30)
|
||||
|
||||
|
||||
return False
|
||||
|
||||
def merge_pr(pr_number: int) -> bool:
|
||||
"""合并PR"""
|
||||
url = f'https://api.github.com/repos/{REPOSITORY}/pulls/{pr_number}/merge'
|
||||
data = {'merge_method': 'merge'}
|
||||
data = {
|
||||
'merge_method': 'merge'
|
||||
}
|
||||
response = requests.put(url, headers=HEADERS, json=data)
|
||||
|
||||
|
||||
if response.status_code == 200:
|
||||
print(f"成功合并PR #{pr_number}")
|
||||
return True
|
||||
@@ -184,51 +171,33 @@ jobs:
|
||||
pr_number = pr['number']
|
||||
pr_author = pr['user']['login']
|
||||
pr_title = pr['title']
|
||||
pr_body = pr.get('body', '') or ''
|
||||
|
||||
pr_body = pr.get('body', '')
|
||||
|
||||
print(f"处理PR #{pr_number} 来自 {pr_author}: {pr_title}")
|
||||
|
||||
|
||||
# 解析更新类型
|
||||
update_type = parse_version_update(pr_body)
|
||||
|
||||
|
||||
if not update_type:
|
||||
print(f"无法确定PR #{pr_number} 的更新类型,跳过")
|
||||
add_comment(pr_number, "⚠️ 自动处理失败: 无法确定更新类型")
|
||||
return
|
||||
|
||||
|
||||
print(f"PR #{pr_number} 更新类型: {update_type}")
|
||||
|
||||
|
||||
# 如果是大版本更新,跳过
|
||||
if update_type == 'major':
|
||||
print(f"PR #{pr_number} 是大版本更新,跳过")
|
||||
add_comment(pr_number, "⏭️ 自动跳过: 大版本更新需要手动审核")
|
||||
return
|
||||
|
||||
|
||||
# 检查PR是否可以合并
|
||||
if not wait_for_checks(pr_number):
|
||||
print(f"PR #{pr_number} 在等待时间内未通过检查")
|
||||
|
||||
# 判断 rebase checkbox 是否存在且未勾选
|
||||
if is_rebase_checkbox_unchecked(pr_body):
|
||||
print(f"PR #{pr_number} 检测到未勾选的 rebase checkbox,尝试触发 rebase...")
|
||||
triggered = trigger_renovate_rebase(pr_number, pr_body)
|
||||
if triggered:
|
||||
add_comment(
|
||||
pr_number,
|
||||
"🔄 自动触发 Rebase: 检查超时,已自动勾选 rebase checkbox,"
|
||||
"Renovate 将重新触发 rebase/retry,下次调度时将再次尝试合并。"
|
||||
)
|
||||
else:
|
||||
add_comment(
|
||||
pr_number,
|
||||
"⏰ 自动跳过: 在等待时间内未通过所有检查,且无法触发 rebase,请手动处理。"
|
||||
)
|
||||
else:
|
||||
# checkbox 不存在或已经勾选过(Renovate 还在处理中)
|
||||
add_comment(
|
||||
pr_number,
|
||||
"⏰ 自动跳过: 在等待时间内未通过所有检查,"
|
||||
"rebase checkbox 不存在或已触发,请稍后等待 Renovate 处理或手动介入。"
|
||||
)
|
||||
print(f"PR #{pr_number} 在等待时间内未通过检查,跳过")
|
||||
add_comment(pr_number, "⏰ 自动跳过: 在等待时间内未通过所有检查")
|
||||
return
|
||||
|
||||
|
||||
# 尝试合并PR
|
||||
if merge_pr(pr_number):
|
||||
add_comment(pr_number, "✅ 自动合并: 小版本更新已自动合并")
|
||||
else:
|
||||
@@ -237,18 +206,22 @@ jobs:
|
||||
def main():
|
||||
"""主函数"""
|
||||
try:
|
||||
# 获取所有PR
|
||||
prs = get_prs()
|
||||
print(f"找到 {len(prs)} 个打开的PR")
|
||||
|
||||
|
||||
# 筛选Renovate的PR
|
||||
renovate_prs = [pr for pr in prs if is_renovate_pr(pr)]
|
||||
print(f"找到 {len(renovate_prs)} 个Renovate/Mend的PR")
|
||||
|
||||
|
||||
# 处理每个PR
|
||||
for pr in renovate_prs:
|
||||
try:
|
||||
process_pr(pr)
|
||||
except Exception as e:
|
||||
print(f"处理PR #{pr['number']} 时出错: {str(e)}")
|
||||
|
||||
# 继续处理下一个PR
|
||||
|
||||
except Exception as e:
|
||||
print(f"处理PR时发生错误: {str(e)}")
|
||||
raise
|
||||
|
||||
@@ -1,231 +0,0 @@
|
||||
name: Auto Process Renovate PRs
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened, ready_for_review]
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '0 * * * *'
|
||||
|
||||
jobs:
|
||||
process-renovate-prs:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: '3.x'
|
||||
|
||||
- name: Install dependencies
|
||||
run: pip install requests
|
||||
|
||||
- name: Process Renovate PRs
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
python << 'EOF'
|
||||
import os
|
||||
import re
|
||||
import time
|
||||
import requests
|
||||
from typing import Optional, Dict, Any
|
||||
|
||||
# 从环境变量获取GitHub token和仓库信息
|
||||
GITHUB_TOKEN = os.getenv('GITHUB_TOKEN')
|
||||
REPOSITORY = os.getenv('GITHUB_REPOSITORY')
|
||||
HEADERS = {
|
||||
'Authorization': f'Bearer {GITHUB_TOKEN}',
|
||||
'Accept': 'application/vnd.github.v3+json',
|
||||
'X-GitHub-Api-Version': '2022-11-28'
|
||||
}
|
||||
|
||||
def get_prs() -> list:
|
||||
"""获取所有打开的PR列表"""
|
||||
url = f'https://api.github.com/repos/{REPOSITORY}/pulls?state=open'
|
||||
response = requests.get(url, headers=HEADERS)
|
||||
response.raise_for_status()
|
||||
return response.json()
|
||||
|
||||
def is_renovate_pr(pr: Dict[str, Any]) -> bool:
|
||||
"""检查PR是否来自Renovate"""
|
||||
author = pr.get('user', {}).get('login', '').lower()
|
||||
return 'renovate' in author or 'mend' in author
|
||||
|
||||
def parse_version_update(pr_body: str) -> Optional[str]:
|
||||
"""解析PR正文,确定更新类型"""
|
||||
# 匹配Markdown表格格式
|
||||
# 示例格式:
|
||||
# | Package | Update | Change |
|
||||
# |---------|--------|--------|
|
||||
# | [uusec/openresty-manager](...) | patch | `2.3.4` -> `2.3.5` |
|
||||
|
||||
# 查找表格行
|
||||
lines = pr_body.split('\n')
|
||||
in_table = False
|
||||
|
||||
for line in lines:
|
||||
# 检测表格开始
|
||||
if re.search(r'^\s*\|.*Package.*Update.*Change.*\|\s*$', line, re.IGNORECASE):
|
||||
in_table = True
|
||||
continue
|
||||
|
||||
# 跳过表格分隔线
|
||||
if in_table and re.search(r'^\s*\|[-:|]+\|\s*$', line):
|
||||
continue
|
||||
|
||||
# 处理表格数据行
|
||||
if in_table and line.strip().startswith('|'):
|
||||
# 提取单元格内容
|
||||
cells = [cell.strip() for cell in line.split('|') if cell.strip()]
|
||||
|
||||
if len(cells) >= 3:
|
||||
update_type = cells[1].lower() # 第二列是更新类型
|
||||
|
||||
# 检查更新类型
|
||||
if update_type == 'major':
|
||||
return 'major'
|
||||
elif update_type in ['minor', 'patch']:
|
||||
return update_type
|
||||
|
||||
# 如果没有明确类型,尝试从版本变化中推断
|
||||
change_cell = cells[2] # 第三列是版本变化
|
||||
|
||||
# 提取版本号
|
||||
version_pattern = r'(\d+\.\d+\.\d+|\d+\.\d+|\d+)'
|
||||
versions = re.findall(version_pattern, change_cell)
|
||||
|
||||
if len(versions) >= 2:
|
||||
old_version = versions[0]
|
||||
new_version = versions[1]
|
||||
|
||||
# 分割版本号
|
||||
old_parts = old_version.split('.')
|
||||
new_parts = new_version.split('.')
|
||||
|
||||
if len(old_parts) > 0 and len(new_parts) > 0:
|
||||
if old_parts[0] != new_parts[0]:
|
||||
return 'major'
|
||||
elif len(old_parts) > 1 and len(new_parts) > 1 and old_parts[1] != new_parts[1]:
|
||||
return 'minor'
|
||||
else:
|
||||
return 'patch'
|
||||
elif in_table and not line.strip().startswith('|'):
|
||||
# 表格结束
|
||||
break
|
||||
|
||||
return None
|
||||
|
||||
def is_pr_mergeable(pr_number: int) -> bool:
|
||||
"""检查PR是否可以合并"""
|
||||
url = f'https://api.github.com/repos/{REPOSITORY}/pulls/{pr_number}'
|
||||
response = requests.get(url, headers=HEADERS)
|
||||
response.raise_for_status()
|
||||
pr_data = response.json()
|
||||
|
||||
# 检查合并状态
|
||||
return pr_data.get('mergeable', False) and pr_data.get('mergeable_state', '') == 'clean'
|
||||
|
||||
def wait_for_checks(pr_number: int, max_wait: int = 600) -> bool:
|
||||
"""等待检查通过,最多等待max_wait秒"""
|
||||
start_time = time.time()
|
||||
|
||||
while time.time() - start_time < max_wait:
|
||||
if is_pr_mergeable(pr_number):
|
||||
return True
|
||||
|
||||
# 等待30秒后再次检查
|
||||
time.sleep(30)
|
||||
|
||||
return False
|
||||
|
||||
def merge_pr(pr_number: int) -> bool:
|
||||
"""合并PR"""
|
||||
url = f'https://api.github.com/repos/{REPOSITORY}/pulls/{pr_number}/merge'
|
||||
data = {
|
||||
'merge_method': 'merge'
|
||||
}
|
||||
response = requests.put(url, headers=HEADERS, json=data)
|
||||
|
||||
if response.status_code == 200:
|
||||
print(f"成功合并PR #{pr_number}")
|
||||
return True
|
||||
else:
|
||||
print(f"合并PR #{pr_number} 失败: {response.json().get('message', '未知错误')}")
|
||||
return False
|
||||
|
||||
def add_comment(pr_number: int, comment: str):
|
||||
"""在PR上添加评论"""
|
||||
url = f'https://api.github.com/repos/{REPOSITORY}/issues/{pr_number}/comments'
|
||||
data = {'body': comment}
|
||||
response = requests.post(url, headers=HEADERS, json=data)
|
||||
response.raise_for_status()
|
||||
|
||||
def process_pr(pr: Dict[str, Any]):
|
||||
"""处理单个PR"""
|
||||
pr_number = pr['number']
|
||||
pr_author = pr['user']['login']
|
||||
pr_title = pr['title']
|
||||
pr_body = pr.get('body', '')
|
||||
|
||||
print(f"处理PR #{pr_number} 来自 {pr_author}: {pr_title}")
|
||||
|
||||
# 解析更新类型
|
||||
update_type = parse_version_update(pr_body)
|
||||
|
||||
if not update_type:
|
||||
print(f"无法确定PR #{pr_number} 的更新类型,跳过")
|
||||
add_comment(pr_number, "⚠️ 自动处理失败: 无法确定更新类型")
|
||||
return
|
||||
|
||||
print(f"PR #{pr_number} 更新类型: {update_type}")
|
||||
|
||||
# 如果是大版本更新,跳过
|
||||
if update_type == 'major':
|
||||
print(f"PR #{pr_number} 是大版本更新,跳过")
|
||||
add_comment(pr_number, "⏭️ 自动跳过: 大版本更新需要手动审核")
|
||||
return
|
||||
|
||||
# 检查PR是否可以合并
|
||||
if not wait_for_checks(pr_number):
|
||||
print(f"PR #{pr_number} 在等待时间内未通过检查,跳过")
|
||||
add_comment(pr_number, "⏰ 自动跳过: 在等待时间内未通过所有检查")
|
||||
return
|
||||
|
||||
# 尝试合并PR
|
||||
if merge_pr(pr_number):
|
||||
add_comment(pr_number, "✅ 自动合并: 小版本更新已自动合并")
|
||||
else:
|
||||
add_comment(pr_number, "❌ 自动合并失败: 请手动处理")
|
||||
|
||||
def main():
|
||||
"""主函数"""
|
||||
try:
|
||||
# 获取所有PR
|
||||
prs = get_prs()
|
||||
print(f"找到 {len(prs)} 个打开的PR")
|
||||
|
||||
# 筛选Renovate的PR
|
||||
renovate_prs = [pr for pr in prs if is_renovate_pr(pr)]
|
||||
print(f"找到 {len(renovate_prs)} 个Renovate/Mend的PR")
|
||||
|
||||
# 处理每个PR
|
||||
for pr in renovate_prs:
|
||||
try:
|
||||
process_pr(pr)
|
||||
except Exception as e:
|
||||
print(f"处理PR #{pr['number']} 时出错: {str(e)}")
|
||||
# 继续处理下一个PR
|
||||
|
||||
except Exception as e:
|
||||
print(f"处理PR时发生错误: {str(e)}")
|
||||
raise
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
EOF
|
||||
@@ -1,24 +0,0 @@
|
||||
networks:
|
||||
1panel-network:
|
||||
external: true
|
||||
|
||||
services:
|
||||
adguardhome:
|
||||
image: adguard/adguardhome:v0.107.77
|
||||
container_name: ${CONTAINER_NAME}
|
||||
labels:
|
||||
createdBy: "Apps"
|
||||
restart: always
|
||||
network_mode: ${NETWORK_MODE}
|
||||
ports:
|
||||
- ${PANEL_APP_PORT_HTTP}:3000
|
||||
- ${PANEL_APP_PORT_DNS}:53/tcp
|
||||
- ${PANEL_APP_PORT_DNS}:53/udp
|
||||
env_file:
|
||||
- ${GLOBAL_ENV_FILE:-/etc/1panel/envs/global.env}
|
||||
- ${ENV_FILE:-/etc/1panel/envs/default.env}
|
||||
volumes:
|
||||
- ${ADGUARDHOME_ROOT_PATH}/work:/opt/adguardhome/work
|
||||
- ${ADGUARDHOME_ROOT_PATH}/conf:/opt/adguardhome/conf
|
||||
environment:
|
||||
- TZ=Asia/Shanghai
|
||||
@@ -1,31 +0,0 @@
|
||||
# Adguard Home
|
||||
|
||||
简短的介绍
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
## 简介
|
||||
|
||||
AdGuard Home 是一种基于网络的广告和跟踪器拦截解决方案。只需在您的路由器上安装一次,即可覆盖您家庭网络中的所有设备——无需额外的客户端软件。这对于各种经常威胁您隐私的物联网设备尤其重要。
|
||||
|
||||
## 安装说明
|
||||
|
||||
### 默认 DNS
|
||||
|
||||
需要提前关闭宿主机 `resolved` 功能,否则会导致 DNS 解析失败。
|
||||
|
||||
```sh
|
||||
systemctl disable systemd-resolved
|
||||
systemctl stop systemd-resolved
|
||||
```
|
||||
|
||||
### 初始化配置
|
||||
|
||||
安装后进入页面后,必须将 80 端口改为 3000 否则,结束后 页面将无法访问。
|
||||
|
||||
---
|
||||
|
||||

|
||||

|
||||
@@ -1,17 +0,0 @@
|
||||
additionalProperties:
|
||||
key: adguardhome
|
||||
name: Adguard Home
|
||||
tags:
|
||||
- WebSite
|
||||
- Local
|
||||
shortDescZh: 广告卫士之家
|
||||
shortDescEn: Adguard Home
|
||||
type: website
|
||||
crossVersionUpdate: true
|
||||
limit: 0
|
||||
website: https://adguard.com/
|
||||
github: https://github.com/AdguardTeam/AdGuardHome/
|
||||
document: https://adguard.com/
|
||||
architectures:
|
||||
- amd64
|
||||
- arm64
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 2.1 KiB |
@@ -4,7 +4,7 @@ networks:
|
||||
|
||||
services:
|
||||
ammds:
|
||||
image: qyg2297248353/ammds:v1.6.57-ol8
|
||||
image: qyg2297248353/ammds:v1.6.56-ol8
|
||||
container_name: ${CONTAINER_NAME}
|
||||
labels:
|
||||
createdBy: "Apps"
|
||||
@@ -4,7 +4,7 @@ networks:
|
||||
|
||||
services:
|
||||
ammds:
|
||||
image: qyg2297248353/ammds:v1.6.57
|
||||
image: qyg2297248353/ammds:v1.6.56
|
||||
container_name: ${CONTAINER_NAME}
|
||||
labels:
|
||||
createdBy: "Apps"
|
||||
@@ -4,7 +4,7 @@ networks:
|
||||
|
||||
services:
|
||||
apprise:
|
||||
image: caronc/apprise:v1.5.0
|
||||
image: caronc/apprise:v1.3.2
|
||||
container_name: ${CONTAINER_NAME}
|
||||
labels:
|
||||
createdBy: "Apps"
|
||||
+1
-1
@@ -4,7 +4,7 @@ networks:
|
||||
|
||||
services:
|
||||
archisteamfarm:
|
||||
image: justarchi/archisteamfarm:6.3.6.1
|
||||
image: justarchi/archisteamfarm:6.3.4.0
|
||||
container_name: ${CONTAINER_NAME}
|
||||
labels:
|
||||
createdBy: "Apps"
|
||||
@@ -4,7 +4,7 @@ networks:
|
||||
|
||||
services:
|
||||
archivebox:
|
||||
image: archivebox/archivebox:0.7.4
|
||||
image: archivebox/archivebox:0.7.3
|
||||
container_name: ${CONTAINER_NAME}
|
||||
labels:
|
||||
createdBy: "Apps"
|
||||
+2
-2
@@ -4,7 +4,7 @@ networks:
|
||||
|
||||
services:
|
||||
napcat:
|
||||
image: mlikiowa/napcat-docker:v4.18.6
|
||||
image: mlikiowa/napcat-docker:v4.17.52
|
||||
container_name: napcat-${CONTAINER_NAME}
|
||||
restart: always
|
||||
networks:
|
||||
@@ -24,7 +24,7 @@ services:
|
||||
- NAPCAT_UID=${NAPCAT_UID:-1000}
|
||||
- NAPCAT_GID=${NAPCAT_GID:-1000}
|
||||
astrbot:
|
||||
image: soulter/astrbot:v4.25.5
|
||||
image: soulter/astrbot:v4.20.1
|
||||
container_name: ${CONTAINER_NAME}
|
||||
labels:
|
||||
createdBy: "Apps"
|
||||
@@ -4,7 +4,7 @@ networks:
|
||||
|
||||
services:
|
||||
astrbot:
|
||||
image: soulter/astrbot:v4.25.5
|
||||
image: soulter/astrbot:v4.20.1
|
||||
container_name: ${CONTAINER_NAME}
|
||||
labels:
|
||||
createdBy: "Apps"
|
||||
@@ -1,24 +0,0 @@
|
||||
additionalProperties:
|
||||
formFields:
|
||||
- default: "/home/baihu-panel"
|
||||
edit: true
|
||||
envKey: BAIHU_ROOT_PATH
|
||||
labelZh: 数据持久化路径
|
||||
labelEn: Data persistence path
|
||||
required: true
|
||||
type: text
|
||||
- default: 8052
|
||||
edit: true
|
||||
envKey: PANEL_APP_PORT_HTTP
|
||||
labelZh: WebUI 端口
|
||||
labelEn: WebUI port
|
||||
required: true
|
||||
rule: paramPort
|
||||
type: number
|
||||
- default: ""
|
||||
edit: true
|
||||
envKey: BH_SECRET
|
||||
labelZh: 密钥
|
||||
labelEn: Secret
|
||||
required: true
|
||||
type: text
|
||||
@@ -1,34 +0,0 @@
|
||||
networks:
|
||||
1panel-network:
|
||||
external: true
|
||||
|
||||
services:
|
||||
baihu-panel:
|
||||
image: ghcr.io/engigu/baihu:1.1.14
|
||||
container_name: ${CONTAINER_NAME}
|
||||
labels:
|
||||
createdBy: "Apps"
|
||||
restart: always
|
||||
networks:
|
||||
- 1panel-network
|
||||
ports:
|
||||
- ${PANEL_APP_PORT_HTTP}:8052
|
||||
env_file:
|
||||
- ${GLOBAL_ENV_FILE:-/etc/1panel/envs/global.env}
|
||||
- ${ENV_FILE:-/etc/1panel/envs/default.env}
|
||||
volumes:
|
||||
- ${BAIHU_ROOT_PATH}/data:/app/data
|
||||
- ${BAIHU_ROOT_PATH}/envs:/app/envs
|
||||
environment:
|
||||
- TZ=Asia/Shanghai
|
||||
- BH_SERVER_PORT=8052
|
||||
- BH_SERVER_HOST=0.0.0.0
|
||||
- BH_DB_TYPE=sqlite
|
||||
- BH_DB_PATH=/app/data/baihu.db
|
||||
- BH_DB_TABLE_PREFIX=baihu_
|
||||
- BH_DB_NAME=baihu
|
||||
logging:
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
@@ -1,70 +0,0 @@
|
||||
# 白虎面板
|
||||
|
||||
🐯轻量级定时任务管理系统
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
## 安装说明
|
||||
|
||||
> 默认用户名:admin
|
||||
>
|
||||
> 默认密码:首次安装后在日志中打印 12位随机密码
|
||||
|
||||
## 简介
|
||||
|
||||
白虎面板 (Baihu Panel) 是一款极致轻量、高性能的自动化任务调度平台。采用 Go + Vue3 架构,专注于高性能与低系统开销。通过深度集成
|
||||
Mise 运行时管理,它原生支持 Python、Node.js、Go、Rust、PHP 等所有主流语言环境的动态安装(几乎所有的版本)与统一依赖管理。支持
|
||||
Docker/Docker-Compose 一键部署,开箱即用,是您理想的轻量化脚本托管与任务调度解决方案。
|
||||
|
||||
## 特色
|
||||
|
||||
### 轻量级
|
||||
|
||||
docker/compose部署,无需复杂配置,开箱即用
|
||||
|
||||
### 任务调度
|
||||
|
||||
支持标准 Cron 表达式,常用时间规则快捷选择。日志不落文件,没有磁盘频繁io的问题
|
||||
|
||||
### 脚本管理
|
||||
|
||||
在线代码编辑器,支持文件上传、压缩包解压
|
||||
|
||||
### 在线终端
|
||||
|
||||
WebSocket 实时终端,命令执行结果实时输出
|
||||
|
||||
### 消息推送
|
||||
|
||||
内置强大消息推送与通知引擎,无缝兼容主流渠道,支持系统级事件告警
|
||||
|
||||
### 机密管理
|
||||
|
||||
(New) 类似 GitHub Secrets 的安全存储,支持 AES-GCM 加密,日志自动打码,仅在调度时注入
|
||||
|
||||
### 环境变量
|
||||
|
||||
存储普通配置,任务执行时自动注入
|
||||
|
||||
### 现代UI
|
||||
|
||||
响应式设计,深色/浅色主题切换
|
||||
|
||||
### 移动端
|
||||
|
||||
适配移动小屏样式
|
||||
|
||||
### 远程执行
|
||||
|
||||
支持远程agent执行任务,展示执行结果
|
||||
|
||||
### 多语言支持
|
||||
|
||||
深度集成 Mise,支持几乎所有主流编程语言的动态安装、多版本切换及依赖管理
|
||||
|
||||
---
|
||||
|
||||

|
||||

|
||||
@@ -1,17 +0,0 @@
|
||||
additionalProperties:
|
||||
key: baihu-panel
|
||||
name: 白虎面板
|
||||
tags:
|
||||
- WebSite
|
||||
- Local
|
||||
shortDescZh: 轻量级定时任务管理系统
|
||||
shortDescEn: Lightweight Timed Task Management System
|
||||
type: website
|
||||
crossVersionUpdate: true
|
||||
limit: 0
|
||||
website: https://github.com/engigu/baihu-panel/
|
||||
github: https://github.com/engigu/baihu-panel/
|
||||
document: https://github.com/engigu/baihu-panel/
|
||||
architectures:
|
||||
- amd64
|
||||
- arm64
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 28 KiB |
@@ -1 +0,0 @@
|
||||
<svg t="1766107903919" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1942" width="200" height="200"><path d="M884.992 273.05984c4.10624 0 5.0688-2.36544 2.10944-5.25312 0 0-64.28672-65.55648-111.7696-75.55072-47.48288-9.984-45.47584-59.37152-80.56832-75.02848-72.0896-32.16384-158.6176-34.3552-158.6176-34.3552s-91.37152-4.92544-138.752-9.89184c-19.46624-2.03776-54.46656-9.58464-54.46656-9.58464-4.0448-0.84992-10.63936-1.19808-14.66368-0.44032 0 0-30.63808-0.07168-44.30848 43.35616-8.8576 28.11904 1.792 104.79616 1.792 104.79616 1.46432 12.27776-3.42016 30.21824-10.72128 40.20224 0 0-36.77184 46.03904-58.9312 100.34176-22.15936 54.30272 118.15936 145.05984 208.98816 205.27104C507.82208 613.89824 502.03648 743.424 502.03648 743.424s-74.19904-96.75776-194.00704-156.9792C188.2112 526.22336 150.30272 442.23488 150.30272 442.23488c-2.89792-5.45792-5.94944-4.94592-6.71744 1.21856 0 0-15.1552 91.61728 16.25088 147.8144 70.92224 126.88384 141.74208 112.88576 197.03808 183.27552s54.272 164.9152 54.272 164.9152-97.62816-141.29152-235.66336-205.55776c-91.53536-61.27616-74.7008-125.91104-85.49376-101.85728-10.79296 24.05376 26.73664 192.41984 65.40288 222.2592 80.57856 62.18752 94.16704 101.98016 94.16704 101.98016h175.53408S544.512 814.85824 572.928 725.73952c44.41088-139.30496 40.20224-191.26272 40.20224-191.26272 0.08192-8.22272 6.81984-14.19264 14.98112-13.29152 0 0 46.45888 4.64896 66.64192 9.68704 23.53152 5.86752 55.35744 26.20416 55.35744 26.20416 3.49184 2.14016 7.39328 0.68608 8.69376-3.1744l34.4576-102.77888c1.30048-3.8912-0.63488-5.51936-4.352-3.75808 0 0-45.37344 25.09824-88.17664 12.1856-20.15232-6.08256-59.60704-14.82752-74.69056-32.6656-16.95744-20.03968-15.59552-71.3728 26.66496-79.21664 48.0256-8.9088 33.13664 15.14496 65.91488 24.64768 27.42272 7.95648 22.29248-1.69984 26.69568 5.21216 1.67936 2.63168 0.38912 32.65536 0.38912 32.65536-0.21504 6.144 3.39968 7.84384 8.0384 3.79904l41.89184-36.46464c17.37728-11.24352 30.86336-0.57344 48.24064-11.81696 14.73536-9.53344 29.58336-43.66336 29.58336-43.66336 4.48512-9.24672 0.60416-20.41856-8.63232-24.92416l-42.58816-20.80768c-3.69664-1.80224-3.38944-3.26656 0.74752-3.26656h62.0032zM422.54336 123.87328s-49.88928 50.7392-74.5472 50.66752c-24.65792-0.07168-33.24928-56.12544-3.92192-56.12544 18.00192 0 76.32896 0.21504 76.32896 0.21504 4.13696 0.02048 5.0688 2.36544 2.14016 5.24288z m123.09504 249.64096s-3.31776-25.53856-33.16736-40.05888c-29.8496-14.52032-52.5312-41.13408-59.648-68.95616-12.1856-54.8864 48.29184-104.192 48.29184-104.192s-30.1056 73.6768 3.5328 106.60864c54.272 53.12512 40.99072 106.5984 40.99072 106.5984z m155.56608-164.46464c-7.94624 10.32192-9.60512 37.92896-59.2384 20.736-49.63328-17.2032-71.00416-54.5792-71.00416-54.5792-2.27328-3.40992-0.79872-6.49216 3.328-6.8096 0 0 43.55072-5.03808 80.06656 6.44096 24.91392 7.82336 54.79424 23.88992 46.848 34.21184z" fill="#272636" p-id="1943"></path><path d="M366.30528 259.26656c1.05472-1.76128 1.51552-1.57696 1.19808 0.43008 0 0-7.55712 19.0464 22.8864 87.63392 27.0848 61.02016 87.49056 68.7104 118.66112 98.23232 55.808 52.82816 53.52448 123.45344 53.52448 123.45344s-25.82528-49.85856-85.98528-78.83776-92.6208-50.52416-127.7952-85.77024c-45.02528-45.12768 17.5104-145.14176 17.5104-145.14176zM500.0704 961.44384h134.49216s95.8464-138.07616 46.68416-291.25632c-16.19968-50.46272-43.45856-80.00512-43.45856-80.00512-5.18144-6.38976-8.89856-4.88448-8.448 3.34848 0 0 9.15456 99.80928-19.44576 194.00704-28.60032 94.208-109.824 173.90592-109.824 173.90592zM681.61536 956.8768h105.24672s22.38464-73.5232 16.61952-130.21184c-9.30816-91.57632-48.31232-132.72064-48.31232-132.72064-3.80928-4.77184-6.0928-3.67616-5.2224 2.38592 0 0 16.75264 89.1904-14.4896 150.1184-30.9248 60.30336-53.84192 110.42816-53.84192 110.42816zM869.30432 811.35616c-2.88768-2.9184-4.80256-1.95584-4.38272 2.10944 0 0 6.79936 44.99456-7.76192 81.22368-10.12736 25.1904-28.91776 58.60352-28.91776 58.60352h107.17184s5.34528-50.31936-19.89632-83.97824c-11.56096-23.99232-46.21312-57.9584-46.21312-57.9584z" fill="#272636" p-id="1944"></path></svg>
|
||||
|
Before Width: | Height: | Size: 4.0 KiB |
@@ -4,7 +4,7 @@ networks:
|
||||
|
||||
services:
|
||||
bark:
|
||||
image: finab/bark-server:v2.3.5
|
||||
image: finab/bark-server:v2.3.3
|
||||
container_name: ${CONTAINER_NAME}
|
||||
labels:
|
||||
createdBy: "Apps"
|
||||
+1
-1
@@ -4,7 +4,7 @@ networks:
|
||||
|
||||
services:
|
||||
beszel-agent:
|
||||
image: henrygd/beszel-agent:0.18.7
|
||||
image: henrygd/beszel-agent:0.18.4
|
||||
container_name: ${CONTAINER_NAME}
|
||||
labels:
|
||||
createdBy: "Apps"
|
||||
@@ -4,7 +4,7 @@ networks:
|
||||
|
||||
services:
|
||||
bonita:
|
||||
image: suwmlee/bonita:0.27.1
|
||||
image: suwmlee/bonita:0.22.2
|
||||
container_name: ${CONTAINER_NAME}
|
||||
labels:
|
||||
createdBy: "Apps"
|
||||
+1
-1
@@ -4,7 +4,7 @@ networks:
|
||||
|
||||
services:
|
||||
bookstack:
|
||||
image: linuxserver/bookstack:26.05.1
|
||||
image: linuxserver/bookstack:25.12.9
|
||||
container_name: ${CONTAINER_NAME}
|
||||
labels:
|
||||
createdBy: "Apps"
|
||||
@@ -4,7 +4,7 @@ networks:
|
||||
|
||||
services:
|
||||
casdoor:
|
||||
image: casbin/casdoor:3.0.1
|
||||
image: casbin/casdoor:2.359.0
|
||||
container_name: ${CONTAINER_NAME}
|
||||
labels:
|
||||
createdBy: "Apps"
|
||||
@@ -1,20 +0,0 @@
|
||||
networks:
|
||||
1panel-network:
|
||||
external: true
|
||||
|
||||
services:
|
||||
app_name:
|
||||
image: ghcr.io/chartdb/chartdb:1.20.1
|
||||
container_name: ${CONTAINER_NAME}
|
||||
labels:
|
||||
createdBy: "Apps"
|
||||
restart: always
|
||||
networks:
|
||||
- 1panel-network
|
||||
ports:
|
||||
- ${PANEL_APP_PORT_HTTP}:80
|
||||
env_file:
|
||||
- ${GLOBAL_ENV_FILE:-/etc/1panel/envs/global.env}
|
||||
- ${ENV_FILE:-/etc/1panel/envs/default.env}
|
||||
environment:
|
||||
- TZ=Asia/Shanghai
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user