fir-cli 2.0.8 → 2.0.13

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9850b88e681117a4ca51cbbb03a4a763b9988e0bbbe9a71240ce4be0c0d3af8e
4
- data.tar.gz: 7216bcba798d427464cea462fd51c01547930478eb173a145d8395c2e1c3b4c2
3
+ metadata.gz: 8320833a429e9d6ffafbe6feacc844f1351c987c901eeac424adbaa2b4d95c8b
4
+ data.tar.gz: 6009124d94abd0d307350faeebd78fa60cfaf7b4cb93ba8d437545f885d4f2aa
5
5
  SHA512:
6
- metadata.gz: c296355543864f8b42c21c356a54d8c297aa4f3cc31ac0df0e94a3e9a6a54aaca68a8d1970052cb4106b102d42eb0ac8fe82618c860b787adbd85b6dba9c2083
7
- data.tar.gz: 8c5beba65c8401c85a87f1b8437682133fdec9c9ad95441df4c8ac4ef199044ec23aacc105aa72bef21c046e4699de9e14616254406eeac9cf664b6be419e7e7
6
+ metadata.gz: e580eeb77c1b70129c819d44543991afa1164f93939459877791bb29b3d933c11834b4febf298976a3f149d83972df0acdc09044ba609228d869d34fe176b904
7
+ data.tar.gz: 0b1fc894b5aef760d0848184a5dd942e98b1d6f3aa0968ffaf16faab3bffd4f76e4c94a4780b50c10083278dd3f4f5a9bb70e7dfda30d23f255f41b008c0e346
data/.travis.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  rvm:
2
- - 2.4
2
+ - 3.0
3
3
  env:
4
4
  matrix:
5
5
  - USE_OFFICIAL_GEM_SOURCE=true
data/Dockerfile CHANGED
@@ -1,4 +1,4 @@
1
- FROM ruby:2.6.1
1
+ FROM ruby:2.7.1
2
2
  RUN gem install bundler
3
3
  ENV LANG=C.UTF-8
4
4
  ENV WORKDIR=/fir-cli
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,12 +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
- - 深信服 的 上网行为管理AC 的域名黑名单误将 fir-cli version 2.0.4 版本使用的 api.bq04.com 加入了黑名单, 我们已经联系了 深信服, 他们的回答是 `收到!已反馈!预计在3月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
  # 最近更新
21
- - (2.0.8) publish 支持 飞书通知, 可使用 `feishu_access_token` 和 `feishu_custom_message`
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`
22
25
  - (2.0.7) 修复了提示 token 错误的问题
23
26
  - (2.0.6) 修复了因为文件读取方式变化而导致的文件找不到不报错的问题
24
27
  - (2.0.5) 因为深信服 的黑名单误判, 将 api 切换到了备用域名
@@ -46,24 +49,49 @@ fir.im-cli 可以通过指令查看, 上传, iOS/Android 应用.
46
49
 
47
50
  ## 热门问题
48
51
 
49
- ### 如何配合 jenkins 使用?
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 使用?
50
74
 
