Jenkins no OS X: xcodebuild fornece erro de sinal de código

Summary:

A configuração do Jenkins no OS X ficou significativamente mais fácil com o instalador mais recente as de 1.449 - 9 de março de 2012), no entanto, gerenciar o processo de assinatura de código ainda é muito difícil, sem resposta diret

Motivação

Execute um servidor de IC sem cabeçalho que siga as práticas recomendadas comuns para executar serviços no OS X Alguns dos quais são explicados aqui em linguagem simples).

Fundo

12 de outubro de 2009 -Como automatizar as compilações de aplicativos para iPhone com o Hudson 15 de junho de 2011 - Jenkins no Mac OS X; chave pública git w / ssh 23 de junho de 2011 - Implantação contínua de aplicativos iOS com Jenkins e TestFlight 26 de julho de 2011 -Missing certificados e chaves no keychain ao usar Jenkins / Hudson como integração contínua para desenvolvimento iOS e Mac 30 de agosto de 2011 -Xcode Provisioning File não encontrado com Jenkins 20 de setembro de 2011 -Como configurar o Jenkins CI em um Mac 14 de setembro de 2011 -Getting Jenkins em execução em um Mac 12 de novembro de 2011 -Como: Instale o Jenkins no OS X e faça com que ele construa coisas para Mac 23 de janeiro de 2012 - Próximas alterações do instalador do Jenkins OSX 7 de março de 2012 - Obrigado por usar o OSX Installer

Processo

Instale o Jenkins CI via OS X pacote de instalação. Para a etapa "Tipo de instalação", clique no botão Personalizar e escolha "Iniciar na inicialização como 'jenkins.'"

Discussão

A expectativa ingênua neste momento era que um projeto de estilo livre com o script de construçãoxcodebuild -target MyTarget -sdk iphoneos Deveria trabalhar. Conforme indicado pelo título deste post, ele não falha e falha com:

Code Sign error: The identity 'iPhone Developer' doesn't match any valid certificate/private key pair in the default keychain

É óbvio o que precisa acontecer - você precisa adicionar um certificado de assinatura de código válido e uma chave privada ao chaveiro padrão. Ao pesquisar como fazer isso, não encontrei uma solução que não abra o sistema a algum nível de vulnerabilidad

Problema 1: nenhum chaveiro padrão para o daemon jenkins

sudo -u jenkins security default-keychain ... gera "Não foi possível encontrar um chaveiro padrão"

Conforme indicado abaixo porIvo Dancet, o UserShell está definido como / usr / bin / false para o daemon jenkins por padrão (acho que esse é um recurso, não um bug); siga sua resposta para alterar o UserShell para bash. Você pode usarsudo su jenkins para efetuar login como usuário jenkins e obter um prompt do bas

sudo su jenkinscd ~/Librarymkdir Keychainscd Keychainssecurity create-keychain <keychain-name>.keychainsecurity default-keychain -s <keychain-name>.keychain

Certo, ótimo. Temos um chaveiro padrão agora; vamos seguir em frente? Mas, primeiro, por que nos incomodamos em criar um chaveiro padrão?

Quase todas as respostas, sugestões ou conversas que eu li ao longo da pesquisa sugerem que você deve apenas inserir os códigos e chaves de assinatura de código no chaveiro do sistema. Se você executarsecurity list-keychains como um projeto de estilo livre em Jenkins, você vê que o único chaveiro disponível é o chaveiro do sistema; Acho que foi aí que a maioria das pessoas teve a ideia de colocar seu certificado e chave lá. Mas isso parece uma péssima idéia, principalmente porque você precisará criar um script de texto sem formatação com a senha para abrir o chaveiro.

Problema 2: Adicionando certificados de assinatura de código e chave privada

É aqui que eu realmente começo a ficar melindroso. Tenho a sensação de que devo criar uma nova chave pública / privada exclusiva para uso com o Jenkins. Meu processo de pensamento é se o daemon jenkins estiver comprometido, então eu posso revogar facilmente o certificado no Portal de provisionamento da Apple e gerar outra chave pública / privada. Se eu usar a mesma chave e certificado para minha conta de usuário e Jenkins, significa mais problemas (danos?) Se o serviço jenkins for atacad

Apontando paraSimon Urbanek's answer você estará desbloqueando o chaveiro de um script com uma senha de texto sem formatação. Parece irresponsável manter qualquer coisa, exceto certificados e chaves "descartáveis" nas chaves do daemon jenkin

Estou muito interessado em qualquer discussão em contrário. Estou sendo excessivamente cauteloso?

Para criar um novo CSR como o daemon jenkins no Terminal, fiz o seguinte ...

sudo su jenkinscerttool r CertificateSigningRequest.certSigningRequest Ser-lhe-á pedido o seguinte (a maioria deles fiz palpites com a resposta correta; você tem uma melhor visão? Por favor, compartilhe.) ...Insira a chave e o rótulo do certificado:Selecione o algoritmo:r (para RSA) Digite o tamanho da chave em bits:2048Selecione o algoritmo de assinatura:5 (para MD5)Insira a sequência de desafio:Então um monte de perguntas para o RDNEnvie o arquivo CSR gerado (CertificateSigningRequest.certSigningRequest) ao Portal de provisionamento da Apple sob um novo ID AppleAprove a solicitação e faça o download do arquivo .cersecurity unlock-keychainsecurity add-certificate ios_development.cer

Isso nos leva um passo mais perto ...

Problem 3: perfil de provisionamento e desbloqueio de chaveiro

Eu criei um perfil especial de provisionamento no Portal de provisionamento para uso com a CI, na esperança de que, se algo ruim acontecer, diminua o impacto. Prática recomendada ou excessivamente cautelosa?

