delivery ios jenkins continuous-integration

ios - delivery - jenkins continuous testing



Jenkins-Xcode build works codesign falla (10)

Al mover los certificados al llavero del sistema, y ​​al hacer referencia a él, se solucionó específicamente el problema.

A continuación está mi script de compilación (sin usar el complemento xcodebuild).

  1. Construir paso funciona
  2. Creé un llavero por separado con los certificados requeridos y las claves privadas, y son visibles en el Acceso a Llaveros
  3. los comandos de llavero no fallan en la secuencia de comandos
  4. lista de seguridad-llaveros muestra estos como llaveros válidos

Actuar como un comando de desbloqueo realmente no tiene éxito. Cuando intento ejecutar codesign desde la línea de comando a través de

codesign -f -s "iPhone Developer: mycert" -v sample.app/ --keychain /Users/Shared/Jenkins/Library/Keychains/JenkinsCI.keychain

yo obtengo

CSSM_SignData returned: 000186AD sample.app/: unknown error -2070=fffffffffffff7ea

aunque no estoy seguro de que estoy emulando desde la línea de comandos, ya que en el mejor de los casos puedes

sudo -u jenkins bash xcodebuild ONLY_ACTIVE_ARCH="NO" CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED="NO" -scheme "MySchemeName" CONFIGURATION_BUILD_DIR="`pwd`" security list-keychains -s /Users/Shared/Jenkins/Library/Keychains/JenkinsCI.keychain + security default-keychain -d user -s /Users/Shared/Jenkins/Library/Keychains/JenkinsCI.keychain + security unlock-keychain -p jenkins /Users/Shared/Jenkins/Library/Keychains/JenkinsCI.keychain + security list-keychains "/Users/Shared/Jenkins/Library/Keychains/JenkinsCI.keychain" "/Library/Keychains/System.keychain" + security default-keychain "/Users/Shared/Jenkins/Library/Keychains/JenkinsCI.keychain" + codesign -f -s ''$IDENTITY_GOES_HERE.'' -v sample.app/ sample.app/: User interaction is not allowed.

Cualquier ayuda es muy apreciada.


Aquí lo que funcionó para mí:

  1. Creé un nuevo llavero y copié todas las entradas de "iniciar sesión" en él, lo llamé "jenkins_ios"
  2. Hecho nuevo llavero por defecto.
  3. Se agregó un nuevo paso "Ejecutar shell" en la configuración de Jenkins, debería ser el primer paso antes de la firma del código, que contiene lo siguiente:

KEYCHAIN=/Users/<user>/Library/Keychains/jenkins_ios.keychain security -v list-keychains -s $KEYCHAIN security -v unlock-keychain -p <password> $KEYCHAIN security set-keychain-settings -t 3600 -l $KEYCHAIN

El último paso es realmente importante, ya que el tiempo de espera de desbloqueo predeterminado puede no ser suficiente para que tu proyecto se construya correctamente (exactamente esto sucedió con nuestro proyecto, ya que es enorme y el paso de construcción duró unos 5-7 minutos y el llavero quedó bloqueado en este momento) fue requerido para el codesign).


Copié todos los certificados / claves privadas a un nuevo llavero (puede hacer clic derecho en los artículos y simplemente copiar y pegar). En el nuevo llavero, haga clic con el botón derecho en cada clave privada, obtenga Información -> Control de acceso y ponga las llaves a disposición de todas las aplicaciones.

Es importante destacar que en la esquina superior izquierda de la aplicación Keychain está la lista de llaveros. Reordenarlos para que el nuevo llavero sea el primero en la lista.

Otra respuesta que encontré dio el paso de compilación para desbloquear este llavero durante la compilación:

KEYCHAIN=/Users/<you>/Library/Keychains/codesign.keychain # the -s option adds $KEYCHAIN to the search scope, while the -d option adds $KEYCHAIN to the system domain; both are needed security -v list-keychains -d system -s $KEYCHAIN security -v unlock-keychain -p <keychain password> $KEYCHAIN


