Skip to content

Commit 1722239

Browse files
feat: add devcontainer for VS Code and GitHub Codespaces
Add comprehensive development container setup for easier onboarding: - Go 1.24 with gopls, delve, staticcheck, golangci-lint - SQL Server 2025 (Developer Edition) as sidecar container - Docker-in-Docker for container operations - GitHub CLI for PR management - Pre-configured VS Code extensions (Go, MSSQL, Docker, Copilot, GitLens) - Environment variables pre-set for tests (SQLCMDSERVER, etc.) - Helpful aliases (gtest, gbuild, sql, etc.) - Locally built sqlcmd added to PATH automatically - Detailed documentation in .devcontainer/README.md Files added: - .devcontainer/Dockerfile - .devcontainer/docker-compose.yml - .devcontainer/devcontainer.json - .devcontainer/post-create.sh - .devcontainer/mssql/setup.sql - .devcontainer/README.md - .dockerignore Also updates main README.md with: - 'Open in Dev Containers' badge - Development section with quick start instructions
1 parent 460b0c9 commit 1722239

8 files changed

Lines changed: 654 additions & 0 deletions

File tree

.devcontainer/Dockerfile

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# go-sqlcmd Development Container
2+
FROM mcr.microsoft.com/devcontainers/go:1-1.24-bookworm
3+
4+
# Install additional OS packages
5+
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
6+
&& apt-get install -y curl libkrb5-dev \
7+
&& apt-get clean -y && rm -rf /var/lib/apt/lists/*
8+
9+
# Install golangci-lint for code quality
10+
RUN curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b /usr/local/bin v1.64.8
11+
12+
# Install additional Go tools
13+
RUN go install golang.org/x/tools/gopls@latest \
14+
&& go install github.com/go-delve/delve/cmd/dlv@latest \
15+
&& go install honnef.co/go/tools/cmd/staticcheck@latest \
16+
&& go install golang.org/x/text/cmd/gotext@latest
17+
18+
# Create bin directory for local sqlcmd builds
19+
RUN mkdir -p /home/vscode/bin && chown vscode:vscode /home/vscode/bin
20+
ENV PATH="/home/vscode/bin:${PATH}"

.devcontainer/README.md

Lines changed: 236 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,236 @@
1+
# go-sqlcmd Development Container
2+
3+
This folder contains the configuration for a VS Code Dev Container / GitHub Codespaces development environment for go-sqlcmd.
4+
5+
## What's Included
6+
7+
- **Go 1.24** development environment with all necessary tools
8+
- **SQL Server 2025** (Developer Edition) running in a sidecar container
9+
- **Pre-configured VS Code extensions**:
10+
- Go (official extension)
11+
- MS SQL (for database management)
12+
- Docker
13+
- GitHub Copilot
14+
- GitLens
15+
- **Go quality tools**: golangci-lint, gopls, delve debugger, staticcheck
16+
- **Locally built sqlcmd** added to PATH automatically
17+
18+
## Quick Start
19+
20+
### Using VS Code (Recommended)
21+
22+
1. Install the [Dev Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers)
23+
2. Open this repository in VS Code
24+
3. When prompted, click **"Reopen in Container"**, or:
25+
- Press `F1` and select **"Dev Containers: Reopen in Container"**
26+
4. Wait for the container to build (first time takes ~5 minutes)
27+
5. Start developing!
28+
29+
### Using GitHub Codespaces
30+
31+
1. Click the green **"Code"** button on the repository
32+
2. Select **"Codespaces"** tab
33+
3. Click **"Create codespace on main"** (or your preferred branch)
34+
4. Wait for the environment to start
35+
36+
## Running Tests
37+
38+
Environment variables are pre-configured for running tests:
39+
40+
```bash
41+
# Run all tests
42+
go test ./...
43+
44+
# Run short tests
45+
go test -short ./...
46+
47+
# Run tests with verbose output
48+
go test -v ./...
49+
```
50+
51+
### Helpful Aliases
52+
53+
After the container starts, these aliases are available:
54+
55+
| Alias | Command |
56+
|-------|---------|
57+
| `gtest` | Run all tests |
58+
| `gtest-short` | Run short tests |
59+
| `gtest-v` | Run tests with verbose output |
60+
| `gbuild` | Build sqlcmd locally |
61+
| `ginstall` | Build and install sqlcmd to ~/bin |
62+
| `gfmt` | Format code |
63+
| `gvet` | Run go vet |
64+
| `glint` | Run golangci-lint |
65+
| `ggen` | Run go generate (for translations) |
66+
| `test-db` | Test database connection |
67+
| `sql` | Connect to SQL Server interactively |
68+
| `rebuild` | Rebuild sqlcmd |
69+
70+
## SQL Server Connection
71+
72+
The SQL Server instance is accessible at:
73+
74+
- **Server**: `localhost,1433`
75+
- **Username**: `sa`
76+
- **Password**: `SqlCmd@2025!`
77+
- **Database**: `master` (default) or `SqlCmdTest` (created for testing)
78+
79+
### Using the Built-in sqlcmd
80+
81+
The container builds sqlcmd from source and adds it to your PATH:
82+
83+
```bash
84+
# Using the alias
85+
sql
86+
87+
# Or explicitly
88+
~/bin/sqlcmd -S localhost -U sa -P "SqlCmd@2025!" -C
89+
90+
# Run a query
91+
sql -Q "SELECT @@VERSION"
92+
```
93+
94+
### VS Code SQL Extension
95+
96+
The MSSQL extension is pre-configured with a connection profile named **"sqlcmd-container"**. Click the SQL Server icon in the Activity Bar to connect.
97+
98+
## Environment Variables
99+
100+
The following environment variables are set automatically:
101+
102+
| Variable | Value |
103+
|----------|-------|
104+
| `SQLCMDSERVER` | `localhost` |
105+
| `SQLCMDUSER` | `sa` |
106+
| `SQLCMDPASSWORD` | `SqlCmd@2025!` |
107+
| `SQLCMDDATABASE` | `master` |
108+
| `SQLCMDDBNAME` | `master` |
109+
110+
These are the same variables used by the CI pipeline, so tests run identically.
111+
112+
## Working with sqlcmd
113+
114+
### Build and Test Workflow
115+
116+
```bash
117+
# Build sqlcmd from source
118+
ginstall
119+
120+
# Test the build
121+
~/bin/sqlcmd --version
122+
123+
# Run a query against the local SQL Server
124+
sql -Q "SELECT name FROM sys.databases"
125+
126+
# Run the test suite
127+
gtest
128+
```
129+
130+
### Rebuilding After Changes
131+
132+
```bash
133+
# Quick rebuild
134+
rebuild
135+
136+
# Or full rebuild with install
137+
ginstall
138+
```
139+
140+
## Customization
141+
142+
### Adding SQL Setup Scripts
143+
144+
Place `.sql` files in `.devcontainer/mssql/` to have them executed when the container starts.
145+
146+
### Modifying the SA Password
147+
148+
To change the SQL Server password:
149+
150+
1. Update `MSSQL_SA_PASSWORD` in `docker-compose.yml`
151+
2. Update `SQLCMDPASSWORD` in `devcontainer.json` (remoteEnv section)
152+
3. Update the password in the `mssql.connections` settings in `devcontainer.json`
153+
154+
### Using a Different SQL Server Version
155+
156+
Edit `docker-compose.yml` and change the image tag:
157+
158+
```yaml
159+
db:
160+
image: mcr.microsoft.com/mssql/server:2022-latest # or 2019-latest
161+
```
162+
163+
> **Note:** SQL Server 2025 is the default as it includes the latest features.
164+
165+
## Troubleshooting
166+
167+
### ARM64 (Apple Silicon) Users
168+
169+
SQL Server container images may have issues on ARM64 architecture. If you encounter problems:
170+
171+
1. Edit `docker-compose.yml` to use SQL Server 2022:
172+
```yaml
173+
db:
174+
image: mcr.microsoft.com/mssql/server:2022-latest
175+
```
176+
2. Ensure Rosetta is enabled in Docker Desktop: **Settings > General > "Use Rosetta for x86_64/amd64 emulation on Apple Silicon"**
177+
178+
### SQL Server not starting
179+
180+
Check the Docker logs:
181+
```bash
182+
docker logs $(docker ps -qf "name=db")
183+
```
184+
185+
Common issues:
186+
- Insufficient memory (SQL Server requires at least 2GB RAM)
187+
- Port 1433 already in use
188+
- ARM64 architecture issues (see above)
189+
190+
### Connection refused
191+
192+
Wait a few seconds after the container starts. SQL Server takes ~30 seconds to become ready. The health check should handle this automatically.
193+
194+
### Tests failing with connection errors
195+
196+
Ensure the environment variables are set:
197+
```bash
198+
echo $SQLCMDSERVER
199+
echo $SQLCMDPASSWORD
200+
```
201+
202+
If empty, try restarting the terminal or running:
203+
```bash
204+
source ~/.bashrc
205+
```
206+
207+
### sqlcmd not found
208+
209+
Run the install command:
210+
```bash
211+
ginstall
212+
```
213+
214+
Or manually:
215+
```bash
216+
go build -o ~/bin/sqlcmd ./cmd/modern
217+
```
218+
219+
## Files Reference
220+
221+
| File | Purpose |
222+
|------|---------|
223+
| `devcontainer.json` | Main configuration file |
224+
| `docker-compose.yml` | Container orchestration (Go + SQL Server) |
225+
| `Dockerfile` | Go development container image |
226+
| `post-create.sh` | Setup script (runs after container creation) |
227+
| `mssql/setup.sql` | Initial database setup script |
228+
229+
## Contributing
230+
231+
When modifying the devcontainer:
232+
233+
1. Test locally with `Dev Containers: Rebuild Container`
234+
2. Ensure all tests pass: `go test ./...`
235+
3. Verify SQL connection works: `test-db`
236+
4. Verify sqlcmd builds: `ginstall && ~/bin/sqlcmd --version`

.devcontainer/devcontainer.json

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
{
2+
"name": "go-sqlcmd Development",
3+
"dockerComposeFile": "docker-compose.yml",
4+
"service": "devcontainer",
5+
"workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}",
6+
"shutdownAction": "stopCompose",
7+
8+
// Configure tool-specific properties
9+
"customizations": {
10+
"vscode": {
11+
"extensions": [
12+
"golang.go",
13+
"ms-mssql.mssql",
14+
"ms-azuretools.vscode-docker",
15+
"GitHub.copilot",
16+
"GitHub.copilot-chat",
17+
"eamodio.gitlens",
18+
"EditorConfig.EditorConfig",
19+
"streetsidesoftware.code-spell-checker"
20+
],
21+
"settings": {
22+
"go.toolsManagement.autoUpdate": true,
23+
"go.useLanguageServer": true,
24+
"go.lintTool": "golangci-lint",
25+
"go.lintFlags": ["--fast"],
26+
"go.testEnvVars": {
27+
"SQLCMDSERVER": "localhost",
28+
"SQLCMDUSER": "sa",
29+
"SQLCMDPASSWORD": "SqlCmd@2025!",
30+
"SQLCMDDATABASE": "master"
31+
},
32+
"mssql.connections": [
33+
{
34+
"server": "localhost,1433",
35+
"database": "master",
36+
"authenticationType": "SqlLogin",
37+
"user": "sa",
38+
"password": "SqlCmd@2025!",
39+
"savePassword": true,
40+
"profileName": "sqlcmd-container",
41+
"encrypt": "Optional",
42+
"trustServerCertificate": true
43+
}
44+
],
45+
"editor.formatOnSave": true,
46+
"editor.defaultFormatter": "golang.go",
47+
"[go]": {
48+
"editor.formatOnSave": true,
49+
"editor.codeActionsOnSave": {
50+
"source.organizeImports": "explicit"
51+
}
52+
},
53+
"terminal.integrated.defaultProfile.linux": "bash"
54+
}
55+
}
56+
},
57+
58+
// Forward the SQL Server port
59+
"forwardPorts": [1433],
60+
"portsAttributes": {
61+
"1433": {
62+
"label": "SQL Server",
63+
"onAutoForward": "silent"
64+
}
65+
},
66+
67+
// Use 'postCreateCommand' to run commands after the container is created
68+
"postCreateCommand": "bash .devcontainer/post-create.sh",
69+
70+
// Environment variables for tests
71+
"remoteEnv": {
72+
"SQLCMDSERVER": "localhost",
73+
"SQLCMDUSER": "sa",
74+
"SQLCMDPASSWORD": "SqlCmd@2025!",
75+
"SQLCMDDATABASE": "master",
76+
"SQLCMDDBNAME": "master"
77+
},
78+
79+
// Features to add to the dev container
80+
"features": {
81+
"ghcr.io/devcontainers/features/docker-in-docker:2": {
82+
"version": "latest",
83+
"moby": true
84+
},
85+
"ghcr.io/devcontainers/features/github-cli:1": {
86+
"version": "latest"
87+
}
88+
}
89+
}

.devcontainer/docker-compose.yml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
version: '3.8'
2+
3+
services:
4+
devcontainer:
5+
build:
6+
context: .
7+
dockerfile: Dockerfile
8+
volumes:
9+
- ../..:/workspaces:cached
10+
# Overrides default command so things don't shut down after the process ends.
11+
command: sleep infinity
12+
# Runs app on the same network as the database container, allows "forwardPorts" in devcontainer.json function.
13+
network_mode: service:db
14+
depends_on:
15+
db:
16+
condition: service_healthy
17+
18+
db:
19+
image: mcr.microsoft.com/mssql/server:2025-latest
20+
restart: unless-stopped
21+
environment:
22+
ACCEPT_EULA: "Y"
23+
MSSQL_SA_PASSWORD: "SqlCmd@2025!"
24+
MSSQL_PID: "Developer"
25+
volumes:
26+
- mssql-data:/var/opt/mssql
27+
healthcheck:
28+
test: /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P "SqlCmd@2025!" -C -Q "SELECT 1" || exit 1
29+
interval: 10s
30+
timeout: 5s
31+
retries: 15
32+
start_period: 45s
33+
34+
volumes:
35+
mssql-data:

0 commit comments

Comments
 (0)