Skip to content

Chore setup the workspace projects - #7

Merged
DoniLite merged 9 commits into
mainfrom
develop
Aug 1, 2025
Merged

Chore setup the workspace projects#7
DoniLite merged 9 commits into
mainfrom
develop

Conversation

@DoniLite

@DoniLite DoniLite commented Apr 26, 2025

Copy link
Copy Markdown
Member

Summary by Sourcery

Introduce a new build system (bx/build) with ecosystem detection, Dockerfile templating, and support for various sources (Git, local) and outputs (Docker, local tar, B2). Add a WebSocket API (socket/) for remote build triggering and status streaming. Reorganize the project structure into server/, builder/, bx/, services/, frontend/, cli/ directories.

New Features:

  • Add a build service (bx/build) to manage artifact creation.
  • Add ecosystem detection for various languages/frameworks.
  • Include Dockerfile templates for common project types.
  • Add a WebSocket server and client (socket/) for remote build management.
  • Implement B2 cloud storage helpers for artifact upload/download.
  • Add JWT authentication middleware and basic database setup for the server.
  • Add a frontend component management script (cli/components/run.go).

Build:

  • Update golangci-lint configuration to v2 format.
  • Add a lint target to the Makefile.
  • Update Makefile test target to pass Docker socket path.

CI:

  • Update Go version to 1.23 in GitHub Actions workflow.
  • Update Docker service image in CI workflow.

Tests:

  • Add unit and integration tests for the new build service (bx/build).
  • Add integration tests for triggering builds via the WebSocket API.

Chores:

  • Reorganize project structure and update Go module paths.
  • Update Go version to 1.23.
  • Update Go dependencies across modules.
  • Switch frontend to use pnpm and add lockfile.
  • Refactor service initialization and configuration.
  • Remove Go React SSR (gossr) dependency and usage.

DoniLite added 6 commits April 6, 2025 12:54
- setup the workspace
- create a new packages
- structuring the codebase
- create new packages `bx`, `socket` and `cli`
- implementing new features
- fixing some bugs
- refactoring the codebase
@sourcery-ai

sourcery-ai Bot commented Apr 26, 2025

Copy link
Copy Markdown

Reviewer's Guide by Sourcery

This pull request involves significant refactoring of the project structure, introduces a new 'bx' build tool with advanced capabilities and various output targets, implements a WebSocket communication layer for build triggering and monitoring, and adds foundational backend services for database, authentication (JWT), and file handling. It also updates frontend tooling and enhances development workflows.

No diagrams generated as the changes look simple and do not need a visual representation.

File-Level Changes

Change Details Files
Project Structure and Module Updates
  • Renamed top-level directories for better organization.
  • Updated Go module paths in various go.mod files.
  • Corrected import paths across the codebase to reflect the new structure.
go.mod
server/go.mod
services/go.mod
bx/go.mod
cmd/main.go
server/main.go
cmd/build/main.go
builder/main.go
cmd/watch/main.go
builder/watch/main.go
models/props.go
server/models/props.go
controllers/test_controller.go
server/controllers/test_controller.go
build/builder.go
builder/build/builder.go
tsconfig.json
frontend/tsconfig.json
package.json
Implementation of a New Build Service (bx/build)
  • Implemented core build logic supporting multiple source types, resources, and build steps.
  • Added support for different build output targets (docker, local tar, B2).
  • Included functionality to generate a .run.yml file for artifact execution.
  • Implemented automatic language ecosystem detection.
  • Added predefined Dockerfile templates for various languages.
  • Wrote comprehensive unit and integration tests for the build service.
  • Added a new 'bx run' command to execute services defined in .run.yml.
bx/build/builder.go
bx/build/detector.go
bx/build/templates.go
bx/build/build_test.go
bx/build/build_integration_test.go
bx/cmd/run.go
WebSocket Communication Layer
  • Created a WebSocket server to manage client connections and message routing.
  • Defined a structured message format and event types for communication.
  • Implemented a WebSocket client for interaction with the server.
  • Integrated the build service with the socket server to trigger builds and stream updates.
  • Added integration tests for the socket-triggered build flow.
socket/server.go
socket/client.go
socket/hub.go
socket/message.go
bx/build/socket.go
Core Backend Services (DB, Auth, Files, Cloud)
  • Configured PostgreSQL database access using GORM.
  • Implemented JWT token generation and validation middleware.
  • Added controllers for authentication and file management.
  • Updated the main API router to include new routes and auth middleware.
  • Added a new service for cloud storage operations (Backblaze B2).
  • Defined structs for a separate build metadata concept.
  • Added a basic test for the ping route.
server/db/db.go
server/middleware/auth.go
server/controllers/auth_controller.go
server/controllers/file_controller.go
server/api/routes.go
services/cloud_service.go
services/builder_service.go
server/server_test.go
Frontend Tooling and Component Management
  • Migrated frontend package management to pnpm.
  • Added a Go CLI tool to manage frontend components using npx shadcn-ui.
  • Adjusted frontend configuration files for the new structure.
