From 427f7a710ca27d005aa6c72ad9e9a8e4863a3165 Mon Sep 17 00:00:00 2001 From: DevContainer User Date: Sat, 21 Feb 2026 14:28:58 +0000 Subject: [PATCH] fix: automate git credentials setup during container initialization - Configure git credentials at the beginning of init-repo.sh - Set up git user name/email with defaults or from environment variables - Create .git-credentials file with proper permissions (600) - Support multiple GitHub credential formats for better compatibility - Create symlinks to handle different credential file locations - Add test script to verify credentials configuration - Update documentation with new environment variables This fixes issues where containers fail due to missing .git-credentials by ensuring credentials are properly configured before any git operations. Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude Co-Authored-By: Happy --- CLAUDE.md | 14 +++++-- scripts/init-repo.sh | 69 ++++++++++++++++++++++++++------- scripts/test-git-credentials.sh | 46 ++++++++++++++++++++++ 3 files changed, 112 insertions(+), 17 deletions(-) create mode 100755 scripts/test-git-credentials.sh diff --git a/CLAUDE.md b/CLAUDE.md index efe9b7c..2de147c 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -57,8 +57,11 @@ make push # Push image to registry (build first) ``` Container start → scripts/startapp.sh - → scripts/init-repo.sh (clone GITHUB_REPO, start Happy Coder) - → launch VSCode as user `claude` in /workspace + → scripts/init-repo.sh + → Configure git user & credentials + → Clone GITHUB_REPO (if set) + → Start Happy Coder + → Launch VSCode as user `user` in /workspace ``` ### Key Files @@ -66,7 +69,7 @@ Container start | File | Purpose | |------|---------| | `Dockerfile` | Image definition — installs Chrome, Node.js, VSCode, Happy Coder; creates non-root user (UID 1000) | -| `scripts/init-repo.sh` | Clones GitHub repo, authenticates with token, starts Happy Coder background service | +| `scripts/init-repo.sh` | Configures git credentials, clones GitHub repo, starts Happy Coder background service | | `scripts/startapp.sh` | Calls init-repo.sh then opens VSCode in the workspace | | `chart/` | Helm chart for Kubernetes deployment | | `chart/templates/deployment.yaml` | Deployment spec — main container + MCP sidecar containers | @@ -137,7 +140,10 @@ helm install my-devcontainer ./chart -f custom-values.yaml - `GITHUB_REPO` — URL of repository to clone into `/workspace` **Optional:** -- `GITHUB_TOKEN` — PAT for private repo access +- `GITHUB_TOKEN` — PAT for private repo access (automatically configures git credentials) +- `GIT_USER_NAME` — Git user name for commits (default: "DevContainer User") +- `GIT_USER_EMAIL` — Git user email for commits (default: "devcontainer@example.com") +- `GITLAB_HOST` — GitLab hostname if using GitLab with same token - `VNC_PASSWORD` — VNC web interface password - `DISPLAY_WIDTH` / `DISPLAY_HEIGHT` — VNC resolution - `USER_ID` / `GROUP_ID` — Override UID/GID (default 1000) diff --git a/scripts/init-repo.sh b/scripts/init-repo.sh index 7347e83..4a5548c 100644 --- a/scripts/init-repo.sh +++ b/scripts/init-repo.sh @@ -4,6 +4,62 @@ set -e echo "=== Repository Initialization ===" +# Set up basic git configuration +echo "Configuring git user settings..." +# Use environment variables if provided, otherwise use defaults +GIT_USER_NAME="${GIT_USER_NAME:-DevContainer User}" +GIT_USER_EMAIL="${GIT_USER_EMAIL:-devcontainer@example.com}" + +git config --global user.name "$GIT_USER_NAME" +git config --global user.email "$GIT_USER_EMAIL" + +# Set up git credentials early if GITHUB_TOKEN is provided +# This ensures all git operations have proper authentication +if [ -n "$GITHUB_TOKEN" ]; then + echo "Setting up git credentials..." + # Configure git to use credential store globally + git config --global credential.helper store + + # Create or update the credentials file + CREDENTIALS_FILE="/config/userdata/.git-credentials" + + # Support multiple git hosting providers + # GitHub supports both oauth2 and token as username + echo "https://oauth2:${GITHUB_TOKEN}@github.com" > "$CREDENTIALS_FILE" + echo "https://${GITHUB_TOKEN}:x-oauth-basic@github.com" >> "$CREDENTIALS_FILE" + echo "https://token:${GITHUB_TOKEN}@github.com" >> "$CREDENTIALS_FILE" + + # GitLab format (if same token works) + if [ -n "$GITLAB_HOST" ]; then + echo "https://oauth2:${GITHUB_TOKEN}@${GITLAB_HOST}" >> "$CREDENTIALS_FILE" + fi + + chmod 600 "$CREDENTIALS_FILE" + + # Also create a symlink in the home directory if it doesn't exist + # This handles cases where git might look in different locations + if [ ! -f "$HOME/.git-credentials" ] && [ "$HOME" != "/config/userdata" ]; then + ln -sf "$CREDENTIALS_FILE" "$HOME/.git-credentials" + fi + + echo "Git credentials configured" +else + # Even without a token, ensure git has a proper credential helper configured + # This prevents errors when credentials are added later + echo "No GITHUB_TOKEN provided, configuring basic git settings..." + git config --global credential.helper store + + # Create an empty credentials file with proper permissions + CREDENTIALS_FILE="/config/userdata/.git-credentials" + touch "$CREDENTIALS_FILE" + chmod 600 "$CREDENTIALS_FILE" + + # Create symlink if needed + if [ ! -f "$HOME/.git-credentials" ] && [ "$HOME" != "/config/userdata" ]; then + ln -sf "$CREDENTIALS_FILE" "$HOME/.git-credentials" + fi +fi + # Check if GITHUB_REPO is set if [ -z "$GITHUB_REPO" ]; then echo "GITHUB_REPO not set, skipping repository clone" @@ -21,14 +77,6 @@ else if [ -d "$WORKSPACE_DIR/.git" ]; then echo "Repository already exists, pulling latest changes..." cd "$WORKSPACE_DIR" - - # Configure git to use token if provided - if [ -n "$GITHUB_TOKEN" ]; then - git config credential.helper store - echo "https://oauth2:${GITHUB_TOKEN}@github.com" > /config/userdata/.git-credentials - chmod 600 /config/userdata/.git-credentials - fi - git pull || echo "Pull failed, continuing anyway..." else echo "Cloning repository..." @@ -39,11 +87,6 @@ else # Replace https://github.com/ with https://oauth2:token@github.com/ CLONE_URL=$(echo "$GITHUB_REPO" | sed "s|https://github.com/|https://oauth2:${GITHUB_TOKEN}@github.com/|") git clone "$CLONE_URL" "$WORKSPACE_DIR" - - # Configure credentials for future use - git config --global credential.helper store - echo "https://oauth2:${GITHUB_TOKEN}@github.com" > /config/userdata/.git-credentials - chmod 600 /config/userdata/.git-credentials else git clone "$GITHUB_REPO" "$WORKSPACE_DIR" fi diff --git a/scripts/test-git-credentials.sh b/scripts/test-git-credentials.sh new file mode 100755 index 0000000..1075cf9 --- /dev/null +++ b/scripts/test-git-credentials.sh @@ -0,0 +1,46 @@ +#!/bin/bash +# Test script to verify git credentials configuration + +set -e + +echo "=== Git Credentials Test ===" + +# Check git configuration +echo "1. Git user configuration:" +git config --global user.name || echo " ❌ user.name not set" +git config --global user.email || echo " ❌ user.email not set" + +echo "" +echo "2. Git credential helper:" +git config --global credential.helper || echo " ❌ credential.helper not set" + +echo "" +echo "3. Credentials file locations:" +CREDENTIALS_FILE="/config/userdata/.git-credentials" +if [ -f "$CREDENTIALS_FILE" ]; then + echo " ✓ $CREDENTIALS_FILE exists" + echo " Permissions: $(stat -c %a $CREDENTIALS_FILE)" + echo " Lines in file: $(wc -l < $CREDENTIALS_FILE)" +else + echo " ❌ $CREDENTIALS_FILE does not exist" +fi + +if [ -f "$HOME/.git-credentials" ]; then + if [ -L "$HOME/.git-credentials" ]; then + echo " ✓ $HOME/.git-credentials is a symlink to $(readlink -f $HOME/.git-credentials)" + else + echo " ✓ $HOME/.git-credentials exists (not a symlink)" + fi +else + echo " ❌ $HOME/.git-credentials does not exist" +fi + +echo "" +echo "4. Environment check:" +echo " HOME=$HOME" +echo " GITHUB_TOKEN=${GITHUB_TOKEN:+[SET]}" +echo " GIT_USER_NAME=${GIT_USER_NAME:-[NOT SET]}" +echo " GIT_USER_EMAIL=${GIT_USER_EMAIL:-[NOT SET]}" + +echo "" +echo "=== Test Complete ===" \ No newline at end of file