Resumo:
Configurar o Jenkins no OS X ficou significativamente mais fácil com o instalador mais recente ( de 1.449 - 9 de março de 2012 ), no entanto, gerenciar o processo de assinatura de código ainda é muito difícil sem uma resposta direta.
Motivação:
Execute um servidor CI sem periférico que segue as práticas recomendadas comuns para a execução de serviços no OS X ( algumas das quais são explicadas aqui em linguagem simples ).
Fundo:
- 12 de outubro de 2009 - Como automatizar as compilações de seu aplicativo para iPhone com Hudson
- 15 de junho de 2011 - Jenkins no Mac OS X; git com chave pública ssh
- 23 de junho de 2011 - implantação contínua de aplicativos iOS com Jenkins e TestFlight
- 26 de julho de 2011 - Certificados e chaves ausentes nas chaves ao usar Jenkins / Hudson como integração contínua para desenvolvimento iOS e Mac
- 30 de agosto de 2011 - Arquivo de provisionamento Xcode não encontrado com Jenkins
- 20 de setembro de 2011 - Como configurar o Jenkins CI em um Mac
- 14 de setembro de 2011 - Fazendo o Jenkins rodar em um Mac
- 12 de novembro de 2011 - Howto: Instale o Jenkins no OS X e faça com que ele crie coisas para Mac
- 23 de janeiro de 2012 - Próximas mudanças no instalador do Jenkins OSX
- 7 de março de 2012 - Obrigado por usar o OSX Installer
Processo:
Instale 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 ponto era que um projeto de estilo livre com o script de construção xcodebuild -target MyTarget -sdk iphoneos
deveria funcionar. Conforme indicado pelo título desta postagem, ele não funciona e falha com:
Code Sign error: The identity 'iPhone Developer' doesn't match any valid certificate/private key pair in the default keychain
É bastante óbvio o que precisa acontecer - você precisa adicionar um certificado de assinatura de código válido e uma chave privada nas chaves padrão. Ao pesquisar como fazer isso, não encontrei uma solução que não abra o sistema a algum nível de vulnerabilidade.
Problema 1: nenhum keychain padrão para daemon jenkins
sudo -u jenkins security default-keychain
... produz "Não foi possível encontrar um chaveiro padrão"
Conforme apontado abaixo por Ivo Dancet , o UserShell é definido como / usr / bin / false para o daemon jenkins por padrão (acho que isso é um recurso, não um bug); siga sua resposta para alterar o UserShell para bash. Você pode usar sudo su jenkins
para fazer o login como o usuário jenkins e obter um prompt do bash.
sudo su jenkins
cd ~/Library
mkdir Keychains
cd Keychains
security create-keychain <keychain-name>.keychain
security default-keychain -s <keychain-name>.keychain
Certo, ótimo. Agora temos um chaveiro padrão; vamos seguir em frente certo? Mas, primeiro, por que nos incomodamos em fazer um chaveiro padrão?
Quase todas as respostas, sugestões ou conversas que li ao longo da pesquisa sugerem que se deve apenas jogar seus certificados de assinatura de código e chaves nas chaves do sistema. Se você executar security list-keychains
como um projeto de estilo livre no Jenkins, verá que as únicas chaves disponíveis são as 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 ideia - especialmente considerando que você precisará criar um script de texto simples com a senha para abrir as chaves .
Problema 2: Adicionar certificados de assinatura de código e chave privada
É aqui que eu realmente começo a ficar enjoado. Tenho a sensação de que devo criar uma nova chave pública / privada exclusiva para uso com Jenkins. Meu processo de pensamento é, se o daemon jenkins estiver comprometido, posso facilmente revogar 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, isso significa mais problemas (danos?) Se o serviço jenkins for atacado.
Apontando para a resposta de Simon Urbanek, você estará desbloqueando o chaveiro de um script com uma senha em texto simples. Parece irresponsável manter qualquer coisa, exceto certificados e chaves "descartáveis" nas chaves do daemon jenkins.
Estou muito interessado em qualquer discussão em contrário. Estou sendo excessivamente cauteloso?
Para fazer um novo CSR como o daemon jenkins no Terminal, fiz o seguinte ...
sudo su jenkins
certtool r CertificateSigningRequest.certSigningRequest
Você será solicitado a responder o seguinte (a maioria dessas eu fiz suposições fundamentadas na resposta correta; você tem uma visão melhor? Por favor, compartilhe.) ...- Insira a chave e a etiqueta do certificado:
- Selecione o algoritmo:
r
(para RSA) - Insira o tamanho da chave em bits:
2048
- Selecione o algoritmo de assinatura:
5
(para MD5) - Insira a string de desafio:
- Em seguida, um monte de perguntas para RDN
- Envie o arquivo CSR gerado (CertificateSigningRequest.certSigningRequest) para o Portal de aprovisionamento da Apple com um novo ID Apple
- Aprove a solicitação e baixe o arquivo .cer
security unlock-keychain
security add-certificate ios_development.cer
Isso nos leva um passo mais perto ...
Problema 3: perfil de provisionamento e desbloqueio de chaves
Fiz um perfil de provisionamento especial no Portal de provisionamento apenas para uso com CI, na esperança de que, se algo ruim acontecer, eu diminua um pouco o impacto. Melhor prática ou excessivamente cauteloso?
sudo su jenkins
mkdir ~/Library/MobileDevice
mkdir ~/Library/MobileDevice/Provisioning\ Profiles
- Mova o perfil de provisionamento que você configurou no Portal de provisionamento para esta nova pasta. Estamos agora a dois passos de poder executar xcodebuild a partir da linha de comando como jenkins, e isso significa que também estamos perto de conseguir fazer o Jenkins CI rodar compilações.
security unlock-keychain -p <keychain password>
xcodebuild -target MyTarget -sdk iphoneos
Agora obtemos uma construção bem-sucedida de uma linha de comando quando conectado como o daemon jenkins, então se criarmos um projeto de estilo livre e adicionarmos essas duas etapas finais (# 5 e # 6 acima), seremos capazes de automatizar a construção de nosso projeto iOS!
Pode não ser necessário, mas me senti melhor configurando o jenkins UserShell de volta para / usr / bin / false depois de obter toda essa configuração. Estou sendo paranóico?
Problema 4: chaveiro padrão ainda não disponível!
( EDITAR: postei as edições da minha pergunta, reiniciei para ter certeza de que minha solução era 100% e, claro, deixei uma etapa de fora )
Mesmo depois de todas as etapas acima, você precisará modificar o plist Launch Daemon em /Library/LaunchDaemons/org.jenkins-ci.plist conforme declarado nesta resposta . Observe que este também é um bug do openrdar .
Deve ser 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 essa configuração, eu também recomendaria o plugin Xcode para Jenkins , que torna a configuração do script xcodebuild um pouco mais fácil. Nesse ponto, eu também recomendo ler as páginas de manual do xcodebuild - diabos, você chegou até aqui no Terminal, certo?
Esta configuração não é perfeita e qualquer conselho ou visão é muito apreciado.
Tive dificuldade em selecionar uma resposta "correta", pois o que passei a usar para resolver meu problema foi uma coleção de opiniões de quase todos. Tentei dar a todos pelo menos um voto favorável, mas conceda a resposta a Simon porque ele respondeu principalmente à pergunta original. Além disso, Sami Tikka merece muito crédito por seus esforços para fazer o Jenkins funcionar por meio do AppleScript como um aplicativo OS X simples e antigo. Se você está interessado apenas em fazer o Jenkins funcionar rapidamente na sua sessão de usuário (ou seja, não como um servidor sem comando), sua solução é muito mais semelhante a um Mac.
Espero que meus esforços gerem mais discussões e ajudem a próxima pobre alma que vier pensando que pode configurar o Jenkins CI para seus projetos iOS em um fim de semana por causa de todas as coisas maravilhosas que ouviram sobre isso.
Atualização: 9 de agosto de 2013
Com tantos votos positivos e favoritos, pensei em voltar a isso 18 meses depois com algumas breves lições aprendidas.
Lição 1: não exponha o Jenkins à Internet pública
No WWDC de 2012, levei essa pergunta aos engenheiros do Xcode e do OS X Server. Recebi uma cacofonia de "não faça isso!" de qualquer pessoa a quem eu perguntei. Todos concordaram que um processo de construção automatizado era ótimo, mas que o servidor só deveria estar acessível na rede local. Os engenheiros do OS X Server sugeriram permitir o acesso remoto via VPN.
Lição 2: Existem novas opções de instalação agora
Recentemente, dei uma palestra no CocoaHeads sobre minha experiência com o Jenkins e, para minha surpresa, encontrei alguns novos métodos de instalação - Homebrew e até mesmo uma versão Bitnami Mac App Store . Definitivamente vale a pena conferir. Jonathan Wright tem uma essência que detalha como o Homebrew Jenkins funciona .
Lição 3: Não, sério, não exponha sua caixa de construção à Internet
Ficou bem claro na postagem original que não sou um administrador de sistema nem um especialista em segurança. O bom senso sobre coisas privadas (chaveiros, credenciais, certificados, etc.) me deixou bastante desconfortável em colocar minha caixa Jenkins na Internet. Nick Arnott, da Neglected Potential, foi capaz de confirmar meus heebie-jeebies com bastante facilidade neste artigo .
TL; DR
Minha recomendação para outras pessoas que buscam automatizar seu processo de criação mudou no último ano e meio. Certifique-se de que sua máquina Jenkins esteja protegida por firewall. Instale e configure o Jenkins como um usuário dedicado do Jenkins usando o instalador, a versão Bitnami Mac App Store, o AppleScript de Sami Tikka, etc; isso resolve a maior parte da dor de cabeça que detalhei acima. Se você precisar de acesso remoto, configurar serviços VPN no OS X Server leva no máximo dez minutos. Eu uso essa configuração há mais de um ano e estou muito feliz com isso. Boa sorte!
Respostas:
As chaves precisam ser desbloqueadas antes de serem usadas. Você pode usar
security unlock-keychain
para desbloquear. Você pode fazer isso de forma interativa (mais seguro) ou especificando a senha na linha de comando (não seguro), por exemplo:Obviamente, colocar isso em um script compromete a segurança desse keychain, então muitas vezes as pessoas configuram um keychain individual com apenas as credenciais de assinatura para minimizar tais danos.
Normalmente,
Terminal
as chaves já estão desbloqueadas pela sua sessão, uma vez que as chaves padrão são desbloqueadas no login, então você não precisa fazer isso. No entanto, qualquer processo não executado em sua sessão não terá as chaves desbloqueadas, mesmo se tiver você como o usuário (mais comumente isso afetassh
, mas também qualquer outro processo).fonte
security unlock-keychain -p password -k /path/codesign.keychain
não funciona.-k
argumento para,unlock-keychain
portanto, tudo o que você está tentando fazer não parece certo (consulte Recursossecurity help unlock-keychain
).sudo -u jenkins bash
) e verificar se você tem as permissões corretas em todo o caminho. Você fez muitas coisas que não disse (como usardscl
para criar o usuário), então está realmente por conta própria. Você também vai querer verificar a configuração inicial (dependendo se você configurou o shell ou não, você pode usarsudo -u jenkins -i
para obter as configurações de login correspondentes).Suponha que você também queira fazer distribuição ad hoc por meio do Jenkins, isso exige que o Jenkins tenha acesso a um certificado de distribuição e à identidade do administrador da equipe, além dos perfis de provisionamento.
Usando uma identidade exportada em um arquivo .cer, você pode importá-la programaticamente dessa forma, a opção -A é para permitir que todos os programas acessem esta entrada. Como alternativa, você pode usar várias
-T /path/to/program
opções para permitircodesign
excodebuild
acessar:Claro, também devemos ter o certificado Apple WWDCRA, importado praticamente da mesma maneira:
No entanto, também precisamos da chave privada para o
devcertificate.cer
. Para fazer isso, você precisa exportar a chave privada correspondente como uma chave .p12 e definir uma senha. Coloque-o em algum lugar onde possa acessá-lo do shell do Jenkins, desbloquear o chaveiro e importá-lo:A importação do certificado de distribuição funciona da mesma maneira. Não sei por que você precisa desbloquear o chaveiro para importar um .p12 e não para um .cer, mas bem.
Você também precisará acessar os perfis de provisionamento. Em breve, editarei essas instruções nesta postagem.
fonte
Eu tive o mesmo problema e estou procurando por uma resposta há algum tempo. Aqui está uma coisa que aprendi.
Estou executando jenkins como o usuário jenkins, usuário criado pelo instalador e, como todos os outros mencionaram, ele não tem acesso às mesmas chaves que seu usuário normal. Em vez de tentar fazer login como o usuário jenkins, criei um segundo projeto de compilação que simplesmente tem uma etapa de compilação que é "Executar Shell", na qual executo comandos que desejo testar como o usuário jenkins.
Depois de configurar, eu poderia executar o comando
security list-keychains
E isso me revelou que a única coisa que Jenkins conseguia ver era o chaveiro do sistema.
Com esse conhecimento, abri o aplicativo Keychain Access e copiei meu certificado "iPhone Developer: xxxx" no keychain System (clique com o botão direito, copie do keychain "login").
Isso me fez passar o erro de sinal de código do par de certificado / chave privada, mas abriu outro com o perfil de provisionamento (parece um problema semelhante, mas diferente).
fonte
Para alterar a senha, você pode usar
sudo passwd jenkins <new-pw>
. No entanto, acho que seria melhor usar o comando dscl para alterar a senha.Na minha instalação, jenkins (instalador oficial) tinha um shell de usuário / usr / bin / false. Alterá-lo para bash resolveu o problema de não conseguir fazer o login:
Agora você deve conseguir fazer o login com
su jenkins
.fonte
create-keychain
comando que não funcionava com o usuário jenkins. A execução deste comando pareceu resolver o problema.Eu usei o plugin Xcode para construir o aplicativo iOS. Na configuração de um projeto.
escolha Adicionar etapa de compilação> Xcode> assinatura de código e opções de chaveiro do OS X.
marque a caixa Desbloquear chaveiro e adicione o seguinte (para exemplos)
às vezes, se eu obtiver o erro
Vou reabrir o Jenkins e inserir a senha novamente para desbloquear
fonte
Para pessoas com problemas com chaveiros, eu recomendo que você experimente meu instalador alternativo do Jenkins em https://github.com/stisti/jenkins-app , downloads em https://github.com/stisti/jenkins-app/downloads
Jenkins.app executa Jenkins em sua sessão de usuário, portanto, problemas de acesso de keychain não são um problema :)
fonte
Se você tiver sudo, poderá usar passwd para alterar a senha do usuário Jenkins. Então você pode obter a senha do Jenkins.
Além disso, não tenho certeza se esse é o problema para você, mas o ANT Script que uso via Jenkins tem o seguinte:
fonte
Por alguma razão, o utilitário de "segurança" não estava funcionando para mim no Lion com a nova instalação do Jenkins.
Depois de "sudo su jenkins", ele foi capaz de criar novas chaves, mas ignorou silenciosamente todos os comandos "default-keychain -s ..." ou "unlock", retornando o status de saída zero e não imprimindo nada no console. A lista de keychains padrão ou de login não deu nada, a lista de pesquisa de keychains continha apenas keychain do sistema e eu não pude alterar isso seja lá o que for que digito.
Depois que eu loguei na área de trabalho do usuário e iniciei o Keychain Utility, ele mostrou meu keychain criado e depois disso tudo funcionou conforme descrito nos posts superiores.
Estou me perguntando se algum comportamento inicial do chaveiro mudou no Lion ou estou faltando alguma coisa?
fonte
Eu adicionei a chave privada e pública da empresa ao chaveiro. Eu adicionei os perfis de provisão para a produção que irei construir.
Como esse usuário não tinha uma conta, eu entrei no devcenter com minha conta. Baixou os certificados de provisionamento e os carregou no Xcode.
Não adicionei um certificado especificamente para a conta de função de construção, por exemplo, Jenkins.
Eu adicionei isso ao script de construção: security unlock-keychain -p mySecretPassword como acima, mas ...
Eu criei um arquivo ~ / .ssh / mypass e adicionei a senha ao arquivo.
Em seguida, o comando se torna: security unlock-keychain -p
cat ~/.ssh/mypass
Builds estão funcionando como um campeão. Pego o arquivo ipa, ele carrega na central de aplicativos e funciona no dispositivo.
fonte
Também pode instalar e iniciar o JenkinsCI como um usuário OS X em vez de um daemon:
http://127.0.0.1:8080
sudo launchctl unload /Library/LaunchDaemons/org.jenkins-ci.plist
/Applications/Jenkins/jenkins.war
http://127.0.0.1:8080
fonte
Para resolver esse problema, tente fazer login em http://appleid.apple.com e atualize suas perguntas de segurança.
Isso me ajudou.
fonte