Skip to content

Commit c97db8c

Browse files
ScottArbeitScott Arbeit
andauthored
Improve Grace's agent-readiness (#52)
* Removing old references to Dapr and Kubernetes. * Improve Grace's agent-readiness. * Reuse shared Aspire host for smoke test * Quick namespace fix. * Run Fantomas checks in CI * Disable Fantomas check in validate --------- Co-authored-by: Scott Arbeit <scottarbeit@github.com>
1 parent db036f5 commit c97db8c

File tree

16 files changed

+930
-75
lines changed

16 files changed

+930
-75
lines changed

.config/dotnet-tools.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"version": 1,
3+
"isRoot": true,
4+
"tools": {
5+
"fantomas-tool": {
6+
"version": "4.7.9",
7+
"commands": [
8+
"fantomas"
9+
]
10+
}
11+
}
12+
}

.env.example

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# Grace .env example (placeholders only)
2+
3+
GRACE_SERVER_URI=http://localhost:5000
4+
GRACE_TOKEN=changeme
5+
GRACE_TOKEN_FILE=
6+
7+
GRACE_TESTING=0
8+
GRACE_TEST_CLEANUP=1
9+
10+
ASPIRE_RESOURCE_MODE=Local
11+
12+
# Telemetry
13+
# grace__applicationinsightsconnectionstring=
14+
15+
# OIDC / Auth
16+
# grace__auth__oidc__authority=
17+
# grace__auth__oidc__audience=
18+
# grace__auth__oidc__cli_client_id=
19+
# grace__auth__oidc__cli_redirect_port=
20+
# grace__auth__oidc__cli_scopes=
21+
# grace__auth__oidc__m2m_client_id=
22+
# grace__auth__oidc__m2m_client_secret=
23+
# grace__auth__oidc__m2m_scopes=
24+
25+
# PAT defaults
26+
# grace__auth__pat__default_lifetime_days=
27+
# grace__auth__pat__max_lifetime_days=
28+
# grace__auth__pat__allow_no_expiry=
29+
30+
# Azure Storage
31+
# grace__azure_storage__connectionstring=
32+
# grace__azure_storage__account_name=
33+
# grace__azure_storage__endpoint_suffix=
34+
# grace__azure_storage__key=
35+
# grace__azure_storage__directoryversion_container_name=
36+
# grace__azure_storage__diff_container_name=
37+
# grace__azure_storage__zipfile_container_name=
38+
39+
# Azure Cosmos DB
40+
# grace__azurecosmosdb__connectionstring=
41+
# grace__azurecosmosdb__endpoint=
42+
# grace__azurecosmosdb__database_name=
43+
# grace__azurecosmosdb__container_name=
44+
45+
# Azure Service Bus
46+
# grace__azure_service_bus__connectionstring=
47+
# grace__azure_service_bus__namespace=
48+
# grace__azure_service_bus__topic=
49+
# grace__azure_service_bus__subscription=
50+
51+
# Redis
52+
# grace__redis__host=127.0.0.1
53+
# grace__redis__port=6379
54+
55+
# Orleans
56+
# orleans_cluster_id=
57+
# orleans_service_id=
58+
59+
# Pub/Sub
60+
# grace__pubsub__system=AzureServiceBus
61+
62+
# Diagnostics
63+
# grace__log_directory=
64+
# grace__debug_environment=Local

.github/workflows/validate.yml

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
name: Validate
2+
3+
on:
4+
pull_request:
5+
branches: [ main ]
6+
push:
7+
branches: [ main ]
8+
schedule:
9+
- cron: "0 3 * * *"
10+
11+
jobs:
12+
fast:
13+
if: github.event_name == 'pull_request'
14+
runs-on: ubuntu-latest
15+
steps:
16+
- uses: actions/checkout@v4
17+
- name: Setup .NET
18+
uses: actions/setup-dotnet@v4
19+
with:
20+
global-json-file: global.json
21+
- name: Install .NET Aspire workload
22+
run: dotnet workload install aspire
23+
- name: Validate (Fast)
24+
run: pwsh ./scripts/validate.ps1 -Fast
25+
26+
full:
27+
if: github.event_name != 'pull_request'
28+
runs-on: ubuntu-latest
29+
steps:
30+
- uses: actions/checkout@v4
31+
- name: Setup .NET
32+
uses: actions/setup-dotnet@v4
33+
with:
34+
global-json-file: global.json
35+
- name: Install .NET Aspire workload
36+
run: dotnet workload install aspire
37+
- name: Docker info
38+
run: docker info
39+
- name: Validate (Full)
40+
run: pwsh ./scripts/validate.ps1 -Full