sudo su jenkinsmkdir ~/Library/MobileDevicemkdir ~/Library/MobileDevice/Provisioning\ Profiles Mova o perfil de provisionamento configurado no Portal de provisionamento para essa nova pasta. Estamos agora a dois passos de podermos executar o xcodebuild a partir da linha de comando como jenkins, e isso significa que também estamos perto de conseguir que o Jenkins CI execute compilações.security unlock-keychain -p <keychain password>xcodebuild -target MyTarget -sdk iphoneos

Agora, obtemos uma compilação bem-sucedida a partir de uma linha de comando quando logado como o daemon jenkins; portanto, se criarmos um projeto de estilo livre e adicionarmos as duas etapas finais (nº 5 e nº 6 acima), poderemos automatizar a construção do nosso projeto iOS!

Pode não ser necessário, mas me senti melhor ao definir o jenkins UserShell de volta para / usr / bin / false, depois de obter toda essa configuração. Estou sendo paranóico?

Problema 4: o chaveiro padrão ainda não está disponíve

( EDIT: Publiquei as edições da minha pergunta, reiniciei para garantir que minha solução fosse 100% e, é claro, deixei de fora uma etapa)

Mesmo após todas as etapas acima, você precisará modificar o plist do Daemon de inicialização em /Library/LaunchDaemons/org.jenkins-ci.plist, conforme declarado emesta resposta. Observe que este também é umopenrdar bug.

Deve ficar assim:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>EnvironmentVariables</key>
        <dict>
                <key>JENKINS_HOME</key>
                <string>/Users/Shared/Jenkins/Home</string>
        </dict>
        <key>GroupName</key>
        <string>daemon</string>
        <key>KeepAlive</key>
        <true/>
        <key>Label</key>
        <string>org.jenkins-ci</string>
        <key>ProgramArguments</key>
        <array>
                <string>/bin/bash</string>
                <string>/Library/Application Support/Jenkins/jenkins-runner.sh</string>
        </array>
        <key>RunAtLoad</key>
        <true/>
        <key>UserName</key>
        <string>jenkins</string>
        <!-- **NEW STUFF** -->
        <key>SessionCreate</key>
        <true />
</dict>
</plist>

Com esta configuração, eu também recomendaria olugin @Xcode para Jenkins, o que facilita a configuração do script xcodebuild. Nesse ponto, eu também recomendo a leitura das páginas de manual do xcodebuild - diabos você chegou até aqui no Terminal, certo?

Esta configuração não é perfeita e qualquer conselho ou insight é muito apreciad

Eu tive dificuldade para selecionar uma resposta "correta", pois o que vim para resolver meu problema foi uma coleção de informações de quase todos. Eu tentei dar a todos pelo menos um voto positivo, mas conceda a resposta a Simon porque ele principalmente respondeu à pergunta original. Além disso, Sami Tikka merece muito crédito por seus esforços em fazer Jenkins trabalhar com o AppleScript como um aplicativo simples e antigo do OS X. Se você estiver interessado apenas em criar Jenkins e entrar rapidamente na sua sessão de usuário (ou seja, não como um servidor sem cabeça), a solução dele é muito mais parecida com o Mac.

Espero que meus esforços façam uma discussão mais aprofundada e ajude a próxima pobre coitada que aparecer pensando que pode instalar o Jenkins CI para seus projetos iOS em um fim de semana por causa de todas as coisas maravilhosas que ouviram falar sobre iss

Update: 9 de agosto de 2013

Com tantos votos positivos e favoritos, pensei em voltar a isso 18 meses depois com algumas breves lições aprendida

Lição 1: Não exponha Jenkins à Internet pública

Na WWDC 2012, levei essa pergunta aos engenheiros do Xcode e do OS X Server. Eu recebi uma cacofonia de "não faça isso!" de quem eu pedi. Todos eles concordaram que um processo de criação automatizado era ótimo, mas que o servidor só deveria estar acessível na rede local. Os engenheiros do OS X Server sugeriram a permissão de acesso remoto via VP

Lição 2: Existem novas opções de instalação agora

Fiz recentemente uma palestra no CocoaHeads sobre minha experiência com Jenkins e, para minha surpresa, encontrei alguns novos métodos de instalação - Homebrew e até umBitnami Mac App Store version. Definitivamente vale a pena conferir.Jonathan Wright tem uma essência que detalha como obterHomebrew Jenkins trabalhando.

Lição 3: Não, sério, não exponha sua caixa de criação à internet

É bastante claro pela postagem original que eu não sou um administrador de sistemas nem um especialista em segurança. O bom senso sobre coisas pessoais (chaveiros, credenciais, certificados etc.) me deixou bastante desconfortável ao colocar minha caixa de Jenkins na internet.Nick Arnott no Neglected Potential foi capaz de confirmar meus heebie-jeebies com bastante facilidade emEste artig.

TL; DR

A minha recomendação para outras pessoas que desejam automatizar seu processo de criação mudou no último ano e meio. Verifique se a sua máquina Jenkins está atrás do seu firewall. Instale e configure o Jenkins como um usuário dedicado do Jenkins, usando o instalador, a versão da Bitnami Mac App Store, o AppleScript de Sami Tikka, etc; isso resolve a maior parte da dor de cabeça que eu detalho acima. Se você precisar de acesso remoto, a configuração dos serviços VPN no OS X Server leva dez minutos no máximo. Uso essa configuração há mais de um ano e estou muito feliz com isso. Boa sorte

questionAnswers(22)

yourAnswerToTheQuestion