DevOps and Security
SKILL.md
DevOps and Security (DevOps 与资安)
Instructions
- 仅在发布准备或流程自动化需求时使用
- 先填写 Required Inputs(CI 平台、签章策略、密钥来源)
- 依照下方章节顺序套用
- 一次只处理一个 pipeline 或安全措施
- 完成后对照 Quick Checklist
When to Use
- Scenario E:App 发布准备
Example Prompts
- "请依照 Build Speed Optimization,调整 Gradle 设置"
- "用 CI Quality Gates 章节创建 GitHub Actions"
- "请参考 Security Hardening,检查 secrets 与网络安全"
Workflow
- 先确认 Required Inputs(CI provider、发布渠道、secret 管理)
- 创建 Build Speed 与 CI Quality Gates
- 导入 Fastlane 与 Security Hardening
- 执行 Delivery Gate 并记录发布演练结果
- 用 Quick Checklist 验收
Practical Notes (2026)
- 依赖来源与版本必有审核与锁定策略
- Secrets 仅能通过环境变量或安全保存
- CI Gate 必含 Lint/Detekt/Test/Build
- Pipeline 失败要可重现,禁止人工临时绕过
- 发布流程至少每月 dry-run 一次,避免到发布日失效
Minimal Template
目标:
CI Gate:
CI Provider:
Secrets 来源:
安全措施:
发版流程:
验收: Quick Checklist
Required Inputs (执行前输入)
CI provider(GitHub Actions / GitLab CI / Jenkins)发布渠道(Play Internal/Alpha/Production)Secret 管理策略(CI Secret / Vault / KMS)签章策略(keystore 来源、轮换周期)阻挡条件(哪些任务失败即阻挡发布)
Deliverables (完成后交付物)
- 可执行
CI pipeline(lint/detekt/test/assemble) 发布流水线(Fastlane 或等效脚本)安全加固配置(Network Security / Pinning / Secret policy)告警与追踪(失败通知、日志可追溯)发布演练记录(dry-run 结果)
Delivery Gate (验收门槛)
./gradlew lint detekt test assemble
./gradlew bundleRelease
若使用 Fastlane,需补跑
fastlane lane的 dry-run 或 internal track 发布演练。
Build Speed Optimization
Configuration Cache
// gradle.properties
org.gradle.configuration-cache=true
org.gradle.configuration-cache.problems=warn
Build Cache
// settings.gradle.kts
buildCache {
local {
directory = File(rootDir, "build-cache")
removeUnusedEntriesAfterDays = 7
}
// 企业级:Remote cache
remote<HttpBuildCache> {
url = uri("https://cache.example.com/")
isPush = System.getenv("CI") != null
}
}
Parallel Execution
// gradle.properties
org.gradle.parallel=true
org.gradle.caching=true
org.gradle.jvmargs=-Xmx4g -XX:+HeapDumpOnOutOfMemoryError
CI Quality Gates
GitHub Actions 范例
name: Android CI
on:
pull_request:
branches: [main, develop]
jobs:
quality:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup JDK
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
- name: Lint
run: ./gradlew lintDebug
- name: Detekt
run: ./gradlew detekt
- name: Unit Tests
run: ./gradlew testDebugUnitTest
- name: Build
run: ./gradlew assembleDebug
Danger for PR Review
# Dangerfile
# APK Size Check
apk_size = File.size("app/build/outputs/apk/debug/app-debug.apk") / 1024.0 / 1024.0
warn "APK size is #{apk_size.round(2)}MB" if apk_size > 50
# Kotlin Files changed
kotlin_files = git.modified_files.select { |f| f.end_with?(".kt") }
warn "Large PR with #{kotlin_files.count} Kotlin files" if kotlin_files.count > 20
Fastlane Automation
Fastfile
default_platform(:android)
platform :android do
desc "Deploy to Play Store Internal Track"
lane :internal do
gradle(task: "bundleRelease")
upload_to_play_store(
track: "internal",
aab: "app/build/outputs/bundle/release/app-release.aab"
)
end
desc "Promote Internal to Production"
lane :promote do
upload_to_play_store(
track: "internal",
track_promote_to: "production",
skip_upload_apk: true,
skip_upload_aab: true
)
end
end
Security Hardening
Secrets Management
// ❌ 不要把真实密钥写进 BuildConfig / strings.xml / assets
// ✅ 用 secrets-gradle-plugin 管理「可公开但需分环境」的配置
// build.gradle.kts
plugins {
id("com.google.android.libraries.mapsplatform.secrets-gradle-plugin")
}
secrets {
propertiesFileName = "secrets.properties" // 本地/CI 注入,不进版控
defaultPropertiesFileName = "local.defaults.properties" // 可提交的占位值
}
// 真正敏感凭证:由后端签发短时 token,不内置在 APK
interface TokenApi {
suspend fun getEphemeralToken(): String
}
secrets.properties
local.properties
Certificate Pinning
// OkHttp
val certificatePinner = CertificatePinner.Builder()
.add("example.com", "sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=")
.build()
val client = OkHttpClient.Builder()
.certificatePinner(certificatePinner)
.build()
Root Detection
class RootDetection {
fun isDeviceRooted(): Boolean {
return checkRootBinaries() || checkSuExists() || checkRootCloaking()
}
private fun checkRootBinaries(): Boolean {
val paths = arrayOf("/system/bin/su", "/system/xbin/su", "/sbin/su")
return paths.any { File(it).exists() }
}
}
Network Security Config
<!-- res/xml/network_security_config.xml -->
<network-security-config>
<base-config cleartextTrafficPermitted="false">
<trust-anchors>
<certificates src="system" />
</trust-anchors>
</base-config>
<domain-config>
<domain includeSubdomains="true">example.com</domain>
<pin-set>
<pin digest="SHA-256">...</pin>
</pin-set>
</domain-config>
</network-security-config>
Quick Checklist
- Required Inputs 已填写并冻结(CI/发布/密钥策略)
- Build Cache 激活 (Local + Remote)
- CI 包含 Lint, Detekt, Unit Test
- Fastlane 自动化部署
- Secrets 不进版控
- Certificate Pinning 激活
- Network Security Config 禁止 Cleartext
- Delivery Gate 已执行并通过