AGENTS.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,29 @@
33
Other `AGENTS.md` files exist in subdirectories, refer to them for more specific
44
context.
55

6+
## Agent Quickstart (Local)
7+
8+
Prerequisites:
9+
10+
- PowerShell 7.x
11+
- .NET 10 SDK
12+
- Docker Desktop (required for `-Full`)
13+
14+
Commands:
15+
16+
- `pwsh ./scripts/bootstrap.ps1`
17+
- `pwsh ./scripts/validate.ps1 -Fast`
18+
19+
Use `pwsh ./scripts/validate.ps1 -Full` for Aspire integration coverage.
20+
Optional: `pwsh ./scripts/install-githooks.ps1` to add a pre-commit
21+
`validate -Fast` hook.
22+
23+
More context:
24+
25+
- `src/AGENTS.md`
26+
- `src/docs/ASPIRE_SETUP.md`
27+
- `src/docs/ENVIRONMENT.md`
28+
629
## Issue Tracking
730

831
This project uses **bd (beads)** for issue tracking.

global.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"sdk": {
3+
"version": "10.0.100",
4+
"rollForward": "latestPatch"
5+
}
6+
}

scripts/bootstrap.ps1

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
[CmdletBinding()]
2+
param(
3+
[switch]$SkipDocker,
4+
[switch]$CI
5+
)
6+
7+
Set-StrictMode -Version Latest
8+
$ErrorActionPreference = "Stop"
9+
10+
if ($CI) {
11+
$ProgressPreference = "SilentlyContinue"
12+
}
13+
14+
$startTime = Get-Date
15+
$exitCode = 0
16+
17+
function Write-Section([string]$Title) {
18+
Write-Host ""
19+
Write-Host ("== {0} ==" -f $Title)
20+
}
21+
22+
function Invoke-External([string]$Label, [scriptblock]$Command) {
23+
& $Command
24+
if ($LASTEXITCODE -ne 0) {
25+
throw "$Label failed with exit code $LASTEXITCODE."
26+
}
27+
}
28+
29+
try {
30+
Write-Section "Prerequisites"
31+
32+
if ($PSVersionTable.PSVersion.Major -lt 7) {
33+
throw "PowerShell 7.x is required. Current version: $($PSVersionTable.PSVersion)."
34+
}
35+
36+
Write-Verbose ("PowerShell version: {0}" -f $PSVersionTable.PSVersion)
37+
38+
try {
39+
Get-Command dotnet -ErrorAction Stop | Out-Null
40+
} catch {
41+
throw "dotnet SDK not found. Install the .NET 10 SDK and retry."
42+
}
43+
44+
$dotnetVersion = (& dotnet --version).Trim()
45+
if ($LASTEXITCODE -ne 0) {
46+
throw "dotnet --version failed. Ensure the .NET 10 SDK is installed."
47+
}
48+
if ([string]::IsNullOrWhiteSpace($dotnetVersion)) {
49+
throw "dotnet --version returned an empty value."
50+
}
51+
52+
$dotnetMajor = [int]($dotnetVersion.Split(".")[0])
53+
if ($dotnetMajor -lt 10) {
54+
throw "dotnet SDK 10.x required. Detected $dotnetVersion."
55+
}
56+
57+
if (-not $SkipDocker) {
58+
try {
59+
Get-Command docker -ErrorAction Stop | Out-Null
60+
} catch {
61+
throw "Docker is required for full validation. Install Docker Desktop or run with -SkipDocker."
62+
}
63+
64+
Invoke-External "docker info" { docker info | Out-Null }
65+
} else {
66+
Write-Host "Skipping Docker check (-SkipDocker)."
67+
}
68+
69+
Write-Section "Restore Tools"
70+
Invoke-External "dotnet tool restore" { dotnet tool restore }
71+
72+
Write-Section "Restore Packages"
73+
Invoke-External "dotnet restore" { dotnet restore "src/Grace.sln" }
74+
75+
Write-Section "Next Steps"
76+
Write-Host "Run: pwsh ./scripts/validate.ps1 -Fast"
77+
Write-Host "Use -Full for Aspire integration coverage."
78+
} catch {
79+
$exitCode = 1
80+
Write-Error $_
81+
} finally {
82+
$elapsed = (Get-Date) - $startTime
83+
Write-Host ""
84+
Write-Host ("Elapsed: {0:c}" -f $elapsed)
85+
86+
if ($exitCode -ne 0) {
87+
exit $exitCode
88+
}
89+
}

