From a298de5af9137966a8e2c2b3e2b4fb36a594f12f Mon Sep 17 00:00:00 2001 From: Peter Wood Date: Sun, 4 May 2025 21:09:44 -0400 Subject: [PATCH] feat: add PowerShell build script for Windows users (#29) - Add build-and-push.ps1 script for Windows users - Update ENVIRONMENT_SETUP.md with cross-platform build instructions - Improve error handling and feedback in build scripts - Add proper Windows path handling Part of #29 --- .devcontainer/build-and-push.ps1 | 115 +++++++++++++++++++++++ ENVIRONMENT_SETUP.md | 155 +++++++++++++++++++++++++++++++ 2 files changed, 270 insertions(+) create mode 100644 .devcontainer/build-and-push.ps1 create mode 100644 ENVIRONMENT_SETUP.md diff --git a/.devcontainer/build-and-push.ps1 b/.devcontainer/build-and-push.ps1 new file mode 100644 index 0000000..6544b0a --- /dev/null +++ b/.devcontainer/build-and-push.ps1 @@ -0,0 +1,115 @@ +# Requires -Version 5.0 +param( + [Parameter(Mandatory=$true)] + [string]$GitHubUsername +) + +# Stop on first error +$ErrorActionPreference = "Stop" + +# Configuration +$ImageName = "finance-devcontainer" +$ImageTag = "latest" +$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path +$DockerfilePath = Join-Path $ScriptDir "Dockerfile" +$EnvFile = Join-Path $ScriptDir ".env" +$FullImageName = "ghcr.io/$GitHubUsername/$ImageName`:$ImageTag" + +# Function to check required tools +function Test-RequiredTools { + $tools = @("docker", "gh") + foreach ($tool in $tools) { + if (-not (Get-Command $tool -ErrorAction SilentlyContinue)) { + Write-Error "Error: $tool is required but not installed" + exit 1 + } + } +} + +# Function to load environment variables from .env file +function Get-EnvContent { + if (Test-Path $EnvFile) { + Write-Host "Loading environment from $EnvFile" + $envContent = Get-Content $EnvFile + foreach ($line in $envContent) { + if ($line -match '^GITHUB_PERSONAL_ACCESS_TOKEN=(.*)$') { + return $matches[1] + } + } + } + Write-Error "Error: GITHUB_PERSONAL_ACCESS_TOKEN not found in $EnvFile" + exit 1 +} + +# Verify prerequisites +Write-Host "=== Building Development Container ===" +Write-Host "Username: $GitHubUsername" +Write-Host "Image: $FullImageName" +Write-Host "Dockerfile: $DockerfilePath" + +# Check required tools +Test-RequiredTools + +# Check GitHub authentication +try { + gh auth status +} catch { + Write-Error "Error: Not authenticated with GitHub. Please run 'gh auth login' first" + exit 1 +} + +# Get GitHub PAT from .env file +$GitHubPAT = Get-EnvContent + +if ([string]::IsNullOrEmpty($GitHubPAT)) { + Write-Error "Error: GITHUB_PERSONAL_ACCESS_TOKEN is empty" + exit 1 +} + +Write-Host "Using PAT: $($GitHubPAT.Substring(0, 4))... (first 4 chars)" + +# Build the image +Write-Host "`n=> Building image..." +try { + docker build -t $FullImageName -f $DockerfilePath $ScriptDir +} catch { + Write-Error "Error: Docker build failed" + exit 1 +} + +# Log in to GitHub Container Registry +Write-Host "`n=> Logging into GitHub Container Registry..." +$GitHubPAT | docker login ghcr.io -u $GitHubUsername --password-stdin + +if ($LASTEXITCODE -ne 0) { + Write-Error "Error: Failed to authenticate with GitHub Container Registry" + exit 1 +} + +# Push to GitHub Container Registry +Write-Host "`n=> Pushing image to GitHub Container Registry..." +docker push $FullImageName + +if ($LASTEXITCODE -ne 0) { + Write-Error @" +Error: Failed to push image +Please check your GitHub PAT has the required permissions: + - read:packages + - write:packages +"@ + exit 1 +} + +Write-Host "`n=== Success! ===" +Write-Host "The development container image has been built and pushed" +Write-Host "`nTo use this image, update your devcontainer.json with:" +Write-Host @" +{ + "image": "$FullImageName" +} +"@ + +Write-Host "`nNext steps:" +Write-Host "1. Update .devcontainer/devcontainer.json with the image reference above" +Write-Host "2. Rebuild your development container in VS Code" +Write-Host " (Command Palette -> 'Dev Containers: Rebuild Container')" \ No newline at end of file diff --git a/ENVIRONMENT_SETUP.md b/ENVIRONMENT_SETUP.md new file mode 100644 index 0000000..c2c6676 --- /dev/null +++ b/ENVIRONMENT_SETUP.md @@ -0,0 +1,155 @@ +# Development Environment Setup Guide + +## Prerequisites + +- Windows, macOS, or Linux +- Git +- Docker Desktop +- Visual Studio Code with Remote - Containers extension +- GitHub CLI + +## Initial Setup + +1. **Clone the Repository** + ```bash + git clone https://github.com/acedanger/finance.git + cd finance + ``` + +2. **Create Environment Files** + ```bash + cp .devcontainer/.env.example .devcontainer/.env + cp .env.example .env + ``` + +## GitHub Personal Access Token (PAT) + +1. **Create a new PAT:** + - Go to GitHub Settings > Developer settings > Personal access tokens > Tokens (classic) + - Click "Generate new token (classic)" + - Name: `finance-dev-token` + - Set expiration: 90 days (recommended) + - Required scopes: + - `repo` (Full control of private repositories) + - `read:packages` (Download container images) + - `write:packages` (Upload container images) + - `delete:packages` (Optional: manage container versions) + - `workflow` (GitHub Actions integration) + +2. **Configure the PAT:** + - Open `.devcontainer/.env` + - Set `GITHUB_PERSONAL_ACCESS_TOKEN=your_token_here` + +## Building the Development Container + +### Using VS Code (Recommended) +1. Open the project in VS Code +2. When prompted, click "Reopen in Container" + - Or press F1 and run "Dev Containers: Rebuild and Reopen in Container" + +### Using Command Line +1. Install the devcontainer CLI: + ```bash + npm install -g @devcontainers/cli + ``` + +2. Build the container: + ```bash + devcontainer build . + ``` + +3. Start the container: + ```bash + # With post-create command + devcontainer up --workspace-folder . + + # Skip post-create command + devcontainer up --workspace-folder . --skip-post-create + ``` + +## Building and Pushing the Container Image + +1. Ensure you're in the `.devcontainer` directory + +2. Choose your preferred script: + + **Using PowerShell:** + ```powershell + .\build-and-push.ps1 your_github_username + ``` + + **Using Git Bash/Unix Shell:** + ```bash + chmod +x build-and-push.sh + ./build-and-push.sh your_github_username + ``` + +Both scripts perform the same functions: +- Validate prerequisites (Docker, GitHub CLI) +- Load GitHub PAT from `.env` file +- Build the container image +- Push to GitHub Container Registry +- Provide next steps for using the image + +## Environment Files + +The project uses two separate environment files: + +1. `.devcontainer/.env`: + - Container-specific configuration + - GitHub PAT + - PostgreSQL settings + - pgAdmin settings + +2. `.env`: + - Application-specific configuration + - Development server port + - API base URL + - Node environment + +## Troubleshooting + +### Container Build Issues +- Ensure Docker Desktop is running +- Check that your PAT has the correct permissions +- Try rebuilding without cache: `devcontainer build . --no-cache` + +### GitHub Authentication Issues +- Verify your PAT in `.devcontainer/.env` +- Try logging in manually: `gh auth login` +- Check GitHub CLI status: `gh auth status` + +### Network Issues +- If DNS resolution fails, try using different DNS servers in `devcontainer.json` +- Check if GitHub Container Registry (ghcr.io) is accessible +- Verify Docker network settings + +### VS Code Issues +- Install/update the Remote - Containers extension +- Clear VS Code's container cache +- Check VS Code's "Dev Containers" output panel for detailed logs + +## Common Operations + +### Rebuilding the Container +```bash +# Using VS Code +F1 -> "Dev Containers: Rebuild Container" + +# Using CLI +devcontainer build . --no-cache +``` + +### Updating the Container Image +1. Make changes to `Dockerfile` or `devcontainer.json` +2. Run the build script: + ```bash + ./build-and-push.sh your_github_username + ``` +3. Update image reference in `devcontainer.json` +4. Rebuild container in VS Code + +### Starting Development Server +```bash +npm run dev +``` \ No newline at end of file