Thank you for your interest in contributing to the Explain Error Plugin!
This guide will help you get started with development and contribution.
- Java: Version 17 or later
- Maven: Version 3.9 or later
- Jenkins: Version 2.528.3 or later for testing
- Git: For version control
- IDE: IntelliJ IDEA or VS Code recommended
-
Fork and clone the repository:
git clone https://github.com/<your-username>/explain-error-plugin.git cd explain-error-plugin
-
Build the plugin:
A
Makefileis provided for convenience. Run the following to see all available targets and their descriptions:make help
-
Build the plugin:
make package
-
Install in Jenkins:
- Copy
target/explain-error.hpito your Jenkins instance - Go to
Manage Jenkins→Manage Plugins→Advanced - Upload the
.hpifile in the "Upload Plugin" section - Restart Jenkins
- Copy
-
Alternative: Direct file copy:
cp target/explain-error.hpi $JENKINS_HOME/plugins/ # Restart Jenkins
Tip: Run
make helpanytime to see all available build, test, and run targets.
-
Navigate to Jenkins configuration:
- Go to
Manage Jenkins→Configure System - Find "Explain Error Plugin Configuration" section
- Go to
-
Configure test settings:
- Enable AI Error Explanation
- API Key: Your OpenAI API key (get from OpenAI Dashboard)
- API URL:
https://api.openai.com/v1/chat/completions(default) - Model:
gpt-3.5-turboorgpt-4
-
Test your configuration:
- Click "Test Configuration" button
- Verify the test passes before development
Run make help to see all available test-related targets.
We use JUnit 5, Mockito, and WireMock for testing. Examples:
@ExtendWith(MockitoExtension.class)
class AIServiceTest {
@Mock
private GlobalConfigurationImpl config;
@Test
void shouldExplainError() {
// Test implementation
}
}-
Create a test pipeline:
pipeline { agent any stages { stage('Test') { steps { script { // Intentionally fail to test error explanation sh 'exit 1' } } } } post { failure { explainError() } } } -
Test console button:
- Run any job that fails
- Go to console output
- Click "Explain Error" button
- Verify explanation appears
- Java: Follow standard Java conventions
- Indentation: 4 spaces (no tabs)
- Line length: Maximum 120 characters
- Naming: Use descriptive names for classes and methods
To check for code quality issues, run make help to find the lint target and execute it.
The plugin follows these patterns:
src/main/java/io/jenkins/plugins/explain_error/
├── GlobalConfigurationImpl.java # Main plugin class
├── ExplainErrorStep.java # Pipeline step (explainError + autoFix parameters)
├── ErrorExplainer.java # Error analysis logic (provider resolution)
├── ConsoleExplainErrorAction.java # Console button action
├── ErrorExplanationAction.java # Build action for storing results
├── provider/
│ ├── BaseAIProvider.java # Abstract AI service base class
│ ├── AnthropicProvider.java # Anthropic Claude / LangChain4j
│ ├── AzureOpenAIProvider.java # Azure OpenAI / LangChain4j
│ ├── BedrockProvider.java # AWS Bedrock / LangChain4j
│ ├── CustomOktaAIProvider.java # Custom Okta AI gateway
│ ├── DeepSeekProvider.java # DeepSeek / LangChain4j
│ ├── GeminiProvider.java # Google Gemini / LangChain4j
│ ├── MicrosoftFoundryProvider.java # Microsoft Foundry / LangChain4j
│ ├── OllamaProvider.java # Ollama / LangChain4j
│ ├── OpenAIProvider.java # OpenAI / LangChain4j
│ └── QwenProvider.java # Qwen / LangChain4j
└── autofix/
├── AutoFixOrchestrator.java # Coordinates AI suggestion → branch → PR flow
├── AutoFixAction.java # Build action that stores and displays the PR URL
├── AutoFixResult.java # Result value object (status + PR URL + message)
├── AutoFixStatus.java # Enum: CREATED, FAILED, SKIPPED_*, NOT_APPLICABLE
├── FixAssistant.java # LangChain4j AI service interface for fix suggestions
├── FixSuggestion.java # Structured AI response (fixable, changes, confidence)
├── UnifiedDiffApplier.java # Applies unified diffs to file content (fuzzy match)
└── scm/
├── ScmApiClient.java # Interface: createBranch, commitFiles, createPullRequest…
├── ScmClientFactory.java # Factory: creates the right client from ScmRepo
├── ScmRepo.java # Value object: SCM type + base URL + owner/repo + token
├── ScmType.java # Enum: GITHUB, GITLAB, BITBUCKET
├── GitHubApiClient.java # GitHub REST API v3 (Git Trees API for atomic commits)
├── GitLabApiClient.java # GitLab REST API v4 (Commits API)
├── BitbucketApiClient.java # Bitbucket Cloud REST API v2
└── PullRequest.java # Value object returned by createPullRequest()
-
Create feature branch:
git checkout -b feature/your-feature-name
-
Follow TDD approach:
- Write tests first
- Implement feature
- Refactor and optimize
-
Update documentation:
- Update README.md if needed (keep provider lists in alphabetical order)
- Update
docs/if the change affects existing feature docs - Add Javadoc comments
- In Jenkins:
- Go to
Manage Jenkins→System Log - Add logger:
io.jenkins.plugins.explain_error - Set level to
FINEorALL
- Go to
-
Before submitting:
- ✅ All tests pass
- ✅ Full verify passes
- ✅ No new lint issues
- ✅ Code follows style guidelines
- ✅ Documentation updated
Run
make helpto see the relevant targets for each of the above steps. -
PR checklist:
- Descriptive title and description
- Related issue linked (if applicable)
- Tests included
- Documentation updated
- No breaking changes (or clearly documented)
-
Review process:
- Automated tests will run
- Maintainers will review code
- Address feedback promptly
Use our bug report template:
- Environment: Jenkins version, plugin version, Java version
- Steps to reproduce: Clear, numbered steps
- Expected behavior: What should happen
- Actual behavior: What actually happens
- Logs: Relevant error logs or stack traces
Use our feature request template:
- Problem: What problem does this solve?
- Solution: Proposed solution
- Alternatives: Alternative approaches considered
- Additional context: Screenshots, examples, etc.
- 💬 Discussions: GitHub Discussions
- 🐛 Issues: GitHub Issues
- 📧 Security: security@jenkins.io
Thank you for contributing to the Explain Error Plugin! 🎉