Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 116 additions & 0 deletions .github/ISSUE_TEMPLATE/template-submission.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
name: "Submit an azd Template"
description: "Add your azd template to the Awesome azd gallery"
title: "[Template]: "
labels: ["template-submission"]
body:
- type: markdown
attributes:
value: |
Thanks for submitting your azd template! Just provide the repository URL below.
Most fields are **auto-detected** from your repo — only fill them in if you want to override the detected values.

- type: input
id: source-repo
attributes:
label: "Source Repository"
description: "GitHub repository URL for your template (we'll auto-detect the rest!)"
placeholder: "https://github.com/org/repo"
validations:
required: true

- type: input
id: template-title
attributes:
label: "Template Title (optional — auto-detected from repo)"
description: "Override the auto-detected title"
validations:
required: false

- type: textarea
id: description
attributes:
label: "Description (optional — auto-detected from repo)"
description: "Override the auto-detected description"
validations:
required: false

- type: input
id: author
attributes:
label: "Author (optional — auto-detected from repo owner)"
description: "Override the auto-detected author name"
validations:
required: false

- type: input
id: author-url
attributes:
label: "Author URL (optional — auto-detected from repo owner)"
description: "Override the auto-detected author URL"
validations:
required: false

- type: dropdown
id: author-type
attributes:
label: "Author Type (optional — auto-detected)"
description: "Override the auto-detected author type"
options:
- ""
- Community
- Microsoft
validations:
required: false

- type: input
id: preview-image
attributes:
label: "Preview Image URL (optional)"
description: "URL to an architecture diagram or screenshot"
validations:
required: false

- type: dropdown
id: iac-provider
attributes:
label: "IaC Provider (optional — auto-detected from infra/ directory)"
description: "Override the auto-detected IaC provider"
options:
- ""
- Bicep
- Terraform
- Both
validations:
required: false

- type: input
id: languages
attributes:
label: "Languages (optional — auto-detected from repo)"
description: "Comma-separated language tags (e.g., python, javascript)"
validations:
required: false

- type: input
id: frameworks
attributes:
label: "Frameworks (optional)"
description: "Comma-separated framework tags (e.g., reactjs, fastapi)"
validations:
required: false

- type: input
id: azure-services
attributes:
label: "Azure Services (optional — auto-detected from repo topics)"
description: "Comma-separated Azure service tags (e.g., aca, openai)"
validations:
required: false

- type: textarea
id: additional-info
attributes:
label: "Additional Information"
description: "Any additional context about your template (optional)"
validations:
required: false
214 changes: 214 additions & 0 deletions .github/workflows/template-submission.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
name: Template Submission

on:
issues:
types: [opened, labeled]
workflow_dispatch:
inputs:
source_repo:
description: "GitHub repository URL"
required: true
template_title:
description: "Template title (optional - auto-detected)"
required: false
description:
description: "Description (optional - auto-detected)"
required: false
author:
description: "Author name (optional - auto-detected)"
required: false
author_url:
description: "Author GitHub URL (optional - auto-detected)"
required: false
author_type:
description: "Microsoft or Community (optional - auto-detected)"
required: false
default: ""
type: choice
options:
- ""
- Community
- Microsoft
preview_image:
description: "Preview image URL (optional)"
required: false
iac_provider:
description: "IaC provider (optional - auto-detected)"
required: false
default: ""
type: choice
options:
- ""
- Bicep
- Terraform
- Both
languages:
description: "Comma-separated language tags (optional - auto-detected)"
required: false
frameworks:
description: "Comma-separated framework tags (optional)"
required: false
azure_services:
description: "Comma-separated Azure service tags (optional - auto-detected)"
required: false

permissions:
contents: write
pull-requests: write
issues: write

concurrency:
group: template-submission
cancel-in-progress: false

jobs:
process-template:
if: >-
github.event_name == 'workflow_dispatch' ||
contains(github.event.issue.labels.*.name, 'template-submission')
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@eca02f6b962f33b848cbe9e9f4dd5d23a0b61747 # v6

