feat: integrate azd extensions into awesome-azd gallery#749
feat: integrate azd extensions into awesome-azd gallery#749jongio merged 16 commits intoAzure:mainfrom
Conversation
Add first-class support for azd extensions with: - Templates | Extensions toggle on gallery page - Extension cards with capability badges, version, install copy - Filtering by extension capabilities - Search across extension fields - Dynamic hero (title, description, placeholder) - Automated submission pipeline (issue template + workflow) - Validation script for registry.json - Extensions documentation and contributor guide update - 5 seed extensions (app, copilot, exec, rest, demo) Closes Azure#748 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This pull request integrates azd extensions into the awesome-azd gallery as a first-class content type alongside templates. The PR adds a comprehensive extension discovery and submission system that parallels the existing template infrastructure.
Changes:
- Adds a toggle UI to switch between Templates and Extensions views in the gallery with dynamic hero text, search placeholders, and contextual CTAs
- Implements extension data layer with JSON seed data for 5 extensions, TypeScript types, data loaders, and 6 new capability tags for filtering
- Creates an automated submission pipeline with GitHub issue template, validation workflow, and registry.json validator that automatically creates PRs for new extensions
Reviewed changes
Copilot reviewed 16 out of 22 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
website/static/extensions.json |
Seed data for 5 initial extensions (4 community, 1 Microsoft) |
website/src/data/extensionTypes.ts |
TypeScript type definitions for Extension, ExtensionCapability, and ExtensionPlatform |
website/src/data/extensions.ts |
Data loader with sorting logic mirroring the template pattern |
website/src/data/tags.tsx |
Added 6 extension capability tag types (ext-custom-commands, ext-lifecycle-events, etc.) |
website/src/pages/ShowcaseCardPage.tsx |
Content type toggle, extension filtering, pagination support for both content types |
website/src/pages/ShowcaseExtensionCards.tsx |
Container component for rendering extension card grid |
website/src/components/gallery/ShowcaseExtensionCard/index.tsx |
Extension card component with capability badges, version info, install command copy |
website/src/components/gallery/ShowcaseExtensionCard/styles.module.css |
Styling for extension cards with light/dark theme support |
website/src/components/gallery/ShowcaseTemplateSearch/index.tsx |
Dynamic title, description, and placeholder based on content type |
website/src/components/gallery/ShowcaseLeftFilters/index.tsx |
Added Extension Capabilities filter section |
.github/workflows/extension-submission.yml |
Automated workflow to validate registries and create PRs from issue submissions |
.github/ISSUE_TEMPLATE/extension-submission.yml |
GitHub issue form for extension submissions |
website/scripts/validate-extension.js |
Node.js script to validate registry.json structure, capabilities, semver, and platforms |
website/docs/extensions.md |
New documentation page about azd extensions with installation and submission guides |
website/docs/contribute.md |
Added "Submit an azd Extension" section with submission workflow |
website/test/tags_match.test.ts |
Added 3 test cases for extension validation (tags exist, unique IDs, required fields) |
- Add rel=noopener noreferrer to all target=_blank links in extension card - Fix star icon to be decorative (alt='', aria-hidden) - Add width attributes to images to prevent CLS - Add aria-live=polite to copy confirmation popover - Add focus-visible style for copy button keyboard navigation - Add dark mode support for 'New' badge green color - Remove dead toggleTag function (hooks violation) - Remove unused useCallback import - Fix operator precedence in filter condition - Replace div.clearAll with semantic button element - Add button reset styles (background:none, border:none) - Fix implicit any types on location and clearAll props - Use proper ellipsis character (…) instead of three dots - Remove redundant placeholder on install command input Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add step id 'update' to Update extensions.json step and fix output refs (thread Azure#1) - Add aria-labels to Templates/Extensions toggle buttons (thread Azure#2) - Tighten SEMVER_REGEX to reject trailing dashes in pre-release (thread Azure#3) - Add missing 'community' tag to 4 community extensions (threads Azure#4-7) - Use heredoc syntax for multi-line GITHUB_OUTPUT (thread Azure#8) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
wbreza
left a comment
There was a problem hiding this comment.
This is solid but I do have some questions on the validations and whether we can build those directly into the x extension or somewhere else.
We also likely have a little more work to do before accepting 3rd party contributions.
- CELA review
- Security review
- Indepth code scanning
hemarina
left a comment
There was a problem hiding this comment.
Thank you very much for adding the extension to the gallery. This is awesome! I'm looking forward to seeing it go live.
- Filter sidebar now shows only relevant filters per content type: Templates view: Language, Framework, Services, Database, IaC, Tools, Topic, Authors Extensions view: New/Community/MSFT checkboxes + Extension Capabilities - Removed screenshots/ folder (only needed for PR description) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Adds sync-extension-versions.js script and a scheduled GitHub Action that runs daily at 6 AM UTC. Fetches each extension's registry.json, compares versions, and auto-creates a PR if any changed. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Also picks up microsoft.azd.demo version bump 0.4.0 → 0.5.0. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add concurrency limit (5) for registry fetches in sync script - Use Record<string, string> for type-safe content-type indexing - Remove test-results from tracking, add .gitignore - Add URL validation (http/https only) for user-submitted URLs - Bump peter-evans/create-pull-request from v6 to v7 - Use JSON.stringify for analytics content (prevents quote injection) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Extract getLatestVersion to shared semver-utils.js module - Add pre-release lexicographic comparison for same numeric base - Guard ext.versions iteration with Array.isArray check - Validate data.extensions is array before iterating Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add author filtering to filterExtensions() function - Show Authors sidebar section for both templates and extensions - Compute extension authors dynamically from extensions data - Author filter clears properly when switching content types Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
jongio
left a comment
There was a problem hiding this comment.
Added! The Authors filter now appears in the extensions sidebar too, populated with extension authors. It also supports filtering — selecting an author filters extension cards to only show that author's extensions. Pushed in 808db66.
- Use explicit Location type import from history package - Remove stale getLatestVersion from validate-extension.js exports - Fix extension author filter: pass selectedAuthors (string[]) not selectedUsers (User[]) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Fix CRITICAL: isExtensions used before declaration in ShowcaseLeftFilters (TDZ crash) - Fix HIGH: Add SSRF protection with URL protocol validation in validate-extension.js - Fix MEDIUM: Add 30s fetch timeouts via AbortController in both scripts - Fix MEDIUM: Handle first version entry without .version in getLatestVersion - Add URL protocol validation to sync-extension-versions.js - Add role=group with aria-label to content type toggle - Remove stray tracked files (02-extensions-gallery.png, node_modules/.package-lock.json) - Add *.png to .gitignore Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add role=button, tabIndex, onKeyDown to filter Badge chips for keyboard accessibility - Add aria-label to filter removal badges for screen readers - Add missing width attribute to copy icon img (prevent CLS) - Remove redundant role=button from Fluent UI Button component Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Both jongio.azd.exec and jongio.azd.rest have live GitHub Pages sites but were missing the website field in extensions.json. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Summary
Integrates azd extensions into the awesome-azd gallery as a first-class content type alongside templates. Closes #748.
Screenshots
Templates Gallery (default view with toggle)
Extensions Gallery
Contextual Sidebar Filters (Extensions View)
Extensions Documentation
Updated Contribute Page
Extension Submission Flow
flowchart TD A[Developer builds azd extension] --> B[Creates registry.json<br/>via azd x publish] B --> C{Choose submission method} C -->|GitHub Issue| D[Opens 'Submit an azd Extension' issue] C -->|Manual Trigger| E[Runs workflow_dispatch<br/>from Actions tab] D --> F[Fills form:<br/>Registry URL, Source Repo,<br/>Author, Website] F --> G[Issue created with<br/>extension-submission label] G --> H[GitHub Actions workflow triggers] E --> H H --> I[Checkout repo + Setup Node.js] I --> J[Parse submission fields] J --> K[validate-extension.js<br/>fetches registry.json] K --> L{Validation passes?} L -->|No| M[❌ Comment on issue<br/>with error details] M --> N[Developer fixes and<br/>resubmits] N --> D L -->|Yes| O[Extract extension metadata:<br/>id, displayName, description,<br/>capabilities, version, platforms] O --> P[Update extensions.json<br/>add/update entries] P --> Q[peter-evans/create-pull-request<br/>creates PR automatically] Q --> R[✅ Comment on issue:<br/>PR created successfully] R --> S[Maintainer reviews PR] S --> T{Approved?} T -->|Yes| U[PR merged → Extension<br/>appears in gallery] T -->|No| V[Request changes] V --> S style A fill:#e1f5fe style U fill:#c8e6c9 style M fill:#ffcdd2 style H fill:#fff3e0 style Q fill:#fff3e0What's Changed
Gallery UI
Data Layer
website/static/extensions.jsonΓÇö Seed data for 5 extensionswebsite/src/data/extensionTypes.tsΓÇö TypeScript typeswebsite/src/data/extensions.tsΓÇö Data loader with sortingwebsite/src/data/tags.tsxΓÇö 6 new extension capability tagsAutomated Submission Pipeline
.github/ISSUE_TEMPLATE/extension-submission.ymlΓÇö Issue form for submissions.github/workflows/extension-submission.ymlΓÇö Validates registry.json, updates extensions.json, creates PR automaticallywebsite/scripts/validate-extension.jsΓÇö Registry validation (structure, capabilities, semver, platforms)Documentation
website/docs/extensions.mdΓÇö Extensions overview and submission guidewebsite/docs/contribute.mdΓÇö Added "Submit an azd Extension" sectionSecurity
process.envfor all user-controlled inputs (prevents script injection)Testing
Seed Extensions