Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
1792aaf
feat: Add unit test infrastructure and MeetingHelpers class
BenGWeeks Dec 3, 2025
889640c
feat: Add local development configuration support
BenGWeeks Dec 3, 2025
2bdb256
feat: Add test environment configuration
BenGWeeks Dec 3, 2025
0ca54c4
feat: Add Spot VM support and CI/CD workflow improvements
BenGWeeks Dec 3, 2025
a402863
docs: Add DEVELOPMENT.adoc for developer onboarding
BenGWeeks Dec 3, 2025
d581cfc
Remove Key Vault from bot configuration
BenGWeeks Dec 3, 2025
65608be
Clean up Key Vault references and deployment artifacts
BenGWeeks Dec 3, 2025
6fe1fae
Remove Key Vault references from deploy workflow
BenGWeeks Dec 3, 2025
de3233b
Remove Key Vault references from deployment scripts
BenGWeeks Dec 3, 2025
4fbcc88
Update deploy-teams-app.sh to use environment variables
BenGWeeks Dec 3, 2025
fa7825f
Update documentation for GitHub Secrets (remove Key Vault refs)
BenGWeeks Dec 3, 2025
72d22a4
Update DEPLOYMENT.adoc: Remove Key Vault refs and Phase terminology
BenGWeeks Dec 3, 2025
f47188c
Remove production values from appsettings.json
BenGWeeks Dec 3, 2025
fcd7af5
Fix Bicep templates for test environment deployment
BenGWeeks Dec 3, 2025
4131a16
Remove teamsAppId parameter from workflow Bicep deployment
BenGWeeks Dec 3, 2025
83e991b
Enable per-environment infrastructure deployment, convert brand guide…
BenGWeeks Dec 3, 2025
3dbe6f1
docs: Document GitHub Actions RBAC requirements for new environments
BenGWeeks Dec 3, 2025
0a7d3c8
fix: Use job outputs for environment-scoped variables in workflow con…
BenGWeeks Dec 3, 2025
dd3b92b
refactor: Change Bicep to resource group scope for restricted permiss…
BenGWeeks Dec 3, 2025
c1030b3
fix: Make AI services optional, fix storage account name length
BenGWeeks Dec 3, 2025
0fea22c
docs: Add first-time environment setup section to DEPLOYMENT.adoc
BenGWeeks Dec 3, 2025
63ca4b4
feat: Add deployVM and useSpotVM parameters for test environment
BenGWeeks Dec 4, 2025
7500df7
docs: Add environment separation info to CLAUDE.md
BenGWeeks Dec 4, 2025
7c2d202
fix: Include deploy script in package to avoid command line too long …
BenGWeeks Dec 4, 2025
aa9b809
fix: Fix parameter passing in deploy workflow for VM run-command
BenGWeeks Dec 4, 2025
9a15e27
fix: Use double-quoted here-string to embed package URL directly
BenGWeeks Dec 4, 2025
a6f975f
fix: Use single quotes for paths in VM script to prevent quote stripping
BenGWeeks Dec 4, 2025
b9e9243
fix: Use double quotes for PackageUrl to enable variable expansion
BenGWeeks Dec 4, 2025
ce1863c
fix: Use Base64 encoding for package URL to handle SAS URL special ch…
BenGWeeks Dec 4, 2025
f2e8ecc
fix: Use temp file and string replace for VM script to avoid escaping…
BenGWeeks Dec 4, 2025
b3b4d95
fix: Write Base64 URL to file on VM before running deploy script
BenGWeeks Dec 4, 2025
c13c915
fix: Refactor VM deployment into sequential single-line commands
BenGWeeks Dec 4, 2025
215100b
fix: Update deploy script for pre-built binaries and NSSM auto-install
BenGWeeks Dec 4, 2025
6952ec8
feat: Add secret injection to deploy workflow and fix ReDoS vulnerabi…
BenGWeeks Dec 4, 2025
a24c38f
Security: Add SSL setup, secure VM password, restrict RDP access
BenGWeeks Dec 4, 2025
2c2a8f1
docs: Add troubleshooting entries for SSL, RDP, and VM password fixes
BenGWeeks Dec 4, 2025
741a48e
fix: Configure Kestrel SSL instead of HTTP.sys in deploy workflow
BenGWeeks Dec 4, 2025
8f707a5
Add Azure Bot registration to deployment workflow
BenGWeeks Dec 4, 2025
3e42d6f
fix: Use environment-specific backend URL in deploy workflow
BenGWeeks Dec 4, 2025
5a1e841
fix: Correct regex pattern for meeting ID extraction
BenGWeeks Dec 4, 2025
4b01a6a
feat: Implement smoke tests in deployment workflow
BenGWeeks Dec 4, 2025
e0aa9b5
feat: Extract bot config to script with null safety + add Spot VM docs
BenGWeeks Dec 4, 2025
a124eaa
fix: PowerShell escaping in SSL certificate step
BenGWeeks Dec 4, 2025
eb5689e
fix: Use environment-specific resource groups in deploy workflow
BenGWeeks Dec 4, 2025
868f804
fix: Add --app-type parameter to az bot create command
BenGWeeks Dec 4, 2025
7d65201
fix: Remove incompatible --app-type and --sku from az bot create
BenGWeeks Dec 4, 2025
56b69f0
fix: Use modern az bot create syntax with --app-type
BenGWeeks Dec 4, 2025
ebc1a9d
Fix bot registration: Use SingleTenant instead of deprecated MultiTenant
BenGWeeks Dec 4, 2025
732aa4e
Add Azure OpenAI configuration to bot deployment
BenGWeeks Dec 4, 2025
e89725a
Fix Azure OpenAI settings not being passed to VM
BenGWeeks Dec 4, 2025
e789943
fix: Base64-encode all secrets for VM configuration
BenGWeeks Dec 4, 2025
d03f6ca
fix: Address PR review issues
BenGWeeks Dec 4, 2025
5511ffe
feat: Add Let's Encrypt SSL certificate support
BenGWeeks Dec 4, 2025
683a67e
refactor: Standardize config keys to use underscores
BenGWeeks Dec 4, 2025
3526827
fix: Add secret masking and fix Bicep linter warnings
BenGWeeks Dec 4, 2025
52961a9
refactor: Remove backup/restore, use GitHub Secrets for all config
BenGWeeks Dec 4, 2025
2057e24
fix: Embed Base64 values directly in script (--parameters unreliable)
BenGWeeks Dec 4, 2025
d7508af
fix: Suppress Bicep linter warnings (issue #74)
BenGWeeks Dec 4, 2025
4c1867e
debug: Add secret length debugging to identify empty secrets
BenGWeeks Dec 4, 2025
0e0a36c
fix: remove curly braces from inline PowerShell scripts in deploy.yml
BenGWeeks Dec 4, 2025
c526c01
fix: use PowerShell subexpression syntax for variable interpolation
BenGWeeks Dec 4, 2025
9512e8a
feat: add port 80 to NSG for Let's Encrypt ACME challenge
BenGWeeks Dec 4, 2025
d647322
fix: Remove apostrophe in NSG description to fix Bicep syntax error
BenGWeeks Dec 4, 2025
ace48c2
fix: Set UseApplicationHostedMedia default to false
BenGWeeks Dec 4, 2025
8038146
fix: Add Windows Firewall rule for port 80 in configure-ssl.ps1
BenGWeeks Dec 5, 2025
39c670a
fix: Improve NSSM detection to find Chocolatey-installed version
BenGWeeks Dec 5, 2025
eb3cdef
docs: Add troubleshooting for appsettings.json overwrite issue
BenGWeeks Dec 5, 2025
a71b4a3
ci: Add Azure OpenAI RBAC grant step and troubleshooting docs
BenGWeeks Dec 5, 2025
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
7 changes: 4 additions & 3 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,10 @@ AZURE_DEVOPS_ORG=your-org-name
AZURE_DEVOPS_PAT=abcdef1234567890abcdef1234567890abcdef1234567890

# Microsoft Teams Bot
# Note: TEAMS_APP_ID and TEAMS_APP_PASSWORD are stored in Key Vault, not .env
# The bot loads credentials from Key Vault at runtime using managed identity
AZURE_KEY_VAULT_NAME=your-key-vault-name
# Note: TEAMS_APP_ID and TEAMS_APP_PASSWORD are managed via GitHub Secrets
# and set as environment variables during deployment
TEAMS_APP_ID=your-teams-app-id
TEAMS_APP_PASSWORD=your-teams-app-password

# Local Development
PORT=8000
Expand Down
487 changes: 412 additions & 75 deletions .github/workflows/deploy.yml

Large diffs are not rendered by default.

29 changes: 23 additions & 6 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ jobs:
unit-tests:
name: Unit Tests
runs-on: ubuntu-latest
needs: [build-bot]

steps:
- name: Checkout code
Expand All @@ -83,19 +82,37 @@ jobs:
with:
dotnet-version: ${{ env.DOTNET_VERSION }}

- name: Run tests
- name: Restore dependencies
run: dotnet restore ./Pennie.sln

- name: Build solution
run: dotnet build ./Pennie.sln --configuration Release --no-restore

- name: Run unit tests
run: |
# TODO: Implement unit tests
# dotnet test ./tests/unit/ --configuration Release --collect:"XPlat Code Coverage"
echo "Unit tests would run here"
dotnet test ./tests/PennieBot.Tests.csproj \
--configuration Release \
--no-build \
--verbosity normal \
--logger "trx;LogFileName=test-results.trx" \
--collect:"XPlat Code Coverage" \
--results-directory ./TestResults

- name: Upload test results
if: always()
uses: actions/upload-artifact@v4
with:
name: test-results
path: ./TestResults

- name: Upload coverage
if: always()
uses: codecov/codecov-action@v4
with:
files: ./coverage.xml
directory: ./TestResults
flags: unittests
name: codecov-umbrella
fail_ci_if_error: false

validate-bicep:
name: Validate Bicep Templates
Expand Down
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
.env.*.local
*.env

# Local development config (contains secrets)
appsettings.local.json
bot/appsettings.local.json

# Azure and Keys
*.pfx
*.p12
Expand Down Expand Up @@ -118,3 +122,4 @@ ApplicationInsights.config
bot/*.zip
bot/publish-*/
bot/teams-manifest/*.zip
src/*.zip
20 changes: 16 additions & 4 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,14 +105,26 @@ Pennie uses Microsoft's official Azure DevOps MCP Server for work item operation

## Deployment Strategy

### Target Environment (KnowAll Ltd - Internal Deployment)
- **Resource Group**: `TMinus15Agents` (existing in KnowAll Ltd tenant)
### Target Environments (KnowAll Ltd - Internal Deployment)

**CRITICAL: Each environment uses a SEPARATE resource group. Never deploy test to prod or vice versa.**

| Environment | Resource Group | VM Name | Description |
|-------------|----------------|---------|-------------|
| **Production** | `TMinus15Agents` | `pennie-vm-prod` | Live production environment |
| **Test** | `TMinus15Agents-Test` | `pennie-vm-test` | Test/staging environment (uses Spot VM) |

- **Location**: `uksouth` (single-region deployment for UK data residency)
- **Subscription**: See `.env` file (not committed to Git)
- **AI Hub**: `knowall-ai-foundry` (existing, UK South)
- **AI Project**: `T-Minus-15 Agents` (existing)
- **OpenAI Model**: GPT-4o (2024-08-06) - verified available in UK South

**GitHub Environment Configuration**:
- Each GitHub environment (`prod`, `test`) has its own `AZURE_RESOURCE_GROUP` secret
- The workflow reads from the environment-scoped secret, not a repo-level secret
- Test environment uses Spot VM (`useSpotVM: true`) for 60-80% cost savings

**Note for Other Deployers**: This is KnowAll's internal configuration. Choose your own region based on compliance needs. GPT-4o is available in UK South, East US 2, Sweden Central, and other regions.

### Deployment Scripts
Expand Down Expand Up @@ -146,7 +158,7 @@ az deployment sub create \
--template-file infra/main.bicep \
--parameters environmentName=prod
```
- Deploys AI Foundry Hub, Project, Storage, Key Vault, Monitoring
- Deploys AI Foundry Hub, Project, Storage, Monitoring
- Windows VM for Teams Bot (future phase)

### GitHub Actions Workflow
Expand Down Expand Up @@ -179,7 +191,7 @@ Values already configured in `.env`:

- All components must reside within the organization's Azure tenant
- No external services required
- Secrets managed via GitHub Secrets and Azure Key Vault
- Secrets managed via GitHub Secrets (set as environment variables during deployment)
- Authentication uses managed identity, not PAT tokens where possible

## Repository Structure
Expand Down
25 changes: 25 additions & 0 deletions Pennie.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PennieBot", "bot\PennieBot.csproj", "{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PennieBot.Tests", "tests\PennieBot.Tests.csproj", "{B2C3D4E5-F6A7-8901-BCDE-F23456789012}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}.Release|Any CPU.Build.0 = Release|Any CPU
{B2C3D4E5-F6A7-8901-BCDE-F23456789012}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B2C3D4E5-F6A7-8901-BCDE-F23456789012}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B2C3D4E5-F6A7-8901-BCDE-F23456789012}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B2C3D4E5-F6A7-8901-BCDE-F23456789012}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
2 changes: 1 addition & 1 deletion agent-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@
"owner": "Ben Weeks",
"owner_email": "ben.weeks@outlook.com",
"license": "MIT",
"repository": "https://github.com/benweeks/GetPenn.ie",
"repository": "https://github.com/KnowAll-AI/GetPenn.ie",
"deployment_region": "uksouth",
"model_info": {
"name": "GPT-4o",
Expand Down
Loading
Loading