Skip to content

Commit d3dab42

Browse files
authored
feat(ci): add SpotBugs and PMD static analysis (#369)
* feat(static-analysis): add SpotBugs and PMD code quality tools - Add SpotBugs 4.8.6.6 with FindSecBugs plugin to parent pom.xml - Add PMD 7.9.0 with custom ruleset to parent pom.xml - Create spotbugs/exclude-filter.xml for QQQ-specific exclusions - Create pmd/ruleset.xml tuned for QQQ conventions - Update CircleCI config to use qqq-orb static_analysis workflow - Report-only by default; use -Dspotbugs.failOnError=true to fail * ci: run static analysis in parallel with tests * feat(ci): add SpotBugs and PMD static analysis to CI pipeline Run static_analysis job in parallel with tests on feature branches.
1 parent f3ee422 commit d3dab42

File tree

7 files changed

+457
-93
lines changed

7 files changed

+457
-93
lines changed

.circleci/config.yml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
version: 2.1
44

55
orbs:
6-
qqq-orb: kingsrook/qqq-orb@0.5.0
6+
qqq-orb: kingsrook/qqq-orb@0.6.0
77

88
workflows:
99

@@ -16,6 +16,14 @@ workflows:
1616
ignore: /(develop|main|release/.*|hotfix/.*|integration.*)/
1717
tags:
1818
only: []
19+
# Static analysis runs in parallel with tests
20+
- qqq-orb/static_analysis:
21+
context: [qqq-maven-registry-credentials]
22+
filters:
23+
branches:
24+
ignore: /(develop|main|release/.*|hotfix/.*|integration.*)/
25+
tags:
26+
only: []
1927

2028
publish_snapshot:
2129
jobs:
@@ -26,6 +34,12 @@ workflows:
2634
branches:
2735
only:
2836
- develop
37+
- qqq-orb/static_analysis:
38+
context: [qqq-maven-registry-credentials]
39+
filters:
40+
branches:
41+
only:
42+
- develop
2943

3044
publish_feature:
3145
jobs:

docs/PLAN-spotbugs-pmd.md

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# PLAN: SpotBugs + PMD Code Quality Integration
2+
3+
## Goal
4+
5+
Add SpotBugs and PMD static analysis to the QQQ build for local execution and optional CI/CD.
6+
7+
## Approach
8+
9+
1. **Maven Integration** - Add plugins to parent pom.xml with sensible defaults
10+
2. **Non-blocking by default** - Warnings reported but don't fail builds initially
11+
3. **Optional CI workflow** - Manual trigger GitHub Action for on-demand analysis
12+
13+
## Configuration Strategy
14+
15+
| Tool | Phase | Default | Override Property |
16+
|------|-------|---------|-------------------|
17+
| SpotBugs | verify | report only | `-Dspotbugs.failOnError=true` |
18+
| PMD | verify | report only | `-Dpmd.failOnViolation=true` |
19+
20+
## Files to Create/Modify
21+
22+
- `pom.xml` - Add plugin configurations
23+
- `spotbugs/exclude-filter.xml` - Exclusions for known false positives
24+
- `pmd/ruleset.xml` - Custom ruleset tuned for QQQ
25+
- `.github/workflows/static-analysis.yml` - Optional CI workflow
26+
27+
## Local Commands
28+
29+
```bash
30+
# Run SpotBugs only
31+
mvn spotbugs:check
32+
33+
# Run PMD only
34+
mvn pmd:check
35+
36+
# Run both during verify
37+
mvn verify
38+
39+
# Fail on issues (CI mode)
40+
mvn verify -Dspotbugs.failOnError=true -Dpmd.failOnViolation=true
41+
```
42+
43+
## Plugin Versions
44+
45+
- SpotBugs Maven Plugin: 4.8.6.6
46+
- PMD Maven Plugin: 3.26.0
47+
- PMD: 7.9.0
48+
49+
## Exclusion Strategy
50+
51+
SpotBugs exclusions for QQQ patterns:
52+
- `EI_EXPOSE_REP` / `EI_EXPOSE_REP2` - Fluent builders intentionally expose mutable state
53+
- `NP_NULL_ON_SOME_PATH` - QContext patterns with known null handling
54+
55+
PMD suppressions:
56+
- `AvoidFieldNameMatchingMethodName` - QQQ getter/setter pattern
57+
- `TooManyMethods` - MetaData classes are large by design

docs/SESSION.md

Lines changed: 59 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,79 @@
11
# Session State
22

3-
**Last Updated:** 2026-01-09
4-
**Branch:** `develop`
5-
**Last Task:** PR Merge and Daily Build Log
3+
**Last Updated:** 2026-01-14
4+
**Branch:** `feature/implement-spotbugs`
5+
**Last Task:** SpotBugs + PMD Static Analysis Implementation
66

77
## Current Context
88

9-
Completed merging 5 PRs into develop and created a Daily Build Log discussion on GitHub to document the changes.
9+
Implemented SpotBugs and PMD static analysis for QQQ with both local Maven execution and CircleCI orb support.
1010

1111
## Completed This Session
1212

13-
1. **PR Merge Plan** - Created `docs/PLAN-pr-merge-order.md` with optimal merge strategy
13+
1. **Maven Plugin Configuration** - Added SpotBugs and PMD plugins to parent pom.xml
14+
- SpotBugs 4.8.6.6 with FindSecBugs plugin
15+
- PMD 7.9.0 with custom ruleset
16+
- Report-only by default (`-Dspotbugs.failOnError=true` / `-Dpmd.failOnViolation=true` to fail)
1417

15-
2. **Merged 5 PRs to develop** (in order):
16-
- PR #321 - fix(personalization): child-table meta-data (`b2837708`)
17-
- PR #320 - fix(bulkEditWithFile): avoid huge query results (`dea9c2a4`)
18-
- PR #335 - fix(rdbms): PostgreSQL timestamp/identifier fixes (`886f86f1`)
19-
- PR #337 - feat(auth): OAuth2 customizer support (`53d6a5bc`)
20-
- PR #280 - feat: virtual fields and alternative sections (`a9eb8d28`)
18+
2. **Configuration Files Created**
19+
- `spotbugs/exclude-filter.xml` - Exclusions for QQQ patterns (fluent builders, singletons)
20+
- `pmd/ruleset.xml` - Custom ruleset tuned for QQQ conventions
2121

22-
3. **Post-Merge Validation**
23-
- qqq-backend-core: 147 tests passed
24-
- qqq-backend-module-postgres: 42 tests passed
25-
- Checkstyle: 0 violations
22+
3. **QQQ-Orb Enhancements** (in `/Users/james.maes/Git.Local/QRun-IO/qqq-orb/`)
23+
- `src/commands/mvn_spotbugs.yml` - SpotBugs command
24+
- `src/commands/mvn_pmd.yml` - PMD command
25+
- `src/commands/collect_static_analysis_reports.yml` - Report collector
26+
- `src/jobs/static_analysis.yml` - Combined analysis job
27+
- `src/scripts/mvn_spotbugs.sh`, `mvn_pmd.sh`, `collect_static_analysis_reports.sh`
2628

27-
4. **Daily Build Log** - Created GitHub Discussion #340
28-
- Category: Daily Build Log
29-
- Title: "Five PRs Hit Develop: Virtual Fields, OAuth2 Customizers, and Three Production Fixes"
30-
- URL: https://github.com/orgs/QRun-IO/discussions/340
29+
4. **Local Testing** - Verified both tools work
30+
- SpotBugs found ~100 issues (many false positives for singletons/fluent APIs)
31+
- PMD found ~2800 violations (many low-priority style suggestions)
3132

32-
## Open Items
33+
## Files Modified/Created
3334

34-
- **Issue #336** - Feature: Pluggable QSessionStoreInterface QBit (future work)
35-
- **License Migration** - Paused, see `docs/PLAN-license-migration.md`
35+
### QQQ Repo
36+
- `pom.xml` - Added SpotBugs and PMD plugin configurations
37+
- `spotbugs/exclude-filter.xml` - NEW
38+
- `pmd/ruleset.xml` - NEW
39+
- `.circleci/config.yml` - Added pipeline parameter and commented example workflow
40+
- `docs/PLAN-spotbugs-pmd.md` - NEW
41+
42+
### QQQ-Orb Repo
43+
- `src/commands/mvn_spotbugs.yml` - NEW
44+
- `src/commands/mvn_pmd.yml` - NEW
45+
- `src/commands/collect_static_analysis_reports.yml` - NEW
46+
- `src/jobs/static_analysis.yml` - NEW
47+
- `src/scripts/mvn_spotbugs.sh` - NEW
48+
- `src/scripts/mvn_pmd.sh` - NEW
49+
- `src/scripts/collect_static_analysis_reports.sh` - NEW
50+
51+
## Local Commands
52+
53+
```bash
54+
# Run SpotBugs (report only)
55+
mvn spotbugs:check -DskipTests
56+
57+
# Run PMD (report only)
58+
mvn pmd:check -DskipTests
59+
60+
# Run both with failure on issues
61+
mvn verify -Dspotbugs.failOnError=true -Dpmd.failOnViolation=true
62+
63+
# Run on single module
64+
mvn spotbugs:check pmd:check -pl qqq-backend-core -DskipTests
65+
```
66+
67+
## Next Steps
68+
69+
1. **Publish qqq-orb@0.6.0** - Bump version and publish to CircleCI registry
70+
2. **Uncomment static_analysis workflow** - After orb is published
71+
3. **Tune exclusions** - Review findings and add exclusions for false positives
72+
4. **Consider making PMD stricter** - Exclude more low-priority rules
3673

3774
## To Continue
3875

3976
Say **"continue from last session"** and Claude will:
4077
1. Read this file and `docs/TODO.md`
4178
2. Check for any pending work
4279
3. Resume from last checkpoint
43-
44-
## Key Files Reference
45-
46-
### New Classes (from merged PRs)
47-
- `qqq-backend-core/.../metadata/fields/QVirtualFieldMetaData.java`
48-
- `qqq-backend-core/.../tables/QFieldSectionAlternativeType.java`
49-
- `qqq-backend-core/.../widgets/blocks/icon/IconBlockData.java`
50-
51-
### Modified Classes
52-
- `qqq-backend-core/.../OAuth2AuthenticationModule.java` (customizer support)
53-
- `qqq-backend-core/.../BulkInsertTransformStep.java` (three-tier fallback)
54-
- `qqq-backend-module-rdbms/.../QueryManager.java` (TIMESTAMPTZ parsing)
55-
- `qqq-backend-core/.../ChildRecordListData.java` (personalization fix)
56-
57-
### Documentation
58-
- `docs/PLAN-pr-merge-order.md` - PR merge plan (completed)
59-
- `docs/PLAN-license-migration.md` - License migration plan (paused)

docs/TODO.md

Lines changed: 46 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,65 @@
11
# TODO
22

3-
## Recently Completed (2026-01-09)
4-
5-
### PR Merge Task
6-
- [x] Create merge plan (`docs/PLAN-pr-merge-order.md`)
7-
- [x] Merge PR #321 - child-table personalization fix
8-
- [x] Merge PR #320 - bulk edit query optimization
9-
- [x] Merge PR #335 - PostgreSQL timestamp/identifier fixes
10-
- [x] Merge PR #337 - OAuth2 customizer support
11-
- [x] Merge PR #280 - virtual fields and alternative sections
12-
- [x] Post-merge validation (189 tests)
13-
- [x] Create Daily Build Log (Discussion #340)
14-
15-
### Issue #334 - OAuth2 Session Security Keys
16-
- [x] Add customizer support to OAuth2AuthenticationModule
17-
- [x] Add unit tests and integration tests
18-
- [x] Create PR #337 (MERGED)
19-
- [x] Create GitHub issue #336 for Phase 2 QBit
3+
## Completed (2026-01-14)
4+
5+
### SpotBugs + PMD Implementation
6+
- [x] Create implementation plan (`docs/PLAN-spotbugs-pmd.md`)
7+
- [x] Add SpotBugs Maven plugin to parent pom.xml
8+
- [x] Create SpotBugs exclusion filter (`spotbugs/exclude-filter.xml`)
9+
- [x] Add PMD Maven plugin to parent pom.xml
10+
- [x] Create PMD ruleset (`pmd/ruleset.xml`)
11+
- [x] Test local Maven execution
12+
- [x] Add static analysis commands to qqq-orb
13+
- [x] Add static analysis job to qqq-orb
14+
- [x] Update CircleCI config with pipeline parameter
2015

2116
---
2217

2318
## Pending Work
2419

25-
### Future: Issue #336 - QSessionStoreInterface QBit
26-
- [ ] Design pluggable session store interface
27-
- [ ] Implement default in-memory store
28-
- [ ] Add Redis/database store options
29-
- [ ] Documentation
20+
### Orb Release Required
21+
- [ ] Bump qqq-orb version to 0.6.0
22+
- [ ] Publish qqq-orb to CircleCI registry
23+
- [ ] Uncomment static_analysis workflow in qqq `.circleci/config.yml`
24+
25+
### Future: Tune Static Analysis
26+
- [ ] Review SpotBugs findings and add targeted exclusions
27+
- [ ] Review PMD findings and tune ruleset
28+
- [ ] Consider enabling `failOnError` for specific high-priority rules
3029

3130
### Background: License Migration (Paused)
3231
See `docs/PLAN-license-migration.md` for details.
3332

34-
- [x] Push LICENSE, NOTICE, README to all 25 repos
35-
- [x] Delete old LICENSE.txt files
36-
- [x] Update `checkstyle/license.txt` header
37-
- [ ] Update Java source file headers (~5,747 files)
38-
- [ ] Update pom.xml `<licenses>` sections (~20 files)
39-
- [ ] Update README.md AGPL references (~15 files)
40-
- [ ] Update package.json license field (qqq-frontend-core)
41-
- [ ] Run checkstyle to verify headers
42-
4333
---
4434

45-
## Notes
35+
## Quick Reference
4636

47-
### New Features Available (v0.36.0-SNAPSHOT)
37+
### Local Static Analysis Commands
38+
```bash
39+
# SpotBugs only
40+
mvn spotbugs:check -DskipTests
4841

49-
**Virtual Fields:**
50-
```java
51-
new QTableMetaData()
52-
.withVirtualField(new QVirtualFieldMetaData("computed")
53-
.withType(QFieldType.STRING));
54-
```
42+
# PMD only
43+
mvn pmd:check -DskipTests
5544

56-
**Alternative Sections:**
57-
```java
58-
new QFieldSection()
59-
.withAlternative(QFieldSectionAlternativeType.MOBILE,
60-
new QFieldSection().withFields(List.of("name")));
61-
```
45+
# Both with failure on issues
46+
mvn verify -Dspotbugs.failOnError=true -Dpmd.failOnViolation=true
47+
48+
# Single module
49+
mvn spotbugs:check pmd:check -pl qqq-backend-core -DskipTests
6250

63-
**OAuth2 Customizer:**
64-
```java
65-
new OAuth2AuthenticationModule()
66-
.withCustomizer(new QCodeReference(MyCustomizer.class));
51+
# View SpotBugs GUI
52+
mvn spotbugs:gui -pl qqq-backend-core
6753
```
6854

69-
### Related Links
70-
- [Discussion #340 - Daily Build Log](https://github.com/orgs/QRun-IO/discussions/340)
71-
- [Issue #336 - QSessionStoreInterface](https://github.com/Kingsrook/qqq/issues/336)
72-
- [PR #280](https://github.com/Kingsrook/qqq/pull/280), [#320](https://github.com/Kingsrook/qqq/pull/320), [#321](https://github.com/Kingsrook/qqq/pull/321), [#335](https://github.com/Kingsrook/qqq/pull/335), [#337](https://github.com/Kingsrook/qqq/pull/337)
55+
### CircleCI Trigger (after orb release)
56+
```bash
57+
# Via tag
58+
git tag static-analysis/$(date +%Y%m%d) && git push origin --tags
59+
60+
# Via API
61+
curl -X POST https://circleci.com/api/v2/project/gh/Kingsrook/qqq/pipeline \
62+
-H "Circle-Token: $CIRCLE_TOKEN" \
63+
-H "Content-Type: application/json" \
64+
-d '{"parameters": {"run_static_analysis": true}}'
65+
```

0 commit comments

Comments
 (0)