Skip to content

feat(cli): implement config validation with mapstructure metadata and validator#432

Merged
CybotTM merged 1 commit intomainfrom
feature/config-validation-improvements
Dec 24, 2025
Merged

feat(cli): implement config validation with mapstructure metadata and validator#432
CybotTM merged 1 commit intomainfrom
feature/config-validation-improvements

Conversation

@CybotTM
Copy link
Member

@CybotTM CybotTM commented Dec 24, 2025

Summary

  • Add comprehensive config validation system with two-layer approach using mapstructure Metadata for key presence detection and go-playground/validator/v10 for struct value validation
  • Enhance deprecation detection to use key presence instead of just value (poll-interval, no-poll now detected even when set to zero values)
  • Add Levenshtein-based "did you mean?" suggestions for unknown/typo keys in config files
  • Centralize all deprecation handling, removing distributed warning code from middlewares

Key Changes

  • cli/config_decode.go: New decoder with DecodeResult tracking used/unused keys during INI parsing
  • cli/config_validate.go: Validators with custom cron and dockerimage validators, unknown key warning generation
  • cli/deprecations.go: Centralized deprecation registry with KeyName field for presence-based detection
  • cli/config.go: Updated parsing to track all used keys, added validation tags to Global/DockerConfig structs
  • docs/adr/ADR-003: Architecture Decision Record documenting the design

Test plan

  • All existing tests pass
  • New unit tests for decoder metadata tracking (config_decode_test.go)
  • New unit tests for validators (config_validate_test.go)
  • New unit tests for key-presence deprecation detection (deprecations_test.go)
  • Levenshtein distance and "did you mean?" suggestions tested
  • CI checks (lint, tests, build)

… validator

Add comprehensive config validation system with two-layer approach:
- mapstructure Metadata for key presence detection (unknown keys, deprecated options)
- go-playground/validator/v10 for struct value validation with custom validators

Key changes:
- Add DecodeResult tracking used/unused keys during INI parsing
- Add custom validators for cron expressions and Docker image references
- Enhance deprecation detection to use key presence (poll-interval, no-poll)
- Add Levenshtein-based "did you mean?" suggestions for typos
- Centralize deprecation handling, remove distributed warning code
- Add validation tags to Global and DockerConfig structs

Includes ADR-003 documenting the design decision.
Copilot AI review requested due to automatic review settings December 24, 2025 09:01
@github-actions
Copy link

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

OpenSSF Scorecard

PackageVersionScoreDetails
gomod/github.com/gabriel-vasile/mimetype 1.4.12 🟢 7.4
Details
CheckScoreReason
Code-Review⚠️ 0Found 2/22 approved changesets -- score normalized to 0
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Maintained🟢 1029 commit(s) and 6 issue activity found in the last 90 days -- score normalized to 10
Binary-Artifacts🟢 10no binaries found in the repo
Packaging⚠️ -1packaging workflow not detected
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Token-Permissions🟢 10GitHub workflow tokens follow principle of least privilege
CII-Best-Practices🟢 5badge detected: Passing
Security-Policy⚠️ 0security policy file not detected
License🟢 10license file detected
Fuzzing🟢 10project is fuzzed
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md
Vulnerabilities🟢 100 existing vulnerabilities detected
SAST🟢 10SAST tool is run on all commits
gomod/github.com/go-playground/locales 0.14.1 🟢 3.7
Details
CheckScoreReason
Packaging⚠️ -1packaging workflow not detected
Maintained⚠️ 00 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Token-Permissions⚠️ -1No tokens found
Dangerous-Workflow⚠️ -1no workflows found
Code-Review🟢 5Found 7/12 approved changesets -- score normalized to 5
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Binary-Artifacts🟢 10no binaries found in the repo
Security-Policy⚠️ 0security policy file not detected
License🟢 10license file detected
Pinned-Dependencies⚠️ -1no dependencies found
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
Vulnerabilities🟢 100 existing vulnerabilities detected
Fuzzing⚠️ 0project is not fuzzed
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
gomod/github.com/go-playground/universal-translator 0.18.1 🟢 3.7
Details
CheckScoreReason
Binary-Artifacts🟢 10no binaries found in the repo
Maintained⚠️ 00 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Packaging⚠️ -1packaging workflow not detected
Code-Review🟢 3Found 4/11 approved changesets -- score normalized to 3
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Security-Policy⚠️ 0security policy file not detected
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Vulnerabilities🟢 100 existing vulnerabilities detected
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
gomod/github.com/go-playground/validator/v10 10.30.0 🟢 5.4
Details
CheckScoreReason
Packaging⚠️ -1packaging workflow not detected
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Maintained🟢 1025 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 10
Code-Review🟢 9Found 16/17 approved changesets -- score normalized to 9
Binary-Artifacts🟢 10no binaries found in the repo
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Security-Policy⚠️ 0security policy file not detected
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md
Vulnerabilities🟢 73 existing vulnerabilities detected
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
gomod/github.com/leodido/go-urn 1.4.0 🟢 4.8
Details
CheckScoreReason
Code-Review⚠️ 0Found 0/4 approved changesets -- score normalized to 0
Packaging⚠️ -1packaging workflow not detected
Binary-Artifacts🟢 10no binaries found in the repo
Token-Permissions🟢 10GitHub workflow tokens follow principle of least privilege
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Maintained⚠️ 00 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Security-Policy⚠️ 0security policy file not detected
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md
Vulnerabilities🟢 100 existing vulnerabilities detected
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0

