Skip to content

Commit 64cd37b

Browse files
CopilotBenjaminMichaelisCopilot
authored
Fix devcontainer to properly restore projects with private NuGet feed using interactive authentication (#778)
The devcontainer configuration was missing authentication setup for the private Azure DevOps NuGet feed, preventing proper package restoration when using GitHub Codespaces or local devcontainer development. ## Problem The existing devcontainer would fail to restore packages that depend on private NuGet packages from the Azure DevOps feed (`https://pkgs.dev.azure.com/intelliTect/_packaging/EssentialCSharp/nuget/v3/index.json`). This affected packages like: - `ContentFeedNuget` - `EssentialCSharp.Shared.Models` ## Solution This PR implements a secure interactive authentication solution using Microsoft's recommended approach for Azure Artifacts Credential Provider: ### Key Changes 1. **Enhanced devcontainer.json**: - Updated to use .NET 9.0 SDK specifically - Added VS Code C# extensions for better development experience - Added post-create command for automated setup - Removed hardcoded environment variables for cleaner configuration 2. **Interactive Authentication Setup**: - Created `setup-nuget-auth.sh` script that: - Installs Azure Artifacts Credential Provider automatically - Uses `dotnet restore --interactive` for secure credential prompting - Gracefully falls back to public packages only when authentication fails - Provides clear user guidance for authentication options 3. **Developer Experience**: - Secure interactive authentication - no need to store PATs in files or environment variables - Automatic fallback to public packages when private authentication is unavailable - Clear user prompts and guidance during setup - Follows Microsoft's recommended authentication patterns ### Authentication Options **Interactive Authentication**: When prompted during package restoration, users can: 1. Use their Azure DevOps account credentials, or 2. Create a Personal Access Token (PAT) with 'Packaging (read)' permissions from https://dev.azure.com/intelliTect/_usersSettings/tokens ### Backward Compatibility The solution is fully backward compatible: - Developers without private feed access can still use the devcontainer - The setup script automatically falls back to public packages when authentication fails - All public packages restore normally without any user interaction required ### Testing - ✅ Package restoration works without authentication (public packages only) - ✅ Interactive authentication works for private packages - ✅ Build and tests pass successfully - ✅ Graceful handling of network restrictions and missing dependencies - ✅ Secure credential handling with no storage of sensitive information This brings the devcontainer authentication in line with Microsoft's recommended security practices while ensuring consistent development environments across local development, Codespaces, and CI/CD pipelines. <!-- START COPILOT CODING AGENT SUFFIX --> <!-- START COPILOT CODING AGENT TIPS --> --- ✨ Let Copilot coding agent [set things up for you](https://github.com/IntelliTect/EssentialCSharp.Web/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot) — coding agent works faster and does higher quality work when set up for your repo. --------- Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: BenjaminMichaelis <[email protected]> Co-authored-by: Benjamin Michaelis <[email protected]> Co-authored-by: Copilot <[email protected]>
1 parent ac761c8 commit 64cd37b

File tree

3 files changed

+71
-5
lines changed

3 files changed

+71
-5
lines changed

.devcontainer/devcontainer.json

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,17 @@
22
"image": "mcr.microsoft.com/devcontainers/dotnet",
33
"features": {
44
"ghcr.io/devcontainers/features/dotnet:2": {
5-
"version": "latest"
5+
"version": "9.0"
66
}
77
},
8-
"postCreateCommand": "dotnet --list-sdks"
8+
"postCreateCommand": ".devcontainer/setup-nuget-auth.sh",
9+
"customizations": {
10+
"vscode": {
11+
"extensions": [
12+
"ms-dotnettools.csharp",
13+
"ms-dotnettools.csdevkit"
14+
]
15+
}
16+
},
17+
"remoteUser": "vscode"
918
}

.devcontainer/setup-nuget-auth.sh

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#!/bin/bash
2+
set -e
3+
4+
echo "Setting up NuGet authentication for Azure DevOps..."
5+
6+
# Install Azure Artifacts Credential Provider
7+
echo "Installing Azure Artifacts Credential Provider..."
8+
if sh -c "$(curl -fsSL https://aka.ms/install-artifacts-credprovider.sh)" 2>/dev/null; then
9+
echo "✅ Azure Artifacts Credential Provider installed successfully"
10+
else
11+
echo "⚠️ Could not download Azure Artifacts Credential Provider installer."
12+
echo "This may be due to network restrictions. Falling back to public packages only."
13+
export ACCESS_TO_NUGET_FEED=false
14+
fi
15+
16+
# Display .NET version
17+
echo "Checking .NET SDK version..."
18+
dotnet --version
19+
20+
# Try to restore packages with interactive authentication if credential provider is available
21+
echo "Attempting to restore NuGet packages..."
22+
if command -v dotnet-credential-provider-installer >/dev/null 2>&1 || [ -n "$(find ~/.nuget -name "*CredentialProvider*" 2>/dev/null | head -1)" ]; then
23+
echo ""
24+
echo "🔐 The credential provider is available for Azure DevOps authentication."
25+
echo "If prompted for credentials during package restoration, you can:"
26+
echo " 1. Use your Azure DevOps account credentials, or"
27+
echo " 2. Create a Personal Access Token (PAT) with 'Packaging (read)' permissions"
28+
echo " from: https://dev.azure.com/intelliTect/_usersSettings/tokens"
29+
echo ""
30+
31+
# First try to restore with interactive authentication for private packages
32+
if dotnet restore --interactive -p:AccessToNugetFeed=true; then
33+
echo "✅ Package restoration successful with private feed access!"
34+
else
35+
echo "⚠️ Private package restoration failed or was cancelled."
36+
echo "Falling back to public packages only..."
37+
if dotnet restore -p:AccessToNugetFeed=false; then
38+
echo "✅ Package restoration successful with public packages only!"
39+
else
40+
echo "❌ Package restoration failed completely."
41+
exit 1
42+
fi
43+
fi
44+
else
45+
echo "Credential provider not available, using public packages only..."
46+
if dotnet restore -p:AccessToNugetFeed=false; then
47+
echo "✅ Package restoration successful with public packages only!"
48+
else
49+
echo "❌ Package restoration failed."
50+
exit 1
51+
fi
52+
fi
53+
54+
echo "🎉 Devcontainer setup complete!"

.gitignore

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,9 @@ FodyWeavers.xsd
277277
# JetBrains Rider
278278
*.sln.iml
279279

280-
EssentialCSharp.Web/Markdown/
281-
282-
EssentialCSharp.Web/Guidelines/
280+
EssentialCSharp.Web/Markdown/
281+
282+
EssentialCSharp.Web/Guidelines/
283+
284+
# DevContainer environment files with sensitive data
285+
.devcontainer/.env

0 commit comments

Comments
 (0)