fir-cli 2.0.7 → 2.0.12
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -1
- data/README.md +52 -23
- data/doc/publish.md +45 -22
- data/fir-cli.gemspec +8 -2
- data/lib/fir.rb +1 -0
- data/lib/fir/api.yml +1 -0
- data/lib/fir/cli.rb +10 -1
- data/lib/fir/util/app_uploader.rb +10 -3
- data/lib/fir/util/dingtalk_helper.rb +67 -0
- data/lib/fir/util/feishu_helper.rb +95 -0
- data/lib/fir/util/publish.rb +35 -30
- data/lib/fir/version.rb +1 -1
- metadata +39 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 954e969109ed3d6d61b3ca1a736f3078607fc56bfb079e225042d8badd061902
|
4
|
+
data.tar.gz: 9a07109ea940a55fac9a95794261536c622e068d53ea26f6fa99d493ba2acea8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 78807f3b119d7386fdd67b3073983edfb61b68cfb77b7b0efd2746cc32b37eb27b8f99d4b736b7b541d3d7b75154551d701b0b6a3449a4a1dfd05d5ed7d6ddad
|
7
|
+
data.tar.gz: 3acc0e40268677755254abf3e9232eedc3765b34f26983fc8a34d4eed089dee22fe4f8e742039f6802395c0670d9010ccd2d6ce23608ed0ad8b5ea8277b5f8fc
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
✈ fir.im-cli
|
2
|
-
----
|
2
|
+
----
|
3
3
|
|
4
4
|
![Build Status Images](https://travis-ci.org/FIRHQ/fir-cli.svg)
|
5
5
|
[![Code Climate](https://codeclimate.com/github/FIRHQ/fir-cli/badges/gpa.svg)](https://codeclimate.com/github/FIRHQ/fir-cli)
|
@@ -13,11 +13,15 @@ fir.im-cli 可以通过指令查看, 上传, iOS/Android 应用.
|
|
13
13
|
![fir-cli](http://7rf35s.com1.z0.glb.clouddn.com/fir-cli-new.gif)
|
14
14
|
|
15
15
|
# 重大提醒
|
16
|
-
- fir.im 更换域名后, 需要升级至 `fir-cli` >= `2.0.4` 有部分用户反馈 2.0.2 无法直接使用 `gem update fir-cli` 升级到 2.0.4, 则可以尝试卸载后重新安装, 即 `gem uninstall fir-cli` 后 `gem install fir-cli`
|
17
|
-
|
18
|
-
当然还有种解决办法是 更新 `fir-cli` 至 `2.0.5`, 这个版本换到了备用域名
|
16
|
+
- fir.im 更换域名后, 需要升级至 `fir-cli` >= `2.0.4` 有部分用户反馈 2.0.2 无法直接使用 `gem update fir-cli` 升级到 2.0.4, 则可以尝试卸载后重新安装, 即 `gem uninstall fir-cli` 后 `gem install fir-cli`
|
17
|
+
|
19
18
|
|
20
19
|
# 最近更新
|
20
|
+
- (2.0.12) 修复因为钉钉机器人不再支持base64导致无法显示二维码,另外开始支持钉钉加签方式的鉴权, 参数为 --dingtalk_secret
|
21
|
+
- (2.0.11) 兼容了 ruby 3.0
|
22
|
+
- (2.0.10) 飞书支持了 V2 版本的机器人推送
|
23
|
+
- (2.0.9) publish 支持了 企业微信通知 可以使用 --wxwork_access_token 或 --wxwork_webhook, 增加了回调超时时间至20秒
|
24
|
+
- (2.0.8) publish 支持 飞书通知, 可使用 `feishu_access_token` 和 `feishu_custom_message`, 详情见 `fir publish --help`
|
21
25
|
- (2.0.7) 修复了提示 token 错误的问题
|
22
26
|
- (2.0.6) 修复了因为文件读取方式变化而导致的文件找不到不报错的问题
|
23
27
|
- (2.0.5) 因为深信服 的黑名单误判, 将 api 切换到了备用域名
|
@@ -45,24 +49,49 @@ fir.im-cli 可以通过指令查看, 上传, iOS/Android 应用.
|
|
45
49
|
|
46
50
|
## 热门问题
|
47
51
|
|
48
|
-
###
|
52
|
+
### 啥是 钉钉 / 企业微信 / 飞书 的 `access_token` ?
|
53
|
+
|
54
|
+
就是回调地址中的长得最像 access_token 的东西
|
55
|
+
|
56
|
+
```
|
57
|
+
钉钉: https://oapi.dingtalk.com/robot/send?access_token=xxxxx
|
58
|
+
就是 xxx 那部分
|
59
|
+
|
60
|
+
企业微信: https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxxxx-xxxx-xxxx-xxxx-xxxxx
|
61
|
+
就是 xxxxx-xxxx-xxxx-xxxx-xxxxx 那部分
|
62
|
+
|
63
|
+
https://open.feishu.cn/open-apis/bot/hook/xxxxxxxxxxxxxxxxxxx
|
64
|
+
|
65
|
+
就是 xxxxxxxxxxxxxxxx 那部分
|
66
|
+
|
67
|
+
```
|
68
|
+
|
69
|
+
|
70
|
+
|
71
|
+
|
72
|
+
|
73
|
+
### 如何配合 jenkins 使用?
|
49
74
|
|
50
75
|
参见 blog [http://blog.betaqr.com/use-fir-cli-in-jenkins/](http://blog.betaqr.com/use-fir-cli-in-jenkins/)
|
51
76
|
|
52
|
-
|
77
|
+
这里有个快速检查脚本, 可以在 jenkins 中新建一个 脚本, 进行检查
|
53
78
|
|
54
|
-
|
79
|
+
```
|
80
|
+
#!/bin/bash --login
|
55
81
|
|
82
|
+
rvm list # 确保 rvm 正确安装, 如果直接通过系统安装ruby, 可以注释此行
|
83
|
+
ruby -v # 查看 ruby 的版本, 请确保大于 2.4.0
|
84
|
+
gem install fir-cli # 现场安装fir-cli , 如果安装过, 则会略过
|
85
|
+
fir -v # 查看 fir-cli 的版本
|
56
86
|
|
57
|
-
|
87
|
+
# 在这里执行 fir publish xxxxx
|
88
|
+
```
|
58
89
|
|
59
90
|
|
91
|
+
### 在 Circle CI, Travis CI 或 Github Actions 等境外服务上, 有概率超时, 能否解决?
|
60
92
|
|
61
|
-
|
93
|
+
2.0.3 版本 及其以上, 可以申请海外加速内测资格, 开启后可以使用海外加速上传 `--oversea_turbo`
|
62
94
|
|
63
|
-
1. 设置较长的超时时间 如 `FIR_TIMEOUT=300 fir publish xxxx`, 则可将超时时间设置为 300 秒.
|
64
|
-
2. 如果fir-cli 版本 >= 2.0.0, 也可在出现超时后, 使用 `--switch-to-qiniu` 来切换到我们的另外一条存储线路. 如 `fir publish xxxx.apk --switch-to-qiniu`, 多一条线路备选.
|
65
|
-
3. 如果确实对这方面服务要求很高, 则可购买我们的私有部署服务. 我们可以在 aws 上部署一套专供您使用, 具体情况可以与客服或者加我微信进行沟通.
|
66
95
|
|
67
96
|
更多细节请参考 [https://github.com/FIRHQ/fir-cli/issues/260](https://github.com/FIRHQ/fir-cli/issues/260)
|
68
97
|
|
@@ -91,13 +120,13 @@ fir-cli 提供对 aab 文件有限程度支持的上传与下载. 在使用 fir-
|
|
91
120
|
|
92
121
|
### 我想将 我上传的版本展示在下载的页面上
|
93
122
|
|
94
|
-
可以在 publish 的时候使用 --force_pin_history 这样 这个上传的版本即成为 "历史版本", 会在下载页面里一直显示. 当有新的版本上传后, 这个版本会作为 "历史版本" 在下载页面中展示.
|
123
|
+
可以在 publish 的时候使用 --force_pin_history 这样 这个上传的版本即成为 "历史版本", 会在下载页面里一直显示. 当有新的版本上传后, 这个版本会作为 "历史版本" 在下载页面中展示.
|
95
124
|
|
96
125
|
当版本设置为历史版本后, 用户可以直接下载指定的版本, 由于因成本原因, 一个 app 最多的 "历史版本" 为 30 个, 如果有用户有特殊需求, 可以与我们取得联系进行单独修改
|
97
126
|
|
98
127
|
当达到上限后, 如果继续标记 force_pin_history, 则历史版本的最老版本(以上传时间为准)会被移出历史版本列表
|
99
128
|
|
100
|
-
### 境外上传老出现 stream closed
|
129
|
+
### 境外上传老出现 stream closed
|
101
130
|
|
102
131
|
因为网络时延问题, 可传入环境变量 `FIR_TIMEOUT=xxx` 进行超时时间设置
|
103
132
|
|
@@ -112,22 +141,22 @@ fir-cli 提供对 aab 文件有限程度支持的上传与下载. 在使用 fir-
|
|
112
141
|
- [fir publish 发布应用到 fir.im](https://github.com/FIRHQ/fir-cli/blob/master/doc/publish.md)
|
113
142
|
- [fir upgrade 升级相关](https://github.com/FIRHQ/fir-cli/blob/master/doc/upgrade.md)
|
114
143
|
|
115
|
-
## Docker 运行 fir-cli
|
144
|
+
## Docker 运行 fir-cli
|
116
145
|
|
117
146
|
### 准备工作
|
118
147
|
1. 将自己需要的文件挂载到 docker 中, 之后即可直接运行
|
119
|
-
2. 将自己的 API_TOKEN 以环境变量的形式传入container
|
148
|
+
2. 将自己的 API_TOKEN 以环境变量的形式传入container
|
120
149
|
|
121
150
|
### 如何运行
|
122
151
|
|
123
|
-
假设 我需要上传桌面的 1.apk
|
152
|
+
假设 我需要上传桌面的 1.apk
|
124
153
|
|
125
154
|
```
|
126
|
-
docker run -e API_TOKEN=您的token -v 您的上传文件的目录的绝对路径:/tmp firhq/fir-cli:latest publish /tmp/你的文件
|
155
|
+
docker run -e API_TOKEN=您的token -v 您的上传文件的目录的绝对路径:/tmp firhq/fir-cli:latest publish /tmp/你的文件
|
127
156
|
|
128
157
|
# 如 `docker run -e API_TOKEN=xxxxxxxe -v /Users/atpking/Desktop:/tmp firhq/fir-cli:latest publish /tmp/1.apk`
|
129
158
|
|
130
|
-
# 实际含义是把我的桌面挂载到 docker 里的 /tmp 目录 之后上传 docker 文件里的 /tmp/1.apk
|
159
|
+
# 实际含义是把我的桌面挂载到 docker 里的 /tmp 目录 之后上传 docker 文件里的 /tmp/1.apk
|
131
160
|
# 也可以修改为其他目录
|
132
161
|
```
|
133
162
|
|
@@ -135,13 +164,13 @@ docker run -e API_TOKEN=您的token -v 您的上传文件的目录的绝对路
|
|
135
164
|
|
136
165
|
- 联系微信 `atpking`, 请注明 "fir-cli 交流"
|
137
166
|
|
138
|
-
- 使用 Github 的 [Issue](https://github.com/FIRHQ/fir-cli/issues)
|
167
|
+
- 使用 Github 的 [Issue](https://github.com/FIRHQ/fir-cli/issues)
|
139
168
|
|
140
|
-
## 特别感谢
|
169
|
+
## 特别感谢
|
141
170
|
|
142
171
|
- 感谢 sparkrico 提供修正的 https://github.com/sparkrico/ruby_apk 解决了 android 解析的问题
|
143
|
-
|
172
|
+
- 感谢 fabcz 同学对企业微信的通知的支持 https://github.com/FIRHQ/fir-cli/pull/277
|
144
173
|
|
145
174
|
## 鼓励维护
|
146
175
|
|
147
|
-
|
176
|
+
hia~ hia~ hia~
|
data/doc/publish.md
CHANGED
@@ -3,33 +3,56 @@
|
|
3
3
|
`fir publish` 命令用于可以发布应用到 fir.im, 支持 ipa 和 apk 文件.
|
4
4
|
|
5
5
|
```sh
|
6
|
-
$ fir publish --help
|
7
6
|
Usage:
|
8
7
|
fir publish APP_FILE_PATH
|
9
8
|
|
10
9
|
Options:
|
11
|
-
-s, [--short=SHORT]
|
12
|
-
-c, [--changelog=CHANGELOG]
|
13
|
-
-Q, [--qrcode], [--no-qrcode]
|
14
|
-
[--
|
15
|
-
|
16
|
-
-
|
17
|
-
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
-
|
10
|
+
-s, [--short=SHORT] # 设置short
|
11
|
+
-c, [--changelog=CHANGELOG] # 设置更新内容, 可是文件地址也可直接是内容
|
12
|
+
-Q, [--qrcode], [--no-qrcode] # 生成二维码图片在当前目录
|
13
|
+
[--need-ansi-qrcode], [--no-need-ansi-qrcode] #
|
14
|
+
-R, [--need-release-id], [--no-need-release-id] # 在下载地址中包含具体版本(警告, 每个app 最多保留30个版本, 超过后会失效最老的版本)
|
15
|
+
-H, [--force-pin-history], [--no-force-pin-history] # 将版本留在下载页(即在新版本上传后, 下面仍然有旧版本的二维码可以引导)
|
16
|
+
-S, [--skip-update-icon], [--no-skip-update-icon] # 跳过更新图标
|
17
|
+
[--specify-icon-file=SPECIFY_ICON_FILE] # 指定更新图标
|
18
|
+
[--skip-fir-cli-feedback], [--no-skip-fir-cli-feedback] # 跳过 用来做统计fir-cli的反馈(用于改进fir-cli)
|
19
|
+
[--specify-app-display-name=SPECIFY_APP_DISPLAY_NAME] # 指定app 名称
|
20
|
+
-N, [--switch-to-qiniu], [--no-switch-to-qiniu] # 切换到七牛线路上传(当上传较慢时, 可试试这个)
|
21
|
+
[--oversea-turbo], [--no-oversea-turbo] # 海外加速(需联系微信 atpking 开通)
|
22
|
+
-m, [--mappingfile=MAPPINGFILE] # mappingfile
|
23
|
+
-D, [--dingtalk-access-token=DINGTALK_ACCESS_TOKEN] # 上传完毕后 若发送至钉钉, 则填写钉钉的webhook 的access_token
|
24
|
+
[--dingtalk-custom-message=DINGTALK_CUSTOM_MESSAGE] # 自定义钉钉消息 (针对钉钉新版webhook 需要校验的时候, 可以做关键字)
|
25
|
+
[--dingtalk-at-phones=DINGTALK_AT_PHONES] # 钉钉 at 某人手机号
|
26
|
+
[--dingtalk-at-all], [--no-dingtalk-at-all]
|
27
|
+
[--feishu-access-token=FEISHU_ACCESS_TOKEN] # 飞书的webhook 的access_token
|
28
|
+
[--feishu-custom-message=FEISHU_CUSTOM_MESSAGE] # 自定义飞书消息
|
29
|
+
[--wxwork-webhook=WXWORK_WEBHOOK] # 企业微信的 webhook 地址 (注意这里与 access_token 只需要填写一个参数即可)
|
30
|
+
[--wxwork-access-token=WXWORK_ACCESS_TOKEN] # 企业微信的 webhook access_token (注意这里与 access_token 只需要填写一个参数即可)
|
31
|
+
[--wxwork-custom-message=WXWORK_CUSTOM_MESSAGE] # 企业微信 的自定义消息
|
32
|
+
[--wxwork-pic-url=WXWORK_PIC_URL] # 企业微信的图片链接, best size is 1068x455
|
33
|
+
[--open], [--no-open] # 是否下载可见, 默认open
|
34
|
+
[--password=PASSWORD] # 下载页面密码, 默认为空
|
35
|
+
[--bundletool-jar-path=BUNDLETOOL_JAR_PATH] # (beta) 上传AAB 文件的特殊指令: upload aab file command: to specify bundletool.jar if command bundletool can not run directly
|
36
|
+
[--auto-download-bundletool-jar], [--no-auto-download-bundletool-jar] # (beta) 上传AAB 文件的特殊指令: upload aab file command: would download bundletool when invoke bundletool failure
|
37
|
+
-T, [--token=TOKEN] # betaqr.com(fir.im) 账户的 API_TOKEN
|
38
|
+
-L, [--logfile=LOGFILE] # Path to writable logfile
|
39
|
+
-V, [--verbose], [--no-verbose] # Show verbose
|
40
|
+
# Default: true
|
41
|
+
-q, [--quiet], [--no-quiet] # Silence commands
|
42
|
+
-h, [--help], [--no-help] # Show this help message and quit
|
43
|
+
|
44
|
+
Description:
|
45
|
+
`publish` command will publish your app file to fir.im, also the command support to publish app's short & changelog.
|
46
|
+
|
47
|
+
Example:
|
48
|
+
|
49
|
+
$ fir p <app file path> [-c <changelog> -s <custom short link> -Q -T <your api token>]
|
50
|
+
|
51
|
+
$ fir p <app file path> [-c <changelog> -s <custom short link> --password=123456 --open=false -Q -T <your api token>]
|
52
|
+
|
53
|
+
$ fir p <app file path> [-c <changelog> -s <custom short link> -m <mapping file path> -P <bughd project id> -Q -T <your
|
54
|
+
api token>]
|
24
55
|
```
|
25
56
|
|
26
|
-
相关参数详解:
|
27
57
|
|
28
|
-
- `-s` 参数, 自定义发布后的短链接地址.
|
29
|
-
- `-c` 参数, 自定义发布时的 changelog, 支持字符串与文件两种方式, 即 `--changelog='this is changelog'` 和 `--changelog='/Users/fir-cli/changelog'`.
|
30
|
-
- `-Q` 参数, 是否生成发布后二维码, 默认为不生成, 加上 `-Q` 参数后会在当前目录生成一张二维码图片, 扫描该图片即可下载该应用.
|
31
|
-
- `-R` 参数, 显示具体版本, 会在发布结束后的下载地址中生成指定的版本
|
32
|
-
- `-D` 参数, 钉钉机器人的access_token, 填写后当上传完毕, 会发送至钉钉机器人
|
33
|
-
- `--open` 参数, 设置发布后的应用是否开放给所有人下载, 关闭开放使用 `--no-open` 参数.
|
34
|
-
- `--password` 参数, 设置发布后的应用密码
|
35
58
|
|
data/fir-cli.gemspec
CHANGED
@@ -27,6 +27,11 @@ Gem::Specification.new do |spec|
|
|
27
27
|
/_/ /___/_/ |_| \____/_____/___/
|
28
28
|
|
29
29
|
## 更新记录
|
30
|
+
- (2.0.12) 修复因为钉钉机器人不再支持base64导致无法显示二维码,另外开始支持钉钉加签方式的鉴权, 参数为 --dingtalk_secret
|
31
|
+
- (2.0.11) 兼容了 ruby 3.0 版本, 增加了环境变量FEISHU_TIMEOUT,可以多给飞书一些超时时间
|
32
|
+
- (2.0.10) 飞书支持了 V2 版本的机器人推送
|
33
|
+
- (2.0.9) publish 支持了 企业微信通知 可以使用 --wxwork_access_token 或 --wxwork_webhook, 增加了回调超时时间至20秒
|
34
|
+
- (2.0.8) publish 支持 飞书通知, 可使用 `feishu_access_token` 和 `feishu_custom_message`, 详情见 `fir publish --help`
|
30
35
|
- (2.0.7) 修复了提示 token 有问题的错误
|
31
36
|
- (2.0.6) 将校验文件是否存在提前
|
32
37
|
- (2.0.5) 更换了上传域名, 避免与 深信服的设备冲突
|
@@ -49,12 +54,13 @@ Gem::Specification.new do |spec|
|
|
49
54
|
# spec.add_development_dependency 'byebug'
|
50
55
|
spec.add_development_dependency 'minitest', '~> 5.7'
|
51
56
|
spec.add_development_dependency 'pry', '~> 0.10'
|
52
|
-
|
57
|
+
|
53
58
|
spec.add_dependency 'admqr_knife', '~> 0.1.5'
|
54
59
|
spec.add_dependency 'thor', '~> 0.19'
|
55
60
|
spec.add_dependency 'rest-client', '~> 2.0'
|
56
61
|
spec.add_dependency 'ruby_android_apk', '~> 0.7.7.1'
|
57
62
|
spec.add_dependency 'rqrcode', '~> 0.7'
|
63
|
+
spec.add_dependency 'rexml'
|
58
64
|
spec.add_dependency 'CFPropertyList'
|
59
|
-
spec.add_dependency 'api_tools', '~> 0.1.
|
65
|
+
spec.add_dependency 'api_tools', '~> 0.1.1'
|
60
66
|
end
|
data/lib/fir.rb
CHANGED
data/lib/fir/api.yml
CHANGED
@@ -2,6 +2,7 @@ fir:
|
|
2
2
|
domain: 'http://www.betaqr.com'
|
3
3
|
base_url: 'http://fir-api.admqr.com'
|
4
4
|
user_url: 'http://fir-api.admqr.com/user'
|
5
|
+
user_feishu_access_token: 'http://fir-api.admqr.com/user/fetch_feishu_v3_token'
|
5
6
|
app_url: 'http://fir-api.admqr.com/apps'
|
6
7
|
udids_url: 'http://fir-api.admqr.com/devices/multi_udid'
|
7
8
|
|
data/lib/fir/cli.rb
CHANGED
@@ -125,7 +125,16 @@ module FIR
|
|
125
125
|
method_option :dingtalk_access_token, type: :string, aliases: '-D', desc: 'Send msg to dingtalk, only need access_token, not whole url'
|
126
126
|
method_option :dingtalk_custom_message, type: :string, desc: 'add custom message to dingtalk'
|
127
127
|
method_option :dingtalk_at_phones, type: :string, desc: 'at some phones, split by , eg: 13111111111,13111111112'
|
128
|
-
method_option :dingtalk_at_all, type: :boolean,
|
128
|
+
method_option :dingtalk_at_all, type: :boolean, default: false
|
129
|
+
method_option :dingtalk_secret, type: :string, desc: 'dingtalk bot secret code (eg: SEC********)'
|
130
|
+
|
131
|
+
method_option :feishu_access_token, type: :string, desc: 'Send msg to feishu, need access_token, not whole url'
|
132
|
+
method_option :feishu_custom_message, type: :string, desc: 'add custom message to feishu'
|
133
|
+
|
134
|
+
method_option :wxwork_webhook, type: :string, desc: 'wxwork webhook url (optional)'
|
135
|
+
method_option :wxwork_access_token, type: :string, desc: 'Send msg to wxwork group, need group bot webhook, not whole url'
|
136
|
+
method_option :wxwork_custom_message, type: :string, desc: 'add custom message to wxwork group'
|
137
|
+
method_option :wxwork_pic_url, type: :string, desc: 'message background image, best size is 1068x455'
|
129
138
|
|
130
139
|
method_option :open, type: :boolean, desc: 'true/false if open for everyone'
|
131
140
|
method_option :password, type: :string, desc: 'Set password for app'
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module FIR
|
2
4
|
class AppUploader
|
3
5
|
include ApiTools::DefaultRestModule
|
@@ -14,6 +16,8 @@ module FIR
|
|
14
16
|
def upload
|
15
17
|
upload_icon
|
16
18
|
binary_callback_info = upload_binary
|
19
|
+
raise binary_callback_info if binary_callback_info.is_a? StandardError
|
20
|
+
|
17
21
|
# 将 binary 的callback信息返回
|
18
22
|
binary_callback_info
|
19
23
|
end
|
@@ -21,9 +25,12 @@ module FIR
|
|
21
25
|
protected
|
22
26
|
|
23
27
|
def callback_to_api(callback_url, callback_binary_information)
|
28
|
+
logger.debug 'begin to callback api'
|
24
29
|
return if callback_binary_information.blank?
|
25
30
|
|
26
|
-
post callback_url, callback_binary_information
|
31
|
+
answer = post callback_url, callback_binary_information, timeout: 20
|
32
|
+
logger.debug 'callback api finished'
|
33
|
+
answer
|
27
34
|
end
|
28
35
|
|
29
36
|
def icon_file_path
|
@@ -74,6 +81,7 @@ module FIR
|
|
74
81
|
|
75
82
|
def callback_icon_information
|
76
83
|
return {} if icon_file_path.nil?
|
84
|
+
|
77
85
|
{
|
78
86
|
key: icon_cert[:key],
|
79
87
|
token: icon_cert[:token],
|
@@ -106,6 +114,5 @@ module FIR
|
|
106
114
|
def logger
|
107
115
|
FIR.logger
|
108
116
|
end
|
109
|
-
|
110
117
|
end
|
111
|
-
end
|
118
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'openssl'
|
3
|
+
require 'base64'
|
4
|
+
require 'cgi'
|
5
|
+
# require 'byebug'
|
6
|
+
class DingtalkHelper
|
7
|
+
attr_accessor :app_info, :options, :access_token, :qrcode_path, :image_key, :download_url, :title
|
8
|
+
include FIR::Config
|
9
|
+
|
10
|
+
def initialize(app_info, options, qrcode_path, download_url)
|
11
|
+
@app_info = app_info
|
12
|
+
@options = options
|
13
|
+
@access_token = @options[:dingtalk_access_token]
|
14
|
+
@secret = @options[:dingtalk_secret]
|
15
|
+
@qrcode_path = qrcode_path
|
16
|
+
@download_url = download_url
|
17
|
+
end
|
18
|
+
|
19
|
+
def send_msg
|
20
|
+
return if options[:dingtalk_access_token].blank?
|
21
|
+
|
22
|
+
api_domain = @app_info[:api_url]
|
23
|
+
title = "#{@app_info[:name]}-#{@app_info[:version]}(Build #{@app_info[:build]})"
|
24
|
+
payload = {
|
25
|
+
"msgtype": 'markdown',
|
26
|
+
"markdown": {
|
27
|
+
"title": "#{title} uploaded",
|
28
|
+
"text": "#### #{title}\n\n>uploaded at #{Time.now}\n\nurl: #{download_url}\n\n#{options[:dingtalk_custom_message]}\n\n ![](#{api_domain}/welcome/qrcode?url=#{download_url})"
|
29
|
+
}
|
30
|
+
}
|
31
|
+
build_dingtalk_at_info(payload)
|
32
|
+
url = "https://oapi.dingtalk.com/robot/send?access_token=#{options[:dingtalk_access_token]}"
|
33
|
+
if options[:dingtalk_secret]
|
34
|
+
info = secret_cal(options[:dingtalk_secret])
|
35
|
+
url = "#{url}×tamp=#{info[:timestamp]}&sign=#{info[:sign]}"
|
36
|
+
end
|
37
|
+
|
38
|
+
x = DefaultRest.post(url, payload)
|
39
|
+
rescue StandardError => e
|
40
|
+
end
|
41
|
+
|
42
|
+
def build_dingtalk_at_info(payload)
|
43
|
+
answer = {}
|
44
|
+
answer[:isAtAll] = options[:dingtalk_at_all]
|
45
|
+
|
46
|
+
unless options[:dingtalk_at_phones].blank?
|
47
|
+
answer[:atMobiles] = options[:dingtalk_at_phones].split(',')
|
48
|
+
payload[:markdown][:text] += options[:dingtalk_at_phones].split(',').map { |x| "@#{x}" }.join(',')
|
49
|
+
end
|
50
|
+
|
51
|
+
payload[:at] = answer
|
52
|
+
end
|
53
|
+
|
54
|
+
def secret_cal(secret)
|
55
|
+
timestamp = Time.now.to_i * 1000
|
56
|
+
secret_enc = secret.encode('utf-8')
|
57
|
+
str = "#{timestamp}\n#{secret}"
|
58
|
+
string_to_sign_enc = str.encode('utf-8')
|
59
|
+
|
60
|
+
hmac = OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha256'), secret_enc, string_to_sign_enc)
|
61
|
+
{
|
62
|
+
timestamp: timestamp,
|
63
|
+
sign: CGI.escape(Base64.encode64(hmac).strip)
|
64
|
+
}
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'json'
|
2
|
+
# require 'byebug'
|
3
|
+
class FeishuHelper
|
4
|
+
attr_accessor :app_info, :options, :feishu_access_token, :qrcode_path, :image_key, :download_url, :title
|
5
|
+
include FIR::Config
|
6
|
+
|
7
|
+
def initialize(app_info, options, qrcode_path, download_url)
|
8
|
+
@app_info = app_info
|
9
|
+
@options = options
|
10
|
+
@feishu_access_token = @options[:feishu_access_token]
|
11
|
+
@qrcode_path = qrcode_path
|
12
|
+
@download_url = download_url
|
13
|
+
@title = "#{@app_info[:name]}-#{@app_info[:version]}(Build #{@app_info[:build]})"
|
14
|
+
end
|
15
|
+
|
16
|
+
def send_msg
|
17
|
+
return if feishu_access_token.blank?
|
18
|
+
|
19
|
+
answer = v2_request
|
20
|
+
v1_request if answer.dig('ok') == 'false'
|
21
|
+
end
|
22
|
+
|
23
|
+
def v2_request
|
24
|
+
url = "https://open.feishu.cn/open-apis/bot/v2/hook/#{feishu_access_token}"
|
25
|
+
x = build_v2_info
|
26
|
+
# byebug
|
27
|
+
DefaultRest.post(url, x, {timeout: ENV['FEISHU_TIMEOUT'] ? ENV['FEISHU_TIMEOUT'].to_i : 30 })
|
28
|
+
end
|
29
|
+
|
30
|
+
def v1_request
|
31
|
+
url = "https://open.feishu.cn/open-apis/bot/hook/#{feishu_access_token}"
|
32
|
+
payload = {
|
33
|
+
"title": "#{title} uploaded",
|
34
|
+
"text": "#{title} uploaded at #{Time.now}\nurl: #{download_url}\n#{options[:feishu_custom_message]}\n"
|
35
|
+
}
|
36
|
+
DefaultRest.post(url, payload, {timeout: ENV['FEISHU_TIMEOUT'] ? ENV['FEISHU_TIMEOUT'].to_i : 30 })
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def build_v2_info
|
42
|
+
{
|
43
|
+
msg_type: 'post',
|
44
|
+
content: {
|
45
|
+
post: {
|
46
|
+
zh_cn: {
|
47
|
+
title: title,
|
48
|
+
content: [build_info_tags, [build_image_tag]]
|
49
|
+
}
|
50
|
+
}
|
51
|
+
}
|
52
|
+
}
|
53
|
+
end
|
54
|
+
|
55
|
+
def build_info_tags
|
56
|
+
text = "#{title} uploaded at #{Time.now}\n#{options[:feishu_custom_message]}\n"
|
57
|
+
[
|
58
|
+
{
|
59
|
+
"tag": 'text',
|
60
|
+
"text": text
|
61
|
+
},
|
62
|
+
{
|
63
|
+
"tag": 'a',
|
64
|
+
"text": download_url,
|
65
|
+
"href": download_url
|
66
|
+
}
|
67
|
+
]
|
68
|
+
end
|
69
|
+
|
70
|
+
def build_image_tag
|
71
|
+
{
|
72
|
+
"tag": 'img',
|
73
|
+
"image_key": upload_qr_code,
|
74
|
+
"width": 300,
|
75
|
+
"height": 300
|
76
|
+
}
|
77
|
+
end
|
78
|
+
|
79
|
+
def fetch_image_access_token
|
80
|
+
answer = DefaultRest.post(fir_api[:fetch_feishu_v3_token] || 'http://fir-api.admqr.com/user/fetch_feishu_v3_token', {})
|
81
|
+
answer[:feishu_v3_token]
|
82
|
+
end
|
83
|
+
|
84
|
+
def upload_qr_code
|
85
|
+
answer = RestClient.post('https://open.feishu.cn/open-apis/image/v4/put/', {
|
86
|
+
image_type: 'message',
|
87
|
+
image: File.new(qrcode_path, 'rb')
|
88
|
+
}, {
|
89
|
+
'Authorization' => "Bearer #{fetch_image_access_token}"
|
90
|
+
})
|
91
|
+
|
92
|
+
json = JSON.parse(answer)
|
93
|
+
json.dig('data', 'image_key')
|
94
|
+
end
|
95
|
+
end
|
data/lib/fir/util/publish.rb
CHANGED
@@ -1,8 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# require 'byebug'
|
4
|
+
|
4
5
|
require_relative './qiniu_uploader'
|
5
6
|
require_relative './ali_uploader'
|
7
|
+
require_relative '../util/feishu_helper'
|
8
|
+
require_relative '../util/dingtalk_helper'
|
6
9
|
|
7
10
|
module FIR
|
8
11
|
module Publish
|
@@ -11,8 +14,10 @@ module FIR
|
|
11
14
|
logger_info_publishing_message
|
12
15
|
|
13
16
|
logger.info 'begin to upload ...'
|
17
|
+
logger.info "fir-cli version #{FIR::VERSION} (#{RUBY_VERSION} @ #{RUBY_PLATFORM})"
|
14
18
|
received_app_info = upload_app
|
15
19
|
|
20
|
+
|
16
21
|
short = received_app_info[:short]
|
17
22
|
download_domain = received_app_info[:download_domain]
|
18
23
|
release_id = received_app_info[:release_id]
|
@@ -25,7 +30,11 @@ module FIR
|
|
25
30
|
logger.info "Published succeed: #{download_url}"
|
26
31
|
|
27
32
|
qrcode_path = build_qrcode download_url
|
33
|
+
|
28
34
|
dingtalk_notifier(download_url, qrcode_path)
|
35
|
+
feishu_notifier(download_url, qrcode_path)
|
36
|
+
wxwork_notifier(download_url)
|
37
|
+
|
29
38
|
upload_mapping_file_with_publish
|
30
39
|
|
31
40
|
upload_fir_cli_usage_info(received_app_info)
|
@@ -190,26 +199,31 @@ module FIR
|
|
190
199
|
end
|
191
200
|
|
192
201
|
def dingtalk_notifier(download_url, qrcode_path)
|
193
|
-
|
202
|
+
DingtalkHelper.new(@app_info, options, qrcode_path, download_url).send_msg
|
203
|
+
end
|
204
|
+
|
205
|
+
def feishu_notifier(download_url, qrcode_path)
|
206
|
+
FeishuHelper.new(@app_info, options, qrcode_path, download_url).send_msg
|
207
|
+
end
|
208
|
+
|
209
|
+
def wxwork_notifier(download_url)
|
210
|
+
webhook_url = options[:wxwork_webhook]
|
211
|
+
webhook_url ||= "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=#{options[:wxwork_access_token]}"
|
212
|
+
return if webhook_url.blank?
|
194
213
|
|
195
214
|
title = "#{@app_info[:name]}-#{@app_info[:version]}(Build #{@app_info[:build]})"
|
196
215
|
payload = {
|
197
|
-
"msgtype":
|
198
|
-
"
|
199
|
-
"
|
200
|
-
|
201
|
-
|
202
|
-
|
216
|
+
"msgtype": "news",
|
217
|
+
"news": {
|
218
|
+
"articles": [{
|
219
|
+
"title": "#{title} uploaded",
|
220
|
+
"description": "#{title} uploaded at #{Time.now}\nurl: #{download_url}\n#{options[:wxwork_custom_message]}\n",
|
221
|
+
"url": download_url,
|
222
|
+
"picurl": options[:wxwork_pic_url]
|
223
|
+
}],
|
224
|
+
},
|
203
225
|
}
|
204
|
-
|
205
|
-
url = "https://oapi.dingtalk.com/robot/send?access_token=#{options[:dingtalk_access_token]}"
|
206
|
-
|
207
|
-
# 用完了二维码, 就删了
|
208
|
-
File.delete(qrcode_path) unless @export_qrcode
|
209
|
-
|
210
|
-
DefaultRest.post(url, payload)
|
211
|
-
rescue StandardError => e
|
212
|
-
logger.warn "Dingtalk send error #{e.message}"
|
226
|
+
DefaultRest.post(webhook_url, payload)
|
213
227
|
end
|
214
228
|
|
215
229
|
def initialize_publish_options(args, options)
|
@@ -219,10 +233,10 @@ module FIR
|
|
219
233
|
|
220
234
|
check_file_exist(@file_path)
|
221
235
|
check_supported_file(@file_path)
|
222
|
-
|
236
|
+
|
223
237
|
@token = options[:token] || current_token
|
224
238
|
check_token_cannot_be_blank(@token)
|
225
|
-
|
239
|
+
|
226
240
|
@changelog = read_changelog(options[:changelog]).to_s.to_utf8
|
227
241
|
@short = options[:short].to_s
|
228
242
|
@passwd = options[:password].to_s
|
@@ -234,7 +248,10 @@ module FIR
|
|
234
248
|
@app_id = @uploading_info[:id]
|
235
249
|
|
236
250
|
@skip_update_icon = options[:skip_update_icon]
|
251
|
+
|
237
252
|
@force_pin_history = options[:force_pin_history]
|
253
|
+
|
254
|
+
@app_info[:api_url] = fir_api[:base_url]
|
238
255
|
unless options[:specify_icon_file].blank?
|
239
256
|
@specify_icon_file_path = File.absolute_path(options[:specify_icon_file])
|
240
257
|
end
|
@@ -247,17 +264,5 @@ module FIR
|
|
247
264
|
end
|
248
265
|
|
249
266
|
|
250
|
-
|
251
|
-
def build_dingtalk_at_info(payload)
|
252
|
-
answer = {}
|
253
|
-
answer[:isAtAll] = options[:dingtalk_at_all]
|
254
|
-
|
255
|
-
unless options[:dingtalk_at_phones].blank?
|
256
|
-
answer[:atMobiles] = options[:dingtalk_at_phones].split(',')
|
257
|
-
payload[:markdown][:text] += options[:dingtalk_at_phones].split(',').map { |x| "@#{x}" }.join(',')
|
258
|
-
end
|
259
|
-
|
260
|
-
payload[:at] = answer
|
261
|
-
end
|
262
267
|
end
|
263
268
|
end
|
data/lib/fir/version.rb
CHANGED
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fir-cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.12
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- NaixSpirit
|
8
8
|
- atpking
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2021-02-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -137,6 +137,20 @@ dependencies:
|
|
137
137
|
- - "~>"
|
138
138
|
- !ruby/object:Gem::Version
|
139
139
|
version: '0.7'
|
140
|
+
- !ruby/object:Gem::Dependency
|
141
|
+
name: rexml
|
142
|
+
requirement: !ruby/object:Gem::Requirement
|
143
|
+
requirements:
|
144
|
+
- - ">="
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
version: '0'
|
147
|
+
type: :runtime
|
148
|
+
prerelease: false
|
149
|
+
version_requirements: !ruby/object:Gem::Requirement
|
150
|
+
requirements:
|
151
|
+
- - ">="
|
152
|
+
- !ruby/object:Gem::Version
|
153
|
+
version: '0'
|
140
154
|
- !ruby/object:Gem::Dependency
|
141
155
|
name: CFPropertyList
|
142
156
|
requirement: !ruby/object:Gem::Requirement
|
@@ -157,14 +171,14 @@ dependencies:
|
|
157
171
|
requirements:
|
158
172
|
- - "~>"
|
159
173
|
- !ruby/object:Gem::Version
|
160
|
-
version: 0.1.
|
174
|
+
version: 0.1.1
|
161
175
|
type: :runtime
|
162
176
|
prerelease: false
|
163
177
|
version_requirements: !ruby/object:Gem::Requirement
|
164
178
|
requirements:
|
165
179
|
- - "~>"
|
166
180
|
- !ruby/object:Gem::Version
|
167
|
-
version: 0.1.
|
181
|
+
version: 0.1.1
|
168
182
|
description: fir.im command tool, support iOS and Android
|
169
183
|
email:
|
170
184
|
- atpking@gmail.com
|
@@ -218,6 +232,8 @@ files:
|
|
218
232
|
- lib/fir/util/build_common.rb
|
219
233
|
- lib/fir/util/build_ipa.rb
|
220
234
|
- lib/fir/util/config.rb
|
235
|
+
- lib/fir/util/dingtalk_helper.rb
|
236
|
+
- lib/fir/util/feishu_helper.rb
|
221
237
|
- lib/fir/util/http.rb
|
222
238
|
- lib/fir/util/info.rb
|
223
239
|
- lib/fir/util/login.rb
|
@@ -254,18 +270,23 @@ metadata: {}
|
|
254
270
|
post_install_message: "\n ______________ ________ ____\n /
|
255
271
|
____/ _/ __ \\ / ____/ / / _/\n / /_ / // /_/ /_____/ / / / /
|
256
272
|
/\n / __/ _/ // _, _/_____/ /___/ /____/ /\n /_/ /___/_/ |_| \\____/_____/___/\n\n
|
257
|
-
\ ## 更新记录\n - (2.0.
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
`
|
266
|
-
|
267
|
-
publish
|
268
|
-
|
273
|
+
\ ## 更新记录\n - (2.0.12) 修复因为钉钉机器人不再支持base64导致无法显示二维码,另外开始支持钉钉加签方式的鉴权, 参数为 --dingtalk_secret\n
|
274
|
+
\ - (2.0.11) 兼容了 ruby 3.0 版本, 增加了环境变量FEISHU_TIMEOUT,可以多给飞书一些超时时间\n - (2.0.10) 飞书支持了
|
275
|
+
V2 版本的机器人推送\n - (2.0.9) publish 支持了 企业微信通知 可以使用 --wxwork_access_token 或 --wxwork_webhook,
|
276
|
+
增加了回调超时时间至20秒\n - (2.0.8) publish 支持 飞书通知, 可使用 `feishu_access_token` 和 `feishu_custom_message`,
|
277
|
+
详情见 `fir publish --help`\n - (2.0.7) 修复了提示 token 有问题的错误\n - (2.0.6) 将校验文件是否存在提前\n
|
278
|
+
\ - (2.0.5) 更换了上传域名, 避免与 深信服的设备冲突\n - (2.0.4) 修复了 cdn 不支持 patch 方法透传, 导致在修改 app
|
279
|
+
信息的时候返回的 400 错误\n - (2.0.3) 增加 dingtalk_at_phones, 钉钉通知可 at 用户手机号, 以逗号,分割. 此命令需配合
|
280
|
+
`dingtalk_access_token` 使用\n - (2.0.3) 增加 dingtalk_at_all, 钉钉通知可 at 所有人, 此命令需配合
|
281
|
+
`dingtalk_access_token` 使用\n - (2.0.3) publish 增加海外加速参数 --oversea_turbo\n - (2.0.2)
|
282
|
+
有限支持 aab 文件上传, 强依赖`bundletool`工具, 具体请参见参数 `--bundletool_jar_path` 和 `auto_download_bundletool_jar`\n
|
283
|
+
\ - (2.0.1) publish 支持 新参数 `specify_app_display_name`, 指定 app 显示名称\n - (2.0.1)
|
284
|
+
publish 支持 新参数 `need_ansi_qrcode`, 在控制台直接打印二维码, jenkins 用户可能需要使用 `AnsiColor Plugin`
|
285
|
+
插件配合\n - (2.0.1) publish 支持 新参数 `dingtalk_custom_message`, 可以在钉钉通知里增加自定义消息, 此命令需配合
|
286
|
+
`dingtalk_access_token` 使用\n - (2.0.1) publish 支持 新参数 `skip_fir_cli_feedback`,
|
287
|
+
可禁止 fir-cli 发送统计信息\n - (2.0.0) publish 使用更快的存储商, 加速上传速度, 若感觉没以前可使用 switch_to_qiniu
|
288
|
+
恢复\n - [fir-cli](https://github.com/firhq/fir-cli) 已经开源\n - 欢迎 fork, issue 和 pull
|
289
|
+
request\n "
|
269
290
|
rdoc_options: []
|
270
291
|
require_paths:
|
271
292
|
- lib
|
@@ -281,7 +302,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
281
302
|
version: '0'
|
282
303
|
requirements: []
|
283
304
|
rubygems_version: 3.0.3
|
284
|
-
signing_key:
|
305
|
+
signing_key:
|
285
306
|
specification_version: 4
|
286
307
|
summary: fir.im command tool
|
287
308
|
test_files:
|