Scanned Files

  • go.mod

@github-actions
Copy link

✅ Mutation Testing Results

Mutation Score: 79.17% (threshold: 60%)

✨ Good job! Mutation score meets the threshold.

What is mutation testing?

Mutation testing measures test quality by introducing small changes (mutations) to the code and checking if tests detect them. A higher score means better test effectiveness.

  • Killed mutants: Tests caught the mutation (good!)
  • Survived mutants: Tests missed the mutation (needs improvement)

@CybotTM CybotTM added this pull request to the merge queue Dec 24, 2025
Merged via the queue into main with commit 7c12680 Dec 24, 2025
31 checks passed
@CybotTM CybotTM deleted the feature/config-validation-improvements branch December 24, 2025 09:10
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements a comprehensive configuration validation system for Ofelia with a two-layer approach: mapstructure metadata for key presence detection and go-playground/validator/v10 for struct value validation. The key improvement is the ability to detect deprecated configuration options even when set to zero values (e.g., poll-interval = 0), which was previously missed. It also adds Levenshtein-based "did you mean?" suggestions for typos in configuration keys and centralizes all deprecation handling.

Key Changes

  • New validation infrastructure: Added cli/config_decode.go for metadata tracking during INI parsing and cli/config_validate.go with custom validators for cron expressions and Docker image references
  • Centralized deprecation system: Created cli/deprecations.go with a registry that uses key presence detection instead of just value checking, enabling detection of zero-value deprecated options
  • Enhanced user feedback: Implements Levenshtein distance algorithm for suggesting corrections to typo'd configuration keys

Reviewed changes

Copilot reviewed 14 out of 15 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
go.mod Adds go-playground/validator/v10 dependency and related packages
go.sum Dependency checksums for new validator packages
middlewares/slack.go Removes distributed deprecation warning code in favor of centralized handling
cli/deprecations.go New centralized deprecation registry with presence-based detection
cli/deprecations_test.go Comprehensive tests for deprecation detection and migration
cli/config_decode.go New decoder that tracks used/unused keys during INI parsing
cli/config_decode_test.go Tests for metadata tracking and key normalization
cli/config_validate.go Validation infrastructure with custom cron and dockerimage validators, plus Levenshtein distance for typo suggestions
cli/config_validate_test.go Tests for validators and suggestion algorithm
cli/config.go Integrates new decoder and adds validation tags to Config/DockerConfig structs
cli/docker_config_handler.go Removes deprecation migration logic (now handled centrally)
cli/docker_handler_test.go Updates tests to use new centralized migration system
cli/doctor.go Adds deprecation checking to doctor command output
docs/adr/ADR-003-config-validation-improvements.md Architecture Decision Record documenting the design and implementation
docs/adr/README.md Adds ADR-003 to the index

CybotTM added a commit that referenced this pull request Dec 24, 2025
Rewrites ADR-003 to follow proper ADR conventions:
- Remove implementation plan sections (ADRs document decisions, not plans)
- Remove test plan section
- Fix DecodeResult struct to match implementation (UsedKeys/UnusedKeys only)
- Document Levenshtein distance as part of the decision, not future work
- Add Scope Limitations section documenting current job section limitation
- Change status from Proposed to Accepted

Addresses Copilot review comments on PR #432.
github-merge-queue bot pushed a commit that referenced this pull request Dec 24, 2025
## Summary
- Rewrite ADR-003 to follow proper ADR conventions (decisions, not
plans)
- Remove implementation plan and test plan sections
- Fix DecodeResult struct to match implementation
- Document Levenshtein distance as part of the decision
- Add Scope Limitations section for job section limitation
- Update status from Proposed to Accepted

## Addresses
Copilot review comments from PR #432:
- DecodeResult struct mismatch
- Levenshtein phase placement
- Job sections unknown key limitation

## Test plan
- [x] ADR follows proper format (Context, Decision, Consequences)
- [x] README index updated with Accepted status
@CybotTM CybotTM added the released:v0.18.0 Released in v0.18.0 label Dec 26, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

released:v0.18.0 Released in v0.18.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants