Skip to main content

Maintain the catalog

The site only lists public, non-archived repositories under nathanmcnulty that start with azd- and contain an azure.yaml file at the root of the default branch.

Add a newly published template

  1. Publish the repository on GitHub with an azd- prefix and a root azure.yaml file.
  2. Give the repository a useful GitHub description and topics so the automatic fallback metadata is meaningful.
  3. Add .azd/catalog.json to the template repository when it needs curated catalog metadata.
  4. Validate the metadata, then run a local website build or request an immediate refresh.

The build regenerates src/generated/solutions.ts from GitHub metadata and rewrites the generated solution guide pages under docs/solutions/. The catalog sync workflow performs the same full discovery after an immediate dispatch and once per day as a fallback.

Repository-owned metadata

Curated metadata normally belongs in the template repository at .azd/catalog.json. This keeps the catalog description and deployment guidance next to the solution they describe. The stable schema is catalog/catalog.schema.json.

Every field is optional, but supplied values are strict: unknown properties, empty strings, duplicate array values, invalid booleans, and non-positive solutionCount values fail generation.

{
"title": "Example workload",
"summary": "One-sentence explanation of what the template deploys.",
"tags": ["Tag One", "Tag Two"],
"highlights": [
"Important selling point",
"Another useful detail"
],
"featured": false,
"solutionCount": 1,
"quickstartCommands": [
"azd init -t nathanmcnulty/azd-example",
"azd up"
]
}

Validate a metadata file from this repository without running discovery:

npm run validate:catalog -- path\to\.azd\catalog.json

Then validate the generated site locally:

npm run build

Editorial overrides

Use catalog/overrides.json only when the website needs to editorially replace repository-owned metadata. Overrides use the same fields plus repoName. Precedence is field-level: a field supplied by the local override replaces that field from .azd/catalog.json; repository-owned fields that are not overridden remain in effect. GitHub descriptions, topics, and generator defaults fill any fields missing from both sources.

{
"repoName": "azd-example",
"featured": true,
"summary": "Website-specific editorial summary."
}

Request an immediate refresh

Template repositories can send a repository_dispatch event to nathanmcnulty/azd-website with event type azd-catalog-updated. The optional payload is validated for logging only; it is never trusted as a local path and does not restrict discovery to one repository.

{
"event_type": "azd-catalog-updated",
"client_payload": {
"repository": "nathanmcnulty/azd-example",
"ref": "main",
"catalogPath": ".azd/catalog.json"
}
}

The source repository needs a fine-grained token or GitHub App token that can call the website repository's dispatch endpoint. Store it as a source-repository secret such as AZD_CATALOG_DISPATCH_TOKEN and grant Contents: read and write access to nathanmcnulty/azd-website. If the dispatch is unavailable or fails, the daily scheduled sync remains the fallback.

The website repository also requires CATALOG_SYNC_TOKEN with Contents: read and write and Pull requests: read and write access so the sync workflow can update automation/sync-catalog and create its pull request under read-only default workflow permissions.

GitHub API notes

The generator uses the public GitHub API. For a small personal catalog, anonymous access is usually fine. If you want a higher rate limit during local builds or CI, set GITHUB_TOKEN before running the build.