Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
296 changes: 138 additions & 158 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,174 +1,154 @@
name: Build and Release
name: Test, Build and Release

on:
push:
branches:
- main
tags:
- 'v*'
pull_request:
workflow_dispatch:
inputs:
version:
description: 'Version tag (e.g., v1.0.0)'
description: 'Release tag, for example v1.0.1'
required: true
default: 'v1.0.0'
type: string

permissions:
contents: read

jobs:
build-windows:
test:
name: Windows unit tests
runs-on: windows-latest

timeout-minutes: 15

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install pyinstaller

- name: Build Windows executable
run: |
pyinstaller --onefile --name "AutoClickerPro" --icon=NONE --add-data "config;config" --add-data "core;core" --add-data "ui;ui" --add-data "utils;utils" main.py
shell: pwsh

- name: Create Windows release package
run: |
New-Item -ItemType Directory -Force -Path release
Copy-Item dist\AutoClickerPro.exe release\
Copy-Item README.md release\
Copy-Item LICENSE release\ 2>$null || echo "No LICENSE file"
Compress-Archive -Path release\* -DestinationPath AutoClickerPro_Windows.zip -Force
shell: pwsh

- name: Upload Windows artifact
uses: actions/upload-artifact@v4
with:
name: windows-build
path: AutoClickerPro_Windows.zip

build-linux:
runs-on: ubuntu-latest

- name: Checkout
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
cache: pip
cache-dependency-path: requirements.txt

- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install -r requirements.txt

- name: Run unit tests
run: python -m unittest discover tests -v

build-windows:
name: Build Windows executable
needs: test
runs-on: windows-latest
timeout-minutes: 20

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install pyinstaller

- name: Build Linux executable
run: |
pyinstaller --onefile --name "AutoClickerPro" --icon=NONE --add-data "config:config" --add-data "core:core" --add-data "ui:ui" --add-data "utils:utils" main.py

- name: Create Linux release package
run: |
mkdir -p release
cp dist/AutoClickerPro release/
cp README.md release/
cp LICENSE release/ 2>/dev/null || echo "No LICENSE file"
cd release && tar -czvf ../AutoClickerPro_Linux.tar.gz *

- name: Upload Linux artifact
uses: actions/upload-artifact@v4
with:
name: linux-build
path: AutoClickerPro_Linux.tar.gz

create-release:
needs: [build-windows, build-linux]
- name: Checkout
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
cache: pip
cache-dependency-path: requirements.txt

- name: Install build dependencies
run: |
python -m pip install --upgrade pip
python -m pip install -r requirements.txt
python -m pip install pyinstaller

- name: Build through the canonical packaging script
run: python pack.py --ci

- name: Validate executable
shell: pwsh
run: |
if (-not (Test-Path 'dist\AutoClickerPro.exe')) {
throw 'dist\AutoClickerPro.exe was not created'
}
$size = (Get-Item 'dist\AutoClickerPro.exe').Length
if ($size -le 0) {
throw 'AutoClickerPro.exe is empty'
}
Write-Host "Executable size: $size bytes"

- name: Create release package
shell: pwsh
run: |
New-Item -ItemType Directory -Force -Path release | Out-Null
Copy-Item 'dist\AutoClickerPro.exe' 'release\AutoClickerPro.exe'
Copy-Item 'README.md' 'release\README.md'
if (Test-Path 'LICENSE') {
Copy-Item 'LICENSE' 'release\LICENSE'
}
Compress-Archive -Path 'release\*' -DestinationPath 'AutoClickerPro_Windows.zip' -Force
if ((Get-Item 'AutoClickerPro_Windows.zip').Length -le 0) {
throw 'Release ZIP is empty'
}

- name: Upload Windows artifact
uses: actions/upload-artifact@v4
with:
name: windows-build
path: AutoClickerPro_Windows.zip
if-no-files-found: error
retention-days: 14

release:
name: Publish GitHub Release
needs: build-windows
if: startsWith(github.ref, 'refs/tags/v') || github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch'

