Repository Groups are a core organizational feature of Source Code Portal that allows you to logically group related repositories together, regardless of their naming conventions or GitHub organization structure.
Instead of viewing repositories as a flat list, Repository Groups let you organize them into meaningful systems or projects. For example, all repositories related to an "IAM Platform" can be grouped together, even if they have different prefixes or belong to different GitHub organizations.
Key Benefits:
- Logical Organization: Group repositories by system, product, or team
- Flexible Matching: Use regex patterns to automatically include repositories
- Team Focus: Each team can focus on their group without noise from other repos
- Documentation Hub: Each group has a default repository for documentation
- Unified Status: See build/security status for all repos in a group at once
Repository groups are configured in src/main/resources/conf/config.json.
{
"github": {
"organization": "YourOrgName",
"visibility": "public"
},
"groups": [
{
"groupId": "group-identifier",
"display-name": "Human Readable Name",
"description": "Description of this group",
"defaultGroupRepo": "DefaultRepositoryName",
"artifactId": ["Pattern1", "Pattern2*", "Pattern3"]
}
]
}github.organization (required)
- The GitHub organization name to fetch repositories from
- Example:
"Cantara"
github.visibility (optional, default: "public")
- Repository visibility filter
- Options:
"public","private","all" - Note: Viewing private repos requires a GitHub token with
reposcope
groupId (required)
- Unique identifier for the group (used in URLs)
- Must be URL-safe (lowercase, no spaces)
- Example:
"whydah","monitoring-tools","config-service"
display-name (required)
- Human-readable name shown in the UI
- Can contain spaces, capitalization, special characters
- Example:
"Whydah IAM Platform","Monitoring & Observability"
description (optional)
- Brief description of the group's purpose
- Shown on group cards and detail pages
- Example:
"Identity and Access Management infrastructure"
defaultGroupRepo (required)
- Name of the repository to use for group-level documentation
- This repo's README is displayed on the group page
- Example:
"Whydah-Documentation"
artifactId (required)
- Array of repository name patterns to include in this group
- Supports wildcards and regex patterns
- Patterns are case-sensitive
- Example:
["Whydah*", "IAM-*"]
{
"github": {
"organization": "Cantara",
"visibility": "public"
},
"groups": [
{
"groupId": "whydah",
"display-name": "Whydah IAM Platform",
"description": "Identity and Access Management infrastructure",
"defaultGroupRepo": "Whydah-Documentation",
"artifactId": [
"Whydah*"
],
"jenkins": {
"prefix": "Whydah-"
},
"snyk": {
"organization": "cantara",
"projectPrefix": "whydah-"
}
},
{
"groupId": "config-service",
"display-name": "ConfigService",
"description": "Configuration management and distribution service",
"defaultGroupRepo": "ConfigService",
"artifactId": [
"ConfigService",
"ConfigService-*"
],
"jenkins": {
"prefix": "ConfigService-"
}
},
{
"groupId": "monitoring",
"display-name": "Monitoring & Observability",
"description": "Application monitoring and observability tools",
"defaultGroupRepo": "Stingray-Documentation",
"artifactId": [
"Stingray*",
"*-Monitor",
"Grafana-*"
]
}
]
}Repository groups use pattern matching to determine which repositories belong to which groups.
Match a repository name exactly.
Pattern: "ConfigService"
Matches:
ConfigService✓
Does Not Match:
ConfigService-Client✗configservice✗ (case-sensitive)
Match all repositories starting with a prefix.
Pattern: "Whydah*"
Matches:
Whydah-UserAdminService✓Whydah-SecurityTokenService✓Whydah-OAuth2Service✓
Does Not Match:
whydah-client✗ (case-sensitive)MyWhydah✗ (wildcard only at end)
Match all repositories ending with a suffix.
Pattern: "*-Monitor"
Matches:
Application-Monitor✓Database-Monitor✓Network-Monitor✓
Does Not Match:
Monitor✗ (no prefix)Monitor-Tool✗ (wildcard only at start)
Combine multiple patterns to create complex matching rules.
Pattern: ["MyApp-*", "MyApp", "*-MyApp-*"]
Matches:
MyApp✓ (exact match)MyApp-Client✓ (prefix)MyApp-Backend✓ (prefix)Common-MyApp-Utils✓ (contains)
-
Use Consistent Naming: Establish repository naming conventions in your organization
- Good:
Platform-Service-Name(e.g.,IAM-UserService,IAM-TokenService) - Bad: Inconsistent naming makes grouping difficult
- Good:
-
Test Patterns: Before deploying, test patterns to ensure they match the right repos
- Use the Dashboard to verify which repos appear in each group
- Check for overlap between groups
-
Order Matters: If a repository matches multiple groups, it appears in all of them
- This is by design (a shared library might belong to multiple groups)
- Use more specific patterns to avoid unintended matches
-
Case Sensitivity: Patterns are case-sensitive
"Whydah*"does NOT match"whydah-client"- Be consistent with repository naming case
On the main dashboard, each group is displayed as a card showing:
- Group name (from
display-name) - Description (from
description) - Repository count (number of repos matching patterns)
- Recent commits (commits in the last 24 hours)
- Quick link to group detail page
The group detail page (/group/{groupId}) shows:
-
Group Header:
- Group name and description
- Link to default group repository
-
Repository List:
- All repositories matching the group's patterns
- Each repository card shows:
- Repository name, description, URL
- Latest commit (author, message, time)
- Build status badge (Jenkins/GitHub Actions)
- Security status badge (Snyk)
- Repository stats (stars, forks, watchers)
- Primary language and license
-
Group Documentation:
- Rendered README from the
defaultGroupRepo - Markdown or AsciiDoc format
- Syntax-highlighted code blocks
- Embedded images
- Rendered README from the
-
Recent Activity:
- Commit timeline for all repos in the group
- Filter by repository or author
Each group must specify a defaultGroupRepo which serves as the documentation hub for that group.
The default group repository:
- Provides group-level documentation (architecture, getting started, etc.)
- Acts as the landing page for the group detail view
- Should contain a comprehensive README explaining the group
-
Create a dedicated documentation repo:
- Example:
Whydah-Documentationfor the Whydah group - Contains architecture diagrams, API docs, tutorials
- Example:
-
Use a main repository:
- Example:
ConfigServicefor the ConfigService group - If the group represents a single project, use the main repo
- Example:
-
Keep it updated:
- The README is the first thing users see when viewing the group
- Include links to individual repositories
- Maintain an up-to-date architecture diagram
Recommended README structure for default group repos:
# Group Name
## Overview
Brief description of what this group of repositories does.
## Architecture
High-level architecture diagram and explanation.
## Repositories
List of repositories in this group with descriptions.
## Getting Started
Quick start guide for developers new to this group.
## Documentation
Links to detailed documentation for each repository.
## Support
How to get help (Slack, email, GitHub Discussions).A repository can belong to multiple groups by matching patterns in multiple group configurations.
{
"groups": [
{
"groupId": "platform-core",
"display-name": "Platform Core",
"artifactId": ["Platform-*"]
},
{
"groupId": "shared-libraries",
"display-name": "Shared Libraries",
"artifactId": ["*-Common", "*-Utils", "*-Shared"]
}
]
}In this example:
Platform-Commonmatches both groups- It appears in both "Platform Core" and "Shared Libraries"
- This is intentional and useful for shared components
To prevent unintended overlap:
-
Use specific patterns:
- Instead of
"*"(matches everything), use"MyApp-*"
- Instead of
-
Test thoroughly:
- Review the dashboard to see which repos appear in which groups
- Use
/actuator/infoto see loaded configuration
-
Document overlap:
- If a repo intentionally appears in multiple groups, document why
Repository groups can include integration configurations for external services.
Configure Jenkins build status for all repos in a group:
{
"groupId": "whydah",
"jenkins": {
"prefix": "Whydah-"
}
}This tells SCP to look for Jenkins jobs named:
Whydah-UserAdminServiceWhydah-SecurityTokenService- etc.
See Integrations for details.
Configure Snyk security scanning for all repos in a group:
{
"groupId": "whydah",
"snyk": {
"organization": "cantara",
"projectPrefix": "whydah-"
}
}This tells SCP to look for Snyk projects named:
whydah-useradminservicewhydah-securitytokenservice- etc.
See Integrations for details.
Add custom badges to groups:
{
"groupId": "whydah",
"shields": [
{
"label": "coverage",
"message": "85%",
"color": "brightgreen"
},
{
"label": "license",
"message": "Apache 2.0",
"color": "blue"
}
]
}See Integrations for details.
When the application starts or when configuration is reloaded, SCP:
- Reads
config.json - Fetches the repository list from GitHub API
- Applies pattern matching for each group
- Populates the cache with repository metadata
- Prefetches recent commits for each repository
- Startup: All groups are loaded and cached
- Scheduled Refresh: Groups are refreshed every 1 hour (configurable)
- Webhook Trigger: When a push event is received, the affected repository's cache is updated immediately
- Manual Refresh: Restart the application to force a full refresh
- GitHub API Rate Limit: Each repository fetch counts against your rate limit
- With 100 repositories, initial load uses ~100 API calls
- Use webhooks to minimize subsequent API calls
- Cache TTL: Repository metadata is cached for 1 hour to reduce API calls
- Conditional Requests: SCP uses ETags to make efficient conditional requests
SCP validates config.json on startup and logs errors if issues are found.
Missing Required Fields:
ERROR: Group 'whydah' is missing required field 'defaultGroupRepo'
Solution: Add the missing field to the group configuration.
Invalid Pattern Syntax:
WARN: Pattern '[Whydah*' in group 'whydah' has invalid regex syntax
Solution: Fix the regex pattern (remove invalid characters).
No Matching Repositories:
WARN: Group 'whydah' has no matching repositories (pattern: 'Whydah*')
Solution: Check the pattern and verify repositories exist in GitHub.
Duplicate Group IDs:
ERROR: Duplicate group ID 'whydah' found
Solution: Ensure each group has a unique groupId.
You can hide groups with no repositories by configuring the dashboard controller.
Configuration: application.yml
scp:
dashboard:
hide-empty-groups: trueGroups are displayed in the order they appear in config.json. To reorder:
- Edit
config.json - Rearrange the groups in the
groupsarray - Restart the application
Use Spring profiles to load different configurations per environment:
application-dev.yml (development):
scp:
config-file: /path/to/dev-config.jsonapplication-prod.yml (production):
scp:
config-file: /path/to/prod-config.jsonRun with: mvn spring-boot:run -Dspring-boot.run.profiles=dev
Issue: A configured group doesn't appear on the dashboard.
Possible Causes:
- Invalid
config.jsonsyntax - No repositories match the group's patterns
- GitHub organization name mismatch
Solutions:
- Validate JSON syntax:
cat config.json | jq . - Test patterns against repository list
- Check GitHub organization name in config matches your actual organization
Issue: Expected repositories don't appear in a group.
Possible Causes:
- Pattern doesn't match repository name
- Repository visibility (private repo with insufficient token permissions)
- Repository recently created (cache not refreshed)
Solutions:
- Test pattern: Use a regex tester to verify pattern matches repo name
- Verify token has
reposcope for private repositories - Force refresh by restarting application or waiting for scheduled refresh
Issue: Same repository appears multiple times in a group.
Possible Causes:
- Multiple patterns in
artifactIdarray match the same repository - Pattern overlap with wildcard
Solutions:
- Remove duplicate patterns from
artifactIdarray - Use more specific patterns
Issue: Dashboard loads slowly with many groups/repositories.
Possible Causes:
- Too many repositories in one group
- GitHub API rate limit reached
- Network latency to GitHub API
Solutions:
- Split large groups into smaller groups
- Check rate limit:
/actuator/health/github - Enable GitHub webhooks to reduce API calls
- Dashboard - Main dashboard features
- Integrations - Jenkins, Snyk, Shields.io configuration
- Configuration Guide - Full configuration reference
- Architecture Overview - System design