From 2cfd6a5b4339aa3efd7fbb65303b878acecd3cc3 Mon Sep 17 00:00:00 2001 From: Ben Davis <45952064+bmdavis419@users.noreply.github.com> Date: Mon, 12 Oct 2026 23:18:23 -0700 Subject: [PATCH] Add GitHub Actions CI and contributor install docs. Run gofmt, go vet, go build, and go test on pull requests and pushes to main. Document install, the first tx9 create, and the opt-in Docker helper tests. --- .github/workflows/ci.yml | 49 +++++++++++++++++++++++ CONTRIBUTING.md | 86 ++++++++++++++++++++++++++++++++++++++++ README.md | 55 +++++++++++++++++++++++-- 3 files changed, 187 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/ci.yml create mode 100644 CONTRIBUTING.md diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..3997e66 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,49 @@ +name: CI + +on: + pull_request: + push: + branches: [main] + +permissions: + contents: read + +jobs: + go: + name: Go + runs-on: ubuntu-latest + timeout-minutes: 15 + steps: + - name: Checkout + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + - name: Set up Go + uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 + with: + go-version-file: go.mod + + # -buildvcs=false matches the Makefile. Go fails the build when VCS + # metadata is unavailable, which includes the default shallow checkout + # and this repo's linked worktrees. The CLI version comes from -ldflags. + # + # internal/docker's live helper tests run only when TX9_TEST_DOCKER_IMAGE + # names an already installed shell image. Leave it unset so this job does + # not pull images or start containers. See CONTRIBUTING.md. + - name: gofmt + run: | + unformatted="$(gofmt -l .)" + if [ -n "$unformatted" ]; then + printf 'gofmt: unformatted files:\n%s\n' "$unformatted" >&2 + exit 1 + fi + + - name: go vet + run: go vet -buildvcs=false ./... + + - name: go build + run: go build -buildvcs=false -o "${RUNNER_TEMP}/tx9" . + + - name: go test + run: go test -buildvcs=false ./... diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..49dcbd8 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,86 @@ +# Contributing + +## Prerequisites + +- Go 1.26.7 or newer, matching the `go` line in `go.mod` +- GNU Make +- Bash, Python 3 with PyYAML, jq, gzip, and tar (the shell regression suite) +- ShellCheck 0.11.0 (`make lint` and `make check`) +- A Docker daemon only when you run a box, or the optional integration tests below + +Builds pass `-buildvcs=false`. A shallow checkout or a linked git worktree can +make Go's VCS stamping fail, and the CLI version is set with `-ldflags`. + +## Build + +```bash +make tx9 +``` + +That writes `bin/tx9` (gitignored). The same build by hand: + +```bash +go build -buildvcs=false -ldflags "-X github.com/davis7dotsh/tx9/internal/version.Version=dev" -o bin/tx9 . +``` + +`go install github.com/davis7dotsh/tx9@latest` installs a published module +version. A source build reports version `dev` and tags its image `tx9-box:dev`. + +The binary embeds `box.env`, `provision/`, `guest/`, and `docker/` at compile +time. Rebuild after editing those files before the next `tx9 create` or +`tx9 upgrade`. + +Cross-compile the four release binaries and `checksums.txt` into `dist/`: + +```bash +make dist VERSION=0.12.1 +``` + +## Test + +`make check` is the full local gate: shell syntax, ShellCheck, guest +regressions, a gofmt check, `go vet`, and `go test ./...`. + +```bash +make check +make go-check # gofmt, go vet, go test only +make format # gofmt -w . +``` + +GitHub Actions (`.github/workflows/ci.yml`) runs the same gofmt check, +`go vet -buildvcs=false ./...`, `go build -buildvcs=false`, and +`go test -buildvcs=false ./...` on pull requests and on pushes to `main`. + +`.depot/workflows/check.yml` runs `make check` and the `site/` Worker checks +on Depot. Changes under `guest/`, `provision/`, `docker/`, `scripts/`, or +`tests/` still need `make check` locally. + +### Docker integration tests + +`TestEphemeralDockerIntegration` and `TestExecDockerIntegration` talk to a +live daemon. `go test` skips them unless `TX9_TEST_DOCKER_IMAGE` is an image +already present locally that provides `/bin/sh`, `cat`, `ls`, and `sleep`. +The tests create disposable containers and do not mount host data. CI leaves +the variable unset. + +```bash +TX9_TEST_DOCKER_IMAGE=ubuntu:24.04 go test -buildvcs=false ./internal/docker/ +``` + +`make go-check` and `make check` pick up the same variable when it is set in +the environment. + +## Makefile targets + +| Target | What it runs | +| --- | --- | +| `syntax` | `bash -n` / `sh -n`, and a Python compile of the guest and release scripts | +| `lint` | ShellCheck on the bash scripts, and on `scripts/install.sh` as POSIX sh | +| `test` | `tests/static.sh`, `tests/hermes-state.sh`, and `tests/regressions-*.sh` | +| `go-check` | gofmt check, `go vet ./...`, `go test ./...` | +| `check` | `syntax`, `lint`, `test`, and `go-check` | +| `format` | `gofmt -w .` | +| `tx9` | Build `bin/tx9` | +| `dist` | Cross-compile release binaries into `dist/` (`VERSION=` stamps the binary) | + +`make test` is the shell suite. The Go tests are `make go-check`. diff --git a/README.md b/README.md index dc931a7..bb9895e 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,48 @@ Separate containers do not keep Executor credentials confidential from that agent. Read the [security model](docs/security-model.md) before connecting sensitive accounts or host storage. +## Install + +Prerequisites: a running Docker daemon your user can access. Release binaries +are Linux and macOS, amd64 and arm64. The first `tx9 create` builds the box +image on that daemon. The build takes several minutes and is cached after that. + +Install the current release into `~/.local/bin` (`TX9_INSTALL_DIR` overrides +the directory). The installer prints a `PATH` line when that directory is +absent from `PATH`: + +```bash +curl -fsSL https://tx9.col-agents.com/install | sh +tx9 version +``` + +Or install a published module version. This needs the Go version in `go.mod` +(1.26.7 or newer): + +```bash +go install github.com/davis7dotsh/tx9@latest +``` + +Or build from a checkout. `make tx9` writes `./bin/tx9`: + +```bash +make tx9 +./bin/tx9 version +``` + +A source build reports version `dev` and tags its image `tx9-box:dev`. + +Create a box, then open a shell in the agent container. With no name, `tx9 +create` generates one and prints it: + +```bash +tx9 create my-box +tx9 list +tx9 enter my-box +``` + +Build, test, and Makefile details are in [CONTRIBUTING.md](CONTRIBUTING.md). + The [October 2026 reliability and performance pass](docs/audit-2026-10-04.md) records the latest fixes and measurements. The [August 2026 audit](docs/audit-2026-08-27.md) records earlier validation and remaining decisions. Package versions and earlier @@ -255,10 +297,17 @@ toolchain declared in `go.mod`, and Node 22.18 or newer with npm. Go modules and npm packages must be available or downloaded first. With an older Go 1.26 patch release installed, `go` downloads the declared toolchain on first use unless `GOTOOLCHAIN=local` is set, in which case the build fails instead. -Docker integration tests are optional; setting `TX9_TEST_DOCKER_IMAGE` to an -already installed image with `/bin/sh`, `cat`, `ls`, and `sleep` enables -disposable helper tests. The audit used an existing `ubuntu:24.04` image. +Set `TX9_TEST_DOCKER_IMAGE` to run the live Docker helper tests. The image +must already be installed and must provide `/bin/sh`, `cat`, `ls`, and +`sleep`. Without that variable, `go test ./...` skips them, including on +GitHub Actions: + +```bash +TX9_TEST_DOCKER_IMAGE=ubuntu:24.04 go test -buildvcs=false ./internal/docker/ +``` +`.github/workflows/ci.yml` runs gofmt, `go vet`, `go build`, and +`go test ./...` on pull requests and pushes to `main`. `.depot/workflows/check.yml` runs the Go/guest and site checks through Depot CI for pushes to `main` and pull requests against any branch, including stacks.