|
| 1 | +# Implementation Plan: Install Zig for Cross-Platform CI Builds |
| 2 | + |
| 3 | +**Status**: Draft |
| 4 | +**Research Doc**: `.docs/research-zig-ci-installation.md` |
| 5 | +**Author**: AI Agent (Claude Code) |
| 6 | +**Date**: 2026-05-27 |
| 7 | +**Estimated Effort**: 2 hours |
| 8 | + |
| 9 | +## Overview |
| 10 | + |
| 11 | +### Summary |
| 12 | +Enable zig for all CI build targets by: |
| 13 | +1. Adding `Cross.toml` with pre-build commands to install zig in cross containers |
| 14 | +2. Adding zig installation step for Windows builds |
| 15 | +3. Fixing Docker workspace member path issue |
| 16 | + |
| 17 | +### Approach |
| 18 | +Use cross's built-in `pre-build` feature to install zig in Docker containers, and standard package managers for Windows. |
| 19 | + |
| 20 | +### Scope |
| 21 | + |
| 22 | +**In Scope:** |
| 23 | +- Create `Cross.toml` with zig pre-build for musl targets |
| 24 | +- Add Windows zig install step in workflow |
| 25 | +- Fix Docker workspace member issue |
| 26 | +- Test the complete workflow |
| 27 | + |
| 28 | +**Out of Scope:** |
| 29 | +- Replacing zlob with pure-Rust alternative |
| 30 | +- Forking cross Docker images |
| 31 | +- Custom Docker image builds |
| 32 | +- Fixing crates.io publishing issue (separate problem) |
| 33 | + |
| 34 | +**Avoid At All Cost:** |
| 35 | +- Hardcoding specific zig versions (use latest or env var) |
| 36 | +- Complex custom Dockerfiles |
| 37 | +- Breaking existing macOS builds |
| 38 | + |
| 39 | +## Architecture |
| 40 | + |
| 41 | +### Component Diagram |
| 42 | + |
| 43 | +``` |
| 44 | +GitHub Actions Workflow |
| 45 | +├── Linux musl builds (cross) |
| 46 | +│ └── Cross.toml → pre-build: apt-get install zig |
| 47 | +│ └── Container now has zig → build succeeds |
| 48 | +├── Windows build |
| 49 | +│ └── Workflow step: choco install zig |
| 50 | +│ └── Runner now has zig → build succeeds |
| 51 | +├── macOS builds |
| 52 | +│ └── Already has zig → no changes |
| 53 | +└── Docker builds |
| 54 | + └── Fix workspace member path → build succeeds |
| 55 | +``` |
| 56 | + |
| 57 | +### Key Design Decisions |
| 58 | + |
| 59 | +| Decision | Rationale | Alternatives Rejected | |
| 60 | +|----------|-----------|----------------------| |
| 61 | +| Use `pre-build` in Cross.toml | Official cross feature, minimal complexity | Custom Docker images | |
| 62 | +| Use apt-get for Linux containers | Debian-based containers, most reliable | Download from ziglang.org | |
| 63 | +| Use chocolatey for Windows | Standard on GitHub-hosted runners | Scoop, manual download | |
| 64 | +| Fix Docker workspace issue | Simple path fix in Dockerfile | Restructure workspace | |
| 65 | + |
| 66 | +### Simplicity Check |
| 67 | + |
| 68 | +> "What if this could be easy?" |
| 69 | +
|
| 70 | +The simplest solution: |
| 71 | +1. One `Cross.toml` file with 3 pre-build lines |
| 72 | +2. One workflow step for Windows |
| 73 | +3. One Dockerfile edit |
| 74 | + |
| 75 | +**Senior Engineer Test**: Is this overcomplicated? No - it's using built-in features. |
| 76 | + |
| 77 | +## File Changes |
| 78 | + |
| 79 | +### New Files |
| 80 | +| File | Purpose | |
| 81 | +|------|---------| |
| 82 | +| `Cross.toml` | cross configuration with zig pre-build | |
| 83 | + |
| 84 | +### Modified Files |
| 85 | +| File | Changes | |
| 86 | +|------|---------| |
| 87 | +| `.github/workflows/release-comprehensive.yml` | Add Windows zig install, fix Docker issue | |
| 88 | +| `Dockerfile` or `.github/workflows/docker-multiarch.yml` | Fix workspace member path | |
| 89 | + |
| 90 | +## Implementation Steps |
| 91 | + |
| 92 | +### Step 1: Create Cross.toml |
| 93 | +**File:** `Cross.toml` |
| 94 | +**Description:** Configure cross to install zig before building musl targets |
| 95 | + |
| 96 | +```toml |
| 97 | +[target.aarch64-unknown-linux-musl] |
| 98 | +pre-build = [ |
| 99 | + "apt-get update && apt-get install -y snapd", |
| 100 | + "snap install zig --classic --beta", |
| 101 | +] |
| 102 | + |
| 103 | +[target.x86_64-unknown-linux-musl] |
| 104 | +pre-build = [ |
| 105 | + "apt-get update && apt-get install -y snapd", |
| 106 | + "snap install zig --classic --beta", |
| 107 | +] |
| 108 | + |
| 109 | +[target.armv7-unknown-linux-musleabihf] |
| 110 | +pre-build = [ |
| 111 | + "apt-get update && apt-get install -y snapd", |
| 112 | + "snap install zig --classic --beta", |
| 113 | +] |
| 114 | +``` |
| 115 | + |
| 116 | +Wait - snap may not work in Docker containers. Let me use a different approach. |
| 117 | + |
| 118 | +Better approach - download zig directly: |
| 119 | +```toml |
| 120 | +[target.aarch64-unknown-linux-musl] |
| 121 | +pre-build = [ |
| 122 | + "apt-get update && apt-get install -y curl xz-utils", |
| 123 | + "curl -L https://ziglang.org/builds/zig-linux-x86_64-0.16.0-dev.1234+abcdef.tar.xz -o /tmp/zig.tar.xz", |
| 124 | + "tar -xf /tmp/zig.tar.xz -C /usr/local --strip-components=1", |
| 125 | +] |
| 126 | +``` |
| 127 | + |
| 128 | +Actually, the simplest and most reliable approach is to use the official zig download: |
| 129 | + |
| 130 | +```toml |
| 131 | +[target.aarch64-unknown-linux-musl] |
| 132 | +pre-build = [ |
| 133 | + "apt-get update && apt-get install -y wget tar xz-utils", |
| 134 | + "wget -q https://ziglang.org/download/0.13.0/zig-linux-x86_64-0.13.0.tar.xz -O /tmp/zig.tar.xz", |
| 135 | + "tar -xf /tmp/zig.tar.xz -C /tmp", |
| 136 | + "cp /tmp/zig-linux-x86_64-0.13.0/zig /usr/local/bin/zig", |
| 137 | + "chmod +x /usr/local/bin/zig", |
| 138 | +] |
| 139 | +``` |
| 140 | + |
| 141 | +But we want to avoid hardcoding versions. Let me check if we can use the latest version or apt. |
| 142 | + |
| 143 | +Actually, for Ubuntu/Debian, there's a simpler way - use the official zig PPA or just download the latest stable version. |
| 144 | + |
| 145 | +Let me use a more robust approach that works with any version: |
| 146 | + |
| 147 | +```toml |
| 148 | +[target.aarch64-unknown-linux-musl] |
| 149 | +pre-build = [ |
| 150 | + "apt-get update && apt-get install -y curl tar xz-utils", |
| 151 | + "curl -s https://ziglang.org/download/index.json | grep -o 'https://.*zig-linux-x86_64-[^\"]*\\.tar\\.xz' | head -1 | xargs -I {} curl -L {} -o /tmp/zig.tar.xz", |
| 152 | + "tar -xf /tmp/zig.tar.xz -C /tmp", |
| 153 | + "cp /tmp/zig-*/zig /usr/local/bin/zig", |
| 154 | + "chmod +x /usr/local/bin/zig", |
| 155 | + "zig version", |
| 156 | +] |
| 157 | +``` |
| 158 | + |
| 159 | +This dynamically fetches the latest zig version. |
| 160 | + |
| 161 | +**Tests:** Build locally with cross |
| 162 | +**Estimated:** 30 minutes |
| 163 | + |
| 164 | +### Step 2: Add Windows zig installation |
| 165 | +**File:** `.github/workflows/release-comprehensive.yml` |
| 166 | +**Description:** Add step to install zig on Windows runner |
| 167 | + |
| 168 | +```yaml |
| 169 | +- name: Install zig (required by zlob dependency) |
| 170 | + if: contains(matrix.target, 'windows') |
| 171 | + run: | |
| 172 | + choco install zig |
| 173 | + zig version |
| 174 | +``` |
| 175 | +
|
| 176 | +**Tests:** Verify Windows build succeeds |
| 177 | +**Estimated:** 15 minutes |
| 178 | +
|
| 179 | +### Step 3: Fix Docker workspace issue |
| 180 | +**File:** `.github/workflows/docker-multiarch.yml` or Dockerfile |
| 181 | +**Description:** The Docker build fails because it doesn't copy `infrastructure/` but workspace expects it. |
| 182 | + |
| 183 | +Options: |
| 184 | +1. Add `infrastructure/` to Docker COPY commands |
| 185 | +2. Remove `infrastructure/*` from workspace members and make it a separate workspace |
| 186 | +3. Use `--exclude infrastructure` in cargo build |
| 187 | + |
| 188 | +The simplest fix is option 1 - copy infrastructure into the Docker context. |
| 189 | + |
| 190 | +**Estimated:** 30 minutes |
| 191 | + |
| 192 | +### Step 4: Test workflow |
| 193 | +**Description:** |
| 194 | +1. Commit changes |
| 195 | +2. Push to main |
| 196 | +3. Create test tag or re-run workflow |
| 197 | +4. Verify all builds succeed |
| 198 | + |
| 199 | +**Estimated:** 30 minutes |
| 200 | + |
| 201 | +## Rollback Plan |
| 202 | + |
| 203 | +If issues discovered: |
| 204 | +1. Revert Cross.toml |
| 205 | +2. Revert workflow changes |
| 206 | +3. macOS builds will still work (unaffected) |
| 207 | + |
| 208 | +## Dependencies |
| 209 | + |
| 210 | +### New Dependencies |
| 211 | +None |
| 212 | + |
| 213 | +### External Tools |
| 214 | +- curl (in cross containers) |
| 215 | +- tar (in cross containers) |
| 216 | +- xz-utils (in cross containers) |
| 217 | +- chocolatey (on Windows runners) |
| 218 | + |
| 219 | +## Performance Considerations |
| 220 | + |
| 221 | +### Expected Impact |
| 222 | +- Pre-build adds ~30-60 seconds per musl build |
| 223 | +- Windows zig install adds ~30 seconds |
| 224 | +- Total workflow time increase: ~2-3 minutes |
| 225 | + |
| 226 | +## Open Items |
| 227 | + |
| 228 | +| Item | Status | Owner | |
| 229 | +|------|--------|-------| |
| 230 | +| Verify cross container has internet | Pending | Test in CI | |
| 231 | +| Verify chocolatey works on Windows | Pending | Test in CI | |
| 232 | +| Determine correct zig version | Pending | Use latest stable | |
| 233 | + |
| 234 | +## Approval |
| 235 | + |
| 236 | +- [ ] Technical review complete |
| 237 | +- [ ] Test strategy approved |
| 238 | +- [ ] Human approval received |
0 commit comments