diff --git a/.dockerignore b/.dockerignore index 78f7b804172..7233cf16441 100644 --- a/.dockerignore +++ b/.dockerignore @@ -2,5 +2,11 @@ target bin **/target **/node_modules +.git +.github +.DS_Store +coverage-check +coverage.txt wormchain/build/config/gentx/ +.DS_Store diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 404aa953933..d5f6bb38755 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -185,3 +185,6 @@ scripts/coverage-check @evan-gray @kcsongor @johnsaigle @mdulin2 @pleasew8t @bem ## CI .golangci.yml @evan-gray @djb15 @johnsaigle @mdulin2 cspell* @evan-gray @kcsongor @panoel @djb15 @SEJeff @johnsaigle @mdulin2 @pleasew8t @bemic +Dockerfile.unit @evan-gray @panoel @djb15 @SEJeff @johnsaigle @mdulin2 @pleasew8t @bemic +Dockerfile.lint @evan-gray @panoel @djb15 @SEJeff @johnsaigle @mdulin2 @pleasew8t @bemic +.dockerignore @evan-gray @panoel @djb15 @SEJeff @johnsaigle @mdulin2 @pleasew8t @bemic diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 627a2caaf6e..46803a1fef5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -303,11 +303,11 @@ jobs: with: go-version: "1.25.10" - name: Install formatter - run: go install golang.org/x/tools/cmd/goimports@v0.8.0 + run: go install golang.org/x/tools/cmd/goimports@009367f5c17a8d4c45a961a3a509277190a9a6f0 # v0.42.0 - name: Formatting checks run: ./scripts/lint.sh -l -g format - name: Install linters - run: curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v2.8.0 + run: go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@c0d3ddc9cf3faa61a4e378e879ece580256d76e5 # v2.12.2 - name: Run linters run: make generate && golangci-lint --version && ./scripts/lint.sh -g lint - name: Ensure generated proto matches diff --git a/Dockerfile.lint b/Dockerfile.lint new file mode 100644 index 00000000000..7c81e22145a --- /dev/null +++ b/Dockerfile.lint @@ -0,0 +1,34 @@ +# syntax=docker.io/docker/dockerfile:1.3@sha256:42399d4635eddd7a9b8a24be879d2f9a930d0ed040a61324cfdf59ef1357b3b2 +FROM node:22.16-bullseye-slim@sha256:550b434f7edc3a1875860657a3e306752358029c957280809ae6395ab296faeb AS node-tools + +RUN npm install -g cspell@9.8.0 + +# keep Go version in sync with node/go.mod +FROM docker.io/golang:1.25.10-bookworm@sha256:154bd7001b6eb339e88c964442c0ad6ed5e53f09844cc818a41ce4ecb3ce3b43 + +# Direct Go module/state under /tmp so the non-root user can write to it. +ENV GOPATH=/tmp/go +ENV GOCACHE=/tmp/go-build +ENV PATH=/tmp/go/bin:$PATH + +COPY --from=node-tools /usr/local/bin/node /usr/local/bin/node +COPY --from=node-tools /usr/local/lib/node_modules /usr/local/lib/node_modules + +RUN ln -s /usr/local/lib/node_modules/cspell/bin.mjs /usr/local/bin/cspell + +# Create a non-root user for the lint container (matches host UID convention). +# Direct Go caches to /tmp with world-writable perms so goimports/golangci-lint +# can download modules at runtime regardless of user. +RUN useradd -u 1000 -U -m -d /home/lint lint && mkdir -p /tmp/go /tmp/go-build && chmod -R 1777 /tmp/go /tmp/go-build + +# install goimports (pinned to match CI; commit is v0.42.0) +RUN go install golang.org/x/tools/cmd/goimports@009367f5c17a8d4c45a961a3a509277190a9a6f0 + +# install golangci-lint (pinned to match CI) +RUN go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@c0d3ddc9cf3faa61a4e378e879ece580256d76e5 + +# Re-apply perms after go install wrote into /tmp/go as root. +RUN chmod -R 1777 /tmp/go /tmp/go-build + +USER 1000 +WORKDIR /home/lint diff --git a/Dockerfile.unit b/Dockerfile.unit new file mode 100644 index 00000000000..0cea08f936f --- /dev/null +++ b/Dockerfile.unit @@ -0,0 +1,14 @@ +# syntax=docker.io/docker/dockerfile:1.3@sha256:42399d4635eddd7a9b8a24be879d2f9a930d0ed040a61324cfdf59ef1357b3b2 +# keep Go version in sync with node/go.mod +FROM docker.io/golang:1.25.10-bookworm@sha256:154bd7001b6eb339e88c964442c0ad6ed5e53f09844cc818a41ce4ecb3ce3b43 + +# Direct Go module/state under /tmp because the container runs as an arbitrary host UID, +# which cannot write to the default /go owned by root. +ENV GOPATH=/tmp/go +ENV GOCACHE=/tmp/go-build + +# Create Go cache dirs with world-writable sticky bit so that any user (including +# the host-mapped UID at runtime) can read and write module downloads and build cache. +RUN mkdir -p /tmp/go /tmp/go-build && chmod -R 1777 /tmp/go /tmp/go-build + +WORKDIR /app diff --git a/Makefile b/Makefile index b478e809749..ce575b6dfe5 100755 --- a/Makefile +++ b/Makefile @@ -8,6 +8,8 @@ MAKEFLAGS += --no-builtin-rules PREFIX ?= /usr/local OUT = build BIN = $(OUT)/bin +UNIT_DOCKER_IMAGE ?= wormhole-unit-test +UNIT_DOCKER_RUN = docker run --rm --workdir /app --user "$$(id -u):$$(id -g)" --mount type=bind,source=$(CURDIR),target=/app $(UNIT_DOCKER_IMAGE) -include Makefile.help @@ -36,11 +38,33 @@ lint: # Lints spelling and Go bash scripts/lint.sh lint +.PHONY: lint-docker +## Run Go lints in Docker +lint-docker: + bash scripts/lint.sh -c lint + .PHONY: lint-rust lint-rust: # Runs clippy for most Rust crates. bash scripts/clippy.sh +.PHONY: build-unit-docker +## Build the unit test container used for node/sdk Go tests +build-unit-docker: + DOCKER_BUILDKIT=1 docker build -f Dockerfile.unit -t $(UNIT_DOCKER_IMAGE) . + +.PHONY: test-unit +## Run node and sdk Go unit tests +test-unit: + @echo "Running unit tests for node and sdk..." + @cd node && go test -count=1 -v -timeout 5m -race ./... + @cd sdk && go test -count=1 -v -timeout 5m -race ./... + +.PHONY: test-docker +## Run node and sdk Go unit tests in Docker +test-docker: build-unit-docker + $(UNIT_DOCKER_RUN) make test-unit + .PHONY: node ## Build guardiand binary node: $(BIN)/guardiand @@ -59,6 +83,11 @@ test-coverage: @set -o pipefail && (cd node && go test -count=1 -v -timeout 5m -race -cover ./...) 2>&1 | tee coverage.txt @set -o pipefail && (cd sdk && go test -count=1 -v -timeout 5m -race -cover ./...) 2>&1 | tee -a coverage.txt +.PHONY: test-coverage-docker +## Run test-coverage in Docker +test-coverage-docker: build-unit-docker + $(UNIT_DOCKER_RUN) make test-coverage + .PHONY: check-coverage ## Check coverage against baseline (run tests first) check-coverage: build-coverage-check test-coverage diff --git a/scripts/Dockerfile.lint b/scripts/Dockerfile.lint deleted file mode 100644 index a66f32d0648..00000000000 --- a/scripts/Dockerfile.lint +++ /dev/null @@ -1,13 +0,0 @@ -# syntax=docker.io/docker/dockerfile:1.3@sha256:42399d4635eddd7a9b8a24be879d2f9a930d0ed040a61324cfdf59ef1357b3b2 -FROM docker.io/golang:1.25.10-bookworm@sha256:154bd7001b6eb339e88c964442c0ad6ed5e53f09844cc818a41ce4ecb3ce3b43 - -RUN useradd -u 1000 -U -m -d /home/lint lint -USER 1000 -WORKDIR /home/lint - -# install goimports -RUN go install golang.org/x/tools/cmd/goimports@latest - -# install golangci-lint -RUN curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | \ - sh -s -- -b $(go env GOPATH)/bin v1.52.2 diff --git a/scripts/lint.sh b/scripts/lint.sh index da82a8b4b2e..da83a7502b6 100755 --- a/scripts/lint.sh +++ b/scripts/lint.sh @@ -4,7 +4,7 @@ set -eo pipefail -o nounset ROOT="$(dirname "$(dirname "$(realpath "$0")")")" -DOCKERFILE="$ROOT/scripts/Dockerfile.lint" +DOCKERFILE="$ROOT/Dockerfile.lint" VALID_COMMANDS=("lint" "format") @@ -147,7 +147,7 @@ if [ "$DOCKER" == "true" ]; then if ! [[ "$GOIMPORTS_ARGS" =~ "w" ]]; then MOUNT+=",readonly" fi - docker run --workdir /app "$MOUNT" "$DOCKER_IMAGE" "$DOCKER_EXEC" $SELF_ARGS_WITHOUT_DOCKER "$COMMAND" + docker run --rm --workdir /app "$MOUNT" "$DOCKER_IMAGE" "$DOCKER_EXEC" $SELF_ARGS_WITHOUT_DOCKER "$COMMAND" exit "$?" fi