Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
9516d1c
chore: remove junie files
afranken Feb 21, 2026
e492c54
feat: let Claude generate skills
afranken Feb 21, 2026
3b23edc
feat: let Claude generate generic skills
afranken Feb 21, 2026
73a870f
feat: let Claude generate specific "AGENTS.md"
afranken Feb 21, 2026
3ff26ba
feat: let Claude refactor README.md
afranken Feb 21, 2026
c21c570
feat: let Claude condense AGENTS.md
afranken Feb 22, 2026
080ff03
feat: expand README.md with "Architecture & Development" section
afranken Feb 22, 2026
9482c4e
feat: improve README usability
afranken Feb 22, 2026
eea69c6
chore: changelog for 5.0.0
afranken Feb 23, 2026
5eec9fd
feat: add security policy
afranken Feb 23, 2026
79c94b0
feat: add quick start and troubleshooting sections
afranken Feb 23, 2026
bf00a7b
feat: DO/DON'T lists, clarifications for agents
afranken Feb 23, 2026
dd6c8f6
feat: sub-module AGENTS.md guardrails
afranken Feb 23, 2026
dad5602
feat: version compatibility, migrations, architecture diagram
afranken Feb 23, 2026
c94e4d2
feat: add CODEOWNERS
afranken Feb 23, 2026
d68f6e1
feat: enhance CONTRIBUTING with clarifications and how-tos
afranken Feb 23, 2026
74897a9
feat: add Github issue forms to help triage issues
afranken Feb 23, 2026
832c454
feat: add Github issue forms to help triage issues
afranken Feb 23, 2026
a9d78a1
feat: update tasks in PR template
afranken Feb 23, 2026
fb37564
feat: add version and branch strategy
afranken Feb 23, 2026
8b7751f
feat: add performance and resources section
afranken Feb 23, 2026
935f85f
feat: let users know to prefer testcontainers over TestNG / JUnit5
afranken Feb 23, 2026
3487e2a
feat: add troubleshooting section to SKILL.md
afranken Feb 23, 2026
b1d0aee
feat: clarify verification process for AWS S3 XML output in AGENTS.md
afranken Feb 23, 2026
5ccae8b
feat: update badge from Java to JVM in README.md
afranken Feb 23, 2026
5e21dc6
feat: mark test classes as internal in AGENTS.md
afranken Feb 23, 2026
b69e62b
feat: update testing guidelines in AGENTS.md
afranken Feb 23, 2026
9a9d8b3
feat: add guideline to name 'it' parameter in nested lambdas
afranken Feb 23, 2026
4f19744
feat: add error handling guidelines for S3 exceptions in AGENTS.md
afranken Feb 23, 2026
b1de2c9
feat: update S3 exception handling to use S3Exception constants
afranken Feb 23, 2026
04593c3
feat: update configuration section with default values and binding
afranken Feb 23, 2026
65e12aa
feat: instructions for unique bucket names and error handling guidelines
afranken Feb 23, 2026
8c4bb79
feat: update ETag handling instructions
afranken Feb 23, 2026
372cb58
feat: update test guidelines for unique bucket names and visibility
afranken Feb 23, 2026
bc2a5f2
feat: Add security and issue templates to the documentation skill
afranken Feb 23, 2026
29d656c
feat: add detailed structure and component descriptions
afranken Feb 23, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions .claude/skills/document/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
---
name: document
description: Generate or update project documentation. Use when asked to document code, create docs, or explain features.
---

# Documentation Skill — S3Mock

Generate and maintain documentation for the S3Mock project.

## When to Use

- Creating or updating README.md
- Updating the CHANGELOG.md for new features/fixes
- Updating the S3 operations support table
- Documenting new configuration options
- Updating AGENTS.md files when architecture changes

## Pre-Flight Checklist

- [ ] Read existing `AGENTS.md` for project conventions and structure
- [ ] Review the documentation being updated for current style and tone
- [ ] Identify target audience (end users for README, agents for AGENTS.md, contributors for CONTRIBUTING.md)

