Compare commits

..
Author SHA1 Message Date
gfdgd-xi 23aba101a6 添加推荐依赖deepin-liferaft
Signed-off-by: gfdgd_xi <3025613752@qq.com>
2026-08-06 18:08:37 +08:00
shenmo7192 8ee15d5725 fix(sync.py): 修正Gitee仓库名称获取逻辑,使用安全路径
Gitee的name字段可能包含非法字符,改用path作为仓库URL安全路径,确保clone/push URL合法
2026-08-03 19:39:56 +08:00
shenmo7192 a6f6c26fb9 ci(github workflow): simplify sync workflow and rewrite sync script
1. 移除多余的第三方同步目标和依赖包
2. 将原bash脚本重写为python脚本,新增多线程同步、失败重试和同步报告
3. 精简工作流的环境变量和执行参数
2026-08-03 19:16:34 +08:00
gfdgd-xi eebd5d7817 修复github项目页图片缺失的问题
Signed-off-by: gfdgd_xi <3025613752@qq.com>
2026-07-29 09:49:43 +08:00
gfdgd-xi dd3d0e1a34 使用gitee令牌拉取仓库
Signed-off-by: gfdgd_xi <3025613752@qq.com>
2026-07-25 18:28:20 +08:00
CharOfString 73a77bb9ca polish: README 2026-07-24 00:08:32 +08:00
gfdgd-xi 96feeb840f 调整ssh加密方式
Signed-off-by: gfdgd_xi <3025613752@qq.com>
2026-07-14 11:23:59 +08:00
10 changed files with 174 additions and 84 deletions
@@ -140,10 +140,8 @@ jobs:
mkdir -p ~/.ssh/ mkdir -p ~/.ssh/
ssh-keyscan -p $UPORT -H $UHOST >> ~/.ssh/known_hosts ssh-keyscan -p $UPORT -H $UHOST >> ~/.ssh/known_hosts
tarName=$(ls | grep .tar | head -n 1) tarName=$(ls | grep .tar | head -n 1)
sudo sysctl -w net.ipv4.tcp_mtu_probing=1 sshpass -p "$UPASSWD" rsync -e "ssh -p $UPORT" $tarName $UUSERS@$UHOST:$UPATH
sshpass -p "$UPASSWD" scp -o HostKeyAlgorithms=ecdsa-sha2-nistp256 -o KexAlgorithms=ecdh-sha2-nistp256 -c aes128-ctr -O $tarName $UUSERS@$UHOST:$UPATH sshpass -p "$UPASSWD" ssh $UUSERS@$UHOST -p $UPORT $UPROGRAM ${{ inputs.gxde-codename-upload }} $UPATH/$tarName > /dev/null
sshpass -p "$UPASSWD" ssh $UUSERS@$UHOST -o HostKeyAlgorithms=ecdsa-sha2-nistp256 -o KexAlgorithms=ecdh-sha2-nistp256 -c aes128-ctr -p $UPORT $UPROGRAM ${{ inputs.gxde-codename-upload }} $UPATH/$tarName > /dev/null
sudo sysctl -w net.ipv4.tcp_mtu_probing=0
- name: Create Release - name: Create Release
uses: softprops/action-gh-release@v1 uses: softprops/action-gh-release@v1
+2 -4
View File
@@ -141,10 +141,8 @@ jobs:
mkdir -p ~/.ssh/ mkdir -p ~/.ssh/
ssh-keyscan -p $UPORT -H $UHOST >> ~/.ssh/known_hosts ssh-keyscan -p $UPORT -H $UHOST >> ~/.ssh/known_hosts
tarName=$(ls | grep .tar | head -n 1) tarName=$(ls | grep .tar | head -n 1)
sudo sysctl -w net.ipv4.tcp_mtu_probing=1 sshpass -p "$UPASSWD" rsync -e "ssh -p $UPORT" $tarName $UUSERS@$UHOST:$UPATH
sshpass -p "$UPASSWD" scp -o HostKeyAlgorithms=ecdsa-sha2-nistp256 -o KexAlgorithms=ecdh-sha2-nistp256 -c aes128-ctr -O $tarName $UUSERS@$UHOST:$UPATH sshpass -p "$UPASSWD" ssh $UUSERS@$UHOST -p $UPORT $UPROGRAM ${{ inputs.gxde-codename-upload }} $UPATH/$tarName > /dev/null
sshpass -p "$UPASSWD" ssh $UUSERS@$UHOST -o HostKeyAlgorithms=ecdsa-sha2-nistp256 -o KexAlgorithms=ecdh-sha2-nistp256 -c aes128-ctr -p $UPORT $UPROGRAM ${{ inputs.gxde-codename-upload }} $UPATH/$tarName > /dev/null
sudo sysctl -w net.ipv4.tcp_mtu_probing=0
- name: Create Release - name: Create Release
uses: softprops/action-gh-release@v1 uses: softprops/action-gh-release@v1
+4 -6
View File
@@ -16,17 +16,15 @@ jobs:
- name: Config - name: Config
run: | run: |
sudo apt update sudo apt update
sudo apt install git python3-requests -y sudo apt install git -y
- name: Push - name: Push
env: env:
GITHUBTOKEN: ${{ secrets.GITHUBTOKEN }} GITHUBTOKEN: ${{ secrets.GITHUBTOKEN }}
GITHUBUSER: ${{ secrets.GITHUBUSER }} GITHUBUSER: ${{ secrets.GITHUBUSER }}
GITCODETOKEN: ${{ secrets.GITCODETOKEN }} GITEEUSER: ${{ secrets.GITEEUSER }}
GITCODEUSER: ${{ secrets.GITCODEUSER }} GITEETOCKEN: ${{ secrets.GITEETOCKEN }}
ATOMGITTOKEN: ${{ secrets.ATOMGITTOKEN }}
ATOMGITUSER: ${{ secrets.ATOMGITUSER }}
run: | run: |
cd sync-gitee-to-github cd sync-gitee-to-github
python3 sync.py $GITHUBUSER $GITHUBTOKEN $GITCODEUSER $GITCODETOKEN $ATOMGITUSER $ATOMGITTOKEN python3 sync.py $GITEEUSER $GITEETOCKEN $GITHUBUSER $GITHUBTOKEN
+15 -3
View File
@@ -1,9 +1,18 @@
![HEADER](./readme-header.png)
<div>
<div style="float: left; display: flex; align-items: center" >
<a href='https://gitee.com/GXDE-OS/GXDE/stargazers'><img src='https://gitee.com/GXDE-OS/GXDE/badge/star.svg?theme=dark' alt='star'></img></a>
<img src='https://gitcode.com/GXDE-OS/GXDE/star/badge.svg' alt='G-Star'></img>
</div>
<div style="float: right">
<a href="./README.zh.md">中文版</a>
</div>
</div>
## Welcome to GXDE OS Community ## Welcome to GXDE OS Community
**[中文](/README.zh.md)**
GXDE OS is an Debian based Linux distro featuring GXDE Desktop Environment. It offers an elegant, beautifu, light weight and out-of-the-box experience. GXDE OS is an Debian based Linux distro featuring GXDE Desktop Environment. It offers an elegant, beautifu, light weight and out-of-the-box experience.
### Classic and Extended Deepin DE Experience ### Classic and Extended Deepin DE Experience
@@ -88,4 +97,7 @@ The author is online and hungry for support (nom nom~). Feeding might even get u
<p><img src="https://www.gxde.top/install/gf.jpg" style="border-radius: 4px;" ></p> <p><img src="https://www.gxde.top/install/gf.jpg" style="border-radius: 4px;" ></p>
# ©2023Now gfdgd xi
<span style="color: #E6004C; font-size: 20px"><b>©2023Now gfdgd xi</b></span>
<div style="background: #E6004C; width: 100%; height: 3px;"></div>
+12 -8
View File
@@ -1,11 +1,14 @@
<center><img src=new-logo-long.png width=300/></center> ![HEADER](./readme-header.png)
<hr>
<div>
<div style="float: left; display: flex; align-items: center" >
<a href='https://gitee.com/GXDE-OS/GXDE/stargazers'><img src='https://gitee.com/GXDE-OS/GXDE/badge/star.svg?theme=dark' alt='star'></img></a> <a href='https://gitee.com/GXDE-OS/GXDE/stargazers'><img src='https://gitee.com/GXDE-OS/GXDE/badge/star.svg?theme=dark' alt='star'></img></a>
<img src='https://gitcode.com/GXDE-OS/GXDE/star/badge.svg' alt='G-Star'></img>
![G-Start](https://gitcode.com/GXDE-OS/GXDE/star/badge.svg) </div>
<div style="float: right">
<a href="./README.md">English Version</a>
**[English](/README.md)** </div>
</div>
## 简介 ## 简介
@@ -87,5 +90,6 @@ Gitcodehttps://gitcode.com/GXDE-OS
<p><img src="https://www.gxde.top/install/gf.jpg" style="border-radius: 4px;" ></p> <p><img src="https://www.gxde.top/install/gf.jpg" style="border-radius: 4px;" ></p>
<span style="color: #E6004C; font-size: 20px"><b>©2023Now gfdgd xi</b></span>
# ©2023Now gfdgd xi <div style="background: #E6004C; width: 100%; height: 3px;"></div>
+3 -2
View File
@@ -1,4 +1,4 @@
gxde (2026.07.11) UNRELEASED; urgency=medium gxde (2026.08.06) UNRELEASED; urgency=medium
* 新增 remmina 以解决远程问题 * 新增 remmina 以解决远程问题
* 改为安装 dde-printer * 改为安装 dde-printer
@@ -25,8 +25,9 @@ gxde (2026.07.11) UNRELEASED; urgency=medium
* 更改 gxde-desktop-extra 推荐依赖 * 更改 gxde-desktop-extra 推荐依赖
* 推荐安装 firmware-atheros | firmware-ath9k-htc * 推荐安装 firmware-atheros | firmware-ath9k-htc
* gxde-desktop-android 指定安装 spark-store 而不是可选安装 aptss * gxde-desktop-android 指定安装 spark-store 而不是可选安装 aptss
* 添加推荐依赖 deepin-liferaft
-- gfdgd_xi <3025613752@qq.com> Sat, 11 Jul 2026 14:12:50 +0800 -- gfdgd_xi <3025613752@qq.com> Thu, 06 Aug 2026 18:08:23 +0800
gxde (2024.10.20) UNRELEASED; urgency=medium gxde (2024.10.20) UNRELEASED; urgency=medium
+1
View File
@@ -50,6 +50,7 @@ Recommends: ${misc:Depends},
fcitx5-pinyin-zhwiki, fcitx5-pinyin-zhwiki,
dde-cooperation, dde-cooperation,
firmware-atheros, firmware-atheros,
deepin-liferaft,
Description: GXDE New Desktop Environment Extra - Next Description: GXDE New Desktop Environment Extra - Next
This is a meta package depends GXDE New Desktop Envrionment Extra. This is a meta package depends GXDE New Desktop Envrionment Extra.
. .
Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

+135 -57
View File
@@ -1,68 +1,146 @@
#!/bin/bash #!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
将 Gitee 上的 GXDE-OS 组织仓库镜像同步到 GitHubGXDE-OS 组织)。
用法:
python3 sync.py <gitee用户名> <gitee密码或Token> <github用户名> <githubToken>
流程:
1. 通过 Gitee API v5 分页获取 GXDE-OS 组织下的全部仓库列表(带 token 失败时回退匿名)
2. 多线程 clone --bare 拉取 Gitee 仓库
3. 逐个 push --mirror 推送到 GitHub,失败自动重试并在结束时汇总报告
"""
import json
import os import os
import subprocess
import sys import sys
import time import time
import requests import urllib.parse
import threading import urllib.request
from concurrent.futures import ThreadPoolExecutor, as_completed
programPath = os.path.split(os.path.realpath(__file__))[0] # 返回 string programPath = os.path.split(os.path.realpath(__file__))[0]
dataHeaders = { cloneDir = os.path.join(programPath, "git-clone")
"accept": "application/json" orgName = "GXDE-OS"
} perPage = 100
pullUrl = "https://gitee.com/GXDE-OS/" threadMax = 8
pushUrl = [
"https://@USER@:@PASS@@github.com/GXDE-OS/",
"https://@USER@:@PASS@@gitcode.com/GXDE-OS/",
"https://@USER@:@PASS@@atomgit.com/GXDE-OS/"
]
if (len(sys.argv) < 1 + len(pushUrl) * 2):
print(f"请输入用于推送的账户和密码(需要 {len(pushUrl)} 组以推送不同的平台,提供顺序如下)")
for i in pushUrl:
print(f" {i}")
exit(1)
# 读取参数 def usage():
userName = [] print("用法: python3 sync.py <gitee用户名> <gitee密码或Token> <github用户名> <githubToken>")
password = [] sys.exit(1)
for i in range(1, len(sys.argv)):
# 输入账户
if (i % 2 == 1):
userName.append(sys.argv[i])
# 输入密码
if (i % 2 == 0):
password.append(sys.argv[i])
def sync(i):
global thread
# 拉取代码进行同步
if (not os.path.exists(f"{programPath}/git-clone")):
os.makedirs(f"{programPath}/git-clone")
print(f"======================> {pullUrl}/{i}")
os.system(f"cd '{programPath}/git-clone' ; git clone --bare '{pullUrl}/{i}'")
# 推送
for j in range(len(pushUrl)):
# git remote set-url origin
gitUrl = pushUrl[j].replace("@USER@", userName[j]).replace("@PASS@", password[j]) + "/" + i
os.system(f"cd '{programPath}/git-clone/{i}.git' ; git remote set-url origin '{gitUrl}'")
os.system(f"cd '{programPath}/git-clone/{i}.git' ; git push --mirror")
# 移除临时文件
os.system(f"rm -rf '{programPath}/git-clone/{i}.git'")
thread -= 1
data = requests.get("https://api.github.com/users/GXDE-OS/repos", headers=dataHeaders).json() def apiGet(path, params):
repoList = [] """调用 Gitee API v5 的单个请求"""
# 获取仓库列表 params["per_page"] = str(perPage)
for i in data: url = "https://gitee.com/api/v5" + path + "?" + urllib.parse.urlencode(params)
repoList.append(i["name"]) req = urllib.request.Request(url, headers={"User-Agent": "GXDE-Sync/1.0"})
# 多线程处理以提升速度 with urllib.request.urlopen(req, timeout=30) as resp:
thread = 0 return json.loads(resp.read().decode("utf-8"))
threadMax = 32
for i in repoList:
def getGiteeRepos(token):
"""分页获取 Gitee 组织下全部仓库的 path(URL 安全路径)
Gitee API 返回的 name 是仓库别名(可能含大写、中文或括号,如
"CTranslate2"),不能直接用作 clone URL 的路径组件;path 才是 URL
安全的仓库路径(如 "ctranslate2"),用它拼接 clone/push URL 才合法。
"""
repoList = []
page = 1
while True: while True:
time.sleep(0.1) params = {"page": str(page)}
if (thread < threadMax): if token:
threading.Thread(target=sync, args=[i]).start() params["access_token"] = token
thread += 1 data = apiGet(f"/orgs/{orgName}/repos", params)
if not isinstance(data, list) or len(data) == 0:
break break
repoList.extend([i["path"] for i in data])
page += 1
return repoList
def runGit(args, cwd=None):
return subprocess.run(args, cwd=cwd, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT, text=True)
def syncRepo(name, pullUrl, pushUrl):
repoDir = os.path.join(cloneDir, name + ".git")
try:
# 1. 从 Gitee clone --bare(重试 3 次)
ok = False
lastOut = ""
for attempt in range(3):
result = runGit(["git", "clone", "--bare", pullUrl + name, repoDir])
if result.returncode == 0:
ok = True
break
lastOut = result.stdout
time.sleep(5)
if not ok:
print(f"[FAIL] clone 失败: {name}\n{lastOut}")
return False
# 2. push --mirror 到 GitHub(重试 3 次)
ok = False
lastOut = ""
for attempt in range(3):
result = runGit(["git", "-C", repoDir, "push", "--mirror", pushUrl + name])
if result.returncode == 0:
ok = True
break
lastOut = result.stdout
time.sleep(5)
if not ok:
print(f"[FAIL] push 失败: {name}\n{lastOut}")
return False
print(f"[ OK ] 同步完成: {name}")
return True
finally:
# 清理临时目录
runGit(["rm", "-rf", repoDir])
def main():
if len(sys.argv) < 5:
usage()
giteeUser, giteeToken = sys.argv[1], sys.argv[2]
githubUser, githubToken = sys.argv[3], sys.argv[4]
pullUrl = f"https://{urllib.parse.quote(giteeUser)}:{urllib.parse.quote(giteeToken)}@gitee.com/{orgName}/"
pushUrl = f"https://{urllib.parse.quote(githubUser)}:{urllib.parse.quote(githubToken)}@github.com/{orgName}/"
os.makedirs(cloneDir, exist_ok=True)
# 获取仓库列表:优先带 token,失败则回退到匿名(仅公开仓库)
try:
repoList = getGiteeRepos(giteeToken)
except Exception:
repoList = getGiteeRepos("")
print(f"共获取到 {len(repoList)} 个仓库")
if not repoList:
print("未能获取仓库列表,退出")
sys.exit(1)
failed = []
with ThreadPoolExecutor(max_workers=threadMax) as pool:
futures = {pool.submit(syncRepo, n, pullUrl, pushUrl): n for n in repoList}
for future in as_completed(futures):
if not future.result():
failed.append(futures[future])
print("=" * 50)
print(f"同步完成: 成功 {len(repoList) - len(failed)} / {len(repoList)}")
if failed:
print("以下仓库同步失败:")
for name in failed:
print(" -", name)
sys.exit(1)
if __name__ == "__main__":
main()