diff --git a/.github/workflows/template_techdocs_monorepo.yml b/.github/workflows/template_techdocs_monorepo.yml
new file mode 100644
index 00000000..cf78999c
--- /dev/null
+++ b/.github/workflows/template_techdocs_monorepo.yml
@@ -0,0 +1,76 @@
+name: TechDocs
+
+on:
+ workflow_call:
+ secrets:
+ azure-account-name:
+ required: true
+ azure-account-key:
+ required: true
+jobs:
+ techdocs:
+ name: TechDocs
+ runs-on: ubuntu-24.04
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4.2.2
+
+ - name: Setup Node
+ uses: actions/setup-node@v4.2.0
+
+ - name: Setup Python
+ uses: actions/setup-python@v5.5.0
+ with:
+ python-version: "3.12"
+
+ - name: Install techdocs-cli
+ run: sudo npm install -g @techdocs/cli
+
+ - name: Install mkdocs and mkdocs plugins
+ run: |
+ python -m pip install mkdocs-techdocs-core==1.* mkdocs-awesome-pages-plugin==2.* mkdocs-awesome-nav==3.0.0
+
+ - name: Generate and Publish TechDocs
+ run: |
+ find . -name "catalog-info.yaml" -print0 | while read -r -d $'\0' file
+ do
+ echo ""
+ echo "Working on $file"
+ i="0"
+ while true; do
+ idx=$i
+ i=$((i+1))
+
+ # .kind is mandatory and can be used to check whether there is another document
+ kind=$(yq e "select(documentIndex == $idx) | .kind" "$file")
+ if [ -z "$kind" ]; then
+ break
+ fi
+
+ name=$(yq e "select(documentIndex == $idx) | .metadata.name" "$file")
+ # Only process documents with techdocs-ref annotation
+ techDocsConfigured=$(yq e "select(documentIndex == $idx) | .metadata.annotations | has(\"backstage.io/techdocs-ref\")" "$file")
+ if [ "$techDocsConfigured" == false ]; then
+ echo " 😥 Skip $kind/$name - TechDocs not configured"
+ continue
+ fi
+
+ echo " 📝 Publish TechDocs for $kind/$name"
+
+ fileDir=$(find "$file" -printf '%h' -quit)
+ techdocs-cli generate \
+ --no-docker \
+ --verbose \
+ --source-dir=$fileDir \
+ --output-dir=$fileDir/site/ 1>/dev/null
+
+ techdocs-cli publish \
+ --directory=$fileDir/site/ \
+ --publisher-type azureBlobStorage \
+ --storage-name techdocs \
+ --azureAccountName ${{ secrets.azure-account-name }} \
+ --azureAccountKey ${{ secrets.azure-account-key }} \
+ --entity default/$kind/$name 1>/dev/null
+ done
+ done
diff --git a/README.md b/README.md
index d2076e08..21b199ba 100644
--- a/README.md
+++ b/README.md
@@ -456,6 +456,35 @@ jobs:
+### TechDocs Monorepo (Azure)
+
+
+This GitHub Action can be used for generating and publishing Backstage TechDocs for a monorepo. It is limited to an Azure Storage account.
+
+```yml
+name: TechDocs
+
+on:
+ push:
+ branches:
+ - 'main'
+ paths:
+ - "docs/**"
+ - "mkdocs.yml"
+ - ".github/workflows/techdocs.yaml"
+
+jobs:
+ techdocs:
+ uses: Staffbase/gha-workflows/.github/workflows/template_techdocs_monorepo.yml@v7.2.0
+ secrets:
+ # required: specifies an Azure Storage account name
+ azure-account-name: ${{ secrets.TECHDOCS_AZURE_ACCOUNT_NAME }}
+ # required: specifies the access key associated with the storage account
+ azure-account-key: ${{ secrets.TECHDOCS_AZURE_ACCESS_KEY }}
+```
+
+
+
### TechDocs