## S3Mock Documentation Structure

| File | Audience | Purpose |
|------|----------|---------|
| `README.md` | End users & contributors | Usage, configuration, quick start |
| `CHANGELOG.md` | End users | Version history, breaking changes, migration notes |
| `AGENTS.md` (root) | AI agents & contributors | Architecture, code style, DO/DON'T guardrails |
| `server/AGENTS.md` | AI agents | Server module implementation details |
| `integration-tests/AGENTS.md` | AI agents | Integration test patterns and helpers |
| `testsupport/AGENTS.md` | AI agents | Test framework integration details |
| `.github/CONTRIBUTING.md` | Contributors | How to contribute, dev setup, code reviews |
| `.github/SECURITY.md` | Security researchers | Vulnerability reporting, supported versions |
| `.github/CODEOWNERS` | GitHub | Automatic PR review assignment |
| `.github/ISSUE_TEMPLATE/*.yml` | Users & contributors | Structured bug reports and feature requests |

## Documentation Tasks

### When a New S3 Operation is Implemented
1. Update the **operations table** in `README.md` — change `:x:` to `:white_check_mark:` for the operation
2. Add a CHANGELOG entry under the current version section in `CHANGELOG.md`
3. Update `server/AGENTS.md` if the implementation introduces new patterns

### When Configuration Changes
1. Update the **Configuration table** in `README.md`
2. Update the **Configuration section** in `AGENTS.md`
3. Add a CHANGELOG entry

### When Architecture Changes
1. Update the relevant module's `AGENTS.md`
2. Update the root `AGENTS.md` if the change affects the overall structure
3. Add a CHANGELOG entry for breaking changes

### CHANGELOG Format
Follow the existing pattern in `CHANGELOG.md`:
- Group changes under the current version heading (e.g., `## 5.0.0`)
- Use clear, user-facing language
- Note breaking changes prominently
- Reference related GitHub issues or PRs

## Writing Style

- **Concise**: Short sentences, active voice
- **Code examples**: Include runnable examples where possible (Kotlin for API, shell for CLI)
- **Links**: Reference AWS S3 API docs for operations, link to source files for implementations
- **Consistent**: Match existing formatting — Markdown headings, table alignment, badge style

## Post-Flight Checklist

- [ ] Technical accuracy verified against source code
- [ ] Code examples compile/run correctly
- [ ] Links are valid (internal file paths, external URLs)
- [ ] Consistent style with surrounding documentation
- [ ] Markdown renders correctly (tables, code blocks, badges)
- [ ] No outdated version numbers or deprecated references

## Output

Provide documentation ready to integrate into the appropriate project files, matching existing conventions.
80 changes: 80 additions & 0 deletions .claude/skills/implement/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
---
name: implement
description: Implement features, fix bugs, or refactor code. Use when asked to add functionality, modify code, or improve structure.
---

# Implementation Skill — S3Mock

Implement features and fix bugs in the S3Mock project (Kotlin 2.3, Spring Boot 4.0.x, Maven).

## When to Use

- Adding new S3 API operations
- Fixing bugs in existing operations
- Refactoring server, service, or store layers
- Updating DTOs or XML serialization

## Pre-Flight Checklist

