Skip to content

Commit 40179b0

Browse files
Merge pull request #19 from nauticalab/eywalker/plt-149-manually-verify-the-parity-between-new-devenv-engine-and-the
Fix GPU resource formatting and enhance manifest generation
2 parents fbb0e00 + 98017e1 commit 40179b0

File tree

21 files changed

+209
-159
lines changed

21 files changed

+209
-159
lines changed

.github/workflows/release.yml

Lines changed: 78 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1,85 +1,85 @@
11
name: Release
22

33
on:
4-
push:
5-
tags:
6-
- "v*" # Trigger on version tags like v0.1.0, v1.2.3
4+
push:
5+
tags:
6+
- "v*" # Trigger on version tags like v0.1.0, v1.2.3
77

88
permissions:
9-
contents: write # Required for creating releases
9+
contents: write # Required for creating releases
1010

1111
jobs:
12-
test:
13-
name: Run Tests
14-
runs-on: ubuntu-latest
15-
steps:
16-
- name: Checkout code
17-
uses: actions/checkout@v5
18-
19-
- name: Set up Go
20-
uses: actions/setup-go@v5
21-
with:
22-
go-version: "1.24"
23-
24-
- name: Run tests
25-
run: go test -v ./...
26-
27-
release:
28-
name: Build and Release
29-
needs: test # Only run if tests pass
30-
runs-on: ubuntu-latest
31-
steps:
32-
- name: Checkout code
33-
uses: actions/checkout@v5
34-
35-
- name: Set up Go
36-
uses: actions/setup-go@v5
37-
with:
38-
go-version: "1.24"
39-
40-
- name: Build binaries for all platforms
41-
run: |
42-
# Get version from tag (GitHub sets GITHUB_REF to refs/tags/v0.1.0)
43-
VERSION=${GITHUB_REF#refs/tags/}
44-
COMMIT=$(git rev-parse --short HEAD)
45-
BUILD_TIME=$(date -u +'%Y-%m-%dT%H:%M:%SZ')
46-
GO_VERSION=$(go version | awk '{print $3}')
47-
48-
echo "Building version: ${VERSION}"
49-
50-
# Build flags
51-
LDFLAGS="-X main.version=${VERSION} -X main.gitCommit=${COMMIT} -X main.buildTime=${BUILD_TIME} -X main.goVersion=${GO_VERSION} -w -s"
52-
53-
# Create output directory
54-
mkdir -p dist
55-
56-
# Linux amd64
57-
echo "Building Linux amd64..."
58-
GOOS=linux GOARCH=amd64 go build -ldflags="${LDFLAGS}" -o dist/devenv-linux-amd64 ./cmd/devenv
59-
60-
# macOS amd64 (Intel)
61-
echo "Building macOS amd64..."
62-
GOOS=darwin GOARCH=amd64 go build -ldflags="${LDFLAGS}" -o dist/devenv-darwin-amd64 ./cmd/devenv
63-
64-
# macOS arm64 (Apple Silicon)
65-
echo "Building macOS arm64..."
66-
GOOS=darwin GOARCH=arm64 go build -ldflags="${LDFLAGS}" -o dist/devenv-darwin-arm64 ./cmd/devenv
67-
68-
# Windows amd64
69-
echo "Building Windows amd64..."
70-
GOOS=windows GOARCH=amd64 go build -ldflags="${LDFLAGS}" -o dist/devenv-windows-amd64.exe ./cmd/devenv
71-
72-
echo "✅ All binaries built successfully"
73-
ls -lh dist/
74-
75-
- name: Create Release
76-
uses: softprops/action-gh-release@v2
77-
with:
78-
files: |
79-
dist/devenv-linux-amd64
80-
dist/devenv-darwin-amd64
81-
dist/devenv-darwin-arm64
82-
dist/devenv-windows-amd64.exe
83-
generate_release_notes: true
84-
draft: false
85-
prerelease: false
12+
test:
13+
name: Run Tests
14+
runs-on: ubuntu-latest
15+
steps:
16+
- name: Checkout code
17+
uses: actions/checkout@v5
18+
19+
- name: Set up Go
20+
uses: actions/setup-go@v5
21+
with:
22+
go-version: "1.24"
23+
24+
- name: Run tests
25+
run: go test -v ./...
26+
27+
release:
28+
name: Build and Release
29+
needs: test # Only run if tests pass
30+
runs-on: ubuntu-latest
31+
steps:
32+
- name: Checkout code
33+
uses: actions/checkout@v5
34+
35+
- name: Set up Go
36+
uses: actions/setup-go@v5
37+
with:
38+
go-version: "1.24"
39+
40+
- name: Build binaries for all platforms
41+
run: |
42+
# Get version from tag (GitHub sets GITHUB_REF to refs/tags/v0.1.0)
43+
VERSION=${GITHUB_REF#refs/tags/}
44+
COMMIT=$(git rev-parse --short HEAD)
45+
BUILD_TIME=$(date -u +'%Y-%m-%dT%H:%M:%SZ')
46+
GO_VERSION=$(go version | awk '{print $3}')
47+
48+
echo "Building version: ${VERSION}"
49+
50+
# Build flags
51+
LDFLAGS="-X main.version=${VERSION} -X main.gitCommit=${COMMIT} -X main.buildTime=${BUILD_TIME} -X main.goVersion=${GO_VERSION} -w -s"
52+
53+
# Create output directory
54+
mkdir -p dist
55+
56+
# Linux amd64
57+
echo "Building Linux amd64..."
58+
GOOS=linux GOARCH=amd64 go build -ldflags="${LDFLAGS}" -o dist/devenv-linux-amd64 ./cmd/devenv
59+
60+
# macOS amd64 (Intel)
61+
echo "Building macOS amd64..."
62+
GOOS=darwin GOARCH=amd64 go build -ldflags="${LDFLAGS}" -o dist/devenv-darwin-amd64 ./cmd/devenv
63+
64+
# macOS arm64 (Apple Silicon)
65+
echo "Building macOS arm64..."
66+
GOOS=darwin GOARCH=arm64 go build -ldflags="${LDFLAGS}" -o dist/devenv-darwin-arm64 ./cmd/devenv
67+
68+
# Windows amd64
69+
echo "Building Windows amd64..."
70+
GOOS=windows GOARCH=amd64 go build -ldflags="${LDFLAGS}" -o dist/devenv-windows-amd64.exe ./cmd/devenv
71+
72+
echo "✅ All binaries built successfully"
73+
ls -lh dist/
74+
75+
- name: Create Release
76+
uses: softprops/action-gh-release@v2
77+
with:
78+
files: |
79+
dist/devenv-linux-amd64
80+
dist/devenv-darwin-amd64
81+
dist/devenv-darwin-arm64
82+
dist/devenv-windows-amd64.exe
83+
generate_release_notes: true
84+
draft: false
85+
prerelease: false

Taskfile.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ tasks:
116116
test:
117117
desc: Run tests
118118
cmds:
119-
- go test -v ./... {{.CLI_ARGS}}
119+
- go test ./... {{.CLI_ARGS}}
120120

121121
clean:
122122
desc: Clean build artifacts
@@ -129,7 +129,7 @@ tasks:
129129
update-golden:
130130
desc: Update golden files for tests
131131
cmds:
132-
- go test ./... -update-golden {{.CLI_ARGS}}
132+
- go test ./... -- -update-golden {{.CLI_ARGS}}
133133

134134
doc:
135135
desc: Launch pkgsite documentation server

cmd/devenv/generate.go

Lines changed: 62 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -78,37 +78,56 @@ func init() {
7878
}
7979

8080
func generateAllDevelopersWithProgress() {
81-
// Step 1: Discover all developers
81+
// Step 1: Load global config once
82+
globalConfig, err := config.LoadGlobalConfig(configDir)
83+
if err != nil {
84+
fmt.Fprintf(os.Stderr, "Error loading global config in %s: %v\n", configDir, err)
85+
os.Exit(1)
86+
}
87+
88+
if verbose {
89+
fmt.Printf("Generating system manifests in %s\n", outputDir)
90+
}
91+
92+
// Step 2: Generate system manifests once
93+
if !dryRun {
94+
if err := generateSystemManifests(globalConfig, outputDir); err != nil {
95+
fmt.Fprintf(os.Stderr, "Error generating system manifests: %v\n", err)
96+
os.Exit(1)
97+
}
98+
}
99+
100+
// Step 3: Discover all developers
82101
developers, err := findAllDevelopers(configDir)
83102
if err != nil {
84103
fmt.Fprintf(os.Stderr, "Error discovering developers: %v\n", err)
85104
os.Exit(1)
86105
}
87106

88107
if len(developers) == 0 {
89-
fmt.Printf("No deveolopers found in %s\n", configDir)
108+
fmt.Printf("No developers found in %s\n", configDir)
90109
return
91110
}
92111

93112
fmt.Printf("Found %d developers to process.\n", len(developers))
94113

95-
// Step 2: Set up channels for worker communication
114+
// Step 4: Set up channels for worker communication
96115
const numWorkers = 4
97116
jobs := make(chan DeveloperJob, len(developers))
98117
results := make(chan ProcessingResult, len(developers))
99118

100-
// Step 3: Start worker goroutines
119+
// Step 5: Start worker goroutines
101120
for i := 0; i < numWorkers; i++ {
102-
go developerWorker(jobs, results)
121+
go developerWorker(jobs, results, globalConfig)
103122
}
104123

105-
// Step 4: Send all jobs to workers
124+
// Step 6: Send all jobs to workers
106125
for _, dev := range developers {
107126
jobs <- DeveloperJob{Name: dev}
108127
}
109128
close(jobs)
110129

111-
// Step 5: Collect results
130+
// Step 7: Collect results
112131
var successCount, failureCount int
113132
var failures []ProcessingResult
114133

@@ -126,7 +145,7 @@ func generateAllDevelopersWithProgress() {
126145
}
127146
}
128147

129-
// Step 6: Print final summary
148+
// Step 8: Print final summary
130149
fmt.Printf("\n🎉 Batch processing complete!\n")
131150
fmt.Printf("✅ Successful: %d\n", successCount)
132151
if failureCount > 0 {
@@ -142,10 +161,10 @@ func generateAllDevelopersWithProgress() {
142161
}
143162
}
144163

145-
func developerWorker(jobs <-chan DeveloperJob, results chan<- ProcessingResult) {
164+
func developerWorker(jobs <-chan DeveloperJob, results chan<- ProcessingResult, globalConfig *config.BaseConfig) {
146165
for job := range jobs {
147166
startTime := time.Now()
148-
err := processSingleDeveloperForBatchWithError(job.Name)
167+
err := processSingleDeveloperForBatchWithError(job.Name, globalConfig)
149168

150169
results <- ProcessingResult{
151170
Developer: job.Name,
@@ -157,12 +176,12 @@ func developerWorker(jobs <-chan DeveloperJob, results chan<- ProcessingResult)
157176
}
158177

159178
// processSingleDeveloperForBatchWithError processes a single developer for batch mode
160-
func processSingleDeveloperForBatchWithError(developerName string) error {
179+
func processSingleDeveloperForBatchWithError(developerName string, globalConfig *config.BaseConfig) error {
161180
if verbose {
162181
fmt.Printf("Processing developer: %s\n", developerName)
163182
}
164183

165-
cfg, err := config.LoadDeveloperConfigWithGlobalDefaults(configDir, developerName)
184+
cfg, err := config.LoadDeveloperConfigWithBaseConfig(configDir, developerName, globalConfig)
166185
if err != nil {
167186
return fmt.Errorf("failed to load config: %w", err)
168187
}
@@ -171,7 +190,7 @@ func processSingleDeveloperForBatchWithError(developerName string) error {
171190
userOutputDir := filepath.Join(outputDir, developerName)
172191

173192
if !dryRun {
174-
if err := generateManifests(cfg, userOutputDir); err != nil {
193+
if err := generateDeveloperManifests(cfg, userOutputDir); err != nil {
175194
return fmt.Errorf("failed to generate manifests: %w", err)
176195
}
177196
}
@@ -212,7 +231,18 @@ func generateSingleDeveloper(developerName string) {
212231

213232
userOutputDir := filepath.Join(outputDir, developerName)
214233

215-
cfg, err := config.LoadDeveloperConfigWithGlobalDefaults(configDir, developerName)
234+
globalConfig, err := config.LoadGlobalConfig(configDir)
235+
if err != nil {
236+
fmt.Fprintf(os.Stderr, "Error loading global config in %s: %v\n", configDir, err)
237+
os.Exit(1)
238+
}
239+
240+
if err := generateSystemManifests(globalConfig, outputDir); err != nil {
241+
fmt.Fprintf(os.Stderr, "Error generating system manifests: %v\n", err)
242+
os.Exit(1)
243+
}
244+
245+
cfg, err := config.LoadDeveloperConfigWithBaseConfig(configDir, developerName, globalConfig)
216246
if err != nil {
217247
fmt.Fprintf(os.Stderr, "Error loading config for developer %s: %v\n", developerName, err)
218248
os.Exit(1)
@@ -225,7 +255,7 @@ func generateSingleDeveloper(developerName string) {
225255
}
226256

227257
if !dryRun {
228-
if err := generateManifests(cfg, userOutputDir); err != nil {
258+
if err := generateDeveloperManifests(cfg, userOutputDir); err != nil {
229259
fmt.Fprintf(os.Stderr, "Error generating manifests: %v\n", err)
230260
os.Exit(1)
231261
}
@@ -234,10 +264,24 @@ func generateSingleDeveloper(developerName string) {
234264
}
235265
}
236266

237-
// generateManifests creates Kubernetes manifests for a developer
238-
func generateManifests(cfg *config.DevEnvConfig, outputDir string) error {
267+
func generateSystemManifests(cfg *config.BaseConfig, outputDir string) error {
268+
// Create template renderer
269+
renderer := templates.NewSystemRenderer(outputDir)
270+
271+
// Render all main templates
272+
if err := renderer.RenderAll(cfg); err != nil {
273+
return fmt.Errorf("failed to render templates: %w", err)
274+
}
275+
276+
fmt.Printf("🎉 Successfully generated system manifests\n")
277+
278+
return nil
279+
}
280+
281+
// generateDeveloperManifests creates Kubernetes manifests for a developer
282+
func generateDeveloperManifests(cfg *config.DevEnvConfig, outputDir string) error {
239283
// Create template renderer
240-
renderer := templates.NewRenderer(outputDir)
284+
renderer := templates.NewDevRenderer(outputDir)
241285

242286
// Render all main templates
243287
if err := renderer.RenderAll(cfg); err != nil {

internal/config/parser.go

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -79,16 +79,11 @@ func LoadDeveloperConfig(configDir, developerName string) (*DevEnvConfig, error)
7979
// LoadDeveloperConfigWithGlobalDefaults loads a developer config and merges it with global defaults.
8080
// This is the recommended loading function that provides the complete configuration hierarchy:
8181
// System defaults → Global config → User config
82-
func LoadDeveloperConfigWithGlobalDefaults(configDir, developerName string) (*DevEnvConfig, error) {
83-
// Step 1: Load global configuration (pre-populated with system defaults)
84-
globalConfig, err := LoadGlobalConfig(configDir)
85-
if err != nil {
86-
return nil, fmt.Errorf("failed to load global config: %w", err)
87-
}
82+
func LoadDeveloperConfigWithBaseConfig(configDir, developerName string, baseConfig *BaseConfig) (*DevEnvConfig, error) {
8883

8984
// Step 2: Create user config pre-populated with global config values
9085
userConfig := &DevEnvConfig{
91-
BaseConfig: *globalConfig, // Copy all global values (which include system defaults)
86+
BaseConfig: *baseConfig, // Copy all global values (which include system defaults)
9287
}
9388

9489
// Step 3: Load user YAML
@@ -113,7 +108,7 @@ func LoadDeveloperConfigWithGlobalDefaults(configDir, developerName string) (*De
113108

114109
// Step 5: Merge additive list fields (packages, volumes, SSH keys)
115110
// Note that this step is neceessary because YAML unmarshaling replaces slices
116-
userConfig.mergeListFields(globalConfig)
111+
userConfig.mergeListFields(baseConfig)
117112

118113
// Step 6: Set developer directory and validate
119114
userConfig.DeveloperDir = developerDir

0 commit comments

Comments
 (0)