From be71b209410761606ac00a168d051433e0d3a4c4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 10 Sep 2025 16:00:38 +0000 Subject: [PATCH 1/5] Initial plan From 5c04b1132708f9c67abc77f7d6f284950711ac2f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 10 Sep 2025 16:09:57 +0000 Subject: [PATCH 2/5] Implement devcontainer authentication for private NuGet feed Co-authored-by: BenjaminMichaelis <22186029+BenjaminMichaelis@users.noreply.github.com> --- .devcontainer/.env.template | 7 ++ .devcontainer/README.md | 114 ++++++++++++++++++++++++++++++ .devcontainer/devcontainer.json | 16 ++++- .devcontainer/setup-nuget-auth.sh | 52 ++++++++++++++ .gitignore | 9 ++- 5 files changed, 193 insertions(+), 5 deletions(-) create mode 100644 .devcontainer/.env.template create mode 100644 .devcontainer/README.md create mode 100755 .devcontainer/setup-nuget-auth.sh diff --git a/.devcontainer/.env.template b/.devcontainer/.env.template new file mode 100644 index 00000000..b9bd2061 --- /dev/null +++ b/.devcontainer/.env.template @@ -0,0 +1,7 @@ +# Template for devcontainer environment variables +# Copy this file to .env and fill in your values + +# Azure DevOps Personal Access Token (PAT) with Packaging (read) permissions +# Get this from: https://dev.azure.com/intelliTect/_usersSettings/tokens +# Required permissions: Packaging (read) +AZURE_DEVOPS_PAT=your_pat_token_here \ No newline at end of file diff --git a/.devcontainer/README.md b/.devcontainer/README.md new file mode 100644 index 00000000..628371f1 --- /dev/null +++ b/.devcontainer/README.md @@ -0,0 +1,114 @@ +# DevContainer Setup for EssentialCSharp.Web + +This project includes a DevContainer configuration for development with Visual Studio Code and GitHub Codespaces. + +## Prerequisites + +- [Visual Studio Code](https://code.visualstudio.com/) with the [Remote-Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) +- [Docker Desktop](https://www.docker.com/products/docker-desktop) (for local development) + +## Private NuGet Feed Authentication + +This project uses a private Azure DevOps NuGet feed for some packages. To access these packages, you need to set up authentication. + +### For GitHub Codespaces + +1. Create a Personal Access Token (PAT) in Azure DevOps: + - Go to https://dev.azure.com/intelliTect/_usersSettings/tokens + - Click "New Token" + - Name: "EssentialCSharp DevContainer" + - Scopes: Select "Packaging (read)" + - Click "Create" + +2. Add the token as a Codespace secret: + - Go to your GitHub repository settings + - Navigate to "Codespaces" → "Repository secrets" + - Click "New repository secret" + - Name: `AZURE_DEVOPS_PAT` + - Value: Your Azure DevOps PAT + +### For Local Development + +1. Create a Personal Access Token (PAT) in Azure DevOps (same as above) + +2. Create a `.env` file in the `.devcontainer` directory: + ```bash + cp .devcontainer/.env.template .devcontainer/.env + ``` + +3. Edit `.devcontainer/.env` and replace `your_pat_token_here` with your actual PAT: + ``` + AZURE_DEVOPS_PAT=your_actual_pat_token_here + ``` + +⚠️ **Important**: Never commit the `.env` file to source control as it contains sensitive information. + +## Opening the DevContainer + +### In VS Code (Local) +1. Open the repository in VS Code +2. When prompted, click "Reopen in Container" +3. Or use Command Palette (Ctrl+Shift+P): "Remote-Containers: Reopen in Container" + +### In GitHub Codespaces +1. Click the "Code" button on the GitHub repository +2. Select "Codespaces" tab +3. Click "Create codespace on main" + +## What Happens During Setup + +The DevContainer will automatically: + +1. Install the .NET 9.0 SDK +2. Install Azure Artifacts Credential Provider +3. Configure NuGet authentication (if PAT is provided) +4. Restore NuGet packages +5. Set up VS Code extensions for C# development + +## Troubleshooting + +### Package Restoration Fails + +If package restoration fails: + +1. **Check your PAT**: Ensure it has "Packaging (read)" permissions +2. **Verify the PAT**: Test it manually with: + ```bash + curl -u :YOUR_PAT https://dev.azure.com/intelliTect/_apis/packaging/feeds + ``` +3. **Check environment**: Ensure `AZURE_DEVOPS_PAT` is set correctly + +### DevContainer Won't Start + +1. **Check Docker**: Ensure Docker Desktop is running +2. **Check VS Code Extensions**: Ensure Remote-Containers extension is installed +3. **Rebuild Container**: Use Command Palette: "Remote-Containers: Rebuild Container" + +### No Access to Private Packages + +If you don't have access to the private Azure DevOps feed: + +1. The setup script will automatically set `AccessToNugetFeed=false` +2. Private packages will be excluded from the build +3. The project will still build and run with public packages only + +## Available Commands + +Once the DevContainer is running, you can use these commands: + +```bash +# Restore packages +dotnet restore + +# Build the solution +dotnet build + +# Run tests +dotnet test + +# Run the web application +dotnet run --project EssentialCSharp.Web + +# Run the chat application +dotnet run --project EssentialCSharp.Chat +``` \ No newline at end of file diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index aecaa942..89904fd0 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -2,8 +2,20 @@ "image": "mcr.microsoft.com/devcontainers/dotnet", "features": { "ghcr.io/devcontainers/features/dotnet:2": { - "version": "latest" + "version": "9.0" } }, - "postCreateCommand": "dotnet --list-sdks" + "containerEnv": { + "ACCESS_TO_NUGET_FEED": "true" + }, + "postCreateCommand": ".devcontainer/setup-nuget-auth.sh", + "customizations": { + "vscode": { + "extensions": [ + "ms-dotnettools.csharp", + "ms-dotnettools.csdevkit" + ] + } + }, + "remoteUser": "vscode" } diff --git a/.devcontainer/setup-nuget-auth.sh b/.devcontainer/setup-nuget-auth.sh new file mode 100755 index 00000000..5c971ac0 --- /dev/null +++ b/.devcontainer/setup-nuget-auth.sh @@ -0,0 +1,52 @@ +#!/bin/bash +set -e + +echo "Setting up NuGet authentication for Azure DevOps..." + +# Load environment variables from .env file if it exists +if [ -f ".devcontainer/.env" ]; then + echo "Loading environment variables from .devcontainer/.env..." + export $(grep -v '^#' .devcontainer/.env | xargs) +fi + +# Install Azure Artifacts Credential Provider +echo "Installing Azure Artifacts Credential Provider..." +if ! sh -c "$(curl -fsSL https://aka.ms/install-artifacts-credprovider.sh)" 2>/dev/null; then + echo "⚠️ Could not download Azure Artifacts Credential Provider installer." + echo "This may be due to network restrictions. The provider will be installed later if needed." +fi + +# Check if AZURE_DEVOPS_PAT is set +if [ -z "$AZURE_DEVOPS_PAT" ]; then + echo "" + echo "⚠️ AZURE_DEVOPS_PAT environment variable is not set." + echo "To enable private NuGet feed access, you need to:" + echo "1. Create a Personal Access Token (PAT) in Azure DevOps with 'Packaging (read)' permissions" + echo "2. Add it to your devcontainer environment by creating a .devcontainer/.env file:" + echo " AZURE_DEVOPS_PAT=your_pat_token_here" + echo "3. Or set it as a codespace secret named 'AZURE_DEVOPS_PAT'" + echo "" + echo "For now, setting AccessToNugetFeed=false to allow restore without private packages..." + export ACCESS_TO_NUGET_FEED=false +else + echo "AZURE_DEVOPS_PAT found, setting up authentication..." + # Set up the credential provider environment + export VSS_NUGET_EXTERNAL_FEED_ENDPOINTS="{\"endpointCredentials\": [{\"endpoint\":\"https://pkgs.dev.azure.com/intelliTect/_packaging/EssentialCSharp/nuget/v3/index.json\", \"password\":\"$AZURE_DEVOPS_PAT\"}]}" + export ACCESS_TO_NUGET_FEED=true + echo "✅ NuGet authentication configured for Azure DevOps private feed" +fi + +# Display .NET version +echo "Checking .NET SDK version..." +dotnet --version + +# Try to restore packages +echo "Attempting to restore NuGet packages..." +if dotnet restore -p:AccessToNugetFeed=$ACCESS_TO_NUGET_FEED; then + echo "✅ Package restoration successful!" +else + echo "❌ Package restoration failed. Check your Azure DevOps PAT if you need private packages." + exit 1 +fi + +echo "🎉 Devcontainer setup complete!" \ No newline at end of file diff --git a/.gitignore b/.gitignore index e3ef6bcf..e67eb8a4 100644 --- a/.gitignore +++ b/.gitignore @@ -277,6 +277,9 @@ FodyWeavers.xsd # JetBrains Rider *.sln.iml -EssentialCSharp.Web/Markdown/ - -EssentialCSharp.Web/Guidelines/ +EssentialCSharp.Web/Markdown/ + +EssentialCSharp.Web/Guidelines/ + +# DevContainer environment files with sensitive data +.devcontainer/.env From 9fba55cf51148ab895611fd7d9b07d451b64c2a3 Mon Sep 17 00:00:00 2001 From: Benjamin Michaelis Date: Sat, 20 Sep 2025 11:20:58 -0700 Subject: [PATCH 3/5] Update .devcontainer/setup-nuget-auth.sh Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .devcontainer/setup-nuget-auth.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/setup-nuget-auth.sh b/.devcontainer/setup-nuget-auth.sh index 5c971ac0..e76473fc 100755 --- a/.devcontainer/setup-nuget-auth.sh +++ b/.devcontainer/setup-nuget-auth.sh @@ -6,7 +6,7 @@ echo "Setting up NuGet authentication for Azure DevOps..." # Load environment variables from .env file if it exists if [ -f ".devcontainer/.env" ]; then echo "Loading environment variables from .devcontainer/.env..." - export $(grep -v '^#' .devcontainer/.env | xargs) + set -o allexport; source .devcontainer/.env; set +o allexport fi # Install Azure Artifacts Credential Provider From a97396ca795a3bde39b73a447c67b830bef01dd0 Mon Sep 17 00:00:00 2001 From: Benjamin Michaelis Date: Sat, 20 Sep 2025 11:21:22 -0700 Subject: [PATCH 4/5] Delete .devcontainer/README.md --- .devcontainer/README.md | 114 ---------------------------------------- 1 file changed, 114 deletions(-) delete mode 100644 .devcontainer/README.md diff --git a/.devcontainer/README.md b/.devcontainer/README.md deleted file mode 100644 index 628371f1..00000000 --- a/.devcontainer/README.md +++ /dev/null @@ -1,114 +0,0 @@ -# DevContainer Setup for EssentialCSharp.Web - -This project includes a DevContainer configuration for development with Visual Studio Code and GitHub Codespaces. - -## Prerequisites - -- [Visual Studio Code](https://code.visualstudio.com/) with the [Remote-Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) -- [Docker Desktop](https://www.docker.com/products/docker-desktop) (for local development) - -## Private NuGet Feed Authentication - -This project uses a private Azure DevOps NuGet feed for some packages. To access these packages, you need to set up authentication. - -### For GitHub Codespaces - -1. Create a Personal Access Token (PAT) in Azure DevOps: - - Go to https://dev.azure.com/intelliTect/_usersSettings/tokens - - Click "New Token" - - Name: "EssentialCSharp DevContainer" - - Scopes: Select "Packaging (read)" - - Click "Create" - -2. Add the token as a Codespace secret: - - Go to your GitHub repository settings - - Navigate to "Codespaces" → "Repository secrets" - - Click "New repository secret" - - Name: `AZURE_DEVOPS_PAT` - - Value: Your Azure DevOps PAT - -### For Local Development - -1. Create a Personal Access Token (PAT) in Azure DevOps (same as above) - -2. Create a `.env` file in the `.devcontainer` directory: - ```bash - cp .devcontainer/.env.template .devcontainer/.env - ``` - -3. Edit `.devcontainer/.env` and replace `your_pat_token_here` with your actual PAT: - ``` - AZURE_DEVOPS_PAT=your_actual_pat_token_here - ``` - -⚠️ **Important**: Never commit the `.env` file to source control as it contains sensitive information. - -## Opening the DevContainer - -### In VS Code (Local) -1. Open the repository in VS Code -2. When prompted, click "Reopen in Container" -3. Or use Command Palette (Ctrl+Shift+P): "Remote-Containers: Reopen in Container" - -### In GitHub Codespaces -1. Click the "Code" button on the GitHub repository -2. Select "Codespaces" tab -3. Click "Create codespace on main" - -## What Happens During Setup - -The DevContainer will automatically: - -1. Install the .NET 9.0 SDK -2. Install Azure Artifacts Credential Provider -3. Configure NuGet authentication (if PAT is provided) -4. Restore NuGet packages -5. Set up VS Code extensions for C# development - -## Troubleshooting - -### Package Restoration Fails - -If package restoration fails: - -1. **Check your PAT**: Ensure it has "Packaging (read)" permissions -2. **Verify the PAT**: Test it manually with: - ```bash - curl -u :YOUR_PAT https://dev.azure.com/intelliTect/_apis/packaging/feeds - ``` -3. **Check environment**: Ensure `AZURE_DEVOPS_PAT` is set correctly - -### DevContainer Won't Start - -1. **Check Docker**: Ensure Docker Desktop is running -2. **Check VS Code Extensions**: Ensure Remote-Containers extension is installed -3. **Rebuild Container**: Use Command Palette: "Remote-Containers: Rebuild Container" - -### No Access to Private Packages - -If you don't have access to the private Azure DevOps feed: - -1. The setup script will automatically set `AccessToNugetFeed=false` -2. Private packages will be excluded from the build -3. The project will still build and run with public packages only - -## Available Commands - -Once the DevContainer is running, you can use these commands: - -```bash -# Restore packages -dotnet restore - -# Build the solution -dotnet build - -# Run tests -dotnet test - -# Run the web application -dotnet run --project EssentialCSharp.Web - -# Run the chat application -dotnet run --project EssentialCSharp.Chat -``` \ No newline at end of file From be160fbb66918a5887d7e5a1e2cf1ac5c261d302 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 20 Sep 2025 18:28:13 +0000 Subject: [PATCH 5/5] Implement interactive authentication for devcontainer NuGet access Co-authored-by: BenjaminMichaelis <22186029+BenjaminMichaelis@users.noreply.github.com> --- .devcontainer/.env.template | 7 ---- .devcontainer/devcontainer.json | 3 -- .devcontainer/setup-nuget-auth.sh | 66 ++++++++++++++++--------------- 3 files changed, 34 insertions(+), 42 deletions(-) delete mode 100644 .devcontainer/.env.template diff --git a/.devcontainer/.env.template b/.devcontainer/.env.template deleted file mode 100644 index b9bd2061..00000000 --- a/.devcontainer/.env.template +++ /dev/null @@ -1,7 +0,0 @@ -# Template for devcontainer environment variables -# Copy this file to .env and fill in your values - -# Azure DevOps Personal Access Token (PAT) with Packaging (read) permissions -# Get this from: https://dev.azure.com/intelliTect/_usersSettings/tokens -# Required permissions: Packaging (read) -AZURE_DEVOPS_PAT=your_pat_token_here \ No newline at end of file diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 89904fd0..edbb2ddc 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -5,9 +5,6 @@ "version": "9.0" } }, - "containerEnv": { - "ACCESS_TO_NUGET_FEED": "true" - }, "postCreateCommand": ".devcontainer/setup-nuget-auth.sh", "customizations": { "vscode": { diff --git a/.devcontainer/setup-nuget-auth.sh b/.devcontainer/setup-nuget-auth.sh index e76473fc..1fbd62df 100755 --- a/.devcontainer/setup-nuget-auth.sh +++ b/.devcontainer/setup-nuget-auth.sh @@ -3,50 +3,52 @@ set -e echo "Setting up NuGet authentication for Azure DevOps..." -# Load environment variables from .env file if it exists -if [ -f ".devcontainer/.env" ]; then - echo "Loading environment variables from .devcontainer/.env..." - set -o allexport; source .devcontainer/.env; set +o allexport -fi - # Install Azure Artifacts Credential Provider echo "Installing Azure Artifacts Credential Provider..." -if ! sh -c "$(curl -fsSL https://aka.ms/install-artifacts-credprovider.sh)" 2>/dev/null; then +if sh -c "$(curl -fsSL https://aka.ms/install-artifacts-credprovider.sh)" 2>/dev/null; then + echo "✅ Azure Artifacts Credential Provider installed successfully" +else echo "⚠️ Could not download Azure Artifacts Credential Provider installer." - echo "This may be due to network restrictions. The provider will be installed later if needed." -fi - -# Check if AZURE_DEVOPS_PAT is set -if [ -z "$AZURE_DEVOPS_PAT" ]; then - echo "" - echo "⚠️ AZURE_DEVOPS_PAT environment variable is not set." - echo "To enable private NuGet feed access, you need to:" - echo "1. Create a Personal Access Token (PAT) in Azure DevOps with 'Packaging (read)' permissions" - echo "2. Add it to your devcontainer environment by creating a .devcontainer/.env file:" - echo " AZURE_DEVOPS_PAT=your_pat_token_here" - echo "3. Or set it as a codespace secret named 'AZURE_DEVOPS_PAT'" - echo "" - echo "For now, setting AccessToNugetFeed=false to allow restore without private packages..." + echo "This may be due to network restrictions. Falling back to public packages only." export ACCESS_TO_NUGET_FEED=false -else - echo "AZURE_DEVOPS_PAT found, setting up authentication..." - # Set up the credential provider environment - export VSS_NUGET_EXTERNAL_FEED_ENDPOINTS="{\"endpointCredentials\": [{\"endpoint\":\"https://pkgs.dev.azure.com/intelliTect/_packaging/EssentialCSharp/nuget/v3/index.json\", \"password\":\"$AZURE_DEVOPS_PAT\"}]}" - export ACCESS_TO_NUGET_FEED=true - echo "✅ NuGet authentication configured for Azure DevOps private feed" fi # Display .NET version echo "Checking .NET SDK version..." dotnet --version -# Try to restore packages +# Try to restore packages with interactive authentication if credential provider is available echo "Attempting to restore NuGet packages..." -if dotnet restore -p:AccessToNugetFeed=$ACCESS_TO_NUGET_FEED; then - echo "✅ Package restoration successful!" +if command -v dotnet-credential-provider-installer >/dev/null 2>&1 || [ -n "$(find ~/.nuget -name "*CredentialProvider*" 2>/dev/null | head -1)" ]; then + echo "" + echo "🔐 The credential provider is available for Azure DevOps authentication." + echo "If prompted for credentials during package restoration, you can:" + echo " 1. Use your Azure DevOps account credentials, or" + echo " 2. Create a Personal Access Token (PAT) with 'Packaging (read)' permissions" + echo " from: https://dev.azure.com/intelliTect/_usersSettings/tokens" + echo "" + + # First try to restore with interactive authentication for private packages + if dotnet restore --interactive -p:AccessToNugetFeed=true; then + echo "✅ Package restoration successful with private feed access!" + else + echo "⚠️ Private package restoration failed or was cancelled." + echo "Falling back to public packages only..." + if dotnet restore -p:AccessToNugetFeed=false; then + echo "✅ Package restoration successful with public packages only!" + else + echo "❌ Package restoration failed completely." + exit 1 + fi + fi else - echo "❌ Package restoration failed. Check your Azure DevOps PAT if you need private packages." - exit 1 + echo "Credential provider not available, using public packages only..." + if dotnet restore -p:AccessToNugetFeed=false; then + echo "✅ Package restoration successful with public packages only!" + else + echo "❌ Package restoration failed." + exit 1 + fi fi echo "🎉 Devcontainer setup complete!" \ No newline at end of file