Skip to content

Repository scanning

Repository scanning is the capability that finds componecat.yaml descriptors in your repositories and turns them into catalog entities. It runs two ways that complement each other: a scheduled scan crawls your organizations looking for descriptors the catalog doesn’t know about yet, and a webhook re-ingests a descriptor the moment someone pushes a change to it.

Both are configured on a Git integration — see Integrations for connecting one. GitHub, GitLab, and Bitbucket all support repository scanning.

The connection’s credential is what reads your repositories, so it needs:

  • GitHub — read access to repository contents and code search across the organizations you want scanned. A personal access token or a GitHub App installation both work.
  • GitLab — the read_api scope (or api). A project access token covers a single project; use a personal access token to scan groups.
  • Bitbucket — an access token with read access to the workspaces and repositories you want scanned.

Private repositories that the credential can’t see are invisible to the scan.

On the integration’s page, open the Git Scanning card. Set the configuration first, then switch the capability on — the panel is editable while the capability is off, so the first run uses your settings.

Setting Meaning
Schedule (cron) How often the scan runs. Default 0 */6 * * * — every six hours.
Target Orgs/Groups Which organizations, groups, or workspaces to crawl. A comma-separated list, or * for everything the credential can see.
File Pattern Which files count as descriptors. Default componecat.yaml.

Use Run now on the card to trigger a scan immediately — handy right after you change the pattern or targets.

For each target, the scan asks the provider’s search API for repositories containing the descriptor filename, then lists each candidate repository’s files and matches them against your full pattern. Every match that the catalog doesn’t already track is queued for ingestion.

That last part is the important one: a scheduled scan ingests descriptors that are new to the catalog. Edits to a descriptor that already has an entity arrive through the webhook. If you want a scan to pick up a changed descriptor, the webhook is the mechanism to fix — or delete the entity so the next scan treats the descriptor as new.

The pattern is matched against each repository’s file listing with a small glob syntax: * matches within one path segment, ? matches a single character, and ** matches any number of segments.

Repository layout File Pattern Result
Descriptors anywhere in the repo (leave as the default) componecat.yaml matched at any depth.
One descriptor per top-level service directory services/*/componecat.yaml Matches services/api/componecat.yaml and siblings; a descriptor at the repo root or nested deeper is not discovered.
Services nested arbitrarily deep under one root services/**/componecat.yaml Matches at any depth under services/.
A different descriptor filename **/catalog-info.yaml Any depth, different filename.

A bare filename with no / matches at any depth. A pattern containing / is anchored to that directory structure.

Note that the pattern applies to scans only. Webhook ingestion always looks for files named componecat.yaml, at any depth, whatever pattern you set here — so a custom descriptor filename is discovered by scans but not by pushes.

The webhook is what makes the catalog update within seconds of a merge. Setting it up takes two values from Componecat and one webhook in your Git provider.

  1. Open the integration. The Webhook endpoint card shows the URL to use — it ends in your integration’s id, so each connection has its own.
  2. In the Git Scanning card, choose Rotate Webhook Secret and confirm. The new secret is shown once — copy it before closing the dialog.
  3. Create the webhook in your Git provider with that URL and secret, as below.

Rotating the secret invalidates the previous one immediately, so update the provider’s webhook configuration right away or pushes will be rejected.

Add a webhook on the repository or organization:

  • Payload URL — the endpoint from the integration page.
  • Content typeapplication/json.
  • Secret — the rotated secret.
  • Events — just the push event.

Add a webhook under the project’s or group’s Webhooks settings:

  • URL — the endpoint from the integration page.
  • Secret token — the rotated secret.
  • Trigger — push events.

Add a repository webhook:

  • URL — the endpoint from the integration page.
  • Secret — the rotated secret.
  • Triggers — repository push.

Bitbucket’s push events don’t list the files that changed, so a push re-reads the descriptor at the repository root. Descriptors in subdirectories of a Bitbucket repository are discovered by scheduled scans instead.

Only pushes to the repository’s default branch are processed; anything else is acknowledged and ignored, as are non-push events. Componecat looks at the files the push touched, picks out every componecat.yaml among them (at any depth), and queues one ingestion per descriptor — so a monorepo push that changes three descriptors updates three entities independently. Deleting a descriptor is a change too, and is processed the same way.

The Git Scanning card lists recent runs while the capability is enabled, with a status, timestamps, a discovered count — descriptors newly queued for ingestion in that run — and any errors. Errors are per repository: a repository the credential can’t read, or one whose file listing failed, is recorded and the scan carries on with the rest.

Runs in progress refresh automatically, so a Run now shows its result without a reload.

Connecting a Git provider also enriches entities that link to a repository, even ones you created by hand. Componecat fetches the repository’s languages, README, default branch, and description, and tracks whether the repository is reachable, archived, or gone. Values you set manually aren’t overwritten. Without a matching integration this only works for public repositories — the integration’s credential is what makes private repositories readable.

  • Pushes aren’t ingested. Check the delivery response in your Git provider’s webhook log. 401 means the signature didn’t match — usually a secret that was rotated on one side only. 404 means the URL is wrong, or the integration doesn’t have Git Scanning enabled.
  • The push was accepted but nothing changed. The response body says why: a push to a non-default branch and a push that touched no componecat.yaml are both acknowledged and ignored.
  • A scan finds nothing. Confirm the target organizations are spelled as the provider knows them, that the credential can see those repositories, and that the file pattern matches where your descriptors actually live.
  • An existing descriptor’s changes never appear. Scheduled scans skip descriptors already tracked by the catalog; that path is the webhook’s job.
  • A very large push. Webhook payloads above 512 KB are rejected. The scheduled scan still picks up anything new from such a push.
  • A descriptor was found but the entity is wrong. That’s ingestion, not discovery — see Catalog as code for how descriptor and manual edits are reconciled.