Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ export XDG_CONFIG_HOME=$HOME/.config
export XDG_DATA_HOME=$HOME/.data
export XDG_CACHE_HOME=$HOME/.cache
export XDG_STATE_HOME=$HOME/.state
export PNPM_STORE_PATH=${XDG_DATA_HOME}/pnpm-store
export PNPM_STORE_PATH=$HOME/.pnpm-store
export ZSH="$HOME/.oh-my-zsh"

mkdir -p $XDG_CONFIG_HOME $XDG_DATA_HOME $XDG_CACHE_HOME $XDG_STATE_HOME $PNPM_STORE_PATH
Expand All @@ -13,4 +13,4 @@ alias stan="./vendor/bin/phpstan"
alias phpstan="./vendor/bin/phpstan"
alias pest="./vendor/bin/pest"
alias amf="php artisan migrate:fresh"
alias amfs="php artisan migrate:fresh --seed"
alias amfs="php artisan migrate:fresh --seed"
19 changes: 10 additions & 9 deletions .github/workflows/pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
runs-on: ubuntu-24.04
outputs:
# Push if it's a scheduled job, a tag, or if we're committing to the main branch
push: ${{ (github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && inputs.version) || (github.ref == 'refs/heads/main' && github.event_name != 'pull_request')) && true || false }}
push: ${{ github.event_name == 'schedule' || (github.ref == 'refs/heads/main' && github.event_name != 'pull_request') }}
variants: ${{ steps.matrix.outputs.variants }}
platforms: ${{ steps.matrix.outputs.platforms }}
metadata: ${{ steps.matrix.outputs.metadata }}
Expand Down Expand Up @@ -65,15 +65,15 @@ jobs:
done <<< "$ALL_PHP_VERSIONS"

# Get the last 2 minor versions
MINOR_VERSIONS_SORTED=($(printf '%s\n' "${!LATEST_MINOR_VERSIONS[@]}" | sort -V | tail -2))
mapfile -t MINOR_VERSIONS_SORTED < <(printf '%s\n' "${!LATEST_MINOR_VERSIONS[@]}" | sort -V | tail -2)

