chore(release): build cross-platform binaries and update Homebrew tap#27
chore(release): build cross-platform binaries and update Homebrew tap#27wax911 wants to merge 10 commits into
Conversation
- Deno 2.x project structure with deno.json and task definitions - JSR dependencies: @cliffy/command, @std/assert, @std/testing, @std/yaml, @std/dotenv, @std/fs, @std/path - Full CLI command tree with stubs for all 15 issues - Shared interfaces (ProcessRunner, config types, ExitCode) for parallel work - FakeProcessRunner with recording, pre-programmed responses, and dry-run support - CI pipeline: fmt, lint, typecheck, test, coverage, and cross-platform build - .gitignore for generated and environment-specific files
- Default config values with sensible defaults - Deep merge for 5-layer config resolution (defaults -> base -> profile -> local -> local-profile) - Filesystem discovery (.stackctl, .stackctl.<profile>, .stackctl.local, .stackctl.local.<profile>) - Post-merge validation returning all errors at once - Template generation with inline comments, --detect, --preset, --profile, --force, --dry-run - STACKCTL_PROFILE env var support - 43 config tests + existing 15 = 58 passing - CLI init command wired to real implementation
Port of tools/generate_stacks.py from AniTrend/local-stack to idiomatic Deno TypeScript: - File discovery: walks repo root, finds docker-compose.yml/yaml files with x-stack metadata - Fragment loading: optional swarm.fragment.yml deep-merge per service - Compose deep merge (dict recursive, array replacement, scalar override) - Service transforms: strip compose-only keys (container_name, restart, build), inject logging defaults, rewrite env_file and bind-mount paths to repo-root relative - Named volume collection (external: true), default traefik-public overlay network - YAML output with header comment, --dry-run support - CLI generate command wired to real implementation - 60 compose tests + 58 existing = 118 passing
- composeOverrideMerge: scalars replace, maps merge, sequences append (distinct from fragment merge which replaces arrays) - loadOverrideFile: load YAML override from relative/absolute path - applyOverrides: load and apply chain of override files to base compose - Override integration in generateStacks via GenerateOptions.overrides - 26 tests covering all merge rules, file loading, edge cases - CLI generate command accepts --override flag
- Variable interpolation: ${VAR}, ${VAR-default}, ${VAR:-default}, $VAR, $$
- Variable scope resolution: shell env -> env_file(s) -> service.environment
- Deep interpolation through all string values in compose structures
- Path absolutization for env_file and bind-mount paths
- Strict mode (fail on unresolved) and non-strict mode (leave as-is with warnings)
- CLI pipeline: resolveConfig -> generateStacks -> renderStack -> output
- 49 comprehensive tests covering all interpolation forms and edge cases
Covers config migration, command mapping, profiles, overrides, rollback, troubleshooting, and behavior differences.
- Add composite action at .github/actions/setup-stackctl/action.yml - Support linux-x64, linux-arm64, macos-x64, macos-arm64 - Download from GitHub Releases, verify SHA256, cache in tool cache - Resolve latest version via GitHub API, accept explicit versions - Add PATH integration for subsequent workflow steps - Document CI usage in docs/migration.md Closes #11
- Add RealProcessRunner using Deno.Command with dry-run and signal forwarding - Add Docker CLI integration module (deploy, rm, services, ps, logs, info, swarm) - Add full sync pipeline: config -> discover -> generate -> render -> deploy - Wire CLI commands: up, down, status, logs, doctor, sync - Replace all issue #6 stubs with real implementations - Add 31 new tests (22 docker + 9 sync) all using FakeProcessRunner
- deno.json: add build:* tasks with Deno.compile for 4 targets - .github/workflows/release.yml: build matrix, SHA256 checksums, GitHub Releases - .github/workflows/ci.yml: update build stage to use renamed tasks
wax911
left a comment
There was a problem hiding this comment.
Review notes against #12:
-
Release asset naming does not match the agreed contract. The issue required tarballs like
stackctl-v<version>-x86_64-apple-darwin.tar.gzpluschecksums.txt. This workflow publishes raw binaries namedstackctl-linux-x64,stackctl-macos-arm64, etc. That will not line up with the Homebrew formula issue or setup-action issue. -
Each tarball should contain
stackctl,README.md, andLICENSE. This workflow does not package tarballs at all. -
macOS runners generally do not provide GNU
sha256sumby default. Use a portable checksum strategy, for exampleshasum -a 256, or run checksum generation in a Linux packaging job after downloading artifacts. -
deno compileuses broad--allow-run --allow-sys. The plan required explicit permissions, especially scoped--allow-run=docker,sops,age,age-keygen,shred,rmand scoped sys permissions. -
The workflow does not trigger or open a reviewable PR against
AniTrend/homebrew-tap. That can be a follow-up if documented, but the current PR says it includes Homebrew tap update support, so the gap should be resolved or the claim removed.
This needs to align with the release asset contract before the setup action and Homebrew formula can be reliable.
- Package binaries as stackctl-v<version>-<target>.tar.gz - Include stackctl, README, LICENSE in each tarball - Use portable checksum generation (shasum -a 256) - Add scoped permissions to deno compile commands - Include README/LICENSE copy in build artifacts
Closes #12