Skip to content

Commit 82ef5d3

Browse files
committed
init
0 parents  commit 82ef5d3

File tree

14 files changed

+671
-0
lines changed

14 files changed

+671
-0
lines changed

.github/workflows/go.yaml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
name: Go CI
2+
on: [push, pull_request]
3+
4+
jobs:
5+
build:
6+
runs-on: ubuntu-latest
7+
steps:
8+
- uses: actions/checkout@v4
9+
10+
- name: Install Go
11+
uses: actions/setup-go@v4
12+
with:
13+
go-version: "1.24.1"
14+
15+
- name: Install Task
16+
run: go install github.com/go-task/task/v3/cmd/task@latest
17+
18+
- name: Install golangci-lint
19+
run: go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
20+
21+
- name: Run linter
22+
run: task lint

.gitignore

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Default ignored files
2+
/shelf/
3+
/workspace.xml
4+
# Editor-based HTTP Client requests
5+
/httpRequests/
6+
# Datasource local storage ignored files
7+
/dataSources/
8+
/dataSources.local.xml
9+
10+
# Intellij project files
11+
*.iml
12+
*.ipr
13+
*.iws
14+
.idea/
15+
16+
# go.gitignore from https://github.com/github/gitignore/blob/master/Go.gitignore
17+
# Binaries for programs and plugins
18+
*.exe
19+
*.exe~
20+
*.dll
21+
*.so
22+
*.dylib
23+
24+
# Test binary, built with `go test -c`
25+
*.test
26+
27+
# Output of the go coverage tool, specifically when used with LiteIDE
28+
*.out
29+
30+
# Dependency directories (remove the comment below to include it)
31+
# If you use Go Vendor to build code
32+
# go.mod
33+
# go.sum
34+
# vendor/
35+
36+
.idea
37+
.env
38+
*log

