feat: Add Official Microsoft & Gemini Skills (845+ Total)
🚀 Impact Significantly expands the capabilities of **Antigravity Awesome Skills** by integrating official skill collections from **Microsoft** and **Google Gemini**. This update increases the total skill count to **845+**, making the library even more comprehensive for AI coding assistants. ✨ Key Changes 1. New Official Skills - **Microsoft Skills**: Added a massive collection of official skills from [microsoft/skills](https://github.com/microsoft/skills). - Includes Azure, .NET, Python, TypeScript, and Semantic Kernel skills. - Preserves the original directory structure under `skills/official/microsoft/`. - Includes plugin skills from the `.github/plugins` directory. - **Gemini Skills**: Added official Gemini API development skills under `skills/gemini-api-dev/`. 2. New Scripts & Tooling - **`scripts/sync_microsoft_skills.py`**: A robust synchronization script that: - Clones the official Microsoft repository. - Preserves the original directory heirarchy. - Handles symlinks and plugin locations. - Generates attribution metadata. - **`scripts/tests/inspect_microsoft_repo.py`**: Debug tool to inspect the remote repository structure. - **`scripts/tests/test_comprehensive_coverage.py`**: Verification script to ensure 100% of skills are captured during sync. 3. Core Improvements - **`scripts/generate_index.py`**: Enhanced frontmatter parsing to safely handle unquoted values containing `@` symbols and commas (fixing issues with some Microsoft skill descriptions). - **`package.json`**: Added `sync:microsoft` and `sync:all-official` scripts for easy maintenance. 4. Documentation - Updated `README.md` to reflect the new skill counts (845+) and added Microsoft/Gemini to the provider list. - Updated `CATALOG.md` and `skills_index.json` with the new skills. 🧪 Verification - Ran `scripts/tests/test_comprehensive_coverage.py` to verify all Microsoft skills are detected. - Validated `generate_index.py` fixes by successfully indexing the new skills.
This commit is contained in:
334
skills/official/microsoft/dotnet/compute/botservice/SKILL.md
Normal file
334
skills/official/microsoft/dotnet/compute/botservice/SKILL.md
Normal file
@@ -0,0 +1,334 @@
|
||||
---
|
||||
name: azure-mgmt-botservice-dotnet
|
||||
description: |
|
||||
Azure Resource Manager SDK for Bot Service in .NET. Management plane operations for creating and managing Azure Bot resources, channels (Teams, DirectLine, Slack), and connection settings. Triggers: "Bot Service", "BotResource", "Azure Bot", "DirectLine channel", "Teams channel", "bot management .NET", "create bot".
|
||||
package: Azure.ResourceManager.BotService
|
||||
---
|
||||
|
||||
# Azure.ResourceManager.BotService (.NET)
|
||||
|
||||
Management plane SDK for provisioning and managing Azure Bot Service resources via Azure Resource Manager.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
dotnet add package Azure.ResourceManager.BotService
|
||||
dotnet add package Azure.Identity
|
||||
```
|
||||
|
||||
**Current Versions**: Stable v1.1.1, Preview v1.1.0-beta.1
|
||||
|
||||
## Environment Variables
|
||||
|
||||
```bash
|
||||
AZURE_SUBSCRIPTION_ID=<your-subscription-id>
|
||||
# For service principal auth (optional)
|
||||
AZURE_TENANT_ID=<tenant-id>
|
||||
AZURE_CLIENT_ID=<client-id>
|
||||
AZURE_CLIENT_SECRET=<client-secret>
|
||||
```
|
||||
|
||||
## Authentication
|
||||
|
||||
```csharp
|
||||
using Azure.Identity;
|
||||
using Azure.ResourceManager;
|
||||
using Azure.ResourceManager.BotService;
|
||||
|
||||
// Authenticate using DefaultAzureCredential
|
||||
var credential = new DefaultAzureCredential();
|
||||
ArmClient armClient = new ArmClient(credential);
|
||||
|
||||
// Get subscription and resource group
|
||||
SubscriptionResource subscription = await armClient.GetDefaultSubscriptionAsync();
|
||||
ResourceGroupResource resourceGroup = await subscription.GetResourceGroups().GetAsync("myResourceGroup");
|
||||
|
||||
// Access bot collection
|
||||
BotCollection botCollection = resourceGroup.GetBots();
|
||||
```
|
||||
|
||||
## Resource Hierarchy
|
||||
|
||||
```
|
||||
ArmClient
|
||||
└── SubscriptionResource
|
||||
└── ResourceGroupResource
|
||||
└── BotResource
|
||||
├── BotChannelResource (DirectLine, Teams, Slack, etc.)
|
||||
├── BotConnectionSettingResource (OAuth connections)
|
||||
└── BotServicePrivateEndpointConnectionResource
|
||||
```
|
||||
|
||||
## Core Workflows
|
||||
|
||||
### 1. Create Bot Resource
|
||||
|
||||
```csharp
|
||||
using Azure.ResourceManager.BotService;
|
||||
using Azure.ResourceManager.BotService.Models;
|
||||
|
||||
// Create bot data
|
||||
var botData = new BotData(AzureLocation.WestUS2)
|
||||
{
|
||||
Kind = BotServiceKind.Azurebot,
|
||||
Sku = new BotServiceSku(BotServiceSkuName.F0),
|
||||
Properties = new BotProperties(
|
||||
displayName: "MyBot",
|
||||
endpoint: new Uri("https://mybot.azurewebsites.net/api/messages"),
|
||||
msaAppId: "<your-msa-app-id>")
|
||||
{
|
||||
Description = "My Azure Bot",
|
||||
MsaAppType = BotMsaAppType.MultiTenant
|
||||
}
|
||||
};
|
||||
|
||||
// Create or update the bot
|
||||
ArmOperation<BotResource> operation = await botCollection.CreateOrUpdateAsync(
|
||||
WaitUntil.Completed,
|
||||
"myBotName",
|
||||
botData);
|
||||
|
||||
BotResource bot = operation.Value;
|
||||
Console.WriteLine($"Bot created: {bot.Data.Name}");
|
||||
```
|
||||
|
||||
### 2. Configure DirectLine Channel
|
||||
|
||||
```csharp
|
||||
// Get the bot
|
||||
BotResource bot = await resourceGroup.GetBots().GetAsync("myBotName");
|
||||
|
||||
// Get channel collection
|
||||
BotChannelCollection channels = bot.GetBotChannels();
|
||||
|
||||
// Create DirectLine channel configuration
|
||||
var channelData = new BotChannelData(AzureLocation.WestUS2)
|
||||
{
|
||||
Properties = new DirectLineChannel()
|
||||
{
|
||||
Properties = new DirectLineChannelProperties()
|
||||
{
|
||||
Sites =
|
||||
{
|
||||
new DirectLineSite("Default Site")
|
||||
{
|
||||
IsEnabled = true,
|
||||
IsV1Enabled = false,
|
||||
IsV3Enabled = true,
|
||||
IsSecureSiteEnabled = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Create or update the channel
|
||||
ArmOperation<BotChannelResource> channelOp = await channels.CreateOrUpdateAsync(
|
||||
WaitUntil.Completed,
|
||||
BotChannelName.DirectLineChannel,
|
||||
channelData);
|
||||
|
||||
Console.WriteLine("DirectLine channel configured");
|
||||
```
|
||||
|
||||
### 3. Configure Microsoft Teams Channel
|
||||
|
||||
```csharp
|
||||
var teamsChannelData = new BotChannelData(AzureLocation.WestUS2)
|
||||
{
|
||||
Properties = new MsTeamsChannel()
|
||||
{
|
||||
Properties = new MsTeamsChannelProperties()
|
||||
{
|
||||
IsEnabled = true,
|
||||
EnableCalling = false
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
await channels.CreateOrUpdateAsync(
|
||||
WaitUntil.Completed,
|
||||
BotChannelName.MsTeamsChannel,
|
||||
teamsChannelData);
|
||||
```
|
||||
|
||||
### 4. Configure Web Chat Channel
|
||||
|
||||
```csharp
|
||||
var webChatChannelData = new BotChannelData(AzureLocation.WestUS2)
|
||||
{
|
||||
Properties = new WebChatChannel()
|
||||
{
|
||||
Properties = new WebChatChannelProperties()
|
||||
{
|
||||
Sites =
|
||||
{
|
||||
new WebChatSite("Default Site")
|
||||
{
|
||||
IsEnabled = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
await channels.CreateOrUpdateAsync(
|
||||
WaitUntil.Completed,
|
||||
BotChannelName.WebChatChannel,
|
||||
webChatChannelData);
|
||||
```
|
||||
|
||||
### 5. Get Bot and List Channels
|
||||
|
||||
```csharp
|
||||
// Get bot
|
||||
BotResource bot = await botCollection.GetAsync("myBotName");
|
||||
Console.WriteLine($"Bot: {bot.Data.Properties.DisplayName}");
|
||||
Console.WriteLine($"Endpoint: {bot.Data.Properties.Endpoint}");
|
||||
|
||||
// List channels
|
||||
await foreach (BotChannelResource channel in bot.GetBotChannels().GetAllAsync())
|
||||
{
|
||||
Console.WriteLine($"Channel: {channel.Data.Name}");
|
||||
}
|
||||
```
|
||||
|
||||
### 6. Regenerate DirectLine Keys
|
||||
|
||||
```csharp
|
||||
var regenerateRequest = new BotChannelRegenerateKeysContent(BotChannelName.DirectLineChannel)
|
||||
{
|
||||
SiteName = "Default Site"
|
||||
};
|
||||
|
||||
BotChannelResource channelWithKeys = await bot.GetBotChannelWithRegenerateKeysAsync(regenerateRequest);
|
||||
```
|
||||
|
||||
### 7. Update Bot
|
||||
|
||||
```csharp
|
||||
BotResource bot = await botCollection.GetAsync("myBotName");
|
||||
|
||||
// Update using patch
|
||||
var updateData = new BotData(bot.Data.Location)
|
||||
{
|
||||
Properties = new BotProperties(
|
||||
displayName: "Updated Bot Name",
|
||||
endpoint: bot.Data.Properties.Endpoint,
|
||||
msaAppId: bot.Data.Properties.MsaAppId)
|
||||
{
|
||||
Description = "Updated description"
|
||||
}
|
||||
};
|
||||
|
||||
await bot.UpdateAsync(updateData);
|
||||
```
|
||||
|
||||
### 8. Delete Bot
|
||||
|
||||
```csharp
|
||||
BotResource bot = await botCollection.GetAsync("myBotName");
|
||||
await bot.DeleteAsync(WaitUntil.Completed);
|
||||
```
|
||||
|
||||
## Supported Channel Types
|
||||
|
||||
| Channel | Constant | Class |
|
||||
|---------|----------|-------|
|
||||
| Direct Line | `BotChannelName.DirectLineChannel` | `DirectLineChannel` |
|
||||
| Direct Line Speech | `BotChannelName.DirectLineSpeechChannel` | `DirectLineSpeechChannel` |
|
||||
| Microsoft Teams | `BotChannelName.MsTeamsChannel` | `MsTeamsChannel` |
|
||||
| Web Chat | `BotChannelName.WebChatChannel` | `WebChatChannel` |
|
||||
| Slack | `BotChannelName.SlackChannel` | `SlackChannel` |
|
||||
| Facebook | `BotChannelName.FacebookChannel` | `FacebookChannel` |
|
||||
| Email | `BotChannelName.EmailChannel` | `EmailChannel` |
|
||||
| Telegram | `BotChannelName.TelegramChannel` | `TelegramChannel` |
|
||||
| Telephony | `BotChannelName.TelephonyChannel` | `TelephonyChannel` |
|
||||
|
||||
## Key Types Reference
|
||||
|
||||
| Type | Purpose |
|
||||
|------|---------|
|
||||
| `ArmClient` | Entry point for all ARM operations |
|
||||
| `BotResource` | Represents an Azure Bot resource |
|
||||
| `BotCollection` | Collection for bot CRUD |
|
||||
| `BotData` | Bot resource definition |
|
||||
| `BotProperties` | Bot configuration properties |
|
||||
| `BotChannelResource` | Channel configuration |
|
||||
| `BotChannelCollection` | Collection of channels |
|
||||
| `BotChannelData` | Channel configuration data |
|
||||
| `BotConnectionSettingResource` | OAuth connection settings |
|
||||
|
||||
## BotServiceKind Values
|
||||
|
||||
| Value | Description |
|
||||
|-------|-------------|
|
||||
| `BotServiceKind.Azurebot` | Azure Bot (recommended) |
|
||||
| `BotServiceKind.Bot` | Legacy Bot Framework bot |
|
||||
| `BotServiceKind.Designer` | Composer bot |
|
||||
| `BotServiceKind.Function` | Function bot |
|
||||
| `BotServiceKind.Sdk` | SDK bot |
|
||||
|
||||
## BotServiceSkuName Values
|
||||
|
||||
| Value | Description |
|
||||
|-------|-------------|
|
||||
| `BotServiceSkuName.F0` | Free tier |
|
||||
| `BotServiceSkuName.S1` | Standard tier |
|
||||
|
||||
## BotMsaAppType Values
|
||||
|
||||
| Value | Description |
|
||||
|-------|-------------|
|
||||
| `BotMsaAppType.MultiTenant` | Multi-tenant app |
|
||||
| `BotMsaAppType.SingleTenant` | Single-tenant app |
|
||||
| `BotMsaAppType.UserAssignedMSI` | User-assigned managed identity |
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Always use `DefaultAzureCredential`** — supports multiple auth methods
|
||||
2. **Use `WaitUntil.Completed`** for synchronous operations
|
||||
3. **Handle `RequestFailedException`** for API errors
|
||||
4. **Use async methods** (`*Async`) for all operations
|
||||
5. **Store MSA App credentials securely** — use Key Vault for secrets
|
||||
6. **Use managed identity** (`BotMsaAppType.UserAssignedMSI`) for production bots
|
||||
7. **Enable secure sites** for DirectLine channels in production
|
||||
|
||||
## Error Handling
|
||||
|
||||
```csharp
|
||||
using Azure;
|
||||
|
||||
try
|
||||
{
|
||||
var operation = await botCollection.CreateOrUpdateAsync(
|
||||
WaitUntil.Completed,
|
||||
botName,
|
||||
botData);
|
||||
}
|
||||
catch (RequestFailedException ex) when (ex.Status == 409)
|
||||
{
|
||||
Console.WriteLine("Bot already exists");
|
||||
}
|
||||
catch (RequestFailedException ex)
|
||||
{
|
||||
Console.WriteLine($"ARM Error: {ex.Status} - {ex.ErrorCode}: {ex.Message}");
|
||||
}
|
||||
```
|
||||
|
||||
## Related SDKs
|
||||
|
||||
| SDK | Purpose | Install |
|
||||
|-----|---------|---------|
|
||||
| `Azure.ResourceManager.BotService` | Bot management (this SDK) | `dotnet add package Azure.ResourceManager.BotService` |
|
||||
| `Microsoft.Bot.Builder` | Bot Framework SDK | `dotnet add package Microsoft.Bot.Builder` |
|
||||
| `Microsoft.Bot.Builder.Integration.AspNet.Core` | ASP.NET Core integration | `dotnet add package Microsoft.Bot.Builder.Integration.AspNet.Core` |
|
||||
|
||||
## Reference Links
|
||||
|
||||
| Resource | URL |
|
||||
|----------|-----|
|
||||
| NuGet Package | https://www.nuget.org/packages/Azure.ResourceManager.BotService |
|
||||
| API Reference | https://learn.microsoft.com/dotnet/api/azure.resourcemanager.botservice |
|
||||
| GitHub Source | https://github.com/Azure/azure-sdk-for-net/tree/main/sdk/botservice/Azure.ResourceManager.BotService |
|
||||
| Azure Bot Service Docs | https://learn.microsoft.com/azure/bot-service/ |
|
||||
377
skills/official/microsoft/dotnet/compute/durabletask/SKILL.md
Normal file
377
skills/official/microsoft/dotnet/compute/durabletask/SKILL.md
Normal file
@@ -0,0 +1,377 @@
|
||||
---
|
||||
name: azure-resource-manager-durabletask-dotnet
|
||||
description: |
|
||||
Azure Resource Manager SDK for Durable Task Scheduler in .NET. Use for MANAGEMENT PLANE operations: creating/managing Durable Task Schedulers, Task Hubs, and retention policies via Azure Resource Manager. Triggers: "Durable Task Scheduler", "create scheduler", "task hub", "DurableTaskSchedulerResource", "provision Durable Task", "orchestration scheduler".
|
||||
package: Azure.ResourceManager.DurableTask
|
||||
---
|
||||
|
||||
# Azure.ResourceManager.DurableTask (.NET)
|
||||
|
||||
Management plane SDK for provisioning and managing Azure Durable Task Scheduler resources via Azure Resource Manager.
|
||||
|
||||
> **⚠️ Management vs Data Plane**
|
||||
> - **This SDK (Azure.ResourceManager.DurableTask)**: Create schedulers, task hubs, configure retention policies
|
||||
> - **Data Plane SDK (Microsoft.DurableTask.Client.AzureManaged)**: Start orchestrations, query instances, send events
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
dotnet add package Azure.ResourceManager.DurableTask
|
||||
dotnet add package Azure.Identity
|
||||
```
|
||||
|
||||
**Current Versions**: Stable v1.0.0 (2025-11-03), Preview v1.0.0-beta.1 (2025-04-24)
|
||||
**API Version**: 2025-11-01
|
||||
|
||||
## Environment Variables
|
||||
|
||||
```bash
|
||||
AZURE_SUBSCRIPTION_ID=<your-subscription-id>
|
||||
AZURE_RESOURCE_GROUP=<your-resource-group>
|
||||
# For service principal auth (optional)
|
||||
AZURE_TENANT_ID=<tenant-id>
|
||||
AZURE_CLIENT_ID=<client-id>
|
||||
AZURE_CLIENT_SECRET=<client-secret>
|
||||
```
|
||||
|
||||
## Authentication
|
||||
|
||||
```csharp
|
||||
using Azure.Identity;
|
||||
using Azure.ResourceManager;
|
||||
using Azure.ResourceManager.DurableTask;
|
||||
|
||||
// Always use DefaultAzureCredential
|
||||
var credential = new DefaultAzureCredential();
|
||||
var armClient = new ArmClient(credential);
|
||||
|
||||
// Get subscription
|
||||
var subscriptionId = Environment.GetEnvironmentVariable("AZURE_SUBSCRIPTION_ID");
|
||||
var subscription = armClient.GetSubscriptionResource(
|
||||
new ResourceIdentifier($"/subscriptions/{subscriptionId}"));
|
||||
```
|
||||
|
||||
## Resource Hierarchy
|
||||
|
||||
```
|
||||
ArmClient
|
||||
└── SubscriptionResource
|
||||
└── ResourceGroupResource
|
||||
└── DurableTaskSchedulerResource
|
||||
├── DurableTaskHubResource
|
||||
└── DurableTaskRetentionPolicyResource
|
||||
```
|
||||
|
||||
## Core Workflow
|
||||
|
||||
### 1. Create Durable Task Scheduler
|
||||
|
||||
```csharp
|
||||
using Azure.ResourceManager.DurableTask;
|
||||
using Azure.ResourceManager.DurableTask.Models;
|
||||
|
||||
// Get resource group
|
||||
var resourceGroup = await subscription
|
||||
.GetResourceGroupAsync("my-resource-group");
|
||||
|
||||
// Define scheduler with Dedicated SKU
|
||||
var schedulerData = new DurableTaskSchedulerData(AzureLocation.EastUS)
|
||||
{
|
||||
Properties = new DurableTaskSchedulerProperties
|
||||
{
|
||||
Sku = new DurableTaskSchedulerSku(DurableTaskSchedulerSkuName.Dedicated)
|
||||
{
|
||||
Capacity = 1 // Number of instances
|
||||
},
|
||||
// Optional: IP allowlist for network security
|
||||
IPAllowlist = { "10.0.0.0/24", "192.168.1.0/24" }
|
||||
}
|
||||
};
|
||||
|
||||
// Create scheduler (long-running operation)
|
||||
var schedulerCollection = resourceGroup.Value.GetDurableTaskSchedulers();
|
||||
var operation = await schedulerCollection.CreateOrUpdateAsync(
|
||||
WaitUntil.Completed,
|
||||
"my-scheduler",
|
||||
schedulerData);
|
||||
|
||||
DurableTaskSchedulerResource scheduler = operation.Value;
|
||||
Console.WriteLine($"Scheduler created: {scheduler.Data.Name}");
|
||||
Console.WriteLine($"Endpoint: {scheduler.Data.Properties.Endpoint}");
|
||||
```
|
||||
|
||||
### 2. Create Scheduler with Consumption SKU
|
||||
|
||||
```csharp
|
||||
// Consumption SKU (serverless)
|
||||
var consumptionSchedulerData = new DurableTaskSchedulerData(AzureLocation.EastUS)
|
||||
{
|
||||
Properties = new DurableTaskSchedulerProperties
|
||||
{
|
||||
Sku = new DurableTaskSchedulerSku(DurableTaskSchedulerSkuName.Consumption)
|
||||
// No capacity needed for consumption
|
||||
}
|
||||
};
|
||||
|
||||
var operation = await schedulerCollection.CreateOrUpdateAsync(
|
||||
WaitUntil.Completed,
|
||||
"my-serverless-scheduler",
|
||||
consumptionSchedulerData);
|
||||
```
|
||||
|
||||
### 3. Create Task Hub
|
||||
|
||||
```csharp
|
||||
// Task hubs are created under a scheduler
|
||||
var taskHubData = new DurableTaskHubData
|
||||
{
|
||||
// Properties are optional for basic task hub
|
||||
};
|
||||
|
||||
var taskHubCollection = scheduler.GetDurableTaskHubs();
|
||||
var hubOperation = await taskHubCollection.CreateOrUpdateAsync(
|
||||
WaitUntil.Completed,
|
||||
"my-taskhub",
|
||||
taskHubData);
|
||||
|
||||
DurableTaskHubResource taskHub = hubOperation.Value;
|
||||
Console.WriteLine($"Task Hub created: {taskHub.Data.Name}");
|
||||
```
|
||||
|
||||
### 4. List Schedulers
|
||||
|
||||
```csharp
|
||||
// List all schedulers in subscription
|
||||
await foreach (var sched in subscription.GetDurableTaskSchedulersAsync())
|
||||
{
|
||||
Console.WriteLine($"Scheduler: {sched.Data.Name}");
|
||||
Console.WriteLine($" Location: {sched.Data.Location}");
|
||||
Console.WriteLine($" SKU: {sched.Data.Properties.Sku?.Name}");
|
||||
Console.WriteLine($" Endpoint: {sched.Data.Properties.Endpoint}");
|
||||
}
|
||||
|
||||
// List schedulers in resource group
|
||||
var schedulers = resourceGroup.Value.GetDurableTaskSchedulers();
|
||||
await foreach (var sched in schedulers.GetAllAsync())
|
||||
{
|
||||
Console.WriteLine($"Scheduler: {sched.Data.Name}");
|
||||
}
|
||||
```
|
||||
|
||||
### 5. Get Scheduler by Name
|
||||
|
||||
```csharp
|
||||
// Get existing scheduler
|
||||
var existingScheduler = await schedulerCollection.GetAsync("my-scheduler");
|
||||
Console.WriteLine($"Found: {existingScheduler.Value.Data.Name}");
|
||||
|
||||
// Or use extension method
|
||||
var schedulerResource = armClient.GetDurableTaskSchedulerResource(
|
||||
DurableTaskSchedulerResource.CreateResourceIdentifier(
|
||||
subscriptionId,
|
||||
"my-resource-group",
|
||||
"my-scheduler"));
|
||||
var scheduler = await schedulerResource.GetAsync();
|
||||
```
|
||||
|
||||
### 6. Update Scheduler
|
||||
|
||||
```csharp
|
||||
// Get current scheduler
|
||||
var scheduler = await schedulerCollection.GetAsync("my-scheduler");
|
||||
|
||||
// Update with new configuration
|
||||
var updateData = new DurableTaskSchedulerData(scheduler.Value.Data.Location)
|
||||
{
|
||||
Properties = new DurableTaskSchedulerProperties
|
||||
{
|
||||
Sku = new DurableTaskSchedulerSku(DurableTaskSchedulerSkuName.Dedicated)
|
||||
{
|
||||
Capacity = 2 // Scale up
|
||||
},
|
||||
IPAllowlist = { "10.0.0.0/16" } // Update IP allowlist
|
||||
}
|
||||
};
|
||||
|
||||
var updateOperation = await schedulerCollection.CreateOrUpdateAsync(
|
||||
WaitUntil.Completed,
|
||||
"my-scheduler",
|
||||
updateData);
|
||||
```
|
||||
|
||||
### 7. Delete Resources
|
||||
|
||||
```csharp
|
||||
// Delete task hub first
|
||||
var taskHub = await scheduler.GetDurableTaskHubs().GetAsync("my-taskhub");
|
||||
await taskHub.Value.DeleteAsync(WaitUntil.Completed);
|
||||
|
||||
// Then delete scheduler
|
||||
await scheduler.DeleteAsync(WaitUntil.Completed);
|
||||
```
|
||||
|
||||
### 8. Manage Retention Policies
|
||||
|
||||
```csharp
|
||||
// Get retention policy collection
|
||||
var retentionPolicies = scheduler.GetDurableTaskRetentionPolicies();
|
||||
|
||||
// Create or update retention policy
|
||||
var retentionData = new DurableTaskRetentionPolicyData
|
||||
{
|
||||
Properties = new DurableTaskRetentionPolicyProperties
|
||||
{
|
||||
// Configure retention settings
|
||||
}
|
||||
};
|
||||
|
||||
var retentionOperation = await retentionPolicies.CreateOrUpdateAsync(
|
||||
WaitUntil.Completed,
|
||||
"default", // Policy name
|
||||
retentionData);
|
||||
```
|
||||
|
||||
## Key Types Reference
|
||||
|
||||
| Type | Purpose |
|
||||
|------|---------|
|
||||
| `ArmClient` | Entry point for all ARM operations |
|
||||
| `DurableTaskSchedulerResource` | Represents a Durable Task Scheduler |
|
||||
| `DurableTaskSchedulerCollection` | Collection for scheduler CRUD |
|
||||
| `DurableTaskSchedulerData` | Scheduler creation/update payload |
|
||||
| `DurableTaskSchedulerProperties` | Scheduler configuration (SKU, IPAllowlist) |
|
||||
| `DurableTaskSchedulerSku` | SKU configuration (Name, Capacity, RedundancyState) |
|
||||
| `DurableTaskSchedulerSkuName` | SKU options: `Dedicated`, `Consumption` |
|
||||
| `DurableTaskHubResource` | Represents a Task Hub |
|
||||
| `DurableTaskHubCollection` | Collection for task hub CRUD |
|
||||
| `DurableTaskHubData` | Task hub creation payload |
|
||||
| `DurableTaskRetentionPolicyResource` | Retention policy management |
|
||||
| `DurableTaskRetentionPolicyData` | Retention policy configuration |
|
||||
| `DurableTaskExtensions` | Extension methods for ARM client |
|
||||
|
||||
## SKU Options
|
||||
|
||||
| SKU | Description | Use Case |
|
||||
|-----|-------------|----------|
|
||||
| `Dedicated` | Fixed capacity with configurable instances | Production workloads, predictable performance |
|
||||
| `Consumption` | Serverless, auto-scaling | Development, variable workloads |
|
||||
|
||||
## Extension Methods
|
||||
|
||||
The SDK provides extension methods on `SubscriptionResource` and `ResourceGroupResource`:
|
||||
|
||||
```csharp
|
||||
// On SubscriptionResource
|
||||
subscription.GetDurableTaskSchedulers(); // List all in subscription
|
||||
subscription.GetDurableTaskSchedulersAsync(); // Async enumerable
|
||||
|
||||
// On ResourceGroupResource
|
||||
resourceGroup.GetDurableTaskSchedulers(); // Get collection
|
||||
resourceGroup.GetDurableTaskSchedulerAsync(name); // Get by name
|
||||
|
||||
// On ArmClient
|
||||
armClient.GetDurableTaskSchedulerResource(id); // Get by resource ID
|
||||
armClient.GetDurableTaskHubResource(id); // Get task hub by ID
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Use `WaitUntil.Completed`** for operations that must finish before proceeding
|
||||
2. **Use `WaitUntil.Started`** when you want to poll manually or run operations in parallel
|
||||
3. **Always use `DefaultAzureCredential`** — never hardcode keys
|
||||
4. **Handle `RequestFailedException`** for ARM API errors
|
||||
5. **Use `CreateOrUpdateAsync`** for idempotent operations
|
||||
6. **Delete task hubs before schedulers** — schedulers with task hubs cannot be deleted
|
||||
7. **Use IP allowlists** for network security in production
|
||||
|
||||
## Error Handling
|
||||
|
||||
```csharp
|
||||
using Azure;
|
||||
|
||||
try
|
||||
{
|
||||
var operation = await schedulerCollection.CreateOrUpdateAsync(
|
||||
WaitUntil.Completed, schedulerName, schedulerData);
|
||||
}
|
||||
catch (RequestFailedException ex) when (ex.Status == 409)
|
||||
{
|
||||
Console.WriteLine("Scheduler already exists");
|
||||
}
|
||||
catch (RequestFailedException ex) when (ex.Status == 404)
|
||||
{
|
||||
Console.WriteLine("Resource group not found");
|
||||
}
|
||||
catch (RequestFailedException ex)
|
||||
{
|
||||
Console.WriteLine($"ARM Error: {ex.Status} - {ex.ErrorCode}: {ex.Message}");
|
||||
}
|
||||
```
|
||||
|
||||
## Complete Example
|
||||
|
||||
```csharp
|
||||
using Azure;
|
||||
using Azure.Identity;
|
||||
using Azure.ResourceManager;
|
||||
using Azure.ResourceManager.DurableTask;
|
||||
using Azure.ResourceManager.DurableTask.Models;
|
||||
using Azure.ResourceManager.Resources;
|
||||
|
||||
// Setup
|
||||
var credential = new DefaultAzureCredential();
|
||||
var armClient = new ArmClient(credential);
|
||||
|
||||
var subscriptionId = Environment.GetEnvironmentVariable("AZURE_SUBSCRIPTION_ID")!;
|
||||
var resourceGroupName = Environment.GetEnvironmentVariable("AZURE_RESOURCE_GROUP")!;
|
||||
|
||||
var subscription = armClient.GetSubscriptionResource(
|
||||
new ResourceIdentifier($"/subscriptions/{subscriptionId}"));
|
||||
var resourceGroup = await subscription.GetResourceGroupAsync(resourceGroupName);
|
||||
|
||||
// Create scheduler
|
||||
var schedulerData = new DurableTaskSchedulerData(AzureLocation.EastUS)
|
||||
{
|
||||
Properties = new DurableTaskSchedulerProperties
|
||||
{
|
||||
Sku = new DurableTaskSchedulerSku(DurableTaskSchedulerSkuName.Dedicated)
|
||||
{
|
||||
Capacity = 1
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var schedulerCollection = resourceGroup.Value.GetDurableTaskSchedulers();
|
||||
var schedulerOp = await schedulerCollection.CreateOrUpdateAsync(
|
||||
WaitUntil.Completed, "my-scheduler", schedulerData);
|
||||
var scheduler = schedulerOp.Value;
|
||||
|
||||
Console.WriteLine($"Scheduler endpoint: {scheduler.Data.Properties.Endpoint}");
|
||||
|
||||
// Create task hub
|
||||
var taskHubData = new DurableTaskHubData();
|
||||
var taskHubOp = await scheduler.GetDurableTaskHubs().CreateOrUpdateAsync(
|
||||
WaitUntil.Completed, "my-taskhub", taskHubData);
|
||||
var taskHub = taskHubOp.Value;
|
||||
|
||||
Console.WriteLine($"Task Hub: {taskHub.Data.Name}");
|
||||
|
||||
// Cleanup
|
||||
await taskHub.DeleteAsync(WaitUntil.Completed);
|
||||
await scheduler.DeleteAsync(WaitUntil.Completed);
|
||||
```
|
||||
|
||||
## Related SDKs
|
||||
|
||||
| SDK | Purpose | Install |
|
||||
|-----|---------|---------|
|
||||
| `Azure.ResourceManager.DurableTask` | Management plane (this SDK) | `dotnet add package Azure.ResourceManager.DurableTask` |
|
||||
| `Microsoft.DurableTask.Client.AzureManaged` | Data plane (orchestrations, activities) | `dotnet add package Microsoft.DurableTask.Client.AzureManaged` |
|
||||
| `Microsoft.DurableTask.Worker.AzureManaged` | Worker for running orchestrations | `dotnet add package Microsoft.DurableTask.Worker.AzureManaged` |
|
||||
| `Azure.Identity` | Authentication | `dotnet add package Azure.Identity` |
|
||||
| `Azure.ResourceManager` | Base ARM SDK | `dotnet add package Azure.ResourceManager` |
|
||||
|
||||
## Source Reference
|
||||
|
||||
- [GitHub: Azure.ResourceManager.DurableTask](https://github.com/Azure/azure-sdk-for-net/tree/main/sdk/durabletask/Azure.ResourceManager.DurableTask)
|
||||
- [NuGet: Azure.ResourceManager.DurableTask](https://www.nuget.org/packages/Azure.ResourceManager.DurableTask)
|
||||
297
skills/official/microsoft/dotnet/compute/playwright/SKILL.md
Normal file
297
skills/official/microsoft/dotnet/compute/playwright/SKILL.md
Normal file
@@ -0,0 +1,297 @@
|
||||
---
|
||||
name: azure-resource-manager-playwright-dotnet
|
||||
description: |
|
||||
Azure Resource Manager SDK for Microsoft Playwright Testing in .NET. Use for MANAGEMENT PLANE operations: creating/managing Playwright Testing workspaces, checking name availability, and managing workspace quotas via Azure Resource Manager. NOT for running Playwright tests - use Azure.Developer.MicrosoftPlaywrightTesting.NUnit for that. Triggers: "Playwright workspace", "create Playwright Testing workspace", "manage Playwright resources", "ARM Playwright", "PlaywrightWorkspaceResource", "provision Playwright Testing".
|
||||
package: Azure.ResourceManager.Playwright
|
||||
---
|
||||
|
||||
# Azure.ResourceManager.Playwright (.NET)
|
||||
|
||||
Management plane SDK for provisioning and managing Microsoft Playwright Testing workspaces via Azure Resource Manager.
|
||||
|
||||
> **⚠️ Management vs Test Execution**
|
||||
> - **This SDK (Azure.ResourceManager.Playwright)**: Create workspaces, manage quotas, check name availability
|
||||
> - **Test Execution SDK (Azure.Developer.MicrosoftPlaywrightTesting.NUnit)**: Run Playwright tests at scale on cloud browsers
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
dotnet add package Azure.ResourceManager.Playwright
|
||||
dotnet add package Azure.Identity
|
||||
```
|
||||
|
||||
**Current Versions**: Stable v1.0.0, Preview v1.0.0-beta.1
|
||||
|
||||
## Environment Variables
|
||||
|
||||
```bash
|
||||
AZURE_SUBSCRIPTION_ID=<your-subscription-id>
|
||||
# For service principal auth (optional)
|
||||
AZURE_TENANT_ID=<tenant-id>
|
||||
AZURE_CLIENT_ID=<client-id>
|
||||
AZURE_CLIENT_SECRET=<client-secret>
|
||||
```
|
||||
|
||||
## Authentication
|
||||
|
||||
```csharp
|
||||
using Azure.Identity;
|
||||
using Azure.ResourceManager;
|
||||
using Azure.ResourceManager.Playwright;
|
||||
|
||||
// Always use DefaultAzureCredential
|
||||
var credential = new DefaultAzureCredential();
|
||||
var armClient = new ArmClient(credential);
|
||||
|
||||
// Get subscription
|
||||
var subscriptionId = Environment.GetEnvironmentVariable("AZURE_SUBSCRIPTION_ID");
|
||||
var subscription = armClient.GetSubscriptionResource(
|
||||
new ResourceIdentifier($"/subscriptions/{subscriptionId}"));
|
||||
```
|
||||
|
||||
## Resource Hierarchy
|
||||
|
||||
```
|
||||
ArmClient
|
||||
└── SubscriptionResource
|
||||
├── PlaywrightQuotaResource (subscription-level quotas)
|
||||
└── ResourceGroupResource
|
||||
└── PlaywrightWorkspaceResource
|
||||
└── PlaywrightWorkspaceQuotaResource (workspace-level quotas)
|
||||
```
|
||||
|
||||
## Core Workflow
|
||||
|
||||
### 1. Create Playwright Workspace
|
||||
|
||||
```csharp
|
||||
using Azure.ResourceManager.Playwright;
|
||||
using Azure.ResourceManager.Playwright.Models;
|
||||
|
||||
// Get resource group
|
||||
var resourceGroup = await subscription
|
||||
.GetResourceGroupAsync("my-resource-group");
|
||||
|
||||
// Define workspace
|
||||
var workspaceData = new PlaywrightWorkspaceData(AzureLocation.WestUS3)
|
||||
{
|
||||
// Optional: Configure regional affinity and local auth
|
||||
RegionalAffinity = PlaywrightRegionalAffinity.Enabled,
|
||||
LocalAuth = PlaywrightLocalAuth.Enabled,
|
||||
Tags =
|
||||
{
|
||||
["Team"] = "Dev Exp",
|
||||
["Environment"] = "Production"
|
||||
}
|
||||
};
|
||||
|
||||
// Create workspace (long-running operation)
|
||||
var workspaceCollection = resourceGroup.Value.GetPlaywrightWorkspaces();
|
||||
var operation = await workspaceCollection.CreateOrUpdateAsync(
|
||||
WaitUntil.Completed,
|
||||
"my-playwright-workspace",
|
||||
workspaceData);
|
||||
|
||||
PlaywrightWorkspaceResource workspace = operation.Value;
|
||||
|
||||
// Get the data plane URI for running tests
|
||||
Console.WriteLine($"Data Plane URI: {workspace.Data.DataplaneUri}");
|
||||
Console.WriteLine($"Workspace ID: {workspace.Data.WorkspaceId}");
|
||||
```
|
||||
|
||||
### 2. Get Existing Workspace
|
||||
|
||||
```csharp
|
||||
// Get by name
|
||||
var workspace = await workspaceCollection.GetAsync("my-playwright-workspace");
|
||||
|
||||
// Or check if exists first
|
||||
bool exists = await workspaceCollection.ExistsAsync("my-playwright-workspace");
|
||||
if (exists)
|
||||
{
|
||||
var existingWorkspace = await workspaceCollection.GetAsync("my-playwright-workspace");
|
||||
Console.WriteLine($"Workspace found: {existingWorkspace.Value.Data.Name}");
|
||||
}
|
||||
```
|
||||
|
||||
### 3. List Workspaces
|
||||
|
||||
```csharp
|
||||
// List in resource group
|
||||
await foreach (var workspace in workspaceCollection.GetAllAsync())
|
||||
{
|
||||
Console.WriteLine($"Workspace: {workspace.Data.Name}");
|
||||
Console.WriteLine($" Location: {workspace.Data.Location}");
|
||||
Console.WriteLine($" State: {workspace.Data.ProvisioningState}");
|
||||
Console.WriteLine($" Data Plane URI: {workspace.Data.DataplaneUri}");
|
||||
}
|
||||
|
||||
// List across subscription
|
||||
await foreach (var workspace in subscription.GetPlaywrightWorkspacesAsync())
|
||||
{
|
||||
Console.WriteLine($"Workspace: {workspace.Data.Name}");
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Update Workspace
|
||||
|
||||
```csharp
|
||||
var patch = new PlaywrightWorkspacePatch
|
||||
{
|
||||
Tags =
|
||||
{
|
||||
["Team"] = "Dev Exp",
|
||||
["Environment"] = "Staging",
|
||||
["UpdatedAt"] = DateTime.UtcNow.ToString("o")
|
||||
}
|
||||
};
|
||||
|
||||
var updatedWorkspace = await workspace.Value.UpdateAsync(patch);
|
||||
```
|
||||
|
||||
### 5. Check Name Availability
|
||||
|
||||
```csharp
|
||||
using Azure.ResourceManager.Playwright.Models;
|
||||
|
||||
var checkRequest = new PlaywrightCheckNameAvailabilityContent
|
||||
{
|
||||
Name = "my-new-workspace",
|
||||
ResourceType = "Microsoft.LoadTestService/playwrightWorkspaces"
|
||||
};
|
||||
|
||||
var result = await subscription.CheckPlaywrightNameAvailabilityAsync(checkRequest);
|
||||
|
||||
if (result.Value.IsNameAvailable == true)
|
||||
{
|
||||
Console.WriteLine("Name is available!");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"Name unavailable: {result.Value.Message}");
|
||||
Console.WriteLine($"Reason: {result.Value.Reason}");
|
||||
}
|
||||
```
|
||||
|
||||
### 6. Get Quota Information
|
||||
|
||||
```csharp
|
||||
// Subscription-level quotas
|
||||
await foreach (var quota in subscription.GetPlaywrightQuotasAsync(AzureLocation.WestUS3))
|
||||
{
|
||||
Console.WriteLine($"Quota: {quota.Data.Name}");
|
||||
Console.WriteLine($" Limit: {quota.Data.Limit}");
|
||||
Console.WriteLine($" Used: {quota.Data.Used}");
|
||||
}
|
||||
|
||||
// Workspace-level quotas
|
||||
var workspaceQuotas = workspace.Value.GetAllPlaywrightWorkspaceQuota();
|
||||
await foreach (var quota in workspaceQuotas.GetAllAsync())
|
||||
{
|
||||
Console.WriteLine($"Workspace Quota: {quota.Data.Name}");
|
||||
}
|
||||
```
|
||||
|
||||
### 7. Delete Workspace
|
||||
|
||||
```csharp
|
||||
// Delete (long-running operation)
|
||||
await workspace.Value.DeleteAsync(WaitUntil.Completed);
|
||||
```
|
||||
|
||||
## Key Types Reference
|
||||
|
||||
| Type | Purpose |
|
||||
|------|---------|
|
||||
| `ArmClient` | Entry point for all ARM operations |
|
||||
| `PlaywrightWorkspaceResource` | Represents a Playwright Testing workspace |
|
||||
| `PlaywrightWorkspaceCollection` | Collection for workspace CRUD |
|
||||
| `PlaywrightWorkspaceData` | Workspace creation/response payload |
|
||||
| `PlaywrightWorkspacePatch` | Workspace update payload |
|
||||
| `PlaywrightQuotaResource` | Subscription-level quota information |
|
||||
| `PlaywrightWorkspaceQuotaResource` | Workspace-level quota information |
|
||||
| `PlaywrightExtensions` | Extension methods for ARM resources |
|
||||
| `PlaywrightCheckNameAvailabilityContent` | Name availability check request |
|
||||
|
||||
## Workspace Properties
|
||||
|
||||
| Property | Description |
|
||||
|----------|-------------|
|
||||
| `DataplaneUri` | URI for running tests (e.g., `https://api.dataplane.{guid}.domain.com`) |
|
||||
| `WorkspaceId` | Unique workspace identifier (GUID) |
|
||||
| `RegionalAffinity` | Enable/disable regional affinity for test execution |
|
||||
| `LocalAuth` | Enable/disable local authentication (access tokens) |
|
||||
| `ProvisioningState` | Current provisioning state (Succeeded, Failed, etc.) |
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Use `WaitUntil.Completed`** for operations that must finish before proceeding
|
||||
2. **Use `WaitUntil.Started`** when you want to poll manually or run operations in parallel
|
||||
3. **Always use `DefaultAzureCredential`** — never hardcode keys
|
||||
4. **Handle `RequestFailedException`** for ARM API errors
|
||||
5. **Use `CreateOrUpdateAsync`** for idempotent operations
|
||||
6. **Navigate hierarchy** via `Get*` methods (e.g., `resourceGroup.GetPlaywrightWorkspaces()`)
|
||||
7. **Store the DataplaneUri** after workspace creation for test execution configuration
|
||||
|
||||
## Error Handling
|
||||
|
||||
```csharp
|
||||
using Azure;
|
||||
|
||||
try
|
||||
{
|
||||
var operation = await workspaceCollection.CreateOrUpdateAsync(
|
||||
WaitUntil.Completed, workspaceName, workspaceData);
|
||||
}
|
||||
catch (RequestFailedException ex) when (ex.Status == 409)
|
||||
{
|
||||
Console.WriteLine("Workspace already exists");
|
||||
}
|
||||
catch (RequestFailedException ex) when (ex.Status == 400)
|
||||
{
|
||||
Console.WriteLine($"Bad request: {ex.Message}");
|
||||
}
|
||||
catch (RequestFailedException ex)
|
||||
{
|
||||
Console.WriteLine($"ARM Error: {ex.Status} - {ex.ErrorCode}: {ex.Message}");
|
||||
}
|
||||
```
|
||||
|
||||
## Integration with Test Execution
|
||||
|
||||
After creating a workspace, use the `DataplaneUri` to configure your Playwright tests:
|
||||
|
||||
```csharp
|
||||
// 1. Create workspace (this SDK)
|
||||
var workspace = await workspaceCollection.CreateOrUpdateAsync(
|
||||
WaitUntil.Completed, "my-workspace", workspaceData);
|
||||
|
||||
// 2. Get the service URL
|
||||
var serviceUrl = workspace.Value.Data.DataplaneUri;
|
||||
|
||||
// 3. Set environment variable for test execution
|
||||
Environment.SetEnvironmentVariable("PLAYWRIGHT_SERVICE_URL", serviceUrl.ToString());
|
||||
|
||||
// 4. Run tests using Azure.Developer.MicrosoftPlaywrightTesting.NUnit
|
||||
// (separate package for test execution)
|
||||
```
|
||||
|
||||
## Related SDKs
|
||||
|
||||
| SDK | Purpose | Install |
|
||||
|-----|---------|---------|
|
||||
| `Azure.ResourceManager.Playwright` | Management plane (this SDK) | `dotnet add package Azure.ResourceManager.Playwright` |
|
||||
| `Azure.Developer.MicrosoftPlaywrightTesting.NUnit` | Run NUnit Playwright tests at scale | `dotnet add package Azure.Developer.MicrosoftPlaywrightTesting.NUnit --prerelease` |
|
||||
| `Azure.Developer.Playwright` | Playwright client library | `dotnet add package Azure.Developer.Playwright` |
|
||||
|
||||
## API Information
|
||||
|
||||
- **Resource Provider**: `Microsoft.LoadTestService`
|
||||
- **Default API Version**: `2025-09-01`
|
||||
- **Resource Type**: `Microsoft.LoadTestService/playwrightWorkspaces`
|
||||
|
||||
## Documentation Links
|
||||
|
||||
- [Azure.ResourceManager.Playwright API Reference](https://learn.microsoft.com/en-us/dotnet/api/azure.resourcemanager.playwright)
|
||||
- [Microsoft Playwright Testing Overview](https://learn.microsoft.com/en-us/azure/playwright-testing/overview-what-is-microsoft-playwright-testing)
|
||||
- [Quickstart: Run Playwright Tests at Scale](https://learn.microsoft.com/en-us/azure/playwright-testing/quickstart-run-end-to-end-tests)
|
||||
Reference in New Issue
Block a user