diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 000000000..778a774d0 --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,61 @@ +# Use the official Go image as base +FROM golang:1.25-bookworm + +# Install system dependencies +RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ + && apt-get -y install --no-install-recommends \ + build-essential \ + ca-certificates \ + curl \ + git \ + gnupg \ + make \ + nano \ + software-properties-common \ + vim \ + wget \ + && apt-get clean -y && rm -rf /var/lib/apt/lists/* + +# Install golangci-lint +RUN curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b /usr/local/bin v1.62.2 + +# Install goreleaser +RUN echo 'deb [trusted=yes] https://repo.goreleaser.com/apt/ /' | tee /etc/apt/sources.list.d/goreleaser.list \ + && apt-get update \ + && apt-get install -y goreleaser \ + && apt-get clean -y && rm -rf /var/lib/apt/lists/* + +# Install Hugo (for documentation) +RUN wget https://github.com/gohugoio/hugo/releases/download/v0.139.4/hugo_extended_0.139.4_linux-amd64.deb \ + && dpkg -i hugo_extended_0.139.4_linux-amd64.deb \ + && rm hugo_extended_0.139.4_linux-amd64.deb + +# Create a non-root user +ARG USERNAME=vscode +ARG USER_UID=1000 +ARG USER_GID=$USER_UID + +RUN groupadd --gid $USER_GID $USERNAME \ + && useradd --uid $USER_UID --gid $USER_GID -m $USERNAME -s /bin/bash \ + && apt-get update \ + && apt-get install -y sudo \ + && echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \ + && chmod 0440 /etc/sudoers.d/$USERNAME + +# Set up Go workspace +ENV GOPATH=/go +RUN mkdir -p /go/pkg/mod && chown -R ${USERNAME}:${USERNAME} /go + +# Switch to non-root user +USER $USERNAME + +# Install Go tools that are commonly used +RUN go install golang.org/x/tools/gopls@latest \ + && go install github.com/go-delve/delve/cmd/dlv@latest \ + && go install honnef.co/go/tools/cmd/staticcheck@latest + +# Set working directory +WORKDIR /workspace + +# Persist bash history across container restarts +VOLUME ["/home/vscode/.bash_history"] diff --git a/.devcontainer/README.md b/.devcontainer/README.md new file mode 100644 index 000000000..541690775 --- /dev/null +++ b/.devcontainer/README.md @@ -0,0 +1,231 @@ +# Kosli CLI DevContainer + +This devcontainer provides a complete development environment for the Kosli CLI project. + +## What's Included + +### Languages & Runtimes + +- **Go 1.25** - Primary development language +- **Node.js LTS** - For npm package management and release + +### Development Tools + +- **golangci-lint** - Go linting and static analysis +- **goreleaser** - Release automation +- **gotestsum** - Enhanced Go test runner +- **Hugo Extended** - Documentation site generation +- **GitHub CLI (gh)** - GitHub integration + +### Infrastructure + +- **Docker-in-Docker** - For integration tests (runs Kosli server) +- **Make** - Build automation +- **Git** - Version control + +## Getting Started + +1. **Open in VS Code** + - Install the "Dev Containers" extension + - Open this repository in VS Code + - Click "Reopen in Container" when prompted (or use Command Palette: "Dev Containers: Reopen in Container") + +2. **Wait for Setup** + - The container will build (first time takes a few minutes) + - Post-create commands will run automatically (`go mod download`, etc.) + +3. **Start Developing** + + ```bash + # Build the CLI + make build + + # Run tests + make test_integration + + # Run linting + make lint + + # Build documentation + make hugo-local + ``` + +## Container Features + +### Forwarded Ports + +- **1515** - Hugo documentation server +- **8001** - Local Kosli server (for integration tests) + +### Volume Mounts + +- Go module cache is persisted in a Docker volume for faster builds +- Docker socket is mounted for Docker-in-Docker functionality + +### VS Code Extensions + +The following extensions are automatically installed: + +- **Go** - Go language support +- **Docker** - Docker file and container management +- **GitLens** - Enhanced Git capabilities + +### VS Code Settings + +Pre-configured with: + +- Go formatting on save +- Automatic import organization +- golangci-lint integration +- Go language server (gopls) + +## Common Tasks + +### Building the CLI + +```bash +make build +./kosli version +``` + +### Running Tests + +```bash +# Integration tests (requires Docker) +make test_integration + +# Run all tests including slow ones +make test_integration_full + +# Run specific test suite +make test_integration_single TARGET=TestAttestJunitCommandTestSuite +``` + +### Working with NPM Package + +```bash +# Test npm package installation locally +npm install +npm test + +# Pack for distribution +npm pack + +# Test the packed version +mkdir /tmp/npm-test && cd /tmp/npm-test +npm install /workspace/*.tgz +npx kosli version +``` + +### Documentation + +```bash +# Generate CLI documentation +make cli-docs + +# Start Hugo documentation server (accessible at localhost:1515) +make hugo-local +``` + +### Linting + +```bash +make lint +``` + +## Environment Variables + +The following environment variables are pre-configured: + +- `CGO_ENABLED=0` - Disable CGO for static binaries +- `GO111MODULE=on` - Use Go modules +- `GOPATH=/go` - Go workspace location + +### Required for Testing + +You need to set `KOSLI_API_TOKEN_PROD` for integration tests: + +```bash +export KOSLI_API_TOKEN_PROD="your-token-here" +``` + +## Docker Integration + +The devcontainer uses Docker-in-Docker to run integration tests. The Kosli server runs in a container alongside your tests. + +### Managing Test Containers + +```bash +# View server logs +make logs_integration_test_server + +# Follow server logs +make follow_integration_test_server + +# Enter server container +make enter_integration_test_server +``` + +## Troubleshooting + +### Container won't start + +- Ensure Docker Desktop is running +- Check Docker has enough resources (4GB+ RAM recommended) +- Try rebuilding: Command Palette → "Dev Containers: Rebuild Container" + +### Tests failing + +- Ensure `KOSLI_API_TOKEN_PROD` is set +- Check Docker is working: `docker ps` +- Verify network: `docker network ls` (should see `cli_net`) + +### Go modules issues + +```bash +go clean -modcache +go mod download +go mod tidy +``` + +### NPM installation issues + +```bash +rm -rf node_modules package-lock.json +npm install +``` + +## Customization + +### Adding VS Code Extensions + +Edit [.devcontainer/devcontainer.json](.devcontainer/devcontainer.json): + +```json +"extensions": [ + "golang.go", + "your-extension-id" +] +``` + +### Installing Additional Tools + +Edit [.devcontainer/Dockerfile](.devcontainer/Dockerfile) and rebuild the container. + +### Changing Environment Variables + +Edit the `remoteEnv` section in [.devcontainer/devcontainer.json](.devcontainer/devcontainer.json). + +## Non-Root User + +The container runs as the `vscode` user (non-root) for security. Use `sudo` if you need root access: + +```bash +sudo apt-get install some-package +``` + +## References + +- [Dev Containers Documentation](https://code.visualstudio.com/docs/devcontainers/containers) +- [Kosli Documentation](https://docs.kosli.com/) +- [Project Development Guide](../dev-guide.md) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 000000000..c98e8c192 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,74 @@ +{ + "name": "Kosli CLI Development", + "build": { + "dockerfile": "Dockerfile", + "context": ".." + }, + + // Configure tool-specific properties + "customizations": { + "vscode": { + "settings": { + "go.gopath": "/go", + "go.toolsManagement.checkForUpdates": "local", + "go.useLanguageServer": true, + "go.lintTool": "golangci-lint", + "go.lintOnSave": "workspace", + "editor.formatOnSave": true, + "[go]": { + "editor.defaultFormatter": "golang.go", + "editor.codeActionsOnSave": { + "source.organizeImports": "explicit" + } + } + }, + "extensions": [ + "DavidAnson.vscode-markdownlint", + "eamodio.gitlens", + "golang.go", + "ms-azuretools.vscode-docker", + "ms-vscode.makefile-tools", + "yzhang.markdown-all-in-one" + ] + } + }, + + // Use 'forwardPorts' to make a list of ports inside the container available locally + "forwardPorts": [1515, 8001], + + // Use 'postCreateCommand' to run commands after the container is created + "postCreateCommand": "go mod download && go install gotest.tools/gotestsum@latest", + + // Features to add to the dev container + "features": { + "ghcr.io/devcontainers/features/docker-in-docker:2": { + "version": "latest", + "moby": true, + "dockerDashComposeVersion": "v2" + }, + "ghcr.io/devcontainers/features/node:1": { + "version": "lts", + "nodeGypDependencies": true, + "installYarnUsingApt": false + }, + "ghcr.io/devcontainers/features/github-cli:1": { + "version": "latest" + } + }, + + // Set environment variables + "remoteEnv": { + "CGO_ENABLED": "0", + "GO111MODULE": "on", + "GOPATH": "/go" + }, + + // Run as vscode user (non-root) + "remoteUser": "vscode", + + // Mount docker socket and go module cache + "mounts": [ + "source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind", + "source=kosli-cli-gomod,target=/go/pkg/mod,type=volume" + ] +}