본문으로 건너뛰기
cccskills
무료GitHub에 공개

release-signing

Reference for RIPDPI release signing config and versioning. Use when touching signing config or version bumps. Keep rules: r8-jni-keep-rules. Tagging and publishing: ripdpi-release.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

설치 방법 보기

포함된 파일(1)

  • SKILL.md6.6 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

Release Signing

End-to-end release pipeline: signing config, R8/ProGuard, versioning, artifact naming.

Release flow: manually dispatch .github/workflows/release-candidate.yml for an exact main SHA, then push the matching v* tag to trigger .github/workflows/release.yml, which promotes the immutable candidate.

Signing Configuration

Four environment variables, read via Gradle providers in app/build.gradle.kts:

VariablePurpose
RIPDPI_SIGNING_STORE_FILEPath to decoded keystore file
RIPDPI_SIGNING_STORE_PASSWORDKeystore password
RIPDPI_SIGNING_KEY_ALIASKey alias within the keystore
RIPDPI_SIGNING_KEY_PASSWORDKey password

Lookup order: app/build.gradle.kts resolves each signing value through a localOrEnv(propKey, envKey) helper in the signingConfigs { } block: it reads local.properties first (keys signing.storeFile, signing.storePassword, signing.keyAlias, signing.keyPassword), falling back to the matching environment variable only when the property is absent. The release signing config is created only when the resolved store-file path is non-null -- a build with neither source configured skips signing.

CI flow: the keystore is stored as base64 in GitHub secret KEYSTORE_BASE64; release-candidate.yml decodes it to a temp file and exports RIPDPI_SIGNING_STORE_FILE (and the matching password/alias variables) so localOrEnv() resolves them from the environment. release.yml never touches the keystore -- it only promotes an already-signed candidate.

Never commit keystores to the repository.

R8 / ProGuard Rules

Three layers of rules, evaluated together at build time:

FilePurpose
app/proguard-rules.proApp-level rules (intentionally minimal -- relies on library consumer rules)
core/data/consumer-rules.proPreserves protobuf lite classes: com.poyka.ripdpi.proto.**
core/engine/consumer-rules.proPreserves each JNI binding class with -keepclasseswithmembernames, plus a couple of by-name-callback keep blocks; see the file for the current entries

R8 Diagnostics

Enable with -Pripdpi.r8Diagnostics=true to generate analysis files:

./gradlew assembleGithubFullRelease -Pripdpi.r8Diagnostics=true

Output in app/build/outputs/mapping/githubFullRelease/ for that task:

  • usage.txt -- Classes/methods removed by R8
  • seeds.txt -- Classes/methods kept by keep rules
  • configuration.txt -- Merged R8 configuration

Configured in ripdpi.android.application.gradle.kts.

Adding JNI Consumer Rules

When adding a new JNI binding class, add a keep rule to the module's consumer-rules.pro using the same shape as the existing entries:

-keepclasseswithmembernames class com.poyka.ripdpi.core.NewNativeBindings {
    native <methods>;
}

A Kotlin callback invoked by name from native code (not a native method itself) needs a different keep shape; see the .agents/skills/r8-jni-keep-rules/SKILL.md decision tree for that case and for the general JNI keep-rule failure modes.

Versioning

PropertyLocationCurrent
versionCodeapp/build.gradle.ktsread ripdpiVersionCode live
versionNameapp/build.gradle.ktsread ripdpiVersionName live

Artifact naming pattern (from ripdpi.android.application.gradle.kts):

RIPDPI-{versionName}-{versionCode}-{buildType}-universal.aab
RIPDPI-{versionName}-{versionCode}-{buildType}-universal.apk

Version bumping checklist:

  1. Update versionCode (must increment for every Play Store upload).
  2. Update versionName (semantic versioning).
  3. Do not tag or push directly -- hand off to the ripdpi-release skill, which enforces the release-window cut and the candidate-dispatch sequence before any tag exists.

Release Artifacts

