# Contributing to tauri-plugin-ad2mob
Thanks for your interest in improving **tauri-plugin-ad2mob**! This document
explains how the project is organized, how to verify your changes locally and
what is expected from a pull request.
## Project layout
```
├── src/ Rust core (commands, state machine, mobile/desktop bridges)
├── android/ Kotlin implementation (Google Mobile Ads SDK + UMP)
├── ios/ Swift implementation (GoogleMobileAds SPM + UMP)
├── guest-js/ TypeScript bindings (published to npm)
├── permissions/ Tauri ACL permissions (default + autogenerated)
├── build.rs ACL command registry — the canonical command surface
├── examples/admob-demo/ Complete demo app (button grid + event log)
├── scripts/ Verification scripts (see below)
└── tests/ Rust integration tests + TypeScript tests
```
## The cross-language contract
The plugin speaks one contract in four languages. `build.rs` declares the
canonical command surface; Kotlin implements it on Android, Swift on iOS,
`guest-js` exposes it to the webview, and the ACL permissions must match
exactly.
**Never edit one side without the others.** The verification pipeline catches
drift:
```bash
node scripts/check-contract.mjs
```
If you add a command or an event, update **all** of: `build.rs`, `src/lib.rs`
(`generate_handler!`), `src/commands.rs`, `src/mobile.rs`/`src/desktop.rs`,
`AdmobPlugin.kt`, `AdmobPlugin.swift`, `guest-js/index.ts`, `guest-js/types.ts`
and re-generate the ACL (`permissions/`).
## Local development
Requirements: Rust 1.77+ (with `rustfmt` and `clippy`), Node 18+ or Bun,
Android Studio/SDK and Xcode for the native sides.
```bash
bun install # or npm install
bash scripts/verify.sh # the full pipeline (see below)
```
### The one-command verification
`scripts/verify.sh` is the single entry point used by CI and before every
release:
| Rust | `cargo fmt --check`, `cargo check`, `cargo clippy -D warnings`, `cargo test` |
| TypeScript | `bun run build`, `bun run typecheck`, `bun run test` |
| Contract | `scripts/check-contract.mjs` — cross-language parity |
| Publish | `scripts/check-publish.mjs` + `cargo publish --dry-run` |
Extra flags: `--quick` (skip the publish dry-run), `--with-example`
(also `cargo check` the demo app).
### Android / iOS
The native sides compile inside a real Tauri app. On a fresh checkout, generate
the platform project first:
```bash
cd examples/admob-demo/src-tauri
cargo tauri android init
cd ../../..
node scripts/prepare-demo-android.mjs
cd examples/admob-demo/src-tauri
cargo tauri android build --debug --target aarch64
cargo tauri ios init # macOS only
cargo tauri ios build --target aarch64-apple-ios-sim
```
`prepare-demo-android.mjs` keeps the generated demo compatible with the current
AdMob Android SDK: Kotlin Gradle Plugin 2.1.0 and Google's official test App ID.
The generated `gen/android` project is local build output and should not be
treated as plugin source.
Android JVM unit tests (pure-Kotlin mappers):
```bash
cd examples/admob-demo/src-tauri/gen/android
./gradlew :tauri-plugin-ad2mob:testDebugUnitTest
```
## Pull requests
1. Fork the repository and create a feature branch from `main`.
2. Run `bash scripts/verify.sh` — CI runs the same pipeline and it must be
green before review.
3. Update documentation when you change behavior: `README.md` (English) and
`CHANGELOG.md` (Keep a Changelog format).
4. Keep the diff focused; one logical change per PR.
5. Sign off that you accept the **dual MIT / Apache-2.0 licensing**: by
contributing you agree your work is released under both licenses.
## Reporting bugs
Open a GitHub issue with the bug-report template. Include: plugin version,
Tauri version, platform + OS version, device/emulator, and a minimal
reproduction. Test-mode reproductions (`isTesting: true`) are strongly
preferred.
## Code of conduct
Be respectful and constructive. Maintainers may remove comments or block
accounts that behave abusively.