scripts/install-githooks.ps1

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
[CmdletBinding()]
2+
param(
3+
[switch]$Uninstall,
4+
[switch]$Force
5+
)
6+
7+
Set-StrictMode -Version Latest
8+
$ErrorActionPreference = "Stop"
9+
10+
$repoRoot = Resolve-Path (Join-Path $PSScriptRoot "..")
11+
$gitDir = Join-Path $repoRoot ".git"
12+
13+
if (-not (Test-Path $gitDir)) {
14+
throw "No .git directory found at $gitDir. Run from inside a Git clone."
15+
}
16+
17+
$hookDir = Join-Path $gitDir "hooks"
18+
$hookPath = Join-Path $hookDir "pre-commit"
19+
$backupPath = Join-Path $hookDir "pre-commit.grace.bak"
20+
$marker = "Grace Validate Hook"
21+
22+
function Get-FileContent([string]$Path) {
23+
if (-not (Test-Path $Path)) {
24+
return ""
25+
}
26+
27+
return (Get-Content -Path $Path -Raw)
28+
}
29+
30+
function Write-Hook([string]$Path) {
31+
$hook = @"
32+
#!/usr/bin/env sh
33+
# Grace Validate Hook (installed by scripts/install-githooks.ps1)
34+
# Runs validate -Fast after any existing hook logic.
35+
36+
HOOK_DIR=$(cd "$(dirname "$0")" && pwd)
37+
BACKUP="$HOOK_DIR/pre-commit.grace.bak"
38+
39+
if [ -x "$BACKUP" ]; then
40+
"$BACKUP" "$@" || exit $?
41+
fi
42+
43+
if command -v pwsh >/dev/null 2>&1; then
44+
REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null)
45+
if [ -n "$REPO_ROOT" ]; then
46+
pwsh -NoProfile -ExecutionPolicy Bypass -File "$REPO_ROOT/scripts/validate.ps1" -Fast || exit $?
47+
else
48+
echo "Grace hook: unable to locate repo root; skipping validate." >&2
49+
fi
50+
else
51+
echo "Grace hook: pwsh not found; skipping validate." >&2
52+
fi
53+
"@
54+
55+
Set-Content -Path $Path -Value $hook -Encoding ASCII
56+
}
57+
58+
if ($Uninstall) {
59+
$current = Get-FileContent $hookPath
60+
61+
if ($current -match $marker) {
62+
if (Test-Path $backupPath) {
63+
Copy-Item -Path $backupPath -Destination $hookPath -Force
64+
Remove-Item -Path $backupPath -Force
65+
Write-Host "Restored original pre-commit hook."
66+
} else {
67+
Remove-Item -Path $hookPath -Force
68+
Write-Host "Removed Grace pre-commit hook."
69+
}
70+
} else {
71+
Write-Host "Grace pre-commit hook not installed. No changes made."
72+
}
73+
74+
return
75+
}
76+
77+
$existing = Get-FileContent $hookPath
78+
if ($existing -match $marker) {
79+
Write-Host "Grace pre-commit hook already installed."
80+
return
81+
}
82+
83+
if (Test-Path $hookPath) {
84+
if ((Test-Path $backupPath) -and -not $Force) {
85+
throw "Backup already exists at $backupPath. Use -Force to overwrite."
86+
}
87+
88+
Copy-Item -Path $hookPath -Destination $backupPath -Force
89+
}
90+
91+
Write-Hook $hookPath
92+
Write-Host "Installed Grace pre-commit hook (validate -Fast)."
93+
Write-Host "Run with -Uninstall to restore the previous hook."

0 commit comments

Comments
 (0)