我有一个 Jenkins 管道作业,它构建 iOS 代码、创建 .app 文件并针对它运行测试。这些作业由 iOS 存储库中的 PR 触发。一次可以运行大约 4-5 个并行构建。

构建机器的配置:

  • 1 个安装了 xcode 和其他依赖项的 mac 机器
  • 这台mac机器是Jenkins slave agent
  • 当构建被触发时,它会在工作区中创建一个文件夹,在其中克隆源存储库以进行构建。

  • 例如
    jenkins-workspace-folder-on-mac-machine/
    -> build/ (folder created by a job that builds .app file for a PR)
    -> build@2/ (another folder created by a parallel job that builds .app for a PR)
    -> build@3/ (another folder created by a parallel job that builds .app for a PR)
    

    这是我的 Jenkinsfile 脚本以供引用:
    stages {
    
      stage('Clean Workspace') {
       steps {
        cleanWs deleteDirs: true, patterns: [[pattern: '**/Podfile.lock', type: 'EXCLUDE'], [pattern: '**/Pods/**', type: 'EXCLUDE'], [pattern: '**/Podfile', type: 'EXCLUDE'], [pattern: '**/Carthage/**', type: 'EXCLUDE'], [pattern: '**/Cartfile', type: 'EXCLUDE'], [pattern: '**/Cartfile.lock', type: 'EXCLUDE'], [pattern: '**/Cartfile.private', type: 'EXCLUDE'], [pattern: '**/Cartfile.resolved', type: 'EXCLUDE'], [pattern: '**/Gemfile', type: 'EXCLUDE'], [pattern: '**/Gemfile.lock', type: 'EXCLUDE']]
       }
      }
    
      /* Download and checkout iOS repository in the workplace.
      Also set all the keys for iOS into .env file */
      stage('Checkout iOS Source repository') {
          steps{
                checkout([$class: 'GitSCM', branches: [[name: "${PR_BRANCH}"]], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'abc', url: 'https://github.com/abc']]])
            }
        }
    
      /* Install all dependencies. These will be skipped if repo folder is not cleaned in the beginning.
      Full install will be done if an executor has to clone the repository from scratch*/
      stage('Install dependencies') {
        steps {
          sh '''
             bundle install
             make install
             '''
          }
      }
    
      stage('Build .app file and trigger tests') {
        steps {//This will perform xcode build and build .app file }
    

    我面临的问题:

    当我每次在开始构建之前清理工作区时,
  • 构建花费的时间太长。我期待如果我清理除文件和文件夹 Podfile, Pod folder, podfile.lock, Carthage folder, Cartfile, Cartfile.private, Cartfile.resolved, Gemfile, Gemfile.lock 之外的工作区,这会加快构建速度。但这行不通。
  • 由于缓存问题而导致随机构建失败,例如:
  • *** Checking out Nimble at "v8.0.4"
    A shell task (/usr/bin/env git checkout --quiet --force v8.0.4 (launched in /Users/user/Library/Caches/org.carthage.CarthageKit/dependencies/Nimble)) failed with exit code 1:
    error: pathspec 'v8.0.4' did not match any file(s) known to git
    
    make: *** [carthage-install] Error 1
    
    ### Error
    Errno::ENOENT - No such file or directory @ rb_file_s_stat - /Users/user/Library/Caches/CocoaPods/Pods/Release/Flurry-iOS-SDK/8.4.0-0c448
    
    bundle exec pod install
    Analyzing dependencies
    Pre-downloading: `CLImageEditor` from `git@github.com/CLImageEditor.git`, commit `96e78cdf95761170d5bf11653a8257a3ccfeb19a`
    [!] Failed to download 'CLImageEditor': Directory not empty @ dir_s_rmdir - /Users/user/Library/Caches/CocoaPods/Pods
    make: *** [pod-install] Error 1
    

    如果有人能帮助理解我在这里做错了什么,那就太好了。

    最佳答案

    我根据不同版本的 Gemfile.lock、Podfile.lock 和 Cartfile.resolved 编写了一个脚本来管理 cocoapods、gems 和 carthage 的依赖项缓存,从而解决了这个问题。

    Jenkinsfile 中管理缓存的示例脚本

    sh '''
          set +x
          mkdir -p ${HOME}/ioscache/pod
          # CocoaPods
          POD_SHASUM=$(shasum Podfile.lock | awk '{print $1}')
          POD_KEY="pod-${POD_SHASUM}"
          POD_CACHE_PATH="${HOME}/ioscache/pod/${POD_KEY}.tar.gz"
    
          echo "Checking cache for CocoaPods with they key: $POD_KEY"
          if [ ! -e "${POD_CACHE_PATH}" ]; then
            echo "CocoaPods cache not found with the key: $POD_KEY"
            POD_CACHE_FOUND=false
          else
            echo "CocoaPods cache found with the key: $POD_KEY"
            echo "restoring cache.."
            tar xf ${POD_CACHE_PATH}
            POD_CACHE_FOUND=true
          fi
    
          make pod-install
          if [ "$POD_CACHE_FOUND" = "false" ]; then
            echo "Saving cache for CocoaPods with key: $POD_KEY"
            tar cfz ${POD_CACHE_PATH} Pods/
            echo "Saved."
          fi
        '''
    

    对 Gemfile.lock 和 Cartfile.resolved 重复相同的操作。

    关于ios - 尝试在单台 Mac 机器上构建具有并行 Jenkins 管道构建的 iOS 应用程序时出现缓存问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58229687/

    10-14 12:01
    查看更多