spotify / XCRemoteCache

Other
825 stars 50 forks source link

How to change producer and consumer mode on Remote CI #226

Closed anuragstar closed 7 months ago

anuragstar commented 9 months ago

**Hey We are exploring XCRemote Cache to improve our iOS build time, While going thorough documentation we have a couple of queries We are using self-hosted Mac runners for iOS builds, which we are on different architecture - Intel Mac Machine (X86_64), M1 Mac(ARM architecture), device and simulator configuration, If we use Intel arch cache on Mac it will fail, How to handle this use case. Is there is any UI to see XCRemote cache results. How we can choose when to run build in producer and consumer mode. Is it possible to specify architecture while pushing the artifact to the XCRemote cache server. If we have multiple targets in a repo how to specify the xc mark for each target. Whenever we are running locally we are getting cache miss.

XCRC/xcprepare stats

hit_count: 0

miss_count: 237

local_cache_bytes: 0

indexing_hit_count: 0

indexing_miss_count: 0**

[-] CocoaPods cocoapods-xcremotecache plugin [ ] Automatic integration using xcprepare integrate ... [ ] Manual integration [ ] Carthage

Expected/desired behavior

Minimal reproduction of the problem with instructions

Producer Logs

 [REPLACE THIS WITH YOUR INFORMATION] 

Consumer Logs

 [REPLACE THIS WITH YOUR INFORMATION] 

Pods/Carthage file

 [REPLACE THIS WITH YOUR INFORMATION] 

Environment

Post build stats

 [REPLACE THIS WITH YOUR INFORMATION] 

Others

polac24 commented 9 months ago

We are using self-hosted Mac runners for iOS builds, which we are on different architecture - Intel Mac Machine (X86_64), M1 Mac(ARM architecture), device and simulator configuration, If we use Intel arch cache on Mac it will fail, How to handle this use case.

I guess your meant If we use Intel arch cache on ARM it will fail. Suggest following the recommendation here

Is there is any UI to see XCRemote cache results.

If you mean cache hits -> then there is xcprepare stats. If for generated artifacts - that depends where you store artifacts. For suggested approach with GCS or S3 -> use Google's or Amazon's UI.

How we can choose when to run build in producer and consumer mode.

you configure that depending on an integation. If automatic, then call xcprepare integrate --mode producer. If manually, update.rcinfo with mode: producer or mode: consumer

Is it possible to specify architecture while pushing the artifact to the XCRemote cache server.

Yes, e.x. xcodebuild ARCHS=x86_64 ONLY_ACTIVE_ARCH=NO ... for Intel

If we have multiple targets in a repo how to specify the xc mark for each target.

XCRemoteCache doesn't support that. It is designed to work only on a "complete cache" mode.

Whenever we are running locally we are getting cache miss.

https://github.com/spotify/XCRemoteCache/blob/master/docs/FAQ.md#troubleshooting-cache-misses might help

anuragstar commented 9 months ago

@polac24 I have configured S3 for xcremotecache, I want to know If I have different configuration, Debug, Release, Dogfood, Beta configuration of app the xcmark makes a record with each commit, what's the ideal way to store cache results for different build configuration and different env(dev,qa,pp,prod).

Ques 2: Can I put minimum details in .rcinfo file and rest other details specify at run time ? .rcinfo file

cache_addresses primary_repo xccc_file, remote_commit_file

and specify mode at run time by using - xcprepare integrate --mode producer at the time of building the app similarly xcprepare integrate --mode consumer at the GitHub actions or CI level.

Ques 3: How to see cumulative build scan results on XCRemoteCache - right now for each build record I can check via this way - xcprepare stats

Ques 4: What is the recommended way to use producer for any commit merged on development branch, run it on producer mode and generate all the artifacts for all configuration and device type, Is there is a better way to do it.

Ques 5 : In .rcinfo file AWS S3 removed automatically after first run.

cache_addresses: https://bucket-name-amazonaws.com/cache aws_secret_key: xxx aws_access_key: xx aws_region: xx aws_service: s3

Whenever I add AWS S3 configuration and run pod install the cache artifact is pushed, in the next run, I can see from the .rcinfo file these entries got removed from the .rcinfo file automatically.

polac24 commented 9 months ago

Hi!

I have configured S3 for xcremotecache, I want to know If I have different configuration, Debug, Release, Dogfood, Beta configuration of app the xcmark makes a record with each commit, what's the ideal way to store cache results for different build configuration and different env(dev,qa,pp,prod).

Do I understand you correctly that you have potentially 16 builds? 4 configurations x 4 envs? XCRemoteCache separates build artifacts only by configurations, not configurations x envs. For CocoaPods plugin and automatic integration, artifacts and markers are always unique for configuration so you don't have to do anything special. For the manual integration, you have to pass --configuration #Configuration# param to xcprepare

Ques 2: Can I put minimum details in .rcinfo file and rest other details specify at run time ? .rcinfo file

cache_addresses primary_repo xccc_file, remote_commit_file

and specify mode at run time by using - xcprepare integrate --mode producer at the time of building the app similarly xcprepare integrate --mode consumer at the GitHub actions or CI level.

Yes, to override defaults placed in .rcinfo, properties that are defined in user.rcinfo have higher priority.

Ques 3: How to see cumulative build scan results on XCRemoteCache - right now for each build record I can check via this way - xcprepare stats

xcprepare stats presents cumulative results. All counters are reset only if you pass --reset

Ques 4: What is the recommended way to use producer for any commit merged on development branch, run it on producer mode and generate all the artifacts for all configuration and device type, Is there is a better way to do it.

That is exactly the recommended way.

Ques 5 : In .rcinfo file AWS S3 removed automatically after first run.

