mcpField
G
gpc-preflight

gpc-preflight

github.com/yasserstudio测试与质量139 次安装1 周前更新
代码仓库

关于 gpc-preflight

GPC Preflight Scanner 是一项技能,用于发布前检查 Android 应用包和 APK 是否符合 Google Play 要求。它介绍九类扫描器、可配置的检查结果、签名一致性检查及 CI 用法。

主要功能

  1. 01扫描 AAB 和 APK 文件
  2. 02检查清单与权限
  3. 03检查原生库及对齐情况
  4. 04检测密钥和计费 SDK
  5. 05验证商店资料与政策
  6. 06通过 Play API 检查签名证书

适用场景

  1. 01上传至 Play 前发现政策问题
  2. 02在 CI 中依据扫描结果设发布门禁
  3. 03排查签名证书不一致

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/yasserstudio/gpc-skills --skill gpc-preflight

安装后在 Claude Code 中输入/gpc-preflight确认已加载。

详细介绍

GPC 预检扫描器

使用场景

在任务涉及以下内容时使用此技能:

  • 在上传到 Google Play 之前扫描 AAB 或 APK 文件
  • 检查目标 SDK 版本是否合规
  • 审核权限是否符合 Google Play 政策
  • 验证是否支持 64 位原生库
  • 扫描源代码中的硬编码密钥或凭据
  • 检测非 Play 结算 SDK
  • 检查商店商品详情元数据是否合规
  • 基于政策合规性设置 CI/CD 质量门禁

快速参考

# Full scan (AAB or APK)
gpc preflight app.aab
gpc preflight app.apk

# With metadata and source scanning
gpc preflight app.aab --metadata fastlane/metadata/android --source app/src

# Specific scanners only
gpc preflight manifest app.aab
gpc preflight permissions app.aab
gpc preflight metadata ./metadata
gpc preflight codescan ./src

# CI mode
gpc preflight app.aab --fail-on error --json

9 个扫描器

扫描器检查项严重级别
manifesttargetSdk >= 36(v0.9.79+)、debuggable、testOnly(自 v0.9.80 起从 <application> 元素读取)、cleartext、缺少 exported、FGS 类型、地理围栏前台服务(v0.9.65+)critical/error/warning
permissions18 项受限权限、通讯录广泛访问、Health Connect 细粒度权限(v0.9.65+)、Data Safety 提醒critical/error/warning/info
native-libs64 位 ARM 合规性、ABI 检测、16KB 页面边界对齐(自 v0.9.80 起支持 AAB + APK;读取 4096 字节 ELF 标头;每次扫描最多 512 个库)critical/warning
metadata商品详情字符数限制、截图、隐私政策 URLerror/warning
secretsAWS 密钥、Google API 密钥、Stripe 密钥、私钥critical/warning
billingStripe、Braintree、PayPal、Razorpay SDK 检测warning
privacy跟踪 SDK、Advertising ID、数据收集交叉核对warning/info
policy家庭/COPPA、金融、健康、UGC、悬浮层warning/info
size每台设备的预计下载大小(AAB:仅计最大 ABI,不含 bundle 元数据或按需/快速跟进模块;APK:计整个文件)、大型原生库、大型资源warning/info

配置(.preflightrc.json)

{
  "failOn": "error",
  "targetSdkMinimum": 36,
  "maxDownloadSizeMb": 200,
  "allowedPermissions": ["android.permission.READ_SMS"],
  "disabledRules": ["cleartext-traffic"],
  "severityOverrides": { "billing-stripe-sdk": "info" }
}

从 2026 年 8 月 31 日起,Google Play 上的所有新应用和更新都必须使用 API 级别 36(Android 16)。GPC preflight 在 v0.9.79 中将 targetSdkMinimum 默认值更新为 36,以符合此期限要求。

下载大小(v0.9.99+)

