A unified Jenkins SCM plugin that integrates with Diversion repositories, providing both pipeline checkout and Global Pipeline Library support.
Author: Ian Bain (ibain@mac.com)
License: MIT
Latest Version: Available on plugins.jenkins.io/diversion-scm
- Repository Checkout: Checkout files from Diversion repositories for pipeline jobs
- Branch Support: Support for different branches and refs
- Credential Integration: Secure API token management through Jenkins credentials
- Pipeline Support: Works with both freestyle and pipeline jobs
- Auto-Detection: Automatically detects pipeline script files based on job name
- Changelog Support: Full changelog display with commit IDs, authors, messages, and changed files
- Library Loading: Load shared libraries from Diversion repositories
- Interactive UI: Dropdown menus for repository and branch selection
- Auto-Discovery: Automatically discovers available repositories and branches
- Library Path Configuration: Configurable base path for library files (e.g.,
Meta/Jenkins/SharedLib) - Smart Reloading: Automatically detects when library files change based on commit timestamps
- Seamless Integration: Works alongside existing GitHub or Git-based libraries
- Commit ID Display: Shows commit IDs in both the Changes page list and detail pages
- Detailed Views: Full commit details including author, date, message, and changed files
- Proper Navigation: Working detail page links from the Changes page
- Credential Protection: Permission checks prevent unauthorized credential enumeration
- CSRF Protection: All external API calls are protected from cross-site request forgery attacks
- Authorization: Proper permission checks ensure only authorized users can access sensitive operations
- Security Scanning: Plugin passes Jenkins CodeQL security scans
- Jenkins 2.504.3 or later
- Java 17 or later
- Diversion API refresh token (Get one here)
The plugin can be installed from the Jenkins Plugin Manager once published, or built from source.
For developers: See DEVELOPMENT.md for build instructions and development setup.
- Go to Manage Jenkins → Manage Credentials
- Click Add Credentials
- Select Secret text
- Fill in:
- ID:
diversion-refresh-token(or your preferred ID) - Description:
Diversion Refresh Token - Secret: Your Diversion API refresh token
- ID:
Important: You need a refresh token, not an access token. Get this from your Diversion account settings.
- Create a new pipeline job
- In Pipeline section, select Pipeline script from SCM under Definition
- In SCM, select Diversion
- Configure:
- Credentials: Select your Diversion API token credential
- Repository: Your Diversion repository (dropdown will populate after selecting credentials)
- Branch: Branch to checkout (dropdown will populate after selecting repository)
- Script Path: Optional path to specific .groovy file, or leave empty to auto-detect based on job name
The plugin will automatically search for a .groovy file matching your job name in common locations like Meta/Jenkins/, Jenkins/, scripts/, etc.
- Create a new freestyle job
- In Source Code Management, select Diversion
- Configure the same fields as above
- Go to Manage Jenkins → System
- Scroll to Global Trusted Pipeline Libraries
- Click Add to create a new library
- Configure the library:
- Name:
diversion-lib(or your preferred name) - Default Version:
main(or your preferred branch) - Modern SCM: Select Diversion from dropdown
- Credentials: Select your Diversion API token credential
- Repository: Your Diversion repository (dropdown populates automatically)
- Default Branch: Branch to checkout (dropdown populates automatically)
- Library Base Path: Path to your folder containing
vars/,src/,resources/directories (e.g.,Meta/Jenkins/SharedLib)
- Name:
@Library('diversion-lib') _
pipeline {
agent any
stages {
stage('Build') {
steps {
script {
// Use helpers from your library's vars/ directory
deploymentHelpers.deployToStaging()
// Your build logic here
}
}
}
}
}
The plugin provides comprehensive changelog support:
- Changes Page: Shows commit IDs, messages, and authors in a numbered list
- Detail Pages: Click any commit to see full details including:
- Commit ID
- Author name and email
- Commit date
- Full commit message
- List of changed files
Global Pipeline Libraries automatically reload when:
- New commits are made to the repository
- Library files are updated
- The commit timestamp changes
The plugin checks the actual commit timestamp to determine if libraries need to be reloaded, ensuring you always have the latest version.
The plugin provides user-friendly dropdown menus that:
- Populate repositories based on selected credentials
- Populate branches based on selected repository
- Show repository and branch names with IDs in parentheses
- Validate configuration in real-time
This plugin integrates with the Diversion API using:
- Token Exchange:
POST https://auth.diversion.dev/oauth2/token - Repository List:
GET https://api.diversion.dev/v0/repos - Repository Details:
GET https://api.diversion.dev/v0/repos/{repoId} - Branch List:
GET https://api.diversion.dev/v0/repos/{repoId}/branches - File Tree:
GET https://api.diversion.dev/v0/repos/{repoId}/trees/{refId} - File Content:
GET https://api.diversion.dev/v0/repos/{repoId}/blobs/{refId}/{path} - Commits:
GET https://api.diversion.dev/v0/repos/{repoId}/commits
# Clean and compile
mvn clean compile
# Run tests
mvn test
# Package plugin (skips tests for faster builds)
mvn clean package -DskipTests
# Run Jenkins with plugin
mvn hpi:run
src/main/java/io/superstudios/plugins/diversion/
├── DiversionSCM.java # Legacy SCM implementation
├── DiversionSCMSource.java # Modern SCM (Global Libraries)
├── DiversionSCMFileSystem.java # File system for library loading
├── DiversionSCMFileSystemBuilder.java # Builder for file systems
├── DiversionSCMHead.java # SCM head (branch) representation
├── DiversionSCMRevision.java # SCM revision (commit) representation
├── DiversionSCMRevisionState.java # State tracking for builds
├── DiversionChangeLogParser.java # Parses changelog XML
├── DiversionChangeLogSet.java # Change log set container
├── DiversionChangeLogEntry.java # Individual changelog entry
├── DiversionApiClient.java # Diversion API client
├── DiversionUIHelper.java # Shared UI helper methods
├── DiversionRepository.java # Repository model
├── DiversionBranch.java # Branch model
├── DiversionCommit.java # Commit model
├── DiversionFile.java # File model
├── DiversionAuthor.java # Author model
└── DiversionTag.java # Tag model (for future use)
src/main/resources/
├── index.jelly # Plugin index page
└── io/superstudios/plugins/diversion/
├── DiversionSCM/
│ ├── config.jelly # Legacy SCM configuration UI
│ └── help-repositoryId.html # Help text
├── DiversionSCMSource/
│ ├── config.jelly # Modern SCM configuration UI
│ └── help-libraryPath.html # Help text
├── DiversionChangeLogEntry/
│ ├── digest.jelly # One-line summary template
│ └── index.jelly # Detail page template
└── DiversionChangeLogSet/
└── index.jelly # ChangeLogSet list template
The plugin follows Jenkins plugin best practices:
- Code Deduplication: Shared UI logic in
DiversionUIHelperclass - Proper Error Handling: Graceful fallbacks for API failures
- Null Safety: Comprehensive null checks throughout
- Documentation: Javadoc comments on all public methods
- No Stale Code: All code is actively used
-
Authentication Failed
- Verify your Diversion API refresh token is correct
- Check that the Jenkins credential ID matches in job configuration
- Ensure the token hasn't expired (refresh tokens don't expire, but check your Diversion account)
-
Repository Not Found
- Verify the repository ID is correct
- Check that your API token has access to the repository
- Try refreshing the repository dropdown after selecting credentials
-
File Checkout Failed
- Check network connectivity to Diversion API
- Verify the branch/ref exists in the repository
- Check Jenkins logs for detailed error messages
-
Library Not Reloading
- The plugin checks commit timestamps to detect changes
- If libraries aren't reloading, check that new commits are being made
- Verify the library path is correct
-
Changelog Not Showing
- Ensure the build has completed successfully
- Check that commits exist in the repository
- Verify the changelog XML file exists in the build directory
- ✅ Fixed folder-scoped credentials: Credentials created in folders now work correctly at runtime
- ✅ Credential tracking: Added credential usage tracking for reporting
- ✅ Modern Credentials API: Updated to use modern API pattern (no Authentication parameter)
- ✅ UI improvements: Using
StandardListBoxModelfor proper credential display - ✅ Updated to Java 17 (matches Jenkins baseline requirements)
- ✅ Migrated to BOM-based dependency management (cleaner, more maintainable)
- ✅ Updated Jenkins baseline to 2.504.3
- ✅ Improved dependency version management using Jenkins BOM
- ✅ Updated parent POM to version 5.28 (Jenkins requirement)
- ✅ Replaced direct dependencies with Jenkins API plugins:
httpclient→apache-httpcomponents-client-4-apijackson-databind→jackson2-api
- ✅ Added security scanning workflow and dependency update automation
- ✅ Security Enhancements:
- Credential enumeration protection (permission checks before accessing credentials)
- CSRF protection (
@RequirePOSTannotations on external API calls) - Proper permission checks using
hasPermission()for better UX - Proxy support with authentication via
ProxyConfiguration.newHttpClient() - All security findings from Jenkins CodeQL scans resolved
- ✅ Fixed changelog detail page display
- ✅ Added commit ID display in Changes page list
- ✅ Fixed changelog entry parent relationships
- ✅ Improved global library reload detection (uses commit timestamps)
- ✅ Code deduplication (created
DiversionUIHelperclass) - ✅ Removed stale code (workspaceId field)
- ✅ Enhanced error handling and null safety
- ✅ Improved Jelly templates with proper null checks
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Submit a pull request
This plugin is licensed under the MIT License.
For issues and questions:
- Create an issue in the repository
- Check the Jenkins plugin documentation
- Review the Diversion API documentation
Built with ❤️ for the Jenkins and Diversion communities.