持续集成

持续集成

Posted by nomadli on April 18, 2016

持续集成

  1. 第一进阶, 自动检查分析编译:每次代码提交都触发一个hook,代码风格检查、静态代码分析、编译、单元测试、测试覆盖率检查,如果错误就通知对应的提交者。
  2. 第二进阶, 集成workflow:自动触发 自动部署测试环境的流程,编写集成测试用例
  3. 第三进阶,持续部署与交付:workflow中增加部署预生产环境进行灰度集成测试,将生产环节的部署和持续集成系统整合,通过持续集成系统来触发生产环境的部署,同时做线上环境部署后的回归测试
  4. 第四进阶,feature分支模式:通过release、develop、debug、new work等分支达到敏捷开发

gitlable workflow

1

持续集成需求

  1. User & AuthManager 这个是任何一个系统的基本需求,同时和持续集成的提醒反馈机制,以及第四进阶的个性化集成都相关。
  2. Project 权限控制一般是以项目为粒度的,同时持续集成的Build configure都是关联在项目之下。
  3. Build Runner 因为各种语言的build工具以及项目定义都不相同,需要允许扩展。为什么不直接用命令行调用呢?Build Runner需要做的事情包括日志收集,错误收集,变量注入等,用脚本比较困难。
  4. Source configure 项目关联的源码配置
  5. Build configure Builder Runner需要的参数等设置,一般都需要支持能配置多个step配置。
  6. Workflow (pipeline) 这个到第二进阶的时候就需要。因为持续集成系统执行的最小单元是Build configure,同一个configure的step不能独立执行,如果没有workflow机制,直接将所有的流程都放到同一个Build configure的不同的step,导致的结果就是如果后面的step失败,则必须从头开始。比如灰度测试的时候,部署脚本出现了错误,导致失败。如果有workflow,修复脚本后再次运行灰度测试这个Build configure即可,否则必须从头构建,非常浪费时间。
  7. Build agent 这个不同的CI工具实现的机制不一样,在这里指真正执行Build Runner的单元。Build agent要能支持库扩充部署,方便实现并行Build。
  8. Notification 通知和反馈对持续集成非常重要,最开始和就说到,持续集成包含的一层含义就是持续反馈。只有Build的结果及时通知到开发,测试,运维人员,才能形成持续集成环。

Jenkins ios 配置

  1. sudo launchctl unload -w /Library/LaunchDaemons/org.jenkins-ci.plist
  2. sudo launchctl load -w /Library/LaunchDaemons/org.jenkins-ci.plist
  3. plist 可以用参数 prefix httpPort httpListenAddress httpsPort httpsListenAddress httpsKeyStore httpsKeyStorePassword
  4. svn git 地址 .是jenkins-home/workspace/projectname/ 即 ${WORKSPACE}
  5. ${HOME} jenkins home path
  6. ${VERSION} ${BUILD_DATE}
  7. Code Signing Identity keychina->common name 拷贝login.keychain 到 jenkins-home/…
  8. Custom xcodebuild arguments 修改PRODUCT_BUNDLE_IDENTIFIER=com.nomadli.tools、DEVELOPMENT_TEAM=25TR5G565J、PROVISIONING_PROFILE、PROVISIONING_PROFILE_SPECIFIER、CODE_SIGN_IDENTITY=”iPhone Distribution”
  9. 自动签名比较麻烦
  10. keychian provision 放jenkins目录
  11. pod 需要在jenkins的系统管理->系统设置->Environment variables添加 LANG zh_CN.UTF-8

Jenkins ios sample

echo clean project versin = ${SVN_REVISION} pro dir = ${WORKSPACE} rm -rf ${WORKSPACE}/EMBroker.xcworkspace rm -rf ${WORKSPACE}/Podfile.lock rm -rf ${WORKSPACE}/Pods pushd ${WORKSPACE} /usr/local/bin/pod install –verbose –no-repo-update popd

