技术控

    今日:126| 主题:49289
收藏本版 (1)
最新软件应用技术尽在掌握

[其他] The Eidolon Deploy Process

[复制链接]
怪我长得丑 发表于 2016-10-9 07:20:41
92 0

立即注册CoLaBug.com会员,免费获得投稿人的专业资料,享用更多功能,玩转个人品牌!

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
Since weoriginally built Eidolon – an auction bidding kiosk app – the project has largely remained in maintenance mode. Eidolon was one of the first projects that we used automated deploys for, and the deploy process has remained largely unchanged. I believe this stability of the deploy process is a testament to how well the automated deploys have gone.  
  This post is going to detail the mechanics of automated deploys for an enterprise-distributed iOS application, discuss lessons we learned and applied to other projects' deploy processes, and describe some of the changes we'd like to make. Our project is entirely open source, so you can check out any part of the code on your own or    open an issuewith questions.  
  Deploying Eidolon

  It's one command on the terminal to deploy Eidolon:
           
  1. bundle exec fast lane deploy version:X.Y.Z
复制代码
       This command does a lot of things. It uses    Fastlane, and you can    read the entire script here. We're going to go over each part line-by-line. A few notes:  
  
       
  • We run this command locally on a development machine that has the keys installed to sign a deploy.   
  • Our changelog is formatted in      yaml, our script uses this strategically.   
  • Our deploy script modifies the project's Info.plist version and build number, as well as the changelog.  
  Let's dive in!
  The Script

  The first thing we do is verify that the version number we've been given is in the proper    SemVerformat.  
           
  1. version = options[:version]
  2. raise "You must specify a version in A.B.X format to deploy." if version.nil? || version.scan(/\d+\.\d+\.\d+/).length == 0
复制代码
       We deploy using Hockey, so make sure that an environment variable with the Hockey API key is set.
           
  1. hockey_api_token = ENV['HOCKEY_API_TOKEN']
  2. raise "You must specify a HOCKEY_API_TOKEN environment variable to deploy." if hockey_api_token.nil?
复制代码
       We also want to verify that we have valid API keys for analytics, the Artsy API, and a few other services yhe app uses. This validation only makes sure the keys have been set to non-empty values. And we don't want to accidentally deploy uncommited changes, so we check the git status first.
           
  1. verify_pod_keys
  2. ensure_git_status_clean
复制代码
       Next we need to set the build number. These need to be unique, and we use the current date. This could be a problem if we need to deploy more than once in a day. It hasn't been a problem yet, though, since we rarely deploy.
  We also want to set the Info.plist's version to the one specified when we run the    fast lanecommand.  
           
  1. build_number = Time.new.strftime("%Y.%m.%d")
  2. increment_build_number build_number: build_number
  3. increment_version_number version_number: version
复制代码
       Okay, now it's time to generate markdown release notes from the changelog. Our changelog is in the following format:
           
  1. upcoming:
  2. - Upcoming version bug fix.
  3. releases:
  4. - version: X.Y.Z
  5.   date: Month Day Year
  6.   notes:
  7.   - Previous version bug fix.
复制代码
       We want to grab the    upcomingnotes for the changelog, and then move them to the    releasessection. Let's generate the notes first:  
           
  1. changelog_filename = '../CHANGELOG.yml'
  2. changelog_yaml = YAML.load_file(changelog_filename)
  3. release_notes = changelog_yaml['upcoming'].map{ |note| note.prepend '- ' }.join("\n")
复制代码
       Updating the changelog is a little messy. I tried parsing the changelog as yaml, modifying it, and then writing it back as yaml, but kept running into trouble. Instead, I treat it as plain text. We open the changelog, split on    releases:, prepend the existing releases with a the generated release notes, and write the changelog.  
           
  1. changelog_contents = File.read(changelog_filename)
  2. existing_releases = changelog_contents.split('releases:').last
  3. this_release = changelog_yaml['upcoming'].map{ |note| note.prepend '  ' }.join("\n")
  4. changelog_contents = <<-EOS
  5. upcoming:
  6. releases:
  7. - version: #{version}
  8.   date: #{Time.new.strftime("%B %d %Y")}
  9.   notes:
  10. #{this_release}
  11. #{existing_releases}
  12. EOS
  13. File.open(changelog_filename, 'w') { |file| file.puts changelog_contents }
复制代码
       At this point, we're ready to start the actual deploy process. First we need to download the provisioning profiles, which is only one step with Fastlane:
           
  1. sigh
