如何在 Gitlab CI 中为 android 管理签名密钥库
How to manage signing keystore in Gitlab CI for android
亲爱的 Whosebug 社区,我再次求助于您 :)
我最近遇到了 Gitlab 的奇迹及其非常好的捆绑 CI/CD 解决方案。然而,它工作得很好,我们都需要签署我们的二进制文件,不是吗,我发现没有办法上传密钥,就像我上传到 Jenkins 服务器那样。
那么,在构建发布时,我如何在不检查我的密钥和机密的情况下签署我的 android(实际上是 flutter)应用程序?
据我所知,大多数人使用引用未提交的 key.properties 文件并指定本地 keystore.jks 的签名设置来定义构建作业。这在本地构建 APK 时工作正常,但如果我想将它们作为 CI/CD 作业的一部分构建和存档,我该怎么做?
对于密钥,例如密钥库本身的密码,我发现我可以简单地将它们存储为受保护的变量,而不是实际的密钥库文件本身。我该怎么办?
非常欢迎任何想法和建议。
干杯
编辑:
我很抱歉从来没有在这里标记正确答案,因为@IvanP 提出了将单个值写入文件的解决方案,这是我长期使用的解决方案。但正如@VonC 后来补充的那样,Gitlab 现在可以将数据作为实际文件进行处理,这简化了这一点,所以我将其标记为正确答案。
我已经使用 git-secret in the past to check-in password protected secret files. Then pass the password via a secret/protected environmental variable(如您所知)并修改了 .gitlab-ci.yml 以使用密码打开文件并使用它们。
通常我将密钥库文件(作为 base64 字符串)、别名和密码存储到 Gitlab 的秘密变量中。
在 .gitlab-ci.yml 中执行如下操作:
create_property_files:
stage: prepare
only:
- master
script:
- echo $KEYSTORE | base64 -d > my.keystore
- echo "keystorePath=my.keystore" > signing.properties
- echo "keystorePassword=$KEYSTORE_PASSWORD" >> signing.properties
- echo "keyAlias=$ALIAS" >> signing.properties
- echo "keyPassword=$KEY_PASSWORD" >> signing.properties
artifacts:
paths:
- my.keystore
- signing.properties
expire_in: 10 mins
最后,在您的构建中 gradle:
signingConfigs {
release {
file("../signing.properties").with { propFile ->
if (propFile.canRead()) {
def properties = new Properties()
properties.load(new FileInputStream(propFile))
storeFile file(properties['keystorePath'])
storePassword properties['keystorePassword']
keyAlias properties['keyAlias']
keyPassword properties['keyPassword']
} else {
println 'Unable to read signing.properties'
}
}
}
}
感谢@IvanP 的回答,但我必须对 Gitlab 管道进行一些更改才能使其正常工作。
将密钥库导出为 base64 字符串:
openssl base64 -A -in my.keystore > base64
创建一个新变量并将值复制粘贴到文件 base64 中。这样做时要小心,我搞砸了格式,管道无法解码密钥库。变量必须用 ${} 引用,而不仅仅是 $.
- echo -n ${ANDROID_KEYSTORE} | base64 -d > my.keystore
- echo "keystorePath=../my.keystore" > myapp.properties
- echo "keystorePassword=${KEYSTORE_PASSWORD}" >> myapp.properties
- echo "keyAlias=${ALIAS_NAME}" >> myapp.properties
- echo "keyPassword=${KEY_PASSWORD}" >> myapp.properties
参考上面@IvanP 的回答中解释的 build.gradle 中的 myapp.properties。
来自IvanP's :
Usually I store keystore file (as base64 string), alias and passwords to Gitlab's secrets variables.
GitLab 15.0(2022 年 5 月)
应该更容易
Project-level Secure Files in open beta
Previously, it was difficult to use binary files in your CI/CD pipelines because CI/CD variables could only contain text values. This made it difficult to make use of profiles, certificates, keystores, and other secure information, which are important for teams building mobile apps.
Today we are releasing Project-level Secure Files in open beta. Now you can upload binary files to projects in GitLab, and include those files in CI/CD jobs to be used in the build and release processes as needed. Secure Files are stored outside of version control and are not part of the project repository.
Please leave us your feedback about your experience with this feature in the feedback issue.
See Documentation and Issue.
亲爱的 Whosebug 社区,我再次求助于您 :)
我最近遇到了 Gitlab 的奇迹及其非常好的捆绑 CI/CD 解决方案。然而,它工作得很好,我们都需要签署我们的二进制文件,不是吗,我发现没有办法上传密钥,就像我上传到 Jenkins 服务器那样。
那么,在构建发布时,我如何在不检查我的密钥和机密的情况下签署我的 android(实际上是 flutter)应用程序?
据我所知,大多数人使用引用未提交的 key.properties 文件并指定本地 keystore.jks 的签名设置来定义构建作业。这在本地构建 APK 时工作正常,但如果我想将它们作为 CI/CD 作业的一部分构建和存档,我该怎么做?
对于密钥,例如密钥库本身的密码,我发现我可以简单地将它们存储为受保护的变量,而不是实际的密钥库文件本身。我该怎么办?
非常欢迎任何想法和建议。 干杯
编辑: 我很抱歉从来没有在这里标记正确答案,因为@IvanP 提出了将单个值写入文件的解决方案,这是我长期使用的解决方案。但正如@VonC 后来补充的那样,Gitlab 现在可以将数据作为实际文件进行处理,这简化了这一点,所以我将其标记为正确答案。
我已经使用 git-secret in the past to check-in password protected secret files. Then pass the password via a secret/protected environmental variable(如您所知)并修改了 .gitlab-ci.yml 以使用密码打开文件并使用它们。
通常我将密钥库文件(作为 base64 字符串)、别名和密码存储到 Gitlab 的秘密变量中。
在 .gitlab-ci.yml 中执行如下操作:
create_property_files:
stage: prepare
only:
- master
script:
- echo $KEYSTORE | base64 -d > my.keystore
- echo "keystorePath=my.keystore" > signing.properties
- echo "keystorePassword=$KEYSTORE_PASSWORD" >> signing.properties
- echo "keyAlias=$ALIAS" >> signing.properties
- echo "keyPassword=$KEY_PASSWORD" >> signing.properties
artifacts:
paths:
- my.keystore
- signing.properties
expire_in: 10 mins
最后,在您的构建中 gradle:
signingConfigs {
release {
file("../signing.properties").with { propFile ->
if (propFile.canRead()) {
def properties = new Properties()
properties.load(new FileInputStream(propFile))
storeFile file(properties['keystorePath'])
storePassword properties['keystorePassword']
keyAlias properties['keyAlias']
keyPassword properties['keyPassword']
} else {
println 'Unable to read signing.properties'
}
}
}
}
感谢@IvanP 的回答,但我必须对 Gitlab 管道进行一些更改才能使其正常工作。
将密钥库导出为 base64 字符串:
openssl base64 -A -in my.keystore > base64
创建一个新变量并将值复制粘贴到文件 base64 中。这样做时要小心,我搞砸了格式,管道无法解码密钥库。变量必须用 ${} 引用,而不仅仅是 $.
- echo -n ${ANDROID_KEYSTORE} | base64 -d > my.keystore
- echo "keystorePath=../my.keystore" > myapp.properties
- echo "keystorePassword=${KEYSTORE_PASSWORD}" >> myapp.properties
- echo "keyAlias=${ALIAS_NAME}" >> myapp.properties
- echo "keyPassword=${KEY_PASSWORD}" >> myapp.properties
参考上面@IvanP 的回答中解释的 build.gradle 中的 myapp.properties。
来自IvanP's
Usually I store keystore file (as base64 string), alias and passwords to Gitlab's secrets variables.
GitLab 15.0(2022 年 5 月)
应该更容易Project-level Secure Files in open beta
Previously, it was difficult to use binary files in your CI/CD pipelines because CI/CD variables could only contain text values. This made it difficult to make use of profiles, certificates, keystores, and other secure information, which are important for teams building mobile apps.
Today we are releasing Project-level Secure Files in open beta. Now you can upload binary files to projects in GitLab, and include those files in CI/CD jobs to be used in the build and release processes as needed. Secure Files are stored outside of version control and are not part of the project repository.
Please leave us your feedback about your experience with this feature in the feedback issue.
See Documentation and Issue.