security: 修复 CI/Release workflow 签名凭据风险
- 所有 action 引用改为 commit SHA pin(checkout/setup-java/setup-android/action-gh-release/upload-artifact) - build.gradle.kts 移除硬编码签名密码 fallback,改用 takeIf 防御 null 和空字符串 - release.yml 构建完成后清理 release.jks(if: always()) - ci.yml 补充最小权限声明 permissions: contents: read
This commit is contained in:
parent
172d6b61aa
commit
f203149f4f
29
.github/workflows/ci.yml
vendored
29
.github/workflows/ci.yml
vendored
@ -5,17 +5,20 @@ on:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: Unit Tests & Lint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-java@v4
|
||||
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
|
||||
- uses: actions/setup-java@cf277c60eb25467037889841efdb72551f06f6c3 # v4
|
||||
with:
|
||||
java-version: '17'
|
||||
distribution: 'temurin'
|
||||
- uses: android-actions/setup-android@v3
|
||||
- uses: android-actions/setup-android@9fc6c4e9069bf8d3d10b2204b1fb8f6ef7065407 # v3
|
||||
with:
|
||||
packages: 'platforms;android-35 build-tools;35.0.0'
|
||||
|
||||
@ -27,7 +30,7 @@ jobs:
|
||||
|
||||
- name: Upload test results
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
||||
with:
|
||||
name: unit-test-results
|
||||
path: app/build/test-results/testDebugUnitTest/*.xml
|
||||
@ -38,7 +41,7 @@ jobs:
|
||||
|
||||
- name: Upload lint results
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
||||
with:
|
||||
name: lint-results
|
||||
path: app/build/reports/lint-results-debug.*
|
||||
@ -49,12 +52,12 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
needs: test
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-java@v4
|
||||
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
|
||||
- uses: actions/setup-java@cf277c60eb25467037889841efdb72551f06f6c3 # v4
|
||||
with:
|
||||
java-version: '17'
|
||||
distribution: 'temurin'
|
||||
- uses: android-actions/setup-android@v3
|
||||
- uses: android-actions/setup-android@9fc6c4e9069bf8d3d10b2204b1fb8f6ef7065407 # v3
|
||||
with:
|
||||
packages: 'platforms;android-35 build-tools;35.0.0'
|
||||
|
||||
@ -65,7 +68,7 @@ jobs:
|
||||
run: ./gradlew assembleDebug
|
||||
|
||||
- name: Upload Debug APK
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
||||
with:
|
||||
name: debug-apk
|
||||
path: app/build/outputs/apk/debug/app-debug.apk
|
||||
@ -76,12 +79,12 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
needs: test
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-java@v4
|
||||
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
|
||||
- uses: actions/setup-java@cf277c60eb25467037889841efdb72551f06f6c3 # v4
|
||||
with:
|
||||
java-version: '17'
|
||||
distribution: 'temurin'
|
||||
- uses: android-actions/setup-android@v3
|
||||
- uses: android-actions/setup-android@9fc6c4e9069bf8d3d10b2204b1fb8f6ef7065407 # v3
|
||||
with:
|
||||
packages: 'platforms;android-35 build-tools;35.0.0'
|
||||
|
||||
@ -119,7 +122,7 @@ jobs:
|
||||
echo "✅ APK integrity verified: manifest + arsc + res/ all present"
|
||||
|
||||
- name: Upload Release APK
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
||||
with:
|
||||
name: release-apk
|
||||
path: app/build/outputs/apk/release/app-release.apk
|
||||
|
||||
11
.github/workflows/release.yml
vendored
11
.github/workflows/release.yml
vendored
@ -10,12 +10,12 @@ jobs:
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-java@v4
|
||||
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
|
||||
- uses: actions/setup-java@cf277c60eb25467037889841efdb72551f06f6c3 # v4
|
||||
with:
|
||||
java-version: '17'
|
||||
distribution: 'temurin'
|
||||
- uses: android-actions/setup-android@v3
|
||||
- uses: android-actions/setup-android@9fc6c4e9069bf8d3d10b2204b1fb8f6ef7065407 # v3
|
||||
with:
|
||||
packages: 'platforms;android-35 build-tools;35.0.0'
|
||||
- name: Decode Keystore
|
||||
@ -28,10 +28,13 @@ jobs:
|
||||
run: |
|
||||
chmod +x gradlew
|
||||
./gradlew assembleRelease
|
||||
- name: Cleanup keystore (always run for security)
|
||||
run: rm -f release.jks
|
||||
if: always()
|
||||
- name: Rename & Release
|
||||
run: |
|
||||
cp app/build/outputs/apk/release/app-release.apk "RainyToken-${GITHUB_REF#refs/tags/}.apk"
|
||||
- uses: softprops/action-gh-release@v2
|
||||
- uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2
|
||||
with:
|
||||
name: "🎉 RainyToken ${{ github.ref_name }}"
|
||||
files: RainyToken-${{ github.ref_name }}.apk
|
||||
|
||||
@ -32,9 +32,18 @@ android {
|
||||
val keystoreFile = rootProject.file("release.jks")
|
||||
if (keystoreFile.exists()) {
|
||||
storeFile = keystoreFile
|
||||
storePassword = System.getenv("KEYSTORE_PASSWORD") ?: "RainyToken2026!"
|
||||
keyAlias = System.getenv("KEYSTORE_ALIAS") ?: "rainy"
|
||||
keyPassword = System.getenv("KEY_PASSWORD") ?: "RainyToken2026!"
|
||||
// 凭据必须通过环境变量注入;缺失或为空时直接报错,不提供任何隐式 fallback
|
||||
// 注意:GitHub Actions 中未设置的 secret 会被替换为空字符串(非 null),
|
||||
// 因此用 takeIf { isNotBlank() } 同时防御 null 和空字符串
|
||||
storePassword = System.getenv("KEYSTORE_PASSWORD")
|
||||
?.takeIf { it.isNotBlank() }
|
||||
?: throw GradleException("KEYSTORE_PASSWORD env var not set or empty — cannot sign release")
|
||||
keyAlias = System.getenv("KEYSTORE_ALIAS")
|
||||
?.takeIf { it.isNotBlank() }
|
||||
?: throw GradleException("KEYSTORE_ALIAS env var not set or empty — cannot sign release")
|
||||
keyPassword = System.getenv("KEY_PASSWORD")
|
||||
?.takeIf { it.isNotBlank() }
|
||||
?: throw GradleException("KEY_PASSWORD env var not set or empty — cannot sign release")
|
||||
} else {
|
||||
// 仅在 CI 环境中 fallback 到 debug keystore(用于编译/资源完整性验证)
|
||||
// 本地构建缺少 release.jks 时直接报错,避免静默生成 debug 签名的 Release APK
|
||||
|
||||
Loading…
Reference in New Issue
Block a user