Search code examples
iosautomationtestflight

How to automatically download app builds from TestFlight


I have a bunch of apps uploaded to the Testflight. How to automatically download all the builds to my computer?


Solution

  • You can use Ruby + Mechanize (https://github.com/sparklemotion/mechanize):

    require 'mechanize'
    
    @agent = Mechanize.new
    
    def process_login_page page
    
      puts 'Login...'
    
      login_form = page.forms.first # form has no action or name so just take the first one
    
      login_field = login_form.field_with(:name => 'username')
      password_field = login_form.field_with(:name => 'password')
    
      login_field.value = 'username'
      password_field.value = 'password'
    
      login_form.submit
    
      app_link_pattern = /\/dashboard\/applications\/(.*?)\/token\//
    
      puts 'Dashboard...'
      @agent.get("https://testflightapp.com/dashboard/applications/") do |dashboard_page|
        dashboard_page.links.each do |link|
          link.href =~ app_link_pattern
          if $1 != nil
            puts "Builds page for #{$1}..."
            @agent.get "https://testflightapp.com/dashboard/applications/#{$1}/builds/" do |builds_page|
              process_builds_page builds_page
            end
          end
        end
      end
    
    end
    
    def process_builds_page page
      body = page.body
      build_pages = body.scan /<tr class="goversion pointer" id="\/dashboard\/builds\/report\/(.*?)\/">/
      build_pages.each do |build_id|
        @agent.get "https://testflightapp.com/dashboard/builds/complete/#{build_id.first}/" do |build_page|
          process_build_page build_page
        end
      end
    end
    
    def process_build_page page
      build_link = page.links_with(:dom_class => 'bitly').first
      @agent.get("https://www.testflightapp.com#{build_link.href}") { |install_page| process_install_page install_page}
    end
    
    def process_install_page page
      # we need to figure out what kind of build is that
      ipa_link = page.link_with(:text => "download the IPA.")
      if (ipa_link != nil)
        download_build ipa_link, "ipa"
      else
        apk_link = page.link_with(:text => "download the APK.")
        if (apk_link != nil)
          download_build apk_link, "apk"
        end
      end
    
    end
    
    def download_build link, file_ext
    
      link.href =~ /\/dashboard\/ipa\/(.*?)\//
      filename = "#{$1}.#{file_ext}"
    
      file_url = "https://www.testflightapp.com#{link.href}"
      puts "Downloading #{file_url}..."
      @agent.get(file_url).save("out/#{filename}")
    end
    
    FileUtils.rm_rf "out"
    Dir.mkdir "out"
    
    login_page_url = "https://testflightapp.com/login/"
    @agent.get(login_page_url) { |page| process_login_page page }
    

    Disclaimer: I'm not a Ruby developer and this code is way far from being well designed or safe. Just a quick and dirty solution.