Skip to content

Commit 2f05e7e

Browse files
Merge pull request #22 from nauticalab/add-features
Add support for Git repositories and Homebrew packages
2 parents 41d5852 + ed19208 commit 2f05e7e

File tree

6 files changed

+108
-4
lines changed

6 files changed

+108
-4
lines changed

.github/workflows/release.yml

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919
- name: Set up Go
2020
uses: actions/setup-go@v5
2121
with:
22-
go-version: "1.24"
22+
go-version: "1.25"
2323

2424
- name: Run tests
2525
run: go test -v ./...
@@ -35,7 +35,7 @@ jobs:
3535
- name: Set up Go
3636
uses: actions/setup-go@v5
3737
with:
38-
go-version: "1.24"
38+
go-version: "1.25"
3939

4040
- name: Build binaries for all platforms
4141
run: |
@@ -57,6 +57,10 @@ jobs:
5757
echo "Building Linux amd64..."
5858
GOOS=linux GOARCH=amd64 go build -ldflags="${LDFLAGS}" -o dist/devenv-linux-amd64 ./cmd/devenv
5959
60+
# Linux arm64
61+
echo "Building Linux arm64..."
62+
GOOS=linux GOARCH=arm64 go build -ldflags="${LDFLAGS}" -o dist/devenv-linux-arm64 ./cmd/devenv
63+
6064
# macOS amd64 (Intel)
6165
echo "Building macOS amd64..."
6266
GOOS=darwin GOARCH=amd64 go build -ldflags="${LDFLAGS}" -o dist/devenv-darwin-amd64 ./cmd/devenv
@@ -72,14 +76,21 @@ jobs:
7276
echo "✅ All binaries built successfully"
7377
ls -lh dist/
7478
79+
- name: Generate checksums
80+
run: |
81+
cd dist
82+
sha256sum * > checksums.txt
83+
7584
- name: Create Release
7685
uses: softprops/action-gh-release@v2
7786
with:
7887
files: |
7988
dist/devenv-linux-amd64
89+
dist/devenv-linux-arm64
8090
dist/devenv-darwin-amd64
8191
dist/devenv-darwin-arm64
8292
dist/devenv-windows-amd64.exe
93+
dist/checksums.txt
8394
generate_release_notes: true
8495
draft: false
8596
prerelease: false