- [ ] Read the root `AGENTS.md` — especially the DO/DON'T section
- [ ] Read the module-specific `AGENTS.md` (`server/AGENTS.md`, etc.)
- [ ] Check `CHANGELOG.md` for planned changes or deprecations
- [ ] Identify which S3 API operation is being implemented (check [AWS docs](https://docs.aws.amazon.com/AmazonS3/latest/API/Welcome.html))
- [ ] Review existing similar implementations in the codebase

## Implementation Flow for New S3 Operations

Follow the **DTO → Store → Service → Controller** layered architecture:

### 1. DTO (`server/src/main/kotlin/com/adobe/testing/s3mock/dto/`)
- Create request/response data classes with Jackson XML annotations
- Use `@JacksonXmlRootElement(localName = "...")` matching the AWS API element name exactly
- Use `@JacksonXmlProperty(localName = "...")` for properties
- Use `@JacksonXmlElementWrapper(useWrapping = false)` for collections
- Verify naming against [AWS S3 API docs](https://docs.aws.amazon.com/AmazonS3/latest/API/Welcome.html)

### 2. Store (`server/src/main/kotlin/com/adobe/testing/s3mock/store/`)
- Add filesystem operations to `BucketStore` or `ObjectStore`
- Follow existing patterns for metadata JSON and binary data storage
- Handle file I/O with proper error handling

### 3. Service (`server/src/main/kotlin/com/adobe/testing/s3mock/service/`)
- Add business logic, validation, and store coordination
- Throw S3 exceptions (`NoSuchBucketException`, `NoSuchKeyException`, etc.)
- Use constructor injection for dependencies

### 4. Controller (`server/src/main/kotlin/com/adobe/testing/s3mock/controller/`)
- Add HTTP endpoint mapping (`@GetMapping`, `@PutMapping`, etc.)
- Controllers only map HTTP — delegate all logic to services
- Return proper HTTP status codes and headers (ETag, Content-Type, etc.)

## Code Standards

- **Language**: Kotlin 2.3, JVM target 17
- **DI**: Constructor injection only — never `@Autowired` or field injection
- **DTOs**: Data classes with `val` properties
- **Null safety**: Use `?`, `?.`, `?:` — avoid `!!`
- **Functions**: Expression bodies for simple functions
- **Dependencies**: Prefer Kotlin stdlib over third-party libraries
- **Versions**: All dependency versions in root `pom.xml` only

## Post-Flight Checklist

- [ ] Run `./mvnw ktlint:format` to fix code style
- [ ] Run `./mvnw clean install` to verify build
- [ ] Verify no checkstyle violations
- [ ] Add/update unit tests (`*Test.kt`) for new service/store logic
- [ ] Add/update integration tests (`*IT.kt`) for new endpoints
- [ ] Update `CHANGELOG.md` under the current version section
- [ ] Update the operations table in `README.md` if a new S3 operation was added

## Troubleshooting

- **Build fails**: Check Java version (`java -version` — needs 25), run `./mvnw ktlint:format`
- **Checkstyle fails**: Review rules in `etc/checkstyle.xml` — common issues are import ordering and missing Javadoc
- **Tests fail after changes**: Ensure XML serialization matches AWS API exactly — compare element names against [AWS docs](https://docs.aws.amazon.com/AmazonS3/latest/API/Welcome.html)
- **Docker build fails**: Try `./mvnw clean install -DskipDocker` first to isolate the issue

## Output

Provide clean, well-structured Kotlin code following the layered architecture and project conventions defined in AGENTS.md.
133 changes: 133 additions & 0 deletions .claude/skills/test/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
---
name: test
description: Write, update, or fix tests. Use when asked to test code, create test cases, or debug failing tests.
---

# Test Skill — S3Mock

Create and maintain tests for S3Mock (JUnit 5, Mockito, AssertJ, AWS SDK v2).

## When to Use

- Writing new unit or integration tests
- Fixing failing tests
- Adding test coverage for S3 operations
- Creating test fixtures or helpers

## Pre-Flight Checklist

- [ ] Read `AGENTS.md` — especially DO/DON'T and Testing sections
- [ ] Identify test type needed (unit vs. integration — see below)
- [ ] Review existing test patterns in the target module
- [ ] For integration tests, review `S3TestBase` for available helpers

## Test Types in S3Mock

### Unit Tests (`*Test.kt`)
- **Location**: `server/src/test/kotlin/com/adobe/testing/s3mock/`
- **Framework**: JUnit 5 + `@SpringBootTest` with `@MockitoBean` for mocking
- **Assertions**: AssertJ (`assertThat(...)`)
- **Purpose**: Test services and stores in isolation with Spring context and mocked dependencies
- **Pattern**:
```kotlin
@SpringBootTest(classes = [ServiceConfiguration::class], webEnvironment = SpringBootTest.WebEnvironment.NONE)
@MockitoBean(types = [BucketService::class, MultipartService::class, MultipartStore::class])
internal class ObjectServiceTest : ServiceTestBase() {
@Autowired
private lateinit var iut: ObjectService

@Test
fun `should delete object`() {
val bucketName = "bucket"
val key = "key"
givenBucketWithContents(bucketName, "", listOf(givenS3Object(key)))

iut.deleteObject(bucketName, key)

assertThat(iut.getObject(bucketName, key)).isNull()
}
}
```

### Integration Tests (`*IT.kt`)
- **Location**: `integration-tests/src/test/kotlin/com/adobe/testing/s3mock/its/`
- **Base class**: Extend `S3TestBase` for access to pre-configured `s3Client` (AWS SDK v2)
- **Assertions**: AssertJ
- **Purpose**: Test S3Mock end-to-end with real AWS SDK clients against the Docker container
- **Pattern**:
```kotlin
internal class MyFeatureIT : S3TestBase() {
@Test
fun `should perform operation`(testInfo: TestInfo) {
// Arrange — always use unique bucket names
val bucketName = givenBucket(testInfo)

// Act
s3Client.putObject(
PutObjectRequest.builder().bucket(bucketName).key("key").build(),
RequestBody.fromString("content")
)

// Assert
val response = s3Client.getObject(
GetObjectRequest.builder().bucket(bucketName).key("key").build()
)
assertThat(response.readAllBytes().decodeToString()).isEqualTo("content")
}
}
```

## Test Standards

- **Naming**: Use backtick names with descriptive sentences: `` fun `should create bucket successfully`() ``
- Legacy `testSomething` camelCase naming exists in older tests — refactor to backtick style when touching those tests
- **Independence**: Each test creates its own resources — never share state between tests
- **Bucket names**: Use `givenBucket(testInfo)` from `S3TestBase` in integration tests for unique names
- **Arrange-Act-Assert**: Follow this pattern consistently
- **Both paths**: Test success cases AND error/exception cases
- **Error assertions**: Use `assertThatThrownBy { ... }.isInstanceOf(AwsServiceException::class.java)` (AssertJ), not `assertThrows`
- **SDK version**: Use AWS SDK v2 (`s3Client`) only — SDK v1 has been removed
- **No JUnit 4**: Use JUnit 5 exclusively (`@Test` from `org.junit.jupiter.api`)
- **Visibility**: Mark test classes as `internal`
- **No MockitoExtension**: Use `@SpringBootTest` with `@MockitoBean` for mocking — never `@ExtendWith(MockitoExtension::class)`
- **Mocking**: Use `@MockitoBean` (class-level `types` or field-level) instead of `@Mock` / `@InjectMocks`
- **Injection**: Use `@Autowired` for the class under test in Spring Boot tests

## Running Tests

```bash
# Unit tests (server module)
./mvnw test -pl server

# All integration tests
./mvnw verify -pl integration-tests

# Specific integration test class
./mvnw verify -pl integration-tests -Dit.test=BucketIT

# Specific test method
./mvnw verify -pl integration-tests -Dit.test=BucketIT#shouldCreateBucket

# Skip Docker (for unit tests only)
./mvnw test -pl server -DskipDocker
```

## Post-Flight Checklist

- [ ] Tests pass locally (`./mvnw test` or `./mvnw verify`)
- [ ] Tests are independent (can run in any order)
- [ ] Both success and failure cases covered
- [ ] Assertions are specific (not just `isNotNull()`)
- [ ] No hardcoded bucket names (use UUID)
- [ ] Code style passes (`./mvnw ktlint:format`)

## Troubleshooting Failing Tests

- **Docker not running**: Integration tests require Docker — start Docker Desktop
- **Port conflict**: Ports 9090/9191 may be in use — check with `lsof -i :9090`
- **Flaky test**: Ensure test independence — check for shared state or ordering dependencies
- **Compilation error**: Run `./mvnw clean install -DskipDocker -DskipTests` first

## Output

Provide complete, runnable Kotlin tests following S3Mock conventions and the Arrange-Act-Assert pattern.
20 changes: 20 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Default owner for everything in the repo
* @afranken

# Core server implementation
/server/ @afranken

# Integration tests
/integration-tests/ @afranken

# Test support modules
/testsupport/ @afranken

# Docker configuration
/docker/ @afranken

# CI/CD and GitHub configuration
/.github/ @afranken

# Build configuration
/build-config/ @afranken
61 changes: 58 additions & 3 deletions .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,66 @@ This project adheres to the Adobe [code of conduct](../CODE_OF_CONDUCT.md). By p

All third-party contributions to this project must be accompanied by a signed contributor license. This gives Adobe permission to redistribute your contributions as part of the project. Sign our [CLA](http://adobe.github.io/cla.html). You only need to submit an Adobe CLA one time, so if you have submitted one previously, you are good to go!

## Development Setup

**Prerequisites:**
- Java 25 (compile version; targets JVM 17)
- Maven 3.9+ (use the included `./mvnw` wrapper)
- Docker (for Docker build and integration tests)

**Build and verify:**
```shell
# Full build with Docker
./mvnw clean install

# Skip Docker (faster, for unit tests only)
./mvnw clean install -DskipDocker

# Run integration tests
./mvnw verify -pl integration-tests

# Format Kotlin code
./mvnw ktlint:format
```

## Architecture

S3Mock follows a **Controller - Service - Store** layered architecture. For detailed architecture documentation, code style guidelines, and project conventions, see the [AGENTS.md](../AGENTS.md) in the project root.

Module-specific documentation:
- [Server Module](../server/AGENTS.md) - core implementation
- [Integration Tests](../integration-tests/AGENTS.md) - test patterns
- [Test Support](../testsupport/AGENTS.md) - framework integrations

## Code Style

- **Kotlin**: Enforced by ktlint - run `./mvnw ktlint:format` before submitting
- **XML/Java**: Enforced by Checkstyle - configuration in [`etc/checkstyle.xml`](../etc/checkstyle.xml)
- **Key conventions**: Constructor injection, data classes for DTOs, backtick test names, `val` over `var`
- See the DO / DON'T section in [AGENTS.md](../AGENTS.md) for the full list

## Code Reviews

All submissions should come in the form of pull requests and need to be reviewed by project committers. Read [GitHub's pull request documentation](https://help.github.com/articles/about-pull-requests/) for more information on sending pull requests.

All submissions must include unit tests for any new functionality or bug fixes. If you are adding a new feature, please include a test that demonstrates the feature.
S3Mock uses Unit tests for function coverage, Spring Boot tests for component coverage, and integration tests against the Docker container artefact for end-to-end coverage. Please ensure that your code is covered by at least one of these test types.
## Testing

All submissions must include tests for any new functionality or bug fixes.

S3Mock uses three test levels:
1. **Unit tests** (`*Test.kt`) - Spring Boot tests with `@MockitoBean` for mocking, in `server/src/test/`
2. **Spring Boot tests** - component-level coverage with Spring context
3. **Integration tests** (`*IT.kt`) - end-to-end tests against the Docker container using real AWS SDK v2 clients, in `integration-tests/src/test/`

Please ensure that your code is covered by at least one of these test types.

## Submitting Changes

1. Ensure all CI gates pass (build, tests, ktlint, checkstyle, Docker)
2. Update [CHANGELOG.md](../CHANGELOG.md) under the current version section for user-facing changes
3. Update documentation if applicable (README.md, AGENTS.md)
4. Follow the [pull request template](PULL_REQUEST_TEMPLATE.md) when submitting

## Security

Lastly, please follow the [pull request template](PULL_REQUEST_TEMPLATE.md) when submitting a pull request!
To report security vulnerabilities, see the [Security Policy](SECURITY.md).
Empty file removed .github/ISSUE_TEMPLATE.md
Empty file.
Loading
Loading