En esta respuesta, agregamos / eliminamos su certificado iOS sin manipular el llavero de inicio de sesión ni cambiar el llavero predeterminado por:

  1. Use un llavero temporal
  2. Adjuntar llavero temporal a la lista de búsqueda (no reemplazando)
  3. Desbloquear llavero temporal sin tiempo de espera
  4. Importe su certificado usando -T /usr/bin/codesign
  5. Hacer la construcción
  6. Eliminar certificado eliminando llavero temporal

Crea llavero temporal. Agregué el $$ que es el PID. Esto significa que permitimos que se pueda paralelizar el script al permitir que se creen varios llaveros temporales al mismo tiempo:

# Create temp keychain MY_KEYCHAIN="MyKeychain-$$.keychain" MY_KEYCHAIN_PASSWORD="secret" security create-keychain -p "$MY_KEYCHAIN_PASSWORD" "$MY_KEYCHAIN"

Añade un llavero temporal a la lista de búsqueda. Tenga cuidado de usar security list-keychains -s para agregar su llavero, de lo contrario, las compilaciones se ejecutarán en otro hilo:

# Append keychain to the search list security list-keychains -d user -s "$MY_KEYCHAIN" $(security list-keychains -d user | sed s//"//g) security list-keychains

Desbloquea el llavero temporal sin tiempo de espera de reenganche automático ( security set-keychain-settings ). Si olvida corregir el tiempo de espera de reenganche, las compilaciones que tarden más que el tiempo de reposición predeterminado activarán la solicitud de contraseña:

# Unlock the keychain security set-keychain-settings "$MY_KEYCHAIN" security unlock-keychain -p "$MY_KEYCHAIN_PASSWORD" "$MY_KEYCHAIN"

Importe el certificado de iOS y otorga el acceso /usr/bin/codesign sin requerir una solicitud de contraseña.

# Import certificate security import $CERT -k "$MY_KEYCHAIN" -P "$CERT_PASSWORD" -T "/usr/bin/codesign"

Debido a que usamos un llavero temporal y sabemos que contiene solo 1 certificado, podemos, programáticamente, derivar IOS_IDENTITY (requerido como entrada para construir los pasos).

# Detect the iOS identity IOS_IDENTITY=$(security find-identity -v -p codesigning "$MY_KEYCHAIN" | head -1 | grep ''"'' | sed -e ''s/[^"]*"//'' -e ''s/".*//'') IOS_UUID=$(security find-identity -v -p codesigning "$MY_KEYCHAIN" | head -1 | grep ''"'' | awk ''{print $2}'') # New requirement for MacOS 10.12 security set-key-partition-list -S apple-tool:,apple: -s -k $MY_KEYCHAIN_PASSWORD $MY_KEYCHAIN

Haz tu construcción ahora

# Insert your custom build steps

Eliminar llavero temporal. Tenga en cuenta que al hacerlo, saldrá automáticamente de la lista de búsqueda. es decir, todos los otros llaveros permanecerán.

# Delete the temp keychain security list-keychains security delete-keychain "$MY_KEYCHAIN" security list-keychains


Es un error de firma de código, el comando xcodebuild no puede acceder a la clave privada de su certificado ya que se está ejecutando a través del esclavo de Jenkins con SSH.

Ejecute esta línea en su script de shell antes de ejecutar el xcodebuild para permitir el acceso:

security set-key-partition-list -S apple-tool:,apple: -s -k <ROOT-PASSWORD> /Users/<YOUR USER NAME>/Library/Keychains/login.keychain-db

¡Espero que ayude!



FWIW ... déjame arrojar otra posible razón para esto. Puede tener certificados duplicados flotando y codesign no puede decir cuál usar. Cuando ejecuta este comando desde su esclavo Jenkins, ¿ve certificados duplicados y válidos? Algo como esto:

$ security find-identity -v -p codesigning 1) AAAAE00066DED2FE77DF43012573AD5B6188AAAA "iPhone Developer: JOHN SMITH (XAAAAFSUSJ)" 2) AAAAE00066DED2FE77DF43012573AD5B6188AAAA "iPhone Developer: JOHN SMITH (XAAAAFSUSJ)" 3) BBBB5B03DB566209964247982908D3DD74D1BBBB "iPhone Distribution: Example, Inc. (TBBBBH5HUE)" 4) BBBB5B03DB566209964247982908D3DD74D1BBBB "iPhone Distribution: Example, Inc. (TBBBBH5HUE)" 5) BBBB5B03DB566209964247982908D3DD74D1BBBB "iPhone Distribution: Example, Inc. (TBBBBH5HUE)" 6) AAAAE00066DED2FE77DF43012573AD5B6188AAAA "iPhone Developer: JOHN SMITH (XAAAAFSUSJ)" 7) AAAAE00066DED2FE77DF43012573AD5B6188AAAA "iPhone Developer: JOHN SMITH (XAAAAFSUSJ)" 8) BBBB5B03DB566209964247982908D3DD74D1BBBB "iPhone Distribution: Example, Inc. (TBBBBH5HUE)" 8 valid identities found