51
75
  参见 blog [http://blog.betaqr.com/use-fir-cli-in-jenkins/](http://blog.betaqr.com/use-fir-cli-in-jenkins/)
52
76
 
53
- ### Circle CI, Travis CI 或 Github Actions 等境外服务上, 有概率超时, 能否解决?
77
+ 这里有个快速检查脚本, 可以在 jenkins 中新建一个 脚本, 进行检查
54
78
 
55
- 2.0.3 版本 及其以上, 可以申请海外加速内测资格, 开启后可以使用海外加速上传
79
+ ```
80
+ #!/bin/bash --login
56
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 的版本
57
86
 
58
- 由于监管要求, 我们必须将服务于存储放置在境内. 由于众所周知的原因, 国内外连通性的表现不太好, 虽然我们的存储服务商 阿里云 提供了 OSS 境外加速服务, 但是高达 1.25 元/GB 的传输成本确实我们也没办法负担.
87
+ # 在这里执行 fir publish xxxxx
88
+ ```
59
89
 
60
90
 
91
+ ### 在 Circle CI, Travis CI 或 Github Actions 等境外服务上, 有概率超时, 能否解决?
61
92
 
62
- 目前我们提供三种临时解决方案来缓解问题(2.0.2以下版本):
93
+ 2.0.3 版本 及其以上, 可以申请海外加速内测资格, 开启后可以使用海外加速上传 `--oversea_turbo`
63
94
 
64
- 1. 设置较长的超时时间 如 `FIR_TIMEOUT=300 fir publish xxxx`, 则可将超时时间设置为 300 秒.
65
- 2. 如果fir-cli 版本 >= 2.0.0, 也可在出现超时后, 使用 `--switch-to-qiniu` 来切换到我们的另外一条存储线路. 如 `fir publish xxxx.apk --switch-to-qiniu`, 多一条线路备选.
66
- 3. 如果确实对这方面服务要求很高, 则可购买我们的私有部署服务. 我们可以在 aws 上部署一套专供您使用, 具体情况可以与客服或者加我微信进行沟通.
67
95
 
68
96
  更多细节请参考 [https://github.com/FIRHQ/fir-cli/issues/260](https://github.com/FIRHQ/fir-cli/issues/260)
69
97
 
@@ -92,13 +120,13 @@ fir-cli 提供对 aab 文件有限程度支持的上传与下载. 在使用 fir-
92
120
 
93
121
  ### 我想将 我上传的版本展示在下载的页面上
94
122
 
95
- 可以在 publish 的时候使用 --force_pin_history 这样 这个上传的版本即成为 "历史版本", 会在下载页面里一直显示. 当有新的版本上传后, 这个版本会作为 "历史版本" 在下载页面中展示.
123
+ 可以在 publish 的时候使用 --force_pin_history 这样 这个上传的版本即成为 "历史版本", 会在下载页面里一直显示. 当有新的版本上传后, 这个版本会作为 "历史版本" 在下载页面中展示.
96
124
 
97
125
  当版本设置为历史版本后, 用户可以直接下载指定的版本, 由于因成本原因, 一个 app 最多的 "历史版本" 为 30 个, 如果有用户有特殊需求, 可以与我们取得联系进行单独修改
98
126
 
99
127
  当达到上限后, 如果继续标记 force_pin_history, 则历史版本的最老版本(以上传时间为准)会被移出历史版本列表
100
128
 
101
- ### 境外上传老出现 stream closed
129
+ ### 境外上传老出现 stream closed
102
130
 
103
131
  因为网络时延问题, 可传入环境变量 `FIR_TIMEOUT=xxx` 进行超时时间设置
104
132
 
@@ -113,22 +141,22 @@ fir-cli 提供对 aab 文件有限程度支持的上传与下载. 在使用 fir-
113
141
  - [fir publish 发布应用到 fir.im](https://github.com/FIRHQ/fir-cli/blob/master/doc/publish.md)
114
142
  - [fir upgrade 升级相关](https://github.com/FIRHQ/fir-cli/blob/master/doc/upgrade.md)
115
143
 
116
- ## Docker 运行 fir-cli
144
+ ## Docker 运行 fir-cli
117
145
 
118
146
  ### 准备工作
119
147
  1. 将自己需要的文件挂载到 docker 中, 之后即可直接运行
120
- 2. 将自己的 API_TOKEN 以环境变量的形式传入container
148
+ 2. 将自己的 API_TOKEN 以环境变量的形式传入container
121
149
 
122
150
  ### 如何运行
123
151
 
124
- 假设 我需要上传桌面的 1.apk
152
+ 假设 我需要上传桌面的 1.apk
125
153
 
126
154
  ```
127
- 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/你的文件
128
156
 
129
157
  # 如 `docker run -e API_TOKEN=xxxxxxxe -v /Users/atpking/Desktop:/tmp firhq/fir-cli:latest publish /tmp/1.apk`
130
158
 
131
- # 实际含义是把我的桌面挂载到 docker 里的 /tmp 目录 之后上传 docker 文件里的 /tmp/1.apk
159
+ # 实际含义是把我的桌面挂载到 docker 里的 /tmp 目录 之后上传 docker 文件里的 /tmp/1.apk
132
160
  # 也可以修改为其他目录
133
161
  ```
134
162
 
@@ -136,13 +164,13 @@ docker run -e API_TOKEN=您的token -v 您的上传文件的目录的绝对路
136
164
 
137
165
  - 联系微信 `atpking`, 请注明 "fir-cli 交流"
138
166
 
139
- - 使用 Github 的 [Issue](https://github.com/FIRHQ/fir-cli/issues)
167
+ - 使用 Github 的 [Issue](https://github.com/FIRHQ/fir-cli/issues)
140
168
 
141
- ## 特别感谢
169
+ ## 特别感谢
142
170
 
143
171
  - 感谢 sparkrico 提供修正的 https://github.com/sparkrico/ruby_apk 解决了 android 解析的问题
144
-
172
+ - 感谢 fabcz 同学对企业微信的通知的支持 https://github.com/FIRHQ/fir-cli/pull/277
145
173
 
146
174
  ## 鼓励维护
147
175
 
148
- 挂了好久没都人鼓励维护, 想想算了吧
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] # Set custom short link
12
- -c, [--changelog=CHANGELOG] # Set changelog
13
- -Q, [--qrcode], [--no-qrcode] # Generate qrcode
14
- [--open], [--no-open] # true/false if open for everyone
15
- [--password=PASSWORD] # Set password for app
16
- -T, [--token=TOKEN] # User's API Token at fir.im
17
- -L, [--logfile=LOGFILE] # Path to writable logfile
18
- -R, [--need_release_id] # show release_id in download_url
19
- -D, [--dingtalk_accesss_token=DINGTALK_ACCESS_TOKEN] # dingtalk notification
20
- -V, [--verbose], [--no-verbose] # Show verbose
21
- # Default: true
22
- -q, [--quiet], [--no-quiet] # Silence commands
23
- -h, [--help], [--no-help] # Show this help message and quit
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.13) 修复了无法跳过企业微信通知逻辑的bug
31
+ - (2.0.12) 修复因为钉钉机器人不再支持base64导致无法显示二维码,另外开始支持钉钉加签方式的鉴权, 参数为 --dingtalk_secret
32
+ - (2.0.11) 兼容了 ruby 3.0 版本, 增加了环境变量FEISHU_TIMEOUT,可以多给飞书一些超时时间
33
+ - (2.0.10) 飞书支持了 V2 版本的机器人推送
34
+ - (2.0.9) publish 支持了 企业微信通知 可以使用 --wxwork_access_token 或 --wxwork_webhook, 增加了回调超时时间至20秒
30
35
  - (2.0.8) publish 支持 飞书通知, 可使用 `feishu_access_token` 和 `feishu_custom_message`, 详情见 `fir publish --help`
31
36
  - (2.0.7) 修复了提示 token 有问题的错误
32
37
  - (2.0.6) 将校验文件是否存在提前
@@ -50,12 +55,13 @@ Gem::Specification.new do |spec|
50
55
  # spec.add_development_dependency 'byebug'
51
56
  spec.add_development_dependency 'minitest', '~> 5.7'
52
57
  spec.add_development_dependency 'pry', '~> 0.10'
53
-
58
+
54
59
  spec.add_dependency 'admqr_knife', '~> 0.1.5'
55
60
  spec.add_dependency 'thor', '~> 0.19'
56
61
  spec.add_dependency 'rest-client', '~> 2.0'
57
62
  spec.add_dependency 'ruby_android_apk', '~> 0.7.7.1'
58
63
  spec.add_dependency 'rqrcode', '~> 0.7'
64
+ spec.add_dependency 'rexml'
59
65
  spec.add_dependency 'CFPropertyList'
60
- spec.add_dependency 'api_tools', '~> 0.1.0'
66
+ spec.add_dependency 'api_tools', '~> 0.1.1'
61
67
  end
data/lib/fir.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # require 'byebug'
3
4
  require 'thor'
4
5
  require 'logger'
5
6
  require 'yaml'
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,11 +125,17 @@ 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, default: false
128
+ method_option :dingtalk_at_all, type: :boolean, default: false
129
+ method_option :dingtalk_secret, type: :string, desc: 'dingtalk bot secret code (eg: SEC********)'
129
130
 
130
131
  method_option :feishu_access_token, type: :string, desc: 'Send msg to feishu, need access_token, not whole url'
131
132
  method_option :feishu_custom_message, type: :string, desc: 'add custom message to feishu'
132
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'
138
+
133
139
  method_option :open, type: :boolean, desc: 'true/false if open for everyone'
134
140
  method_option :password, type: :string, desc: 'Set password for app'
135
141
 
@@ -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}&timestamp=#{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
@@ -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,6 +14,7 @@ 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
 
16
20
  short = received_app_info[:short]
@@ -25,9 +29,10 @@ module FIR
25
29
  logger.info "Published succeed: #{download_url}"
26
30
 
27
31
  qrcode_path = build_qrcode download_url
28
-
32
+
29
33
  dingtalk_notifier(download_url, qrcode_path)
30
- feishu_notifier(download_url)
34
+ feishu_notifier(download_url, qrcode_path)
35
+ wxwork_notifier(download_url)
31
36
 
32
37
  upload_mapping_file_with_publish
33
38
 
@@ -91,9 +96,7 @@ module FIR
91
96
  app_info_dict
92
97
  rescue StandardError => e
93
98
  puts e.message
94
- if e.respond_to?(e.response) && e.respond_to?(e.response.body)
95
- puts e.response.body
96
- end
99
+ puts e.response.body if e.respond_to?(e.response) && e.respond_to?(e.response.body)
97
100
  raise e
98
101
  end
99
102
 
@@ -193,37 +196,32 @@ module FIR
193
196
  end
194
197
 
195
198
  def dingtalk_notifier(download_url, qrcode_path)
196
- return if options[:dingtalk_access_token].blank?
199
+ DingtalkHelper.new(@app_info, options, qrcode_path, download_url).send_msg
200
+ end
197
201
 
198
- title = "#{@app_info[:name]}-#{@app_info[:version]}(Build #{@app_info[:build]})"
199
- payload = {
200
- "msgtype": 'markdown',
201
- "markdown": {
202
- "title": "#{title} uploaded",
203
- "text": "#{title} uploaded at #{Time.now}\nurl: #{download_url}\n#{options[:dingtalk_custom_message]}\n![app二维码](data:image/png;base64,#{Base64.strict_encode64(File.read(open(qrcode_path)))})"
204
- # "text": "#{title} uploaded at #{Time.now}\nurl: #{download_url}\n#{options[:dingtalk_custom_message]}\n"
205
- }
206
- }
207
- build_dingtalk_at_info(payload)
208
- url = "https://oapi.dingtalk.com/robot/send?access_token=#{options[:dingtalk_access_token]}"
202
+ def feishu_notifier(download_url, qrcode_path)
203
+ FeishuHelper.new(@app_info, options, qrcode_path, download_url).send_msg
204
+ end
209
205
 
210
- # 用完了二维码, 就删了
211
- File.delete(qrcode_path) unless @export_qrcode
206
+ def wxwork_notifier(download_url)
207
+ return if options[:wxwork_webhook].blank? && options[:wxwork_access_token].blank?
212
208
 
213
- DefaultRest.post(url, payload)
214
- rescue StandardError => e
215
- logger.warn "Dingtalk send error #{e.message}"
216
- end
209
+ webhook_url = options[:wxwork_webhook]
210
+ webhook_url ||= "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=#{options[:wxwork_access_token]}"
217
211
 
218
- def feishu_notifier(download_url)
219
- return if options[:feishu_access_token].blank?
220
212
  title = "#{@app_info[:name]}-#{@app_info[:version]}(Build #{@app_info[:build]})"
221
- url = "https://open.feishu.cn/open-apis/bot/hook/#{options[:feishu_access_token]}"
222
213
  payload = {
223
- "title": "#{title} uploaded",
224
- "text": "#{title} uploaded at #{Time.now}\nurl: #{download_url}\n#{options[:feishu_custom_message]}\n"
214
+ "msgtype": 'news',
215
+ "news": {
216
+ "articles": [{
217
+ "title": "#{title} uploaded",
218
+ "description": "#{title} uploaded at #{Time.now}\nurl: #{download_url}\n#{options[:wxwork_custom_message]}\n",
219
+ "url": download_url,
220
+ "picurl": options[:wxwork_pic_url]
221
+ }]
222
+ }
225
223
  }
226
- DefaultRest.post(url, payload)
224
+ DefaultRest.post(webhook_url, payload)
227
225
  end
228
226
 
229
227
  def initialize_publish_options(args, options)
@@ -233,10 +231,10 @@ module FIR
233
231
 
234
232
  check_file_exist(@file_path)
235
233
  check_supported_file(@file_path)
236
-
234
+
237
235
  @token = options[:token] || current_token
238
236
  check_token_cannot_be_blank(@token)
239
-
237
+
240
238
  @changelog = read_changelog(options[:changelog]).to_s.to_utf8
241
239
  @short = options[:short].to_s
242
240
  @passwd = options[:password].to_s
@@ -248,7 +246,10 @@ module FIR
248
246
  @app_id = @uploading_info[:id]
249
247
 
250
248
  @skip_update_icon = options[:skip_update_icon]
249
+
251
250
  @force_pin_history = options[:force_pin_history]
251
+
252
+ @app_info[:api_url] = fir_api[:base_url]
252
253
  unless options[:specify_icon_file].blank?
253
254
  @specify_icon_file_path = File.absolute_path(options[:specify_icon_file])
254
255
  end
@@ -259,19 +260,5 @@ module FIR
259
260
 
260
261
  File.exist?(changelog) ? File.read(changelog) : changelog
261
262
  end
262
-
263
-
264
-
265
- def build_dingtalk_at_info(payload)
266
- answer = {}
267
- answer[:isAtAll] = options[:dingtalk_at_all]
268
-
269
- unless options[:dingtalk_at_phones].blank?
270
- answer[:atMobiles] = options[:dingtalk_at_phones].split(',')
271
- payload[:markdown][:text] += options[:dingtalk_at_phones].split(',').map { |x| "@#{x}" }.join(',')
272
- end
273
-
274
- payload[:at] = answer
275
- end
276
263
  end
277
264
  end
data/lib/fir/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module FIR
4
- VERSION = '2.0.8'
4
+ VERSION = '2.0.13'
5
5
  end
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.8
4
+ version: 2.0.13
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: 2020-03-17 00:00:00.000000000 Z
12
+ date: 2021-04-25 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.0
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.0
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,17 +270,20 @@ metadata: {}
254
270
  post_install_message: "\n ______________ ________ ____\n /
255
271
  ____/ _/ __ \\ / ____/ / / _/\n / /_ / // /_/ /_____/ / / / /
256
272
  /\n / __/ _/ // _, _/_____/ /___/ /____/ /\n /_/ /___/_/ |_| \\____/_____/___/\n\n
257
- \ ## 更新记录\n - (2.0.8) publish 支持 飞书通知, 可使用 `feishu_access_token` 和 `feishu_custom_message`,
258
- 详情见 `fir publish --help`\n - (2.0.7) 修复了提示 token 有问题的错误\n - (2.0.6) 将校验文件是否存在提前\n
259
- \ - (2.0.5) 更换了上传域名, 避免与 深信服的设备冲突\n - (2.0.4) 修复了 cdn 不支持 patch 方法透传, 导致在修改 app
260
- 信息的时候返回的 400 错误\n - (2.0.3) 增加 dingtalk_at_phones, 钉钉通知可 at 用户手机号, 以逗号,分割. 此命令需配合
261
- `dingtalk_access_token` 使用\n - (2.0.3) 增加 dingtalk_at_all, 钉钉通知可 at 所有人, 此命令需配合
262
- `dingtalk_access_token` 使用\n - (2.0.3) publish 增加海外加速参数 --oversea_turbo\n - (2.0.2)
263
- 有限支持 aab 文件上传, 强依赖`bundletool`工具, 具体请参见参数 `--bundletool_jar_path` `auto_download_bundletool_jar`\n
264
- \ - (2.0.1) publish 支持 新参数 `specify_app_display_name`, 指定 app 显示名称\n - (2.0.1)
265
- publish 支持 新参数 `need_ansi_qrcode`, 在控制台直接打印二维码, jenkins 用户可能需要使用 `AnsiColor Plugin`
266
- 插件配合\n - (2.0.1) publish 支持 新参数 `dingtalk_custom_message`, 可以在钉钉通知里增加自定义消息, 此命令需配合
267
- `dingtalk_access_token` 使用\n - (2.0.1) publish 支持 新参数 `skip_fir_cli_feedback`,
273
+ \ ## 更新记录\n - (2.0.13) 修复了无法跳过企业微信通知逻辑的bug\n - (2.0.12) 修复因为钉钉机器人不再支持base64导致无法显示二维码,另外开始支持钉钉加签方式的鉴权,
274
+ 参数为 --dingtalk_secret\n - (2.0.11) 兼容了 ruby 3.0 版本, 增加了环境变量FEISHU_TIMEOUT,可以多给飞书一些超时时间\n
275
+ \ - (2.0.10) 飞书支持了 V2 版本的机器人推送\n - (2.0.9) publish 支持了 企业微信通知 可以使用 --wxwork_access_token
276
+ --wxwork_webhook, 增加了回调超时时间至20秒\n - (2.0.8) publish 支持 飞书通知, 可使用 `feishu_access_token`
277
+ `feishu_custom_message`, 详情见 `fir publish --help`\n - (2.0.7) 修复了提示 token 有问题的错误\n
278
+ \ - (2.0.6) 将校验文件是否存在提前\n - (2.0.5) 更换了上传域名, 避免与 深信服的设备冲突\n - (2.0.4) 修复了 cdn
279
+ 不支持 patch 方法透传, 导致在修改 app 信息的时候返回的 400 错误\n - (2.0.3) 增加 dingtalk_at_phones, 钉钉通知可
280
+ at 用户手机号, 以逗号,分割. 此命令需配合 `dingtalk_access_token` 使用\n - (2.0.3) 增加 dingtalk_at_all,
281
+ 钉钉通知可 at 所有人, 此命令需配合 `dingtalk_access_token` 使用\n - (2.0.3) publish 增加海外加速参数 --oversea_turbo\n
282
+ \ - (2.0.2) 有限支持 aab 文件上传, 强依赖`bundletool`工具, 具体请参见参数 `--bundletool_jar_path`
283
+ `auto_download_bundletool_jar`\n - (2.0.1) publish 支持 新参数 `specify_app_display_name`,
284
+ 指定 app 显示名称\n - (2.0.1) publish 支持 新参数 `need_ansi_qrcode`, 在控制台直接打印二维码, jenkins
285
+ 用户可能需要使用 `AnsiColor Plugin` 插件配合\n - (2.0.1) publish 支持 新参数 `dingtalk_custom_message`,
286
+ 可以在钉钉通知里增加自定义消息, 此命令需配合 `dingtalk_access_token` 使用\n - (2.0.1) publish 支持 新参数 `skip_fir_cli_feedback`,
268
287
  可禁止 fir-cli 发送统计信息\n - (2.0.0) publish 使用更快的存储商, 加速上传速度, 若感觉没以前可使用 switch_to_qiniu
269
288
  恢复\n - [fir-cli](https://github.com/firhq/fir-cli) 已经开源\n - 欢迎 fork, issue 和 pull
270
289
  request\n "
@@ -283,7 +302,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
283
302
  version: '0'
284
303
  requirements: []
285
304
  rubygems_version: 3.0.3
286
- signing_key:
305
+ signing_key:
287
306
  specification_version: 4
288
307
  summary: fir.im command tool
289
308
  test_files: