app_store_dev_api 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,234 @@
1
+ # Pindo 项目中 app_store_dev_api 使用参考
2
+
3
+ > 本文档记录 [pindo](../../pindo) CLI 工具如何使用 `app_store_dev_api` gem 进行 App Store Connect API 认证和调用,作为集成参考。
4
+
5
+ ## Gem 依赖
6
+
7
+ ```ruby
8
+ # pindo.gemspec
9
+ spec.add_runtime_dependency "app_store_dev_api", '~> 0.3.0'
10
+ ```
11
+
12
+ ## 认证流程
13
+
14
+ Pindo 采用 **本地 JSON 文件 + 交互式输入** 的方式管理 API 密钥凭证。
15
+
16
+ ### 流程图
17
+
18
+ ```
19
+ 启动命令 (pindo appstore iap)
20
+
21
+ 从项目 config.json 读取 apple_id、bundle_id
22
+
23
+ 检查 {pindo_dir}/api_key.json 是否存在该 apple_id 的凭证
24
+
25
+ ┌─── 存在 ───┐ ┌─── 不存在 ───┐
26
+ │ │ │ │
27
+ │ 直接加载 │ │ 交互式输入 │
28
+ │ issuer_id │ │ issuer_id │
29
+ │ key_id │ │ key_id │
30
+ │ private_key│ │ .p8 文件路径 │
31
+ │ │ │ │
32
+ └─────┬──────┘ │ 读取 .p8 文件 │
33
+ │ │ 用户确认 │
34
+ │ │ 保存到 JSON │
35
+ │ └──────┬────────┘
36
+ │ │
37
+ └────────┬───────────────┘
38
+
39
+ AppStoreDevApi::Client.new(
40
+ issuer_id: issuer_id,
41
+ key_id: key_id,
42
+ private_key: private_key
43
+ )
44
+
45
+ 开始调用 API
46
+ ```
47
+
48
+ ### 核心代码
49
+
50
+ **文件:** `pindo/lib/pindo/command/appstore/iap.rb`
51
+
52
+ ```ruby
53
+ def login_api_key(apple_id: nil)
54
+ load_apikey_config = false
55
+ api_key_json = nil
56
+ pindo_dir = File.expand_path(pindo_single_config.pindo_dir)
57
+ api_key_file = File.join(pindo_dir, "api_key.json")
58
+
59
+ # 步骤1:尝试从本地配置文件加载
60
+ if File.exist?(api_key_file)
61
+ api_key_json = JSON.parse(File.read(api_key_file))
62
+ if !api_key_json.nil? && !api_key_json[apple_id].nil? && !api_key_json[apple_id]["issuer_id"].nil?
63
+ issuer_id = api_key_json[apple_id]["issuer_id"]
64
+ key_id = api_key_json[apple_id]["key_id"]
65
+ private_key = api_key_json[apple_id]["private_key"]
66
+ load_apikey_config = true
67
+ end
68
+ end
69
+
70
+ # 步骤2:如果未加载,交互式输入凭证
71
+ if !load_apikey_config
72
+ issuer_id = ask('请输入 issuer_id: ')
73
+ key_id = ask('请输入 key_id: ')
74
+ private_key_file = ask('请输入private key的文件路径: ')
75
+ private_key = File.read(File.new(private_key_file))
76
+
77
+ # 构建配置
78
+ api_key_json = api_key_json || {}
79
+ api_key_json[apple_id] = api_key_json[apple_id] || {}
80
+ api_key_json[apple_id]["issuer_id"] = issuer_id
81
+ api_key_json[apple_id]["key_id"] = key_id
82
+ api_key_json[apple_id]["private_key"] = private_key
83
+
84
+ # 步骤3:用户确认
85
+ answer = agree("请确认上面信息是否正确(Y/n):")
86
+ unless answer
87
+ raise Informative, "重新输入 !!!"
88
+ end
89
+
90
+ # 步骤4:持久化到本地文件
91
+ File.open(api_key_file, "w") do |f|
92
+ f.write(JSON.pretty_generate(api_key_json))
93
+ end
94
+ load_apikey_config = true
95
+ end
96
+
97
+ # 步骤5:初始化 API 客户端
98
+ if load_apikey_config
99
+ @app_store_connect = AppStoreDevApi::Client.new(
100
+ issuer_id: issuer_id,
101
+ key_id: key_id,
102
+ private_key: private_key
103
+ )
104
+ end
105
+ end
106
+ ```
107
+
108
+ ## 凭证存储格式
109
+
110
+ ### 存储路径
111
+
112
+ ```
113
+ {pindo_dir}/api_key.json
114
+ ```
115
+
116
+ `pindo_dir` 由 `pindo_single_config.pindo_dir` 确定,通常位于用户本地配置目录。
117
+
118
+ ### JSON 结构(支持多账户)
119
+
120
+ ```json
121
+ {
122
+ "user1@example.com": {
123
+ "issuer_id": "57246542-96fe-1a63-e053-0824d011072a",
124
+ "key_id": "2X9R4HXF34",
125
+ "private_key": "-----BEGIN PRIVATE KEY-----\nMIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQg...\n-----END PRIVATE KEY-----"
126
+ },
127
+ "user2@example.com": {
128
+ "issuer_id": "69384721-abcd-efgh-ijkl-123456789012",
129
+ "key_id": "ABC123DEF4",
130
+ "private_key": "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----"
131
+ }
132
+ }
133
+ ```
134
+
135
+ **关键设计:**
136
+ - 以 Apple ID(邮箱)作为一级 key,支持多账户切换
137
+ - `private_key` 直接存储 PEM 格式的私钥内容(非文件路径)
138
+ - 首次输入时从 `.p8` 文件读取,之后直接使用存储的内容
139
+
140
+ ## API 调用示例
141
+
142
+ ### 初始化入口
143
+
144
+ ```ruby
145
+ def run
146
+ # 从项目 config.json 加载 apple_id 和 bundle_id
147
+ config_file = File.join(project_dir, "config.json")
148
+ config_parser = Pindo::IosConfigParser.instance
149
+ config_parser.load_config(config_file: config_file)
150
+ @bundle_id = config_parser.bundle_id
151
+ @apple_id = config_parser.apple_id
152
+
153
+ # 登录并初始化客户端
154
+ login_api_key(apple_id: @apple_id)
155
+
156
+ # 开始使用 API...
157
+ end
158
+ ```
159
+
160
+ ### 查询应用
161
+
162
+ ```ruby
163
+ app_list_response = @app_store_connect.list_apps(
164
+ filter: { bundle_id: @bundle_id }
165
+ )
166
+ ```
167
+
168
+ ### 获取内购项目
169
+
170
+ ```ruby
171
+ # 消耗型内购
172
+ get_consumable_iap_items(
173
+ appstore_client: @app_store_connect,
174
+ app_id: app_id,
175
+ in_app_purchase_type: "CONSUMABLE"
176
+ )
177
+
178
+ # 订阅组
179
+ get_subscriptions_groups(
180
+ appstore_client: @app_store_connect,
181
+ app_id: app_id
182
+ )
183
+ ```
184
+
185
+ ### 沙盒测试账户
186
+
187
+ ```ruby
188
+ @app_store_connect.list_sandbox_testers()
189
+ ```
190
+
191
+ ## 其他集成点
192
+
193
+ Pindo 中还有以下任务类支持 API Key 认证参数(通过 options 传递):
194
+
195
+ ### 截图上传任务
196
+
197
+ **文件:** `pindo/lib/pindo/module/task/model/appstore/appstore_upload_screenshot_task.rb`
198
+
199
+ ```ruby
200
+ def initialize(app_id, screenshot_path, options = {})
201
+ @api_key_id = options[:api_key_id] # API Key ID
202
+ @api_issuer_id = options[:api_issuer_id] # Issuer ID
203
+ @api_key_path = options[:api_key_path] # .p8 文件路径
204
+ end
205
+ ```
206
+
207
+ ### 元数据上传任务
208
+
209
+ **文件:** `pindo/lib/pindo/module/task/model/appstore/appstore_upload_metadata_task.rb`
210
+
211
+ ```ruby
212
+ @api_key_id = options[:api_key_id]
213
+ @api_issuer_id = options[:api_issuer_id]
214
+ @api_key_path = options[:api_key_path]
215
+ ```
216
+
217
+ > 注意:这些任务类使用的是 **文件路径** (`api_key_path`) 而非私钥内容,与 IAP 命令的处理方式略有不同。
218
+
219
+ ## 设计要点总结
220
+
221
+ | 特性 | 说明 |
222
+ |------|------|
223
+ | 多账户支持 | 以 Apple ID 为 key 管理多套凭证 |
224
+ | 本地持久化 | JSON 文件存储,首次输入后免重复 |
225
+ | 交互式输入 | 首次使用通过命令行交互式收集凭证 |
226
+ | 私钥存储方式 | 存储 PEM 内容而非文件路径 |
227
+ | Client 初始化 | 三个参数: `issuer_id`, `key_id`, `private_key` |
228
+ | Token 管理 | 由 `app_store_dev_api` gem 内部自动处理 JWT 生成 |
229
+
230
+ ## 相关文档
231
+
232
+ - [创建 API 密钥](creating_api_keys.md)
233
+ - [生成 API 请求 Token](generating_tokens.md)
234
+ - [撤销 API 密钥](revoking_api_keys.md)
@@ -0,0 +1,118 @@
1
+ # 撤销 API 密钥
2
+
3
+ > 官方文档: https://developer.apple.com/documentation/appstoreconnectapi/revoking-api-keys
4
+
5
+ ## 概述
6
+
7
+ 当 API 密钥不再需要、可能泄露、或需要轮换时,应及时撤销。撤销后的密钥将永久失效,使用该密钥生成的所有 JWT Token 也将立即失效。
8
+
9
+ ## 撤销步骤
10
+
11
+ ### 撤销团队密钥
12
+
13
+ 1. 登录 [App Store Connect](https://appstoreconnect.apple.com/)
14
+ 2. 导航到 **用户和访问 (Users and Access)**
15
+ 3. 选择 **集成 (Integrations)** 选项卡
16
+ 4. 在左侧导航中选择 **App Store Connect API**
17
+ 5. 选择 **团队密钥 (Team Keys)** 标签页
18
+ 6. 找到要撤销的密钥
19
+ 7. 点击密钥名称旁的 **撤销 (Revoke)** 按钮
20
+ 8. 在确认对话框中确认撤销
21
+
22
+ ### 撤销个人密钥
23
+
24
+ 1. 登录 [App Store Connect](https://appstoreconnect.apple.com/)
25
+ 2. 导航到 **用户和访问 (Users and Access)**
26
+ 3. 选择 **集成 (Integrations)** 选项卡
27
+ 4. 选择 **个人密钥 (Individual Keys)** 标签页
28
+ 5. 找到要撤销的密钥并点击 **撤销 (Revoke)**
29
+
30
+ ## 撤销后的影响
31
+
32
+ ### 立即生效
33
+
34
+ - 密钥状态变为 **已撤销 (Revoked)**
35
+ - 使用该密钥签名的所有 JWT Token 立即失效
36
+ - 所有使用该 Token 的 API 请求将返回 `401 NOT_AUTHORIZED`
37
+
38
+ ### 不可逆操作
39
+
40
+ > ⚠️ **警告**: 密钥撤销是**永久性**操作,无法恢复。一旦撤销,该密钥将无法重新激活。
41
+
42
+ - 已撤销的密钥仍会显示在密钥列表中(标记为已撤销),但无法使用
43
+ - 私钥文件(`.p8`)即使仍存在也无法再用于生成有效 Token
44
+ - Key ID 不会被回收利用
45
+
46
+ ### 对正在运行的服务的影响
47
+
48
+ - 所有依赖该密钥的 CI/CD 流水线将立即中断
49
+ - 所有使用该密钥的自动化脚本将失败
50
+ - 所有后端服务的 API 调用将返回认证错误
51
+
52
+ ## 何时应该撤销密钥
53
+
54
+ | 场景 | 紧急程度 | 建议操作 |
55
+ |------|----------|----------|
56
+ | 私钥文件泄露(提交到公开仓库等) | 🔴 立即 | 立刻撤销,创建新密钥 |
57
+ | 团队成员离职 | 🟡 尽快 | 撤销其创建的密钥 |
58
+ | 密钥定期轮换 | 🟢 计划中 | 先创建新密钥,迁移后再撤销旧密钥 |
59
+ | 密钥权限过高 | 🟡 尽快 | 创建权限适当的新密钥后撤销 |
60
+ | 密钥不再使用 | 🟢 常规 | 确认无依赖后撤销 |
61
+
62
+ ## 安全的密钥轮换流程
63
+
64
+ 为避免服务中断,建议按以下步骤进行密钥轮换:
65
+
66
+ ```
67
+ 1. 创建新密钥
68
+
69
+ 2. 下载新私钥文件 (.p8)
70
+
71
+ 3. 更新所有服务/脚本使用新密钥
72
+
73
+ 4. 验证所有服务正常运行
74
+
75
+ 5. 撤销旧密钥
76
+
77
+ 6. 删除旧私钥文件
78
+ ```
79
+
80
+ ### 在本项目中轮换密钥
81
+
82
+ ```ruby
83
+ # 1. 使用新密钥创建客户端
84
+ new_client = AppStoreDevApi::Client.new(
85
+ issuer_id: ENV['APP_STORE_CONNECT_ISSUER_ID'], # Issuer ID 不变
86
+ key_id: 'NEW_KEY_ID',
87
+ private_key: File.read('/path/to/new_AuthKey.p8')
88
+ )
89
+
90
+ # 2. 验证新密钥可用
91
+ apps = new_client.list_apps
92
+ puts "新密钥验证成功,共 #{apps['data'].size} 个应用"
93
+
94
+ # 3. 确认后,在 App Store Connect 中撤销旧密钥
95
+ ```
96
+
97
+ ## 常见问题
98
+
99
+ ### 撤销密钥后可以恢复吗?
100
+
101
+ 不可以。密钥撤销是永久性操作。如果误操作,只能创建新密钥。
102
+
103
+ ### 撤销密钥会影响应用吗?
104
+
105
+ 不会。撤销 API 密钥只影响 API 访问能力,不会影响已发布的应用、用户数据或 App Store 上架状态。
106
+
107
+ ### 一个团队最多可以有多少个活跃密钥?
108
+
109
+ Apple 对每个团队的活跃 API 密钥数量有限制。建议只保留实际使用的密钥,及时撤销不再需要的密钥。
110
+
111
+ ### 撤销后 Issuer ID 会变吗?
112
+
113
+ 不会。Issuer ID 是团队级别的标识,不受单个密钥撤销的影响。
114
+
115
+ ## 相关文档
116
+
117
+ - [创建 API 密钥](creating_api_keys.md)
118
+ - [生成 API 请求 Token](generating_tokens.md)
data/install_local.sh CHANGED
@@ -1,84 +1,95 @@
1
1
  #!/bin/bash
2
- # 简化的本地安装脚本 - 适用于库 gem 项目
3
2
 
4
- set -e # 遇到错误立即退出
3
+ #当前脚本目录 (macOS兼容)
4
+ if [[ "$OSTYPE" == "darwin"* ]]; then
5
+ CURRENT_DIR=$(dirname $(greadlink -f $0 2>/dev/null || readlink $0 2>/dev/null || echo $0))
6
+ else
7
+ CURRENT_DIR=$(dirname $(readlink -f $0))
8
+ fi
9
+ CURRENT_DIR=$(cd "$CURRENT_DIR" && pwd)
10
+ echo $CURRENT_DIR
11
+
5
12
 
6
- # 获取当前目录
7
- CURRENT_DIR="$(cd "$(dirname "$0")" && pwd)"
8
- cd "$CURRENT_DIR"
13
+ # Make all files and directories in the current directory readable, writable, and executable for all users.
14
+ /bin/chmod -R a+rwx $CURRENT_DIR
15
+ # Change the owner of the current directory to the current user.
16
+ /usr/sbin/chown $(whoami) $CURRENT_DIR
17
+ # Change the group of the current directory to "admin".
18
+ /usr/bin/chgrp admin $CURRENT_DIR
9
19
 
10
- echo "=========================================="
11
- echo "本地构建和安装 Gem"
12
- echo "=========================================="
13
- echo
20
+ function readConfigValue()
21
+ {
22
+ File=$1
23
+ KEY=$2
24
+ VALUE=$(grep -m 1 -o "^[ ]*$KEY[ ]*=[ ]*[\"]*.*[\"]*" $File | sed -e "s/^[ ]*$KEY[ ]*=[ ]*[\"]*//" -e "s/[\"]*$//")
25
+ echo $VALUE
26
+ }
14
27
 
15
- # 1. 自动检测项目名称
16
- GEMSPEC_FILE=$(find . -maxdepth 1 -name "*.gemspec" | head -n 1)
28
+
29
+ # 自动检测当前项目名称
30
+ GEMSPEC_FILE=$(find $CURRENT_DIR -maxdepth 1 -name "*.gemspec" | head -n 1)
17
31
  if [ -z "$GEMSPEC_FILE" ]; then
18
- echo "错误: 未找到 .gemspec 文件"
32
+ echo "错误: 未找到gemspec文件!"
19
33
  exit 1
20
34
  fi
21
35
 
22
- PROJECT_NAME=$(basename "$GEMSPEC_FILE" .gemspec)
23
- echo "项目: $PROJECT_NAME"
36
+ # gemspec文件名获取项目名称
37
+ PROJECT_NAME=$(basename $GEMSPEC_FILE .gemspec)
38
+ echo "检测到项目: $PROJECT_NAME"
39
+
40
+ # 清理旧的gem文件
41
+ rm -rf $CURRENT_DIR/*${PROJECT_NAME}-*.gem
24
42
 
25
- # 2. 自动检测版本号
26
- VERSION_FILE=$(find ./lib -name "version.rb" | head -n 1)
43
+ # 自动检测版本文件
44
+ VERSION_FILE=$(find $CURRENT_DIR/lib -name "version.rb" | head -n 1)
27
45
  if [ -z "$VERSION_FILE" ]; then
28
- echo "错误: 未找到 version.rb 文件"
46
+ echo "错误: 未找到version.rb文件!"
29
47
  exit 1
30
48
  fi
31
49
 
32
- # 提取版本号
33
- VERSION=$(grep -o "VERSION.*=.*['\"][0-9.]*['\"]" "$VERSION_FILE" | sed -E "s/.*['\"]([0-9.]+)['\"].*/\1/")
34
-
35
- if [ -z "$VERSION" ]; then
36
- echo " 错误: 无法解析版本号"
37
- cat "$VERSION_FILE"
50
+ echo "检测到版本文件: $VERSION_FILE"
51
+ VERSION_KEY="VERSION"
52
+ # 改进版本号提取方式,确保只获取版本号部分
53
+ VERSION_TAG_NAME=$(grep -o "${VERSION_KEY}.*=.*['\"]\(.*\)['\"]" ${VERSION_FILE} | head -1 | sed -E "s/.*['\"]([0-9]+\.[0-9]+\.[0-9]+)['\"].*/\1/")
54
+ echo "检测到版本: $VERSION_TAG_NAME"
55
+
56
+ # 验证版本号格式
57
+ if [[ ! $VERSION_TAG_NAME =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
58
+ echo "错误: 无法正确解析版本号,获取到的值: '$VERSION_TAG_NAME'"
59
+ echo "直接查看版本文件内容:"
60
+ cat $VERSION_FILE
38
61
  exit 1
39
62
  fi
40
63
 
41
- echo "版本: $VERSION"
42
- echo
43
-
44
- # 3. 清理旧的 gem 文件
45
- echo "清理旧的 gem 文件..."
46
- rm -f *.gem
47
- echo "✓ 清理完成"
48
- echo
49
64
 
50
- # 4. 构建 gem
51
- echo "构建 gem..."
52
- gem build "$GEMSPEC_FILE"
65
+ # 构建和安装gem
66
+ echo "构建 $PROJECT_NAME gem..."
67
+ gem build $GEMSPEC_FILE
53
68
 
54
- GEM_FILE="${PROJECT_NAME}-${VERSION}.gem"
69
+ # 查找生成的gem文件(在当前目录和CURRENT_DIR中查找)
70
+ GEM_FILE=$(find . -maxdepth 1 -name "${PROJECT_NAME}-${VERSION_TAG_NAME}.gem" | head -n 1)
71
+ if [ -z "$GEM_FILE" ]; then
72
+ GEM_FILE=$(find $CURRENT_DIR -maxdepth 1 -name "${PROJECT_NAME}-${VERSION_TAG_NAME}.gem" | head -n 1)
73
+ fi
55
74
 
56
- if [ ! -f "$GEM_FILE" ]; then
57
- echo "❌ 错误: gem 构建失败,未找到 $GEM_FILE"
58
- exit 1
75
+ if [ -n "$GEM_FILE" ]; then
76
+ echo "找到gem文件: $GEM_FILE"
77
+ echo "安装 $PROJECT_NAME-${VERSION_TAG_NAME}.gem..."
78
+ gem install --local "$GEM_FILE"
79
+ else
80
+ echo "错误: 未找到生成的gem文件! 尝试查找任何版本的gem..."
81
+ ANY_GEM=$(find . -maxdepth 1 -name "${PROJECT_NAME}-*.gem" | head -n 1)
82
+ if [ -n "$ANY_GEM" ]; then
83
+ echo "找到gem文件: $ANY_GEM"
84
+ echo "安装 $ANY_GEM..."
85
+ gem install --local "$ANY_GEM"
86
+ else
87
+ echo "未找到任何${PROJECT_NAME}的gem文件"
88
+ fi
59
89
  fi
60
90
 
61
- echo "✓ 构建成功: $GEM_FILE"
62
- echo
63
-
64
- # 5. 安装到本地
65
- echo "安装到本地..."
66
- gem install "$GEM_FILE"
67
-
68
- echo
69
- echo "=========================================="
70
- echo "✅ 安装成功!"
71
- echo "=========================================="
72
- echo
73
- echo "使用方法 (Ruby 代码中):"
74
- echo " require 'app_store_dev_api'"
75
- echo " client = AppStoreDevApi::Client.new("
76
- echo " key_id: 'YOUR_KEY_ID',"
77
- echo " issuer_id: 'YOUR_ISSUER_ID',"
78
- echo " private_key: File.read('AuthKey.p8')"
79
- echo " )"
80
- echo
81
- echo "验证安装:"
82
- echo " gem list | grep $PROJECT_NAME"
83
- echo " ruby -r app_store_dev_api -e 'puts AppStoreDevApi::VERSION'"
84
- echo "=========================================="
91
+
92
+
93
+
94
+
95
+
data/lib/.DS_Store CHANGED
Binary file
@@ -89,7 +89,7 @@ module AppStoreDevApi
89
89
  private
90
90
 
91
91
  def schema_path
92
- File.join(Dir.pwd, 'lib/config/schema_v4.2.json')
92
+ File.join(Dir.pwd, 'lib/config/schema_v4.3.json')
93
93
  end
94
94
  end
95
95
  end
@@ -9,7 +9,7 @@ module AppStoreDevApi
9
9
 
10
10
  DEFAULTS = {
11
11
  analytics_enabled: true,
12
- schema: Schema.new(File.join(__dir__, '..', '..', 'config', 'schema_v4.2.json'))
12
+ schema: Schema.new(File.join(__dir__, '..', '..', 'config', 'schema_v4.3.json'))
13
13
  }.freeze
14
14
  private_constant :DEFAULTS
15
15
 
@@ -32,6 +32,6 @@ module AppStoreDevApi
32
32
  #
33
33
  class Client < Base
34
34
  # 所有方法通过 Base#method_missing 动态调度
35
- # 端点配置从 lib/config/schema_v4.2.json 加载
35
+ # 端点配置从 lib/config/schema_v4.3.json 加载
36
36
  end
37
37
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AppStoreDevApi
4
- VERSION = '0.3.0'
4
+ VERSION = '0.3.1'
5
5
  end
@@ -4602,16 +4602,6 @@
4602
4602
  "url": "https://api.appstoreconnect.apple.com/v1/appStoreVersionLocalizations/{id}/searchKeywords",
4603
4603
  "alias": "app_store_version_localization_search_keywords"
4604
4604
  },
4605
- {
4606
- "http_method": "get",
4607
- "url": "https://api.appstoreconnect.apple.com/v1/appStoreVersions/{id}/relationships/ageRatingDeclaration",
4608
- "alias": "app_store_version_relationships_age_rating_declaration"
4609
- },
4610
- {
4611
- "http_method": "get",
4612
- "url": "https://api.appstoreconnect.apple.com/v1/appStoreVersions/{id}/ageRatingDeclaration",
4613
- "alias": "app_store_version_age_rating_declaration"
4614
- },
4615
4605
  {
4616
4606
  "http_method": "get",
4617
4607
  "url": "https://api.appstoreconnect.apple.com/v1/appStoreVersions/{id}/relationships/alternativeDistributionPackage",
data/push_all.sh ADDED
@@ -0,0 +1,6 @@
1
+ #!/bin/bash
2
+ echo "Pushing to GitHub..."
3
+ git push origin master
4
+ echo "Pushing to Gitee..."
5
+ GIT_SSL_NO_VERIFY=true https_proxy="" http_proxy="" git push gitee master
6
+ echo "Done!"
data/release_remote.sh CHANGED
@@ -21,10 +21,29 @@ function readConfigValue()
21
21
  }
22
22
 
23
23
 
24
- rm -rf $CURRENT_DIR/*app_store_dev_api-*.gem
24
+ # 自动检测当前项目名称
25
+ GEMSPEC_FILE=$(find $CURRENT_DIR -maxdepth 1 -name "*.gemspec" | head -n 1)
26
+ if [ -z "$GEMSPEC_FILE" ]; then
27
+ echo "错误: 未找到gemspec文件!"
28
+ exit 1
29
+ fi
30
+
31
+ # 从gemspec文件名获取项目名称
32
+ PROJECT_NAME=$(basename $GEMSPEC_FILE .gemspec)
33
+ echo "检测到项目: $PROJECT_NAME"
34
+
35
+ # 清理旧的gem文件
36
+ rm -rf $CURRENT_DIR/*${PROJECT_NAME}-*.gem
37
+
38
+ # 自动检测版本文件
39
+ VERSION_FILE=$(find $CURRENT_DIR/lib -name "version.rb" | head -n 1)
40
+ if [ -z "$VERSION_FILE" ]; then
41
+ echo "错误: 未找到version.rb文件!"
42
+ exit 1
43
+ fi
25
44
 
26
- VERSION_FILE=${CURRENT_DIR}/lib/app_store_dev_api/version.rb
27
- VERSION_TAG_NAME=$(grep VERSION ${VERSION_FILE} | cut -d"'" -f2)
45
+ VERSION_KEY="VERSION"
46
+ VERSION_TAG_NAME=$(grep -o "${VERSION_KEY}.*=.*['\"]\(.*\)['\"]" ${VERSION_FILE} | head -1 | sed -E "s/.*['\"]([0-9]+\.[0-9]+\.[0-9]+)['\"].*/\1/")
28
47
  TAG_NAME="v${VERSION_TAG_NAME}"
29
48
 
30
49
  COMMIT_FILE_LIST=$(git -C $CURRENT_DIR ls-files --other --modified --exclude-standard)
@@ -61,9 +80,9 @@ fi
61
80
 
62
81
 
63
82
 
64
- gem build $CURRENT_DIR/app_store_dev_api.gemspec
65
- if [[ -f $CURRENT_DIR/app_store_dev_api-${VERSION_TAG_NAME}.gem ]]; then
66
- gem install --local $CURRENT_DIR/app_store_dev_api-${VERSION_TAG_NAME}.gem
83
+ gem build $GEMSPEC_FILE
84
+ if [[ -f $CURRENT_DIR/${PROJECT_NAME}-${VERSION_TAG_NAME}.gem ]]; then
85
+ gem install --local $CURRENT_DIR/${PROJECT_NAME}-${VERSION_TAG_NAME}.gem
67
86
  fi
68
87
 
69
88
 
@@ -108,8 +127,8 @@ git -C $CURRENT_DIR push origin ${TAG_NAME}
108
127
  git -C $CURRENT_DIR checkout $CODING_BRANCH
109
128
 
110
129
 
111
- if [[ -f $CURRENT_DIR/app_store_dev_api-${VERSION_TAG_NAME}.gem ]]; then
112
- gem push $CURRENT_DIR/app_store_dev_api-${VERSION_TAG_NAME}.gem
130
+ if [[ -f $CURRENT_DIR/${PROJECT_NAME}-${VERSION_TAG_NAME}.gem ]]; then
131
+ gem push $CURRENT_DIR/${PROJECT_NAME}-${VERSION_TAG_NAME}.gem
113
132
  fi
114
133
 
115
134
 
@@ -17,7 +17,7 @@ openapi_paths = openapi_data['paths']
17
17
 
18
18
  # 2. 读取 schema.json 配置
19
19
  schema_files = [
20
- File.join(__dir__, '../lib/config/schema_v4.2.json'),
20
+ File.join(__dir__, '../lib/config/schema_v4.3.json'),
21
21
  File.join(__dir__, '../lib/config/schema.json')
22
22
  ].find { |f| File.exist?(f) }
23
23
 
@@ -15,7 +15,7 @@ puts
15
15
  openapi_file = 'docs/openapi.oas4.2.json'
16
16
  openapi_data = JSON.parse(File.read(openapi_file))
17
17
 
18
- schema_file = 'lib/config/schema_v4.2.json'
18
+ schema_file = 'lib/config/schema_v4.3.json'
19
19
  schema_data = JSON.parse(File.read(schema_file))
20
20
 
21
21
  request_files = Dir.glob('lib/app_store_dev_api/requests/**/{create,update}.rb')