复制代码
       Next we build our app using    gym. We need to use the legacy build API, I can't remember why.  
           
  1. gym(
  2.   scheme: "Kiosk",
  3.   export_method: 'enterprise',
  4.   use_legacy_build_api: true
  5. )
复制代码
       With our build finished, we upload to Hockey.
           
  1. version = options[:version]
  2. raise "You must specify a version in A.B.X format to deploy." if version.nil? || version.scan(/\d+\.\d+\.\d+/).length == 0
  3. 0
复制代码
       Okay, our build is deployed. Time to let the team know there's a new version available:
           
  1. version = options[:version]
  2. raise "You must specify a version in A.B.X format to deploy." if version.nil? || version.scan(/\d+\.\d+\.\d+/).length == 0
  3. 1
复制代码
           default_payloadsneeds to be empty I think, I can't remember why. Seems like "I can't remember why" is a common theme here...  
  Before committing the changes we've made to the changelog and Info.plist files, we need to clean any build artefacts. This includes the actual binary that was compiled, unit test coverage reports, and downloaded provisioning profiles.
           
  1. version = options[:version]
  2. raise "You must specify a version in A.B.X format to deploy." if version.nil? || version.scan(/\d+\.\d+\.\d+/).length == 0
  3. 2
复制代码
       Finally, we commit, tag the build, and push to GitHub. Fastlane's built-in commands to commit to git reject any changes except to Info.plist files, and we've modified the changelog, so I used    shand used git directly.  
           
  1. version = options[:version]
  2. raise "You must specify a version in A.B.X format to deploy." if version.nil? || version.scan(/\d+\.\d+\.\d+/).length == 0
  3. 3
复制代码
       And that's it! With one terminal command, we've done all the following:
  
       
  • Verified version number format.   
  • Verified the local environment is set up to deploy.   
  • Verified API keys used by the app aren't empty.   
  • Incremented the build number and version.   
  • Updated the changelog.   
  • Built and signed the app.   
  • Uploaded the build to Hockey.   
  • Posted a notification to Slack.   
  • Tagged the release and pushed to GitHub.  
  Lessons Learned

  Automating Eidolon deploys was one of the first automated deploys we built on Artsy's iOS team. Now, based on Eidolon's successful deploy process, all our iOS deploys are automated.
  We've learned a few lessons.
  First, running deploys locally is    so 2015. Our more modern deploy processes run on continuous integration servers like Circle CI. This poses some problems around securing certificates necessary to deploy, maybe we'll cover that in a future blog post.  
  We deploy on CI based on pushes to a specific branch, and we run our deploy script only if the unit tests pass. This is a huge incentive to keep CI green.
  On other iOS projects, we sometimes deploy more than once a day, so we use    Year.Month.Day.Houras the build number format, which is unique enough to do one deploy per hour. This is good enough for now.  
  One thing I really wish I'd done when I set up automated deploys is to document things a little better. To be honest, that's part of the motivation to write this blog post (better late than never!).
  Conclusion

  Overall, automating deploys for Eidolon has been a huge win. The other night, we had an emergency at an auction: the Eidolon app was no longer working and we needed a new deploy.
        Guess who’s got two thumbs and forgot that their enterprise distribution certificates expire in September.
      :+1:this guy:+1:
    — Ash vs NSThread (@ashfurrow)    October 8, 2016    From the time the team let me know about the problem to the time they had a fresh deploy with a new certificate, less than twenty minutes had passed. I issued one command and watched it do all the work for me. If I had to manually follow a set of arcane steps I hadn't done in a long time, our team might not have had the new build in time.
友荐云推荐




上一篇:CSS Grid布局:响应式布局
下一篇:HTML Kong
酷辣虫提示酷辣虫禁止发表任何与中华人民共和国法律有抵触的内容!所有内容由用户发布,并不代表酷辣虫的观点,酷辣虫无法对用户发布内容真实性提供任何的保证,请自行验证并承担风险与后果。如您有版权、违规等问题,请通过"联系我们"或"违规举报"告知我们处理。

*滑动验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

我要投稿

推荐阅读

扫码访问 @iTTTTT瑞翔 的微博
回页顶回复上一篇下一篇回列表手机版
手机版/CoLaBug.com ( 粤ICP备05003221号 | 文网文[2010]257号 )|网站地图 酷辣虫

© 2001-2016 Comsenz Inc. Design: Dean. DiscuzFans.

返回顶部 返回列表