Skip to content

Commit e387526

Browse files
committed
feat(android): add AAR package build, release and documentation
1 parent c47a3dd commit e387526

File tree

12 files changed

+687
-34
lines changed

12 files changed

+687
-34
lines changed

.github/workflows/main.yml

Lines changed: 76 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ jobs:
1010
build:
1111
runs-on: ${{ matrix.os }}
1212
container: ${{ matrix.container && matrix.container || '' }}
13-
name: ${{ matrix.name }}${{ matrix.arch && format('-{0}', matrix.arch) || '' }} build${{ matrix.arch != 'arm64-v8a' && matrix.name != 'ios-sim' && matrix.name != 'ios' && matrix.name != 'apple-xcframework' && ' + test' || ''}}
13+
name: ${{ matrix.name }}${{ matrix.arch && format('-{0}', matrix.arch) || '' }} build${{ matrix.arch != 'arm64-v8a' && matrix.name != 'ios-sim' && matrix.name != 'ios' && matrix.name != 'apple-xcframework' && matrix.name != 'android-aar' && ' + test' || ''}}
1414
timeout-minutes: 20
1515
strategy:
1616
fail-fast: false
@@ -52,6 +52,9 @@ jobs:
5252
- os: macos-15
5353
name: apple-xcframework
5454
make: xcframework
55+
- os: ubuntu-22.04
56+
name: android-aar
57+
make: aar
5558

5659
defaults:
5760
run:
@@ -61,6 +64,13 @@ jobs:
6164

6265
- uses: actions/[email protected]
6366

67+
- name: android setup java
68+
if: matrix.name == 'android-aar'
69+
uses: actions/setup-java@v4
70+
with:
71+
distribution: 'temurin'
72+
java-version: '17'
73+
6474
- name: windows install dependencies
6575
if: matrix.name == 'windows'
6676
run: choco install sqlite -y
@@ -188,12 +198,65 @@ jobs:
188198
with:
189199
path: artifacts
190200