The release-candidate workflow builds and uploads:

ArtifactPath
Play AABapp/build/outputs/bundle/playFullRelease/*.aab
F-Droid APKapp/build/outputs/apk/fdroidFull/release/*.apk
GitHub APKapp/build/outputs/apk/githubFull/release/*.apk
R8 Mappingapp/build/outputs/mapping/*Release/mapping.txt
Compose MappingCompose stability report
Native Symbolspackaged release-native-symbols/manifest.json and release-native-symbols.zip

The tag-triggered publication workflow downloads the candidate by its exact run ID, reverifies its manifest and SHA, stages checksums and SBOMs, and uses the pinned softprops/action-gh-release action without rebuilding app binaries.

Release Verification in CI

The release-verification job in ci.yml builds all minified release variants and, on the GitHub shard, assembles the GithubFullReleaseAndroidTest APK with testBuildType=release. It uses prebuilt native inputs and no signing secrets, so release-only Hilt, test ownership, and shrinker problems fail in ordinary CI before the signed-candidate environment. This catches:

  • Missing keep rules for JNI classes
  • R8 stripping classes accessed via reflection
  • ProGuard rule conflicts
  • Release-only instrumentation/Hilt compilation failures

Common Mistakes

MistakeFix
New JNI class without consumer-rulesR8 strips the class, native code crashes. Add keep rule to module's consumer-rules.pro.
Committing keystore to repoUse environment variables + base64 encoding in CI secrets.
Same versionCode as previous releasePlay Store rejects. Always increment versionCode.
Skipping R8 diagnostics checkRun with -Pripdpi.r8Diagnostics=true before release to verify keep rules.
Adding keep rules to app/proguard-rules.proUse module-level consumer-rules.pro so rules travel with the module.
Forgetting native symbol uploadCrash reports will lack native stack traces. Verify the packaged release-native-symbols.zip and manifest upload.

See Also

  • .agents/skills/ripdpi-release/SKILL.md -- the gated tag/publish workflow this skill hands off to
  • .agents/skills/r8-jni-keep-rules/SKILL.md -- general JNI/route/proto keep-rule decision tree
  • .agents/skills/ci-workflow-authoring/SKILL.md -- CI pipeline guidance
  • quality/release-gates/release-contract.json -- machine-readable release flow
  • .github/workflows/release-candidate.yml -- signed candidate production
  • .github/workflows/release.yml -- tag-bound candidate promotion

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

RIPDPI's own Compose conventions: ViewModel pattern, Route/Screen split, DataStore->StateFlow, RipDpiThemeTokens. Use for how this app does Compose, not generic Compose API questions (see compose).

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

po4yka/RIPDPI812026년 10월 21일 업데이트

ADB-based RIPDPI device/emulator debugging: build/install/launch, logcat filtering, fixture port-forwarding, instrumented tests, crash/ANR triage. Use when debugging on a real device or emulator.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

po4yka/RIPDPI812026년 10월 21일 업데이트

RIPDPI Appium launch-contract reference: start routes and permission/service/data presets. Use when a test launches to the wrong screen or a new automation route is added. General flakiness: appium-test-debug.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

po4yka/RIPDPI812026년 10월 21일 업데이트

RIPDPI Appium test authoring: page objects, resource-id locators, assertions, wait tiers. Use when writing a new Appium test or page object, or adding coverage for a new screen.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

po4yka/RIPDPI812026년 10월 21일 업데이트

RIPDPI Appium failure triage: flaky tests, locator/session/wait issues, screenshot and element-tree debugging. Use when an Appium test fails or is flaky.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

po4yka/RIPDPI812026년 10월 21일 업데이트

Add or modify a GitHub Actions job. Use when editing a file under .github/workflows/. Not for running a workflow locally (local-ci-act) or release signing (release-signing).

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

po4yka/RIPDPI812026년 10월 21일 업데이트

po4yka의 스킬 모두 보기

이 스킬의 문제 신고