internal/config/types.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ type BaseConfig struct {
1717
// Package management
1818
Packages PackageConfig `yaml:"packages,omitempty"`
1919

20+
// Git repos to be cloned
21+
GitRepos []GitRepo `yaml:"gitRepos,omitempty" validate:"dive"`
22+
2023
// Storage configuration
2124
Volumes []VolumeMount `yaml:"volumes,omitempty" validate:"dive"`
2225

@@ -68,9 +71,18 @@ type GitConfig struct {
6871
type PackageConfig struct {
6972
Python []string `yaml:"python,omitempty" validate:"dive,min=1"`
7073
APT []string `yaml:"apt,omitempty" validate:"dive,min=1"`
74+
Brew []string `yaml:"brew,omitempty" validate:"dive,min=1"`
7175
// Consider adding other package managers such as NPM, Yarn, etc.
7276
}
7377

78+
type GitRepo struct {
79+
URL string `yaml:"url" validate:"required,min=1,url"`
80+
Branch string `yaml:"branch,omitempty" validate:"omitempty,min=1"`
81+
Tag string `yaml:"tag,omitempty" validate:"omitempty,min=1"`
82+
CommitHash string `yaml:"commitHash,omitempty" validate:"omitempty,min=1"`
83+
Directory string `yaml:"directory,omitempty" validate:"omitempty,min=1,filepath"`
84+
}
85+
7486
// ResourceConfig represents resource allocation
7587
type ResourceConfig struct {
7688
CPU any `yaml:"cpu,omitempty" validate:"omitempty,k8s_cpu"`
@@ -112,7 +124,9 @@ func NewBaseConfigWithDefaults() BaseConfig {
112124
Packages: PackageConfig{
113125
Python: []string{}, // Empty slice - no default packages
114126
APT: []string{}, // Empty slice - no default packages
127+
Brew: []string{}, // Empty slice - no default packages
115128
},
129+
GitRepos: []GitRepo{}, // Empty slice - no default git repositories
116130
Volumes: []VolumeMount{}, // Empty slice - no default volumes
117131
Namespace: "devenv", // Default namespace
118132
EnvironmentName: "development", // Default environment name

internal/config/validation.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ func init() {
5656
if err := validate.RegisterValidation("k8s_memory", validateKubernetesMemory); err != nil {
5757
panic(fmt.Errorf("register validator k8s_memory: %w", err))
5858
}
59+
validate.RegisterStructValidation(validateGitRepo, GitRepo{})
5960
}
6061

6162
// validateSSHKeys implements the "ssh_keys" tag.
@@ -79,6 +80,35 @@ func validateSSHKeys(fl validator.FieldLevel) bool {
7980
return true
8081
}
8182

83+
// validateGitRepo implements the "git_repo" tag.
84+
// Ensures that if both Branch and CommitHash are specified, an error is raised.
85+
func validateGitRepo(sl validator.StructLevel) {
86+
repo := sl.Current().Interface().(GitRepo)
87+
// Both Ref and CommitHash cannot be specified simultaneously.
88+
targets := []string{}
89+
if repo.Branch != "" {
90+
targets = append(targets, repo.Branch)
91+
}
92+
if repo.Tag != "" {
93+
targets = append(targets, repo.Tag)
94+
}
95+
if repo.CommitHash != "" {
96+
targets = append(targets, repo.CommitHash)
97+
}
98+
99+
if len(targets) > 1 {
100+
if repo.Branch != "" {
101+
sl.ReportError(repo.Branch, "branch", "Branch", "too many target specifications", "")
102+
}
103+
if repo.Tag != "" {
104+
sl.ReportError(repo.Tag, "tag", "Tag", "too many target specifications", "")
105+
}
106+
if repo.CommitHash != "" {
107+
sl.ReportError(repo.CommitHash, "commitHash", "CommitHash", "too many target specifications", "")
108+
}
109+
}
110+
}
111+
82112
// validateKubernetesCPU implements the "k8s_cpu" tag for *raw* CPU fields.
83113
// Accepts:
84114
// - Strings: "", "unlimited", plain number ("2", "2.5"), or millicores ("500m")

internal/templates/template_files/dev/scripts/templated/startup.sh

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,11 @@ echo "Installing Python packages: {{range $i, $pkg := .Packages.Python}}{{if gt
145145
/bin/bash /scripts/run_with_git.sh ${DEV_USERNAME} ${PYTHON_PATH} -m pip install --no-user --no-cache-dir{{range .Packages.Python}} {{.}}{{end}}
146146
{{- end}}
147147

148+
{{- if gt (len .Packages.Brew) 0}}
149+
echo "Installing Homebrew packages: {{range $i, $pkg := .Packages.Brew}}{{if gt $i 0}} {{end}}{{$pkg}}{{end}}"
150+
sudo -u ${DEV_USERNAME} brew install{{range .Packages.Brew}} {{.}}{{end}}
151+
{{- end}}
152+
148153
echo "Section 6: Package installation complete"
149154

150155
# === USER ENVIRONMENT SETUP ===
@@ -181,6 +186,47 @@ chown -R ${DEV_USERNAME}:${DEV_USERNAME} /home/${DEV_USERNAME}/.vscode-server
181186

182187
echo "Section 8: VSCode configuration complete"
183188

189+
# === GIT REPO CLONING ===
190+
{{- if gt (len .GitRepos) 0}}
191+
echo "Cloning Git repositories"
192+
{{- range .GitRepos}}
193+
echo "Cloning repository: {{.URL}}"
194+
195+
{{- /* Determine target directory */ -}}
196+
{{- $targetDir := "" -}}
197+
{{- if .Directory -}}
198+
{{- $targetDir = .Directory -}}
199+
{{- else -}}
200+
{{- $targetDir = printf "/home/%s" $.Name -}}
201+
{{- end }}
202+
203+
# Clone the complete repository
204+
git clone {{.URL}} {{$targetDir}}
205+
cd {{$targetDir}}
206+
207+
{{- /* Checkout specific reference */ -}}
208+
{{- if .Tag}}
209+
echo "Checking out tag: {{.Tag}}"
210+
git checkout tags/{{.Tag}}
211+
{{- else if .CommitHash}}
212+
echo "Checking out commit: {{.CommitHash}}"
213+
git checkout {{.CommitHash}}
214+
{{- else if .Branch}}
215+
echo "Checking out branch: {{.Branch}}"
216+
git checkout {{.Branch}}
217+
{{- else}}
218+
echo "Staying on default branch"
219+
{{- end}}
220+
221+
echo "Repository cloned successfully to: {{$targetDir}}"
222+
echo "Current commit: $(git rev-parse --short HEAD)"
223+
echo "Current branch/ref: $(git branch --show-current 2>/dev/null || git describe --tags --exact-match 2>/dev/null || echo 'detached HEAD')"
224+
225+
{{- end}}
226+
{{- else}}
227+
echo "No Git repositories to clone"
228+
{{- end}}
229+
184230
# === SSH SERVER LAUNCH ===
185231
echo "Starting SSH server"
186232
/usr/sbin/sshd -D

internal/templates/template_files/system/manifests/namespace.tmpl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@ apiVersion: v1
22
kind: Namespace
33
metadata:
44
name: {{.Namespace}}
5-
environment: {{.EnvironmentName}}
65
annotations:
7-
description: "Namespace for DevENV resources"
6+
description: "Namespace for DevENV resources"
7+
environment: {{.EnvironmentName}}

internal/templates/testdata/golden/startup-scripts.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,9 @@ data:
151151
152152
echo "Section 8: VSCode configuration complete"
153153
154+
# === GIT REPO CLONING ===
155+
echo "No Git repositories to clone"
156+
154157
# === SSH SERVER LAUNCH ===
155158
echo "Starting SSH server"
156159
/usr/sbin/sshd -D

0 commit comments

Comments
 (0)