permissions:
contents: write

steps:
- name: Download Windows artifact
uses: actions/download-artifact@v4
with:
name: windows-build
path: ./artifacts

- name: Download Linux artifact
uses: actions/download-artifact@v4
with:
name: linux-build
path: ./artifacts

- name: Get version from tag or input
id: get_version
run: |
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
VERSION="${{ github.event.inputs.version }}"
else
VERSION="${{ github.ref_name }}"
fi
echo "version=$VERSION" >> $GITHUB_OUTPUT

- name: Generate changelog
id: changelog
run: |
cat > changelog.md << 'EOF'
## 🎉 自动点击器专业版 ${{ steps.get_version.outputs.version }}

### ✨ 新特性
- 🔐 **加密存储**: 宏录制文件采用 Fernet 对称加密,安全保护您的操作序列
- 🧩 **模块化架构**: UI 与业务逻辑完全解耦,代码更易维护
- ⚡ **高性能**: 优化的线程管理,低延迟响应
- 🛡️ **安全防护**: 完整的输入验证和防滥用机制
- 🎨 **现代化界面**: 简洁直观的用户体验

### 🔧 技术改进
- 分离配置文件 (constants/encryption/validation)
- 新增宏管理模块 (macros.py)
- 快捷键管理器 (hotkey_manager.py)
- 完整的单元测试覆盖 (36+ 测试用例)
- CI/CD 自动化构建

### 📦 安装说明
#### Windows
1. 下载 `AutoClickerPro_Windows.zip`
2. 解压到任意目录
3. 双击运行 `AutoClickerPro.exe`

#### Linux
1. 下载 `AutoClickerPro_Linux.tar.gz`
2. 解压:`tar -xzvf AutoClickerPro_Linux.tar.gz`
3. 运行:`./AutoClickerPro`

### ⌨️ 快捷键
- `F8`: 开始/停止连点
- `F9`: 开始/停止录制
- `F10`: 播放宏
- `ESC`: 停止当前操作

### 📝 更新日志
- 首次正式发布
- 支持鼠标连点和键盘宏录制
- 加密存储保护隐私
- 跨平台支持 (Windows/Linux)
EOF
cat changelog.md

- name: Create Release
uses: softprops/action-gh-release@v1
with:
name: 自动点击器专业版 ${{ steps.get_version.outputs.version }}
body_path: changelog.md
files: |
./artifacts/AutoClickerPro_Windows.zip
./artifacts/AutoClickerPro_Linux.tar.gz
draft: false
prerelease: false
generate_release_notes: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Download tested Windows artifact
uses: actions/download-artifact@v4
with:
name: windows-build
path: artifacts

- name: Resolve and validate version
id: version
shell: bash
env:
DISPATCH_VERSION: ${{ inputs.version }}
run: |
if [[ "${GITHUB_EVENT_NAME}" == "workflow_dispatch" ]]; then
VERSION="${DISPATCH_VERSION}"
else
VERSION="${GITHUB_REF_NAME}"
fi

if [[ ! "${VERSION}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+([.-][0-9A-Za-z.-]+)?$ ]]; then
echo "Invalid version: ${VERSION}. Expected a tag such as v1.0.1." >&2
exit 1
fi

test -s artifacts/AutoClickerPro_Windows.zip
echo "version=${VERSION}" >> "${GITHUB_OUTPUT}"

- name: Create release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ steps.version.outputs.version }}
target_commitish: ${{ github.sha }}
name: AutoClicker Pro ${{ steps.version.outputs.version }}
body: |
Automated Windows release built from the canonical `pack.py` entrypoint.

The unit-test job completed successfully before packaging. Download `AutoClickerPro_Windows.zip`, extract it, and run `AutoClickerPro.exe`.
files: artifacts/AutoClickerPro_Windows.zip
fail_on_unmatched_files: true
generate_release_notes: true
draft: false
prerelease: false
Loading
Loading