201+
- name: zip artifacts
202+
run: |
203+
VERSION=$(make version)
204+
for folder in "artifacts"/*; do
205+
if [ -d "$folder" ]; then
206+
name=$(basename "$folder")
207+
if [[ "$name" != "js-apple-xcframework" && "$name" != "js-android-aar" ]]; then
208+
tar -czf "${name}-${VERSION}.tar.gz" -C "$folder" .
209+
fi
210+
if [[ "$name" != "js-android-aar" ]]; then
211+
(cd "$folder" && zip -rq "../../${name}-${VERSION}.zip" .)
212+
else
213+
cp "$folder"/*.aar "${name}-${VERSION}.aar"
214+
fi
215+
fi
216+
done
217+
191218
- name: release tag version from sqlitejs.h
192219
id: tag
193220
run: |
194221
VERSION=$(make version)
195222
if [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
196-
LATEST=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" https://api.github.com/repos/${{ github.repository }}/releases/latest | jq -r '.name')
223+
LATEST_RELEASE=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" https://api.github.com/repos/${{ github.repository }}/releases/latest)
224+
LATEST=$(echo "$LATEST_RELEASE" | jq -r '.name')
225+
# Check artifact sizes against previous release
226+
if [ -n "$LATEST" ] && [ "$LATEST" != "null" ]; then
227+
echo "Checking artifact sizes against previous release: $LATEST"
228+
FAILED=0
229+
for artifact in js-*-${VERSION}.*; do
230+
if [ ! -f "$artifact" ]; then
231+
continue
232+
fi
233+
# Get current artifact size
234+
NEW_SIZE=$(stat -c%s "$artifact" 2>/dev/null || stat -f%z "$artifact")
235+
# Get artifact name for previous release
236+
ARTIFACT_NAME=$(echo "$artifact" | sed "s/${VERSION}/${LATEST}/")
237+
# Get previous artifact size from GitHub API
238+
OLD_SIZE=$(echo "$LATEST_RELEASE" | jq -r ".assets[] | select(.name == \"$(basename "$ARTIFACT_NAME")\") | .size")
239+
if [ -z "$OLD_SIZE" ] || [ "$OLD_SIZE" = "null" ]; then
240+
echo "⚠️ Previous artifact not found: $(basename "$ARTIFACT_NAME"), skipping comparison"
241+
continue
242+
fi
243+
# Calculate percentage increase
244+
INCREASE=$(awk "BEGIN {printf \"%.2f\", (($NEW_SIZE - $OLD_SIZE) / $OLD_SIZE) * 100}")
245+
echo "📦 $artifact: $OLD_SIZE → $NEW_SIZE bytes (${INCREASE}% change)"
246+
# Check if increase is more than 5%
247+
if (( $(echo "$INCREASE > 5" | bc -l) )); then
248+
echo "❌ ERROR: $artifact size increased by ${INCREASE}% (limit: 5%)"
249+
FAILED=1
250+
fi
251+
done
252+
if [ $FAILED -eq 1 ]; then
253+
echo ""
254+
echo "❌ One or more artifacts exceeded the 5% size increase limit"
255+
exit 1
256+
fi
257+
echo "✅ All artifacts within 5% size increase limit"
258+
fi
259+
197260
if [[ "$VERSION" != "$LATEST" || "$GITHUB_EVENT_NAME" == "workflow_dispatch" ]]; then
198261
echo "version=$VERSION" >> $GITHUB_OUTPUT
199262
else
@@ -203,25 +266,21 @@ jobs:
203266
fi
204267
echo "❌ SQLITE_JS_VERSION not found in sqlitejs.h"
205268
exit 1
206-
207-
- name: zip artifacts
208-
run: |
209-
for folder in "artifacts"/*; do
210-
if [ -d "$folder" ]; then
211-
name=$(basename "$folder")
212-
if [[ "$name" != "js-apple-xcframework" ]]; then
213-
tar -czf "${name}-${{ steps.tag.outputs.version }}.tar.gz" -C "$folder" .
214-
fi
215-
(cd "$folder" && zip -rq "../../${name}-${{ steps.tag.outputs.version }}.zip" .)
216-
fi
217-
done
269+
270+
- uses: actions/setup-java@v4
271+
if: steps.tag.outputs.version != ''
272+
with:
273+
distribution: 'temurin'
274+
java-version: '17'
275+
276+
- name: release android aar to maven central
277+
if: steps.tag.outputs.version != ''
278+
run: make aar && cd packages/android && ./gradlew publishAggregationToCentralPortal -PSIGNING_KEY="${{ secrets.SIGNING_KEY }}" -PSIGNING_PASSWORD="${{ secrets.SIGNING_PASSWORD }}" -PSONATYPE_USERNAME="${{ secrets.MAVEN_CENTRAL_USERNAME }}" -PSONATYPE_PASSWORD="${{ secrets.MAVEN_CENTRAL_TOKEN }}" -PVERSION="${{ steps.tag.outputs.version }}"
218279

219280
- uses: softprops/[email protected]
220281
if: steps.tag.outputs.version != ''
221282
with:
222283
generate_release_notes: true
223284
tag_name: ${{ steps.tag.outputs.version }}
224-
files: |
225-
js-*-${{ steps.tag.outputs.version }}.zip
226-
js-*-${{ steps.tag.outputs.version }}.tar.gz
285+
files: js-*-${{ steps.tag.outputs.version }}.*
227286
make_latest: true

.gitignore

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,29 @@
1-
.DS_Store
1+
# Build artifacts
2+
build/
3+
/dist
4+
.build
5+
*.a
6+
*.sqlite
7+
8+
# iOS/macOS
29
*.xcworkspacedata
310
*.xcuserstate
411
*.xcbkptlist
512
*.plist
6-
/build
7-
/dist
8-
*.sqlite
9-
.build
13+
14+
# Android
15+
.gradle/
16+
*.aar
17+
local.properties
18+
jniLibs/
19+
*.apk
20+
*.ap_
21+
*.dex
22+
23+
# IDE
24+
.vscode
25+
.idea/
26+
*.iml
27+
28+
# System
29+
.DS_Store

Makefile

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,17 @@ $(DIST_DIR)/%.xcframework: $(LIB_NAMES)
216216

217217
xcframework: $(DIST_DIR)/js.xcframework
218218

219+
AAR_ARM = packages/android/src/main/jniLibs/arm64-v8a/
220+
AAR_X86 = packages/android/src/main/jniLibs/x86_64/
221+
aar:
222+
mkdir -p $(AAR_ARM) $(AAR_X86)
223+
$(MAKE) clean && $(MAKE) PLATFORM=android ARCH=arm64-v8a
224+
mv $(DIST_DIR)/js.so $(AAR_ARM)
225+
$(MAKE) clean && $(MAKE) PLATFORM=android ARCH=x86_64
226+
mv $(DIST_DIR)/js.so $(AAR_X86)
227+
cd packages/android && ./gradlew clean assembleRelease
228+
cp packages/android/build/outputs/aar/android-release.aar $(DIST_DIR)/js.aar
229+
219230
version:
220231
@echo $(shell sed -n 's/^#define SQLITE_JS_VERSION[[:space:]]*"\([^"]*\)".*/\1/p' src/sqlitejs.h)
221232

@@ -234,10 +245,12 @@ help:
234245
@echo " ios-sim (only on macOS)"
235246
@echo ""
236247
@echo "Targets:"
237-
@echo " all - Build the extension (default)"
238-
@echo " clean - Remove built files"
239-
@echo " install - Install the extension"
240-
@echo " test - Test the extension"
241-
@echo " help - Display this help message"
248+
@echo " all - Build the extension (default)"
249+
@echo " clean - Remove built files"
250+
@echo " install - Install the extension"
251+
@echo " test - Test the extension"
252+
@echo " help - Display this help message"
253+
@echo " xcframework - Build the Apple XCFramework"
254+
@echo " aar - Build the Android AAR package"
242255