对于 AAB,size-over-limit 会按照 Google Play 分发 bundle 的方式,估算一台设备的下载内容:只计最大 ABI 的原生库,不包括 BUNDLE-METADATA/(调试符号、R8 映射文件)或 bundle 签名,也不包括按需模块、快速跟进模块或资源包。所有屏幕密度和语言仍会计入,因此估算值偏高。对于 APK,则计入整个文件。默认的 maxDownloadSizeMb 为 200,即 Play 在用户使用移动数据时显示大型下载对话框的大小阈值。在 v0.9.99 之前,计算会汇总整个 .aab,因此多 ABI 的 Flutter/React Native bundle 会被误报为实际下载大小的 3-4 倍(GH #116);如果旧版本遇到此问题,请升级,或添加 "disabledRules": ["size-over-limit"]。如需精确数值,请对 bundle 运行 bundletool get-size total。

native-libs-large(native-libs 扫描器)和 size-large-native 对 AAB 也同样按单个最大 ABI 计算。

APK 扫描: manifest 检查(manifest、permissions、policy、privacy 扫描器)目前仅针对 AAB 运行。APK 的二进制 XML manifest 尚无法解码,因此 APK 扫描会报告“Manifest could not be fully parsed”,并继续运行其余检查。若要全面检查,请扫描你准备上传的 AAB。

退出代码

  • 0 — 所有检查均已通过
  • 1 — 运行时错误
  • 6 — 发现项达到或超过 --fail-on 指定的严重级别

关键规则

规则 ID严重程度内容
targetSdk-below-minimum严重targetSdkVersion < 36
debuggable-true严重android:debuggable="true"
testOnly-true严重android:testOnly="true"
missing-arm64严重仅有 32 位 ARM,不含 64 位
missing-exported错误带有 intent-filter 的组件未设置 exported 属性
foreground-service-type-missing警告应用请求了 FOREGROUND_SERVICE,但没有服务声明 foregroundServiceType(API 34+);仅报告一次(v0.9.99+,此前每个服务报告一个错误)
secret-aws-key严重源代码中包含 AWS 访问密钥
secret-stripe-key严重源代码中包含 Stripe 密钥
contacts-permission-broad警告READ_CONTACTS / WRITE_CONTACTS(v0.9.65+,2026 年 4 月政策)
geofencing-foreground-service警告位置 FGS + ACCESS_BACKGROUND_LOCATION(v0.9.65+,2026 年 4 月政策)
health-connect-granular警告/信息READ_ALL_HEALTH_DATA;targetSdk >= 36 时为警告,否则为信息(v0.9.65+,2026 年 4 月政策)
policy-app-content-declaration信息任何 FOREGROUND_SERVICE* 权限;提醒你在 Play Console -> Policy -> App content 中填写相应声明(v0.9.94+)
native-libs-16kb-unchecked警告并非所有原生库都能检查 16 KB 对齐情况(v1.0.0-rc.1+)

native-libs-16kb-unchecked(v1.0.0-rc.1+):读取器最多缓冲 512 个 .so 头文件,避免包含数千个原生库的应用包占用过多内存。当应用包中的库超过此数量时,对齐检查只会覆盖前 512 个,因此预检会明确提示,而不会让不完整的检查显示为通过。检查结果会说明跳过了多少个库。如需检查整个应用包,请使用 Android Studio 的 APK Analyzer,或在通用 APK 上运行 zipalign -c -P 16 -v 4 app.apk。大多数应用都不会遇到此规则。

操作流程

运行完整预检扫描
  1. 构建 AAB 或 APK:./gradlew bundleRelease(APK 使用 assembleRelease)
  2. 运行:gpc preflight app/build/outputs/bundle/release/app-release.aab 或者对 APK 运行:gpc preflight app/build/outputs/apk/release/app-release.apk
  3. 修复所有严重/错误级别的问题
  4. 添加 .preflightrc.json,以允许已批准的权限或禁用误报
  5. 重新运行,直到扫描通过

注意:扫描完成后,GPC 会提醒你 Android 开发者验证要求(2026 年 9 月 30 日起在 BR、ID、SG、TH 强制执行)。运行 gpc verify 查看详情。

从 v0.9.80 起,当扫描器被筛除时,结果 JSON 会包含 skippedScanners 数组(例如,因清单解析失败而跳过依赖清单的扫描器)。这取代了此前静默省略被跳过扫描器的行为。

签名密钥一致性(v0.9.66+)
gpc preflight signing                    # Check cert consistency across two most recent bundles
gpc preflight signing --json             # JSON output for CI
gpc preflight signing --app com.example.app  # Override package name

通过 Play API(generatedApks.list)比较你最近两个应用包版本的签名证书。需要身份验证(服务账号或 OAuth)。不匹配时退出码为 6(与其他预检阈值超限情况相同)。API 出错时退出码为 4。

这不是离线扫描。它会调用 Play API 创建一个 edit、列出应用包、获取版本代码最高的两个版本对应的生成 APK,比较 certificateSha256Fingerprint,然后删除该 edit。

2026 年 4 月政策规则(v0.9.65+)

针对 Google Play 2026 年 4 月 15 日的政策更新,新增了三条规则。合规截止日期:2026 年 5 月 15 日。

  1. 广泛访问联系人(contacts-permission-broad):检测 READ_CONTACTS / WRITE_CONTACTS。Google 现在要求使用 Android Contact Picker,而不是广泛访问联系人。即使同时声明了这两项权限,也只会生成一条发现。拨号器/消息应用可通过 allowedPermissions 忽略此规则。

  2. 地理围栏前台服务(geofencing-foreground-service):当服务的 foregroundServiceType 包含 "location",且应用声明了 ACCESS_BACKGROUND_LOCATION 时触发。Google 已将地理围栏从获批的前台服务使用场景中移除。对于合法的后台位置跟踪(导航、健身),可通过 "disabledRules": ["geofencing-foreground-service"] 忽略此规则。

  3. Health Connect 细粒度权限(health-connect-granular):检测 READ_ALL_HEALTH_DATA。当 targetSdk >= 36(Android 16 要求)时,严重级别为 warning;否则为 info。请改用细粒度权限,例如 health.READ_STEPS、health.READ_HEART_RATE 等。

应用内容声明提示(v0.9.94+)

只要 AAB 请求了任何 FOREGROUND_SERVICE* 权限,policy-app-content-declaration 就会以 info 严重级别触发,并列出相应权限。这是在提醒你:必须在 Play Console → Policy → App content 中完成匹配的“Foreground service permissions”声明,Google 才会接受发布。

为何只能提供提示:该声明存储在 Play Console 中,Publisher API 不会公开此信息,也无法从应用包中读取。Preflight 可以看到你的应用请求了这些权限,但无法判断你是否填写了表单。因此,无论 --fail-on 的设置如何,它都不会导致运行失败。

这与 foreground-service-type-missing 检查并不相同。 后者检查 <service> 元素上的 android:foregroundServiceType,这是调用 startForeground() 的服务必须满足的清单要求。即使所有服务都已正确指定类型,上传仍可能因缺少 Console 声明而被阻止——这正是添加此规则的原因。

如果声明不完整,上传会因 API_DECLARATION_REQUIRED 而失败(v0.9.94+)。在 v0.9.94 之前,同一问题会被报告为服务帐号权限问题,导致用户前往 Users and permissions,而不是 App content。

每次扫描只生成一条发现,而不是每项权限各生成一条。

修复漏报问题(v0.9.80)

v0.9.80 发布了四项扫描准确性改进:

  1. testOnly 属性来源:现在 testOnly 扫描器会从清单的 <application> 元素读取 android:testOnly。此前它错误地从 <manifest> 根元素读取,导致即使在应用上设置了 testOnly="true",检查也总是报告未发现问题。

  2. 16KB 对齐扫描器范围:现在 16KB 页面对齐扫描器除了检查 AAB,还会检查 APK 中的原生库。此前它只检查 AAB 构件,导致 APK 中的原生库未被扫描。

  3. ELF 头读取大小:ELF 头读取器的读取大小从 256 字节增加到 4096 字节。对于某些原生库格式,小尺寸读取不足以完成检查,导致对齐检查被静默跳过。

  4. 结果中的 skippedScanners:通过 skippedScanners 禁用的扫描器(或因缺少输入而跳过的扫描器),现在会在扫描结果 JSON 的 skippedScanners 数组中报告。当扫描器未运行时,这样 CI 中便能清楚地看到。

添加到 CI 中
# GitHub Actions
- name: Preflight
  run: gpc preflight app.aab --fail-on error --json > preflight.json
- name: Upload report
  if: always()
  uses: actions/upload-artifact@v4
  with:
    name: preflight-report
    path: preflight.json

相关技能

  • gpc-release-flow — 预检通过后的上传和发布
  • gpc-ci-integration — CI/CD 模式,包括预检关卡
  • gpc-troubleshooting — 处理退出代码 6
  • gpc-security — 凭据处理和密钥轮换

评论

支持 Markdown