From 9f22e07b85afbd05d1324cec0195ee94eb067364 Mon Sep 17 00:00:00 2001 From: Franccesco Orozco Date: Sat, 26 Jul 2025 01:19:25 +0000 Subject: [PATCH 1/3] feat(devcontainer): add comprehensive VS Code devcontainer support - Add Dockerfile with Python 3.12, uv, GitHub CLI, Claude Code, and direnv - Configure VS Code extensions and settings for Python development - Add post-create script for automatic environment setup - Include GitHub CLI authentication prompt for easy PR management - Set up direnv for automatic virtual environment activation - Configure zsh with Oh My Zsh as default shell --- .devcontainer/Dockerfile | 76 +++++++++++++++++++++++++++++++++ .devcontainer/devcontainer.json | 53 +++++++++++++++++++++++ .devcontainer/post-create.sh | 69 ++++++++++++++++++++++++++++++ pyproject.toml | 2 +- uv.lock | 2 +- 5 files changed, 200 insertions(+), 2 deletions(-) create mode 100644 .devcontainer/Dockerfile create mode 100644 .devcontainer/devcontainer.json create mode 100755 .devcontainer/post-create.sh diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 0000000..e654d5a --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,76 @@ +FROM python:3.12-bookworm + +# Install system dependencies and tools +RUN apt-get update && apt-get install -y \ + # Basic utilities + curl \ + wget \ + git \ + sudo \ + # Build essentials + build-essential \ + # Zsh and utilities + zsh \ + # Direnv + direnv \ + # Clean up + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +# Install GitHub CLI +RUN curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg \ + && chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg \ + && echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | tee /etc/apt/sources.list.d/github-cli.list > /dev/null \ + && apt-get update \ + && apt-get install -y gh \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +# Create non-root user +ARG USERNAME=vscode +ARG USER_UID=1000 +ARG USER_GID=$USER_UID + +RUN groupadd --gid $USER_GID $USERNAME \ + && useradd --uid $USER_UID --gid $USER_GID -m $USERNAME \ + && echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \ + && chmod 0440 /etc/sudoers.d/$USERNAME + +# Switch to non-root user for installations +USER $USERNAME +WORKDIR /home/$USERNAME + +# Install uv +RUN curl -LsSf https://astral.sh/uv/install.sh | sh + +# Install Claude Code +RUN curl -fsSL https://claude.ai/install.sh | bash + +# Configure zsh with Oh My Zsh +RUN sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" "" --unattended + +# Configure direnv for zsh +RUN echo 'eval "$(direnv hook zsh)"' >> ~/.zshrc + +# Add uv and Claude Code to PATH in both bash and zsh +RUN echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc \ + && echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc + +# Set zsh as default shell +ENV SHELL=/usr/bin/zsh + +# Set working directory +WORKDIR /workspace + +# Create .envrc file for direnv (will be populated later if needed) +RUN touch /workspace/.envrc || true + +# Ensure proper permissions +USER root +RUN chown -R $USERNAME:$USERNAME /home/$USERNAME + +# Switch back to non-root user +USER $USERNAME + +# Default command +CMD ["/usr/bin/zsh"] \ No newline at end of file diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..a94c27f --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,53 @@ +{ + "name": "Bloomy Python SDK", + "dockerFile": "Dockerfile", + // Features to add to the dev container + "features": { + "ghcr.io/devcontainers/features/common-utils:2": { + "installZsh": true, + "configureZshAsDefaultShell": true, + "username": "vscode", + "userUid": "1000", + "userGid": "1000" + } + }, + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // "forwardPorts": [], + // Use 'postCreateCommand' to run commands after the container is created. + "postCreateCommand": "chmod +x /workspace/.devcontainer/post-create.sh && /workspace/.devcontainer/post-create.sh", + // Configure tool-specific properties. + "customizations": { + "vscode": { + "extensions": [ + "ms-python.python", + "ms-python.vscode-pylance", + "charliermarsh.ruff", + "Anthropic.claude-code" + ], + "settings": { + "python.defaultInterpreterPath": "/workspace/.venv/bin/python", + "python.testing.pytestEnabled": true, + "python.testing.pytestPath": "uv run pytest", + "python.linting.enabled": false, + "python.formatting.provider": "none", + "[python]": { + "editor.formatOnSave": true, + "editor.codeActionsOnSave": { + "source.organizeImports": "explicit" + }, + "editor.defaultFormatter": "charliermarsh.ruff" + }, + "terminal.integrated.defaultProfile.linux": "zsh" + } + } + }, + // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. + "remoteUser": "vscode", + // Mount the workspace + "workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind,consistency=cached", + "workspaceFolder": "/workspace", + // Environment variables + "remoteEnv": { + "PATH": "/home/vscode/.local/bin:${containerEnv:PATH}" + } +} diff --git a/.devcontainer/post-create.sh b/.devcontainer/post-create.sh new file mode 100755 index 0000000..3c125c0 --- /dev/null +++ b/.devcontainer/post-create.sh @@ -0,0 +1,69 @@ +#!/bin/bash +set -e + +echo "🚀 Setting up Bloomy Python development environment..." + +# Ensure we're in the workspace directory +cd /workspace + +# Install Python dependencies using uv +echo "đŸ“Ļ Installing Python dependencies..." +uv sync --all-extras + +# Set up direnv to auto-activate virtual environment +echo "🔧 Setting up direnv for virtual environment activation..." +if [ -f /workspace/.envrc ]; then + # Check if activation script is already in .envrc + if ! grep -q "source .venv/bin/activate" /workspace/.envrc; then + # Add virtual environment activation at the beginning of .envrc + echo '# Activate virtual environment +if [ -f .venv/bin/activate ]; then + source .venv/bin/activate +fi +' | cat - /workspace/.envrc > /workspace/.envrc.tmp && mv /workspace/.envrc.tmp /workspace/.envrc + echo "✅ Added virtual environment activation to .envrc" + else + echo "✅ Virtual environment activation already configured in .envrc" + fi +else + # Create .envrc with virtual environment activation + echo '# Activate virtual environment +if [ -f .venv/bin/activate ]; then + source .venv/bin/activate +fi +' > /workspace/.envrc + echo "✅ Created .envrc with virtual environment activation" +fi + +# Prompt for GitHub CLI authentication +echo "🔐 GitHub CLI Authentication" +echo "The GitHub CLI (gh) is installed for easy PR creation and repository management." +echo "" +echo -n "Would you like to authenticate with GitHub now? (y/N): " +read -r response +if [[ "$response" =~ ^[Yy]$ ]]; then + echo "🌐 Opening GitHub authentication in your browser..." + gh auth login --web +else + echo "â„šī¸ You can authenticate later by running: gh auth login --web" +fi + +# Display success message +echo "✅ Development environment setup complete!" +echo "" +echo "🔧 Available commands:" +echo " - pytest # Run tests" +echo " - ruff check . # Lint code" +echo " - ruff format . # Format code" +echo " - pyright # Type checking" +echo " - mkdocs serve # Serve docs locally" +echo " - claude # Use Claude Code for AI-assisted coding" +echo " - direnv allow # Allow direnv to load .envrc" +echo " - gh pr create # Create a pull request using GitHub CLI" +echo "" + +echo "💡 Tips:" +echo " - The virtual environment will be auto-activated by direnv" +echo " - Claude Code is installed and available in your PATH" +echo " - You can configure your API key in .envrc" +echo "" diff --git a/pyproject.toml b/pyproject.toml index 14471a6..9f4257d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "bloomy-python" -version = "0.14.0" +version = "0.15.1" description = "Python SDK for Bloom Growth API" readme = "README.md" authors = [{ name = "Franccesco Orozco", email = "franccesco@codingdose.info" }] diff --git a/uv.lock b/uv.lock index 11d40b4..04218ac 100644 --- a/uv.lock +++ b/uv.lock @@ -49,7 +49,7 @@ wheels = [ [[package]] name = "bloomy-python" -version = "0.14.0" +version = "0.15.1" source = { editable = "." } dependencies = [ { name = "httpx" }, From e57c5143128e8c77d37af35ab82ee7c5811eaea6 Mon Sep 17 00:00:00 2001 From: Franccesco Orozco Date: Sat, 26 Jul 2025 01:20:14 +0000 Subject: [PATCH 2/3] chore: bump version to 0.15.0 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 9f4257d..e8f4ebd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "bloomy-python" -version = "0.15.1" +version = "0.15.0" description = "Python SDK for Bloom Growth API" readme = "README.md" authors = [{ name = "Franccesco Orozco", email = "franccesco@codingdose.info" }] From 4c87db33563eb29629c8c038e3568a5909ffd9d6 Mon Sep 17 00:00:00 2001 From: Franccesco Orozco Date: Sat, 26 Jul 2025 01:20:33 +0000 Subject: [PATCH 3/3] chore: update uv.lock with version metadata --- uv.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uv.lock b/uv.lock index 04218ac..39d9138 100644 --- a/uv.lock +++ b/uv.lock @@ -49,7 +49,7 @@ wheels = [ [[package]] name = "bloomy-python" -version = "0.15.1" +version = "0.15.0" source = { editable = "." } dependencies = [ { name = "httpx" },