Skip to content

Commit 21f01e9

Browse files
committed
chore: 添加CI脚本
1 parent cc78db9 commit 21f01e9

File tree

3 files changed

+344
-8
lines changed

3 files changed

+344
-8
lines changed

.github/workflows/release.yml

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
name: Release KiCAD Library
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*'
7+
8+
jobs:
9+
release:
10+
runs-on: ubuntu-latest
11+
permissions:
12+
contents: write
13+
14+
steps:
15+
- name: Checkout repository
16+
uses: actions/checkout@v4
17+
with:
18+
fetch-depth: 0 # 获取完整的git历史,包括所有tags
19+
20+
- name: Set up Python
21+
uses: actions/setup-python@v4
22+
with:
23+
python-version: '3.11'
24+
25+
- name: Install dependencies
26+
run: |
27+
python -m pip install --upgrade pip
28+
pip install requests
29+
30+
- name: Get current tag
31+
id: get_tag
32+
run: echo "tag=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
33+
34+
- name: Build library package
35+
id: build
36+
run: |
37+
python scripts/build_release.py
38+
echo "package_path=$(cat package_path.txt)" >> $GITHUB_OUTPUT
39+
echo "metadata_path=$(cat metadata_path.txt)" >> $GITHUB_OUTPUT
40+
echo "package_size=$(cat package_size.txt)" >> $GITHUB_OUTPUT
41+
echo "install_size=$(cat install_size.txt)" >> $GITHUB_OUTPUT
42+
echo "package_sha256=$(cat package_sha256.txt)" >> $GITHUB_OUTPUT
43+
44+
- name: Create Release
45+
uses: ncipollo/release-action@v1
46+
with:
47+
artifacts: |
48+
${{ steps.build.outputs.package_path }}
49+
${{ steps.build.outputs.metadata_path }}
50+
tag: ${{ steps.get_tag.outputs.tag }}
51+
name: Release ${{ steps.get_tag.outputs.tag }}
52+
body: |
53+
## SiFli KiCAD Library ${{ steps.get_tag.outputs.tag }}
54+
55+
### Package Information
56+
- **Package Size**: ${{ steps.build.outputs.package_size }} bytes
57+
- **Install Size**: ${{ steps.build.outputs.install_size }} bytes
58+
- **SHA256**: `${{ steps.build.outputs.package_sha256 }}`
59+
60+
### Installation
61+
1. Download the `kicad-libraries-${{ steps.get_tag.outputs.tag }}.zip` file
62+
2. Extract to your KiCAD libraries directory
63+
3. Or install via KiCAD Package and Content Manager using the `metadata.json`
64+
65+
### What's Included
66+
- SiFli MCU symbols
67+
- SiFli module footprints
68+
- Resources and documentation
69+
70+
For more information, visit the [SiFli Hardware Design Guidelines](https://wiki.sifli.com/hardware/index.html).
71+
draft: false
72+
prerelease: false
73+
token: ${{ secrets.GITHUB_TOKEN }}

metadata.json

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,5 @@
2020
"license": "CC-BY-SA-4.0",
2121
"resources": {
2222
"homepage": "https://github.com/OpenSiFli/kicad-libraries"
23-
},
24-
"versions": [
25-
{
26-
"version": "1.0.0",
27-
"status": "stable",
28-
"kicad_version": "9.0.0"
29-
}
30-
]
23+
}
3124
}

scripts/build_release.py

