Over The Air Server for deployment of Android, iOS and macOS apps

Overview

Zealot

GitHub release Docker Pulls Maintainability Codacy Badge License

开源自部署 iOS、Android 及 macOS 应用分发平台,提供 iOS、Android SDK、fastlane 等丰富组件库,打包分发流程、上传应用竟然如此简单、独立部署解决企业使用的烦恼。 En Taro Adun! 🖖

Zealot Showcase

特性

  • 支持 iOS、Android 和 macOS 应用的上传、在线安装和本地下载
  • 支持创建类型(Debug、AdHoc、Release)及渠道(小米商店等)
  • 支持自定义网络钩子通知各种服务(钉钉、企业微信、Slack 等)
  • 支持 iOS dSYM 和 Android Progruard 文件的解析和上传
  • 支持应用解包(甚至 mobileprovision 文件)存储和分享
  • 支持一键登录(已接入飞书、Gitlab、Google 和 LDAP)
  • 提供检查新版本和安装服务的 iOS 和 Android 组件
  • 提供获取 iOS 设备标识符并显示支持安装的应用列表
  • 提供丰富的 fastlane 插件 zealot
  • 可接入 Gitlab 服务直接挂钩源码管理
  • 可接入 Jenkins 服务实现远程构建
  • 支持丰富的 REST APIs
  • 支持 GraphQL 接口(进行中)

在线演示

注意: 数据每日都会重新初始化,不对用户上传的应用承担任何法律风险,后果自负!

快速部署

$ git clone https://github.com/tryzealot/zealot-docker.git
$ cd zealot-docker
$ ./deploy

按照部署脚本可以快速部署系统服务,如需自定义其他配置请看项目配置

最佳实践

如果想知道使用 Zealot 如何全流程无缝 CI/CD 接入 iOS 和 Android 请看实践教程

帮助和文档

你可以查看更多的功能截图:

https://zealot.ews.im/#/screenshot

你可以了解下支持什么插件:

https://zealot.ews.im/#/modules

你可以了解提供的 HTTP API 接口:

https://zealot.ews.im/#/api

你可以了解变更日志:

https://zealot.ews.im/#/changelog

对于项目细节感兴趣就来看看翻翻文档:

https://zealot.ews.im

对 Zealot 有疑问或者建议,欢迎提交问题,我会非常欢迎的。

