Compare commits
6
Commits
dbd28458b8
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
60d46a4951 | ||
|
|
0011b1b558 | ||
|
|
1b54447ccb | ||
|
|
cb3a661611 | ||
|
|
84cc672823 | ||
|
|
e30c74007b |
@@ -0,0 +1,5 @@
|
||||
# CodeGraph data files — local to each machine, not for committing.
|
||||
# Ignore everything in .codegraph/ except this file itself, so transient
|
||||
# files (the database, daemon.pid, sockets, logs) never show up in git.
|
||||
*
|
||||
!.gitignore
|
||||
@@ -0,0 +1,189 @@
|
||||
name: Build Multi-Platform Release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*' # 当推送形如 v1.0.0 的 tag 时触发构建
|
||||
workflow_dispatch: # 支持手动触发构建
|
||||
|
||||
jobs:
|
||||
# 1. 编译 Windows 端 (.exe)
|
||||
build-windows:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.11'
|
||||
cache: 'pip'
|
||||
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install -r requirements.txt
|
||||
pip install pyinstaller
|
||||
|
||||
- name: Build EXE
|
||||
run: |
|
||||
python -m PyInstaller build.spec --clean
|
||||
|
||||
- name: Upload Windows Artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: CursorTokenLogin-Windows
|
||||
path: dist/CursorTokenLogin.exe
|
||||
|
||||
# 2. 编译 macOS 端 (.app)
|
||||
build-macos:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macos-13, macos-latest]
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.11'
|
||||
cache: 'pip'
|
||||
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install -r requirements.txt
|
||||
pip install pyinstaller Pillow
|
||||
|
||||
- name: Set Architecture Name
|
||||
run: |
|
||||
if [ "${{ matrix.os }}" = "macos-13" ]; then
|
||||
echo "ARCH_NAME=Intel" >> $GITHUB_ENV
|
||||
else
|
||||
echo "ARCH_NAME=AppleSilicon" >> $GITHUB_ENV
|
||||
fi
|
||||
shell: bash
|
||||
|
||||
- name: Build App Bundle
|
||||
run: |
|
||||
python -m PyInstaller build.spec --clean
|
||||
|
||||
- name: Zip macOS App
|
||||
run: |
|
||||
cd dist
|
||||
zip -r CursorTokenLogin-macOS-${{ env.ARCH_NAME }}.zip CursorTokenLogin.app
|
||||
|
||||
- name: Upload macOS Artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: CursorTokenLogin-macOS-${{ env.ARCH_NAME }}
|
||||
path: dist/CursorTokenLogin-macOS-${{ env.ARCH_NAME }}.zip
|
||||
|
||||
# 3. 编译 Linux 端并打包为 .deb 和 .rpm
|
||||
build-linux:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.11'
|
||||
cache: 'pip'
|
||||
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install -r requirements.txt
|
||||
pip install pyinstaller
|
||||
# 安装打包 deb 和 rpm 所需的系统工具
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y dpkg rpm alien
|
||||
|
||||
- name: Build Linux Binary
|
||||
run: |
|
||||
python -m PyInstaller build.spec --clean
|
||||
|
||||
- name: Pack DEB Package
|
||||
run: |
|
||||
# 创建 deb 包目录结构
|
||||
mkdir -p deb-package/DEBIAN
|
||||
mkdir -p deb-package/usr/bin
|
||||
mkdir -p deb-package/usr/share/applications
|
||||
mkdir -p deb-package/usr/share/pixmaps
|
||||
|
||||
# 拷贝编译好的二进制文件
|
||||
cp dist/CursorTokenLogin deb-package/usr/bin/cursortokenlogin
|
||||
chmod +x deb-package/usr/bin/cursortokenlogin
|
||||
|
||||
# 拷贝图标
|
||||
cp logo.png deb-package/usr/share/pixmaps/cursortokenlogin.png
|
||||
|
||||
# 创建控制文件
|
||||
cat <<EOF > deb-package/DEBIAN/control
|
||||
Package: cursortokenlogin
|
||||
Version: 1.0.0
|
||||
Section: utils
|
||||
Priority: optional
|
||||
Architecture: amd64
|
||||
Maintainer: Yunzer
|
||||
Description: Cursor Token Login Helper
|
||||
EOF
|
||||
|
||||
# 创建桌面启动快捷方式
|
||||
cat <<EOF > deb-package/usr/share/applications/cursortokenlogin.desktop
|
||||
[Desktop Entry]
|
||||
Name=CursorTokenLogin
|
||||
Comment=Cursor Token Login Helper
|
||||
Exec=/usr/bin/cursortokenlogin
|
||||
Icon=cursortokenlogin
|
||||
Terminal=false
|
||||
Type=Application
|
||||
Categories=Utility;Development;
|
||||
EOF
|
||||
|
||||
# 构建 deb
|
||||
dpkg-deb --build deb-package cursortokenlogin.deb
|
||||
|
||||
- name: Pack RPM Package (Convert from DEB using alien)
|
||||
run: |
|
||||
# 使用 alien 工具将 deb 快速转换为 rpm,避免编写复杂的 spec 构建脚本
|
||||
sudo alien --to-rpm --scripts cursortokenlogin.deb
|
||||
# 重命名生成的 rpm 文件方便识别
|
||||
mv *.rpm cursortokenlogin.rpm
|
||||
|
||||
- name: Upload Linux Artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: CursorTokenLogin-Linux
|
||||
path: |
|
||||
cursortokenlogin.deb
|
||||
cursortokenlogin.rpm
|
||||
|
||||
# 4. 自动创建 GitHub Release 并上传 5 个包
|
||||
create-release:
|
||||
needs: [build-windows, build-macos, build-linux]
|
||||
runs-on: ubuntu-latest
|
||||
if: startsWith(github.ref, 'refs/tags/v') # 仅在推送 tag 时执行 Release 发布
|
||||
steps:
|
||||
- name: Download All Artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
path: ./release-files
|
||||
merge-multiple: true
|
||||
|
||||
- name: Create Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
files: |
|
||||
release-files/CursorTokenLogin.exe
|
||||
release-files/CursorTokenLogin-macOS-Intel.zip
|
||||
release-files/CursorTokenLogin-macOS-AppleSilicon.zip
|
||||
release-files/cursortokenlogin.deb
|
||||
release-files/cursortokenlogin.rpm
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -1,13 +1,85 @@
|
||||
python -m PyInstaller -w -F main.py
|
||||
# 多平台编译与打包指南
|
||||
|
||||
<br />
|
||||
在 Windows 系统下,由于 PyInstaller 的工作机制是直接打包当前平台的 Python 解析器和系统动态库,**它不支持交叉编译**(即在 Windows 本机无法编译出 macOS 的 `.app` 苹果程序,也无法直接打包 Linux 的 `.deb` 或 `.rpm` 安装包)。
|
||||
|
||||
# 编译成exe
|
||||
为了解决这个问题,并在一台电脑上实现 4 端程序(Windows `.exe`、macOS `.app`、Debian/Ubuntu `.deb`、RedHat/Fedora `.rpm`)的统一打包,我们已经在项目中配置了 **GitHub Actions 自动化流水线**。
|
||||
|
||||
---
|
||||
|
||||
## 🚀 推荐方案:使用 GitHub Actions 自动打包 4 端程序
|
||||
|
||||
我们已经在项目中创建了自动化打包脚本:[.github/workflows/build.yml](file:///.github/workflows/build.yml)。
|
||||
|
||||
您只需将代码托管在 GitHub 仓库中,GitHub 就会为您调用免费的 Windows、macOS 和 Linux 虚拟服务器,一键自动构建出所有安装包!
|
||||
|
||||
### 操作步骤:
|
||||
1. **首次配置并推送代码到 GitHub 仓库** (在本地项目终端运行):
|
||||
```bash
|
||||
# 关联远程 GitHub 仓库,并将其命名为 github (实现双仓库并存)
|
||||
git remote add github https://github.com/hero920103/cursorlogin.git
|
||||
|
||||
# 将本地的 master 分支推送到 GitHub
|
||||
git push -u github master
|
||||
```
|
||||
2. **推送 Tag 触发 4 端自动打包** (后续每次需要打包发布时,直接运行下面两行):
|
||||
```bash
|
||||
# 1. 本地打上版本 tag
|
||||
git tag vx.x.x
|
||||
|
||||
# 2. 将 tag 单独推送到 github 触发云端自动构建
|
||||
git push github vx.x.x
|
||||
```
|
||||
3. GitHub Actions 收到 Tag 后会自动触发构建,云端会启动多个编译任务,最终产出:
|
||||
- 💻 **Windows**:编译出 `CursorTokenLogin.exe`
|
||||
- 🍏 **macOS (M1/M2/M3 芯片)**:编译出 `CursorTokenLogin-macOS-AppleSilicon.zip` (解压即得 `.app`)
|
||||
- 🍏 **macOS (Intel 芯片)**:编译出 `CursorTokenLogin-macOS-Intel.zip` (解压即得 `.app`)
|
||||
- 🐧 **Linux**:编译出 Linux 运行文件,并自动打包为 `cursortokenlogin.deb` 和 `cursortokenlogin.rpm`
|
||||
4. **下载成品**:构建完成后(耗时约 3~5 分钟),GitHub 会自动在您的仓库右侧 **Releases** 栏目中生成一个名为 `v1.0.0` 的发布页,进入即可直接下载编译好的 5 个安装包!
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ 本地手动构建说明(Windows/Linux/Mac)
|
||||
|
||||
如果您不想使用 GitHub 托管,也可以在本地不同的系统环境中分别运行打包:
|
||||
|
||||
### 1. 编译 Windows 程序 (`.exe`)
|
||||
在 Windows 命令行中运行:
|
||||
```bash
|
||||
python -m PyInstaller build.spec --clean
|
||||
```
|
||||
|
||||
### 2. 编译 macOS 程序 (`.app`)
|
||||
在 macOS 终端中运行:
|
||||
```bash
|
||||
python -m PyInstaller build.spec --clean
|
||||
```
|
||||
*(编译生成 `.app` 文件目录,拷贝分发前建议压缩为 `.zip`)*
|
||||
|
||||
### 3. 编译 Linux 安装包 (`.deb` / `.rpm`)
|
||||
在 Ubuntu / Debian 终端下,可以使用以下命令快速打包:
|
||||
```bash
|
||||
# 1. 编译 Linux 原生可执行文件
|
||||
python -m PyInstaller build.spec --clean
|
||||
|
||||
<br />
|
||||
# 2. 组织 DEB 包目录结构并打包
|
||||
mkdir -p deb-package/DEBIAN
|
||||
mkdir -p deb-package/usr/bin
|
||||
cp dist/CursorTokenLogin deb-package/usr/bin/cursortokenlogin
|
||||
chmod +x deb-package/usr/bin/cursortokenlogin
|
||||
|
||||
# 关于 Win + Mac 同时构建(后续)
|
||||
- PyInstaller 不能在 Windows 本机直接产出 macOS 程序。
|
||||
- 当前命令在 Windows 只能生成 `.exe`,在 macOS 才能生成 `.app`。
|
||||
- 后续可用 GitHub Actions 做双平台构建:本地打 Windows,云端 `macos-latest` 打 macOS。
|
||||
# 创建 control 配置文件
|
||||
cat <<EOF > deb-package/DEBIAN/control
|
||||
Package: cursortokenlogin
|
||||
Version: 1.0.0
|
||||
Architecture: amd64
|
||||
Maintainer: Yunzer
|
||||
Description: Cursor Token Login Helper
|
||||
EOF
|
||||
|
||||
# 生成 deb 安装包
|
||||
dpkg-deb --build deb-package cursortokenlogin.deb
|
||||
|
||||
# 3. 使用 alien 将 deb 包转换为 rpm 包
|
||||
sudo apt-get install alien
|
||||
sudo alien --to-rpm --scripts cursortokenlogin.deb
|
||||
```
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,58 @@
|
||||
import sqlite3
|
||||
from pathlib import Path
|
||||
|
||||
p = Path("state.vscdb")
|
||||
print("db_exists=", p.exists(), p.resolve())
|
||||
|
||||
conn = sqlite3.connect(p)
|
||||
cur = conn.cursor()
|
||||
|
||||
tables = cur.execute(
|
||||
"SELECT name FROM sqlite_master WHERE type='table' ORDER BY name"
|
||||
).fetchall()
|
||||
print("tables=", tables)
|
||||
|
||||
try:
|
||||
schema = cur.execute("PRAGMA table_info(ItemTable)").fetchall()
|
||||
print("ItemTable schema=", schema)
|
||||
|
||||
rows = cur.execute(
|
||||
"""
|
||||
SELECT key, value
|
||||
FROM ItemTable
|
||||
WHERE lower(key) LIKE '%auth%'
|
||||
OR lower(key) LIKE '%token%'
|
||||
OR lower(key) LIKE '%cursoraccount%'
|
||||
OR lower(key) LIKE '%cursor%'
|
||||
ORDER BY key
|
||||
"""
|
||||
).fetchall()
|
||||
|
||||
print("matched_rows=", len(rows))
|
||||
for k, v in rows:
|
||||
s = "" if v is None else str(v)
|
||||
masked = (s[:18] + "..." + s[-12:]) if len(s) > 40 else s
|
||||
print(f"{k} len={len(s)} value={masked}")
|
||||
|
||||
print("\ncursorDiskKV schema=", cur.execute("PRAGMA table_info(cursorDiskKV)").fetchall())
|
||||
disk_rows = cur.execute(
|
||||
"""
|
||||
SELECT key, value
|
||||
FROM cursorDiskKV
|
||||
WHERE lower(key) LIKE '%auth%'
|
||||
OR lower(key) LIKE '%token%'
|
||||
OR lower(key) LIKE '%cursor%'
|
||||
OR lower(key) LIKE '%account%'
|
||||
ORDER BY key
|
||||
"""
|
||||
).fetchall()
|
||||
print("cursorDiskKV matched_rows=", len(disk_rows))
|
||||
for k, v in disk_rows:
|
||||
if isinstance(v, bytes):
|
||||
s = v.decode("utf-8", "ignore")
|
||||
else:
|
||||
s = "" if v is None else str(v)
|
||||
masked = (s[:18] + "..." + s[-12:]) if len(s) > 40 else s
|
||||
print(f"{k} len={len(s)} value={masked}")
|
||||
finally:
|
||||
conn.close()
|
||||
+10
-1
@@ -13,7 +13,7 @@ if not os.path.isfile(_LOGO_ICO):
|
||||
"找不到图标文件: %s\n请将 logo.ico 放在与 build.spec 同一目录后重新打包。" % _LOGO_ICO
|
||||
)
|
||||
_LOGO_ICO_ABS = os.path.abspath(_LOGO_ICO)
|
||||
print("[build.spec] EXE 嵌入图标:", _LOGO_ICO_ABS)
|
||||
print("[build.spec] EXE icon path:", _LOGO_ICO_ABS)
|
||||
|
||||
block_cipher = None
|
||||
|
||||
@@ -66,3 +66,12 @@ exe = EXE(
|
||||
# 必须用绝对路径;资源管理器若仍显示旧图标多半是 Windows 图标缓存,可改 exe 文件名或清 IconCache
|
||||
icon=_LOGO_ICO_ABS,
|
||||
)
|
||||
|
||||
import sys
|
||||
if sys.platform == 'darwin':
|
||||
app = BUNDLE(
|
||||
exe,
|
||||
name='CursorTokenLogin.app',
|
||||
icon='logo.png',
|
||||
bundle_identifier='com.yunzer.cursortokenlogin',
|
||||
)
|
||||
|
||||
+1115
File diff suppressed because it is too large
Load Diff
@@ -1,29 +1,11 @@
|
||||
# -*- mode: python ; coding: utf-8 -*-
|
||||
import os
|
||||
|
||||
try:
|
||||
_SPEC_ROOT = os.path.dirname(os.path.abspath(SPEC))
|
||||
except NameError:
|
||||
_SPEC_ROOT = os.getcwd()
|
||||
_LOGO_ICO = os.path.normpath(os.path.join(_SPEC_ROOT, "logo.ico"))
|
||||
if not os.path.isfile(_LOGO_ICO):
|
||||
raise FileNotFoundError(
|
||||
"找不到图标文件: %s\n请将 logo.ico 放在与 main.spec 同一目录后重新打包。" % _LOGO_ICO
|
||||
)
|
||||
_LOGO_ICO_ABS = os.path.abspath(_LOGO_ICO)
|
||||
|
||||
# 须与 build.spec 一致,否则 onefile 内无 layout/main.ui,会出现「找不到 UI 文件」
|
||||
_datas = [
|
||||
(os.path.join(os.getcwd(), 'layout'), 'layout'),
|
||||
(os.path.join(os.getcwd(), 'assets'), 'assets'),
|
||||
(_LOGO_ICO_ABS, "."),
|
||||
]
|
||||
|
||||
a = Analysis(
|
||||
['main.py'],
|
||||
pathex=[os.getcwd()],
|
||||
pathex=[],
|
||||
binaries=[],
|
||||
datas=_datas,
|
||||
datas=[],
|
||||
hiddenimports=[],
|
||||
hookspath=[],
|
||||
hooksconfig={},
|
||||
@@ -44,14 +26,14 @@ exe = EXE(
|
||||
debug=False,
|
||||
bootloader_ignore_signals=False,
|
||||
strip=False,
|
||||
upx=False,
|
||||
upx=True,
|
||||
upx_exclude=[],
|
||||
runtime_tmpdir=r'%LOCALAPPDATA%\CursorTokenLogin\runtime',
|
||||
runtime_tmpdir=None,
|
||||
console=False,
|
||||
disable_windowed_traceback=False,
|
||||
argv_emulation=False,
|
||||
target_arch=None,
|
||||
codesign_identity=None,
|
||||
entitlements_file=None,
|
||||
icon=_LOGO_ICO_ABS,
|
||||
icon=['logo.ico'],
|
||||
)
|
||||
|
||||
+1
-1
@@ -1120,7 +1120,7 @@ class MainWindow(QMainWindow):
|
||||
self.statusBar().addPermanentWidget(QLabel(f"Version: {__VERSION__}"))
|
||||
|
||||
self.log("🚀 程序启动成功")
|
||||
self.log("📋 请先粘贴Token,然后点击换号")
|
||||
# self.log("📋 请先粘贴Token,然后点击换号")
|
||||
|
||||
if self._splash:
|
||||
self._splash.finish(self)
|
||||
|
||||
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user