** ARCHIVE FAILED ** The following build commands failed: CodeSign /Users/ — Exit Status 65
Recently, I got stuck with an error that drove me crazy. After a quick search, I realized that a lot of people are dealing with the same or a similar issue.
I found multiple solutions that helped some people, but were completely useless to others. Simply because the solution depended on your tech stack.
In that variety of possible solutions, I ended up finding the solution that worked for me. But I payed the price of losing over a week of time, losing sleep and almost losing my mind over it.
So why am I writing this now? What do I want to accomplish writing this?
I want to provide a clear approach, or some kind of a roadmap of what you can do, if you have encountered the same issue.
Problem Statement
Let’s make it clear, what was I using and what I was trying to accomplish.
What do I have and what tools am I using?
- iOS project
- CI/CD pipeline
Now, let’s get a bit deeper into the components of my CI/CD:
- Hosted on Gitlab
- Configured custom Gitlab executor to run the job on the VM
- fastlane to automate testing, building and deployments
What is my goal?
My goal was to build, test and upload an iOS build using a custom GitLab runner on my local machine. Now, it worth mentioning that testing job (scan) executed successfully. I encountered the error during the upload part of the pipeline, which essentially runs match -> gym -> upload to testflight.
The error message appears by the very end of gym execution:
Solution Roadmap
I’m going to share some solutions I found on the web. Now, it is very important for you to understand your own case. It will simply save you a lot of time.
General
First let’s cover some general case, that can happen to anyone.
Expired Certs
Make sure that you don’t have any expired certificates.
Go to the Keychain Access ->Certificates
Make sure that you don’t see any red crosses on the certificates that you are using for your project, it would look something like this:
Unlock Keychain
This approach has helped a lot of people to fix this issue. Unfortunately, I wasn’t one of them. But still, it’s worth trying.
To unlock the keychain you need to add unlock_keychain fastlane action:
unlock_keychain(
path: "/Users/margaret/Library/Keychains/login.keychain-db",
password: "password"
)
Please note, you need to add this action in your upload lane (the lane where you are executing gym). And you need to add it, before gym.
Also, your path might differ from mine. I noticed that most people simply used “login.keychain” for their path. Try it out, if you provided the wrong path, most likely you will get an error that your path is not correct.
Or you can check on your terminal, what keychains do you have, by running the following:
$ security list-keychains
You should see something similar to this:
Now, let’s look at the unlock_keychain action usage example:
You might be having problems with match instead, in this case you can put unlock_keychain, right before match.
Putting the unlock_keychain action helped to get rid of the following error message, however, it did not fix the CodeSign issue.
I had the following error message during gym execution:
Once, I added the action with the correct(!) path & password this issue was fixed.
References:
Running Locally
If you got this error running locally, there are several things that you can do.
- Check whether you are using/have installed correct Provisioning Profiles & certs
- Unlock Keychain with extended time interval
- Deleting Xcode Derived Data Directory
There are more examples & solutions under the Resources & References section.
How did I fix my issue?
Simply by executing the following command on the VM and triggering the pipeline again:
security set-key-partition-list -S apple-tool:,apple: -s -k $YOUR_PASSWORD ~/Library/Keychains/login.keychain-db
What does this command mean?
- security
According to the manual:
security — A simple command line interface which lets you administer keychains, manipulate keys and certificates, and do just about anything the Security framework is capable of from the command line.
- set-key-partition-list
Is one of the rich variety of commands that security provides.
According to the manual:
set-key-partition-list — Set the partition list of a key
I am not joking now. It seems like no one really knows that that does. I found literally one sentence in the manual(!) that pretty much rephrases the command name.
I don’t give up so easy. So I digged a bit deeper.
And here is what I found:
Ex #1:
Ex #2:
Ex #3:
Github Travis-CI has some docs for the common build issues, where they also use set-key-partition-list:
Ex #4:
After looking on all of those examples, for me it seems like it is common solution to a CodeSign/certs issues. However, I think you would agree with me that it looks like no one knows/truly understands what the hell this command is doing.
Until, I finally found this:
The above makes more sense now. Even though I have not imported certificates myself (match has taken care of this for me), they are still imported.
security set-key-partition-list -S apple-tool:,apple: -s -k $YOUR_PASSWORD ~/Library/Keychains/login.keychain-db
As far as I understand, the above means that we give permissions to the partitions to sign the specified keychain.
And then I found the following:
Sets the "partition list" for a key.
The "partition list" is an extra parameter in the ACL which limits access to the key based on an application's code signature.You must present the keychain's password to change a partition list.
If you'd like to run /usr/bin/code- sign with the key, "apple:" must be an element of the partition list.
Where:
- -S
Is the comma-separated partition list, which is in our case are apple-tool: and apple:
- -s
Is an option that matches the keys that can sign
- -k
Is the password for the keychain
The usage of the command looks like this:
security set-key-partition-list [-S <partition list (comma separated)>] [-k <keychain password>] [options...] [keychain]
To sum up, we use set-key-partition-list to enable the specified partition to sign the application code for the keychain we provided. That’s how I understood it. If you have something to share, if you disagree with me, please let me know! I would love to understand more of this. I am not a pro at this topic, all of the above is written based on what I learned during a bit over a week of working on this issue.
Resources & References
On the last note, here is some links that might be useful to you if you are in the same/similar situation. These links include some common solutions that helped some people:
- I wish I would found this earlier, instead I found this article when I started writing this section:
- Unlock Keychain
- Unlock Keychain with extended time interval
- Provisioning Profiles
- Deleting Xcode Derived Data Directory
- Space in Jenkins Project Name
- Wrong Export Method
- Bitrise — wrong project settings
- Bitrise — Common Export Problems
- security set-key-partition-list
That’s all I had to say, I hope this helps :) Happy Coding everyone!