Skip to content

Commit 98f40e5

Browse files
authored
Merge branch 'main' into copilot/add-test-splitting-infrastructure-again
2 parents 531c924 + b9cdc57 commit 98f40e5

File tree

492 files changed

+13202
-4340
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

492 files changed

+13202
-4340
lines changed

.github/copilot-instructions.md

Lines changed: 0 additions & 131 deletions
Original file line numberDiff line numberDiff line change
@@ -183,137 +183,6 @@ The `*.Designer.cs` files are in the repo, but are intended to match same named
183183
* Code blocks should be formatted with triple backticks (```) and include the language identifier for syntax highlighting.
184184
* JSON code blocks should be indented properly.
185185

186-
## Custom Skills System
187-
188-
This repository supports custom skills - reusable, specialized capabilities that extend Copilot's functionality for specific tasks. Skills work like plugins that you should automatically invoke when relevant to the user's request.
189-
190-
### Skill Locations
191-
192-
Skills are stored in the following directories (in order of precedence):
193-
1. **Project Skills** (shared with team): `.claude/skills/` - checked into git
194-
2. **Personal Skills** (user-specific): `~/.claude/skills/` - not checked into git
195-
196-
### Skill Structure
197-
198-
Each skill is a directory containing a `SKILL.md` file with this format:
199-
200-
```markdown
201-
---
202-
name: Human Readable Name (max 64 chars)
203-
description: One-line description of what the skill does and when to use it (max 1024 chars)
204-
allowed-tools: Read, Grep, Glob, Bash, Edit, Write # Optional: restrict which tools the skill can use
205-
---
206-
207-
# Skill Name
208-
209-
## Purpose
210-
Clear explanation of what this skill does.
211-
212-
## When to Use
213-
Specific scenarios when this skill should be invoked.
214-
215-
## Instructions
216-
Step-by-step guidance for executing the skill.
217-
218-
## Examples
219-
Concrete examples demonstrating the skill's usage.
220-
```
221-
222-
### How to Discover and Use Skills
223-
224-
**IMPORTANT**: You must proactively check for and use skills when they match the user's request.
225-
226-
#### Step 1: Skill Discovery
227-
228-
When a user makes a request, before starting work:
229-
230-
1. **Search for relevant skills** by checking `.claude/skills/` and `~/.claude/skills/`:
231-
```bash
232-
# List all available skills
233-
find .claude/skills -name "SKILL.md" -type f 2>/dev/null
234-
find ~/.claude/skills -name "SKILL.md" -type f 2>/dev/null
235-
```
236-
237-
2. **Read skill descriptions** to find matches:
238-
- Read the YAML frontmatter of each `SKILL.md` file
239-
- Match the `description` field against the user's request
240-
- A skill is relevant if its description keywords overlap with the task
241-
242-
#### Step 2: Skill Invocation
243-
244-
When you identify a relevant skill:
245-
246-
1. **Announce skill activation** to the user:
247-
```
248-
I found a relevant skill: "{skill_name}". I'll use this to help with your request.
249-
```
250-
251-
2. **Read the complete SKILL.md file** to understand the full instructions:
252-
- Use the Read tool to load the entire skill file
253-
- Parse both the frontmatter and the markdown content
254-
- Pay special attention to the Instructions and Examples sections
255-
256-
3. **Follow the skill's instructions exactly**:
257-
- Execute each step in the Instructions section
258-
- Use only the tools specified in `allowed-tools` (if defined)
259-
- Adapt the examples to the current context
260-
- If the skill references other files in its directory, read them as needed
261-
262-
4. **Report completion**:
263-
```
264-
Completed task using the "{skill_name}" skill.
265-
```
266-
267-
#### Step 3: When to Use Subagents for Skills
268-
269-
For complex skills that involve multiple phases or extensive codebase exploration, use subagents:
270-
271-
1. **Use Task tool with subagent_type=Explore** when a skill requires:
272-
- Searching across multiple files or directories
273-
- Understanding codebase patterns before making changes
274-
- Gathering context from various locations
275-
276-
2. **Use Task tool with subagent_type=general-purpose** when a skill requires:
277-
- Multi-step workflows that could fail and need retry logic
278-
- Complex decision trees based on what's found in the codebase
279-
- Long-running operations that benefit from isolation
280-
281-
Example of using a subagent for skill execution:
282-
```
283-
I'll use the Task tool to invoke the "{skill_name}" skill:
284-
[Invoke Task tool with subagent_type=Explore and pass the full skill instructions as the prompt]
285-
```
286-
287-
### Skill Best Practices
288-
289-
1. **Always check for skills first** before starting any non-trivial task
290-
2. **Trust the skill instructions** - they are curated and tested
291-
3. **Don't modify skills** unless explicitly asked by the user
292-
4. **Combine skills** when multiple skills apply to different parts of a task
293-
5. **Report when no skill exists** - if a task would benefit from a skill but none exists, mention this to the user
294-
295-
### Example: Using a Skill
296-
297-
User request: "Review the code changes in my PR for performance issues"
298-
299-
Your workflow:
300-
1. Search for skills: `find .claude/skills -name "SKILL.md"`
301-
2. Find match: `.claude/skills/performance-reviewer/SKILL.md`
302-
3. Announce: "I found the 'Performance Reviewer' skill. I'll use this to analyze your PR."
303-
4. Read skill: Load `.claude/skills/performance-reviewer/SKILL.md`
304-
5. Execute: Follow the skill's instructions step-by-step
305-
6. Complete: "Completed performance review using the Performance Reviewer skill."
306-
307-
### Creating New Skills (When Asked)
308-
309-
If a user asks you to create a new skill:
310-
311-
1. Create a directory in `.claude/skills/{skill-name}/`
312-
2. Write a `SKILL.md` file following the structure above
313-
3. Include clear, actionable instructions
314-
4. Add concrete examples
315-
5. Test the skill by using it immediately
316-
317186
## Trust These Instructions
318187

319188
These instructions are comprehensive and tested. Only search for additional information if:

.github/workflows/test-scenario.yml

Lines changed: 120 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -85,52 +85,149 @@ jobs:
8585
gh --version
8686
fi
8787
88-
- name: Create agent task
89-
id: create_agent_task
88+
- name: Create issue and assign to copilot
89+
id: create_issue
9090
run: |
91-
echo "Creating agent task..."
91+
echo "Creating issue in aspire-playground repository..."
9292
PROMPT_FILE="${{ steps.check_prompt.outputs.prompt_file }}"
93+
SCENARIO_NAME="${{ steps.parse_scenario.outputs.scenario_name }}"
94+
SOURCE_PR_URL="${{ github.event.issue.html_url }}"
95+
SOURCE_PR_NUMBER="${{ github.event.issue.number }}"
96+
SOURCE_REPO="${{ github.repository }}"
9397
9498
# Auth using the token
9599
gh auth login --with-token <<< "$GH_PLAYGROUND_TOKEN"
96100
97-
# Create the agent task using stdin and capture the output
98-
OUTPUT=$(cat "$PROMPT_FILE" | gh agent-task create \
101+
# Build the issue body with context from the source PR and the prompt
102+
ISSUE_TITLE="Test Scenario: ${SCENARIO_NAME}"
103+
104+
# Read prompt content first
105+
PROMPT_CONTENT=$(cat "$PROMPT_FILE")
106+
107+
# Build issue body using printf with proper format strings to avoid injection
108+
printf -v ISSUE_BODY '%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s' \
109+
"## Test Scenario Request" \
110+
"" \
111+
"**Scenario:** ${SCENARIO_NAME}" \
112+
"**Source PR:** ${SOURCE_PR_URL}" \
113+
"**Source Repository:** ${SOURCE_REPO}" \
114+
"" \
115+
"---" \
116+
"" \
117+
"$PROMPT_CONTENT" \
118+
"" \
119+
"---" \
120+
"" \
121+
"This issue was created automatically from PR #${SOURCE_PR_NUMBER} in ${SOURCE_REPO}."
122+
123+
# Create the issue and assign to copilot
124+
echo "Creating issue with title: $ISSUE_TITLE"
125+
ISSUE_OUTPUT=$(gh issue create \
99126
--repo "${REPO_OWNER}/${REPO_NAME}" \
100-
-F - \
127+
--title "$ISSUE_TITLE" \
128+
--body "$ISSUE_BODY" \
129+
--assignee "copilot" \
101130
2>&1)
102131
103-
echo "Agent task output:"
104-
echo "$OUTPUT"
132+
echo "Issue creation output:"
133+
echo "$ISSUE_OUTPUT"
105134
106-
# Extract the PR URL from the output
107-
PR_URL=$(echo "$OUTPUT" | \
108-
grep -oP 'https://github.com/[^/]+/[^/]+/pull/\d+' | head -1)
135+
# Extract the issue URL from the output
136+
ISSUE_URL=$(echo "$ISSUE_OUTPUT" | \
137+
grep -oP 'https://github.com/[^/]+/[^/]+/issues/\d+' | head -1)
109138
110-
if [ -z "$PR_URL" ]; then
111-
echo "Warning: Could not extract PR URL from output"
112-
echo "pr_url=" >> $GITHUB_OUTPUT
139+
if [ -z "$ISSUE_URL" ]; then
140+
echo "Error: Could not extract issue URL from output"
141+
exit 1
142+
fi
143+
144+
echo "Successfully created issue: $ISSUE_URL"
145+
echo "issue_url=$ISSUE_URL" >> $GITHUB_OUTPUT
146+
147+
# Extract issue number for later use
148+
ISSUE_NUMBER=$(echo "$ISSUE_URL" | grep -oP '/issues/\K\d+')
149+
echo "issue_number=$ISSUE_NUMBER" >> $GITHUB_OUTPUT
150+
151+
- name: Wait for agent PR to be created
152+
id: wait_for_pr
153+
run: |
154+
echo "Waiting for GitHub Copilot agent to create a PR..."
155+
ISSUE_NUMBER="${{ steps.create_issue.outputs.issue_number }}"
156+
MAX_ATTEMPTS=30
157+
SLEEP_SECONDS=10
158+
ATTEMPT=0
159+
FOUND_PR=""
160+
161+
# Auth using the token
162+
gh auth login --with-token <<< "$GH_PLAYGROUND_TOKEN"
163+
164+
while [ $ATTEMPT -lt $MAX_ATTEMPTS ]; do
165+
ATTEMPT=$((ATTEMPT + 1))
166+
echo "Attempt $ATTEMPT of $MAX_ATTEMPTS..."
167+
168+
# Try to find linked PRs by searching for PRs that reference this issue
169+
LINKED_PRS=$(gh pr list \
170+
--repo "${REPO_OWNER}/${REPO_NAME}" \
171+
--search "linked:issue-${ISSUE_NUMBER}" \
172+
--json number,url,title \
173+
--jq '.[0].url' 2>/dev/null || echo "")
174+
175+
if [ -n "$LINKED_PRS" ] && [ "$LINKED_PRS" != "null" ] && [ "$LINKED_PRS" != "" ]; then
176+
echo "Found linked PR: $LINKED_PRS"
177+
FOUND_PR="$LINKED_PRS"
178+
break
179+
fi
180+
181+
# Also check for PRs created by the copilot bot recently
182+
COPILOT_PRS=$(gh pr list \
183+
--repo "${REPO_OWNER}/${REPO_NAME}" \
184+
--author "copilot" \
185+
--limit 5 \
186+
--json number,url,title,createdAt \
187+
--jq 'sort_by(.createdAt) | reverse | .[0].url' 2>/dev/null || echo "")
188+
189+
if [ -n "$COPILOT_PRS" ] && [ "$COPILOT_PRS" != "null" ] && [ "$COPILOT_PRS" != "" ]; then
190+
echo "Found recent copilot PR: $COPILOT_PRS"
191+
FOUND_PR="$COPILOT_PRS"
192+
break
193+
fi
194+
195+
if [ $ATTEMPT -lt $MAX_ATTEMPTS ]; then
196+
echo "No PR found yet, waiting ${SLEEP_SECONDS} seconds..."
197+
sleep $SLEEP_SECONDS
198+
fi
199+
done
200+
201+
if [ -n "$FOUND_PR" ]; then
202+
echo "pr_url=$FOUND_PR" >> $GITHUB_OUTPUT
113203
else
114-
echo "Successfully created agent task with PR: $PR_URL"
115-
echo "pr_url=$PR_URL" >> $GITHUB_OUTPUT
204+
echo "Warning: No PR found after $MAX_ATTEMPTS attempts"
205+
echo "The agent may still be working on it."
206+
echo "pr_url=" >> $GITHUB_OUTPUT
116207
fi
117208
118-
- name: Comment on PR with agent task link
119-
if: steps.create_agent_task.outputs.pr_url != ''
209+
- name: Comment on PR with issue and agent PR links
120210
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
121211
with:
122212
github-token: ${{ secrets.GITHUB_TOKEN }}
123213
script: |
124-
const prUrl = '${{ steps.create_agent_task.outputs.pr_url }}';
214+
const issueUrl = '${{ steps.create_issue.outputs.issue_url }}';
215+
const prUrl = '${{ steps.wait_for_pr.outputs.pr_url }}';
125216
const scenarioName = '${{ steps.parse_scenario.outputs.scenario_name }}';
126-
const comment = `🤖 **AI Agent Task Created**
217+
218+
let comment = `🤖 **AI Agent Task Created**
127219
128220
Scenario: **${scenarioName}**
129221
130-
An AI agent has been triggered to execute this scenario.
131-
You can track the progress here:
222+
An AI agent has been assigned to execute this scenario.
223+
224+
📝 **Issue:** ${issueUrl}`;
132225
133-
${prUrl}`;
226+
if (prUrl) {
227+
comment += `\n🔀 **Agent PR:** ${prUrl}`;
228+
} else {
229+
comment += `\n\n⏳ The agent is working on this task. The PR will be linked in the issue once created.`;
230+
}
134231
135232
await github.rest.issues.createComment({
136233
issue_number: context.issue.number,

Aspire.slnx

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
<Project Path="src/Components/Aspire.Microsoft.EntityFrameworkCore.SqlServer/Aspire.Microsoft.EntityFrameworkCore.SqlServer.csproj" />
2727
<Project Path="src/Components/Aspire.Microsoft.Extensions.Configuration.AzureAppConfiguration/Aspire.Microsoft.Extensions.Configuration.AzureAppConfiguration.csproj" />
2828
<Project Path="src/Components/Aspire.Milvus.Client/Aspire.Milvus.Client.csproj" />
29-
<Project Path="src/Components/Aspire.MongoDB.Driver.v3/Aspire.MongoDB.Driver.v3.csproj" />
29+
<Project Path="src/Components/Aspire.MongoDB.Driver.v2/Aspire.MongoDB.Driver.v2.csproj" />
3030
<Project Path="src/Components/Aspire.MongoDB.Driver/Aspire.MongoDB.Driver.csproj" />
3131
<Project Path="src/Components/Aspire.MySqlConnector/Aspire.MySqlConnector.csproj" />
3232
<Project Path="src/Components/Aspire.NATS.Net/Aspire.NATS.Net.csproj" />
@@ -36,7 +36,7 @@
3636
<Project Path="src/Components/Aspire.Oracle.EntityFrameworkCore/Aspire.Oracle.EntityFrameworkCore.csproj" />
3737
<Project Path="src/Components/Aspire.Pomelo.EntityFrameworkCore.MySql/Aspire.Pomelo.EntityFrameworkCore.MySql.csproj" />
3838
<Project Path="src/Components/Aspire.Qdrant.Client/Aspire.Qdrant.Client.csproj" />
39-
<Project Path="src/Components/Aspire.RabbitMQ.Client.v7/Aspire.RabbitMQ.Client.v7.csproj" />
39+
<Project Path="src/Components/Aspire.RabbitMQ.Client.v6/Aspire.RabbitMQ.Client.v6.csproj" />
4040
<Project Path="src/Components/Aspire.RabbitMQ.Client/Aspire.RabbitMQ.Client.csproj" />
4141
<Project Path="src/Components/Aspire.Seq/Aspire.Seq.csproj" />
4242
<Project Path="src/Components/Aspire.StackExchange.Redis.DistributedCaching/Aspire.StackExchange.Redis.DistributedCaching.csproj" />
@@ -106,6 +106,11 @@
106106
<File Path="playground/README.md" />
107107
<Project Path="playground/Playground.ServiceDefaults/Playground.ServiceDefaults.csproj" />
108108
</Folder>
109+
<Folder Name="/playground/AspireWithJavaScript/">
110+
<Project Path="playground/AspireWithJavaScript/AspireJavaScript.AppHost/AspireJavaScript.AppHost.csproj" />
111+
<Project Path="playground/AspireWithJavaScript/AspireJavaScript.MinimalApi/AspireJavaScript.MinimalApi.csproj" />
112+
<Project Path="playground/AspireWithJavaScript/AspireJavaScript.ServiceDefaults/AspireJavaScript.ServiceDefaults.csproj" />
113+
</Folder>
109114
<Folder Name="/playground/AzureAIFoundryEndToEnd/">
110115
<Project Path="playground/AzureAIFoundryEndToEnd/AzureAIFoundryEndToEnd.AppHost/AzureAIFoundryEndToEnd.AppHost.csproj" />
111116
<Project Path="playground/AzureAIFoundryEndToEnd/AzureAIFoundryEndToEnd.WebStory/AzureAIFoundryEndToEnd.WebStory.csproj" />
@@ -176,8 +181,8 @@
176181
<Project Path="playground/deployers/Deployers.AppHost/Deployers.AppHost.csproj" />
177182
</Folder>
178183
<Folder Name="/playground/DevTunnels/">
179-
<Project Path="playground/DevTunnels/DevTunnels.AppHost/DevTunnels.AppHost.csproj" />
180184
<Project Path="playground/DevTunnels/DevTunnels.ApiService/DevTunnels.ApiService.csproj" />
185+
<Project Path="playground/DevTunnels/DevTunnels.AppHost/DevTunnels.AppHost.csproj" />
181186
<Project Path="playground/DevTunnels/DevTunnels.WebFrontEnd/DevTunnels.WebFrontEnd.csproj" />
182187
</Folder>
183188
<Folder Name="/playground/dockerfile/">
@@ -199,11 +204,6 @@
199204
<Folder Name="/playground/HealthChecks/">
200205
<Project Path="playground/HealthChecks/HealthChecksSandbox.AppHost/HealthChecksSandbox.AppHost.csproj" />
201206
</Folder>
202-
<Folder Name="/playground/javascript/">
203-
<Project Path="playground/AspireWithJavaScript/AspireJavaScript.AppHost/AspireJavaScript.AppHost.csproj" />
204-
<Project Path="playground/AspireWithJavaScript/AspireJavaScript.MinimalApi/AspireJavaScript.MinimalApi.csproj" />
205-
<Project Path="playground/AspireWithJavaScript/AspireJavaScript.ServiceDefaults/AspireJavaScript.ServiceDefaults.csproj" />
206-
</Folder>
207207
<Folder Name="/playground/kafka/">
208208
<Project Path="playground/kafka/Consumer/Consumer.csproj" />
209209
<Project Path="playground/kafka/KafkaBasic.AppHost/KafkaBasic.AppHost.csproj" />
@@ -234,8 +234,8 @@
234234
</Folder>
235235
<Folder Name="/playground/node/">
236236
<Project Path="playground/AspireWithNode/AspireWithNode.AppHost/AspireWithNode.AppHost.csproj" />
237-
<Project Path="playground/AspireWithNode/AspireWithNode.ServiceDefaults/AspireWithNode.ServiceDefaults.csproj" />
238237
<Project Path="playground/AspireWithNode/AspireWithNode.AspNetCoreApi/AspireWithNode.AspNetCoreApi.csproj" />
238+
<Project Path="playground/AspireWithNode/AspireWithNode.ServiceDefaults/AspireWithNode.ServiceDefaults.csproj" />
239239
</Folder>
240240
<Folder Name="/playground/OpenAIEndToEnd/">
241241
<Project Path="playground/OpenAIEndToEnd/OpenAIEndToEnd.AppHost/OpenAIEndToEnd.AppHost.csproj" />
@@ -392,7 +392,7 @@
392392
<Project Path="tests/Aspire.Microsoft.Extensions.Configuration.AzureAppConfiguration.Tests/Aspire.Microsoft.Extensions.Configuration.AzureAppConfiguration.Tests.csproj" />
393393
<Project Path="tests/Aspire.Milvus.Client.Tests/Aspire.Milvus.Client.Tests.csproj" />
394394
<Project Path="tests/Aspire.MongoDB.Driver.Tests/Aspire.MongoDB.Driver.Tests.csproj" />
395-
<Project Path="tests/Aspire.MongoDB.Driver.v3.Tests/Aspire.MongoDB.Driver.v3.Tests.csproj" />
395+
<Project Path="tests/Aspire.MongoDB.Driver.v2.Tests/Aspire.MongoDB.Driver.v2.Tests.csproj" />
396396
<Project Path="tests/Aspire.MySqlConnector.Tests/Aspire.MySqlConnector.Tests.csproj" />
397397
<Project Path="tests/Aspire.NATS.Net.Tests/Aspire.NATS.Net.Tests.csproj" />
398398
<Project Path="tests/Aspire.Npgsql.EntityFrameworkCore.PostgreSQL.Tests/Aspire.Npgsql.EntityFrameworkCore.PostgreSQL.Tests.csproj" />
@@ -402,7 +402,7 @@
402402
<Project Path="tests/Aspire.Pomelo.EntityFrameworkCore.MySql.Tests/Aspire.Pomelo.EntityFrameworkCore.MySql.Tests.csproj" />
403403
<Project Path="tests/Aspire.Qdrant.Client.Tests/Aspire.Qdrant.Client.Tests.csproj" />
404404
<Project Path="tests/Aspire.RabbitMQ.Client.Tests/Aspire.RabbitMQ.Client.Tests.csproj" />
405-
<Project Path="tests/Aspire.RabbitMQ.Client.v7.Tests/Aspire.RabbitMQ.Client.v7.Tests.csproj" />
405+
<Project Path="tests/Aspire.RabbitMQ.Client.v6.Tests/Aspire.RabbitMQ.Client.v6.Tests.csproj" />
406406
<Project Path="tests/Aspire.Seq.Tests/Aspire.Seq.Tests.csproj" />
407407
<Project Path="tests/Aspire.StackExchange.Redis.DistributedCaching.Tests/Aspire.StackExchange.Redis.DistributedCaching.Tests.csproj" />
408408
<Project Path="tests/Aspire.StackExchange.Redis.OutputCaching.Tests/Aspire.StackExchange.Redis.OutputCaching.Tests.csproj" />

0 commit comments

Comments
 (0)