frontend/pnpm-lock.yaml
cli/components/run.go
frontend/tsconfig.json
Development Workflow Enhancements
  • Updated code linting configuration and introduced new formatters.
  • Added a lint target and updated the test target in the Makefile.
  • Modified the GitHub Actions workflow for CI, including Go version and Docker image updates.
.golangci.yml
Makefile
.github/workflows/go.yml
Code Formatting and Cleanup
  • Applied consistent formatting for struct tags (curly braces to backticks).
  • Added newlines for improved code readability.
  • Updated file permissions for saved files.
services/secureAlgo_service.go
utils/helpers.go
services/compression_service.go
services/init_service.go
services/encryption_service.go
builder/build/builder.go

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @DoniLite - I've reviewed your changes and found some issues that need to be addressed.

Blocking issues:

  • Hardcoded database credentials may expose sensitive information. (link)

Overall Comments:

  • The scope of this PR is very large, involving significant restructuring into workspace projects and adding major features like a new build system and WebSocket communication; the title 'Chore setup the workspace projects' may not fully capture the extent of these changes.
  • This PR introduces a new multi-project structure (server, services, bx, frontend, etc.); consider adding a brief overview of the responsibilities of each new top-level directory in the description or related documentation.
Here's what I looked at during the review
  • 🟡 General issues: 2 issues found
  • 🔴 Security: 1 blocking issue
  • 🟡 Testing: 3 issues found
  • 🟡 Complexity: 2 issues found
  • 🟢 Documentation: all looks good

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread services/encryption_service.go Outdated

func SaveEncryptedFile(filename string, data []byte) error {
return os.WriteFile("/path/to/storage/"+filename, data, 0644)
storagePath := "/path"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Use a platform‐independent method to join file paths.

Instead of concatenating storagePath and filename with '+', consider using filepath.Join(storagePath, filename) to ensure correct path formatting on all platforms.

Comment thread cli/components/run.go
Components []Component `json:"components"`
}

const lockFilePath = "../../frontend/components.lock.json"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (bug_risk): Revisit hardcoded file paths.

Using relative paths like '../../frontend/components.lock.json' may lead to issues if the working directory changes. Consider making these paths configurable or deriving them from a centralized base path.

Suggested implementation:

var lockFilePath string
var componentsDir string

func init() {
	basePath := os.Getenv("FRONTEND_PATH")
	if basePath == "" {
		workingDir, err := os.Getwd()
		if err != nil {
			workingDir = "."
		}
		basePath = filepath.Join(workingDir, "frontend")
	}
	lockFilePath = filepath.Join(basePath, "components.lock.json")
	componentsDir = filepath.Join(basePath, "components")
}

Ensure that the FRONTEND_PATH environment variable is documented for users/developers and reviewed within the broader configuration strategy in the codebase.

Comment thread server/db/db.go Outdated

// Contient la base de données du projet 'cloudbeast' gérée par `gorm ORM`
func Setup() (*gorm.DB, error) {
dsn := "host=localhost user=doni password=DoniLite13 dbname=anexis port=5432 sslmode=disable"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚨 suggestion (security): Hardcoded database credentials may expose sensitive information.

It is advisable to extract credentials from environment variables or a secure configuration to reduce the chances of accidental exposure.

Suggested implementation:

import (
    "fmt"
    "os"
    "gorm.io/driver/postgres"
    "gorm.io/gorm"
)
	host := os.Getenv("DB_HOST")
	user := os.Getenv("DB_USER")
	password := os.Getenv("DB_PASSWORD")
	dbname := os.Getenv("DB_NAME")
	port := os.Getenv("DB_PORT")

	dsn := fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%s sslmode=disable", host, user, password, dbname, port)

Make sure that the respective environment variables (DB_HOST, DB_USER, DB_PASSWORD, DB_NAME, and DB_PORT) are set in your deployment or development environment.

Comment thread services/services_test.go Outdated
OUTPUTDIR = "../tests/output"
)

func TestCompressionService(t *testing.T) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (testing): Test lacks assertions to verify behavior.

This test compresses data and writes it to a file, but it doesn't assert that the compression actually worked or that the output has expected properties (e.g., smaller size, specific format). Consider adding assertions, perhaps by decompressing the result within the test and comparing it to the original.

Comment thread services/services_test.go Outdated
}


func TestDecompressionService(t *testing.T) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (testing): Test lacks assertions and depends on external state.

This test reads a file presumably created by TestCompressionService, decompresses it, and writes the output. It lacks assertions to verify if the decompressed data matches the original input. Furthermore, tests should be independent; this test relies on TestCompressionService running successfully first and creating the 'output' file. Consider making tests self-contained, possibly using t.Run for subtests with shared setup or using in-memory data.

Comment thread utils/helpers_test.go Outdated

const USER = "doni"

func TestGenerator(t *testing.T) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (testing): Test lacks assertions to verify key generation.

This test calls GenerateRSAKeys but doesn't assert anything about the result. It should verify that a non-nil private key is returned and potentially check that the corresponding public/private key files were created in the expected location (though file system interactions might be better mocked or handled with cleanup).