Lines changed: 270 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,270 @@
1+
#!/usr/bin/env python3
2+
"""
3+
SiFli KiCAD Library Release Builder
4+
5+
This script builds a release package for the SiFli KiCAD library according to
6+
KiCAD addon specifications and prepares metadata for upstream submission.
7+
"""
8+
9+
import os
10+
import sys
11+
import json
12+
import zipfile
13+
import hashlib
14+
import subprocess
15+
import shutil
16+
from pathlib import Path
17+
from typing import List, Dict, Any
18+
19+
20+
def get_all_tags() -> List[str]:
21+
"""获取仓库中的所有标签,按版本号排序"""
22+
try:
23+
result = subprocess.run(
24+
['git', 'tag', '--sort=-version:refname'],
25+
capture_output=True,
26+
text=True,
27+
check=True
28+
)
29+
tags = [tag.strip() for tag in result.stdout.strip().split('\n') if tag.strip()]
30+
return tags
31+
except subprocess.CalledProcessError as e:
32+
print(f"Error getting tags: {e}")
33+
return []
34+
35+
36+
def get_current_tag() -> str:
37+
"""获取当前的标签"""
38+
current_tag = os.environ.get('GITHUB_REF_NAME', '')
39+
if not current_tag:
40+
try:
41+
result = subprocess.run(
42+
['git', 'describe', '--tags', '--exact-match', 'HEAD'],
43+
capture_output=True,
44+
text=True,
45+
check=True
46+
)
47+
current_tag = result.stdout.strip()
48+
except subprocess.CalledProcessError:
49+
print("Error: Not on a tagged commit")
50+
sys.exit(1)
51+
return current_tag
52+
53+
54+
def get_repo_info() -> Dict[str, str]:
55+
"""获取仓库信息"""
56+
repo_url = os.environ.get('GITHUB_SERVER_URL', 'https://github.com')
57+
repo_name = os.environ.get('GITHUB_REPOSITORY', 'OpenSiFli/kicad-libraries')
58+
return {
59+
'url': repo_url,
60+
'name': repo_name,
61+
'download_base': f"{repo_url}/{repo_name}/releases/download"
62+
}
63+
64+
65+
def calculate_file_hash(file_path: Path) -> str:
66+
"""计算文件的SHA256哈希值"""
67+
sha256_hash = hashlib.sha256()
68+
with open(file_path, "rb") as f:
69+
for chunk in iter(lambda: f.read(4096), b""):
70+
sha256_hash.update(chunk)
71+
return sha256_hash.hexdigest()
72+
73+
74+
def calculate_directory_size(directory: Path) -> int:
75+
"""计算目录的总大小"""
76+
total_size = 0
77+
for dirpath, dirnames, filenames in os.walk(directory):
78+
for filename in filenames:
79+
file_path = Path(dirpath) / filename
80+
total_size += file_path.stat().st_size
81+
return total_size
82+
83+
84+
def create_package_metadata(all_tags: List[str], current_tag: str) -> Dict[str, Any]:
85+
"""创建打包用的metadata.json"""
86+
with open('metadata.json', 'r', encoding='utf-8') as f:
87+
metadata = json.load(f)
88+
89+
# 添加versions字段
90+
versions = []
91+
for tag in all_tags:
92+
version_info = {
93+
"version": tag,
94+
"status": "stable" if tag == current_tag else "stable",
95+
"kicad_version": "6.0"
96+
}
97+
versions.append(version_info)
98+
99+
metadata["versions"] = versions
100+
return metadata
101+
102+
103+
def create_upstream_metadata(all_tags: List[str], current_tag: str,
104+
package_info: Dict[str, Any]) -> Dict[str, Any]:
105+
"""创建提交到KiCAD上游的metadata.json"""
106+
with open('metadata.json', 'r', encoding='utf-8') as f:
107+
metadata = json.load(f)
108+
109+
repo_info = get_repo_info()
110+
111+
# 添加带下载信息的versions字段
112+
versions = []
113+
for tag in all_tags:
114+
version_info = {
115+
"version": tag,
116+
"status": "stable",
117+
"kicad_version": "6.0"
118+
}
119+
120+
# 为当前tag添加下载信息
121+
if tag == current_tag:
122+
package_filename = f"kicad-libraries-{tag}.zip"
123+
download_url = f"{repo_info['download_base']}/{tag}/{package_filename}"
124+
125+
version_info.update({
126+
"download_url": download_url,
127+
"download_sha256": package_info['sha256'],
128+
"download_size": package_info['size'],
129+
"install_size": package_info['install_size']
130+
})
131+
132+
versions.append(version_info)
133+
134+
metadata["versions"] = versions
135+
return metadata
136+
137+
138+
def create_library_package(current_tag: str) -> Dict[str, Any]:
139+
"""创建KiCAD库包"""
140+
# 定义需要包含的目录和文件
141+
include_items = [
142+
'metadata.json',
143+
'symbols',
144+
'footprints',
145+
'resources'
146+
]
147+
148+
# 检查3dmodels目录是否存在
149+
if Path('3dmodels').exists():
150+
include_items.append('3dmodels')
151+
152+
# 创建临时目录
153+
temp_dir = Path('temp_package')
154+
if temp_dir.exists():
155+
shutil.rmtree(temp_dir)
156+
temp_dir.mkdir()
157+
158+
try:
159+
# 获取所有tags并创建打包用的metadata
160+
all_tags = get_all_tags()
161+
package_metadata = create_package_metadata(all_tags, current_tag)
162+
163+
# 写入修改后的metadata.json到临时目录
164+
with open(temp_dir / 'metadata.json', 'w', encoding='utf-8') as f:
165+
json.dump(package_metadata, f, indent=2, ensure_ascii=False)
166+
167+
# 复制其他文件和目录
168+
for item in include_items:
169+
if item == 'metadata.json':
170+
continue # 已经处理过了
171+
172+
item_path = Path(item)
173+
if item_path.exists():
174+
if item_path.is_dir():
175+
shutil.copytree(item_path, temp_dir / item)
176+
else:
177+
shutil.copy2(item_path, temp_dir / item)
178+
179+
# 计算安装大小
180+
install_size = calculate_directory_size(temp_dir)
181+
182+
# 创建zip包
183+
package_filename = f"kicad-libraries-{current_tag}.zip"
184+
package_path = Path(package_filename)
185+
186+
with zipfile.ZipFile(package_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
187+
for root, dirs, files in os.walk(temp_dir):
188+
for file in files:
189+
file_path = Path(root) / file
190+
# 计算相对于temp_dir的路径
191+
arcname = file_path.relative_to(temp_dir)
192+
zipf.write(file_path, arcname)
193+
194+
# 计算包信息
195+
package_size = package_path.stat().st_size
196+
package_sha256 = calculate_file_hash(package_path)
197+
198+
# 创建上游metadata
199+
upstream_metadata = create_upstream_metadata(all_tags, current_tag, {
200+
'size': package_size,
201+
'sha256': package_sha256,
202+
'install_size': install_size
203+
})
204+
205+
# 保存上游metadata
206+
upstream_metadata_path = Path('metadata-upstream.json')
207+
with open(upstream_metadata_path, 'w', encoding='utf-8') as f:
208+
json.dump(upstream_metadata, f, indent=2, ensure_ascii=False)
209+
210+
# 输出信息供GitHub Actions使用
211+
with open('package_path.txt', 'w') as f:
212+
f.write(str(package_path.absolute()))
213+
214+
with open('metadata_path.txt', 'w') as f:
215+
f.write(str(upstream_metadata_path.absolute()))
216+
217+
with open('package_size.txt', 'w') as f:
218+
f.write(str(package_size))
219+
220+
with open('install_size.txt', 'w') as f:
221+
f.write(str(install_size))
222+
223+
with open('package_sha256.txt', 'w') as f:
224+
f.write(package_sha256)
225+
226+
print(f"✅ Package created: {package_filename}")
227+
print(f"📦 Package size: {package_size:,} bytes")
228+
print(f"💾 Install size: {install_size:,} bytes")
229+
print(f"🔒 SHA256: {package_sha256}")
230+
print(f"📋 Upstream metadata: {upstream_metadata_path}")
231+
232+
return {
233+
'package_path': package_path,
234+
'metadata_path': upstream_metadata_path,
235+
'size': package_size,
236+
'install_size': install_size,
237+
'sha256': package_sha256
238+
}
239+
240+
finally:
241+
# 清理临时目录
242+
if temp_dir.exists():
243+
shutil.rmtree(temp_dir)
244+
245+
246+
def main():
247+
"""主函数"""
248+
print("🚀 Starting SiFli KiCAD Library release build...")
249+
250+
# 检查必要文件
251+
if not Path('metadata.json').exists():
252+
print("❌ Error: metadata.json not found")
253+
sys.exit(1)
254+
255+
# 获取当前标签
256+
current_tag = get_current_tag()
257+
print(f"📌 Current tag: {current_tag}")
258+
259+
# 创建包
260+
try:
261+
package_info = create_library_package(current_tag)
262+
print(f"✅ Release build completed successfully!")
263+
264+
except Exception as e:
265+
print(f"❌ Error during build: {e}")
266+
sys.exit(1)
267+
268+
269+
if __name__ == "__main__":
270+
main()

0 commit comments

Comments
 (0)