- name: Setup Node.js
uses: actions/setup-node@53b83942660f83e34d4f35ba9a3125d67d943f4c # v6
with:
node-version: "24"

- name: Parse issue body
id: parse
env:
GITHUB_EVENT_NAME: ${{ github.event_name }}
ISSUE_BODY: ${{ github.event.issue.body || '' }}
INPUT_SOURCE_REPO: ${{ inputs.source_repo }}
INPUT_TEMPLATE_TITLE: ${{ inputs.template_title }}
INPUT_DESCRIPTION: ${{ inputs.description }}
INPUT_AUTHOR: ${{ inputs.author }}
INPUT_AUTHOR_URL: ${{ inputs.author_url }}
INPUT_AUTHOR_TYPE: ${{ inputs.author_type }}
INPUT_PREVIEW_IMAGE: ${{ inputs.preview_image }}
INPUT_IAC_PROVIDER: ${{ inputs.iac_provider }}
INPUT_LANGUAGES: ${{ inputs.languages }}
INPUT_FRAMEWORKS: ${{ inputs.frameworks }}
INPUT_AZURE_SERVICES: ${{ inputs.azure_services }}
run: node website/scripts/parse-template-issue.js

- name: Install extraction dependencies
run: cd website && npm ci --ignore-scripts

- name: Auto-extract metadata from repository
id: extract
env:
SOURCE_REPO: ${{ steps.parse.outputs.source_repo }}
FORM_TITLE: ${{ steps.parse.outputs.template_title }}
FORM_DESCRIPTION: ${{ steps.parse.outputs.description }}
FORM_AUTHOR: ${{ steps.parse.outputs.author }}
FORM_AUTHOR_URL: ${{ steps.parse.outputs.author_url }}
FORM_AUTHOR_TYPE: ${{ steps.parse.outputs.author_type }}
FORM_IAC_PROVIDER: ${{ steps.parse.outputs.iac_provider }}
FORM_LANGUAGES: ${{ steps.parse.outputs.languages }}
FORM_FRAMEWORKS: ${{ steps.parse.outputs.frameworks }}
FORM_AZURE_SERVICES: ${{ steps.parse.outputs.azure_services }}
FORM_PREVIEW_IMAGE: ${{ steps.parse.outputs.preview_image }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: node website/scripts/merge-extracted-metadata.js

- name: Validate template repository
id: validate
env:
SOURCE_REPO: ${{ steps.extract.outputs.source_repo }}
run: |
node website/scripts/validate-template.js "$SOURCE_REPO" > validation_result.json 2>validation_errors.log
if [ $? -ne 0 ]; then
echo "valid=false" >> $GITHUB_OUTPUT
{
echo 'errors<<EOF'
cat validation_result.json validation_errors.log
echo 'EOF'
} >> $GITHUB_OUTPUT
else
echo "valid=true" >> $GITHUB_OUTPUT
fi

- name: Comment on validation failure
if: steps.validate.outputs.valid == 'false' && github.event_name != 'workflow_dispatch'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ERRORS: ${{ steps.validate.outputs.errors }}
ISSUE_NUMBER: ${{ github.event.issue.number }}
run: |
gh issue comment "$ISSUE_NUMBER" \
--repo "$GITHUB_REPOSITORY" \
--body "❌ **Template validation failed**

Please check your repository URL and try again.

\`\`\`
$ERRORS
\`\`\`"

- name: Update templates.json
id: update
if: steps.validate.outputs.valid == 'true'
env:
TPL_SOURCE_REPO: ${{ steps.extract.outputs.source_repo }}
TPL_TITLE: ${{ steps.extract.outputs.template_title }}
TPL_DESCRIPTION: ${{ steps.extract.outputs.description }}
TPL_AUTHOR: ${{ steps.extract.outputs.author }}
TPL_AUTHOR_URL: ${{ steps.extract.outputs.author_url }}
TPL_AUTHOR_TYPE: ${{ steps.extract.outputs.author_type }}
TPL_PREVIEW_IMAGE: ${{ steps.extract.outputs.preview_image }}
TPL_IAC_PROVIDER: ${{ steps.extract.outputs.iac_provider }}
TPL_LANGUAGES: ${{ steps.extract.outputs.languages }}
TPL_FRAMEWORKS: ${{ steps.extract.outputs.frameworks }}
TPL_AZURE_SERVICES: ${{ steps.extract.outputs.azure_services }}
run: node website/scripts/update-templates-json.js

- name: Create Pull Request
id: create-pr
if: steps.validate.outputs.valid == 'true' && steps.update.outputs.skipped != 'true'
uses: peter-evans/create-pull-request@e0fcfd740c5df573cb2b99ba5cf7bd41528dd2b3 # v8
with:
token: ${{ secrets.GITHUB_TOKEN }}
commit-message: "Add template from ${{ github.event_name == 'workflow_dispatch' && 'manual dispatch' || format('issue #{0}', github.event.issue.number) }}"
branch: "template-submission-${{ github.event_name == 'workflow_dispatch' && github.run_id || github.event.issue.number }}"
title: "Add template: ${{ steps.extract.outputs.template_title }}"
body: |
This PR was automatically generated${{ github.event_name != 'workflow_dispatch' && format(' from issue #{0}', github.event.issue.number) || '' }}.

**Source Repository**: ${{ steps.extract.outputs.source_repo }}
**Title**: ${{ steps.extract.outputs.template_title }}
**Author**: ${{ steps.extract.outputs.author }}
**IaC**: ${{ steps.extract.outputs.iac_provider }}
**Added**: ${{ steps.update.outputs.added || 'None' }}

Please review the changes to `website/static/templates.json`.
labels: template-submission

- name: Comment on success
if: steps.validate.outputs.valid == 'true' && steps.update.outputs.skipped != 'true' && github.event_name != 'workflow_dispatch'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ISSUE_NUMBER: ${{ github.event.issue.number }}
run: |
gh issue comment "$ISSUE_NUMBER" \
--repo "$GITHUB_REPOSITORY" \
--body "✅ **Template validated successfully!**

A pull request has been created to add your template to the gallery. It will be reviewed by the maintainers shortly."

- name: Comment on duplicate
if: steps.update.outputs.skipped == 'true' && github.event_name != 'workflow_dispatch'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SKIP_REASON: ${{ steps.update.outputs.skip_reason }}
ISSUE_NUMBER: ${{ github.event.issue.number }}
run: |
gh issue comment "$ISSUE_NUMBER" \
--repo "$GITHUB_REPOSITORY" \
--body "⚠️ **Template submission skipped**

$SKIP_REASON

If you believe this is an error, please comment on this issue."
8 changes: 8 additions & 0 deletions website/docs/contribute.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,14 @@ If you would like to contribute a template but are not sure where to start, [mak
2. Add Bicep files
3. Update azure.yaml

### Automated Template Submission

For a faster submission experience, use the automated pipeline:

1. **[Submit a template issue](https://github.com/Azure/awesome-azd/issues/new?template=template-submission.yml)** — Fill out the form with your template details
2. **Automatic validation** — A workflow validates your repository and creates a PR automatically
3. **Review & merge** — A maintainer reviews and approves the PR

### [Submit a Resource](https://github.com/Azure/awesome-azd/compare)
Did you write or find an article that helped you get started with `azd`? Or maybe you created or found a video that showed you how to create an azd template? Whatever the resource might be, we would love for you to share it with our community! Submit content you think should be included in `awesome-azd/README.md`

Expand Down
5 changes: 4 additions & 1 deletion website/jest.config.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
module.exports = {
testMatch: ['<rootDir>/test/**/*.test.ts']
testMatch: ['<rootDir>/test/**/*.test.ts'],
transformIgnorePatterns: [
'node_modules/(?!@babel/runtime/helpers/esm)'
]
};
Loading
Loading