Skip to content

Harden ARM64 APK signing password handling in Android build workflow - #65

Merged
JWEB0689 merged 3 commits into
mainfrom
copilot/fix-build-kernelcrafter-arm64-apk
Oct 17, 2026
Merged

JWEB0689 merged 3 commits into
mainfrom
copilot/fix-build-kernelcrafter-arm64-apk

Conversation

Copilot AI commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

User description

The Build KernelCrafter ARM64 APK workflow failed during keystore generation because KEY_PASSWORD could be present but invalid for keytool (under 6 chars). This change normalizes signing password selection so all signing stages use a valid, consistent value.

  • Root cause addressed

    • Keystore generation used KEY_PASSWORD directly, which can violate keytool minimum-length requirements and fail the job before APK build/sign completes.
  • Workflow hardening

    • Added EFFECTIVE_KEY_PASSWORD derivation in the keystore step:
      • Use KEY_PASSWORD when valid
      • Fallback to KEYSTORE_PASSWORD when missing/too short
      • Fail early with a clear error if neither is valid
    • Masked and exported the resolved value via $GITHUB_ENV for downstream reuse.
  • Cross-step signing consistency

    • Updated Gradle release build and apksigner steps to use the same EFFECTIVE_KEY_PASSWORD, removing credential mismatch risk between keystore creation and signing.