sed -i -e ‘s/DevelopmentTeam = ./DevelopmentTeam = D975HMHLA6;/g’ ${WORKSPACE}/EMBroker.xcodeproj/project.pbxproj sed -i -e ‘s/ProvisioningStyle = ./ProvisioningStyle = Manual;/g’ ${WORKSPACE}/EMBroker.xcodeproj/project.pbxproj sed -i -e ‘s/PRODUCT_BUNDLE_IDENTIFIER = ./PRODUCT_BUNDLE_IDENTIFIER = com.eastmoney.financial;/g’ ${WORKSPACE}/EMBroker.xcodeproj/project.pbxproj sed -i -e ‘s/PROVISIONING_PROFILE = ./PROVISIONING_PROFILE = “123457-123-234-5555-123456”;/g’ ${WORKSPACE}/EMBroker.xcodeproj/project.pbxproj sed -i -e ‘s/PROVISIONING_PROFILE_SPECIFIER = ./PROVISIONING_PROFILE_SPECIFIER = freeInHouse;/g’ ${WORKSPACE}/EMBroker.xcodeproj/project.pbxproj sed -i -e ‘s/CODE_SIGN_IDENTITY = ./CODE_SIGN_IDENTITY = “iPhone Distribution: Eastmoney Information Co.,Ltd.”;/g’ ${WORKSPACE}/EMBroker.xcodeproj/project.pbxproj sed -i -e ‘s/”CODE_SIGN_IDENTITY[sdk=iphoneos*]” = ./”CODE_SIGN_IDENTITY[sdk=iphoneos*]” = “iPhone Distribution: Eastmoney Information Co.,Ltd.”;/g’ ${WORKSPACE}/EMBroker.xcodeproj/project.pbxproj sed -i -e ‘s/DEVELOPMENT_TEAM = ./DEVELOPMENT_TEAM = D975HMHLA6;/g’ ${WORKSPACE}/EMBroker.xcodeproj/project.pbxproj

xcode build Generate Archive -archivePath “/Users/nomadli/apps/ios/EMBroker/${BUILD_NUMBER}/EMBroker”

exportOptionsPath=${WORKSPACE}/build/EMBrokerExportOptions.plist ipafilePath=/Users/nomadli/apps/ios/EMBroker/${BUILD_NUMBER} archivefilePath=/Users/nomadli/apps/ios/EMBroker/${BUILD_NUMBER}/EMBroker.xcarchive cat >${exportOptionsPath} «EOT <?xml version=”1.0” encoding=”UTF-8”?> <!DOCTYPE plist PUBLIC “-//Apple//DTD PLIST 1.0//EN” “http://www.apple.com/DTDs/PropertyList-1.0.dtd”>

compileBitcode embedOnDemandResourcesAssetPacksInBundle iCloudContainerEnvironment Production method enterprise thinning <none> uploadBitcode uploadSymbols manifest appURL http://172.30.70.109/..... displayImageURL http://172.30.70.109/..... fullSizeImageURL http://172.30.70.109/.....

EOT

#onDemandResourcesAssetPacksBaseURL teamID #manifest assetPackManifestURL /usr/bin/xcodebuild -exportArchive -archivePath “${archivefilePath}” -exportPath “${ipafilePath}” -exportOptionsPlist “${exportOptionsPath}” CODE_SIGN_IDENTITY=”iPhone Distribution: Eastmoney Information Co.,Ltd.” PROVISIONING_PROFILE=”12345-123-234-432-12345676” cp -a ${WORKSPACE}/build/EMBroker.app.dSYM ${archivefilePath}/dSYMs

生成发布包

  • xcodebuild -list 获取工程信息
  • /Users/用户名/Library/MobileDevice/Provisioning Profiles
  • security cms -D -i xxxx.mobileprovision
  • xcodebuild -target -configuration -showBuildSetting 显示项目配置
  • xcodebuild archive -workspace 项目名称.xcworkspace -scheme 目标 -configuration 构建配置 -archivePath archive包存储路径 CODE_SIGN_IDENTITY=证书 PROVISIONING_PROFILE=描述文件UUID

导出ipa

  • 信息获取同发布包
  • xcodebuild -exportArchive -archivePath archive文件的地址.xcarchive -exportPath 导出的文件夹地址 -exportOptionsPlist exprotOptionsPlist.plist CODE_SIGN_IDENTITY=证书 PROVISIONING_PROFILE=描述文件UUID
  • plist内容
    <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
      <plist version="1.0">
      <dict>
          <key>teamID</key>
          <string>UA11AAJJKK8</string> //TeamID
          <key>method</key>
          <string>ad-hoc</string> //ad-hoc打包
          <key> compileBitcode</key> //是否编译bitcode
          <false/>
      </dict>
      </plist>