Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
38966ea
feat: Add GitHub token support to devcontainer and automate GitHub CL…
lynnwallenstein Mar 8, 2026
097bb8f
feat: Introduce `start-container.sh` as the devcontainer `postStartCo…
lynnwallenstein Mar 8, 2026
e3770b1
fix(container): resolve project root in start-container.sh
lynnwallenstein Mar 8, 2026
49a61cc
chore: add root .gitignore from template
lynnwallenstein Mar 8, 2026
fe162a4
chore(scripts): make setup scripts executable
lynnwallenstein Mar 8, 2026
848a3f4
feat(scripts): add troubleshooting diagnostic script
lynnwallenstein Mar 8, 2026
3cd67b8
chore(env): replace pat prompt with gh auth instructions and add reco…
lynnwallenstein Mar 8, 2026
dc5e1a5
chore: track root dev environment and git hooks
lynnwallenstein Mar 8, 2026
546d32d
docs: add AI agent guidelines to README
lynnwallenstein Mar 8, 2026
7d5d7c6
feat(ci): add E2E install verification workflow and fix install.sh ta…
lynnwallenstein Mar 8, 2026
432df59
chore: ignore .tmp-test directory
lynnwallenstein Mar 8, 2026
5d8213d
feat(lint): add shellcheck for shell script verification
lynnwallenstein Mar 8, 2026
d3c22ee
feat(format): add prettier for repo-wide formatting and fix json syntax
lynnwallenstein Mar 8, 2026
db937dc
chore: Apply Prettier formatting across repository
lynnwallenstein Mar 8, 2026
d5c7fa6
feat(ci): add dependabot configuration for root and templates
lynnwallenstein Mar 8, 2026
51a568e
feat(ci): add Devcontainer build validation workflow
lynnwallenstein Mar 8, 2026
ca97c4e
chore: Apply final polish and gold standard improvements from audit
lynnwallenstein Mar 8, 2026
b89da3d
chore: add root PR template
lynnwallenstein Mar 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions .agents/workflows/test-install.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,30 +9,31 @@ Run this workflow to verify that `install.sh` correctly extracts the `templates/
## Steps

1. Create and enter a temporary test directory:

```bash
mkdir -p /tmp/test-bootstrap && cd /tmp/test-bootstrap && git init
```

// turbo
2. Run the install script from the bootstrap repo (using local copy, not remote):
// turbo 2. Run the install script from the bootstrap repo (using local copy, not remote):

```bash
BOOTSTRAP_DEV=1 bash /Users/lynnwallenstein/workspace/penguinranch/bootstrap/install.sh
```

// turbo
3. Verify the expected file structure exists:
// turbo 3. Verify the expected file structure exists:

```bash
ls -la /tmp/test-bootstrap/.devcontainer/ /tmp/test-bootstrap/scripts/ /tmp/test-bootstrap/docs/decisions/ && echo "✅ Structure intact" || echo "❌ Missing files"
```

// turbo
4. Verify key files are present:
// turbo 4. Verify key files are present:

```bash
for f in AGENTS.md Makefile .editorconfig .env.example .gitattributes .gitignore .prettierrc CHANGELOG.md LICENSE CODE_OF_CONDUCT.md README.md; do [ -f "/tmp/test-bootstrap/$f" ] && echo "✅ $f" || echo "❌ $f MISSING"; done
```

// turbo
5. Clean up:
// turbo 5. Clean up:

```bash
rm -rf /tmp/test-bootstrap
```
12 changes: 12 additions & 0 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
FROM mcr.microsoft.com/devcontainers/base:bookworm

# [Optional] Uncomment this section to install additional OS packages.
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
&& apt-get -y install --no-install-recommends shellcheck

# [Optional] Uncomment if you want to install an additional version of node using nvm
# ARG EXTRA_NODE_VERSION=10
# RUN su node -c "source /usr/local/share/nvm/nvm.sh && nvm install ${EXTRA_NODE_VERSION}"

# [Optional] Uncomment if you want to install more global node modules
# RUN su node -c "npm install -g <your-package-list-here>"
38 changes: 38 additions & 0 deletions .devcontainer/boot-check.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#!/bin/bash
set -euo pipefail