Comments
  • NoMethodError: undefined method `split' for nil:NilClass

    NoMethodError: undefined method `split' for nil:NilClass

    部署方式 | How to Deploy

    Docker (Default)

    部署版本 | Version

    latest

    反代服务 | Reverse Proxy

    nginx

    已阅读文档 | Read the document

    • [X] 已阅读 | Yes

    描述 | Description

    一开始,系统只接入了一个IOS应用,运行比较稳定,后面新加入了一个ios应用,在发布较频繁的时候,很容易就把服务器搞崩溃,看了下后台任务监控信息如下(不知是不是失败重试导致服务器崩溃,目前我这里只能靠重启服务器解决):

    失败面板image

    重试面板image

    信息面板image

    大佬,能不能帮忙看看,这一般是啥情况引起的?

    问题日志 | Relevant log output

    近100条日志(需要更多我再查):
    
    /app/vendor/bundle/ruby/2.7.0/gems/sidekiq-6.3.1/lib/sidekiq/processor.rb:131:in `block (4 levels) in dispatch'
    /app/vendor/bundle/ruby/2.7.0/gems/sidekiq-6.3.1/lib/sidekiq/processor.rb:257:in `stats'
    /app/vendor/bundle/ruby/2.7.0/gems/sidekiq-6.3.1/lib/sidekiq/processor.rb:126:in `block (3 levels) in dispatch'
    /app/vendor/bundle/ruby/2.7.0/gems/sidekiq-6.3.1/lib/sidekiq/job_logger.rb:13:in `call'
    /app/vendor/bundle/ruby/2.7.0/gems/sidekiq-6.3.1/lib/sidekiq/processor.rb:125:in `block (2 levels) in dispatch'
    /app/vendor/bundle/ruby/2.7.0/gems/sidekiq-6.3.1/lib/sidekiq/job_retry.rb:79:in `global'
    /app/vendor/bundle/ruby/2.7.0/gems/sidekiq-6.3.1/lib/sidekiq/processor.rb:124:in `block in dispatch'
    /app/vendor/bundle/ruby/2.7.0/gems/sidekiq-6.3.1/lib/sidekiq/logger.rb:11:in `with'
    /app/vendor/bundle/ruby/2.7.0/gems/sidekiq-6.3.1/lib/sidekiq/job_logger.rb:33:in `prepare'
    /app/vendor/bundle/ruby/2.7.0/gems/sidekiq-6.3.1/lib/sidekiq/processor.rb:123:in `dispatch'
    /app/vendor/bundle/ruby/2.7.0/gems/sidekiq-6.3.1/lib/sidekiq/processor.rb:162:in `process'
    /app/vendor/bundle/ruby/2.7.0/gems/sidekiq-6.3.1/lib/sidekiq/processor.rb:78:in `process_one'
    /app/vendor/bundle/ruby/2.7.0/gems/sidekiq-6.3.1/lib/sidekiq/processor.rb:68:in `run'
    /app/vendor/bundle/ruby/2.7.0/gems/sidekiq-6.3.1/lib/sidekiq/util.rb:43:in `watchdog'
    /app/vendor/bundle/ruby/2.7.0/gems/sidekiq-6.3.1/lib/sidekiq/util.rb:52:in `block in safe_thread'
    2022-05-11T08:43:59.530Z pid=319 tid=z3j class=TeardownJob jid=f5199d5e903817816eb46cff elapsed=7.482 INFO: fail
    2022-05-11T08:43:59.530Z pid=319 tid=z3j WARN: {"context":"Job raised exception","job":{"retry":true,"queue":"app_parse","class":"ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper","wrapped":"TeardownJob","args":[{"job_class":"TeardownJob","job_id":"9f66c66d-eea6-4f25-9cad-13ddfb939ecd","provider_job_id":null,"queue_name":"app_parse","priority":null,"arguments":[539,2],"executions":0,"exception_executions":{},"locale":"zh-CN","timezone":"Beijing","enqueued_at":"2022-05-11T06:11:10Z"}],"jid":"f5199d5e903817816eb46cff","created_at":1652249470.6100562,"enqueued_at":1652258632.04842,"error_message":"undefined method `split' for nil:NilClass","error_class":"NoMethodError","failed_at":1652258639.529939,"retry_count":8,"retried_at":1652254466.520403,"processor":"e1202b56b13a:319"},"jobstr":"{\"retry\":true,\"queue\":\"app_parse\",\"class\":\"ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper\",\"wrapped\":\"TeardownJob\",\"args\":[{\"job_class\":\"TeardownJob\",\"job_id\":\"9f66c66d-eea6-4f25-9cad-13ddfb939ecd\",\"provider_job_id\":null,\"queue_name\":\"app_parse\",\"priority\":null,\"arguments\":[539,2],\"executions\":0,\"exception_executions\":{},\"locale\":\"zh-CN\",\"timezone\":\"Beijing\",\"enqueued_at\":\"2022-05-11T06:11:10Z\"}],\"jid\":\"f5199d5e903817816eb46cff\",\"created_at\":1652249470.6100562,\"enqueued_at\":1652258632.04842,\"error_message\":\"undefined method `split' for nil:NilClass\",\"error_class\":\"NoMethodError\",\"failed_at\":1652249476.7107005,\"retry_count\":8,\"retried_at\":1652254466.520403}"}
    2022-05-11T08:43:59.530Z pid=319 tid=z3j WARN: NoMethodError: undefined method `split' for nil:NilClass
    2022-05-11T08:43:59.531Z pid=319 tid=z3j WARN: /app/app/services/teardown_service.rb:81:in `block in process_ios'
    /app/app/services/teardown_service.rb:80:in `each'
    /app/app/services/teardown_service.rb:80:in `each_with_object'
    /app/app/services/teardown_service.rb:80:in `process_ios'
    /app/app/services/teardown_service.rb:34:in `process'
    /app/app/services/teardown_service.rb:20:in `call'
    /app/app/services/application_service.rb:5:in `call'
    /app/app/jobs/teardown_job.rb:9:in `perform'
    /app/vendor/bundle/ruby/2.7.0/gems/activejob-6.1.4.4/lib/active_job/execution.rb:48:in `block in perform_now'
    /app/vendor/bundle/ruby/2.7.0/gems/activesupport-6.1.4.4/lib/active_support/callbacks.rb:117:in `block in run_callbacks'
    /app/vendor/bundle/ruby/2.7.0/gems/sentry-rails-4.8.1/lib/sentry/rails/active_job.rb:16:in `block (2 levels) in included'
    /app/vendor/bundle/ruby/2.7.0/gems/activesupport-6.1.4.4/lib/active_support/callbacks.rb:126:in `instance_exec'
    /app/vendor/bundle/ruby/2.7.0/gems/activesupport-6.1.4.4/lib/active_support/callbacks.rb:126:in `block in run_callbacks'
    /app/vendor/bundle/ruby/2.7.0/gems/i18n-1.8.11/lib/i18n.rb:314:in `with_locale'
    /app/vendor/bundle/ruby/2.7.0/gems/activejob-6.1.4.4/lib/active_job/translation.rb:9:in `block (2 levels) in <module:Translation>'
    /app/vendor/bundle/ruby/2.7.0/gems/activesupport-6.1.4.4/lib/active_support/callbacks.rb:126:in `instance_exec'
    /app/vendor/bundle/ruby/2.7.0/gems/activesupport-6.1.4.4/lib/active_support/callbacks.rb:126:in `block in run_callbacks'
    /app/vendor/bundle/ruby/2.7.0/gems/activesupport-6.1.4.4/lib/active_support/core_ext/time/zones.rb:66:in `use_zone'
    /app/vendor/bundle/ruby/2.7.0/gems/activejob-6.1.4.4/lib/active_job/timezones.rb:9:in `block (2 levels) in <module:Timezones>'
    /app/vendor/bundle/ruby/2.7.0/gems/activesupport-6.1.4.4/lib/active_support/callbacks.rb:126:in `instance_exec'
    /app/vendor/bundle/ruby/2.7.0/gems/activesupport-6.1.4.4/lib/active_support/callbacks.rb:126:in `block in run_callbacks'
    /app/vendor/bundle/ruby/2.7.0/gems/activejob-6.1.4.4/lib/active_job/instrumentation.rb:21:in `block in instrument'
    /app/vendor/bundle/ruby/2.7.0/gems/activesupport-6.1.4.4/lib/active_support/notifications.rb:203:in `block in instrument'
    /app/vendor/bundle/ruby/2.7.0/gems/activesupport-6.1.4.4/lib/active_support/notifications/instrumenter.rb:24:in `instrument'
    /app/vendor/bundle/ruby/2.7.0/gems/activesupport-6.1.4.4/lib/active_support/notifications.rb:203:in `instrument'
    /app/vendor/bundle/ruby/2.7.0/gems/activejob-6.1.4.4/lib/active_job/instrumentation.rb:31:in `instrument'
    /app/vendor/bundle/ruby/2.7.0/gems/activejob-6.1.4.4/lib/active_job/instrumentation.rb:14:in `block (2 levels) in <module:Instrumentation>'
    /app/vendor/bundle/ruby/2.7.0/gems/activesupport-6.1.4.4/lib/active_support/callbacks.rb:126:in `instance_exec'
    /app/vendor/bundle/ruby/2.7.0/gems/activesupport-6.1.4.4/lib/active_support/callbacks.rb:126:in `block in run_callbacks'
    /app/vendor/bundle/ruby/2.7.0/gems/activejob-6.1.4.4/lib/active_job/logging.rb:24:in `tag_logger'
    /app/vendor/bundle/ruby/2.7.0/gems/activejob-6.1.4.4/lib/active_job/logging.rb:15:in `block (2 levels) in <module:Logging>'
    /app/vendor/bundle/ruby/2.7.0/gems/activesupport-6.1.4.4/lib/active_support/callbacks.rb:126:in `instance_exec'
    /app/vendor/bundle/ruby/2.7.0/gems/activesupport-6.1.4.4/lib/active_support/callbacks.rb:126:in `block in run_callbacks'
    /app/vendor/bundle/ruby/2.7.0/gems/activesupport-6.1.4.4/lib/active_support/callbacks.rb:137:in `run_callbacks'
    /app/vendor/bundle/ruby/2.7.0/gems/activejob-6.1.4.4/lib/active_job/execution.rb:47:in `perform_now'
    /app/vendor/bundle/ruby/2.7.0/gems/activejob-6.1.4.4/lib/active_job/execution.rb:25:in `block in execute'
    /app/vendor/bundle/ruby/2.7.0/gems/activesupport-6.1.4.4/lib/active_support/callbacks.rb:117:in `block in run_callbacks'
    /app/vendor/bundle/ruby/2.7.0/gems/activejob-6.1.4.4/lib/active_job/railtie.rb:47:in `block (4 levels) in <class:Railtie>'
    /app/vendor/bundle/ruby/2.7.0/gems/activesupport-6.1.4.4/lib/active_support/execution_wrapper.rb:88:in `wrap'
    /app/vendor/bundle/ruby/2.7.0/gems/activesupport-6.1.4.4/lib/active_support/reloader.rb:72:in `block in wrap'
    /app/vendor/bundle/ruby/2.7.0/gems/activesupport-6.1.4.4/lib/active_support/execution_wrapper.rb:84:in `wrap'
    /app/vendor/bundle/ruby/2.7.0/gems/activesupport-6.1.4.4/lib/active_support/reloader.rb:71:in `wrap'
    /app/vendor/bundle/ruby/2.7.0/gems/activejob-6.1.4.4/lib/active_job/railtie.rb:46:in `block (3 levels) in <class:Railtie>'
    /app/vendor/bundle/ruby/2.7.0/gems/activesupport-6.1.4.4/lib/active_support/callbacks.rb:126:in `instance_exec'
    /app/vendor/bundle/ruby/2.7.0/gems/activesupport-6.1.4.4/lib/active_support/callbacks.rb:126:in `block in run_callbacks'
    /app/vendor/bundle/ruby/2.7.0/gems/activesupport-6.1.4.4/lib/active_support/callbacks.rb:137:in `run_callbacks'
    /app/vendor/bundle/ruby/2.7.0/gems/activejob-6.1.4.4/lib/active_job/execution.rb:23:in `execute'
    /app/vendor/bundle/ruby/2.7.0/gems/activejob-6.1.4.4/lib/active_job/queue_adapters/sidekiq_adapter.rb:42:in `perform'
    /app/vendor/bundle/ruby/2.7.0/gems/sidekiq-6.3.1/lib/sidekiq/processor.rb:196:in `execute_job'
    /app/vendor/bundle/ruby/2.7.0/gems/sidekiq-6.3.1/lib/sidekiq/processor.rb:164:in `block (2 levels) in process'
    /app/vendor/bundle/ruby/2.7.0/gems/sidekiq-6.3.1/lib/sidekiq/middleware/chain.rb:138:in `block in invoke'
    /app/vendor/bundle/ruby/2.7.0/gems/sentry-sidekiq-4.8.1/lib/sentry/sidekiq/sentry_context_middleware.rb:7:in `call'
    /app/vendor/bundle/ruby/2.7.0/gems/sidekiq-6.3.1/lib/sidekiq/middleware/chain.rb:140:in `block in invoke'
    /app/vendor/bundle/ruby/2.7.0/gems/sidekiq-failures-1.0.1/lib/sidekiq/failures/middleware.rb:9:in `call'
    /app/vendor/bundle/ruby/2.7.0/gems/sidekiq-6.3.1/lib/sidekiq/middleware/chain.rb:140:in `block in invoke'
    /app/vendor/bundle/ruby/2.7.0/gems/sidekiq-6.3.1/lib/sidekiq/middleware/chain.rb:143:in `invoke'
    /app/vendor/bundle/ruby/2.7.0/gems/sidekiq-6.3.1/lib/sidekiq/processor.rb:163:in `block in process'
    /app/vendor/bundle/ruby/2.7.0/gems/sidekiq-6.3.1/lib/sidekiq/processor.rb:136:in `block (6 levels) in dispatch'
    /app/vendor/bundle/ruby/2.7.0/gems/sidekiq-6.3.1/lib/sidekiq/job_retry.rb:112:in `local'
    /app/vendor/bundle/ruby/2.7.0/gems/sidekiq-6.3.1/lib/sidekiq/processor.rb:135:in `block (5 levels) in dispatch'
    /app/vendor/bundle/ruby/2.7.0/gems/sidekiq-6.3.1/lib/sidekiq/rails.rb:14:in `block in call'
    /app/vendor/bundle/ruby/2.7.0/gems/activesupport-6.1.4.4/lib/active_support/execution_wrapper.rb:88:in `wrap'
    /app/vendor/bundle/ruby/2.7.0/gems/activesupport-6.1.4.4/lib/active_support/reloader.rb:72:in `block in wrap'
    /app/vendor/bundle/ruby/2.7.0/gems/activesupport-6.1.4.4/lib/active_support/execution_wrapper.rb:88:in `wrap'
    /app/vendor/bundle/ruby/2.7.0/gems/activesupport-6.1.4.4/lib/active_support/reloader.rb:71:in `wrap'
    /app/vendor/bundle/ruby/2.7.0/gems/sidekiq-6.3.1/lib/sidekiq/rails.rb:13:in `call'
    /app/vendor/bundle/ruby/2.7.0/gems/sidekiq-6.3.1/lib/sidekiq/processor.rb:131:in `block (4 levels) in dispatch'
    /app/vendor/bundle/ruby/2.7.0/gems/sidekiq-6.3.1/lib/sidekiq/processor.rb:257:in `stats'
    /app/vendor/bundle/ruby/2.7.0/gems/sidekiq-6.3.1/lib/sidekiq/processor.rb:126:in `block (3 levels) in dispatch'
    /app/vendor/bundle/ruby/2.7.0/gems/sidekiq-6.3.1/lib/sidekiq/job_logger.rb:13:in `call'
    /app/vendor/bundle/ruby/2.7.0/gems/sidekiq-6.3.1/lib/sidekiq/processor.rb:125:in `block (2 levels) in dispatch'
    /app/vendor/bundle/ruby/2.7.0/gems/sidekiq-6.3.1/lib/sidekiq/job_retry.rb:79:in `global'
    /app/vendor/bundle/ruby/2.7.0/gems/sidekiq-6.3.1/lib/sidekiq/processor.rb:124:in `block in dispatch'
    /app/vendor/bundle/ruby/2.7.0/gems/sidekiq-6.3.1/lib/sidekiq/logger.rb:11:in `with'
    /app/vendor/bundle/ruby/2.7.0/gems/sidekiq-6.3.1/lib/sidekiq/job_logger.rb:33:in `prepare'
    /app/vendor/bundle/ruby/2.7.0/gems/sidekiq-6.3.1/lib/sidekiq/processor.rb:123:in `dispatch'
    /app/vendor/bundle/ruby/2.7.0/gems/sidekiq-6.3.1/lib/sidekiq/processor.rb:162:in `process'
    /app/vendor/bundle/ruby/2.7.0/gems/sidekiq-6.3.1/lib/sidekiq/processor.rb:78:in `process_one'
    /app/vendor/bundle/ruby/2.7.0/gems/sidekiq-6.3.1/lib/sidekiq/processor.rb:68:in `run'
    /app/vendor/bundle/ruby/2.7.0/gems/sidekiq-6.3.1/lib/sidekiq/util.rb:43:in `watchdog'
    /app/vendor/bundle/ruby/2.7.0/gems/sidekiq-6.3.1/lib/sidekiq/util.rb:52:in `block in safe_thread'
    
    bug 
    opened by Cleam 18
  • ios上传报错

    ios上传报错

    web界面上传ipa会出现错误

    I, [2021-04-30T10:38:43.046464 #325] INFO -- : [ota] [e9dcff1a-a06b-487a-b2c9-638731c5f368] Started POST "/channels/YRI5l/releases" for 172.20.0.1 at 2021-04-30 10:38:43 +0800 I, [2021-04-30T10:38:43.048098 #325] INFO -- : [ota] [e9dcff1a-a06b-487a-b2c9-638731c5f368] Processing by ReleasesController#create as HTML I, [2021-04-30T10:38:43.048232 #325] INFO -- : [ota] [e9dcff1a-a06b-487a-b2c9-638731c5f368] Parameters: {"authenticity_token"=>"LhXue8CNBys8GMZiHsAbt9EEZRcbRjj6l+Qy7mPxwQd7XR3/S5Phx/6qn3mHlO+rzoMaYVjb39P+ZMdAI7AJ+g==", "release"=>{"file"=>#<ActionDispatch::Http::UploadedFile:0x00007f501686a700 @tempfile=#Tempfile:/tmp/RackMultipart20210430-325-1jrrbo.ipa, @original_filename="TFHuiLianMS.ipa", @content_type="application/octet-stream", @headers="Content-Disposition: form-data; name="release[file]"; filename="TFHuiLianMS.ipa"\r\nContent-Type: application/octet-stream\r\n">, "changelog"=>"", "release_type"=>"", "branch"=>"", "git_commit"=>"", "ci_url"=>""}, "commit"=>"上传应用", "channel_id"=>"YRI5l"} I, [2021-04-30T10:38:44.227643 #325] INFO -- : [ota] [e9dcff1a-a06b-487a-b2c9-638731c5f368] Completed 500 Internal Server Error in 1179ms (ActiveRecord: 0.3ms | Allocations: 191411) F, [2021-04-30T10:38:44.228230 #325] FATAL -- : [ota] [e9dcff1a-a06b-487a-b2c9-638731c5f368]
    [ota] [e9dcff1a-a06b-487a-b2c9-638731c5f368] Zlib::DataError (invalid stored block lengths): [ota] [e9dcff1a-a06b-487a-b2c9-638731c5f368]
    [ota] [e9dcff1a-a06b-487a-b2c9-638731c5f368] app/models/release.rb:53:in block in upload_file' [ota] [e9dcff1a-a06b-487a-b2c9-638731c5f368] app/models/release.rb:39:inupload_file' [ota] [e9dcff1a-a06b-487a-b2c9-638731c5f368] app/controllers/releases_controller.rb:27:in `create'

    bug 
    opened by mxq0923 17
  • [求助]: cable 连接不上;跨域问题;注册点击无反应

    [求助]: cable 连接不上;跨域问题;注册点击无反应

    部署方式 | How to Deploy

    使用一键部署脚本 | Using zealot-docker on-click install (Default)

    部署版本 | Version

    nightly (Default)

    反代服务 | Reverse Proxy

    nginx

    HTTPS 证书类型 | HTTPS(SSL)

    无 none

    已阅读文档 | Read the document

    • [X] 已阅读 | Yes

    描述 | Description

    我这台服务器是从另一台服务器上代理过来的,所有流量走 80 端口。 然后我把 docker 映射到服务器的 9527 端口,服务器的 nginx 把 80 端口的流量都转发到 9527,然后发现出来的网页一直有几个问题。

    看控制台,首先是有个 /cable 一直连不上,显示 WebSocket connection to 'wss://xxx/cable' failed: There was a bad response from the server.

    其次是点第三方登录显示跨域问题:Origin https://xxx is not allowed by Access-Control-Allow-Origin. Status code: 200

    最后是注册按钮点击无反应,错误如下:

    Error: Form responses must redirect to another location
    requestSucceededWithResponse — application-a6c0272bfdcd3fded69270e0048f85ece58e49fd.js:14198
    (匿名函数) — application-a6c0272bfdcd3fded69270e0048f85ece58e49fd.js:13969
    asyncFunctionResume
    (匿名函数) — application-a6c0272bfdcd3fded69270e0048f85ece58e49fd.js:13947
    asyncFunctionResume
    (匿名函数)
    promiseReactionJobWithoutPromise
    promiseReactionJob
    

    不知道是不是之前没有过和我类似的情况。请大佬指点怎么解决?

    问题日志 | Relevant log output

    我的 nginx 配置如下:
        
    server {
            listen       80;
            server_name  xxx;
    
    #	location ~* ^(/assets|/favicon.ico) {
    #		access_log      off;
    #		expires         max;
    #	}
    # 上一段取消注释,可以解决跨域问题,但会导致 css/js 等资源文件取不到
    
    	location / {
    		try_files $uri @zealot;
    	}
    
    	location @zealot {
    		proxy_set_header Host $host;
    		proxy_set_header X-Real-IP $remote_addr;
    		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    		proxy_set_header X-Forwarded-Proto $scheme;
    		proxy_set_header Proxy "";
    		proxy_pass_header Server;
    
    		proxy_pass http://0.0.0.0:9527;    # 根据实际情况修改地址和端口号
    		proxy_buffering on;
    		proxy_redirect off;
    		proxy_http_version 1.1;
    		proxy_set_header Upgrade $http_upgrade;
    	}
    
    	location /cable {
    		proxy_http_version 1.1;
    		proxy_set_header Upgrade $http_upgrade;
    		proxy_set_header Connection "upgrade";
    		proxy_pass http://0.0.0.0:9527;    # 根据实际情况修改地址和端口号
    	}
        }
    
    bug question 
    opened by softwind0214 13
  • Android应用 发送钩子 发送了iOS的安装连接

    Android应用 发送钩子 发送了iOS的安装连接

    Win+ 测试版 Android 版本号:1.4.0(1644478260) 更新说明:

    • 没有找到更新日志,可能的原因:

    • 开发者很懒没有留下更新日志😂

    • 有不可抗拒的因素造成日志丢失👽

    安装地址: itms-services://?action=download-manifest&url=https://zealot.port2.io/channels/win_test/releases/3/install

    wontfix 
    opened by josercc 13
  • [Bug]: iPhone陌生设备扫码UDID,点击注册本设备按钮无反应

    [Bug]: iPhone陌生设备扫码UDID,点击注册本设备按钮无反应

    部署方式 | How to Deploy

    使用一键部署脚本 | Using zealot-docker on-click install (Default)

    部署版本 | Version

    nightly (Default)

    反代服务 | Reverse Proxy

    none

    HTTPS 证书类型 | HTTPS(SSL)

    自签名证书 Self-signed SSL

    已阅读文档 | Read the document

    • [X] 已阅读 | Yes

    描述 | Description

    大佬你好,前两天参照文档,用docker一键部署分别在自己测试的服务器,也让运维在公司服务器上部署了最新的4.5.1版本, 其他功能都正常,也能用已添加证书的iOS设备正常下载安装,看到最近更新了苹果开发者功能,在网站文档上没有看到相关介绍,在github上更新日志了解了一下,觉得 未添加进设备证书的设备扫码就能一键添加 这个功能很厉害,于是添加了开发者,测试设备同步能正常同步,但是陌生设备扫码点击 注册本设备 按钮没有反应。我自己搭的和运维搭的都是这样,麻烦大佬看看怎么回事。

    用未添加进证书的设备扫码: iShot_2022-10-27_10 50 58

    用添加进证书的设备扫码 正常显示证书: iShot_2022-10-27_10 55 49

    前端页面报错: iShot_2022-10-27_10 23 11

    iShot_2022-10-27_10 45 10

    服务日志: method=POST path=/udid/944168d1ed98baab04c3193bb58f552cf35e2b05/register format=turbo_stream controller=UdidController action=register status=500 duration=5.20 view=0.00 db=0.36 time=2022-10-27 10:38:01 +0800 exception=["NoMethodError", "undefined methoderrors' for #"] exception_object=undefined method errors' for # ip=172.xx.xx.5 username=管理员

    问题日志 | Relevant log output

    No response

    bug wontfix 
    opened by ycy0430 10
  • docker部署报错

    docker部署报错

    initdb: error: could not change permissions of directory "/var/lib/postgresql/data": Operation not permitted

    chmod: /var/lib/postgresql/data: Operation not permitted

    question 
    opened by EasierLu 10
  • 脚本部署,caddy无法启动,容器端口无法映射到宿主机。

    脚本部署,caddy无法启动,容器端口无法映射到宿主机。

    部署方式 | How to Deploy

    使用一键部署脚本 | Using zealot-docker on-click install (Default)

    部署版本 | Version

    nightly (Default)

    反代服务 | Reverse Proxy

    caddy

    已阅读文档 | Read the document

    • [X] 已阅读 | Yes

    描述 | Description

    按照部署文档进行的,环境没有问题,拿其他项目测试过,具体故障为caddy容器一直起不来,手动起有报错。然后其他服务端口无法正确映射到外面,检查了yml文件没有问题。是否是Let's Encrypt SSL 证书那里配置有问题呢? image image

    问题日志 | Relevant log output

    No response

    bug question wontfix 
    opened by Emptyh-2077 9
  • 版本号比较问题

    版本号比较问题

    部署方式 | How to Deploy

    使用一键部署脚本 | Using zealot-docker on-click install (Default)

    部署版本 | Version

    nightly (Default)

    反代服务 | Reverse Proxy

    kong-2.8.1

    已阅读文档 | Read the document

    • [X] 已阅读 | Yes

    描述 | Description

    /api/app/latest 接口获取更新版本存在较大问题,不能正确获取最新版本,经过排查定位到以下代码。 https://github.com/tryzealot/zealot/blob/42094ec89ff0d94c4a7ee42f7d55c24f978728ea/app/models/channel.rb#L31-L36 具体表现如下: 数据库认为版本号“1.0.10” 小于 “1.0.2” 大于 “1.0.1”。 SQL语句: select '1.0.10' > '1.0.1'; 结果:t (true) SQL语句: sselect '1.0.10' > '1.0.2'; 结果:f (false) 同时 build_version 的比较也存在类似问题; SQL语句: select '10' > '1'; 结果:t (true) SQL语句: sselect '10' > '2'; 结果:f (false) 根本原因是postgres的字符串比较问题,导致/api/app/latest 产生了一些莫名其妙的Bug。

    两种修复方案:

    1. postgres 安装pg_semver 扩展,以支持semver数据类型,修改release_version为semver类型,修改build_version为int类型。
    2. 将build_version字段数据类型改为int,修改build_version查询条件为>=, 并且去掉查询中release_version 的 where条件,仅比较 build_version 字段。

    个人建议使用第二种方案进行修复,相比第一种较为简单,同时只根据build_version进行版本更新判断并无不妥, 毕竟build_version 只能为数字,且只能增大不能减小。

    问题日志 | Relevant log output

    No response

    bug 
    opened by denymz 7
  • RFC: iOS 设备名称自注册和同步顺带支持团队管理

    RFC: iOS 设备名称自注册和同步顺带支持团队管理

    描述 | Description

    现状

    托管的 AdHoc 的 iOS 应用会显示包含测试设备 UDID 列表,之前可通过 zealot-sync-device fastlane 插件利用 Apple 开发者账户和密码手动同步,问题是同步不及时就会影响查看测试包的开发或测试同学无法确认上传的包是否包含自己的设备,尤其是新入职或者采购新 iOS 设备的时候。

    服务本身提供获取 iOS UDID 设备的功能同时在获取之后会告知是否有可以按照的应用这本身是一个非常有用的功能,假如没有注册能够提供一个注册设备的功能,同步 CICD 在构建 AdHoc 包的时候自动更新一次证书会非常有帮助。

    另外一点 iOS 已经提供使用 AuthKey + AppStoreConnectAPI 官方 API 来管理应用和证书等,不再涉及密码和二次认证的麻烦事情。

    原理

    • AppStoreConnectAPI 的 Key 对应一个公司主体
      • 通过 Key 可以拿到 Certficate 信息间接获取唯一的公司主体
    • 现有 Devices 表新增设备类型并关联上传 Key 的公司主体
    • 利用 Key 的功能可以注册、更新 Devices 列表

    功能实现

    • [x] 抽离之前的 iOS App 机器人审核使用的 AppStoreConnectAPI 类 https://github.com/icyleaf/tiny_appstore_connect
    • [x] 测试设备表扩容设备类型,网页可通过 UDID 识别设备类型(如果 API 可以拿到的话)
    • [x] 新增团队管理 Team ID,应用可能会是多个 Team ID 组成的,允许注册设备选择自己要注册的 Team
    • [x] 获取 UDID 设备若没有发现可安装的应用提示是否进行注册操作
    • [x] 后台可以管理 AppStoreConnect API 配置的 AuthKey、团队和测试设备相关界面

    功能截图

    苹果开发者管理界面 Apple Developer Manage UI

    获取未注册 UDID 设备可进行注册操作 Register Deivce to Apple Develoer

    enhancement 
    opened by icyleaf 7
  • fastlane zealot 上传失败

    fastlane zealot 上传失败

    +-------------+-----------------------------------------------------------+
    |                        Summary for zealot 0.8.0                         |
    +-------------+-----------------------------------------------------------+
    | channel_key | win_test                                                  |
    | file        | /Users/king/Library/Caches/apk/app-profile-1644561694.apk |
    | changelog   | 体验版本                                                  |
    |             | - - 修复 endpoint 路径错误                                |
    | branch      | origin/develop-支持zealot部署                             |
    | git_commit  | ab6248ada4efb596d81c1d9ea01ff617c768ec78                  |
    | source      | jenkins                                                   |
    | ci_url      | http://127.0.0.1:8080/job/win+_android/189/               |
    +-------------+-----------------------------------------------------------+
    [14:42:29]: Uploading to [http://127.0.0.1:80](http://127.0.0.1/) ...
    [14:42:33]: Error uploading to Zealot [422]: 
    
    invalid 
    opened by josercc 7
  • iOS Channel overview页面 不能访问

    iOS Channel overview页面 不能访问

    部署方式 | How to Deploy

    Docker (Default)

    部署版本 | Version

    nightly (Default)

    反代服务 | Reverse Proxy

    nginx

    已阅读文档 | Read the document

    • [X] 已阅读 | Yes

    描述 | Description

    创建一个iOS 渠道,然后访问它

    https://my-zealot-domain/t0HgR/overview

    页面渲染: 非常抱歉,服务当前遇到一些技术问题造成访问异常。

    问题日志 | Relevant log output

    method=GET path=/t0HgR/overview format=html controller=ChannelsController action=show status=500 duration=63.35 view=0.00 db=14.53 time=2022-06-20 16:54:11 +0800 exception=["ActionView::Template::Error", "No route matches {:action=>\"show\", :channel=>nil, :controller=>\"channels\"}, possible unmatched constraints: [:channel]\nDid you mean?  friendly_channel_overview_url"] exception_object=No route matches {:action=>"show", :channel=>nil, :controller=>"channels"}, possible unmatched constraints: [:channel]
    Did you mean?  friendly_channel_overview_url ip=172.31.0.1 username=管理员
    
    bug 
    opened by rkonfj 6
  • chore(deps): bump puma from 6.0.1 to 6.0.2

    chore(deps): bump puma from 6.0.1 to 6.0.2

    Bumps puma from 6.0.1 to 6.0.2.

    Release notes

    Sourced from puma's releases.

    6.0.2 / 2023-01-01

    • Refactor
      • Remove use of etc and time gems in Puma (#3035, #3033)
      • Refactor const.rb - freeze (#3016)
    Changelog

    Sourced from puma's changelog.

    6.0.2 / 2023-01-01

    • Refactor
      • Remove use of etc and time gems in Puma (#3035, #3033)
      • Refactor const.rb - freeze (#3016)
    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies ruby 
    opened by dependabot[bot] 0
  • chore(deps): bump esbuild from 0.15.18 to 0.16.12

    chore(deps): bump esbuild from 0.15.18 to 0.16.12

    Bumps esbuild from 0.15.18 to 0.16.12.

    Release notes

    Sourced from esbuild's releases.

    v0.16.12

    • Loader defaults to js for extensionless files (#2776)

      Certain packages contain files without an extension. For example, the yargs package contains the file yargs/yargs which has no extension. Node, Webpack, and Parcel can all understand code that imports yargs/yargs because they assume that the file is JavaScript. However, esbuild was previously unable to understand this code because it relies on the file extension to tell it how to interpret the file. With this release, esbuild will now assume files without an extension are JavaScript files. This can be customized by setting the loader for "" (the empty string, representing files without an extension) to another loader. For example, if you want files without an extension to be treated as CSS instead, you can do that like this:

      • CLI:

        esbuild --bundle --loader:=css
        
      • JS:

        esbuild.build({
          bundle: true,
          loader: { '': 'css' },
        })
        
      • Go:

        api.Build(api.BuildOptions{
          Bundle: true,
          Loader: map[string]api.Loader{"": api.LoaderCSS},
        })
        

      In addition, the "type" field in package.json files now only applies to files with an explicit .js, .jsx, .ts, or .tsx extension. Previously it was incorrectly applied by esbuild to all files that had an extension other than .mjs, .mts, .cjs, or .cts including extensionless files. So for example an extensionless file in a "type": "module" package is now treated as CommonJS instead of ESM.

    v0.16.11

    • Avoid a syntax error in the presence of direct eval (#2761)

      The behavior of nested function declarations in JavaScript depends on whether the code is run in strict mode or not. It would be problematic if esbuild preserved nested function declarations in its output because then the behavior would depend on whether the output was run in strict mode or not instead of respecting the strict mode behavior of the original source code. To avoid this, esbuild transforms nested function declarations to preserve the intended behavior of the original source code regardless of whether the output is run in strict mode or not:

      // Original code
      if (true) {
        function foo() {}
        console.log(!!foo)
        foo = null
        console.log(!!foo)
      }
      console.log(!!foo)
      

      // Transformed code if (true) { let foo2 = function() { };

    ... (truncated)

    Changelog

    Sourced from esbuild's changelog.

    0.16.12

    • Loader defaults to js for extensionless files (#2776)

      Certain packages contain files without an extension. For example, the yargs package contains the file yargs/yargs which has no extension. Node, Webpack, and Parcel can all understand code that imports yargs/yargs because they assume that the file is JavaScript. However, esbuild was previously unable to understand this code because it relies on the file extension to tell it how to interpret the file. With this release, esbuild will now assume files without an extension are JavaScript files. This can be customized by setting the loader for "" (the empty string, representing files without an extension) to another loader. For example, if you want files without an extension to be treated as CSS instead, you can do that like this:

      • CLI:

        esbuild --bundle --loader:=css
        
      • JS:

        esbuild.build({
          bundle: true,
          loader: { '': 'css' },
        })
        
      • Go:

        api.Build(api.BuildOptions{
          Bundle: true,
          Loader: map[string]api.Loader{"": api.LoaderCSS},
        })
        

      In addition, the "type" field in package.json files now only applies to files with an explicit .js, .jsx, .ts, or .tsx extension. Previously it was incorrectly applied by esbuild to all files that had an extension other than .mjs, .mts, .cjs, or .cts including extensionless files. So for example an extensionless file in a "type": "module" package is now treated as CommonJS instead of ESM.

    0.16.11

    • Avoid a syntax error in the presence of direct eval (#2761)

      The behavior of nested function declarations in JavaScript depends on whether the code is run in strict mode or not. It would be problematic if esbuild preserved nested function declarations in its output because then the behavior would depend on whether the output was run in strict mode or not instead of respecting the strict mode behavior of the original source code. To avoid this, esbuild transforms nested function declarations to preserve the intended behavior of the original source code regardless of whether the output is run in strict mode or not:

      // Original code
      if (true) {
        function foo() {}
        console.log(!!foo)
        foo = null
        console.log(!!foo)
      }
      console.log(!!foo)
      

      // Transformed code if (true) {

    ... (truncated)

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies javascript 
    opened by dependabot[bot] 0
  • [Bug]: k8s 环境日志在不挂载的情况下无法读取到

    [Bug]: k8s 环境日志在不挂载的情况下无法读取到

    部署方式 | How to Deploy

    使用一键部署脚本 | Using zealot-docker on-click install (Default)

    部署版本 | Version

    nightly (Default)

    反代服务 | Reverse Proxy

    none

    HTTPS 证书类型 | HTTPS(SSL)

    无 none

    已阅读文档 | Read the document

    • [X] 已阅读 | Yes

    描述 | Description

    k8s 环境日志在不挂载的情况下无法读取到,特征显示:日志加载中 ... 挂载的情况同时开启多 scale 会获取到不同环境的日志

    问题日志 | Relevant log output

    No response

    bug wontfix kubernates 
    opened by icyleaf 2
  • 关于调试文件的版本号问题

    关于调试文件的版本号问题

    描述 | Description

    如果我的产物里二进制有多个(除了主bin之外还有好几个framework),会导致调试文件也有多个。这时候我上传所有的调试文件后,自动分析产生的版本号会变成目录下随机一个调试文件的版本号。

    我试了下 api 里增加了版本号参数,发现 iOS 的调试文件好像不起作用。

    也不影响使用,就是错的版本号看着不爽。

    能否支持下这种情况下的版本号识别?

    enhancement wontfix 
    opened by softwind0214 4
  • 性能监控:Metrics

    性能监控:Metrics

    描述 | Description

    对于服务性能方面除了商业的服务外,可能会考虑自己提供一些实时的性能数据,需求先写在这里沉淀之后再看是否需要。

    相关 gems:

    • https://github.com/MiniProfiler/rack-mini-profiler
    • https://github.com/discourse/prometheus_exporter
    • https://github.com/johnewart/ruby-metrics
    • https://github.com/metricfu/metric_fu
    enhancement wip 
    opened by icyleaf 0
Releases(4.5.3)
  • 4.1.0(Jul 27, 2021)

  • 4.0.0.rc2(Dec 25, 2020)

  • 4.0.0.rc1(Oct 29, 2020)

    变更

    • [Docker] 重大变更 合并 rails 和 worker 到同一镜像部署需要同步更新 zealot-docker 库 #235
    • [Docker] Ruby 升级 2.7 部署
    • [Web] font-awesome 从 4.7.0 升级至 5.13.0,可能会有遗漏的 Icon 显示不正常
    • [Web] 调整邀请邮件的文案
    • [Web] 应用和调试文件下载路径统一到 /download 路径
    • [Web] 在线解析应用需要登录权限
    • [Web] 优化已经删除的或不存在的版本详情地址会自动跳转最新版本
    • [Web] 应用安装和下载逻辑做了调整(主要 iPadOS UserAgent 和 Desktop 一样无法判断)

    新功能

    • [Web] 涉及下载文件不存在会提示无法下载
    • [Web] 在线解析支持 .mobileprovision 格式文件以及解析 .ipa 新增开启功能等
    • [Web] 部分系统设置可以使用管理员面板在线修改 #245
    • [Web] 新增游客模式 #243
    • [Web] 支持显示 iOS AdHoc 版本测试设备的名称 #211
    • [Web] 支持解析已上传版本安装包的内容 #210
    • [Web] 支持获取 iOS 设备 UDID 功能 #203
    • [Web] 支持定期数据初始化且有功能限制的演示模式 #198
    • [Web] 上传 App 后在版本详情显示原本应用的名称
    • [Web] 可通过版本、Git 分支、打包类型筛选过滤应用列表
    • [Web] 版本详情最近上传关联 git commit 链接(如果在渠道设置了 git url)
    • [Web] LDAP 登录融合到现有登录界面,不再使用第三方依赖提供的简陋界面
    • [Task] 支持通过 rails 命令管理生成恢复数据备份功能(数据库、上传文件数据)#207
    • [API] 新增检查调试文件是否存在接口 /api/debug_files/version_exist

    修复

    • [Web] 修复上传 App 填写变更日志解析报错
    • [Web] 解决版本详情中二维码在中等分辨率会超出父视图
    • [Web] 解决应用渠道一些值为空确没有不显示默认值
    • [Web] 优化在线解析 iOS 包的内容展示(和永远展示假数据的问题)
    • [Web] 解决版本详情在使用 fastlane-plugin-ci_changelog 生成的变更日志没有展示提交者信息
    • [Web] 修复并优化检查新版本逻辑
    • [Web] 修复删除调试文件确认弹窗信息获取为空
    • [Web] 优化版本详情设备列表在一些手机的显示方式
    • [Web] 修复解析应用在不传参数提交的报错
    • [Web] 优化版本列表在手机查看
    • [Web] 渠道版本的最近上传动态仅显示底部分页,上部改为版本总数
    • [Web] 修复管理员编辑用户留空密码提示不能为空
    • [Web/API] 修复在线下载和安装版本不存在时会采用最新版本
    • [Web] 修复游客模式登录界面会显示边栏菜单
    • [Web] 修复上传同一应用同一平台调试文件总是会被覆盖的问题
    • [Web] 系统设置页面优化对布尔类型、字典类型的显示
    • [Task] 修复定时任务来清理老版本时因版本判断错误发生的误删版本
    • [Docker] 修复因为 volume 存储 public 文件夹造成内部静态资源不会更新
    • [Docker] 容器内的版本和外部不一致
    Source code(tar.gz)
    Source code(zip)
  • 4.0.0.beta4(May 13, 2020)

    新功能

    • [Docker] 支持 Heroku 部署
    • [Web] 游客模式允许查看 App 详情、列表和上传 App 详情
    • [API] 上传 App 支持自定义字段 #178
    • [Web/API] 上传 App 传递了 branch 值开头包含 origin/ 开头会自动清理掉
    • [Web] 登录、注册、找回密码、重设密码等用户认证界面增加项目简介

    修复

    • [Web] 修正用户密码描述文案
    • [Web] 修复网络钩子(WebHook)包含 url 字段的地址错误
    • [Web/API] 修复上传 iOS dSYM 文件上传报错
    • [API] 修复获取 App 接口 has_password 参数异常
    • [API] 修复上传 App 记录的 source 来源都是 Web
    • [API] 修复并支持上传 App 传递字符串类型的 json 格式的 changelog
    • [Web] 修复系统信息没有正常获取 CPU 和内存信息
    • [Web] 修复在线解析 Android 应用偶尔报错
    • [Web] 修复使用微信扫描二维码页面报错

    变更

    • [API] 应用最新版本接口(apps/latest)增加 bundle_id 纬度的验证
    • [Web] 游客模式可以访问应用版本详情和下载操作
    • [Web] 应用版本详情对于 iOS AdHoc 右侧的设备列表左移并默认收起状态
    • [Web] 开发环境移除 GraphQL 控制台功能,推荐使用 graphql-playground
    • [Web] 页面底部移除 footbar,版本信息可以在系统信息查看
    Source code(tar.gz)
    Source code(zip)
  • 4.0.0.beta3(Jan 16, 2020)

    新功能

    • [Web] 管理员添加的用户在邮箱未激活会提示并显示确认邮箱的链接
    • [Web] 默认开启 Sentry 匿名上报机制(可关闭)

    修复

    • [API] 修复上传应用总会创建新渠道
    • [Web/API] 修复上传 Android 应用无法显示图标

    变更

    • [Docker] 初始化数据从镜像移出到 zealot-docker 操作 #120
    • [Docker] 精简镜像的体积大小从 1.18G 降到 308M #114
    • [Worker] 使用异步任务代替传统 cron job 来实现定时清理老版本历史包文件(可关闭)
    • [Worker] 对异步任务进行分组和设置优先级
    • [API] 所有报错信息改成中文显示,因数据库写操作会返回具体错误信息
    • [Web] 使用 Rubocop Lint 规范化代码
    Source code(tar.gz)
    Source code(zip)
  • 4.0.0.beta2(Jan 10, 2020)

    新功能

    • [Web] 新增上传到具体应用渠道的全部版本列表同时支持删除操作

    修复

    • [Web] 对于上传应用不是有效 ipa 或 apk 的会给予错误提示而不是报错
    • [API] 修复获取应用最新版本列表因查询版本号不存在数据库无法返回最新版本列表
    • [API] 只针对写操作的接口才会要求 token 验证(之前是绝大部分都需要)
    Source code(tar.gz)
    Source code(zip)
  • 4.0.0.beta1(Jan 4, 2020)

Owner
Zealot
移动应用上传竟然如此简单、移动 App 应用分发系统 Over The Air Server for deployment of Android and iOS apps
Zealot
Use your old Android device as an OctoPrint server.

Use your old Android device as an OctoPrint server.

Feelfree (Filip) 1k Dec 31, 2022
Just an OIDC Server

Just an OIDC Server

Igor Cavalcante 0 Nov 5, 2021
A plugin written for my 1.12.2 anarchy server

A plugin written for my 1.12.2 anarchy server. I don't recommend using any of the fixes, most of them are garbage. Pull requests are welcome.

comendantmc 4 Jun 6, 2022
A boiler plate that can be re-used to start android apps

Agile Boiler Plate The main task at the innovation labs of Avast is to find new ideas to work on, prototype these ideas, and quickly implement them. A

Abed Almoradi 45 Sep 19, 2022
****. Use the native and support library variants instead - https://developer.android.com/guide/topics/ui/look-and-feel/fonts-in-xml.html. An android library that makes it easy to add custom fonts to edittexts and textviews

Add to your project Add this line to your dependencies in build.gradle compile 'in.workarounds.typography:typography:0.0.8' Using the views There are

Workarounds 43 Nov 6, 2021
SL4A brings scripting languages to Android by allowing you to edit and execute scripts and interactive interpreters directly on the Android device.

#Scripting Layer for Android (SL4A) SL4A brings scripting languages to Android by allowing you to edit and execute scripts and interactive interpreter

Damon Kohler 2.3k Dec 23, 2022
An application for runners and cyclists. Allows you to monitor your physical activity, weight and receive reminders about workouts.

An application for runners and cyclists. Allows you to monitor your physical activity, weight and receive reminders about workouts.

Just_Amalll 3 Feb 7, 2022
A curated list of standards, tests and benchmarks that can be used for testing and evaluating dev-tools

A curated list of standards, tests and benchmarks that can be used for testing and evaluating dev tools Contribution Add the description of the benchm

null 13 Dec 16, 2022
A gradle plugin for getting java lambda support in java 6, 7 and android

Gradle Retrolambda Plugin This plugin will automatically build your java or android project with retrolambda, giving you lambda goodness on java 6 or

Evan Tatarka 5.3k Jan 5, 2023
A Job Queue specifically written for Android to easily schedule jobs (tasks) that run in the background, improving UX and application stability.

Development in this repository is stopped. Future development continues on https://github.com/yigit/android-priority-jobqueue ========================

Path Mobile Inc Pte. Ltd. 2.4k Dec 9, 2022
An android library for displaying fps from the choreographer and percentage of time with two or more frames dropped

DEPRECATED TinyDancer is deprecated. No more development will be taking place. Check out the Google Android developer documentation for UI performance

Friendly Robot 1.9k Jan 3, 2023
📄The reliable, generic, fast and flexible logging framework for Android

logback-android v2.0.0 Overview logback-android brings the power of logback to Android. This library provides a highly configurable logging framework

Tony Trinh 1.1k Jan 8, 2023
It makes a preview from an url, grabbing all the information such as title, relevant texts and images. This a version for Android of my web link preview https://github.com/LeonardoCardoso/Link-Preview

LeoCardz Link Preview for Android It makes a preview from an url, grabbing all the information such as title, relevant texts and images. Visual Exampl

Leonardo Cardoso 420 Nov 19, 2022
A plug and play ;) android library for displaying a "rate this app" dialog

Easy Rating Dialog This lib provides a simple way to display an alert dialog for rating app. Default conditions to show: User opened the app more than

Fernando Martínez 111 Dec 30, 2022
AudioPlayerView is an Android view that loads audio from an url and have basic playback tools.

AudioPlayerView AudioPlayerView is an Android view that loads audio from an url and have basic playback tools. It makes use of the Android MediaPlayer

Hugo Matilla 86 Nov 29, 2022
Common rules and macros for Grab's Android projects built with Bazel.

Common rules and macros for Grab's Android projects built with Bazel. This repo provides rules and macros to support some of Android Gradle Plugin features in Bazel.

Grab 26 Dec 14, 2022
Purpose for this base architectural project is to load it with all latest components and libraries So it become reference for all kind of Android projects

The purpose of this base architectural project is to load it with all the latest components and libraries, So it becomes a reference for all kinds of Android projects

null 7 Dec 7, 2021
This was developed with Android studio and firebase Realtime database

This was developed with Android studio and firebase Realtime database. In this application users are able to see their old result list semester wise. Also they able to pass get analyze about all subject in university. User can predict the GPA value by adding future semester subjects and expected results. Java was used for backend development and XML used for frontend development.

Milinda Ruberu 3 Jul 25, 2021
The QuickJS embeddable Javascript engine packaged for Android and the JVM

The QuickJS embeddable Javascript engine packaged for Android and the JVM

Cash App 1.5k Dec 31, 2022