|
| 1 | +# Instructions for AI agents |
| 2 | + |
| 3 | +This document provides guidance for AI agents working with this repository. |
| 4 | + |
| 5 | +## Repository overview |
| 6 | + |
| 7 | +Hydrofoil Crystal is an opinionated, Alpine-based development container for the |
| 8 | +Crystal programming language. It provides Docker images with Crystal compiler, |
| 9 | +Shards package manager, and essential development tools. |
| 10 | + |
| 11 | +### Directory structure |
| 12 | + |
| 13 | +``` |
| 14 | +. |
| 15 | +├── docker/ # Dockerfiles for each Crystal version |
| 16 | +│ ├── 1.17/ |
| 17 | +│ ├── 1.18/ |
| 18 | +│ ├── 1.19/ |
| 19 | +│ └── ... |
| 20 | +├── .github/ |
| 21 | +│ ├── versions.json # Version matrix for CI builds |
| 22 | +│ └── workflows/ |
| 23 | +│ └── ci.yml # GitHub Actions workflow |
| 24 | +├── examples/ # Usage examples |
| 25 | +├── goss.yaml # Container validation tests |
| 26 | +└── Makefile # Local build commands |
| 27 | +``` |
| 28 | + |
| 29 | +## Adding a new Crystal version |
| 30 | + |
| 31 | +When adding support for a new Crystal version, follow these steps: |
| 32 | + |
| 33 | +### 1. Calculate SHA256 checksums |
| 34 | + |
| 35 | +Use curl to download and calculate checksums for Crystal and Shards: |
| 36 | + |
| 37 | +```bash |
| 38 | +# Crystal source tarball |
| 39 | +curl -L https://github.com/crystal-lang/crystal/archive/refs/tags/VERSION.tar.gz | sha256sum - |
| 40 | + |
| 41 | +# Shards source tarball |
| 42 | +curl -L https://github.com/crystal-lang/shards/archive/refs/tags/vVERSION.tar.gz | sha256sum - |
| 43 | +``` |
| 44 | + |
| 45 | +### 2. Create the Dockerfile |
| 46 | + |
| 47 | +Create a new directory under `docker/` with the major.minor version (e.g., |
| 48 | +`docker/1.19/`) and copy the Dockerfile from the previous version as a base. |
| 49 | + |
| 50 | +Update the following values in the new Dockerfile: |
| 51 | + |
| 52 | +- `CRYSTAL_VERSION` and `CRYSTAL_SHA256` |
| 53 | +- `SHARDS_VERSION` and `SHARDS_SHA256` |
| 54 | +- `ALPINE_VERSION` if a newer stable release is available |
| 55 | + |
| 56 | +Key components in the Dockerfile: |
| 57 | + |
| 58 | +- **stage0**: Cross-compiles Crystal and Shards using Alpine's packaged Crystal |
| 59 | +- **stage1**: Links the compiled objects on the target platform |
| 60 | +- **stage2**: Prepares binaries and source code |
| 61 | +- **stage3**: Final image with development tools (fixuid, Overmind, watchexec) |
| 62 | + |
| 63 | +### 3. Update versions.json |
| 64 | + |
| 65 | +Add an entry to `.github/versions.json`: |
| 66 | + |
| 67 | +```json |
| 68 | +{ |
| 69 | + "1.19": { |
| 70 | + "crystal_full": "1.19.0" |
| 71 | + } |
| 72 | +} |
| 73 | +``` |
| 74 | + |
| 75 | +The key is the major.minor version, and `crystal_full` is the complete version |
| 76 | +string. |
| 77 | + |
| 78 | +### 4. Test the build locally |
| 79 | + |
| 80 | +Use the Makefile to build and test: |
| 81 | + |
| 82 | +```bash |
| 83 | +# Build the image |
| 84 | +make build VERSION=1.19 |
| 85 | + |
| 86 | +# Run container tests with goss |
| 87 | +make test VERSION=1.19 |
| 88 | + |
| 89 | +# Open an interactive shell |
| 90 | +make console VERSION=1.19 |
| 91 | +``` |
| 92 | + |
| 93 | +### 5. Verify the build output |
| 94 | + |
| 95 | +The build should show successful compilation and smoke tests: |
| 96 | + |
| 97 | +``` |
| 98 | +Crystal X.Y.Z (YYYY-MM-DD) |
| 99 | +LLVM: XX.X.X |
| 100 | +Default target: <arch>-alpine-linux-musl |
| 101 | +
|
| 102 | +Shards X.Y.Z (YYYY-MM-DD) |
| 103 | +``` |
| 104 | + |
| 105 | +## Build considerations |
| 106 | + |
| 107 | +### Multi-architecture support |
| 108 | + |
| 109 | +The Dockerfiles support both `linux/amd64` and `linux/arm64` through |
| 110 | +cross-compilation. The `TARGETARCH` build argument is used to compile for the |
| 111 | +target platform. |
| 112 | + |
| 113 | +### Static linking |
| 114 | + |
| 115 | +Crystal and Shards are compiled with `static=1` to produce statically linked |
| 116 | +binaries that work with Alpine's musl libc. |
| 117 | + |
| 118 | +### LLVM version |
| 119 | + |
| 120 | +The LLVM version is determined by Alpine's package repository. Check the |
| 121 | +Dockerfile for `llvm*-dev` packages to see which version is used. |
| 122 | + |
| 123 | +### Alpine version |
| 124 | + |
| 125 | +Use a stable Alpine release. The version is set via `ALPINE_VERSION` ARG at the |
| 126 | +top of the Dockerfile and is used consistently across all build stages. |
| 127 | + |
| 128 | +## Commit guidelines |
| 129 | + |
| 130 | +Follow these rules for commit messages: |
| 131 | + |
| 132 | +1. Separate subject from body with a blank line |
| 133 | +2. Limit subject line to 50 characters |
| 134 | +3. Capitalize the subject line |
| 135 | +4. Do not end the subject line with a period |
| 136 | +5. Use imperative mood in the subject line |
| 137 | +6. Wrap body at 72 characters |
| 138 | +7. Use the body to explain what and why, not how |
| 139 | + |
| 140 | +Example commit for a new version: |
| 141 | + |
| 142 | +``` |
| 143 | +Builds Crystal 1.19.0 |
| 144 | +
|
| 145 | +Introduces support for the latest Crystal release to keep the |
| 146 | +container images up to date with upstream development. |
| 147 | +
|
| 148 | +Version details: |
| 149 | +- Crystal 1.19.0 |
| 150 | +- Shards 0.20.0 |
| 151 | +- Alpine 3.23.2 |
| 152 | +- LLVM 21.1.2 |
| 153 | +``` |
| 154 | + |
| 155 | +Do not co-author commits. |
| 156 | + |
| 157 | +## Git workflow |
| 158 | + |
| 159 | +- Use dashes instead of slashes for branch names: `feature-new-functionality` |
| 160 | +- Do not use: `feature/new-functionality` |
| 161 | +- Create worktrees in `.worktrees/` directory when needed |
| 162 | + |
| 163 | +## CI/CD |
| 164 | + |
| 165 | +The GitHub Actions workflow: |
| 166 | + |
| 167 | +- Automatically detects changes to `docker/` directories |
| 168 | +- Builds only the affected versions on pull requests |
| 169 | +- Pushes multi-arch images to `ghcr.io/luislavena/hydrofoil-crystal` on main |
| 170 | +- Can be manually triggered to build specific or all versions |
| 171 | + |
| 172 | +## Testing |
| 173 | + |
| 174 | +The `goss.yaml` file defines container validation tests: |
| 175 | + |
| 176 | +- Verifies Crystal and Shards are installed and functional |
| 177 | +- Checks that required packages are present (curl, git, tmux, tzdata) |
| 178 | +- Validates fixuid setup and user configuration |
| 179 | +- Tests basic Crystal compilation with OpenSSL and YAML |
0 commit comments