From c464ee2d1f0cc9b38de8b578c59094df94224bea Mon Sep 17 00:00:00 2001 From: James Newman Date: Thu, 3 Sep 2026 13:37:34 -0400 Subject: [PATCH] chore: add CODEOWNERS, dependabot config, and contributor docs --- .github/CODEOWNERS | 1 + .github/dependabot.yml | 17 ++++++++ AGENTS.md | 92 ++++++++++++++++++++++++++++++++++++++++++ CLAUDE.md | 3 ++ CONTRIBUTING.md | 56 +++++++++++++++++++++++++ SECURITY.md | 9 +++++ 6 files changed, 178 insertions(+) create mode 100644 .github/CODEOWNERS create mode 100644 .github/dependabot.yml create mode 100644 AGENTS.md create mode 100644 CLAUDE.md create mode 100644 CONTRIBUTING.md create mode 100644 SECURITY.md diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..3a87f15 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +* @mParticle/sdk-team diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..5c9e0af --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,17 @@ +version: 2 +updates: + - package-ecosystem: gradle + directory: "/" + schedule: + interval: weekly + open-pull-requests-limit: 10 + commit-message: + prefix: "chore" + + - package-ecosystem: github-actions + directory: "/" + schedule: + interval: weekly + open-pull-requests-limit: 4 + commit-message: + prefix: "chore" diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..e603a2b --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,92 @@ +# mParticle Java Server Events SDK - Agent Instructions + +Loaded into every agent session, so it holds only what you cannot get by reading the repository. +Anything a config file already states is deliberately absent: read the config, which cannot go +stale, rather than this file, which can. For the rest see `README.md` (install and public API), +`CONTRIBUTING.md` (build, test and PR conventions) and the +[Events API docs](https://docs.mparticle.com/developers/server/http/). + +## Working rules + +A Java client for mParticle's **server-side** Events API, published to Maven Central. Treat it as a +public library, not an application: keep the public API additive and deprecate rather than remove. +Do not raise the bytecode floor - `sourceCompatibility`/`targetCompatibility` are pinned in +`build.gradle`, and the JDK CI builds with is pinned in each workflow; read those rather than +assuming. Logging goes through `com.mparticle.Logger`, which is a no-op until the consumer installs +a `LogHandler` - never add `System.out` or `printStackTrace`. Never log or embed API keys, secrets +or user PII, including in tests and fixtures. + +This is not the Android SDK. Anything for mobile clients belongs in `mparticle-android-sdk`. + +## Names that collide + +Three different names refer to this one project, and the build uses all three: + +- `mparticle-java-events-sdk` is the repository. +- `server-events-sdk` is the Gradle root project (`settings.gradle`) and the Maven artifact id. +- `com.mparticle` is the group id *and* the Java package - the same package the Android SDK uses, + so a search for `com.mparticle` across a machine will surface both. + +## Commands + +- Build: `./gradlew build` +- Unit tests: `./gradlew test` +- Install locally: `./gradlew publishToMavenLocal -PVERSION=-SNAPSHOT` + +### Command traps + +1. **`publishToMavenLocal` fails without a `-SNAPSHOT` version.** `build.gradle` calls + `signAllPublications()`, which makes signing *required* for any version not ending in + `-SNAPSHOT`, and the Sign task then aborts with no signatory. `-PVERSION` overrides the `VERSION` + file for exactly this reason. CI works around it the other way, injecting + `ORG_GRADLE_PROJECT_signingInMemoryKey` into its non-SNAPSHOT smoke test. +2. **`README.md` documents the command that does not work** - its "Local Maven" section still shows + a bare `./gradlew publishToMavenLocal`. Use the form above. + +## Conventions that no config enforces + +- **The models are not generated, despite looking generated.** They carry `io.swagger` annotations + and were originally derived from a Swagger definition, but there is no generator config and no + `@Generated` marker anywhere. Edit them directly. +- **`@SerializedName` is the wire format, and a wrong one fails silently.** It must match the Events + API schema exactly; a mismatch is dropped server-side rather than erroring. Adding a field means + matching the shape already in that class: a `SERIALIZED_NAME_*` constant, the annotated field, a + fluent setter, a getter and setter, and entries in `equals`, `hashCode` and `toString`. +- **Never hand-edit `VERSION` or the README version strings.** The Release - Draft workflow rewrites + both in one pass; a new place a version lives has to be taught to that workflow or it goes stale. +- **`CHANGELOG.md` is the opposite: it must be hand-written.** Release automation only *renames* the + `## [Unreleased]` heading and never authors entries, so a change with no entry ships an empty + release note. Add yours under `## [Unreleased]`, creating that heading if it is absent. (Note this + is the reverse of `mparticle-apple-sdk`, where the changelog is generated from PR titles - do not + carry that habit across.) + +## Pull requests + +- Base off `main`. Branch name and PR title are both checked against the semantic-commit convention; + the allowed prefixes are listed in `CONTRIBUTING.md`. +- **CI is mostly not the merge gate.** Only `Unit Tests` and `Check PR for semantic title` are + required status checks. The branch-name and target-branch checks run and can go red without + blocking anything. +- **Nothing requires a review.** The `main` protection has no required-review rule and does not + enforce for admins, so a PR can merge unreviewed. CODEOWNERS (`* @mParticle/sdk-team`) requests a + reviewer but does not gate the merge. +- `main` requires signed commits and linear history, and **squash is the only enabled merge method** + - so GitHub authors and signs the commit that actually lands, and an unsigned commit on the PR + branch does not block the merge. +- **`release/` branches fail the branch-name check by design.** Release - Draft opens its + PR from that prefix, which is not in the allow-list. It is red on every release PR and is not a + gate; ignore it there. + +## Gotchas + +1. **Release - Draft is currently broken on `main`.** The 2.7.0 release consumed the + `## [Unreleased]` heading and nothing restored it, so the first `h2` is a version heading. The + pinned `keep-a-changelog-new-release` action requires that heading to be a lone link reference + and throws `Invalid changelog format` otherwise. Restoring the heading fixes it. +2. **Generated changelog compare URLs are wrong.** Release - Draft passes the bare `VERSION` as the + tag while releases are tagged `v`, so the links it writes point at a tag that does not + exist. Pre-existing; do not "fix" a single link by hand. +3. **A Dependabot `labels:` entry naming a label the repo does not have is silently dropped** *and* + suppresses the default labels, leaving its PRs unlabelled. Create the label first or omit the + key. Dependabot is otherwise exempt from the branch-name and title checks, which skip + `dependabot[bot]` outright. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..910a2d8 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,3 @@ +# CLAUDE + +@AGENTS.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..8e4e369 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,56 @@ +# Contributing + +Thanks for your interest in contributing to the mParticle Java Server Events SDK. + +## Reporting issues + +Bug reports and feature requests are welcome via [GitHub issues](https://github.com/mParticle/mparticle-java-events-sdk/issues). + +Please **do not** open an issue or pull request for a security vulnerability — see [SECURITY.md](SECURITY.md) for the disclosure process. + +## Development + +### Requirements + +- JDK 17 to build (CI uses Zulu 17). The library itself targets Java 8 bytecode. + +### Build and test + +```sh +./gradlew build # compile and assemble +./gradlew test # run unit tests +``` + +To try your changes against a local project, install the SDK to your local Maven repository. Pass a `-SNAPSHOT` version — `build.gradle` signs all publications, and signing is required for any non-SNAPSHOT version, so a bare `publishToMavenLocal` fails without mParticle's release key: + +```sh +./gradlew publishToMavenLocal -PVERSION=2.8.0-SNAPSHOT +``` + +### Project layout + +| Path | Contents | +| --- | --- | +| `src/main/java/com/mparticle/client` | `EventsApi` Retrofit interface and `HttpBasicAuth` | +| `src/main/java/com/mparticle/model` | Serializable models mirroring the Events API JSON schema | +| `src/main/java/com/mparticle` | `ApiClient`, `JSON` (Gson config), `Logger` | +| `src/test/java/com/mparticle/client` | Unit tests | + +The model classes mirror the [mParticle Events API](https://docs.mparticle.com/developers/server/http/) payload schema. When adding a field to a model, follow the existing pattern in that class: a `SERIALIZED_NAME_*` constant, a `@SerializedName` annotated field, a fluent setter, a getter, and updates to `equals`, `hashCode` and `toString`. + +## Pull requests + +PRs target `main`. CI runs these checks on every PR: + +1. **Unit tests** (`./gradlew test`) — required to merge. +2. **PR title** must follow [Conventional Commits](https://www.conventionalcommits.org/), e.g. `feat: add FireTV to PlatformEnum` or `chore(deps): bump retrofit` — required to merge. +3. **Branch name** must start with a conventional prefix — `feat/`, `fix/`, `chore/`, `docs/`, `test/`, `refactor/`, `perf/`, `style/`, `build/`, `ci/` or `revert/`. +4. **Target branch** must be `main`. + +Please add or update unit tests for any behaviour change, and make sure `./gradlew test` passes locally before opening the PR. + +Add a line describing your change under `## [Unreleased]` in [CHANGELOG.md](CHANGELOG.md), creating that heading if it is missing. Release automation renames that heading but does not write entries, so a change with no entry ships an empty release note. + +## Releases + +Releases are automated and run by maintainers — see [AGENTS.md](AGENTS.md#releases). Do not hand-edit `VERSION` or the version strings in `README.md` in a feature PR; the release workflow owns both. `CHANGELOG.md` is the exception — add your `## [Unreleased]` entry as described above. diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..4f3346a --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,9 @@ +# Security Policy + +## Reporting a vulnerability + +To avoid abuse by malicious actors please do not open GitHub issues or pull requests for any security related issue you may have spotted. + +The safest way to report any vulnerability or concern you may have is via our [dedicated submission form](https://www.rokt.com/vulnerability-disclosure/). + +For further information please refer to the [Rokt Vulnerability Disclosure Policy](https://www.rokt.com/vulnerability-disclosure/).