243-
.PHONY: all extension clean install test help version xcframework
256+
.PHONY: all extension clean install test help version xcframework aar

README.md

Lines changed: 86 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,16 @@ Download the appropriate pre-built binary for your platform from the official [R
3030
- Android
3131
- iOS
3232

33+
### Loading the Extension
34+
35+
```sql
36+
-- In SQLite CLI
37+
.load ./js
38+
39+
-- In SQL
40+
SELECT load_extension('./js');
41+
```
42+
3343
### Swift Package
3444

3545
You can [add this repository as a package dependency to your Swift project](https://developer.apple.com/documentation/xcode/adding-package-dependencies-to-your-app#Add-a-package-dependency). After adding the package, you'll need to set up SQLite with extension loading by following steps 4 and 5 of [this guide](https://github.com/sqliteai/sqlite-extensions-guide/blob/main/platforms/ios.md#4-set-up-sqlite-with-extension-loading).
@@ -53,14 +63,84 @@ log("js_version(): \(String(cString: sqlite3_column_text(stmt, 0)))")
5363
sqlite3_close(db)
5464
```
5565

56-
### Loading the Extension
66+
### Android Package
67+
68+
You can [add this project as a dependency to your Android project](https://central.sonatype.com/artifact/ai.sqlite/js).
69+
70+
**Groovy:**
71+
```gradle
72+
repositories {
73+
google()
74+
mavenCentral()
75+
maven { url 'https://jitpack.io' }
76+
}
77+
dependencies {
78+
// ...
79+
// Use requery's SQLite instead of Android's built-in SQLite to support loading custom extensions
80+
implementation 'com.github.requery:sqlite-android:3.49.0'
81+
// Both packages below are identical - use either one
82+
implementation 'ai.sqlite:js:0.9.32' // Maven Central
83+
// implementation 'com.github.sqliteai:sqlite-js:0.9.32' // JitPack (alternative)
84+
}
85+
```
5786

58-
```sql
59-
-- In SQLite CLI
60-
.load ./js
87+
**Kotlin:**
88+
```kotlin
89+
repositories {
90+
google()
91+
mavenCentral()
92+
maven(url = "https://jitpack.io")
93+
}
94+
95+
dependencies {
96+
// ...
97+
98+
// Use requery's SQLite instead of Android's built-in SQLite to support loading custom extensions
99+
implementation("com.github.requery:sqlite-android:3.49.0")
100+
// Both packages below are identical - use either one
101+
implementation("ai.sqlite:js:0.9.32") // Maven Central
102+
// implementation("com.github.sqliteai:sqlite-js:0.9.32") // JitPack (alternative)
103+
}
104+
```
61105

62-
-- In SQL
63-
SELECT load_extension('./js');
106+
After adding the package, you'll need to [enable extractNativeLibs](https://github.com/sqliteai/sqlite-extensions-guide/blob/18acfc56d6af8791928f3ac8df7dc0e6a9741dd4/examples/android/src/main/AndroidManifest.xml#L6).
107+
108+
Here's an example of how to use the package:
109+
```java
110+
import android.database.Cursor;
111+
import android.util.Log;
112+
import io.requery.android.database.sqlite.SQLiteCustomExtension;
113+
import io.requery.android.database.sqlite.SQLiteDatabase;
114+
import io.requery.android.database.sqlite.SQLiteDatabaseConfiguration;
115+
import java.util.Collections;
116+
117+
...
118+
119+
private void jsExtension() {
120+
try {
121+
SQLiteCustomExtension jsExtension = new SQLiteCustomExtension(getApplicationInfo().nativeLibraryDir + "/js", null);
122+
SQLiteDatabaseConfiguration config = new SQLiteDatabaseConfiguration(
123+
getCacheDir().getPath() + "/js_test.db",
124+
SQLiteDatabase.CREATE_IF_NECESSARY | SQLiteDatabase.OPEN_READWRITE,
125+
Collections.emptyList(),
126+
Collections.emptyList(),
127+
Collections.singletonList(jsExtension)
128+
);
129+
130+
SQLiteDatabase db = SQLiteDatabase.openDatabase(config, null, null);
131+
132+
Cursor cursor = db.rawQuery("SELECT js_version()", null);
133+
if (cursor.moveToFirst()) {
134+
String version = cursor.getString(0);
135+
Log.i("sqlite-js", "js_version(): " + version);
136+
}
137+
cursor.close();
138+
db.close();
139+
140+
} catch (Exception e) {
141+
Log.e("sqlite-js", "Error: " + e.getMessage());
142+
}
143+
}
64144
```
65145

66146
## Functions Overview

jitpack.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
jdk:
2+
- openjdk17
3+
install:
4+
- make aar ANDROID_NDK=$ANDROID_HOME/ndk-bundle
5+
- export VERSION=$(make version 2>/dev/null | tail -1)
6+
- cd packages/android && ./gradlew publishToMavenLocal -PVERSION="$VERSION"

0 commit comments

Comments
 (0)