.golangci.yaml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
linters-settings:
2+
unused:
3+
check-exported: false
4+
5+
linters:
6+
disable-all: true
7+
enable:
8+
- gofmt
9+
- govet
10+
- unused
11+
- errcheck
12+
- staticcheck
13+
14+
issues:
15+
exclude-dirs:
16+
- vendor
17+
- testdata

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 17neverends
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
# BuildCast 🚀
2+
3+
**Frontend Deployment Automation Tool**
4+
5+
**Main problem:** `front-dev should manual build and send buildp path on other dev servers`
6+
7+
![Go](https://img.shields.io/badge/Go-1.18%2B-blue)
8+
![License](https://img.shields.io/badge/License-MIT-green)
9+
![SFTP](https://img.shields.io/badge/Protocol-SFTP-orange)
10+
11+
## Table of Contents
12+
- [Features](#-features)
13+
- [Installation](#-installation)
14+
- [Configuration](#-configuration)
15+
- [Usage](#-usage)
16+
- [Technical Details](#-technical-details)
17+
18+
## ✨ Features
19+
- 🔄 Environment variable substitution in `.env` files
20+
- 🏗️ Build automation with custom commands
21+
- 🚀 Multi-server SFTP deployment
22+
- 🔒 Secure credential management
23+
- 📊 Detailed logging for debugging
24+
25+
## 📦 Installation
26+
27+
### Prerequisites
28+
- Go 1.18+
29+
- Git
30+
31+
### Steps
32+
```bash
33+
git clone https://github.com/17neverends/buildcast.git
34+
cd buildcast
35+
go mod download
36+
go build -o buildcast main.go
37+
```
38+
39+
## ⚙️ Configuration
40+
41+
- config.json
42+
43+
```json
44+
{
45+
// main settings
46+
"main_cmd": "npm run build", // cmd for build frontend app
47+
"build_output": "build", // path name for build files output
48+
"frontend_env_path": ".env", // path to env file
49+
"env_host": "REACT_APP_API_URL=", // field in env file for change
50+
51+
// individual remote server settings
52+
"servers": [
53+
{
54+
"ip": "xx.xx.xx.xxx", // IP for connect
55+
"password": "...", // password for connect
56+
"user": "root", // system username
57+
"host": "https://test.io", // this value will be override in .env
58+
"sftp_port": 22, // sftp connection port
59+
"path": "/home/project" // path for download files on remore server
60+
}
61+
]
62+
}
63+
```
64+
65+
## 🚀 Usage
66+
67+
- Basic commands
68+
69+
`./buildcast --config=config.json --service=admin_dashboard`
70+
71+
72+
- Command Line Options
73+
74+
| Flag | Description |
75+
|------ |------------- |
76+
| --config | Path to configuration file |
77+
|--service | Service name suffix for deployment path |
78+
79+
## 🛠 Technical Details
80+
81+
### Workflow
82+
1. Reads configuration file
83+
84+
2. Backs up original .env file
85+
86+
3. For each server:
87+
- Updates environment variables
88+
89+
- Executes build command
90+
91+
- Cleans target directory
92+
93+
- Deploys via SFTP
94+
95+
- Restores original .env
96+
97+
### Dependencies
98+
- github.com/pkg/sftp
99+
100+
- golang.org/x/crypto/ssh

Taskfile.yaml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
version: '3'
2+
3+
tasks:
4+
deps:
5+
desc: "Install Go dependencies"
6+
cmds:
7+
- go mod download
8+
9+
fmt:
10+
desc: "Format imports"
11+
cmds:
12+
- goimports -w .
13+
14+
lint:
15+
desc: "Start lint"
16+
cmds:
17+
- golangci-lint run --config .golangci.yaml ./...
18+
sources:
19+
- "**/*.go"
20+
21+
build:
22+
desc: "Build bin"
23+
cmds:
24+
- go build -o buildcast.exe ./cmd

cmd/main.go

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package main
2+
3+
import (
4+
"flag"
5+
cfg "github.com/17neverends/buildcast/internal/config"
6+
"github.com/17neverends/buildcast/internal/core"
7+
"log"
8+
"os"
9+
"path/filepath"
10+
)
11+
12+
func main() {
13+
configPath := flag.String("config", "config.json", "Path to config file")
14+
serviceFlag := flag.String("service", "", "Service name to append to deploy path")
15+
flag.Parse()
16+
17+
config, err := cfg.LoadConfig(*configPath)
18+
if err != nil {
19+
log.Fatalf("Error loading config: %v", err)
20+
}
21+
22+
originalEnv, err := os.ReadFile(config.FrontendEnvPath)
23+
if err != nil {
24+
log.Fatalf("Error reading .env file: %v", err)
25+
}
26+
27+
log.Println("Checking servers availability...")
28+
availableServers := core.CheckServers(config.Servers)
29+
if len(availableServers) == 0 {
30+
log.Fatal("No servers available, exiting")
31+
}
32+
33+
for _, server := range availableServers {
34+
log.Printf("Processing server: %s", server.IP)
35+
36+
modifiedEnv := core.ModifyEnv(originalEnv, server.Host, config.EnvHost)
37+
if err := os.WriteFile(config.FrontendEnvPath, modifiedEnv, 0644); err != nil {
38+
log.Printf("Error writing modified .env: %v", err)
39+
continue
40+
}
41+
42+
log.Println("Running build command...")
43+
if err := core.RunCommand(config.MainCmd); err != nil {
44+
log.Printf("Build failed: %v", err)
45+
continue
46+
}
47+
48+
deployPath := filepath.Join(server.Path, *serviceFlag)
49+
log.Printf("Deploying to %s...", deployPath)
50+
if err := core.DeployToServer(server, deployPath, config.BuildOutput); err != nil {
51+
log.Printf("Deploy failed: %v", err)
52+
}
53+
54+
if err := os.WriteFile(config.FrontendEnvPath, originalEnv, 0644); err != nil {
55+
log.Printf("Error restoring .env: %v", err)
56+
}
57+
}
58+
59+
log.Println("Success!")
60+
}

example.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"main_cmd": "npm run build",
3+
"build_output": "build",
4+
"frontend_env_path": ".env",
5+
"env_host": "REACT_APP_API_URL=",
6+
"servers": [
7+
{
8+
"ip": "xx.xx.xx.xxx",
9+
"password": "...",
10+
"user": "root",
11+
"host": "https://test.ru",
12+
"sftp_port": 22,
13+
"path": "/home/project"
14+
}
15+
]
16+
}

go.mod

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
module github.com/17neverends/buildcast
2+
3+
go 1.24.1
4+
5+
require github.com/pkg/sftp v1.13.9
6+
7+
require (
8+
github.com/kr/fs v0.1.0 // indirect
9+
golang.org/x/crypto v0.31.0 // indirect
10+
golang.org/x/sys v0.28.0 // indirect
11+
)

0 commit comments

Comments
 (0)