From 8d967cfa2ef35eaefa96ae5380b49dbb28373041 Mon Sep 17 00:00:00 2001 From: d3m0k1d Date: Wed, 14 Jan 2026 00:32:40 +0300 Subject: [PATCH] feat: Add CD, first release version --- .gitea/workflows/CD.yml | 104 +++++++++++++++++++++++++++++++++++++ cmd/banforge/main.go | 48 ++++++++++++----- go.mod | 2 +- internal/config/sysconf.go | 5 +- 4 files changed, 143 insertions(+), 16 deletions(-) create mode 100644 .gitea/workflows/CD.yml diff --git a/.gitea/workflows/CD.yml b/.gitea/workflows/CD.yml new file mode 100644 index 0000000..30bbcba --- /dev/null +++ b/.gitea/workflows/CD.yml @@ -0,0 +1,104 @@ + +name: CD - BanForge Release + +on: + push: + tags: + - 'v*' + workflow_dispatch: + +permissions: + contents: write + +jobs: + build: + strategy: + matrix: + include: + - goos: linux + arch: amd64 + - goos: linux + arch: arm64 + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v6 + + - uses: actions/setup-go@v6 + with: + go-version: '1.25' + cache: false + + - run: go mod tidy + + - uses: golangci/golangci-lint-action@v9.20 + with: + args: --timeout=5m + skip-cache: true + + - run: go test ./... + + - name: Build ${{ matrix.goos }}-${{ matrix.arch }} + env: + GOOS: ${{ matrix.goos }} + GOARCH: ${{ matrix.arch }} + run: go build -o banforge-${{ matrix.goos }}-${{ matrix.arch }} ./cmd/banforge + + - uses: actions/upload-artifact@v4 + with: + name: banforge-${{ matrix.arch }} + path: banforge-${{ matrix.goos }}-${{ matrix.arch }} + retention-days: 1 + + release: + needs: build + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v6 + + - uses: actions/download-artifact@v4 + with: + path: ./artifacts + + - name: Create Release + env: + GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} + run: | + TAG="${{ gitea.ref_name }}" + REPO="${{ gitea.repository }}" + SERVER="${{ gitea.server_url }}" + TOKEN="$TOKEN" + + curl -X POST \ + -H "Authorization: token $TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ + "tag_name": "'$TAG'", + "name": "Release '$TAG'", + "body": "# BanForge '$TAG'\n\nIntrusion Prevention System\n\n## Supported Firewalls\n- UFW\n- iptables\n- nftables\n- firewalld", + "draft": false, + "prerelease": false + }' \ + "$SERVER/api/v1/repos/$REPO/releases" + + - name: Upload Assets + env: + GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} + run: | + TAG="${{ gitea.ref_name }}" + REPO="${{ gitea.repository }}" + SERVER="${{ gitea.server_url }}" + TOKEN="$GITEA_TOKEN" + + for artifact_dir in artifacts/*/; do + for file in "$artifact_dir"*; do + [ -f "$file" ] && \ + curl -X POST \ + -H "Authorization: token $TOKEN" \ + -H "Content-Type: application/octet-stream" \ + --data-binary "@$file" \ + "$SERVER/api/v1/repos/$REPO/releases/tags/$TAG/assets?name=$(basename "$file")" + done + done diff --git a/cmd/banforge/main.go b/cmd/banforge/main.go index b877b8c..3894a30 100644 --- a/cmd/banforge/main.go +++ b/cmd/banforge/main.go @@ -86,7 +86,11 @@ var initCmd = &cobra.Command{ fmt.Println(err) os.Exit(1) } - db.CreateTable() + err = db.CreateTable() + if err != nil { + fmt.Println(err) + os.Exit(1) + } defer func() { err = db.Close() if err != nil { @@ -153,20 +157,36 @@ var daemonCmd = &cobra.Command{ } } }() - for service := range cfg.Service { - if cfg.Service[service].Enabled && cfg.Service[service].Name != "nginx" { - pars, err := parser.NewScanner(cfg.Service[service].LogPath) - if err != nil { - log.Error("Failed to create scanner", "error", err) - } - go pars.Start() - go func(p *parser.Scanner) { - ng := parser.NewNginxParser() - resultCh := make(chan *storage.LogEntry, 100) - ng.Parse(p.Events(), resultCh) - go storage.Write(db, resultCh) - }(pars) + + for _, svc := range cfg.Service { + log.Info("Processing service", "name", svc.Name, "enabled", svc.Enabled, "path", svc.LogPath) + + if !svc.Enabled { + log.Info("Service disabled, skipping", "name", svc.Name) + continue } + + if svc.Name != "nginx" { + log.Info("Only nginx supported, skipping", "name", svc.Name) + continue + } + + log.Info("Starting parser for service", "name", svc.Name, "path", svc.LogPath) + + pars, err := parser.NewScanner(svc.LogPath) + if err != nil { + log.Error("Failed to create scanner", "service", svc.Name, "error", err) + continue + } + + go pars.Start() + go func(p *parser.Scanner, serviceName string) { + log.Info("Starting nginx parser", "service", serviceName) + ng := parser.NewNginxParser() + resultCh := make(chan *storage.LogEntry, 100) + ng.Parse(p.Events(), resultCh) + go storage.Write(db, resultCh) + }(pars, svc.Name) } select {} diff --git a/go.mod b/go.mod index 181cfb2..44b3b62 100644 --- a/go.mod +++ b/go.mod @@ -4,11 +4,11 @@ go 1.25.5 require ( github.com/BurntSushi/toml v1.6.0 + github.com/mattn/go-sqlite3 v1.14.33 github.com/spf13/cobra v1.10.2 ) require ( github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/mattn/go-sqlite3 v1.14.33 // indirect github.com/spf13/pflag v1.0.10 // indirect ) diff --git a/internal/config/sysconf.go b/internal/config/sysconf.go index 435adcc..d65ceb5 100644 --- a/internal/config/sysconf.go +++ b/internal/config/sysconf.go @@ -54,7 +54,10 @@ func CreateConf() error { if err != nil { return fmt.Errorf("failed to create database file: %w", err) } - os.Chmod("/var/lib/banforge/storage.db", 0600) + err = os.Chmod("/var/lib/banforge/storage.db", 0600) + if err != nil { + return fmt.Errorf("failed to set permissions: %w", err) + } defer func() { err = file.Close() if err != nil {