skip to Main Content

I am trying to create CI/CD pipeline, for Flutter iOS app using azure-pipelines.yml file.
Everything is OK in android studio and Xcode.
But when I try to build ios app in Azure DevOps I get this error:

/usr/local/lib/ruby/gems/2.7.0/bin/pod --version
1.11.3
/usr/local/lib/ruby/gems/2.7.0/bin/pod install --repo-update
[!] No `Podfile' found in the project directory.
##[error]The process '/usr/local/lib/ruby/gems/2.7.0/bin/pod' failed with exit code 1
##[error]The 'pod' command failed with error: The process '/usr/local/lib/ruby/gems/2.7.0/bin/pod' failed with exit code 1
Finishing: CocoaPods

My azure-pipelines.yml file is:

- task: InstallAppleCertificate@2
  inputs:
    certSecureFile: '$(p12FileName)'
    certPwd: '$(p12Password)'
    keychain: 'temp'
    deleteCert: true  

- task: InstallAppleProvisioningProfile@1
  displayName: "Install provisioning file"
  inputs:
    provisioningProfileLocation: 'secureFiles'
    provProfileSecureFile: '$(provisioningProfile)'

- task: CocoaPods@0
  inputs:
    forceRepoUpdate: true

- task: Xcode@5
  displayName: 'Xcode task'
  inputs:
    actions: 'build'
    sdk: 
    configuration: 'Release'
    xcWorkspacePath: '**/*.xcodeproj/project.xcworkspace'
    xcodeVersion: '12'
    packageApp: true
    signingOption: 'manual'
    signingIdentity: '$(APPLE_CERTIFICATE_SIGNING_IDENTITY)'
    provisioningProfileUuid: '$(APPLE_PROV_PROFILE_UUID)'

- task: FlutterInstall@0
  displayName: "Install Flutter SDK"
  inputs:
    mode: 'auto'
    channel: 'stable'
    version: 'latest'

- task: FlutterBuild@0
  displayName: "Build application"
  inputs:
    target: ipa
    projectDirectory: '$(Build.SourcesDirectory)'
    exportOptionsPlist: 'ios/exportOptions.plist'

and this is myPodfile:

platform :ios, '12.0'

ENV['COCOAPODS_DISABLE_STATS'] = 'true'

project 'Runner', {
  'Debug' => :debug,
  'Profile' => :release,
  'Release' => :release,
}

def flutter_root
  generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
  unless File.exist?(generated_xcode_build_settings_path)
    raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
  end

  File.foreach(generated_xcode_build_settings_path) do |line|
    matches = line.match(/FLUTTER_ROOT=(.*)/)
    return matches[1].strip if matches
  end
  raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
end

require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)

flutter_ios_podfile_setup

def flutter_install_ios_plugin_pods(ios_application_path = nil)
  ios_application_path ||= File.dirname(defined_in_file.realpath) if self.respond_to?(:defined_in_file)
  raise 'Could not find iOS application path' unless ios_application_path

  symlink_dir = File.expand_path('.symlinks', ios_application_path)
  system('rm', '-rf', symlink_dir) # Avoid the complication of dependencies like FileUtils.

  symlink_plugins_dir = File.expand_path('plugins', symlink_dir)
  system('mkdir', '-p', symlink_plugins_dir)

  plugins_file = File.join(ios_application_path, '..', '.flutter-plugins-dependencies')
  plugin_pods = flutter_parse_plugins_file(plugins_file)
  plugin_pods.each do |plugin_hash|
    plugin_name = plugin_hash['name']
    plugin_path = plugin_hash['path']
    if (plugin_name && plugin_path)
      symlink = File.join(symlink_plugins_dir, plugin_name)
      File.symlink(plugin_path, symlink)

      if plugin_name == 'flutter_ffmpeg'
          pod 'flutter_ffmpeg/full-lts', :path => File.join('.symlinks', 'plugins', plugin_name, 'ios')
      else
          pod plugin_name, :path => File.join('.symlinks', 'plugins', plugin_name, 'ios')
      end
    end
  end
end

target 'Runner' do
  use_frameworks!
  use_modular_headers!

  flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
end

post_install do |installer|
  installer.pods_project.build_configurations.each do |config|
    config.build_settings['PROVISIONING_PROFILE_SPECIFIER'] = ''
    config.build_settings['CODE_SIGNING_ALLOWED'] = 'NO'
    config.build_settings['CODE_SIGNING_REQUIRED'] = 'NO'
  end
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
        config.build_settings['PROVISIONING_PROFILE_SPECIFIER'] = ''
        config.build_settings['CODE_SIGNING_ALLOWED'] = 'NO'
        config.build_settings['CODE_SIGNING_REQUIRED'] = 'NO'
    end
  end
end

If I add

workingDirectory: '$(Build.SourcesDirectory)/ios'

I will get this error message:

"Invalid Podfile file: /Users/runner/work/1/s/ios/Flutter/Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first."

2

Answers


  1. Chosen as BEST ANSWER

    Finally, I found the solution:

    - stage: iOSStage
      dependsOn: []
      displayName: iOS
      condition: always()
      jobs:
    
      - job: iOSJob
        displayName: iOS
        steps: 
    
        - task: FlutterInstall@0
          displayName: "Install Flutter SDK"
          inputs:
            mode: 'auto'
            channel: 'stable'
            version: 'latest'
    
        - task: InstallAppleCertificate@2
          displayName: 'Install Apple Certificate'
          inputs:
            certSecureFile: '$(p12FileName)'
            certPwd: '$(p12Password)'
            keychain: 'temp'
            deleteCert: true  
    
        - task: InstallAppleProvisioningProfile@1
          displayName: "Install provisioning file"
          inputs:
            provisioningProfileLocation: 'secureFiles'
            provProfileSecureFile: '$(provisioningProfile)'
    
        - task: Bash@3
          displayName: '[Flutter] Configure Flutter'
          inputs:
            targetType: 'inline'
            script: |
              $(FlutterToolPath)/flutter doctor -v
              $(FlutterToolPath)/flutter config --no-analytics
    
        - task: Bash@3
          displayName: '[Flutter] Build project environment'
          inputs:
            targetType: 'inline'
            script: |
              $(FlutterToolPath)/flutter pub get
              $(FlutterToolPath)/flutter pub global activate junitreport
    
        - task: Bash@3
          displayName: '[Flutter] Flutter coverage'
          inputs:
            targetType: 'inline'
            script: |
              pip install lcov_cobertura
              $(FlutterToolPath)/flutter test --coverage
              python -m lcov_cobertura coverage/lcov.info -o coverage/coverage.xml
              
        - task: Bash@3
          displayName: '[Flutter] Flutter build'
          inputs:
            targetType: 'inline'
            script: |
              $(FlutterToolPath)/flutter build ios --release --no-codesign --build-number $(Build.BuildId)
    
        - task: CocoaPods@0
          inputs:
            workingDirectory: '$(Build.SourcesDirectory)/ios/Flutter'
            forceRepoUpdate: true
    
        - task: Xcode@5
          displayName: 'Xcode task'
          inputs:
            actions: 'build'
            sdk: '$(sdk)'
            configuration: '$(configuration)'
            scheme: '$(scheme)'
            xcWorkspacePath: ios/Runner.xcworkspace
            signingOption: 'manual'
            signingIdentity: $(APPLE_CERTIFICATE_SIGNING_IDENTITY)
            provisioningProfileUuid: $(APPLE_PROV_PROFILE_UUID)
            packageApp: true
            workingDirectory: 'ios'
            exportOptions: 'auto'
            exportMethod: 'ad-hoc'
            archivePath: 'output/$(sdk)/$(configuration)/Runner.xcarchive'
            exportPath: 'output/$(sdk)/$(configuration)'
            useXcpretty: 'false'
            args: '-verbose'
     
        - task: CopyFiles@2
          displayName: 'Copy app to staging directory'
          inputs:
            Contents: '**/*.ipa'
            TargetFolder: '$(build.artifactStagingDirectory)'
            OverWrite: true
    
        - task: PublishBuildArtifacts@1
          inputs:
            PathtoPublish: '$(Build.ArtifactStagingDirectory)'
            ArtifactName: 'drop'
            publishLocation: 'Container'
    

  2. According to the error message, it seems the podfile cannot be found under the repository directory.

    You could check the podfile location and try to specific the workingDirectory and projectDirectory in the CocoaPods@0 task to check the status.

    For more information, you could refer to:
    https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/package/cocoapods?view=azure-devops#yaml-snippet

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search