if [[ ${#MINOR_VERSIONS_SORTED[@]} -lt 2 ]]; then
echo "❌ Could not find 2 different minor versions"
exit 1
fi

PHP_VERSION_1="8.3"
PHP_VERSION_2="8.4"
PHP_VERSION_1="${MINOR_VERSIONS_SORTED[0]}"
PHP_VERSION_2="${MINOR_VERSIONS_SORTED[1]}"

echo "✅ Selected PHP minor versions: ${PHP_VERSION_1} and ${PHP_VERSION_2}"
echo " Latest patches: ${LATEST_MINOR_VERSIONS[$PHP_VERSION_1]} and ${LATEST_MINOR_VERSIONS[$PHP_VERSION_2]}"
Expand Down Expand Up @@ -199,6 +199,7 @@ jobs:
env:
PHP_VERSION: ${{ steps.check.outputs.php_version }}
LATEST: ${{ steps.check.outputs.latest_version }}
SHA: ${{ github.sha }}
build:
runs-on: ${{ startsWith(matrix.platform, 'linux/arm') && 'ubuntu-24.04-arm' || 'ubuntu-24.04' }}
needs:
Expand Down Expand Up @@ -265,6 +266,7 @@ jobs:
env:
PHP_VERSION: ${{ needs.prepare.outputs.php_version }}
LATEST: ${{ needs.prepare.outputs.latest_version }}
SHA: ${{ github.sha }}

- name: Upload image artifact
uses: actions/upload-artifact@v4
Expand Down Expand Up @@ -367,11 +369,10 @@ jobs:
- name: Test image environment
run: |
# Get the built image name
if [[ "${{ matrix.variant }}" == *"-dev" ]]; then
ENV_TYPE="dev"
else
ENV_TYPE="production"
fi
case "${{ matrix.variant }}" in
*-dev) ENV_TYPE="dev" ;;
*) ENV_TYPE="production" ;;
esac

echo "🧪 Testing ${ENV_TYPE} environment in image: ${LOADED_IMAGE_ID}"

Expand Down
43 changes: 20 additions & 23 deletions .zshrc
Original file line number Diff line number Diff line change
Expand Up @@ -8,45 +8,43 @@ if [ -f ~/.bash_aliases ]; then
. ~/.bash_aliases
fi

# Zinit installation
# Load the build-pinned Zinit installation
ZINIT_HOME="${XDG_DATA_HOME:-${HOME}/.local/share}/zinit/zinit.git"
if [[ ! -d "$ZINIT_HOME" ]]; then
mkdir -p "$(dirname $ZINIT_HOME)"
git clone https://github.com/zdharma-continuum/zinit.git "$ZINIT_HOME"
if [[ ! -r "$ZINIT_HOME/zinit.zsh" ]]; then
print -u2 "Missing pinned Zinit installation: $ZINIT_HOME"
return 1
fi
source "${ZINIT_HOME}/zinit.zsh"

# Completions path
export FPATH="$HOME/.eza/completions/zsh:$FPATH"
# Initialize completion before sourcing Oh My Zsh plugins that register compdefs
autoload -Uz compinit
compinit

# Essential plugins (loaded immediately)
zinit ice ver"85919cd1ffa7d2d5412f6d3fe437ebdbeeec4fc5"
zinit light zsh-users/zsh-autosuggestions
zinit ice ver"24105b15714bfec37989ed5c5b6e60f572253019"
zinit light Aloxaf/fzf-tab

# OMZ libs (only essential ones, loaded with turbo)
zinit wait lucid for \
OMZL::git.zsh \
OMZL::completion.zsh

# OMZ plugins (turbo mode - deferred loading)
zinit wait lucid for \
OMZP::git \
OMZP::aws \
OMZP::gh
# Build-pinned Oh My Zsh libraries and plugins
source "$ZSH/lib/git.zsh"
source "$ZSH/lib/completion.zsh"
source "$ZSH/plugins/git/git.plugin.zsh"
source "$ZSH/plugins/aws/aws.plugin.zsh"
source "$ZSH/plugins/gh/gh.plugin.zsh"

# Syntax highlighting (load last, with turbo)
zinit wait lucid for \
atinit"zicompinit; zicdreplay" \
zinit wait lucid ver"3d574ccf48804b10dca52625df13da5edae7f553" for \
zdharma-continuum/fast-syntax-highlighting

# Tool initializations (synchronous - needed for prompt)
eval "$(starship init zsh)"
eval "$(zoxide init zsh --cmd cd)"

# FZF (turbo)
zinit wait lucid for \
atload"source <(fzf --zsh)" \
zdharma-continuum/null
# FZF integration
if [[ -t 0 && -t 1 ]]; then
source <(fzf --zsh)
fi

# Eza aliases (immediate, not deferred)
alias l='eza -lah --icons --git --group-directories-first'
Expand Down Expand Up @@ -95,4 +93,3 @@ zstyle ':fzf-tab:complete:(ls|l|ll|la|lt|eza):*' fzf-preview '[[ -d $realpath ]]
zstyle ':fzf-tab:*' fzf-flags --color=fg:1,fg+:2 --bind=tab:accept
zstyle ':fzf-tab:*' use-fzf-default-opts yes
zstyle ':fzf-tab:*' switch-group '<' '>'

23 changes: 13 additions & 10 deletions .zshrc.prod
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,28 @@ if [ -f ~/.bash_aliases ]; then
. ~/.bash_aliases
fi

# Zinit installation
# Load the build-pinned Zinit installation
ZINIT_HOME="${XDG_DATA_HOME:-${HOME}/.local/share}/zinit/zinit.git"
if [[ ! -d "$ZINIT_HOME" ]]; then
mkdir -p "$(dirname $ZINIT_HOME)"
git clone https://github.com/zdharma-continuum/zinit.git "$ZINIT_HOME"
if [[ ! -r "$ZINIT_HOME/zinit.zsh" ]]; then
print -u2 "Missing pinned Zinit installation: $ZINIT_HOME"
return 1
fi
source "${ZINIT_HOME}/zinit.zsh"

# Initialize completion before sourcing Oh My Zsh plugins that register compdefs
autoload -Uz compinit
compinit

# Minimal plugins for production (loaded immediately)
zinit ice ver"85919cd1ffa7d2d5412f6d3fe437ebdbeeec4fc5"
zinit light zsh-users/zsh-autosuggestions

# OMZ libs and git plugin
zinit wait lucid for \
OMZL::git.zsh \
OMZP::git
# Build-pinned Oh My Zsh library and git plugin
source "$ZSH/lib/git.zsh"
source "$ZSH/plugins/git/git.plugin.zsh"

# Syntax highlighting (load last)
zinit wait lucid for \
atinit"zicompinit; zicdreplay" \
zinit wait lucid ver"3d574ccf48804b10dca52625df13da5edae7f553" for \
zdharma-continuum/fast-syntax-highlighting

# Basic aliases
Expand Down
46 changes: 21 additions & 25 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,33 +1,29 @@
# Agent Guidelines for FrankenPHP Docker Images
# Repository Guidelines

## Build Commands
## Project Structure & Module Organization

- **Build all variants**: `docker buildx bake`
- **Build specific variant**: `docker buildx bake runner-php-8-4-bookworm`
- **Build with push**: `docker buildx bake --push`
- **Print build matrix**: `docker buildx bake --print`
This repository builds the `ghcr.io/prvious/frankenphp` development and production images. `Dockerfile` defines the binary/tool builders and the shared `base`, `dev`, and `prod` stages. `docker-bake.hcl` expands PHP versions and targets across `linux/amd64` and `linux/arm64`. Container behavior is configured by `.env`, `.zshrc`, and `.zshrc.prod`. Executable Laravel health checks live under `usr/local/bin/`. Image validation is centralized in `test.php`, while `.github/workflows/pipeline.yml` builds, tests, and publishes the matrix.

## Test Commands
## Build, Test, and Development Commands

- **Test image**: `docker run --rm -it <image> php -v`
- **Test container**: `docker run --rm -p 80:80 <image>`
- **Run with shell**: `docker run --rm -it <image> bash`
- `docker build --build-arg VERSION=8.5-trixie --target dev -t frankenphp:dev .` builds the local development image.
- `docker build --build-arg VERSION=8.5-trixie --target prod -t frankenphp:prod .` builds the production image.
- `docker buildx bake --print` inspects the default PHP 8.4/8.5 matrix; override `PHP_VERSION`, `SHA`, and `LATEST` to reproduce CI inputs.
- `docker buildx bake` builds all configured variants and architectures.
- `docker run --rm -v "$PWD/test.php:/app/test.php" frankenphp:dev php /app/test.php dev` validates extensions, binaries, and pnpm configuration. Substitute the production image and `production` for that target.

## Available Aliases (from env.sh)
## Coding Style & Naming Conventions

- `pint` - Laravel Pint formatter: `./vendor/bin/pint`
- `pa` - PHP Artisan: `php artisan`
- `stan`/`phpstan` - PHPStan: `./vendor/bin/phpstan`
- `pest` - Pest testing: `./vendor/bin/pest`
- `amf` - Migrate fresh: `php artisan migrate:fresh`
- `amfs` - Migrate fresh with seed: `php artisan migrate:fresh --seed`
Use four-space indentation in PHP, HCL, and workflow YAML. Keep PHP strictly typed and follow the existing PSR-12-style class and method layout; use `camelCase` methods and `UPPER_SNAKE_CASE` constants. In Dockerfile steps, group related packages, use uppercase build arguments, quote shell variables, and clean package caches in the same layer. Health-check filenames use the `healthcheck-<service>` pattern; the Dockerfile copies them into the image as executable POSIX shell scripts.

## Code Style Guidelines
## Testing Guidelines

- **HCL**: 4-space indentation, descriptive variables (e.g., `IMAGE_NAME`, `PHP_VERSION`)
- **Shell**: Use `set -exo pipefail`, proper quoting, environment variable prefixes
- **Docker**: Multi-platform builds (`linux/amd64`, `linux/arm64`), proper labels
- **Tags**: Use semantic versioning, clean tag function for sanitization
- **Functions**: HCL functions for reusable logic (tag generation, version parsing)
- **Matrix builds**: Support multiple PHP versions and OS variants
- **Labels**: Include OpenContainers standard labels with metadata
There is no external test framework or coverage threshold. `test.php` is the acceptance suite. Update its expected extension and binary arrays whenever image contents change, then test both `dev` and `production`. For architecture-sensitive changes, run the Buildx matrix or rely on the PR workflow for both supported platforms.

## Commit & Pull Request Guidelines

Prefer short, imperative Conventional Commit subjects such as `feat: add healthcheck script`, `fix: correct pnpm path`, or `chore: remove package`; avoid `wip` commits in review-ready branches. Pull requests should explain the affected stage or variant, note tag/platform impact, link relevant issues, and list exact build and test commands with results. Screenshots are only useful for user-visible shell behavior.

## Security & Configuration

`.env` is copied into `/etc/profile.d/.env`; keep it limited to non-secret container defaults and aliases. Never commit registry tokens, credentials, or application secrets.
33 changes: 0 additions & 33 deletions CLAUDE.md

This file was deleted.

Loading
Loading