Si es así, he encontrado que es útil hacer lo siguiente y volver a un conjunto de referencia de certificados de firma:

  • Borre todos los certificados del esclavo Jenkins (y otros esclavos Jenkins que ejecutarán su script de compilación).
  • Siguiente: verificar, tiene 0 identifies ejecutando $ security find-identity -v -p codesigning nuevamente.
  • Dentro del repositorio de su aplicación, incluya un MyApp.keychain personalizado con los dos certificados válidos. Asegúrese de eliminar los duplicados.
  • Ahora, desde su script de construcción y antes de que el proceso de codesign se ejecute desde el desbloqueo de MyApp.keychain y MyApp.keychain como el predeterminado. Esto expone esos certificados como disponibles para codesign .
  • Finalmente, verifique de nuevo en su esclavo Jenkins: $ security find-identity -v -p codesigning que $ security find-identity -v -p codesigning que solo ve los certificados que ha incluido en MyApp.keychain y que no hay otras identidades de firma en el sistema. Si aún ve duplicados después de haber hecho esto, tiene otros lugares donde su esclavo Jenkins recibirá estos certificados.

No usamos Jenkins, pero ya he visto esto en nuestra automatización de compilación. Así es como lo resolvimos:

1) Crea tu llavero de construcción. Esto contendrá la clave privada / certificado utilizado para la designación de código:

security create-keychain -p [keychain_password] MyKeychain.keychain

La clave_contraseña es tu decisión. Lo usarás más tarde para desbloquear el llavero durante la compilación.

2) Importe la clave privada (* .p12) para su identidad de CodeSign:

security import MyPrivateKey.p12 -t agg -k MyKeychain.keychain -P [p12_Password] -A

La clave aquí es la bandera "-A". Esto permitirá el acceso al llavero sin previo aviso. Es por eso que está viendo el error "No se permite la interacción del usuario". Si intentaste construir esto a través de la interfaz de usuario de Xcode, este es el punto en el que te pediría "Permitir acceso" a tu llavero.

3) Sin embargo, estás guardando el llavero (por ej., Registrándolo en el control de la fuente), asegúrate de que sea editable y ejecutable por tu usuario de compilación.

Cuando esté listo para construir, agregue lo siguiente antes de ejecutar xcodebuild:

# Switch keychain security list-keychains -s "/path/to/MyKeyhain.keychain" security default-keychain -s "/path/to/MyKeychain.keychain" security unlock-keychain -p "[keychain_password]" "/path/to/MyKeychain.keychain"

Si está ejecutando localmente, es posible que desee agregar algo al final de su script de compilación que vuelva al inicio de sesión del llavero (~ / Library / Keychains / login.keychain), por ejemplo:

# Switch back to login keychain security list-keychains -s "~/Library/Keychains/login.keychain" security default-keychain -s "~/Library/Keychains/login.keychain"

Pruébalo. Creamos un Keychain por separado para cada identidad que usamos (nuestras propias compilaciones más en nombre de los clientes). En el caso de nuestra compañía, tenemos una AppStore y una cuenta Enterprise. Esto puede dar lugar a conflictos de nombres mientras se codifica (por ejemplo, ambas cuentas se resuelven en "Distribución de iPhone: ACME Corporation"). Al mantener estas identidades en llaveros separados, evitamos este conflicto.


Quité las llaves duplicadas de las cadenas de teclas (inicio de sesión y sistema) y comenzó a funcionar. Solo tenía un certificado pero muchas claves, así que tuve que filtrar las claves para verlas correctamente.


Se requiere para desbloquear el llavero antes de firmar "security unlock-keychain -p"