if [ ! -f .env ]; then
echo "⚠️ WARNING: .env file not found."
echo "Please run './scripts/setup-env.sh' in the terminal to initialize your environment variables."
else
echo "✅ .env found. Exporting variables safely..."
while IFS='=' read -r key value; do
# Skip empty lines and comments
if [[ -n "$key" && ! "$key" =~ ^# ]]; then
# Trim leading/trailing whitespace
key="${key#"${key%%[![:space:]]*}"}"
key="${key%"${key##*[![:space:]]}"}"
value="${value#"${value%%[![:space:]]*}"}"
value="${value%"${value##*[![:space:]]}"}"
export "$key=$value"
fi
done < ".env"

# Configure Git if found in .env
if [ -n "${GIT_NAME:-}" ]; then
git config --global user.name "$GIT_NAME"
fi
if [ -n "${GIT_EMAIL:-}" ]; then
git config --global user.email "$GIT_EMAIL"
fi
if [ -n "${SSH_PUBLIC_KEY:-}" ]; then
git config --global gpg.format ssh
git config --global user.signingkey "key::${SSH_PUBLIC_KEY}"
git config --global commit.gpgsign true
fi

# Configure GitHub CLI as credential helper if token is present
if [ -n "${GITHUB_TOKEN:-}" ] && command -v gh &> /dev/null; then
gh auth setup-git
fi
fi
41 changes: 41 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"name": "bootstrap",
"build": {
"dockerfile": "Dockerfile",
"args": { "VARIANT": "latest" }
},
"forwardPorts": [3000, 9222],
"features": {
"ghcr.io/devcontainers/features/common-utils:2": {
"configureZshAsDefaultShell": true
},
"ghcr.io/devcontainers/features/git:1": {},
"ghcr.io/devcontainers/features/node:1": {},
"ghcr.io/devcontainers/features/github-cli:1": {}
},
"postCreateCommand": "bash ./scripts/setup-gemini.sh",
"customizations": {
"vscode": {
"extensions": [
"esbenp.prettier-vscode",
"GitHub.github-vscode-theme",
"bierner.markdown-mermaid",
"mechatroner.rainbow-csv",
"ms-vscode.makefile-tools",
"ms-azuretools.vscode-containers",
"ms-azuretools.vscode-docker",
"github.vscode-github-actions",
"github.vscode-pull-request-github"
],
"settings": {
"workbench.startupEditor": "none"
}
}
},
"postAttachCommand": "code README.md AGENTS.md",
"containerEnv": {
"GEMINI_API_KEY": "${localEnv:GEMINI_API_KEY}",
"GITHUB_TOKEN": "${localEnv:GITHUB_TOKEN}"
},
"postStartCommand": "/bin/bash ./scripts/start-container.sh"
}
13 changes: 13 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Project Environment Variables
# Copy to .env and fill in your details

# Git Configuration (for signing commits within container)
GIT_NAME=
GIT_EMAIL=
SSH_PUBLIC_KEY=

# Gemini CLI API Key (for AI tooling inside the Devcontainer)
# Get your key at: https://aistudio.google.com/app/apikey
GEMINI_API_KEY=

# Add project specific secrets below
36 changes: 36 additions & 0 deletions .githooks/commit-msg
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#!/bin/bash
# Commit message hook: enforces Conventional Commits format.
# Installed automatically by `make setup`.
#
# Valid prefixes: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert
# Format: <type>[optional scope]: <description>
# Examples:
# feat: add user authentication
# fix(api): handle null response from endpoint
# docs: update README with setup instructions

commit_msg_file="$1"
commit_msg=$(cat "$commit_msg_file")

# Allow merge commits and fixup/squash commits
if echo "$commit_msg" | grep -qE "^(Merge|fixup!|squash!)"; then
exit 0
fi

# Validate conventional commit format
pattern="^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\(.+\))?: .{1,}"

if ! echo "$commit_msg" | head -1 | grep -qE "$pattern"; then
echo "❌ Commit message does not follow Conventional Commits format."
echo ""
echo "Expected: <type>[optional scope]: <description>"
echo "Types: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert"
echo ""
echo "Examples:"
echo " feat: add user authentication"
echo " fix(api): handle null response"
echo " docs: update README with setup instructions"
echo ""
echo "Your message: $commit_msg"
exit 1
fi
12 changes: 12 additions & 0 deletions .githooks/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/bash
# Pre-commit hook: runs lint checks before allowing a commit.
# Installed automatically by `make setup`.

# Only lint staged files if make lint is available
if make lint 2>/dev/null; then
echo "✅ Lint checks passed."
else
echo "⚠️ Lint check failed or not configured. Skipping pre-commit lint."
# Exit 0 so commits aren't blocked before the stack is configured
exit 0
fi
27 changes: 27 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
## Description

Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context.

## Type of Change

- [ ] 🐛 Bug fix (non-breaking change which fixes an issue)
- [ ] 🚀 New feature (non-breaking change which adds functionality)
- [ ] 🧹 Chore (refactoring, formatting, dependencies)
- [ ] 📖 Documentation update
- [ ] 🏗 Infrastructure / Environment change

## How Has This Been Tested?

Please describe the tests that you ran to verify your changes.

- [ ] Local manual test
- [ ] CI Automated tests (E2E, Linting, Build)

## Checklist

- [ ] My code follows the style guidelines of this project
- [ ] I have performed a self-review of my own code
- [ ] I have commented my code, particularly in hard-to-understand areas
- [ ] I have made corresponding changes to the documentation
- [ ] My changes generate no new warnings
- [ ] Any dependent changes have been merged and published in downstream modules
13 changes: 13 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
version: 2
updates:
# Maintain GitHub Actions used in this repo
- package-ecosystem: 'github-actions'
directory: '/'
schedule:
interval: 'weekly'

# Maintain Docker base images in the root devcontainer
- package-ecosystem: 'docker'
directory: '/.devcontainer'
schedule:
interval: 'weekly'
32 changes: 32 additions & 0 deletions .github/workflows/devcontainer-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Devcontainer Build Validation

on:
push:
branches: [main, booting]
pull_request:
branches: [main]

jobs:
build-root:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Build root devcontainer
uses: devcontainers/ci@v0.3
with:
subFolder: .
push: never

build-template:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Build template devcontainer
uses: devcontainers/ci@v0.3
with:
subFolder: templates
push: never
52 changes: 52 additions & 0 deletions .github/workflows/e2e-install.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: E2E Install Verification

on:
push:
branches: [main, booting]
pull_request:
branches: [main]

jobs:
test-install:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Run installer
run: |
mkdir test-project
cd test-project
# We point to the local install.sh but it will still try to download a tarball.
# To test the logic of the script using the CURRENT branch changes,
# we override REPO_TAR_URL to point to this repository's current commit.
export REPO_TAR_URL="https://github.com/${{ github.repository }}/tarball/${{ github.sha }}"
bash ../install.sh
env:
BOOTSTRAP_DEV: 1

- name: Verify files
run: |
cd test-project
echo "Verifying critical files exist..."
test -d .devcontainer
test -f .gitignore
test -f Makefile
test -f README.md
test -f AGENTS.md
test -d scripts
test -f scripts/setup-env.sh
test -f scripts/troubleshooting.sh

echo "Verifying execute permissions..."
test -x scripts/setup-env.sh
test -x scripts/start-container.sh
test -x scripts/troubleshooting.sh

echo "Verifying no root-only files leaked..."
if [ -f "install.sh" ]; then
echo "Error: install.sh should not be in the project root."
exit 1
fi

echo "✅ E2E Verification Passed!"
23 changes: 23 additions & 0 deletions .github/workflows/prettier.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: Formatting Check

on:
push:
branches: [main, booting]
pull_request:
branches: [main]

jobs:
prettier:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'

- name: Run Prettier check
run: |
npx -y prettier --check "**/*.{md,json,yml}"
18 changes: 18 additions & 0 deletions .github/workflows/shellcheck.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: Shell Script Linting

on:
push:
branches: [main, booting]
pull_request:
branches: [main]

jobs:
shellcheck:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Run shellcheck
run: |
shellcheck install.sh .devcontainer/*.sh scripts/*.sh templates/scripts/*.sh
Loading