cache_addresses: https://bucket-name-amazonaws.com/cache aws_secret_key: xxx aws_access_key: xx aws_region: xx aws_service: s3

Whenever I add AWS S3 configuration and run pod install the cache artifact is pushed, in the next run, I can see from the .rcinfo file these entries got removed from the .rcinfo file automatically

That looks like something git-related. However, if you use the CocoaPods plugin, I would recommend setting those values in the Podfile, like:

xcremotecache({
    'cache_addresses' => ['http://localhost:8080/cache/pods'],
    'aws_service' => ....
})

Also, note that cache_addresses is an array

anuragstar commented 8 months ago

@polac24 We integrated XCremote in our project, we are able to fetch from remote cache initially, but after few runs, we are getting 403 rate limit, we configured AWS S3 for the remote cache, can you please help us to fix this issue. pod install works successfully, after that whenever we are building we are getting this issue.

Screenshot 2023-10-14 at 3 07 50 PM Screenshot 2023-10-14 at 3 08 33 PM
polac24 commented 8 months ago

This looks unrelated to XCRemoteCache. Are you sure that the error is "rate limiter"? 403 is Access Denied so maybe your configuration in .rcinfo (or Podfile) is incorrect?

If that is really a rate limiter problem, you should investigate AWS's side.

anuragstar commented 8 months ago

@polac24 AWS S3 configuration is correct after sometimes we start seeing success then it starts showing 403.

anuragstar commented 7 months ago

@polac24 We have a very large multi-module project, where there is a main app, and there are lot's of libraries, some libraries which are very huge in size is not able to upload cache artifact on XCRemoteCache server in producer mode and throws 403 error, Is there is any way to skip certain libraries to upload on XCRemoteCache ?

xcremote
anuragstar commented 7 months ago

@polac24 What is the recommended way to run producer mode, at every PR merge to main branch - run a app in producer mode or is there are any other way to upload whenever new code is merged

polac24 commented 7 months ago

You can disable that with --targets-exclude (or exclude_targets in CocoaPods) but keep in mind if that is a non-leaf target, building it locally might invalidate all of its reverse dependencies easier. We implemented a lot of logic to make local compilations with CI, but that highly depends on your setup.

  1. The recommended approach is to produce artifacts only for post-merge builds (everything that landded on a main branch)
anuragstar commented 7 months ago

Thanks @polac24 for the quick response, there is another peculiar issue we are seeing, Once XC Remote Cache is enabled, builds are not stopping on break points, the debugger is not working, Is this a known issue on XCRemote Cache?

Is there any changes required in the XCRemote Cache library for Xcode15?

polac24 commented 7 months ago

Debug symbols are hard because LLDB depends on absolute paths.

With CocoaPods we have a lot of rewriting logic (starting point, startingpoint2). You can start with double checking if anything overridestarget.source-map value set in ~/.lldbinit`

anuragstar commented 7 months ago

Hey @polac24 We are trying to integrate XCRemote Cache on CI, where we want to configure XCRemote Cache mode at run time using command -

XCRC/xcprepare integrate --input project.xcodeproj --mode producer --final-producer-target project-ios-mobile

After that if I perform - xcode build, it started failing with multiple commands in derived data error.

xcremotecache({ 'cache_addresses' => ['s3path/cache'], 'primary_repo' => 'https://github.com/abc.git', 'primary_branch' => 'XCRemoteS3Changes', 'xccc_file' => './XCRC/xccc', 'remote_commit_file' => './XCRC/arc.rc' })


cache_addresses:

Screenshot 2023-11-17 at 2 07 22 PM Screenshot 2023-11-17 at 1 35 43 PM Screenshot 2023-11-17 at 1 35 52 PM Screenshot 2023-11-17 at 1 36 18 PM Screenshot 2023-11-17 at 1 35 28 PM

Can you suggest workaround to build with above configuration on CI, where we can switch to producer and consumer wherever required.

polac24 commented 7 months ago

Any reason to call xcprepare integrate in the CocoaPods flow? That step seems redundant - the cocoapods plugin automatically integrates XCRemoteCache to the xcodeproj/xcworkspace.

anuragstar commented 7 months ago

@polac24 XCRC/xcprepare integrate --input project.xcodeproj --mode producer --final-producer-target project-ios-mobile we are calling this step to setup producer mode at run time on CI, Is there is any other way to setup producer mode at run time instead of hard coded value

polac24 commented 7 months ago

I was saying that you should control consumer/producer mode in Podfile and not call xcprepare integrate at all (since CocoaPods plugin handles everything):

xcremotecache({
    'cache_addresses' => ['http://localhost:8080/cache/pods'],
    'primary_repo' => 'https://your.primary.repo.git',
    'mode' => 'consumer'
})

or

xcremotecache({
    'cache_addresses' => ['http://localhost:8080/cache/pods'],
    'primary_repo' => 'https://your.primary.repo.git',
    'mode' => 'producer'
})
anuragstar commented 7 months ago

@polac24 At run time, it's difficult to set in a podfile, we need to change at run time while running on CI, Is there any way to achieve it ?

xcremotecache({ 'cache_addresses' => ['http://localhost:8080/cache/pods'], 'primary_repo' => 'https://your.primary.repo.git', 'mode' => 'producer' }) this is the default way, but we can't override this value at run time.

polac24 commented 7 months ago

Switching modes without pod install is not supported.

Potential workaround

You try a hacky way of achieving that by:

  1. setting consumer mode in Podfile
  2. (later, on a fly) manually sed the mode in the .rcinfo file - placed in Pods directory (or multiple directories, if you use generate_multiple_pod_projects mode). That might work but do it at your own risk.