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
100 changes: 100 additions & 0 deletions .github/workflows/build-and-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
name: Build and Test

on:
push:
branches:
- main
- master
- develop
- dev
- "release/**"
- "hotfix/**"
- "feature/**"
pull_request:
branches:
- main
- master
- develop
- dev
workflow_dispatch:
workflow_call:
secrets:
ENV_JSON_PASSPHRASE:
required: false

jobs:
build-and-test:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Java
uses: actions/setup-java@v4
with:
distribution: "temurin"
java-version: "17"
cache: "gradle"

- name: Setup Android SDK
uses: android-actions/setup-android@v3

- name: Install Android SDK packages
run: |
yes | sdkmanager --licenses >/dev/null
yes | sdkmanager \
"platform-tools" \
"platforms;android-34" \
"build-tools;34.0.0"

- name: Decrypt env.json for integration tests
if: hashFiles('env.json.enc') != ''
env:
ENV_JSON_PASSPHRASE: ${{ secrets.ENV_JSON_PASSPHRASE }}
run: |
if [ -z "${ENV_JSON_PASSPHRASE:-}" ]; then
echo "ENV_JSON_PASSPHRASE is not set. Integration tests that need env.json will be skipped."
exit 0
fi
./scripts/decrypt-env.sh

- name: Build JVM and Android modules
run: |
./gradlew \
:api:assemble \
:common:assemble \
:crypto:assemble \
:test-common:assemble \
:sdk:assemble \
:crypto-android:assembleRelease \
:android-utils:assembleRelease \
:sdk-android:assembleRelease \
--no-daemon \
--stacktrace

- name: Run JVM tests
run: |
./gradlew \
:api:test \
:common:test \
:crypto:test \
:test-common:test \
:sdk:test \
--no-daemon \
--stacktrace

- name: Cleanup decrypted env.json
if: always()
run: rm -f env.json

- name: Upload test reports
if: always()
uses: actions/upload-artifact@v4
with:
name: jvm-test-reports
path: |
**/build/reports/tests/**/*
**/build/test-results/**/*
if-no-files-found: warn
212 changes: 212 additions & 0 deletions .github/workflows/publish-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
name: Publish Release

on:
push:
tags:
- "v*.*.*"
- "v*.*.*-rc*"
workflow_dispatch:
inputs:
tag:
description: "Tag to release (for example v7.3.2)"
required: true
type: string

jobs:
verify-version:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ github.event_name == 'workflow_dispatch' && inputs.tag || github.ref }}

- name: Verify SDK version matches tag
run: |
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
TAG="${{ inputs.tag }}"
else
TAG="${GITHUB_REF#refs/tags/}"
fi

TAG_VERSION="${TAG#v}"
SDK_VERSION=$(grep -E "final String SDK_VERSION = '[^']+'" build.gradle | sed -E "s/.*'([^']+)'.*/\1/" | tr -d '[:space:]')
SDK_VERSION_BASE="${SDK_VERSION%-SNAPSHOT}"

echo "Tag version: ${TAG_VERSION}"
echo "SDK version: ${SDK_VERSION_BASE}"

if [ -z "${SDK_VERSION_BASE}" ]; then
echo "ERROR: Could not extract SDK_VERSION from build.gradle"
exit 1
fi

if [ "${TAG_VERSION}" != "${SDK_VERSION_BASE}" ]; then
echo "ERROR: Tag version (${TAG_VERSION}) doesn't match SDK version (${SDK_VERSION_BASE})"
exit 1
fi

build:
name: Build and Test
needs: verify-version
uses: ./.github/workflows/build-and-test.yml
secrets: inherit

publish:
name: Publish Artifacts
needs: build
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ github.event_name == 'workflow_dispatch' && inputs.tag || github.ref }}

- name: Setup Java
uses: actions/setup-java@v4
with:
distribution: "temurin"
java-version: "17"
cache: "gradle"

- name: Setup Android SDK
uses: android-actions/setup-android@v3

- name: Install Android SDK packages
run: |
yes | sdkmanager --licenses >/dev/null
yes | sdkmanager \
"platform-tools" \
"platforms;android-34" \
"build-tools;34.0.0"

- name: Verify Central bundle publish tasks exist
run: |
./gradlew -q help --task :api:publishMavenJavaPublicationToCentralBundleRepository
./gradlew -q help --task :common:publishMavenJavaPublicationToCentralBundleRepository
./gradlew -q help --task :crypto:publishMavenJavaPublicationToCentralBundleRepository
./gradlew -q help --task :test-common:publishMavenJavaPublicationToCentralBundleRepository
./gradlew -q help --task :sdk:publishMavenJavaPublicationToCentralBundleRepository
./gradlew -q help --task :crypto-android:publishMavenJavaPublicationToCentralBundleRepository
./gradlew -q help --task :android-utils:publishMavenJavaPublicationToCentralBundleRepository
./gradlew -q help --task :sdk-android:publishMavenJavaPublicationToCentralBundleRepository

