pod-binary-pack 1.0.0

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: d7e56b61776fc312b4ed3c827f8603cce472db265e807e7e14f0db0d42277ed4
4
+ data.tar.gz: ba222d82dc1492ef2ea95df1fd82516d539175d873ba62a5819006aec235647e
5
+ SHA512:
6
+ metadata.gz: 0d5829f480bb10b7619582aaa998ff428b2d7619f1d2b4df74d7301c9888083a52ab9e1ce280131686500ae7f88287a64609b3d8e140a729c2afff7506dae205
7
+ data.tar.gz: dd5937f54f70ed0efd0f64328c1e968f843362755b6f5ec457fcf6cc87e56bd275aa791ca3a26e33feeafd115d65aa2330caee3358758d01c501aa3eecbc43d6
data/CHANGELOG.md ADDED
@@ -0,0 +1,15 @@
1
+ # Changelog
2
+
3
+ ## 1.0.0 - 2026-10-16
4
+
5
+ iOS 双私有源组件打包工具的首个正式版本。以壳工程为打包工程,配合 cocoapods-yaml 插件完成组件的一键打包与发布,自研组件与三方库统一支持。
6
+
7
+ - 一键完成组件源码拉取、依赖裁剪安装、真机/模拟器双架构 xcframework 构建与双仓发布
8
+ - 组件同时发布源码与二进制两种形态,App 优先使用二进制源,可随时切回源码调试
9
+ - 三方库支持自动 fork 上游仓库到私有镜像仓,git 仓库与 http 归档两种来源均可
10
+ - 支持多 subspec 组件整包构建、纯头文件组件、一仓多组件、指定 subspec 集成等例外场景
11
+ - 自动检测并兼容依赖缺失模拟器架构的情况,避免新版 Xcode 下链接失败
12
+ - 产物信息完整可追溯:提交信息、包体占用、CPU 架构、校验和、构建工具版本等
13
+ - 支持 SNAPSHOT 包与正式包两种发布模式,正式包发布后自动锁定源码分支
14
+ - 发布流程规范统一:提交信息可标记裁剪情况,产物无变化自动跳过重复发布
15
+ - 支持 Gitee 与自建 GitLab 两种代码托管平台
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2025 WANGSHUAIPENG
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,147 @@
1
+ # pod-binary-pack
2
+
3
+ iOS 双私有源(源码 spec 仓 / 二进制 spec 仓)组件打包命令行工具。
4
+
5
+ 按组件一键完成:源码拉取 → YAML 依赖裁剪安装(`TRIM_UNUSED_POD`)→ 真机/模拟器 xcframework 构建 → 双仓(spec 仓 + 组件仓)发布与 tag 管理 → 壳工程依赖版本回写。自研组件与三方库(GitHub fork / http 归档 git 化)统一支持。
6
+
7
+ 与 [cocoapods-yaml](https://rubygems.org/gems/cocoapods-yaml) 配套使用:后者负责壳工程的 YAML 依赖管理与裁剪安装,本工具负责打包与发布。
8
+
9
+ ## 功能特性
10
+
11
+ - **壳工程即打包工程**:archive 与版本回写在同一工程完成,无需维护独立打包工程
12
+ - **双私有源**:组件同时发布源码形态与二进制形态,App 优先命中二进制源,可随时切回源码调试
13
+ - **真机 + 模拟器**:一次构建合并 xcframework;模拟器默认 arm64 + x86_64 双架构,兼容 Apple Silicon 与 Intel
14
+ - **三方库 fork**:GitHub 上游自动镜像到私有仓(git 源克隆 / http 归档 git 化),发布 podspec 的 source 改写为镜像仓引用
15
+ - **多 subspec 整包**、**纯头文件组件**、**一仓多组件 tag 前缀**、**互斥 subspec 集成集合**等例外场景均有内建支持
16
+ - **产物可追溯**:podspec `build_metadata` 记录 commit 信息、App 实际占用体积、产物架构、Mach-O SHA256 校验和、Xcode 版本等
17
+
18
+ ## 环境要求
19
+
20
+ - macOS + Xcode(构建机无需证书/Apple ID,产物由 App 出包时统一重签名)
21
+ - Ruby >= 3.2,CocoaPods >= 1.15
22
+ - 组件源码仓 / 二进制仓 / spec 仓托管在 Gitee(或自建 GitLab)
23
+
24
+ ## 安装
25
+
26
+ ```bash
27
+ gem install pod-binary-pack
28
+ ```
29
+
30
+ 或通过私有 git 源引入(内部推荐,随分支更新):
31
+
32
+ ```ruby
33
+ # Gemfile / Jenkins 构建脚本
34
+ gem 'pod-binary-pack', git: 'git@gitee.com:xxx/pod-binary-pack.git', branch: 'master'
35
+ ```
36
+
37
+ ## 快速开始
38
+
39
+ 1. 在工作目录生成配置模板并填写壳工程/spec 仓地址:
40
+
41
+ ```bash
42
+ pod-binary-pack --init --config config/build.yml
43
+ ```
44
+
45
+ 2. 打包一个组件:
46
+
47
+ ```bash
48
+ # SNAPSHOT 包(自研组件默认),真机+模拟器
49
+ pod-binary-pack --pod Foo --version 1.0.0
50
+
51
+ # 正式包并合并到 master、发布到壳工程
52
+ pod-binary-pack --pod Foo --version 1.0.0 --snapshot false --publish-shell true
53
+
54
+ # 版本分支缺省 --version 自动解析
55
+ pod-binary-pack --pod Foo --branch release_1.2.0
56
+ ```
57
+
58
+ ## 命令行参数
59
+
60
+ | 参数 | 说明 |
61
+ | --- | --- |
62
+ | `--pod NAME` | 必填,组件名 |
63
+ | `--version VER` | 组件版本号(不带 SNAPSHOT);使用版本分支时可缺省自动解析 |
64
+ | `--branch BRANCH` | 源码仓库分支/tag,默认 master |
65
+ | `--snapshot true\|false` | 是否 SNAPSHOT 包,自研组件默认 true;fork-github 流程固定 false |
66
+ | `--device true\|false` | 是否构建真机包,默认 true |
67
+ | `--simulator true\|false` | 是否构建模拟器包,默认 true |
68
+ | `--merge-master true\|false` | 是否合并到 master,默认跟随 SNAPSHOT(SNAPSHOT 不合并、正式包合并) |
69
+ | `--force-cover true\|false` | 是否强制覆盖发布,默认 false |
70
+ | `--publish-shell true\|false` | 是否发布到壳工程,默认 false |
71
+ | `--fork-github` | 三方库 fork 模式:自动解析 podspec 并 fork 上游源码 |
72
+ | `--source-url URL` / `--binary-url URL` | 显式指定源码/二进制仓地址,跳过 url_template 拼接 |
73
+ | `--podspec-path PATH` | podspec 相对源码仓根目录的路径(不在根目录时使用) |
74
+ | `--tag-prefix PREFIX` | 一仓多组件时的源码 tag 前缀(如 `Foo/`) |
75
+ | `--subspecs A,B` | 仅集成指定 subspec(互斥 subspec 组件),默认集成全部 |
76
+ | `--profile NAME` | 使用配置文件中的指定 profile,默认按模式自动选择 |
77
+ | `--build-url URL` | 构建地址(通知文案跳转用,由触发方传入:Jenkins 作业/web 平台构建详情页) |
78
+ | `--config PATH` | 环境配置文件,默认 `config/build.yml` |
79
+ | `--verbose` | 输出调试细节,也可用环境变量 `POD_BINARY_PACK_VERBOSE=1` |
80
+ | `--init` | 在 `--config` 指定位置生成配置模板并退出 |
81
+ | `-h` / `--help` | 查看全部参数帮助 |
82
+
83
+ 除 `--pod`/`--version`(或用版本分支解析版本号)外其余参数均有默认值,可按需组合。布尔参数只接受 `true`/`false`,非法值在构建前直接报错拦截。
84
+
85
+ ## build.yml 配置
86
+
87
+ `pod-binary-pack --init` 生成模板,核心结构:
88
+
89
+ ```yaml
90
+ gitee:
91
+ endpoint: "" # 自建 API 地址,留空用官方
92
+ access_token: "" # 建议改用环境变量 GITEE_ACCESS_TOKEN
93
+
94
+ hooks_file: event.rb # 构建钩子(可选)
95
+ sender_file: send.rb # 通知发送器(可选)
96
+
97
+ # 例外组件配置(可选),命令行同名参数优先级更高
98
+ components:
99
+ SomeLib:
100
+ source_url: git@gitee.com:xxx/actual-repo.git
101
+ podspec_path: SubDir/SomeLib.podspec
102
+ tag_prefix: "SomeLib/"
103
+ subspecs: [Core, SQLCipher]
104
+
105
+ profiles:
106
+ default:
107
+ release_branch_prefix: release # 版本分支前缀,可定制
108
+ repos:
109
+ shell: # 壳工程即打包工程
110
+ url: git@gitee.com:xxx/shell.git
111
+ branch: master
112
+ workspace: Shell.xcworkspace
113
+ scheme: Shell
114
+ code_signing: false # archive 不签名,无需证书
115
+ cocoapods_source: # 源码 spec 仓
116
+ url: git@gitee.com:xxx/specs-source.git
117
+ cocoapods_binary: # 二进制 spec 仓
118
+ url: git@gitee.com:xxx/specs-binary.git
119
+ source_module:
120
+ url_template: "git@gitee.com:xxx/%{pod}.git"
121
+ binary_module:
122
+ url_template: "git@gitee.com:xxx/%{pod}.git"
123
+ fork_github:
124
+ mode: fork_github
125
+ repos:
126
+ # 同上;source_module.url_template 指向三方镜像仓名
127
+ ```
128
+
129
+ Gitee 令牌优先级:环境变量 `GITEE_ACCESS_TOKEN` > `git config --global gitee.accesstoken` > build.yml。令牌永远不写入代码仓库与发布包。
130
+
131
+ ## 工作机制
132
+
133
+ 1. 壳工程 Podfile 通过 [cocoapods-yaml](https://rubygems.org/gems/cocoapods-yaml) 插件以 YAML 按 target 管理依赖;打包期生成 `LocalDependencies.yaml` 开启 `TRIM_UNUSED_POD`,只安装目标组件及其依赖,`pod update` 前自动桩化 main.m 保证裁剪干净、archive 不依赖壳工程业务代码
134
+ 2. archive 产出 xcframework(默认不签名),扫描组件与依赖的预编译库,缺 arm64 模拟器 slice 时自动降级 x86_64
135
+ 3. 二进制组件仓清空后写入 xcframework/资源/头文件,podspec 的 source 指向二进制仓 tag,扩展元数据写入 `build_metadata`
136
+ 4. 双 spec 仓与组件仓分别提交打 tag(产物无变化自动跳过),正式包锁定发布分支,可选合并 master 并回写壳工程依赖版本
137
+
138
+ ## 开发
139
+
140
+ ```bash
141
+ ruby scripts/install_local.rb # 本地改动后构建并覆盖安装到当前 Ruby 环境
142
+ ruby scripts/release.rb # 仅构建(安全扫描、隔离环境冒烟安装)
143
+ ```
144
+
145
+ ## License
146
+
147
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'pod/binary_pack'
5
+
6
+ Build::CLI.run(ARGV)
@@ -0,0 +1,299 @@
1
+ # frozen_string_literal: true
2
+ require_relative 'config'
3
+ require_relative 'build_item'
4
+ require_relative 'repo_xcode'
5
+ require_relative 'repo_xcode_package'
6
+ require_relative 'repo_xcode_shell'
7
+ require_relative 'repo_cocoapods'
8
+ require_relative 'repo_module'
9
+ require_relative 'repo_module_source'
10
+ require_relative 'repo_module_binary'
11
+ require_relative 'cost'
12
+ require_relative 'push'
13
+ require_relative 'github_helper'
14
+ require_relative 'github_fork'
15
+
16
+ module Build
17
+ class AutoBuild
18
+ # @return [Config] 全局配置
19
+ attr_accessor :config
20
+
21
+ # @return [BuildItem]构建配置
22
+ attr_accessor :build_item
23
+
24
+ # @return [RepoXCodeShell] 壳工程(同时也是打包工程)
25
+ attr_accessor :repo_xcode_package
26
+
27
+ # @return [RepoXCodeShell] 壳工程
28
+ attr_accessor :repo_xcode_shell
29
+
30
+ # @return [RepoCocoapods] cocoapods源码仓库
31
+ attr_accessor :repo_cocoapods_source
32
+
33
+ # @return [RepoCocoapods] cocoapods二进制仓库
34
+ attr_accessor :repo_cocoapods_binary
35
+
36
+ # @return [RepoModuleSource] 组件源码
37
+ attr_accessor :repo_module_source
38
+
39
+ # @return [RepoModuleBinary] 组件二进制
40
+ attr_accessor :repo_module_binary
41
+
42
+ # @return [Log] 日志
43
+ attr_accessor :log
44
+
45
+ # @return [Push] 推送对象
46
+ attr_accessor :pusher
47
+
48
+ # @return [Boolean] 是否构建二进制
49
+ attr_accessor :build_binary
50
+
51
+ def initialize(config, repo_cocoapods_source, repo_cocoapods_binary)
52
+ @log = Log.new
53
+ @pusher = Push.instance
54
+ @config = config
55
+ @repo_cocoapods_source = repo_cocoapods_source
56
+ @repo_cocoapods_binary = repo_cocoapods_binary
57
+
58
+ end
59
+
60
+ def run(repo_xcode_shell, repo_module_source, repo_module_binary, build_item, sender = nil)
61
+ # 壳工程即打包工程,全流程只使用这一个工程实例
62
+ @repo_xcode_shell = repo_xcode_shell
63
+ @repo_xcode_package = repo_xcode_shell
64
+ @repo_module_source = repo_module_source
65
+ @repo_module_binary = repo_module_binary
66
+ @build_item = build_item
67
+ @pusher.setup(sender, repo_module_source, repo_xcode_shell)
68
+
69
+ bind
70
+ analyzer
71
+ special_analyzer
72
+ print_build_options
73
+ clone_code
74
+ module_source_update
75
+ auto_build_update
76
+ xcode_package_update
77
+ re_pull
78
+ module_binary_update
79
+ cocoapods_update
80
+ merge_master
81
+ push_product
82
+ publish_shell
83
+ push_message_log
84
+ end
85
+
86
+ def bind
87
+ @repo_xcode_shell.pusher = pusher
88
+ @repo_cocoapods_source.pusher = pusher
89
+ @repo_cocoapods_binary.pusher = pusher
90
+ @repo_module_source.pusher = pusher
91
+ @repo_module_binary.pusher = pusher
92
+
93
+ end
94
+
95
+ def analyzer
96
+ Build.log.step("开始 组件:#{repo_module_source.pod_name} 版本:#{repo_module_source.pod_version} 分支/tag:#{repo_module_source.branch}")
97
+ end
98
+
99
+ def special_analyzer
100
+ self.build_item.special_setup(repo_module_source.pod_name)
101
+ end
102
+
103
+ # 在特殊参数调整完成后打印最终生效的构建参数,避免日志与实际构建配置不一致
104
+ def print_build_options
105
+ to_yes = ->(flag) { flag ? "是" : "否" }
106
+ options = [
107
+ ["组件", repo_module_source.pod_name],
108
+ ["发布版本", repo_module_source.pod_version_final],
109
+ ["分支/tag", repo_module_source.branch],
110
+ ["源码仓tag", repo_module_source.version_tag],
111
+ ["podspec路径", repo_module_source.podspec_rel_path || "未指定(自动扫描根目录以及子目录)"],
112
+ ["三方库", to_yes.call(repo_module_source.third)],
113
+ ["fork模式", to_yes.call(self.build_item.fork)],
114
+ ["SNAPSHOT包", to_yes.call(self.build_item.snapshot)],
115
+ ["真机包", to_yes.call(self.build_item.real_device)],
116
+ ["模拟器包", to_yes.call(self.build_item.simulator)],
117
+ ["纯头组件", to_yes.call(self.build_item.header_only)],
118
+ ["合并master", to_yes.call(self.build_item.merge_master)],
119
+ ["强制覆盖", to_yes.call(self.build_item.force_cover)],
120
+ ["发布壳工程", to_yes.call(self.build_item.publish_shell)]
121
+ ]
122
+ Build.log.detail("构建参数:")
123
+ options.each { |name, value| Build.log.detail(" #{name}:#{value}") }
124
+ end
125
+
126
+ def clone_code
127
+ Build.log.step("clone仓库")
128
+
129
+ # Cocoapods源码
130
+ repo_cocoapods_source.git_clone(true)
131
+
132
+ # Cocoapods二进制
133
+ repo_cocoapods_binary.git_clone(true)
134
+
135
+ # 三方库源码fork
136
+ if repo_module_source.third
137
+ github_helper = GithubHelper.instance
138
+ if self.build_item.fork
139
+ github_forker = GithubFork.instance
140
+ github_forker.setup(config.module_github_path, repo_module_source.pod_name, github_helper.github_url, repo_module_source.ssh_url,
141
+ archive: github_helper.archive_info,
142
+ podspec_json_path: github_helper.podspec_json_path,
143
+ force_cover: build_item.force_cover)
144
+ # 仅源码spec仓参与fork校验:二进制spec的source指向二进制组件仓,与GitHub上游无关
145
+ github_forker.fork_if_need(repo_cocoapods_source)
146
+ end
147
+ end
148
+
149
+ # 组件源码
150
+ source_only_head = !self.build_item.merge_master
151
+ repo_module_source.git_clone(source_only_head)
152
+
153
+ # 组件二进制
154
+ # 二进制组件仓不存在时自动创建为私有仓库(固定私有)
155
+ repo_module_binary.hosting.create_project_if_need(repo_module_source.pod_name, repo_module_binary.http_url, description: repo_module_source.http_url)
156
+ repo_module_binary.git_clone(true)
157
+
158
+ # 壳工程(即打包工程),全流程只 clone 一次
159
+ repo_xcode_shell.git_clone(true)
160
+
161
+ # 记录时间
162
+ log.record_time("clone代码")
163
+ end
164
+
165
+ def module_source_update
166
+ # 校验commitID是否包含上次
167
+ repo_module_source.force_cover_validate(repo_cocoapods_source)
168
+
169
+ # 更新podspec文件
170
+ repo_module_source.update_podspec
171
+
172
+ # 更新是否不需要打framework
173
+ repo_module_source.update_binary
174
+
175
+ end
176
+
177
+ def auto_build_update
178
+ # 更新自己的构建二进制属性
179
+ @build_binary = repo_module_source.build_binary
180
+ end
181
+
182
+ def xcode_package_update
183
+
184
+ # 准备壳工程内的 yaml 文件(触发三方库替换等扩展钩子)
185
+ repo_xcode_shell.prepare_yaml_files
186
+
187
+ # 生成local_yaml文件
188
+ repo_xcode_shell.generate_local_yaml(repo_module_source)
189
+
190
+ # 校验组件与壳工程的最低iOS版本融合结果(只读不修改,仅提示不阻断)
191
+ repo_xcode_shell.check_package_version(repo_module_source)
192
+
193
+ # pod update 前桩化 main.m: 让 TRIM_UNUSED_POD 裁剪只保留目标组件依赖,
194
+ # 同时保证 archive 不依赖壳工程业务组件;结束后(main.m)自动还原
195
+ repo_xcode_shell.with_build_stub do
196
+ # pod update
197
+ repo_xcode_shell.pod_update
198
+
199
+ # 记录时间
200
+ log.record_time("pod update")
201
+
202
+ # 构建打包
203
+ repo_xcode_shell.archive(repo_module_source)
204
+
205
+ # 记录时间
206
+ log.record_time("构建打包")
207
+ end
208
+ end
209
+
210
+ def re_pull
211
+ # 拉取代码
212
+ Build.log.step("重新拉取仓库")
213
+ repo_cocoapods_binary.git_pull
214
+ repo_cocoapods_source.git_pull
215
+ repo_module_binary.git_pull
216
+ end
217
+
218
+ def module_binary_update
219
+ if build_item.header_only
220
+ # 纯头文件组件:清空后写入头文件 + 普通形态podspec(无framework产物)
221
+ repo_module_binary.clear
222
+ repo_module_binary.publish_header_only(repo_module_source)
223
+ elsif build_binary
224
+ # 清空二进制仓库
225
+ repo_module_binary.clear
226
+
227
+ # 拷贝framework产物
228
+ repo_module_binary.copy_framework(repo_xcode_package, repo_module_source)
229
+
230
+ # 拷贝资源文件
231
+ repo_module_binary.copy_resources(repo_xcode_package, repo_module_source)
232
+
233
+ # 拷贝podspec文件
234
+ repo_module_binary.copy_podspec(repo_xcode_package, repo_module_source)
235
+ end
236
+ end
237
+
238
+ def cocoapods_update
239
+ # 拷贝到二进制source(编译产物组件 或 纯头文件组件)
240
+ build_item.publish_binary? ? repo_cocoapods_binary.copy_podspec(repo_module_binary) : nil
241
+
242
+ # 拷贝到源码source
243
+ repo_cocoapods_source.copy_podspec(repo_module_source)
244
+ end
245
+
246
+ def merge_master
247
+ # 合并分支到master
248
+ repo_module_source.hosting.merge_branch(repo_module_source, "master")
249
+ end
250
+
251
+ def push_product
252
+ # 两个仓库的tag是否跳过需要分别独立判定:
253
+ # - 源码仓tag: 源码HEAD相对上次发布无新提交则tag仍指向同一commit,跳过删tag重推
254
+ # - 二进制仓tag: 即使源码没变,编译配置/依赖变化也可能产出不同framework,
255
+ # 因此以二进制仓本次是否真的产生了新提交(framework内容有无变化)为准
256
+ skip_source_tag = repo_module_source.no_new_commit_since_last_release?
257
+ if skip_source_tag
258
+ Build.log.info("源码仓: 当前HEAD与上次发布的commit一致(#{repo_module_source.last_released_commit_id[0, 7]}),跳过源码版本tag的删除与重新推送")
259
+ end
260
+
261
+ # 二进制(编译产物组件 或 纯头文件组件)
262
+ if build_item.publish_binary?
263
+ binary_changed = repo_module_binary.push_code
264
+ if binary_changed
265
+ repo_module_binary.git_tag
266
+ else
267
+ Build.log.info("二进制仓: 产物无变化,跳过二进制版本tag的删除与重新推送")
268
+ end
269
+ repo_cocoapods_binary.push_code
270
+ end
271
+
272
+ # 源码
273
+ repo_module_source.git_tag unless skip_source_tag
274
+ repo_cocoapods_source.push_code
275
+ repo_module_source.lock_branch_if_need
276
+
277
+ # 记录时间
278
+ log.record_time("提交产物")
279
+
280
+ end
281
+
282
+ def publish_shell
283
+ # 发布到壳工程
284
+ repo_xcode_shell.publish_shell(repo_module_source)
285
+ end
286
+
287
+ def push_message_log
288
+ # 记录时间
289
+ log.end_record_time("🕓 整体")
290
+
291
+ # 推送结果
292
+ pusher.push("【✅组件版本发布成功】", "耗时: #{log.cost_time}秒 App包占用: #{repo_module_binary.framework_size_format}")
293
+
294
+ # 打印耗时
295
+ log.print_cost
296
+ end
297
+
298
+ end
299
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'push'
4
+
5
+ module Build
6
+ class BuildItem
7
+
8
+ # 定制组件名单:不编译framework也不发布二进制(保持历史行为)
9
+ # special_setup提前置位保证构建参数日志准确,update_binary中幂等重设并跳过源码扫描
10
+ NO_BINARY_PODS = %w[MUCDebugPlugins].freeze
11
+
12
+ attr_accessor :snapshot
13
+ attr_accessor :real_device
14
+ attr_accessor :simulator
15
+ attr_accessor :merge_master
16
+ attr_accessor :force_cover
17
+ attr_accessor :publish_shell
18
+ attr_accessor :fork
19
+ attr_accessor :pusher
20
+
21
+ # 纯头文件组件(无.m/.mm等实现文件):不编译framework,但仍发布头文件形态的二进制podspec
22
+ attr_accessor :header_only
23
+
24
+ # 模拟器产物裁剪arm64:检测到组件或其依赖缺少 arm64 模拟器 slice 时置为 true,
25
+ # 模拟器产物仅构建 x86_64(依赖Rosetta),各仓库提交信息据此追加 [裁剪架构] 关键字
26
+ attr_accessor :simulator_exclude_arm64
27
+
28
+ def initialize(snapshot, real_device, simulator, merge_master, force_cover, publish_shell, fork = false)
29
+
30
+ @snapshot = snapshot.to_s.downcase == "true"
31
+ @real_device = real_device.to_s.downcase == "true"
32
+ @simulator = simulator.to_s.downcase == "true"
33
+ @merge_master = merge_master.to_s.downcase == "true"
34
+ @force_cover = force_cover.to_s.downcase == "true"
35
+ @publish_shell = publish_shell.to_s.downcase == "true"
36
+ @fork = fork.to_s.downcase == "true"
37
+ @header_only = false
38
+ @pusher = Push.instance
39
+
40
+ validate
41
+ end
42
+
43
+ # 是否需要发布到二进制仓/spec仓:有编译产物,或是纯头文件组件
44
+ def publish_binary?
45
+ real_device || simulator || header_only
46
+ end
47
+
48
+ def validate
49
+ if merge_master and snapshot
50
+ error = "SNAPSHOT包发布不能同时选择合并到master分支, 请检查参数"
51
+ pusher.push("❌ 打包失败", error)
52
+ Process.exit(-1)
53
+ end
54
+
55
+ end
56
+
57
+ # 特殊组件处理(在构建参数日志打印前执行,保证日志与实际构建配置一致)
58
+ def special_setup(pod_name)
59
+ if NO_BINARY_PODS.include?(pod_name)
60
+ @real_device = false
61
+ @simulator = false
62
+ @header_only = false
63
+ warn_msg = "定制组件#{pod_name}不需要打二进制"
64
+ Build.log.warn(warn_msg)
65
+ pusher.push("【⚠️组件不构建二进制提醒】", warn_msg)
66
+ end
67
+ end
68
+ end
69
+ end