springboot-verification — Claude Code skill
This skill runs a Spring Boot verification loop covering builds, code analysis, tests, security scans, and diff review. Use it before a PR or deployment.
npx skills add affaan-m/ECC --skill springboot-verification -a claude-codeWhat springboot-verification does
springboot-verification runs a staged verification loop for a Spring Boot service. It builds with Maven or Gradle, checks SpotBugs, PMD, and Checkstyle, then runs unit tests plus Testcontainers integration tests. JaCoCo produces the coverage report and checks the 80%+ threshold.
The skill also runs OWASP Dependency Check, searches source files and Git history for secrets, and flags debug output, raw exception messages, and wildcard CORS. It reviews git diff and returns a readiness report with pass/fail results for the build, static analysis, tests, security checks, and changed files.
Install it when a Spring Boot repository needs one pre-PR or pre-deploy gate. Projects without Maven or Gradle, JaCoCo, configured analyzers, or Testcontainers will not support every phase.
What it helps with
- validate a Spring Boot service before opening a pull request
- build a Maven or Gradle project while skipping tests
- run SpotBugs, PMD, and Checkstyle checks
- verify JaCoCo coverage against the 80%+ threshold
- scan dependencies, source files, and Git history for security issues
Example prompts for the agent
- Run the full verification loop for this Spring Boot project and prepare a VERIFICATION REPORT.
- Run `mvn -T 4 test`, JaCoCo, SpotBugs, and the OWASP check, then list every issue.
- Review `git diff` and tell me whether the project is ready for deployment.
How to install springboot-verification
1Skills CLI (Vercel)
npx skills add affaan-m/ECC --skill springboot-verification -a claude-code2Manually: put the files in place
~/.claude/skills/springboot-verification/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/springboot-verification/
1Skills CLI (Vercel)
npx skills add affaan-m/ECC --skill springboot-verification -a codex2Manually: put the files in place
.agents/skills/springboot-verification/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add affaan-m/ECC --skill springboot-verification -a cursor2Manually: put the files in place
.cursor/skills/springboot-verification/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install affaan-m/ECC springboot-verification2Manually: put the files in place
.github/skills/springboot-verification/SKILL.md1Skills CLI (Vercel)
npx skills add affaan-m/ECC --skill springboot-verification -a gemini-cli2Platform CLI
gemini skills install https://github.com/affaan-m/ECC --path skills/springboot-verificationManually: put the files in place
.devin/skills/springboot-verification/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add affaan-m/ECC --skill springboot-verification -a opencodeClaude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
From the same set146
The whole set →Similar
Questions about springboot-verification
How do I install springboot-verification in Claude Code?
Run npx skills add affaan-m/ECC --skill springboot-verification -a claude-code. The skill file is placed at ~/.claude/skills/springboot-verification/SKILL.md.
What does springboot-verification do?
It checks the build, static analysis, unit and integration tests, JaCoCo coverage, dependencies, secrets, and git diff, then produces a pass/fail readiness report.
Which platforms support springboot-verification?
The skill supports Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, and OpenCode. Its verification phases use Maven or Gradle and Testcontainers.
Source text
SKILL.md · MIT
---
name: springboot-verification
description: Run the full Spring Boot verification loop — Maven or Gradle build, SpotBugs, PMD, and Checkstyle static analysis, unit and Testcontainers integration tests with JaCoCo coverage, OWASP dependency and secret scans, and diff review — producing a pass/fail readiness report. Use when preparing a Spring Boot pull request, validating coverage thresholds, or running pre-deploy verification.
metadata:
origin: ECC
---
# Spring Boot Verification Loop
Run before PRs, after major changes, and pre-deploy.
## When to Activate
- Before opening a pull request for a Spring Boot service
- After major refactoring or dependency upgrades
- Pre-deployment verification for staging or production
- Running full build → lint → test → security scan pipeline
- Validating test coverage meets thresholds
## Phase 1: Build
```bash
mvn -T 4 clean verify -DskipTests
# or
./gradlew clean assemble -x test
```
If build fails, stop and fix.
## Phase 2: Static Analysis
Maven (common plugins):
```bash
mvn -T 4 spotbugs:check pmd:check checkstyle:check
```
Gradle (if configured):
```bash
./gradlew checkstyleMain pmdMain spotbugsMain
```
## Phase 3: Tests + Coverage
```bash
mvn -T 4 test
mvn jacoco:report # verify 80%+ coverage
# or
./gradlew test jacocoTestReport
```
Report:
- Total tests, passed/failed
- Coverage % (lines/branches)
### Unit Tests
Test service logic in isolation with mocked dependencies:
```java
@ExtendWith(MockitoExtension.class)
class UserServiceTest {
@Mock private UserRepository userRepository;
@InjectMocks private UserService userService;
@Test
void createUser_validInput_returnsUser() {
var dto = new CreateUserDto("Alice", "[email protected]");
var expected = new User(1L, "Alice", "[email protected]");
when(userRepository.save(any(User.class))).thenReturn(expected);
var result = userService.create(dto);
assertThat(result.name()).isEqualTo("Alice");
verify(userRepository).save(any(User.class));
}
@Test
void createUser_duplicateEmail_throwsException() {
var dto = new CreateUserDto("Alice", "[email protected]");
when(userRepository.existsByEmail(dto.email())).thenReturn(true);
assertThatThrownBy(() -> userService.create(dto))
.isInstanceOf(DuplicateEmailException.class);
}
}
```
### Integration Tests with Testcontainers
Test against a real database instead of H2:
```java
@SpringBootTest
@Testcontainers
class UserRepositoryIntegrationTest {
@Container
static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:16-alpine")
.withDatabaseName("testdb");
@DynamicPropertySource
static void configureProperties(DynamicPropertyRegistry registry) {
registry.add("spring.datasource.url", postgres::getJdbcUrl);
registry.add("spring.datasource.username", postgres::getUsername);
registry.add("spring.datasource.password", postgres::getPassword);
}
@Autowired private UserRepository userRepository;
@Test
void findByEmail_existingUser_returnsUser() {
userRepository.save(new User("Alice", "[email protected]"));
var found = userRepository.findByEmail("[email protected]");
assertThat(found).isPresent();
assertThat(found.get().getName()).isEqualTo("Alice");
}
}
```
### API Tests with MockMvc
Test controller layer with full Spring context:
```java
@WebMvcTest(UserController.class)
class UserControllerTest {
@Autowired private MockMvc mockMvc;
@MockBean private UserService userService;
@Test
void createUser_validInput_returns201() throws Exception {
var user = new UserDto(1L, "Alice", "[email protected]");
when(userService.create(any())).thenReturn(user);
mockMvc.perform(post("/api/users")
.contentType(MediaType.APPLICATION_JSON)
.content("""
{"name": "Alice", "email": "[email protected]"}
"""))
.andExpect(status().isCreated())
.andExpect(jsonPath("$.name").value("Alice"));
}
@Test
void createUser_invalidEmail_returns400() throws Exception {
mockMvc.perform(post("/api/users")
.contentType(MediaType.APPLICATION_JSON)
.content("""
{"name": "Alice", "email": "not-an-email"}
"""))
.andExpect(status().isBadRequest());
}
}
```
## Phase 4: Security Scan
```bash
# Dependency CVEs
mvn org.owasp:dependency-check-maven:check
# or
./gradlew dependencyCheckAnalyze
# Secrets in source
grep -rn "password\s*=\s*\"" src/ --include="*.java" --include="*.yml" --include="*.properties"
grep -rn "sk-\|api_key\|secret" src/ --include="*.java" --include="*.yml"
# Secrets (git history)
git secrets --scan # if configured
```
### Common Security Findings
```
# Check for System.out.println (use logger instead)
grep -rn "System\.out\.print" src/main/ --include="*.java"
# Check for raw exception messages in responses
grep -rn "e\.getMessage()" src/main/ --include="*.java"
# Check for wildcard CORS
grep -rn "allowedOrigins.*\*" src/main/ --include="*.java"
```
## Phase 5: Lint/Format (optional gate)
```bash
mvn spotless:apply # if using Spotless plugin
./gradlew spotlessApply
```
## Phase 6: Diff Review
```bash
git diff --stat
git diff
```
Checklist:
- No debugging logs left (`System.out`, `log.debug` without guards)
- Meaningful errors and HTTP statuses
- Transactions and validation present where needed
- Config changes documented
## Output Template
```
VERIFICATION REPORT
===================
Build: [PASS/FAIL]
Static: [PASS/FAIL] (spotbugs/pmd/checkstyle)
Tests: [PASS/FAIL] (X/Y passed, Z% coverage)
Security: [PASS/FAIL] (CVE findings: N)
Diff: [X files changed]
Overall: [READY / NOT READY]
Issues to Fix:
1. ...
2. ...
```
## Continuous Mode
- Re-run phases on significant changes or every 30–60 minutes in long sessions
- Keep a short loop: `mvn -T 4 test` + spotbugs for quick feedback
**Remember**: Fast feedback beats late surprises. Keep the gate strict—treat warnings as defects in production systems.
© affaan-m · MIT · affaan-m/ECC