- name: Publish artifacts to local bundle repo
env:
ORG_GRADLE_PROJECT_signingKey: ${{ secrets.CENTRAL_SONATYPE_SIGNING_KEY }}
ORG_GRADLE_PROJECT_signingPassword: ${{ secrets.CENTRAL_SONATYPE_SIGNING_PASSWORD }}
run: |
rm -rf build/central-bundle-repo build/central-bundle.zip
./gradlew \
:api:publishMavenJavaPublicationToCentralBundleRepository \
:common:publishMavenJavaPublicationToCentralBundleRepository \
:crypto:publishMavenJavaPublicationToCentralBundleRepository \
:test-common:publishMavenJavaPublicationToCentralBundleRepository \
:sdk:publishMavenJavaPublicationToCentralBundleRepository \
:crypto-android:publishMavenJavaPublicationToCentralBundleRepository \
:android-utils:publishMavenJavaPublicationToCentralBundleRepository \
:sdk-android:publishMavenJavaPublicationToCentralBundleRepository \
--no-daemon \
--stacktrace

- name: Validate bundle repo contains POMs
run: |
test -d build/central-bundle-repo
POM_COUNT=$(find build/central-bundle-repo -type f -name '*.pom' | wc -l | tr -d '[:space:]')
echo "POM count: ${POM_COUNT}"
if [ "${POM_COUNT}" = "0" ]; then
echo "ERROR: No .pom files found in build/central-bundle-repo"
find build/central-bundle-repo -maxdepth 6 -type f | head -n 200
exit 1
fi

- name: Build Central bundle zip
run: |
test -d build/central-bundle-repo

# Central bundle should not include repository metadata/module metadata.
find build/central-bundle-repo -type f -name 'maven-metadata.xml*' -delete
find build/central-bundle-repo -type f -name '*.module*' -delete

while IFS= read -r -d '' file; do
md5sum "$file" | awk '{print $1}' > "$file.md5"
sha1sum "$file" | awk '{print $1}' > "$file.sha1"
done < <(find build/central-bundle-repo -type f \
! -name '*.asc' \
! -name '*.md5' \
! -name '*.sha1' \
-print0)

(cd build/central-bundle-repo && zip -q -r ../central-bundle.zip .)
ls -la build/central-bundle.zip

- name: Upload Central bundle (debug)
if: always()
uses: actions/upload-artifact@v4
with:
name: central-portal-bundle
path: build/central-bundle.zip

- name: Upload Central bundle repo (debug)
if: always()
uses: actions/upload-artifact@v4
with:
name: central-portal-bundle-repo
path: build/central-bundle-repo/

- name: Upload bundle to Sonatype Central Portal
env:
CENTRAL_USERNAME: ${{ secrets.CENTRAL_SONATYPE_TOKEN_USERNAME }}
CENTRAL_PASSWORD: ${{ secrets.CENTRAL_SONATYPE_TOKEN_PASSWORD }}
run: |
if [ -z "${CENTRAL_USERNAME}" ] || [ -z "${CENTRAL_PASSWORD}" ]; then
echo "ERROR: Missing Central token credentials"
exit 1
fi

CENTRAL_BEARER=$(printf "%s:%s" "${CENTRAL_USERNAME}" "${CENTRAL_PASSWORD}" | base64 | tr -d '\n')
DEPLOYMENT_ID=$(curl -sS \
--fail \
--header "Authorization: Bearer ${CENTRAL_BEARER}" \
--form "bundle=@build/central-bundle.zip" \
"https://central.sonatype.com/api/v1/publisher/upload?publishingType=AUTOMATIC&name=${{ github.event_name == 'workflow_dispatch' && inputs.tag || github.ref_name }}")

if [ -z "${DEPLOYMENT_ID}" ]; then
echo "ERROR: Central Portal did not return deployment ID"
exit 1
fi
echo "Central deployment id: ${DEPLOYMENT_ID}"
echo "DEPLOYMENT_ID=${DEPLOYMENT_ID}" >> "$GITHUB_ENV"

- name: Wait for Central Portal publish
env:
CENTRAL_USERNAME: ${{ secrets.CENTRAL_SONATYPE_TOKEN_USERNAME }}
CENTRAL_PASSWORD: ${{ secrets.CENTRAL_SONATYPE_TOKEN_PASSWORD }}
run: |
CENTRAL_BEARER=$(printf "%s:%s" "${CENTRAL_USERNAME}" "${CENTRAL_PASSWORD}" | base64 | tr -d '\n')

for i in $(seq 1 60); do
STATUS_JSON=$(curl -sS --fail --request POST \
--header "Authorization: Bearer ${CENTRAL_BEARER}" \
"https://central.sonatype.com/api/v1/publisher/status?id=${DEPLOYMENT_ID}")
STATE=$(python3 -c 'import json,sys; print(json.load(sys.stdin).get("deploymentState",""))' <<<"${STATUS_JSON}")
echo "Central state: ${STATE}"

if [ "${STATE}" = "PUBLISHED" ]; then
exit 0
fi
if [ "${STATE}" = "FAILED" ]; then
echo "Central deployment FAILED"
echo "${STATUS_JSON}"
exit 1
fi

sleep 30
done

echo "Timed out waiting for Central Portal publish"
exit 1
65 changes: 0 additions & 65 deletions .travis.yml

This file was deleted.

Loading