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
18 changes: 16 additions & 2 deletions .github/actions/decode_signing_key_action/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,20 @@ runs:
steps:
# After decoding the secret key, place the file in signing_file_path
- run: |
echo "${{inputs.signing_key_file}}" > ~/secretKey.gpg.b64
base64 -d ~/secretKey.gpg.b64 > ${{ inputs.signing_file_path }}
set -euo pipefail
umask 077

# Validate signing_file_path to prevent path traversal
if [[ ! "${SIGNING_FILE_PATH}" =~ ^/[a-zA-Z0-9/_.-]+$ ]]; then
echo "ERROR: Invalid signing file path format"
exit 1
fi

# Safely handle the signing key file
echo "${SIGNING_KEY_FILE_CONTENT}" > ~/secretKey.gpg.b64
base64 -d ~/secretKey.gpg.b64 > "${SIGNING_FILE_PATH}"
chmod 600 "${SIGNING_FILE_PATH}"
shell: bash
env:
SIGNING_KEY_FILE_CONTENT: ${{ inputs.signing_key_file }}
SIGNING_FILE_PATH: ${{ inputs.signing_file_path }}
77 changes: 0 additions & 77 deletions .github/actions/publish_central_portal/action.yml

This file was deleted.

170 changes: 170 additions & 0 deletions .github/actions/publish_maven_central/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
name: 'Publish to Maven Central'
description: 'Publishes all modules using the Maven Central Portal Plugin'
inputs:
sonatype_user:
description: 'Sonatype user'
required: true
default: ''
sonatype_token:
description: 'Sonatype user token'
required: true
default: ''
signing_key_id:
description: 'Signing key id'
required: true
default: ''
signing_key_password:
description: 'Signing key password'
required: true
default: ''
signing_key_file:
description: 'Signing key file'
required: true
default: ''
auto_publish:
description: 'Whether to publish automatically'
required: false
default: 'true'
use_snapshot:
description: 'Whether to publish as a SNAPSHOT version'
required: false
default: 'false'
runs:
using: "composite"
steps:
- name: Set up Maven
uses: stCarolas/setup-maven@v4.5
with:
maven-version: 3.9.5

- name: Create Maven settings directory
shell: bash
run: |
mkdir -p ${{ github.workspace }}/.mvn

- name: Create Maven settings file
shell: bash
run: |
cat > ${{ github.workspace }}/.mvn/maven-settings.xml << 'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
<servers>
<server>
<id>central</id>
<username>${env.SONATYPE_NEXUS_USERNAME}</username>
<password>${env.SONATYPE_NEXUS_PASSWORD}</password>
</server>
</servers>
<profiles>
<profile>
<id>gpg</id>
<properties>
<gpg.executable>gpg</gpg.executable>
<gpg.keyname>${env.SIGNING_KEY_ID}</gpg.keyname>
<gpg.passphrase>${env.SIGNING_KEY_PASSWORD}</gpg.passphrase>
</properties>
</profile>
</profiles>
<activeProfiles>
<activeProfile>gpg</activeProfile>
</activeProfiles>
</settings>
EOF

- name: Prepare and publish via Central Portal (library)
shell: bash
env:
SONATYPE_NEXUS_USERNAME: ${{ inputs.sonatype_user }}
SONATYPE_NEXUS_PASSWORD: ${{ inputs.sonatype_token }}
SIGNING_KEY_ID: ${{ inputs.signing_key_id }}
SIGNING_KEY_PASSWORD: ${{ inputs.signing_key_password }}
SIGNING_KEY_FILE: ${{ inputs.signing_key_file }}
USE_SNAPSHOT: ${{ inputs.use_snapshot }}
AUTO_PUBLISH: ${{ inputs.auto_publish }}
WORKSPACE_DIR: ${{ github.workspace }}
run: |
set -euo pipefail
echo "Publishing via Central Portal Maven plugin (NMCP) - module :library"

# Validate workspace directory path
if [[ ! "${WORKSPACE_DIR}" =~ ^/[a-zA-Z0-9/_.-]+$ ]]; then
echo "ERROR: Invalid workspace directory path format" >&2
exit 1
fi

if [ ! -d "${WORKSPACE_DIR}/library" ]; then
echo "Error: library directory not found" >&2
exit 1
fi

# Validate boolean inputs
if [[ ! "${USE_SNAPSHOT}" =~ ^(true|false)$ ]]; then
echo "ERROR: Invalid USE_SNAPSHOT value. Must be 'true' or 'false'" >&2
exit 1
fi

if [[ ! "${AUTO_PUBLISH}" =~ ^(true|false)$ ]]; then
echo "ERROR: Invalid AUTO_PUBLISH value. Must be 'true' or 'false'" >&2
exit 1
fi

echo "Importing GPG key for signing"
gpg --batch --import "${SIGNING_KEY_FILE}"

# Configure GPG for CI environment
echo "Configuring GPG for CI environment..."
export GPG_TTY=$(tty 2>/dev/null || echo "")
gpg --batch --list-secret-keys --keyid-format LONG

# Test GPG signing capability early
echo "Testing GPG signing capability..."
echo "test" | gpg --batch --yes --pinentry-mode loopback --passphrase "${SIGNING_KEY_PASSWORD}" --local-user "${SIGNING_KEY_ID}" --armor --detach-sign --output /tmp/test.asc || echo "Warning: GPG test signing failed"

echo "Warming up Gradle wrapper (with retries)"
attempts=0
until ./gradlew -v; do
attempts=$((attempts+1))
if [ $attempts -ge 5 ]; then
echo "Gradle wrapper download failed after ${attempts} attempts" >&2
exit 1
fi
echo "Gradle wrapper failed (attempt ${attempts}), retrying in 5s..."
sleep 5
done

VERSION=$(grep -o '"sdkVersionName"\s*:\s*"[^"]*"' "${WORKSPACE_DIR}/build.gradle" | grep -o '"[^"]*"$' | tr -d '"')

# Validate extracted version format
if ! echo "${VERSION}" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.]+)?$'; then
echo "ERROR: Invalid version format extracted from build.gradle: ${VERSION}" >&2
exit 1
fi

if [ "${USE_SNAPSHOT}" = "true" ]; then
[[ "${VERSION}" != *-SNAPSHOT ]] && VERSION="${VERSION}-SNAPSHOT"
echo "Publishing SNAPSHOT version: ${VERSION}"
else
[[ "${VERSION}" == *-SNAPSHOT ]] && VERSION="${VERSION%-SNAPSHOT}"
echo "Publishing release version: ${VERSION}"
fi

echo "Setting project version to ${VERSION}"
./gradlew -PversionParam="${VERSION}" changeReleaseVersion --no-daemon --stacktrace

echo "Building library and preparing artifacts (AAR + sources + POM)"
./prepare-maven-artifacts.sh

echo "Using library POM directly - no wrapper POM needed..."
# The library POM already has all the required configuration:
# - packaging=aar (AAR as primary artifact)
# - maven-gpg-plugin (for signing)
# - central-publishing-maven-plugin (for deployment)
echo "Library POM has all required Maven Central configuration"

echo "Deploying to Central Portal via Maven plugin"
set -euo pipefail
./deploy-snapshot-to-central.sh

echo "NMCP publish finished. Check deployments at https://central.sonatype.com/publishing/deployments"
12 changes: 11 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ concurrency:
group: build-${{ github.event.number }}
cancel-in-progress: true

permissions:
contents: read

jobs:
build:
name: Build Library
Expand All @@ -28,7 +31,7 @@ jobs:

steps:
- name: Checkout repo
uses: actions/checkout@v4
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683

- name: Set up JDK 17
uses: actions/setup-java@v4
Expand All @@ -51,3 +54,10 @@ jobs:
SIGNING_KEY_FILE: ${{ env.SIGNING_KEY_FILE_PATH }}

- run: echo "Build status report=${{ job.status }}."

- name: Cleanup signing key files
if: always()
run: |
shred -u -z -n 3 "${SIGNING_KEY_FILE_PATH}" || rm -f "${SIGNING_KEY_FILE_PATH}"
rm -f ~/secretKey.gpg.b64 || true
shell: bash
5 changes: 4 additions & 1 deletion .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,17 @@ concurrency:
group: lint-${{ github.event.number }}
cancel-in-progress: true

permissions:
contents: read

jobs:
lint:
name: Lint
runs-on: ubuntu-latest

steps:
- name: Checkout repo
uses: actions/checkout@v4
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683

- name: Set up JDK 17
uses: actions/setup-java@v4
Expand Down
Loading