Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,52 @@ jobs:
| `artifact-url` | URL of the build artifact |
| `artifact-id` | ID of the build artifact |

## Code Signing

When `sign: true` is enabled, this action configures Android code signing by setting Gradle properties. It supports **two property conventions** for maximum compatibility:

### Android injected properties

(this is an undocumented feature used by Fastlane and AGP)

The action automatically sets `android.injected.signing.*` properties which are natively recognized by the Android Gradle Plugin. These properties work with any standard `build.gradle` configuration without modifications:

```gradle
signingConfigs {
release {
// These hardcoded values will be automatically overridden
storeFile file('path/to/keystore.jks')
keyAlias 'placeholder'
storePassword 'placeholder'
keyPassword 'placeholder'
}
}
```

### Custom ROCK Properties

For apps that explicitly read custom properties in their `build.gradle`, the action also sets `ROCK_UPLOAD_*` properties:

```gradle
signingConfigs {
release {
storeFile file('path/to/keystore.jks')
keyAlias project.findProperty('ROCK_UPLOAD_KEY_ALIAS') ?: 'placeholder'
storePassword project.findProperty('ROCK_UPLOAD_STORE_PASSWORD') ?: 'placeholder'
keyPassword project.findProperty('ROCK_UPLOAD_KEY_PASSWORD') ?: 'placeholder'
}
}
```
Copy link
Contributor

@thymikee thymikee Oct 15, 2025

Choose a reason for hiding this comment

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

let's add mapping:

  • RNEF_UPLOAD_KEY_ALIAS -> populated by inputs.keystore-key-alias
  • ...


The following mappings are set:

- `ROCK_UPLOAD_KEY_ALIAS` ← `inputs.keystore-key-alias`
- `ROCK_UPLOAD_STORE_FILE` ← `inputs.keystore-store-file`
- `ROCK_UPLOAD_STORE_PASSWORD` ← `inputs.keystore-store-password`
- `ROCK_UPLOAD_KEY_PASSWORD` ← `inputs.keystore-key-password`

Both conventions are set simultaneously, so the action works with any existing build configuration.

## Prerequisites

- Ubuntu runner
Expand Down
34 changes: 28 additions & 6 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -183,10 +183,18 @@ runs:
run: |
mkdir -p $HOME/.gradle
touch $HOME/.gradle/gradle.properties
echo "RNEF_UPLOAD_STORE_FILE=${{ inputs.keystore-store-file }}" >> $HOME/.gradle/gradle.properties
echo "RNEF_UPLOAD_STORE_PASSWORD=${{ inputs.keystore-store-password }}" >> $HOME/.gradle/gradle.properties
echo "RNEF_UPLOAD_KEY_ALIAS=${{ inputs.keystore-key-alias }}" >> $HOME/.gradle/gradle.properties
echo "RNEF_UPLOAD_KEY_PASSWORD=${{ inputs.keystore-key-password }}" >> $HOME/.gradle/gradle.properties

# Android standard properties (auto-recognized by AGP)
echo "android.injected.signing.store.file=${{ inputs.keystore-store-file }}" >> $HOME/.gradle/gradle.properties
echo "android.injected.signing.store.password=${{ inputs.keystore-store-password }}" >> $HOME/.gradle/gradle.properties
echo "android.injected.signing.key.alias=${{ inputs.keystore-key-alias }}" >> $HOME/.gradle/gradle.properties
echo "android.injected.signing.key.password=${{ inputs.keystore-key-password }}" >> $HOME/.gradle/gradle.properties

# Rock custom properties (for apps that explicitly read them in signingConfigs)
echo "ROCK_UPLOAD_STORE_FILE=${{ inputs.keystore-store-file }}" >> $HOME/.gradle/gradle.properties
echo "ROCK_UPLOAD_STORE_PASSWORD=${{ inputs.keystore-store-password }}" >> $HOME/.gradle/gradle.properties
echo "ROCK_UPLOAD_KEY_ALIAS=${{ inputs.keystore-key-alias }}" >> $HOME/.gradle/gradle.properties
echo "ROCK_UPLOAD_KEY_PASSWORD=${{ inputs.keystore-key-password }}" >> $HOME/.gradle/gradle.properties
shell: bash

- name: Determine Android sourceDir and appName
Expand All @@ -204,15 +212,25 @@ runs:
- name: Decode and store keystore file
if: ${{ !env.ARTIFACT_URL && inputs.sign }}
run: |
KEYSTORE_TARGET_PATH="$ANDROID_SOURCE_DIR/$APP_NAME/${{ inputs.keystore-path }}"
if [ -n "$APP_NAME" ]; then
KEYSTORE_TARGET_PATH="$ANDROID_SOURCE_DIR/$APP_NAME/${{ inputs.keystore-path }}"
else
KEYSTORE_TARGET_PATH="$ANDROID_SOURCE_DIR/${{ inputs.keystore-path }}"
fi

echo "Keystore target path before normalizing: $KEYSTORE_TARGET_PATH"
KEYSTORE_TARGET_PATH=$(realpath -m "$KEYSTORE_TARGET_PATH")
echo "Keystore target path after normalizing: $KEYSTORE_TARGET_PATH"
mkdir -p "$(dirname "$KEYSTORE_TARGET_PATH")" || {
echo "Failed to create keystore directory: $(dirname "$KEYSTORE_TARGET_PATH")"
exit 1
}
if [ -n "${{ inputs.keystore-file }}" ]; then
cp "${{ inputs.keystore-file }}" "$KEYSTORE_TARGET_PATH"
echo "Successfully copied keystore file to target path: $KEYSTORE_TARGET_PATH"
else
echo "${{ inputs.keystore-base64 }}" | base64 --decode > "$KEYSTORE_TARGET_PATH"
echo "Successfully copied keystore base64 to target path: $KEYSTORE_TARGET_PATH"
fi
shell: bash
working-directory: ${{ inputs.working-directory }}
Expand Down Expand Up @@ -312,7 +330,11 @@ runs:
if: ${{ !env.ARTIFACT_URL && inputs.sign }}
run: |
rm $HOME/.gradle/gradle.properties
rm "$ANDROID_SOURCE_DIR/$APP_NAME/${{ inputs.keystore-path }}"
if [ -n "$APP_NAME" ]; then
rm "$ANDROID_SOURCE_DIR/$APP_NAME/${{ inputs.keystore-path }}"
else
rm "$ANDROID_SOURCE_DIR/${{ inputs.keystore-path }}"
fi
shell: bash
working-directory: ${{ inputs.working-directory }}

Expand Down