Contributing Guide
Relevant source files
The following files were used as context for generating this wiki page:- CONTRIBUTING.md
- README.md
- README-ptBR.md
- api/securitytest/brakeman.go
- cli/analysis/analysis.go
- cli/types/types.go
- client/analysis/output.go
- client/cmd/main.go
- client/integration/sonarqube/sonarqube.go
- client/integration/sonarqube/sonarqube_test.go
- client/integration/sonarqube/testdata/analysis/vulnerable_go_project.json
- client/integration/sonarqube/testdata/analysis/vulnerable_js_project.json
- client/integration/sonarqube/testdata/analysis/vulnerable_python_project.json
- client/integration/sonarqube/testdata/analysis/vulnerable_ruby_project.json
- client/integration/sonarqube/testdata/sonarqube/vulnerable_js_output.json
This guide provides instructions and best practices for contributing to the huskyCI project. It covers the development process, how to propose bug fixes and improvements, and the technical architecture to help you build and test your changes. huskyCI is an open-source tool that orchestrates security tests and centralizes results, and contributions are welcome to enhance its capabilities.
Before making a change, please discuss it with the repository owners via an issue, email, or another method. All interactions with the project must follow the Code of Conduct.
Sources: CONTRIBUTING.md:3-7, README.md:37-40
Communication Channels
The project maintains several communication channels for contributors and users.
- GitHub Issues: For bug reports and feature requests.
- Gitter: For community discussions.
- Twitter: For updates and announcements.
Sources: README.md:42-46
Pull Request Process
To ensure a smooth and consistent development workflow, please follow these steps when submitting a pull request.
- Ensure any install or build dependencies are removed before the end of the layer when doing a build.
- Update the
README.mdwith details of changes to the interface, including new environment variables, exposed ports, useful file locations, and container parameters. - Increase the version numbers in any example files and the
README.mdto the new version that this Pull Request would represent. The project uses Semantic Versioning (SemVer). - You may merge the Pull Request once you have the sign-off of two other developers. If you do not have merge permissions, you may request the second reviewer to merge it for you.
Sources: CONTRIBUTING.md:9-18
Code of Conduct
All contributors and maintainers pledge to foster an open, welcoming, and harassment-free environment. This applies to all project spaces and public representations of the project.
Standards
- Positive Behaviors: Use welcoming language, be respectful of different viewpoints, accept constructive criticism, and show empathy.
- Unacceptable Behaviors: Avoid sexualized language, trolling, harassment, publishing private information, and other unprofessional conduct.
Enforcement
Project maintainers are responsible for clarifying and enforcing these standards. They have the right to remove, edit, or reject contributions that do not align with the Code of Conduct and can ban contributors for inappropriate behavior. Incidents can be reported by contacting the project team.
Sources: CONTRIBUTING.md:22-77
Technical Overview for Contributors
Understanding the project's architecture is key to making effective contributions. This section details the client workflow, data structures, and how to add new security tools.
Client-Side Workflow
The huskyCI client (main.go) orchestrates the analysis process. The following diagram illustrates the sequence of operations from initialization to result reporting.
This diagram shows the client's execution flow, from configuration checks to the final exit status based on vulnerability findings.
Sources: client/cmd/main.go:17-123
Core Data Structures
The analysis results are organized into a set of well-defined Go structs. Understanding these is crucial for parsing security tool outputs and manipulating analysis data.
Sources: cli/types/types.go
Key Structs
| Struct | Description |
|---|---|
Analysis | Top-level struct holding all data for a single analysis, including status, containers, and results. |
Container | Represents a single security tool run, containing its output, result, and status. |
SecurityTest | Defines a security tool, including its Docker image, command, and language. |
HuskyCIResults | A nested struct that categorizes all findings by language (Go, Python, etc.) and tool. |
HuskyCIVulnerability | A standardized struct for a single vulnerability, used to unify output from different tools. |
Sources: cli/types/types.go:23-100
The following diagram shows the relationship between these core data structures.
Adding a New Security Tool
A common contribution is adding support for a new security tool. This involves creating a new analyzer in the api/securitytest package. The goal is to parse the tool's native JSON output and map it to the standardized HuskyCIVulnerability struct.
The brakeman.go file serves as a great example.
-
Define Output Structs: Create Go structs that match the JSON output of the new tool. For Brakeman, these are
BrakemanOutputandWarningItem.// api/securitytest/brakeman.go:18-28 type BrakemanOutput struct { Warnings []WarningItem `json:"warnings"` IgnoredWarnings []WarningItem `json:"ignored_warnings"` } type WarningItem struct { Type string `json:"warning_type"` Code string `json:"code"` Message string `json:"message"` File string `json:"file"` Line int `json:"line"` Details string `json:"link"` Confidence string `json:"confidence"` }Sources: api/securitytest/brakeman.go:18-28
-
Implement the Analyzer Function: Create a function like
analyzeBrakemanthat unmarshals the raw output (cOutput) into the structs defined above. -
Map to
HuskyCIVulnerability: Implement a method to iterate through the parsed warnings and populate aHuskyCISecurityTestOutputstruct. This standardizes the findings. Confidence levels (High,Medium,Low) are used to categorize vulnerabilities.// api/securitytest/brakeman.go:70-87 func (brakemanScan *SecTestScanInfo) prepareBrakemanVulns() { // ... for _, warning := range brakemanOutput.Warnings { brakemanVuln := types.HuskyCIVulnerability{} brakemanVuln.Language = "Ruby" brakemanVuln.SecurityTool = "Brakeman" brakemanVuln.Confidence = warning.Confidence // ... brakemanVuln.File = warning.File brakemanVuln.Line = strconv.Itoa(warning.Line) switch brakemanVuln.Confidence { case "High": huskyCIbrakemanResults.HighVulns = append(huskyCIbrakemanResults.HighVulns, brakemanVuln) case "Medium": huskyCIbrakemanResults.MediumVulns = append(huskyCIbrakemanResults.MediumVulns, brakemanVuln) case "Low": huskyCIbrakemanResults.LowVulns = append(huskyCIbrakemanResults.LowVulns, brakemanVuln) } } // ... }Sources: api/securitytest/brakeman.go:70-103
-
Register the Tool: The new tool must be registered in
cli/analysis/analysis.goto be discoverable for the relevant language.// cli/analysis/analysis.go:181-183 case "Ruby": list[language] = []string{"huskyci/brakeman"}Sources: cli/analysis/analysis.go:181-183
Output Generation and Integrations
Standard Output
The client can produce two types of output: a human-readable STDOUT format and a machine-readable JSON format. The printSTDOUTOutput function in client/analysis/output.go iterates through all vulnerabilities and prints them, while printJSONOutput marshals the JSONOutput struct.
A summary is printed at the end of the STDOUT, showing the total number of vulnerabilities by severity for each tool.
// client/analysis/output.go:375-381
func printAllSummary(analysis types.Analysis) {
// ...
if outputJSON.Summary.BanditSummary.FoundVuln || outputJSON.Summary.BanditSummary.FoundInfo {
fmt.Println()
fmt.Printf("[HUSKYCI][SUMMARY] Python -> %s\n", banditVersion)
fmt.Printf("[HUSKYCI][SUMMARY] High: %d\n", outputJSON.Summary.BanditSummary.HighVuln)
// ...
}
// ...
}
Sources: client/analysis/output.go:375-476
SonarQube Integration
huskyCI can generate a JSON report compatible with SonarQube's generic issue import format. The sonarqube.GenerateOutputFile function is responsible for this.
The following diagram illustrates the process of converting huskyCI vulnerabilities into SonarQube issues.
This sequence shows how sonarqube.go processes an analysis, maps severities, handles missing file paths, and writes the final JSON report.
Sources: client/integration/sonarqube/sonarqube.go:21-103, client/cmd/main.go:82-86
The severity mapping is as follows:
| huskyCI Severity | SonarQube Severity |
|---|---|
high | BLOCKER |
medium | MAJOR |
low | MINOR |
| default | INFO |
Sources: client/integration/sonar/sonarqube.go:73-82
Conclusion
Contributing to huskyCI can range from improving documentation and fixing bugs to adding support for new security tools. By following the Pull Request process and adhering to the Code of Conduct, you can help improve the security of the software development lifecycle for all users. This guide provides the foundational technical knowledge to get started with code contributions.