android-signing-config
Configure Android release build signing with dual-source credentials (env vars + gradle.properties)
Best use case
android-signing-config is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Configure Android release build signing with dual-source credentials (env vars + gradle.properties)
Teams using android-signing-config should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/android-signing-config/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How android-signing-config Compares
| Feature / Agent | android-signing-config | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Configure Android release build signing with dual-source credentials (env vars + gradle.properties)
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# Android Signing Configuration
Configures release build signing with dual-source strategy: environment variables (CI/CD) and gradle.properties (local dev).
## Prerequisites
- Keystores exist in `keystores/` directory (run `android-keystore-generation` first)
- Android project with Gradle
- Kotlin DSL (build.gradle.kts)
## Inputs
| Input | Required | Default | Description |
|-------|----------|---------|-------------|
| project_path | Yes | . | Android project root |
## Process
### Step 1: Detect and Select Environment Variable Prefix
**Purpose:** Avoid variable name conflicts with other projects by using a project-specific prefix.
**Step 1a: Auto-detect project name**
```bash
# From settings.gradle.kts
PROJECT_NAME=$(grep "rootProject.name" settings.gradle.kts | sed 's/.*"\(.*\)".*/\1/' | tr '[:lower:]' '[:upper:]' | tr '-' '_')
echo "Detected project: $PROJECT_NAME"
```
**Step 1b: Ask user for prefix preference**
> "Choose environment variable prefix for signing configuration:
> 1. **${PROJECT_NAME}** (detected from project) - e.g., `${PROJECT_NAME}_SIGNING_KEY_STORE_PATH`
> 2. **APP** (generic) - e.g., `APP_SIGNING_KEY_STORE_PATH`
> 3. **Custom** - Enter your own prefix
>
> Select option (1/2/3):"
**Step 1c: Store selected prefix**
```bash
# Based on user selection:
# Option 1: PREFIX="$PROJECT_NAME"
# Option 2: PREFIX="APP"
# Option 3: PREFIX="{user_custom_prefix}"
echo "Using prefix: $PREFIX"
echo "Example variable: ${PREFIX}_SIGNING_KEY_STORE_PATH"
```
**GitHub Secrets to create later:**
- `${PREFIX}_SIGNING_KEY_STORE_BASE64`
- `${PREFIX}_SIGNING_KEY_ALIAS`
- `${PREFIX}_SIGNING_STORE_PASSWORD`
- `${PREFIX}_SIGNING_KEY_PASSWORD`
### Step 2: Add Signing Configuration to build.gradle.kts
Update `app/build.gradle.kts` to add signing configuration:
```kotlin
android {
namespace = "com.example.app" // Keep existing
compileSdk = 34 // Keep existing
defaultConfig {
// Keep existing config
}
// ADD THIS SECTION
signingConfigs {
create("release") {
// Use the prefix selected in Step 1 (replace {PREFIX} with actual prefix)
val prefix = "{PREFIX}" // e.g., "APP" or project-specific prefix
// Priority: environment variables (CI/CD) > gradle.properties (local dev)
val keystorePath = System.getenv("${prefix}_SIGNING_KEY_STORE_PATH")
?: project.findProperty("${prefix}_SIGNING_KEY_STORE_PATH")?.toString()
val storePass = System.getenv("${prefix}_SIGNING_STORE_PASSWORD")
?: project.findProperty("${prefix}_SIGNING_STORE_PASSWORD")?.toString()
val alias = System.getenv("${prefix}_SIGNING_KEY_ALIAS")
?: project.findProperty("${prefix}_SIGNING_KEY_ALIAS")?.toString()
val keyPass = System.getenv("${prefix}_SIGNING_KEY_PASSWORD")
?: project.findProperty("${prefix}_SIGNING_KEY_PASSWORD")?.toString()
if (keystorePath != null && storePass != null && alias != null && keyPass != null) {
storeFile = file(keystorePath)
storePassword = storePass
keyAlias = alias
// For PKCS12 keystores, storePassword and keyPassword must be identical
keyPassword = keyPass
}
}
}
buildTypes {
release {
signingConfig = signingConfigs.getByName("release")
// ProGuard config set by android-proguard-setup skill
}
}
// Validate signing config only when building release variants
tasks.matching {
it.name.matches(Regex(".*[aA]ssemble.*Release.*|.*[bB]undle.*Release.*"))
}.configureEach {
doFirst {
val releaseConfig = android.signingConfigs.getByName("release")
if (releaseConfig.storeFile == null) {
throw GradleException(
"""
Release signing not configured!
For CI/CD: Set environment variables (using prefix: $prefix):
- ${prefix}_SIGNING_KEY_STORE_PATH
- ${prefix}_SIGNING_STORE_PASSWORD
- ${prefix}_SIGNING_KEY_ALIAS
- ${prefix}_SIGNING_KEY_PASSWORD
For local development: Add to ~/.gradle/gradle.properties:
${prefix}_SIGNING_KEY_STORE_PATH=/path/to/local-dev-release.jks
${prefix}_SIGNING_STORE_PASSWORD=your-password
${prefix}_SIGNING_KEY_ALIAS=local-dev
${prefix}_SIGNING_KEY_PASSWORD=your-password
""".trimIndent()
)
}
}
}
}
```
**Detection logic:**
- Check if `signingConfigs` already exists - update if present
- Check if release `buildType` already has signingConfig - preserve other settings
- Don't modify ProGuard settings (handled by separate skill)
### Step 2: Update .gitignore
Ensure sensitive files are gitignored:
```bash
# Add to .gitignore if not present
grep -q "gradle.properties" .gitignore 2>/dev/null || echo -e "\n# Gradle properties with secrets\ngradle.properties" >> .gitignore
```
### Step 3: Configure Local Development
Ask user permission to update `~/.gradle/gradle.properties`:
```bash
# Read credentials from KEYSTORE_INFO.txt
LOCAL_PASSWORD=$(grep "Local.*Store Password:" keystores/KEYSTORE_INFO.txt | cut -d: -f2 | xargs)
PROJECT_PATH=$(pwd)
PREFIX="{PREFIX}" # Use the prefix selected in Step 1
# Add to ~/.gradle/gradle.properties (using selected prefix)
cat >> ~/.gradle/gradle.properties << EOF
# ${PROJECT_PATH} (using prefix: ${PREFIX})
${PREFIX}_SIGNING_KEY_STORE_PATH=${PROJECT_PATH}/keystores/local-dev-release.jks
${PREFIX}_SIGNING_KEY_ALIAS=local-dev
${PREFIX}_SIGNING_STORE_PASSWORD=${LOCAL_PASSWORD}
${PREFIX}_SIGNING_KEY_PASSWORD=${LOCAL_PASSWORD}
EOF
```
**Important:** Always ask permission before modifying user's global gradle.properties!
## Verification
**MANDATORY:** Run this command to verify signing works:
```bash
# Build release APK
./gradlew assembleRelease
# Verify APK exists
ls -lh app/build/outputs/apk/release/app-release.apk
# Verify APK signature (supports APK Signature Scheme v2/v3)
$ANDROID_HOME/build-tools/34.0.0/apksigner verify --verbose app/build/outputs/apk/release/app-release.apk
# Or if apksigner is in PATH:
apksigner verify --verbose app/build/outputs/apk/release/app-release.apk
```
**Expected output:**
- Release build succeeds
- APK file exists
- `apksigner` shows "Verifies" with v2/v3 scheme confirmation
## Outputs
| Output | Location | Description |
|--------|----------|-------------|
| Signing config | app/build.gradle.kts | Dual-source signing configuration |
| Local config | ~/.gradle/gradle.properties | Local dev credentials |
## Troubleshooting
### "Signing config not found"
**Cause:** gradle.properties not configured correctly
**Fix:** Verify ~/.gradle/gradle.properties has correct paths and passwords
### "Cannot find keystore file"
**Cause:** Path in gradle.properties is incorrect
**Fix:** Use absolute path: `/full/path/to/keystores/local-dev-release.jks`
### "apksigner verification fails"
**Cause:** Wrong keystore or passwords
**Fix:** Double-check credentials in KEYSTORE_INFO.txt
## Completion Criteria
- [ ] `signingConfigs.release` exists in app/build.gradle.kts
- [ ] Release buildType uses signingConfig
- [ ] `~/.gradle/gradle.properties` configured (or env vars set for CI)
- [ ] `./gradlew assembleRelease` succeeds
- [ ] `apksigner verify` confirms APK is signed (v2/v3 schemes)Related Skills
configuring-devenv
Initializes and configures devenv development environments. Searches packages, sets up languages, services, scripts, git hooks, and processes. Use when setting up devenv, adding packages to devenv.nix, configuring languages, services, git hooks, or searching for devenv options.
configure
Sets up or edits the plugin configuration file interactively. Use on first-time setup, when config is missing, or when the user wants to change settings.
config-audit
This skill should be used when auditing or comparing Claude Code and Cursor IDE configurations to identify feature gaps, equivalencies, and migration opportunities. Useful when managing AI development tooling across both platforms or deciding how to structure AI workflows.
claude-improve-config
Self-reflect on the current session to identify mistakes and propose improvements to .claude configuration (CLAUDE.md, hooks, skills).
android-release
App signing, bundling, and Play Store deployment automation. Use when signing APK/AAB, generating release builds, preparing Play Store upload, or configuring ProGuard.
android-release-validation
Validate Android release builds before publishing to ensure quality and catch ProGuard issues
android-release-build-setup
Complete Android release build configuration - orchestrates keystore, ProGuard, and signing setup
android-proguard-setup
Configure ProGuard/R8 for Android release builds with safe defaults
android-playstore-scan
Scan Android project and generate Play Console setup checklist (analysis only, no file modifications)
acm-config
Use when the user wants to customize Claudikins Automatic Context Manager behavior, configure trigger threshold, snooze duration, summary length, or runs '/acm:config'. Interactively asks questions and saves preferences to config file.
sast-configuration
Configure Static Application Security Testing (SAST) tools for automated vulnerability detection in application code. Use when setting up security scanning, implementing DevSecOps practices, or aut...
configure-ux-testing
Check and configure UX testing infrastructure (Playwright, accessibility, visual regression)