iOS 应用自动上传蒲公英教程
本文将介绍如何使用 Python 脚本,自动将打包生成的 .ipa 文件上传至 蒲公英 (Pgyer) 平台,方便团队分发和测试。
📌 前置准备
- 安装 Python 3
-
macOS 自带 Python,推荐使用 Python 官网 安装最新版本。
-
安装依赖库
bash pip install requests -
注册蒲公英账号
- 登录 蒲公英官网
- 在 用户中心 获取:
USER_KEYAPI_KEY
📂 项目结构
假设脚本文件为 pgyer_upload.py,目录结构如下:
project/
├── ipa/ # 存放打包好的 ipa 文件
├── pgyer_upload.py # 上传脚本
💻 核心功能说明
1. 自动查找最新 IPA 文件
会自动在 ipa/ 文件夹中找到最新打包的 .ipa 文件。
2. 获取上传凭证 (Token)
调用蒲公英 API 获取上传凭证。
3. 执行上传
使用上传凭证将 .ipa 文件上传到蒲公英服务器。
4. 验证上传结果
检查上传是否成功,确保文件在蒲公英平台可用。
🚀 使用方法
- 修改脚本中的配置信息:
PGY_DOWNLOAD_URL = 'https://www.pgyer.com/xxxxxx'
USER_KEY = '你的UserKey'
API_KEY = '你的ApiKey'
- 执行脚本:
python pgyer_upload.py
- 输出示例:
找到 IPA 文件: /Users/xxx/project/ipa/app-20250925.ipa
=========== 获取蒲公英上传 Token ===========
返回的 Token 数据: {...}
=========== 上传 IPA 文件 ===========
✅ 上传成功
=========== 校验上传信息 ===========
✅ 校验成功
📜 完整脚本代码
import os
import requests
import webbrowser
import time
# 蒲公英配置(UAT)
PGY_DOWNLOAD_URL = 'https://www.pgyer.com/xxxxxx'
USER_KEY = ''
API_KEY = ''
# 路径设置
BASE_DIR = os.path.abspath(os.path.dirname(__file__)) # 当前目录
EXPORT_DIR = BASE_DIR
EXPORT_FOLDER = 'ipa'
class PgyerUploader:
def __init__(self):
self.ipa_path = None
def upload(self):
# 自动找到最新的 IPA 文件并上传到蒲公英
ipa_path = self.find_latest_ipa(EXPORT_DIR, EXPORT_FOLDER)
if not ipa_path:
print("❌ 没有找到 IPA 文件")
return
print(f"找到 IPA 文件: {ipa_path}")
# 获取上传凭证
token = self.get_token()
if not token:
return
# 上传文件
self.perform_upload(ipa_path, token)
def find_latest_ipa(self, base_dir, folder_name):
ipa_folder = os.path.join(base_dir, folder_name)
if not os.path.exists(ipa_folder):
print(f"❌ 没有找到 {ipa_folder} 目录")
return None
ipa_files = [f for f in os.listdir(ipa_folder) if f.endswith('.ipa')]
if not ipa_files:
print("❌ 该目录下没有找到 IPA 文件")
return None
latest_ipa = max(ipa_files, key=lambda f: os.path.getmtime(os.path.join(ipa_folder, f)))
return os.path.join(ipa_folder, latest_ipa)
def get_token(self):
print("\n=========== 获取蒲公英上传 Token ===========")
url = 'https://www.pgyer.com/apiv2/app/getCOSToken'
data = {
'uKey': USER_KEY,
'_api_key': API_KEY,
'buildType': 'ios',
}
r = requests.post(url, data=data)
if r.status_code == 200:
res_data = r.json().get("data")
print("返回的 Token 数据:", res_data)
return res_data
else:
print("获取 Token 失败,状态码:", r.status_code)
return None
def perform_upload(self, ipa_path, token):
print("\n=========== 上传 IPA 文件 ===========")
url = token["endpoint"]
data = token["params"]
with open(ipa_path, 'rb') as f:
files = {'file': f}
r = requests.post(url, data=data, files=files)
if r.status_code == 204:
print("✅ 上传成功")
self.build_info(token["key"])
else:
print("❌ 上传失败,状态码:", r.status_code)
def build_info(self, key):
time.sleep(5)
print("\n=========== 校验上传信息 ===========")
url = 'https://www.pgyer.com/apiv2/app/buildInfo'
data = {
'buildKey': key,
'_api_key': API_KEY,
}
r = requests.get(url, params=data)
if r.status_code == 200:
res_json = r.json()
if res_json.get("code") == 0:
print("✅ 校验成功")
else:
print("❓ 验证中:", res_json.get("message"))
else:
print("❌ 校验失败,状态码:", r.status_code)
if __name__ == '__main__':
uploader = PgyerUploader()
uploader.upload()