MareWood is a lightweight front-end deployment tool developed using GOLANG, GIN, GORM, SQLITE, JWT, REACE, and MATERIAL-UI. Unlike Jenkins, MareWood is simple and front-end only, allowing you to flexibly configure a variety of deployment environments. Publishing online can be as simple as clicking a button if you want, or you can configure WEBHOOK to submit GIT code and publish automatically.

Open source: github.com/xusenlin/Ma…

It all started with a bat… (omitted 20,000 words). Then, everyone opens the telecommuting, the back-end network didn’t penetrate in the home, every time fixing bugs will be packaged to the backend or moved to run a Linux command to deploy different environment, may after the meeting, the front end, testing, a friend will call you pack, one day, I do work is packaged, ha, ha, ha.

Of course, we also have Jenkins, but it is not friendly to the front end, because plug-ins are required and the use is not intuitive. After deployment, there is no website to visit, and the back end needs to help build new projects every time. Therefore, I decided to develop a deployment tool for the front end that was beautiful enough, easy enough to install, and easy enough to use.

For simplicity and cleanliness, the tech stack uses GOLANG, GIN, GORM, SQLITE, JWT, REACE, And MATERIAL-UI. With the tools, every time we submit code, the backend and test can be packaged to view debugging projects of their own choice. It doesn’t matter whether we build wheels or not. In this process, we have experienced the sense of achievement and learned a lot of knowledge by making a product with our heart. Sometimes we go to bed, but when inspiration comes, we can’t help getting up and typing codes to verify and record. 😂

Design ideas

I designed three tables, respectively

warehouse


type Repository struct {

    gorm.Model

    Name         string `binding:"required,min=2,max=20"`

    Desc         string `gorm:"type:varchar(1000)"`

    Url          string `binding:"url"`      // Warehouse address

    UserName     string                      // This is required if the warehouse is private

    Password     string                      // This is required if the warehouse is private

    Status       int                         // Whether the repository has already cloned the code

    JobStatus    int                         // A task is being packaged and other tasks cannot be executed

    DependTools  string `binding:"required"` // Rely on tool selection

    TerminalInfo string `gorm:"type:varchar(1000)"`

}

Copy the code

classification


type Category struct {

    gorm.Model

    Name        string `binding:"required,min=2,max=20"`

    JobQuantity int    `gorm:"default:0"`

    Desc        string `gorm:"type:varchar(1000)"`

}

Copy the code

task


type Job struct {

    gorm.Model

    Name          string `binding:"required,min=2,max=20"`

    Desc          string `gorm:"type:varchar(1000)",binding:"required,min=2,max=999"`

    Status        int    `gorm:"default:0"`        // Task status

    Branch        string `gorm:"default:'master'"` // The deployment branch defaults to master, which users can change at any time prior to deployment

    Url           string                           // Access the directory, return only if the status is successful

    RunQuantity   int `gorm:"default:0"`

    CategoryId    int `gorm:"index",binding:"required"`

    WebHookUrl    string

    RepositoryId  int    `gorm:"index",binding:"required"`

    BuildDir      string `binding:"required"` // The packaged directory, the default is dist

    BuildCommand  string `binding:"required"` // Package command, NPM run build can optionally read package.json

    Password      string                      // Task encryption

    TerminalInfo  string `gorm:"type:varchar(1000)"`

    SuccessScript string `gorm:"type:varchar(1000)"` // Package successfully run scripts, multiple use; separated

}

Copy the code

It wasn’t those fields at first, but I changed them many times and deleted a lot of things.


Warehouse management is basically cloning the warehouse to manage the code by the warehouse ID. Every time a task is run, the code is updated, js dependencies are installed, branches are switched and packaged, and the packaged code is managed and accessed through the task ID. One sentence seems to sum up, but in the process of writing to consider a lot of things. For example, the same warehouse needs to package multiple sets of environments, how to lock the warehouse when switching branches, how to report packaging errors to users, when to install dependencies, how to deal with installation failures, how to deal with new code when switching branches of different tasks, what tools to use when installing dependencies, etc

Anyway, I was thinking and doing, and I drew a lot of drafts.


The thing that really bothered me the most was the directory structure and the responsibility of the package, because I accidentally looped through the package, especially the helper package, which provides some common methods. At first, I would reference other self-defined packages in the package, but I shouldn’t have done that. These utility functions should not rely on other custom packages. It should have a single responsibility and no dependencies. If you need to rely on a custom package, you should consider putting it in the corresponding service.


And then I’m the front end, and I’ve written a little bit of Laravel before, so the back end directory looks a little bit like the previous structure and has been refactored a lot. The front-end code organization has also made many adjustments, and the UI interface has also been adjusted a lot. Keep looking for the best solution, but there are still many shortcomings. Welcome to ask questions and communicate with us.

Another deep feeling is that it is very simple to complicate a simple problem, and difficult to simplify a complex problem.

Role authorization

At the beginning, I only did the core functions above and could already use them. However, after the company promoted them, I found that the user module and the permission module were also very important, so I added the simple design of the user module and the permission.

Roles are currently divided into super administrator, administrator, developer, and project reporter. The permissions are as follows:

  • Project reporter – Can only view all content and have access to packaged front-end projects

  • Developer – has permissions to create repositories, sort, task and pull code, switch branches, run packages, and remove dependencies

  • Administrator – Can delete warehouses, categories, and tasks

  • Super Administrator – Can manage users (promote and degrade roles, delete users)

Note: A higher-level role has all the rights of a lower-level role. By default, the user becomes the project reporter. If the name is Admin, the user will automatically become the super administrator. The registered name cannot be repeated.