Skip to content

Commit 8c8778e

Browse files
authored
Refactor publishing workflow, reduce file count (#359)
1 parent cd8c6ae commit 8c8778e

7 files changed

Lines changed: 180 additions & 170 deletions

File tree

.github/workflows/deploy.yml

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -56,30 +56,32 @@ jobs:
5656
with:
5757
artifact-ids: ${{ needs.fetch_prebuilts.outputs.artifact_id }}
5858
path: internal/prebuild-binaries/build/output/
59-
- name: Gradle publish
59+
- name: Generate publications
6060
run: |
6161
./gradlew \
6262
--no-configuration-cache \
6363
-PhasPrebuiltAssets=true \
6464
-PsigningInMemoryKey="${{ secrets.SIGNING_KEY }}" \
6565
-PsigningInMemoryKeyId="${{ secrets.SIGNING_KEY_ID }}" \
6666
-PsigningInMemoryKeyPassword="${{ secrets.SIGNING_PASSWORD }}" \
67-
-PcentralPortal.username="${{secrets.SONATYPE_USERNAME}}" \
68-
-PcentralPortal.password="${{secrets.SONATYPE_PASSWORD}}" \
6967
-Ppowersync.binaries.allPlatforms="true" \
70-
publishAllPublicationsToSonatypeLocalRepository
68+
generatePublishingBundle
7169
72-
./gradlew \
73-
--no-configuration-cache \
74-
-PhasPrebuiltAssets=true \
75-
-PsigningInMemoryKey="${{ secrets.SIGNING_KEY }}" \
76-
-PsigningInMemoryKeyId="${{ secrets.SIGNING_KEY_ID }}" \
77-
-PsigningInMemoryKeyPassword="${{ secrets.SIGNING_PASSWORD }}" \
78-
-PcentralPortal.username="${{secrets.SONATYPE_USERNAME}}" \
79-
-PcentralPortal.password="${{secrets.SONATYPE_PASSWORD}}" \
80-
-Ppowersync.binaries.allPlatforms="true" \
81-
publishAllPublicationsToSonatypeRepository
82-
shell: bash
70+
- name: Inspect publication
71+
run: |
72+
./internal/analyze-bundle.py
73+
zip -r build/sonatypeBundle.zip build/sonatypeBundle/
74+
75+
- name: Upload to Maven Central
76+
env:
77+
# printf "$SONATYPE_USERNAME:$SONATYPE_PASSWORD" | base64
78+
SONATYPE_CREDENTIALS: ${{ secrets.SONATYPE_CREDENTIALS }}
79+
run: |
80+
tag=$(basename "${{ github.ref }}")
81+
curl --fail-with-body --request POST \
82+
--header "Authorization: Bearer $SONATYPE_CREDENTIALS" \
83+
--form bundle=@build/sonatypeBundle.zip \
84+
"https://central.sonatype.com/api/v1/publisher/upload?name=$tag&publishingType=AUTOMATIC"
8385
8486
add_assets:
8587
permissions:
@@ -108,3 +110,4 @@ jobs:
108110
GH_REPO: ${{ github.repository }}
109111
run: |
110112
gh release upload "${{ needs.draft_release.outputs.tag }}" prebuilt_libraries.zip
113+

.github/workflows/test.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,6 @@ jobs:
6262
- name: Set up XCode
6363
if: runner.os == 'macOS'
6464
uses: maxim-lobanov/setup-xcode@v1
65-
with:
66-
# TODO: Update to latest-stable once GH installs iOS 26 simulators
67-
xcode-version: '^16.4.0'
6865
- name: Download prebuilts
6966
uses: actions/download-artifact@v8
7067
with:

build.gradle.kts

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import com.powersync.plugins.sonatype.SonatypeCentralUploadPlugin
2+
13
import com.sun.net.httpserver.HttpExchange
24
import com.sun.net.httpserver.HttpServer
35
import java.net.InetSocketAddress
@@ -21,21 +23,29 @@ plugins {
2123
alias(libs.plugins.androidx.room) apply false
2224
id("org.jetbrains.dokka") version libs.versions.dokkaBase
2325
id("dokka-convention")
26+
id("com.powersync.plugins.sonatype") apply false
2427
}
2528

2629
tasks.getByName<Delete>("clean") {
2730
delete(rootProject.layout.buildDirectory)
2831
}
2932

33+
val sonatypePublishingBundleConfiguration by configurations.creating {
34+
isCanBeConsumed = false
35+
}
36+
3037
// Merges individual module docs into a single HTML output
3138
dependencies {
32-
dokka(projects.common)
33-
dokka(projects.core)
34-
dokka(projects.compose)
35-
dokka(projects.integrations.room)
36-
dokka(projects.integrations.sqldelight)
37-
dokka(projects.integrations.supabase)
38-
dokka(projects.sqlite3multipleciphers)
39+
// Internal published projects we don't include in the Dokka overview.
40+
val undocumentedProjects = listOf(":static-sqlite-driver", ":internal:sqlite3mcandroid")
41+
42+
for (projectPath in SonatypeCentralUploadPlugin.publishedProjects) {
43+
if (!undocumentedProjects.contains(projectPath)) {
44+
dokka(project(path=projectPath))
45+
}
46+
47+
sonatypePublishingBundleConfiguration(project(path=projectPath, configuration="sonatypePublishingBundleConfiguration"))
48+
}
3949
}
4050

4151
dokka {
@@ -100,3 +110,26 @@ tasks.register("serveDokka") {
100110
Thread.currentThread().join()
101111
}
102112
}
113+
114+
val generatePublishingBundle by tasks.registering(Copy::class) {
115+
group = "publishing"
116+
117+
val subprojects: FileCollection = sonatypePublishingBundleConfiguration
118+
inputs.files(subprojects)
119+
120+
from(subprojects.files.toTypedArray()) {
121+
exclude { fileTreeElement ->
122+
val name = fileTreeElement.relativePath.lastName
123+
// Skip some files: We don't need to upload maven metadata as Sonatype generates
124+
// those files for us. There's no way to disable sha512 hashes in Gradle (and it
125+
// insists on hashing signatures), we don't need those files either.
126+
name.startsWith("maven-metadata") ||
127+
name.endsWith(".sha512") ||
128+
name.endsWith(".asc.md5") ||
129+
name.endsWith(".asc.sha1") ||
130+
name.endsWith(".asc.sha256") ||
131+
name.endsWith(".asc.sha512")
132+
}
133+
}
134+
into(layout.buildDirectory.dir("sonatypeBundle").get())
135+
}

internal/analyze-bundle.py

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
#!/usr/bin/env python3
2+
"""Analyze a sonatypeBundle directory and report size breakdown."""
3+
4+
import os
5+
import sys
6+
from collections import defaultdict
7+
from pathlib import Path
8+
9+
10+
def human(size: int) -> str:
11+
for unit in ("B", "KB", "MB", "GB"):
12+
if size < 1024:
13+
return f"{size:.1f} {unit}"
14+
size /= 1024
15+
return f"{size:.1f} TB"
16+
17+
18+
def classify(name: str) -> str:
19+
if name.endswith("-javadoc.jar"):
20+
return "javadoc jar"
21+
if name.endswith("-sources.jar"):
22+
return "sources jar"
23+
if name.endswith(".klib"):
24+
return ".klib"
25+
if name.endswith(".aar"):
26+
return ".aar"
27+
if name.endswith(".jar"):
28+
return ".jar"
29+
if name.endswith(".pom"):
30+
return ".pom"
31+
if name.endswith(".module"):
32+
return ".module"
33+
if name.endswith(".asc"):
34+
return ".asc signature"
35+
for ext in (".sha512", ".sha256", ".sha1", ".md5"):
36+
if name.endswith(ext):
37+
return "checksum"
38+
return "other"
39+
40+
41+
def main(bundle_dir: str) -> None:
42+
root = Path(bundle_dir)
43+
if not root.is_dir():
44+
print(f"error: {bundle_dir} is not a directory", file=sys.stderr)
45+
sys.exit(1)
46+
47+
files: list[tuple[int, Path]] = []
48+
by_type: dict[str, int] = defaultdict(int)
49+
by_type_count: dict[str, int] = defaultdict(int)
50+
51+
for path in root.rglob("*"):
52+
if not path.is_file():
53+
continue
54+
size = path.stat().st_size
55+
files.append((size, path))
56+
57+
kind = classify(path.name)
58+
by_type[kind] += size
59+
by_type_count[kind] += 1
60+
61+
total = sum(s for s, _ in files)
62+
print(f"Total: {human(total)} ({len(files)} files)\n")
63+
64+
# --- By file type ---
65+
print("By file type:")
66+
print(f" {'Type':<20} {'Size':>10} {'Count':>6}")
67+
print(f" {'-'*20} {'-'*10} {'-'*6}")
68+
for kind, size in sorted(by_type.items(), key=lambda x: -x[1]):
69+
print(f" {kind:<20} {human(size):>10} {by_type_count[kind]:>6}")
70+
71+
if __name__ == "__main__":
72+
target = sys.argv[1] if len(sys.argv) > 1 else "build/sonatypeBundle"
73+
main(target)

plugins/sonatype/src/main/kotlin/com/powersync/plugins/sonatype/PublishToCentralPortalTask.kt

Lines changed: 0 additions & 107 deletions
This file was deleted.

0 commit comments

Comments
 (0)