Skip to content

Commit 674948b

Browse files
NonSwagLuggaPugga
andauthored
feat: add proguard plugin (#26)
* Update .gitignore to exclude JetBrains IDE files * Add initial implementation of the ProGuard plugin * Rename fields in ProGuard mapping payload for consistency * Add manifest attribute injection for build ID in ProGuard plugin * Add BuildIdFilter to inject and filter build ID in ProGuard plugin * Add GitHub Actions workflow for building and testing ProGuard plugin * Move version declaration to gradle.properties for ProGuard plugin * Update Gradle workflow to specify ProGuard plugin build path * Clarify default ProGuard mapping file path in README * Update Gradle workflow to use Java 17 * Fix Gradle workflow: set working directory for ProGuard plugin build * chore: add proguard plugin to readme * Adopt upload API changes * chore: update turbo version, add proguard plugin scripts, and enhance GitHub Actions workflow --------- Co-authored-by: Luca <lucameopou@gmail.com>
1 parent 8f2b156 commit 674948b

23 files changed

Lines changed: 969 additions & 6 deletions

.github/workflows/gradle.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
name: Gradle Build
2+
on:
3+
pull_request:
4+
paths: [ "packages/proguard-plugin/**" ]
5+
push:
6+
paths: [ "packages/proguard-plugin/**" ]
7+
branches: [ main ]
8+
jobs:
9+
build:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- name: Checkout sources
13+
uses: actions/checkout@v6
14+
- name: Setup Java
15+
uses: actions/setup-java@v5
16+
with:
17+
distribution: 'temurin'
18+
java-version: 17
19+
- name: Setup Gradle
20+
uses: gradle/actions/setup-gradle@v5
21+
with:
22+
cache-read-only: ${{ github.ref != 'refs/heads/main' }}
23+
- name: Build and Test with Gradle
24+
working-directory: packages/proguard-plugin
25+
run: ./gradlew build test

.github/workflows/release.yml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@ jobs:
3434
with:
3535
bun-version: latest
3636

37+
- name: Setup Java
38+
uses: actions/setup-java@v5
39+
with:
40+
distribution: "temurin"
41+
java-version: "17"
42+
3743
- name: Install Dependencies
3844
run: bun install --frozen-lockfile
3945

@@ -49,4 +55,6 @@ jobs:
4955
commit: "chore: version packages"
5056
title: "chore: version packages"
5157
env:
52-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
58+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
59+
REPOSITORY_TOKEN: ${{ secrets.REPOSITORY_TOKEN }}
60+
REPOSITORY_USER: ${{ secrets.REPOSITORY_USER }}

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
# Dependencies
22
node_modules
33

4+
# JetBrains IDEs
5+
6+
.idea/
7+
*.iml
8+
49
# Local env files
510
.env
611
.env.local

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ A monorepo for sourcemap upload infrastructure.
88
## Structure
99

1010
- **`apps/backend`** — Rust (Axum) API server that ingests sourcemap uploads
11-
- **`packages/bundler-plugin`** — Universal unplugin adapter set (Vite, Rollup, Rolldown, Webpack, Rspack, esbuild, Unloader, Farm, Bun) that uploads sourcemaps after builds
11+
- **`packages/bundler-plugin`** — Universal unplugin adapter set (Vite, Rolldown, Webpack and more) that uploads sourcemaps after builds
12+
- **`packages/proguard-plugin`** — a Gradle plugin for uploading ProGuard obfuscation mappings
1213

1314
## Development
1415

bun.lock

Lines changed: 7 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,17 @@
33
"private": true,
44
"scripts": {
55
"build": "turbo run build",
6-
"build:packages": "turbo run build --filter=@faststats/sourcemap-uploader-plugin",
6+
"build:packages": "turbo run build --filter=@faststats/sourcemap-uploader-plugin && bun run build:proguard-plugin",
7+
"build:proguard-plugin": "bun run --cwd packages/proguard-plugin build",
8+
"sync-proguard-version": "bun scripts/sync-proguard-version.ts",
79
"dev": "turbo run dev",
810
"lint": "turbo run lint",
911
"test": "turbo run test",
1012
"format": "prettier --write \"**/*.{ts,tsx,md}\"",
1113
"check-types": "turbo run check-types",
1214
"ci": "turbo run lint check-types test build",
13-
"ci:version": "changeset version && bun update",
14-
"ci:publish": "changeset publish"
15+
"ci:version": "changeset version && bun update && bun run sync-proguard-version",
16+
"ci:publish": "changeset publish && bun scripts/publish-proguard-plugin.ts"
1517
},
1618
"devDependencies": {
1719
"@biomejs/biome": "2.4.10",
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
build/
2+
.gradle/

packages/proguard-plugin/README.md

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
# Proguard Plugin
2+
3+
A Gradle plugin that uploads ProGuard/R8 obfuscation mapping files to the [Faststats](https://faststats.dev) sourcemaps
4+
API for stacktrace deobfuscation.
5+
6+
## Installation
7+
8+
Add the plugin to your project's `build.gradle.kts`:
9+
10+
```kotlin
11+
plugins {
12+
id("dev.faststats.proguard-mappings-upload") version "0.1.0"
13+
}
14+
```
15+
16+
Or in Groovy (`build.gradle`):
17+
18+
```groovy
19+
plugins {
20+
id 'dev.faststats.proguard-mappings-upload' version '0.1.0'
21+
}
22+
```
23+
24+
## Configuration
25+
26+
### With a custom ProGuard task
27+
28+
```kotlin
29+
mappingsUpload {
30+
authToken.set("your-auth-token")
31+
proguardTask.set(tasks.getByName("proguard"))
32+
mappingFiles.from(layout.buildDirectory.file("proguard/mapping.txt"))
33+
}
34+
```
35+
36+
Setting `proguardTask` ensures the upload task runs after ProGuard finishes. You still need to point `mappingFiles` to
37+
the actual mapping file location (matching your `printmapping` config).
38+
39+
### Android Projects
40+
41+
```kotlin
42+
mappingsUpload {
43+
authToken.set("your-auth-token")
44+
}
45+
```
46+
47+
The plugin automatically detects Android R8/ProGuard mapping file outputs when the Android Gradle Plugin is present. No
48+
additional configuration is needed.
49+
50+
### All Options
51+
52+
```kotlin
53+
mappingsUpload {
54+
// Required – API auth token. Falls back to FASTSTATS_AUTH_TOKEN env var.
55+
authToken.set("your-auth-token")
56+
57+
// Optional – API endpoint (default: https://sourcemaps.faststats.dev/api/sourcemaps)
58+
endpoint.set("https://sourcemaps.faststats.dev/api/sourcemaps")
59+
60+
// Optional – Build identifier (default: project.version)
61+
buildId.set("1.2.3")
62+
63+
// Optional – Task that produces the mapping file (adds a dependsOn)
64+
proguardTask.set(tasks.getByName("proguard"))
65+
66+
// Optional – Mapping files to upload
67+
mappingFiles.from(layout.buildDirectory.file("proguard/mapping.txt"))
68+
}
69+
```
70+
71+
## Usage
72+
73+
Run the upload task:
74+
75+
```bash
76+
./gradlew uploadProguardMappings
77+
```
78+
79+
Or chain it after your obfuscation task:
80+
81+
```bash
82+
./gradlew proguard uploadProguardMappings
83+
```
84+
85+
## CI Configuration
86+
87+
### GitHub Actions
88+
89+
```yaml
90+
name: Build & Upload Mappings
91+
92+
on:
93+
push:
94+
branches: [ main ]
95+
96+
jobs:
97+
build:
98+
runs-on: ubuntu-latest
99+
steps:
100+
- uses: actions/checkout@v4
101+
102+
- uses: actions/setup-java@v4
103+
with:
104+
distribution: temurin
105+
java-version: 17
106+
107+
- name: Build & Upload
108+
run: ./gradlew proguard uploadProguardMappings
109+
env:
110+
FASTSTATS_AUTH_TOKEN: ${{ secrets.FASTSTATS_AUTH_TOKEN }}
111+
```
112+
113+
### GitLab CI
114+
115+
```yaml
116+
build:
117+
stage: build
118+
script:
119+
- ./gradlew proguard uploadProguardMappings
120+
variables:
121+
FASTSTATS_AUTH_TOKEN: $FASTSTATS_AUTH_TOKEN
122+
```
123+
124+
## How It Works
125+
126+
1. The plugin looks for mapping files added via `mappingFiles.from(...)`, or auto-detected Android build outputs.
127+
2. If `proguardTask` is set, the upload task automatically depends on it.
128+
3. Uses `project.version` as the `buildId` by default.
129+
4. Each mapping file is split by class sections and uploaded in batches of up to 50MB, ensuring no class mapping is
130+
split across batches.
131+
132+
## Requirements
133+
134+
- Gradle 7.0+
135+
- JDK 11+
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
plugins {
2+
kotlin("jvm") version "2.3.20"
3+
id("java-gradle-plugin")
4+
id("maven-publish")
5+
}
6+
7+
group = "dev.faststats"
8+
9+
repositories {
10+
mavenCentral()
11+
google()
12+
}
13+
14+
dependencies {
15+
implementation("com.google.code.gson:gson:2.13.1")
16+
compileOnly("com.android.tools.build:gradle:8.7.3")
17+
}
18+
19+
java {
20+
sourceCompatibility = JavaVersion.VERSION_11
21+
targetCompatibility = JavaVersion.VERSION_11
22+
}
23+
24+
kotlin {
25+
jvmToolchain(11)
26+
}
27+
28+
gradlePlugin {
29+
plugins {
30+
create("proguardMappingsUpload") {
31+
id = "dev.faststats.proguard-mappings-upload"
32+
implementationClass = "dev.faststats.proguard.FastStatsProguardPlugin"
33+
displayName = "Faststats ProGuard Mapping Upload Plugin"
34+
description = "Uploads ProGuard/R8 obfuscation mapping files to the FastStats sourcemaps API"
35+
}
36+
}
37+
}
38+
39+
publishing {
40+
publications.create<MavenPublication>("maven") {
41+
// pom.url.set("https://docs.faststats.dev/serviceio")
42+
pom.scm {
43+
val repository = "FastStats-dev/sourcemaps"
44+
url.set("https://github.com/$repository/tree/main/packages/proguard-plugin")
45+
connection.set("scm:git:git://github.com/$repository.git")
46+
developerConnection.set("scm:git:ssh://github.com/$repository.git")
47+
}
48+
from(components["java"])
49+
}
50+
repositories.maven {
51+
val branch = if (version.toString().contains("-pre")) "snapshots" else "releases"
52+
url = uri("https://repo.thenextlvl.net/$branch")
53+
credentials {
54+
username = System.getenv("REPOSITORY_USER")
55+
password = System.getenv("REPOSITORY_TOKEN")
56+
}
57+
}
58+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
version=0.1.0

0 commit comments

Comments
 (0)