Skip to content

Commit 74b0f84

Browse files
Feature/use GitHub codespaces prebuilds (#47)
1 parent 92d781a commit 74b0f84

File tree

6 files changed

+304
-14
lines changed

6 files changed

+304
-14
lines changed

.devcontainer/README.md

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,28 @@ This directory contains the GitHub Dev Container configuration for the APIM Samp
44

55
## 🚀 Quick Start
66

7-
### Using GitHub Codespaces
7+
### Using GitHub Codespaces (Recommended)
8+
9+
This repository is optimized for GitHub Codespaces prebuilds, which significantly reduces startup time:
810

911
1. Navigate to the repository on GitHub
1012
2. Click the green "Code" button
1113
3. Select "Codespaces" tab
1214
4. Click "Create codespace on main"
13-
5. Wait for the environment to build and initialize
15+
5. The prebuild will provide a fast startup experience
16+
6. Run the interactive Azure CLI configuration when prompted
17+
18+
### Prebuild Optimization
19+
20+
The dev container is configured with the following optimization strategy:
21+
22+
- **`onCreateCommand`**: Runs during prebuild creation, installing packages, dependencies, and setting up the environment
23+
- **`postStartCommand`**: Runs when starting a codespace from prebuild, handling only interactive configuration and verification
24+
25+
This approach ensures:
26+
- Fast codespace creation (leverages prebuild)
27+
- Minimal setup time on codespace start
28+
- Interactive Azure CLI configuration when needed
1429

1530
### Using VS Code Dev Containers
1631

.devcontainer/devcontainer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@
6262
"containerEnv": {
6363
"PYTHONPATH": "/workspaces/Apim-Samples/shared/python:/workspaces/Apim-Samples"
6464
},
65-
"postCreateCommand": "bash .devcontainer/setup.sh",
65+
"onCreateCommand": "bash .devcontainer/setup-prebuild.sh",
66+
"postStartCommand": "bash .devcontainer/post-start.sh",
6667
"forwardPorts": [
6768
8000,
6869
8080,

.devcontainer/post-start.sh

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
#!/bin/bash
2+
3+
# ------------------------------
4+
# POST-START VERIFICATION
5+
# ------------------------------
6+
7+
echo ""
8+
echo ""
9+
echo ""
10+
echo "🚀 APIM Samples environment starting..."
11+
12+
# Check if this is a prebuild-created environment
13+
if [ -f ".devcontainer/.prebuild-complete" ]; then
14+
echo "✅ Detected prebuild environment - skipping heavy setup"
15+
PREBUILD_ENV=true
16+
else
17+
echo "⚠️ No prebuild detected - running full setup"
18+
PREBUILD_ENV=false
19+
fi
20+
21+
# ------------------------------
22+
# INTERACTIVE AZURE SETUP
23+
# ------------------------------
24+
25+
if [ "$PREBUILD_ENV" = "false" ]; then
26+
echo "🔧 Running full setup (no prebuild detected)..."
27+
bash .devcontainer/setup.sh
28+
else
29+
echo "🔧 Running Azure CLI interactive configuration..."
30+
31+
# Only run the interactive Azure configuration part
32+
if [ -t 0 ] && [ -t 1 ]; then
33+
export APIM_SAMPLES_INITIAL_SETUP=true
34+
python3 .devcontainer/configure-azure-mount.py
35+
unset APIM_SAMPLES_INITIAL_SETUP
36+
37+
echo ""
38+
echo "⚠️ IMPORTANT: If you chose to mount Azure CLI config, you'll need to:"
39+
echo " 1. Exit this container"
40+
echo " 2. Rebuild the dev container to apply the mount configuration"
41+
echo " 3. The container will restart with your Azure CLI authentication available"
42+
echo ""
43+
else
44+
echo "⚠️ Non-interactive environment detected."
45+
echo " You can run the Azure CLI configuration later with:"
46+
echo " python3 .devcontainer/configure-azure-mount.py"
47+
echo ""
48+
fi
49+
fi
50+
51+
# ------------------------------
52+
# QUICK VERIFICATION
53+
# ------------------------------
54+
55+
echo " ✅ Verifying Python environment..."
56+
python --version
57+
58+
echo ""
59+
echo " ✅ Verifying Azure CLI..."
60+
az --version | head -1
61+
62+
echo ""
63+
echo " ✅ Verifying Python packages..."
64+
python -c "import requests, jwt; print('✅ Core packages available')" || echo "⚠️ Some packages may need reinstalling"
65+
66+
echo ""
67+
echo " ✅ Running environment verification..."
68+
python .devcontainer/verify-setup.py
69+
70+
echo ""
71+
echo " 🎉 APIM Samples environment is ready!"
72+
echo ""
73+
74+
# ------------------------------
75+
# NEXT STEPS GUIDANCE
76+
# ------------------------------
77+
78+
echo "📋 Next steps:"
79+
echo ""
80+
if [ -f ".devcontainer/devcontainer.json" ] && grep -q '"mounts"' .devcontainer/devcontainer.json; then
81+
echo " ✅ Azure CLI config mounting detected - your authentication should be available"
82+
echo ""
83+
echo "1. Verify Azure access and ensure correct tenant/subscription: az account show"
84+
echo "2. If needed, switch tenant: az login --tenant <your-tenant-id-or-domain>"
85+
echo "3. If needed, set subscription: az account set --subscription <your-subscription-id-or-name>"
86+
echo "4. Execute shared/jupyter/verify-az-account.ipynb to verify your Azure setup"
87+
else
88+
echo ""
89+
echo "1. Sign in to your specific Azure tenant: az login --tenant <your-tenant-id-or-domain>"
90+
echo "2. Set your target subscription: az account set --subscription <your-subscription-id-or-name>"
91+
echo "3. Verify your context: az account show"
92+
echo "4. Execute shared/jupyter/verify-az-account.ipynb to verify your Azure setup"
93+
fi
94+
echo "5. Navigate to any infrastructure folder and run the create.ipynb notebook"
95+
echo "6. Explore the samples in the samples/ directory"
96+
echo ""
97+
echo "💡 Tip: The Python path has been configured to include shared/python modules automatically."
98+
echo "🔧 To reconfigure Azure CLI authentication, run: python3 .devcontainer/configure-azure-mount.py"
99+
echo ""
100+
echo " 🎉 ALL DONE!"
101+
echo ""

.devcontainer/setup-prebuild.sh

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
#!/bin/bash
2+
3+
# ------------------------------
4+
# PREBUILD OPTIMIZED SETUP
5+
# ------------------------------
6+
7+
set -e
8+
9+
echo "🔧 Running prebuild-optimized setup..."
10+
11+
# ------------------------------
12+
# PYTHON ENVIRONMENT SETUP
13+
# ------------------------------
14+
15+
echo "📦 Installing Python dependencies..."
16+
pip install --upgrade pip
17+
pip install -r requirements.txt
18+
19+
# Ensure pytest and coverage tools are available
20+
pip install pytest pytest-cov coverage
21+
22+
echo "🔧 Setting up Python path configuration..."
23+
python setup/setup_python_path.py --generate-env
24+
25+
# ------------------------------
26+
# AZURE CLI SETUP
27+
# ------------------------------
28+
29+
echo "☁️ Configuring Azure CLI..."
30+
# Set Azure CLI to use device code flow by default in codespaces/containers
31+
az config set core.login_experience_v2=off 2>/dev/null || true
32+
33+
# Install additional Azure CLI extensions that might be useful
34+
echo "📥 Installing Azure CLI extensions..."
35+
az extension add --name containerapp --only-show-errors 2>/dev/null || true
36+
az extension add --name front-door --only-show-errors 2>/dev/null || true
37+
38+
# ------------------------------
39+
# JUPYTER SETUP
40+
# ------------------------------
41+
42+
echo "📓 Setting up Jupyter environment..."
43+
# Install Jupyter kernel (with error handling)
44+
if python -c "import ipykernel" 2>/dev/null; then
45+
python -m ipykernel install --user --name=apim-samples --display-name="APIM Samples Python" || echo "⚠️ Warning: Failed to install Jupyter kernel, but continuing..."
46+
else
47+
echo "⚠️ Warning: ipykernel not found. Installing it now..."
48+
pip install ipykernel
49+
python -m ipykernel install --user --name=apim-samples --display-name="APIM Samples Python" || echo "⚠️ Warning: Failed to install Jupyter kernel, but continuing..."
50+
fi
51+
52+
# ------------------------------
53+
# WORKSPACE CONFIGURATION
54+
# ------------------------------
55+
56+
echo "🛠️ Configuring workspace settings..."
57+
58+
# Create .vscode directory if it doesn't exist
59+
mkdir -p .vscode
60+
61+
# Create settings.json for the workspace
62+
cat > .vscode/settings.json << 'EOF'
63+
{
64+
"python.terminal.activateEnvironment": true,
65+
"python.defaultInterpreterPath": "/usr/local/bin/python",
66+
"python.analysis.extraPaths": [
67+
"/workspaces/Apim-Samples/shared/python"
68+
],
69+
"jupyter.kernels.filter": [
70+
{
71+
"path": "/usr/local/bin/python",
72+
"type": "pythonEnvironment"
73+
}
74+
],
75+
"files.associations": {
76+
"*.bicep": "bicep"
77+
},
78+
"python.envFile": "${workspaceFolder}/.env"
79+
}
80+
EOF
81+
82+
# ------------------------------
83+
# PREBUILD COMPLETION MARKER
84+
# ------------------------------
85+
86+
echo "✅ Creating prebuild completion marker..."
87+
echo "$(date): Prebuild setup completed" > .devcontainer/.prebuild-complete
88+
89+
echo "🎉 Prebuild setup complete!"
90+
91+
echo "✅ Verifying installation..."
92+
echo "Python version: $(python --version)"
93+
echo "Azure CLI version: $(az --version | head -1)"
94+
echo "Pip packages installed:"
95+
pip list | grep -E "(requests|pandas|matplotlib|pytest|azure|jwt|jupyter|ipykernel)" || true
96+
97+
echo "📋 Prebuild optimization complete!"

.devcontainer/validate-prebuild.sh

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
#!/bin/bash
2+
3+
# ------------------------------
4+
# PREBUILD VALIDATION SCRIPT
5+
# ------------------------------
6+
7+
echo "🔍 Validating prebuild configuration..."
8+
9+
# Check if prebuild marker exists
10+
if [ -f ".devcontainer/.prebuild-complete" ]; then
11+
echo "✅ Prebuild marker found"
12+
echo " Created: $(cat .devcontainer/.prebuild-complete)"
13+
else
14+
echo "❌ No prebuild marker found"
15+
echo " This indicates the environment was not created from a prebuild"
16+
fi
17+
18+
echo ""
19+
echo "📊 Environment Status:"
20+
echo "====================="
21+
22+
# Check Python installation
23+
if command -v python &> /dev/null; then
24+
echo "✅ Python: $(python --version)"
25+
else
26+
echo "❌ Python: Not found"
27+
fi
28+
29+
# Check Azure CLI
30+
if command -v az &> /dev/null; then
31+
echo "✅ Azure CLI: $(az --version | head -1)"
32+
else
33+
echo "❌ Azure CLI: Not found"
34+
fi
35+
36+
# Check key Python packages
37+
echo ""
38+
echo "📦 Python Packages:"
39+
echo "=================="
40+
packages=("requests" "jwt" "pandas" "matplotlib" "pytest" "azure-cli" "jupyter" "ipykernel")
41+
42+
for pkg in "${packages[@]}"; do
43+
if python -c "import ${pkg//-/_}" &> /dev/null; then
44+
version=$(pip show "$pkg" 2>/dev/null | grep Version | cut -d' ' -f2)
45+
echo "$pkg: $version"
46+
else
47+
echo "$pkg: Not installed"
48+
fi
49+
done
50+
51+
echo ""
52+
echo "🔧 Configuration Files:"
53+
echo "======================"
54+
55+
# Check for key configuration files
56+
files=(".env" ".vscode/settings.json" "requirements.txt")
57+
58+
for file in "${files[@]}"; do
59+
if [ -f "$file" ]; then
60+
echo "$file: Found"
61+
else
62+
echo "$file: Missing"
63+
fi
64+
done
65+
66+
echo ""
67+
echo "🎯 Recommendations:"
68+
echo "=================="
69+
70+
if [ ! -f ".devcontainer/.prebuild-complete" ]; then
71+
echo "💡 Consider using GitHub Codespaces prebuilds for faster startup"
72+
echo " Learn more: https://docs.github.com/en/codespaces/prebuilding-your-codespaces"
73+
fi
74+
75+
echo "💡 Run 'python .devcontainer/verify-setup.py' for detailed environment verification"
76+
echo "💡 Run 'python3 .devcontainer/configure-azure-mount.py' to configure Azure CLI authentication"

.devcontainer/verify-setup.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ def check_jupyter_kernel():
122122

123123
def check_azure_cli():
124124
"""Check Azure CLI installation and extensions."""
125-
print("\n☁️ Checking Azure CLI...")
125+
print("\n☁️ Checking Azure CLI...")
126126
try:
127127
# Check Azure CLI
128128
result = subprocess.run(['az', '--version'],
@@ -166,16 +166,16 @@ def main():
166166
print("\n" + "="*50)
167167

168168
if all(checks):
169-
print("🎉 All checks passed! Your dev container is ready to use.")
170-
print("\n📋 Next steps:\n")
171-
print("1. Configure Azure CLI: python .devcontainer/configure-azure-mount.py")
172-
print("2. Or manually sign in with tenant-specific login:")
173-
print(" az login --tenant <your-tenant-id-or-domain>")
174-
print(" az account set --subscription <your-subscription-id-or-name>")
175-
print(" az account show # Verify your context")
176-
print("3. Execute shared/jupyter/verify-az-account.ipynb")
177-
print("4. If prompted, initialize the kernel according to the `Initialization` steps in the root README.md file")
178-
print("5. Explore the samples and infrastructure folders\n")
169+
# print("🎉 All checks passed! Your dev container is ready to use.")
170+
# print("\n📋 Next steps:\n")
171+
# print("1. Configure Azure CLI: python .devcontainer/configure-azure-mount.py")
172+
# print("2. Or manually sign in with tenant-specific login:")
173+
# print(" az login --tenant <your-tenant-id-or-domain>")
174+
# print(" az account set --subscription <your-subscription-id-or-name>")
175+
# print(" az account show # Verify your context")
176+
# print("3. Execute shared/jupyter/verify-az-account.ipynb")
177+
# print("4. If prompted, initialize the kernel according to the `Initialization` steps in the root README.md file")
178+
# print("5. Explore the samples and infrastructure folders\n")
179179
return 0
180180
else:
181181
print("❌ Some checks failed. Please review the output above.")

0 commit comments

Comments
 (0)