Repository Ownership
Shoehorn tracks ownership of repositories through multiple mechanisms: GitHub topics, service manifests, and Forge-created repositories. This guide covers how ownership is established and resolved.
Ownership via GitHub Topics
Section titled “Ownership via GitHub Topics”The simplest way to assign ownership is with GitHub topics. No manifest files required.
Supported Topic Patterns
Section titled “Supported Topic Patterns”Shoehorn recognizes all of these patterns:
| GitHub Topic | Maps to Team |
|---|---|
owner-platform-team | platform-team |
owner:platform-team | platform-team |
team-beta-team | beta-team |
team:beta-team | beta-team |
Recommended for new repositories:
- Use
owner-<team-slug>when you want the topic itself to be treated as the explicit ownership signal. - Use
team-<team-slug>when you want a lighter-weight team ownership topic.
Setting Topics
Section titled “Setting Topics”Via GitHub UI:
- Go to your repository on GitHub
- Click the gear icon next to About
- In the Topics field, add
owner-<your-team-slug>orteam-<your-team-slug> - Click Save changes
Via GitHub API:
curl -X PUT https://api.github.com/repos/<owner>/<repo>/topics \ -H "Authorization: token <github-token>" \ -H "Accept: application/vnd.github+json" \ -d '{"names": ["owner-platform-team", "golang", "microservice"]}'Via Forge (automatic):
When creating a repository through Forge, pass topics directly to github.repo.create:
steps: - id: create-repo name: Create GitHub repository action: github.repo.create inputs: owner: my-org name: "${{ inputs.name }}" description: "Service created via Forge" private: true topics: ["owner-${{ inputs.owner }}", "golang", "microservice"]How Discovery Works
Section titled “How Discovery Works”- The crawler scans repositories in configured GitHub organizations
- Topics matching
owner-*,owner:*,team-*, orteam:*are extracted - The prefix is stripped to get the team slug
- The repository is linked to the matching Shoehorn team
Multiple Topics
Section titled “Multiple Topics”A repository can have many topics. Only owner-*, owner:*, team-*, and team:* affect ownership. All other topics are imported as entity tags.
If multiple ownership topics are present, Shoehorn imports all matching candidates. Use a single ownership topic per repository to keep ownership unambiguous.
Ownership via Manifests
Section titled “Ownership via Manifests”For explicit ownership, add a .shoehorn/manifest.yml to your repository:
schemaVersion: 1
service: id: payment-api name: Payment API type: service
owner: - type: team id: payments-teamManifest ownership has the highest priority and overrides topics and annotations.
Repositories Created via Forge
Section titled “Repositories Created via Forge”Forge workflows can create repositories with ownership pre-configured.
Example: Create a Repository with Ownership
Section titled “Example: Create a Repository with Ownership”version: "1.0.0"metadata: name: create-service displayName: Create Service Repository category: repository
inputs: type: object required: [name, owner] properties: name: type: string title: Service Name owner: type: string title: Owning Team description: Team slug (e.g., platform-team)
steps: - id: create-repo name: Create GitHub repository action: github.repo.create inputs: owner: my-org name: "${{ inputs.name }}" description: "Service created via Forge" private: true topics: ["owner-${{ inputs.owner }}", "shoehorn-managed"]
- id: register name: Register in catalog action: catalog.entity.register inputs: serviceId: "${{ inputs.name }}" name: "${{ inputs.name }}" type: service owner: "${{ inputs.owner }}"Repositories Created via Plain GitHub
Section titled “Repositories Created via Plain GitHub”For repositories created directly on GitHub (not through Forge), ownership is established by:
- Adding a topic — Add
owner-<team-slug>orteam-<team-slug>to the repository topics - Adding a manifest — Create
.shoehorn/manifest.ymlwith anownerfield - Waiting for discovery — The crawler picks up new repositories on its next scan (or immediately via the
repository.createdwebhook)
Ownership Priority
Section titled “Ownership Priority”When multiple sources provide ownership, the highest-priority source wins:
| Priority | Source | Example |
|---|---|---|
| 1 (highest) | Manifest owner field | owner: [{type: team, id: payments}] |
| 2 | Kubernetes annotation | shoehorn.dev/owner: payments |
| 3 (lowest) | GitHub topic | owner-platform-team or team-beta-team |
If a manifest sets an owner, the GitHub topic is ignored for ownership but still tracked as metadata.
Scorecard Integration
Section titled “Scorecard Integration”The scorecard rule team-topic checks if a repository has an ownership topic. This contributes to the ownership category score, encouraging teams to declare ownership for all repositories.
See Also
Section titled “See Also”- GitHub Topics - Topic conventions and priority
- GitHub Integration - GitHub App setup
- Manifests - Manifest file format
- Forge Overview - Self-service workflows
- Creating Molds - Writing Forge mold templates
- Team Sync - Multi-source team synchronization