Skip to content
android-signing-config logo

Android Signing Configuration

android-signing-config

Configure Android release build signing with dual-source credentials (env vars + gradle.properties)

SKILL.md

Full skill instructions

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

InputRequiredDefaultDescription
project_pathYes.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

# 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

# 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:

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:

# 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:

# 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:

# 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

OutputLocationDescription
Signing configapp/​build.gradle.ktsDual-source signing configuration
Local config~/​.gradle/​gradle.propertiesLocal 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)

More skills from majiayu000

xiaohongshu logo
majiayu000/claude-arsenal

xiaohongshu

xiaohongshu

286 148
View
agent-task-conductor logo
majiayu000/claude-skill-registry

agent-task-conductor

Conduct multi-agent task orchestration and workflow coordination.

663 1
View
conductor-setup logo
majiayu000/claude-skill-registry

conductor-setup

Initialize project with Conductor artifacts (product definition,

663 1
View
animation-designer logo
majiayu000/claude-skill-registry

animation-designer

Expert in web animations, transitions, and motion design using Framer Motion and CSS

663 1
View
diagramming logo
majiayu000/claude-skill-registry

diagramming

Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...

663 1
View
h3-pg logo
majiayu000/claude-skill-registry-data

h3-pg

PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.

23 1
View
conductor-development logo
majiayu000/claude-skill-registry

conductor-development

Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...

663 1
View
conductor-status logo
majiayu000/claude-skill-registry

conductor-status

Display project status, active tracks, and next actions

663 1
View
dockerization logo
majiayu000/claude-skill-registry

dockerization

Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.

663 1
View

Popular AI tools

Kaiber logo
Video

Kaiber

Generate, edit, and beat-sync AI video with leading models in one workspace.

Paid
View
Vimcal logo
Productivity

Vimcal

The world's fastest calendar for remote work

Free
View

Transform Your Design with AI Designer by ImgCreator.ai

Freemium
View
Akool AI logo
Content & writing

Akool AI

Revolutionizing Video Production with AI-Powered Creativity

Paid
View

Extend an image past the frame and let AI fill the new aspect ratio.

Freemium
View
StarByFace logo
Security

StarByFace

Discover your celebrity doppelgänger with StarByFace!

Free
View
C

ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.

Freemium
View
Opus Clip logo
Coding & apps

Opus Clip

Opus.ai: Revolutionize Your Web Experience

Free
View