Comment thread bx/build/socket.go


// runBuildLogic contient la logique de build principale, adaptée pour les notifications.
// ATTENTION: Cette fonction est maintenant longue et complexe. Envisager de la découper.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (complexity): Consider decomposing the runBuildLogic function into smaller, focused helper functions for environment setup, secret loading, and build process steps.

The main build logic function is now handling too many responsibilities. Consider decomposing it into focused helper functions, for example:

  1. Setup Environment
    Extract environment preparation into its own function:
    func (s *BuildService) setupBuildDirectory(buildID string) (string, error) {
        buildDir := filepath.Join(s.workDir, buildID)
        if err := os.MkdirAll(buildDir, 0755); err != nil {
            return "", fmt.Errorf("cannot create build directory '%s': %w", buildDir, err)
        }
        return buildDir, nil
    }
  2. Load Environment & Secrets
    Separate these responsibilities:
    func (s *BuildService) loadEnvironment(spec *BuildSpec) map[string]string {
        env := make(map[string]string)
        for k, v := range spec.Env {
            env[k] = v
        }
        // Optionally merge additional environment setup here...
        return env
    }
    
    func (s *BuildService) fetchSecrets(ctx context.Context, spec *BuildSpec, notifier socket.BuildNotifier, buildLogger *log.Logger) (map[string]string, error) {
        secrets := make(map[string]string)
        if s.secretFetcher != nil && len(spec.Secrets) > 0 {
            buildLogger.Println("Fetching secrets...")
            for _, secretSpec := range spec.Secrets {
                secretValue, err := s.GetSecret(ctx, secretSpec.Source)
                if err != nil {
                    return nil, fmt.Errorf("failed to fetch secret '%s': %w", secretSpec.Name, err)
                }
                secrets[secretSpec.Name] = secretValue
                buildLogger.Printf("Secret '%s' fetched successfully.\n", secretSpec.Name)
            }
        }
        return secrets, nil
    }
  3. Build Process Steps
    Similarly, extract download, codebase preparation, build execution, and output handling into their own helper functions.

By splitting these concerns into individually testable functions, you not only reduce the cognitive complexity but also improve overall maintainability without risking a change in functionality.

Comment thread bx/build/builder.go
// --- Core Build Logic ---

// Running the build based on the provided spec
func (s *BuildService) Build(ctx context.Context, spec *BuildSpec) (*BuildResult, error) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (complexity): Consider splitting the Build function into smaller, well-defined modules for environment setup, codebase fetching, resource handling, Dockerfile builds, Compose builds, and helper utilities to improve maintainability.

The changes introduce a very long “Build” function and mix many responsibilities. To improve maintainability while keeping functionality, consider splitting the code into clearly defined modules. For example:

  1. Extract Environment Setup
    Move setup of working directory, env file loading, and secret fetching into its own module/file (e.g., environment.go):

    // environment.go
    package build
    
    func SetupEnvironment(ctx context.Context, spec *BuildSpec, workDir string, inMemory bool, secretFetcher SecretFetcher) (buildDir string, finalEnv map[string]string, logs strings.Builder, err error) {
        var overallLogs strings.Builder
        // Step 1: Create working directory (temp if inMemory...)
        // Step 2: Load env files
        // Step 3: Fetch secrets
        // Return buildDir, merged environment and the logs collected.
        return buildDir, finalEnv, overallLogs, nil
    }
  2. Separate Codebase Fetching and Resource Handling
    Create files like codebases.go and resources.go to encapsulate fetching from Git/local/archive/buffer and downloading/extracting resources. For instance:

    // codebases.go
    package build
    
    func FetchCodebases(ctx context.Context, spec *BuildSpec, buildDir string) (map[string]CodebaseConfig, error) {
        // Loop through spec.Codebases and fetch each into buildDir
        // Return a map keyed on codebase name.
        return nil, nil
    }
    // resources.go
    package build
    
    func DownloadAndExtractResources(ctx context.Context, spec *BuildSpec, buildDir string, logs *strings.Builder) error {
        // Loop through spec.Resources and download/extract as needed.
        return nil
    }
  3. Split Docker and Compose Build Logic
    Instead of one Build() method handling both Dockerfile and Compose logic, create separate functions:

    // docker_build.go
    package build
    
    func BuildWithDockerfile(ctx context.Context, spec *BuildSpec, buildDir string, logs *strings.Builder) (string, error) {
        // Build image using Dockerfile
        return "", nil
    }
    // compose_build.go
    package build
    
    func BuildWithCompose(ctx context.Context, spec *BuildSpec, buildDir string, logs *strings.Builder) error {
        // Build using Docker Compose project
        return nil
    }
  4. Extract Helper Utilities
    Functions like archive extraction, container creation and image save can be moved to a dedicated utils.go file.

By splitting these responsibilities, you make each module easier to follow, test, and maintain while preserving existing functionality.

@DoniLite
DoniLite merged commit a4f05ab into main Aug 1, 2025
2 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant