refactor: move all remaining files to orig/ directory
Completed clean root directory structure: - Root now contains only: .git, .env, docs/, orig/ - Moved all remaining files and directories to orig/: - Config files (.claude, .dockerignore, .drone.yml, etc.) - All .env variants (except active .env) - Git config (.gitconfig, .github, .gitignore, etc.) - Tool configs (.golangci.yml, .revive.toml, etc.) - Documentation (*.md files, @prompts) - Build files (Dockerfiles, Makefile, go.mod, go.sum) - Docker compose files - All source directories (scripts, tests, tools, etc.) - Runtime directories (logs, monitoring, reports) - Dependency files (node_modules, lib, cache) - Special files (--delete) - Removed empty runtime directories (bin/, data/) V2 structure is now clean: - docs/planning/ - V2 planning documents - orig/ - Complete V1 codebase preserved - .env - Active environment config (not in git) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
175
orig/tools/bridge/ci_agent_bridge.go
Normal file
175
orig/tools/bridge/ci_agent_bridge.go
Normal file
@@ -0,0 +1,175 @@
|
||||
package bridge
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"archive/zip"
|
||||
)
|
||||
|
||||
// SummarizeResult holds artifact summary data
|
||||
type SummarizeResult struct {
|
||||
Files []string `json:"files"`
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
}
|
||||
|
||||
// SummarizeConfig configures summarization behavior
|
||||
type SummarizeConfig struct {
|
||||
ArtifactsDir string
|
||||
OutputFile string
|
||||
}
|
||||
|
||||
// ApplyPatch applies a patch file to a new branch
|
||||
func ApplyPatch(op PatchOperation) error {
|
||||
if op.PatchFile == "" || op.BranchName == "" {
|
||||
return fmt.Errorf("both --patch and --branch are required")
|
||||
}
|
||||
|
||||
// create new branch
|
||||
cmd := exec.Command("git", "checkout", "-b", op.BranchName)
|
||||
if out, err := cmd.CombinedOutput(); err != nil {
|
||||
return fmt.Errorf("git checkout failed: %s: %w", string(out), err)
|
||||
}
|
||||
|
||||
// apply patch
|
||||
cmd = exec.Command("git", "apply", op.PatchFile)
|
||||
if out, err := cmd.CombinedOutput(); err != nil {
|
||||
return fmt.Errorf("git apply failed: %s: %w", string(out), err)
|
||||
}
|
||||
|
||||
log.Printf("[CI-Agent-Bridge] Patch applied to branch: %s", op.BranchName)
|
||||
return nil
|
||||
}
|
||||
|
||||
// RevertBranch deletes a branch (hard reset)
|
||||
func RevertBranch(branch string) error {
|
||||
if branch == "" {
|
||||
return fmt.Errorf("--branch is required")
|
||||
}
|
||||
|
||||
// switch to main first
|
||||
cmd := exec.Command("git", "checkout", "main")
|
||||
if out, err := cmd.CombinedOutput(); err != nil {
|
||||
return fmt.Errorf("git checkout main failed: %s: %w", string(out), err)
|
||||
}
|
||||
|
||||
// delete branch
|
||||
cmd = exec.Command("git", "branch", "-D", branch)
|
||||
if out, err := cmd.CombinedOutput(); err != nil {
|
||||
return fmt.Errorf("git branch delete failed: %s: %w", string(out), err)
|
||||
}
|
||||
|
||||
log.Printf("[CI-Agent-Bridge] Branch reverted: %s", branch)
|
||||
return nil
|
||||
}
|
||||
|
||||
// RunPodmanCompose executes podman-compose up
|
||||
func RunPodmanCompose() error {
|
||||
log.Println("[CI-Agent-Bridge] Starting podman-compose...")
|
||||
cmd := exec.Command("podman-compose", "up", "-d")
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
// ZipDir compresses a directory into a ZIP archive
|
||||
func ZipDir(srcDir, destZip string) error {
|
||||
zipFile, err := os.Create(destZip)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer zipFile.Close()
|
||||
|
||||
archive := zip.NewWriter(zipFile)
|
||||
defer archive.Close()
|
||||
|
||||
return filepath.Walk(srcDir, func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// skip directories
|
||||
if info.IsDir() {
|
||||
return nil
|
||||
}
|
||||
|
||||
// create file in archive
|
||||
relPath, _ := filepath.Rel(srcDir, path)
|
||||
zipEntry, err := archive.Create(relPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// copy file data
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
_, err = io.Copy(zipEntry, file)
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
// SummarizeArtifacts creates a JSON summary and ZIP of artifacts
|
||||
func SummarizeArtifacts(cfg SummarizeConfig) error {
|
||||
var files []string
|
||||
err := filepath.Walk(cfg.ArtifactsDir, func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !info.IsDir() {
|
||||
relPath, _ := filepath.Rel(cfg.ArtifactsDir, path)
|
||||
files = append(files, relPath)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to walk artifacts dir: %w", err)
|
||||
}
|
||||
|
||||
result := SummarizeResult{
|
||||
Files: files,
|
||||
Timestamp: time.Now(),
|
||||
}
|
||||
|
||||
// write JSON summary
|
||||
data, _ := json.MarshalIndent(result, "", " ")
|
||||
if err := os.WriteFile(cfg.OutputFile, data, 0644); err != nil {
|
||||
return fmt.Errorf("failed to write summary: %w", err)
|
||||
}
|
||||
|
||||
// create ZIP of artifacts
|
||||
zipPath := strings.TrimSuffix(cfg.OutputFile, filepath.Ext(cfg.OutputFile)) + ".zip"
|
||||
if err := ZipDir(cfg.ArtifactsDir, zipPath); err != nil {
|
||||
return fmt.Errorf("failed to create zip: %w", err)
|
||||
}
|
||||
|
||||
log.Printf("[CI-Agent-Bridge] Artifacts summarized to %s (%d files)", cfg.OutputFile, len(files))
|
||||
return nil
|
||||
}
|
||||
|
||||
// PatchOperation holds patch application parameters
|
||||
type PatchOperation struct {
|
||||
PatchFile string
|
||||
BranchName string
|
||||
}
|
||||
|
||||
// generateSecureBranchName creates a cryptographically secure random branch name
|
||||
func generateSecureBranchName() (string, error) {
|
||||
bytes := make([]byte, 16)
|
||||
if _, err := rand.Read(bytes); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return "ai/" + hex.EncodeToString(bytes), nil
|
||||
}
|
||||
Reference in New Issue
Block a user