EFFECTIVE_KEY_PASSWORD="$KEY_PASSWORD"
if [ -z "$EFFECTIVE_KEY_PASSWORD" ] || [ ${#EFFECTIVE_KEY_PASSWORD} -lt 6 ]; then
  EFFECTIVE_KEY_PASSWORD="$KEYSTORE_PASSWORD"
fi
echo "EFFECTIVE_KEY_PASSWORD=$EFFECTIVE_KEY_PASSWORD" >> "$GITHUB_ENV"

PR Type

Bug fix, Enhancement


Description

  • Derive and validate Android signing key password.

  • Ensure minimum 6-character password length.

  • Apply consistent password across all signing steps.

  • Mask sensitive password in workflow logs.


Diagram Walkthrough

flowchart TD
  A["Start"] --> B{Derive EFFECTIVE_KEY_PASSWORD};
  B -- "Check KEY_PASSWORD" --> C{Is KEY_PASSWORD valid (>=6 chars)?};
  C -- "No, too short/empty" --> D{Fallback to KEYSTORE_PASSWORD};
  D --> E{Is EFFECTIVE_KEY_PASSWORD valid (>=6 chars)?};
  E -- "No, too short/empty" --> F["Fail Workflow"];
  E -- "Yes, valid" --> G["Mask & Export EFFECTIVE_KEY_PASSWORD"];
  G --> H["Generate Keystore"];
  H --> I["Build Release APK"];
  I --> J["Locate, Align, Sign APK"];
Loading

File Walkthrough

Relevant files
Bug fix
android-build.yml
Harden Android APK signing password handling in workflow 

.github/workflows/android-build.yml

  • Implemented logic to derive EFFECTIVE_KEY_PASSWORD from KEY_PASSWORD
    or KEYSTORE_PASSWORD.
  • Added validation to ensure the effective key password meets the
    minimum 6-character length requirement.
  • Masked the EFFECTIVE_KEY_PASSWORD and exported it to GITHUB_ENV for
    secure and consistent reuse.
  • Updated the keystore generation, Gradle build, and apksigner steps to
    consistently use the derived EFFECTIVE_KEY_PASSWORD.
+13/-3   

@coderabbitai

coderabbitai Bot commented Oct 13, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration
  • Configuration used: Repository: JWEB0689/coderabbit/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 22357bb9-162a-41ec-978c-d74acf46697d

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Co-authored-by: JWEB0689 <49634855+JWEB0689@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix the failing GitHub Actions job Build KernelCrafter ARM64 APK Harden ARM64 APK signing password handling in Android build workflow Oct 13, 2026
Copilot AI requested a review from JWEB0689 October 13, 2026 08:34
@JWEB0689
JWEB0689 marked this pull request as ready for review October 13, 2026 13:55
Copilot AI balanced review requested due to automatic review settings October 13, 2026 13:55
@github-actions

github-actions Bot commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

PR Reviewer Guide 🔍

(Review updated until commit ff1a4d4)

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 1 🔵⚪⚪⚪⚪
⚠️ Risk level: Low
✅ Merge recommendation: No concerns found
📂 Priority files: None
🧪 No relevant tests
🔒 No security concerns identified
⚡ No major issues detected

Comment thread .github/workflows/android-build.yml Resolved
@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Validate and reuse the ARM64 APK signing key password

🐞 Bug fix ✨ Enhancement 🕐 Less than 10 minutes

Grey Divider

AI Description

• Fall back to the keystore password when the key password is missing or too short.
• Fail early if neither password meets keytool’s six-character minimum.
• Reuse the resolved, masked password across keystore generation, Gradle, and APK signing.
Diagram

graph TD
  S["Signing secrets"] --> C{"Choose key password"} --> V{"At least six characters?"} -->|yes| E["Mask and export"] --> K["Generate keystore"] --> G["Build release APK"] --> A["Align and sign"]
  V -->|no| F["Fail workflow"]
Loading
High-Level Assessment

Resolving the key password once and exporting it for later workflow steps is appropriate for this single-job pipeline. Resolving it separately in each step would risk inconsistent credentials. The keystore password remains a separate input and is not validated by this change.

Files changed (1) +13 / -3

Bug fix (1) +13 / -3
android-build.ymlValidate and share the APK signing key password +13/-3

Validate and share the APK signing key password

• The keystore step now falls back to KEYSTORE_PASSWORD when KEY_PASSWORD is empty or shorter than six characters, and fails with a clear error if the resulting key password is still too short. It masks and exports the resolved value, which Gradle and apksigner then use instead of reading the key-password secret independently.

.github/workflows/android-build.yml

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

JDK 21’s default PKCS12 behavior can ignore the selected key password, and the keystore password remains insufficiently validated.

2 open findings
What changed in this PR

Hardens ARM64 APK signing password selection and reuse.

Changes:

  • Validates and masks an effective key password.
  • Reuses it across keystore generation, Gradle, and APK signing.
File Description
.github/​workflows/​android-build.yml Normalizes signing credentials across workflow steps.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread .github/workflows/android-build.yml Resolved
Comment on lines +64 to +67
if [ -z "$EFFECTIVE_KEY_PASSWORD" ] || [ ${#EFFECTIVE_KEY_PASSWORD} -lt 6 ]; then
echo "::error::Signing key password must be at least 6 characters. Check KEY_PASSWORD/KEYSTORE_PASSWORD secrets."
exit 1
fi
@qodo-code-review

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. Multiline key passwords stop APK builds 🐞 Bug ☼ Reliability
Description
The keystore step writes EFFECTIVE_KEY_PASSWORD to $GITHUB_ENV using a single-line assignment,
which cannot preserve a password containing a newline. If a valid signing secret contains a newline,
the environment file is rejected or a truncated password reaches apksigner, while keytool
created the key with the full password.
Code

.github/workflows/android-build.yml[69]

+          echo "EFFECTIVE_KEY_PASSWORD=$EFFECTIVE_KEY_PASSWORD" >> "$GITHUB_ENV"
Evidence
The password is taken from a secret, passed quoted to keytool, and newly written as an unescaped
single-line environment-file entry. The later signing step obtains its password from that exported
value and passes it to apksigner, so a newline cannot be preserved across those steps by the new
assignment.

.github/workflows/android-build.yml[55-69]
.github/workflows/android-build.yml[70-77]
.github/workflows/android-build.yml[92-108]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A valid signing password containing a newline cannot be exported using the new single-line `$GITHUB_ENV` assignment, so later signing cannot use the same password as keystore creation.
## Fix Focus Areas
- .github/workflows/android-build.yml[60-69]
- .github/workflows/android-build.yml[92-108]
## Recommended Fix
Write the resolved password using GitHub's multiline environment-file syntax with a delimiter that cannot occur in the value. Keep the downstream signing steps reading that resolved value.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Dismiss ↗ | View ↗


Grey Divider

Context sources
✅ Cross-repo context — repo relationships
Review mode: Auto: ⚖️ Balanced: Workflow secrets and signing behavior create security-sensitive build risk.

Grey Divider

Tip of the day
💡 Did you know, you can turn these tips off under Display > Comment parts

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

exit 1
fi
echo "::add-mask::$EFFECTIVE_KEY_PASSWORD"
echo "EFFECTIVE_KEY_PASSWORD=$EFFECTIVE_KEY_PASSWORD" >> "$GITHUB_ENV"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

1. Multiline key passwords stop apk builds 🐞 Bug ☼ Reliability

The keystore step writes EFFECTIVE_KEY_PASSWORD to $GITHUB_ENV using a single-line assignment,
which cannot preserve a password containing a newline. If a valid signing secret contains a newline,
the environment file is rejected or a truncated password reaches apksigner, while keytool
created the key with the full password.
Agent Prompt
## Issue description
A valid signing password containing a newline cannot be exported using the new single-line `$GITHUB_ENV` assignment, so later signing cannot use the same password as keystore creation.
## Fix Focus Areas
- .github/workflows/android-build.yml[60-69]
- .github/workflows/android-build.yml[92-108]
## Recommended Fix
Write the resolved password using GitHub's multiline environment-file syntax with a delimiter that cannot occur in the value. Keep the downstream signing steps reading that resolved value.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Dismiss ↗ | View ↗

@kilo-code-bot

kilo-code-bot Bot commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Code Review Roast 🔥

Verdict: 1 Issue Found | Recommendation: Address before merge

Overview

Severity Count
🚨 critical 0
⚠️ warning 1
💡 suggestion 0
🤏 nitpick 0
Issue Details (click to expand)
File Line Roast
.github/workflows/android-build.yml 60 This PR exists to fall back to KEYSTORE_PASSWORD when KEY_PASSWORD is too short, but the incremental diff just deleted that fallback.

💀 Worst part: The incremental diff removed the exact KEYSTORE_PASSWORD fallback that the PR's own purpose statement promises. If KEY_PASSWORD is a short-but-truthy stub, GitHub's secrets.KEY_PASSWORD || secrets.KEYSTORE_PASSWORD binding still wins (it only falls back on empty/null), so the workflow hard-fails instead of falling back — the scenario this PR set out to fix.

📊 Overall: Like a screen door on a submarine — technically it still seals, but it's missing the one part that makes the whole thing work.

Files Reviewed (1 file)
  • .github/workflows/android-build.yml - 1 issue
Previous Review Summary (commit 56fb39c)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit 56fb39c)

Verdict: No Issues Found | Recommendation: Merge

Oh wait, this PR is actually clean. I need to sit down. I had my flamethrower warmed up and everything.

The fix properly handles the keytool minimum password length (6 chars) by deriving EFFECTIVE_KEY_PASSWORD with a clear fallback chain: KEY_PASSWORD → KEYSTORE_PASSWORD → hard fail with actionable error. Masking via ::add-mask:: and exporting to GITHUB_ENV ensures consistent, secret-safe usage across keystore generation, Gradle, and apksigner. No credential mismatches, no leaked secrets, no "works on my machine" surprises.

📊 Overall: Like finding a unicorn in production — I didn't think clean PRs existed anymore, but here we are.

Files Reviewed (1 file)
  • .github/workflows/android-build.yml

Reviewed by free · Input: 142K · Output: 43.9K · Cached: 93.2K

@JWEB0689 JWEB0689 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/improve

@JWEB0689
JWEB0689 requested review from JWEB0689 and a balanced review from Copilot October 13, 2026 14:29

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

PKCS12 password handling and incomplete validation can still cause signing failures.

2 open findings
1 resolved since last review

🧠 Review effort: Balanced

exit 1
fi
echo "::add-mask::$EFFECTIVE_KEY_PASSWORD"
echo "EFFECTIVE_KEY_PASSWORD=$EFFECTIVE_KEY_PASSWORD" >> "$GITHUB_ENV"

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot Fix the code for this review comment.

When a review comment includes a suggested change, apply the suggestion exactly.

Do not make changes beyond what is described in the linked review comment.

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
@github-actions

Copy link
Copy Markdown
Contributor

Persistent review updated to latest commit ff1a4d4

@JWEB0689
JWEB0689 merged commit 3184013 into main Oct 17, 2026
8 checks passed
@github-actions

Copy link
Copy Markdown
Contributor

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
Possible issue
Ensure keystore password falls back properly

If only secrets.KEY_PASSWORD is configured, KEYSTORE_PASSWORD remains empty, causing
keytool to fail with a missing keystore password error. Define and export
EFFECTIVE_KEYSTORE_PASSWORD with a fallback to KEY_PASSWORD so -storepass is always
populated correctly.

.github/workflows/android-build.yml [60-74]

+          EFFECTIVE_KEYSTORE_PASSWORD="${KEYSTORE_PASSWORD:-$KEY_PASSWORD}"
           EFFECTIVE_KEY_PASSWORD="$KEY_PASSWORD"
           if [ -z "$EFFECTIVE_KEY_PASSWORD" ] || [ ${#EFFECTIVE_KEY_PASSWORD} -lt 6 ]; then
             echo "::error::Signing key password must be at least 6 characters. Check KEY_PASSWORD/KEYSTORE_PASSWORD secrets."
             exit 1
           fi
+          echo "::add-mask::$EFFECTIVE_KEYSTORE_PASSWORD"
           echo "::add-mask::$EFFECTIVE_KEY_PASSWORD"
+          echo "EFFECTIVE_KEYSTORE_PASSWORD=$EFFECTIVE_KEYSTORE_PASSWORD" >> "$GITHUB_ENV"
           echo "EFFECTIVE_KEY_PASSWORD=$EFFECTIVE_KEY_PASSWORD" >> "$GITHUB_ENV"
           keytool -genkey -v \
             -keystore keystore.jks \
             -alias "$KEY_ALIAS" \
             -keyalg RSA \
             -keysize 2048 \
             -validity 10000 \
-            -storepass "$KEYSTORE_PASSWORD" \
+            -storepass "$EFFECTIVE_KEYSTORE_PASSWORD" \
             -keypass "$EFFECTIVE_KEY_PASSWORD" \
Suggestion importance[1-10]: 7

__

Why: If only secrets.KEY_PASSWORD is set, KEYSTORE_PASSWORD remains empty, which causes keytool to fail. Handling fallback for KEYSTORE_PASSWORD prevents workflow failure in this configuration scenario.

Medium

Comment thread .github/workflows/android-build.yml Resolved
KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }}
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD || secrets.KEYSTORE_PASSWORD }}
run: |
EFFECTIVE_KEY_PASSWORD="$KEY_PASSWORD"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔥 The Roast: This PR exists to "fall back to KEYSTORE_PASSWORD when KEY_PASSWORD is missing OR too short." The incremental diff just deleted the "too short" half. If KEY_PASSWORD is set to a short stub, GitHub's secrets.KEY_PASSWORD || secrets.KEYSTORE_PASSWORD binding still wins — it only falls back on empty/null, never on short-but-truthy — so the workflow now hard-fails with "must be at least 6 characters" instead of falling back to KEYSTORE_PASSWORD. You removed the exact safety net for the scenario you set out to fix.

🩹 The Fix: Restore the fallback before the guard:

EFFECTIVE_KEY_PASSWORD="$KEY_PASSWORD"
if [ -z "$EFFECTIVE_KEY_PASSWORD" ] || [ ${#EFFECTIVE_KEY_PASSWORD} -lt 6 ]; then
  EFFECTIVE_KEY_PASSWORD="$KEYSTORE_PASSWORD"
fi
if [ -z "$EFFECTIVE_KEY_PASSWORD" ] || [ ${#EFFECTIVE_KEY_PASSWORD} -lt 6 ]; then
  echo "::error::Signing key password must be at least 6 characters. Check KEY_PASSWORD/KEYSTORE_PASSWORD secrets."
  exit 1
fi

📏 Severity: warning


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kilocode-bot fix it

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fix has been applied successfully. Here's a summary of what was done:

Applied Fix

The Cloud Agent session modified .github/workflows/android-build.yml (lines 60-67) to restore the KEYSTORE_PASSWORD fallback logic that was previously removed. The keystore step now uses a two-check validation pattern as requested:

EFFECTIVE_KEY_PASSWORD=$KEY_PASSWORD
if [ -z $EFFECTIVE_KEY_PASSWORD ] || [ ${#EFFECTIVE_KEY_PASSWORD} -lt 6 ]; then
  EFFECTIVE_KEY_PASSWORD=$KEYSTORE_PASSWORD
fi
if [ -z $EFFECTIVE_KEY_PASSWORD ] || [ ${#EFFECTIVE_KEY_PASSWORD} -lt 6 ]; then
  echo ::error::Signing key password must be at least 6 characters. Check KEY_PASSWORD/KEYSTORE_PASSWORD secrets.
  exit 1
fi
echo "::add-mask::$EFFECTIVE_KEY_PASSWORD"
echo "EFFECTIVE_KEY_PASSWORD=$EFFECTIVE_KEY_PASSWORD" >> "$GITHUB_ENV"

Verification

  • ✅ Fallback restoration: When KEY_PASSWORD is empty or short, the code falls back to KEYSTORE_PASSWORD before erroring
  • ✅ Early fail: If neither password meets the 6-character minimum, the workflow fails with a clear error message
  • ✅ Password masking: EFFECTIVE_KEY_PASSWORD is masked with ::add-mask:: and exported via $GITHUB_ENV for downstream reuse
  • ✅ Consistent usage: The resolved EFFECTIVE_KEY_PASSWORD is used in keystore generation (keytool -keypass), the Gradle release build step (${{ env.EFFECTIVE_KEY_PASSWORD }}), and the apksigner step (${{ env.EFFECTIVE_KEY_PASSWORD }})

Per policy, no PR was created with this change — it was applied directly to the existing branch. You can verify the change in the PR thread.

@qodo-code-review

Copy link
Copy Markdown

ⓘ Qodo reviews are paused because your trial has ended. Ask your workspace admin to add credits to resume reviews. Manage billing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants