Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/release-testing.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ on:
branches:
- main
- ah-byoc-pre-hook-script
- prashant-warp-849

env:
AWS_ACCESS_KEY_ID: ${{ secrets.WB_PACKAGES_DEV_R2_ACCESS_KEY_ID }}
Expand Down
189 changes: 9 additions & 180 deletions pkg/manager/manager_windows_github_cri.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
//go:build !windows

package manager

import (
"context"
"fmt"
"os"
"os/exec"
"path/filepath"
"sync"

"github.com/warpbuilds/warpbuild-agent/pkg/log"
"errors"
)

// The github_windows_cri provider is Windows-only. This file exists so the
// package compiles on linux/darwin (for tests, cross-builds, IDE tooling).
// The real implementation lives in manager_windows_github_cri_windows.go.
// In production this provider is only ever selected on Windows runners.

type GithubWindowsCRIOptions struct {
PassAllEnvs bool `json:"pass_all_envs"`
StdoutFile string `json:"stdout_file"`
Expand All @@ -32,177 +33,5 @@ func newGithubWindowsCRIManager(opts *ManagerOptions) IManager {
}

func (m *ghWindowsCriManager) StartRunner(ctx context.Context, opts *StartRunnerOptions) (*StartRunnerOutput, error) {
err := m.init(ctx)
if err != nil {
return nil, err
}

// log all the envs
log.Logger().Infof("Environment variables available to the warpbuild agent:")
for _, env := range os.Environ() {
log.Logger().Infof("env: %s", env)
}

cmd := exec.CommandContext(ctx, m.CMDOptions.CMD, m.CMDOptions.Args...)
cmd.Env = append(cmd.Env, "WARPBUILD_GH_JIT_TOKEN="+opts.JitToken)
for _, env := range m.CMDOptions.Envs {
log.Logger().Infof("setting env %s=%s", env.Key, env.Value)
cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", env.Key, env.Value))
}

if m.PassAllEnvs {
log.Logger().Infof("Adding all available envs to command...")
for _, env := range os.Environ() {
log.Logger().Infof("env: %s", env)
cmd.Env = append(cmd.Env, env)
}
}

cmd.Dir = m.CMDOptions.Dir

log.Logger().Infof("starting runner with command: %s", cmd.String())
log.Logger().Infof("JIT Token: %s", opts.JitToken)

stdoutPipe, err := cmd.StdoutPipe()
if err != nil {
log.Logger().Errorf("error creating stdout pipe: %v", err)
return nil, err
}

stderrPipe, err := cmd.StderrPipe()
if err != nil {
log.Logger().Errorf("error creating stderr pipe: %v", err)
return nil, err
}

for _, hook := range GetHooks[IPreStartHook]() {
err := hook.PreStartHook(ctx, &PreStartHookOptions{
StartRunnerOptions: opts,
ManagerOptions: &ManagerOptions{
Provider: ProviderGithubWindowsCRI,
GithubWindowsCRI: m.GithubWindowsCRIOptions,
},
})
if err != nil {
log.Logger().Errorf("error running pre-start hook %s: %v", hook.HookID(), err)
return nil, err
}
}

if err := cmd.Start(); err != nil {
log.Logger().Errorf("error starting command: %v", err)
return nil, err
}

stdoutChan := make(chan string)
stderrChan := make(chan string)
doneChan := make(chan bool)

go captureOutput(stdoutPipe, stdoutChan)
go captureOutput(stderrPipe, stderrChan)

// Open files to write stdout and stderr
stdoutFile, err := openFile(m.StdoutFile)
if err != nil {
log.Logger().Errorf("error opening stdout file: %v", err)
return nil, err
}
defer stdoutFile.Close()

stderrFile, err := openFile(m.StderrFile)
if err != nil {
log.Logger().Errorf("error opening stderr file: %v", err)
return nil, err
}
defer stderrFile.Close()

var wg sync.WaitGroup
wg.Add(1)

go func() {
defer wg.Done()
cmd.Wait()
doneChan <- true
}()

for {
select {
case out := <-stdoutChan:
log.Logger().Infof(out)
fmt.Fprintln(stdoutFile, out)
case err := <-stderrChan:
log.Logger().Errorf(err)
fmt.Fprintln(stderrFile, err)
case <-doneChan:

wg.Wait()

// Exit the loop when command completes
// Run all the post-end hooks
for _, hook := range GetHooks[IPostEndHook]() {
err := hook.PostEndHook(ctx, &PostEndHookOptions{
StartRunnerOptions: opts,
ManagerOptions: &ManagerOptions{
Provider: ProviderGithubWindowsCRI,
GithubWindowsCRI: m.GithubWindowsCRIOptions,
},
})
if err != nil {
log.Logger().Errorf("error running post-end hook %s: %v", hook.HookID(), err)
}
}

return &StartRunnerOutput{
RunCompletedSuccessfully: true,
}, nil
}
}

}

func (m *ghWindowsCriManager) init(ctx context.Context) error {

err := m.createFiles(ctx)
if err != nil {
log.Logger().Errorf("error creating files: %v", err)
return err
}

return nil

}

func (m *ghWindowsCriManager) createFiles(ctx context.Context) error {

fullPaths := []string{
m.StderrFile,
m.StdoutFile,
}

// Iterate over the full paths
for _, fullPath := range fullPaths {
// Get the base directory from the full path
baseDir := filepath.Dir(fullPath)

// Ensure the base directory exists
if _, err := os.Stat(baseDir); os.IsNotExist(err) {
err := os.MkdirAll(baseDir, 0755)
if err != nil {
log.Logger().Errorf("Failed to create base directory %s: %v", baseDir, err)
return err
}
}

// Create the file if it doesn't exist
if _, err := os.Stat(fullPath); os.IsNotExist(err) {
f, err := os.Create(fullPath)
if err != nil {
log.Logger().Errorf("Failed to create file %s: %v", fullPath, err)
return err
}
f.Close()
}
}

return nil
return nil, errors.New("github_windows_cri provider is not implemented on this OS (Windows only)")
}
Loading
Loading