fir-cli 2.0.8 → 2.0.13

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 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: