Skip to content

Commit 051583d

Browse files
Add release workflow (#25)
* Create go.yml * remove unneded workflow * create GzipFile() * added --gzip flag and integrated it into backup process * error handling * Revert " added --gzip flag and integrated it into backup process" This reverts commit c755f46. * tests for gzip functions * fix import * updated readme * properly use gzip const everywhere, change gzip variable definition * more const uses * add test for validity of generated gzip * create gzip testfile during runtime, renamed test * const for test file permissions * cleanup and some comments * rename github workflow * fix forgotten error handling in test * test for CheckAndGunzipFile * documentation * multiline cupcakes * add release workflow * fixed docker user * fixed workflow * update readme toc * update linter cfg * lint maligned structures * linting * Fix error in mongorestore cli flags * add restic output to error restic backup and restore error message * use global linter cfg * attempt to fix workflow * checkout project before linting * remove unneeded lint step, try to fix goreleaser lint step * fix working directory * fix skip dirs * removed context check
1 parent ff81b6c commit 051583d

File tree

26 files changed

+334
-384
lines changed

26 files changed

+334
-384
lines changed

.github/workflows/release.yaml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags:
6+
- '*'
7+
8+
jobs:
9+
build:
10+
name: Build and release image
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v2
14+
15+
- run: docker login -u "${{ secrets.DOCKER_LOGIN_USER }}" -p "${{ secrets.DOCKER_LOGIN_PASSWORD }}" quay.io
16+
17+
- run: curl -sL https://git.io/goreleaser | bash -s -- --config build/ci/.goreleaser.yml --rm-dist
18+
env:
19+
GITHUB_TOKEN: ${{ secrets.RELEASE_USER_TOKEN }}

Makefile

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
BINARY_NAME = brudi
22
COMMIT_HASH = $(shell git rev-parse --verify HEAD)
33
CURDIR = $(shell pwd)
4-
GOLANGCI_LINT_VER = v1.33.0
4+
GOLANGCI_LINT_VER = v1.35.0
55

66
.PHONY: build test
77

@@ -25,14 +25,21 @@ build:
2525
test:
2626
go test -v ./...
2727

28-
lintpull:
29-
docker pull golangci/golangci-lint:$(GOLANGCI_LINT_VER)
30-
31-
lint: lintpull
32-
docker run --rm -v $(CURDIR):/app -w /app golangci/golangci-lint:$(GOLANGCI_LINT_VER) golangci-lint -c build/ci/.golangci.yml run -v
33-
34-
lintfix: lintpull
35-
docker run --rm -v $(CURDIR):/app -w /app golangci/golangci-lint:$(GOLANGCI_LINT_VER) golangci-lint -c build/ci/.golangci.yml run -v --fix
28+
lintci:
29+
docker run --rm \
30+
-v $(CURDIR):/app \
31+
-w /app \
32+
-e GOLANGCI_ADDITIONAL_YML=/app/build/package/ci/.golangci.yml \
33+
quay.io/mittwald/golangci-lint:0.0.8 \
34+
golangci-lint run -v --fix ./...
35+
36+
lint:
37+
docker run --rm \
38+
-v $(shell go env GOPATH):/go \
39+
-v ${CURDIR}:/app -w /app \
40+
-e GOLANGCI_ADDITIONAL_YML=/app/build/package/ci/.golangci.yml \
41+
quay.io/mittwald/golangci-lint:0.0.8 \
42+
golangci-lint run -v --fix ./...
3643

3744
goreleaser:
3845
curl -sL https://git.io/goreleaser | bash -s -- --snapshot --skip-publish --rm-dist

README.md

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -13,30 +13,33 @@ Besides creating backups, `brudi` can also be used to restore your data from bac
1313

1414
## Table of contents
1515

16-
- [Usage](#usage)
17-
- [CLI](#cli)
18-
- [Configuration](#configuration)
19-
- [Sources](#sources)
20-
- [Tar](#tar)
21-
- [MySQLDump](#mysqldump)
22-
- [MongoDump](#mongodump)
23-
- [PgDump](#pgdump)
24-
- [Limitations](#limitations)
25-
- [Redis](#redis)
26-
- [Restic](#restic)
27-
- [Forget](#forget)
28-
- [Sensitive data: Environment variables](#sensitive-data--environment-variables)
29-
- [Restoring from backup](#restoring-from-backup)
30-
- [TarRestore](#tarrestore)
31-
- [MongoRestore](#mongorestore)
32-
- [MySQLRestore](#mysqlrestore)
33-
- [PgRestore](#pgrestore)
34-
- [Restore using pg_restore](#restore-using-pg_restore)
35-
- [Restore using psql](#restore-using-psql)
36-
- [Featurestate](#featurestate)
37-
- [Source backup methods](#source-backup-methods)
38-
- [Restore backup methods](#restore-backup-methods)
39-
- [Incremental backup of the source backups](#incremental-backup-of-the-source-backups)
16+
- [Usage](#usage)
17+
- [CLI](#cli)
18+
- [Docker](#docker)
19+
- [Configuration](#configuration)
20+
- [Sources](#sources)
21+
- [Tar](#tar)
22+
- [MySQLDump](#mysqldump)
23+
- [MongoDump](#mongodump)
24+
- [PgDump](#pgdump)
25+
- [Limitations](#limitations)
26+
- [Redis](#redis)
27+
- [Restic](#restic)
28+
- [Forget](#forget)
29+
- [Sensitive data: Environment variables](#sensitive-data-environment-variables)
30+
- [Gzip support for binaries without native gzip support](#gzip-support-for-binaries-without-native-gzip-support)
31+
- [Restoring from backup](#restoring-from-backup)
32+
- [TarRestore](#tarrestore)
33+
- [MongoRestore](#mongorestore)
34+
- [MySQLRestore](#mysqlrestore)
35+
- [PgRestore](#pgrestore)
36+
- [Restore using pg_restore](#restore-using-pg_restore)
37+
- [Restore using psql](#restore-using-psql)
38+
- [Restoring using restic](#restoring-using-restic)
39+
- [Featurestate](#featurestate)
40+
- [Source backup methods](#source-backup-methods)
41+
- [Restore backup methods](#restore-backup-methods)
42+
- [Incremental backup of the source backups](#incremental-backup-of-the-source-backups)
4043

4144
## Usage
4245

@@ -411,7 +414,7 @@ Restoration for PostgreSQL databases is split into two commands, `psql` and `pgr
411414
412415
`pgrestore` can be used if the `format` option of `pg_dump` was set to `tar`, `directory` or `custom`.
413416
414-
##### Restore using pg_restore
417+
###### Restore using pg_restore
415418
416419
```yaml
417420
pgrestore:
@@ -435,7 +438,7 @@ This command has to be used if the `format` option was set to `tar`, `directory`
435438
436439
All available flags to be set in the `.yaml`-configuration can be found [here](pkg/source/pgrestore/cli.go#L7).
437440
438-
##### Restore using psql
441+
###### Restore using psql
439442
440443
```yaml
441444
psql:

build/ci/.golangci.yml

Lines changed: 3 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1,83 +1,7 @@
1-
linters-settings:
2-
dupl:
3-
threshold: 100
4-
funlen:
5-
lines: 100
6-
statements: 50
7-
goconst:
8-
min-len: 2
9-
min-occurrences: 2
10-
gocritic:
11-
enabled-tags:
12-
- diagnostic
13-
- experimental
14-
- opinionated
15-
- performance
16-
- style
17-
disabled-checks:
18-
- dupImport # https://github.com/go-critic/go-critic/issues/845
19-
- ifElseChain
20-
- octalLiteral
21-
- whyNoLint
22-
- wrapperFunc
23-
gocyclo:
24-
min-complexity: 20
25-
goimports:
26-
local-prefixes: github.com/mittwald/brudi
27-
golint:
28-
min-confidence: 0
29-
gomnd:
30-
settings:
31-
mnd:
32-
# don't include the "operation" and "assign"
33-
checks: argument,case,return
34-
lll:
35-
line-length: 140
36-
maligned:
37-
suggest-new: true
38-
misspell:
39-
locale: US
40-
41-
linters:
42-
disable-all: true
43-
enable:
44-
- bodyclose
45-
- deadcode
46-
- depguard
47-
- dogsled
48-
- dupl
49-
- errcheck
50-
- funlen
51-
- goconst
52-
- gocritic
53-
- gocyclo
54-
- gofmt
55-
- goimports
56-
- golint
57-
- gomnd
58-
- goprintffuncname
59-
- gosimple
60-
- govet
61-
- ineffassign
62-
- interfacer
63-
- lll
64-
- misspell
65-
- nakedret
66-
- rowserrcheck
67-
- scopelint
68-
- staticcheck
69-
- structcheck
70-
- stylecheck
71-
- typecheck
72-
- unconvert
73-
- unparam
74-
- unused
75-
- varcheck
76-
- whitespace
1+
# tested with golangci/golangci-lint:v1.35
772

783
run:
794
skip-dirs:
80-
- example/
81-
- .github/
82-
- dist/
835
- test/
6+
timeout: 10m
7+

build/ci/.goreleaser.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
before:
22
hooks:
33
- go mod download
4-
- make lint
4+
- make lintci
55
builds:
66
-
77
env:

main.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
package main
22

33
import (
4-
"github.com/spf13/cobra"
4+
"errors"
55

66
"github.com/mittwald/brudi/cmd"
77
"github.com/mittwald/brudi/internal"
8+
"github.com/spf13/cobra"
89
)
910

1011
func init() {
@@ -13,7 +14,7 @@ func init() {
1314

1415
func main() {
1516
err := cmd.Execute()
16-
if err != nil && err != cobra.ErrSubCommandRequired {
17+
if err != nil && !errors.Is(err, cobra.ErrSubCommandRequired) {
1718
panic(err)
1819
}
1920
}

pkg/cli/cli.go

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ func includeFlag(flag, val string) []string {
9393
// Notice:
9494
// ----------------------------------------------------
9595
// Zero values (0, "", nil, false) and "-" will be ignored
96-
func StructToCLI(optionStruct interface{}) []string { // nolint: gocyclo
96+
func StructToCLI(optionStruct interface{}) []string {
9797
if optionStruct == reflect.Zero(reflect.TypeOf(optionStruct)).Interface() {
9898
return nil
9999
}
@@ -201,12 +201,12 @@ func Run(ctx context.Context, cmd CommandType) ([]byte, error) {
201201
commandLine := ParseCommandLine(cmd)
202202
log.WithField("command", strings.Join(commandLine, " ")).Debug("executing command")
203203
if ctx != nil {
204-
out, err = exec.CommandContext(ctx, commandLine[0], commandLine[1:]...).CombinedOutput()
204+
out, err = exec.CommandContext(ctx, commandLine[0], commandLine[1:]...).CombinedOutput() // nolint: gosec
205205
if ctx.Err() != nil {
206206
return out, fmt.Errorf("failed to execute command: timed out or canceled")
207207
}
208208
} else {
209-
out, err = exec.Command(commandLine[0], commandLine[1:]...).CombinedOutput()
209+
out, err = exec.Command(commandLine[0], commandLine[1:]...).CombinedOutput() // nolint: gosec
210210
}
211211
if err != nil {
212212
return out, fmt.Errorf("failed to execute command: %s", err)
@@ -251,13 +251,8 @@ func RunPiped(ctx context.Context, cmd1, cmd2 CommandType, pids *PipedCommandsPi
251251
),
252252
).Debug("executing command")
253253

254-
if ctx != nil {
255-
cmd1Exec = exec.CommandContext(ctx, cmdLine1[0], cmdLine1[1:]...)
256-
cmd2Exec = exec.CommandContext(ctx, cmdLine2[0], cmdLine2[1:]...)
257-
} else {
258-
cmd1Exec = exec.Command(cmdLine1[0], cmdLine1[1:]...)
259-
cmd2Exec = exec.Command(cmdLine2[0], cmdLine2[1:]...)
260-
}
254+
cmd1Exec = exec.CommandContext(ctx, cmdLine1[0], cmdLine1[1:]...) // nolint: gosec
255+
cmd2Exec = exec.CommandContext(ctx, cmdLine2[0], cmdLine2[1:]...) // nolint: gosec
261256

262257
cmd2Exec.Stdin, err = cmd1Exec.StdoutPipe()
263258
if err != nil {
@@ -288,7 +283,8 @@ func RunPiped(ctx context.Context, cmd1, cmd2 CommandType, pids *PipedCommandsPi
288283

289284
err = cmd1Exec.Wait()
290285
if err != nil {
291-
msg, ok := err.(*exec.ExitError)
286+
var msg exec.ExitError
287+
ok := errors.As(err, &msg)
292288
if !ok || !(cmd1.Binary == "tar" && msg.Sys().(syscall.WaitStatus).ExitStatus() == 1) { // ignore tar exit-code of 1
293289
errs = append(errs, err.Error())
294290
}
@@ -438,7 +434,7 @@ func CheckAndGunzipFile(fileName string) (string, error) {
438434
}()
439435

440436
// write unzipped file to file system
441-
_, err = io.Copy(outFile, archiveReader)
437+
_, err = io.Copy(outFile, archiveReader) // nolint: gosec // we work with potentially large backups
442438
if err != nil {
443439
return "", errors.WithStack(err)
444440
}

pkg/config/config_handler.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ func ReadPaths(cfgFiles ...string) [][]byte {
3636
}
3737
}
3838

39-
var cfgContent [][]byte
39+
var cfgContent = make([][]byte, 0, len(cfgFiles))
4040
for _, file := range cfgFiles {
4141
content, err := ioutil.ReadFile(file)
4242
if err != nil {
@@ -49,7 +49,7 @@ func ReadPaths(cfgFiles ...string) [][]byte {
4949

5050
// RawConfigs creates templates for provided configs
5151
func RawConfigs(configContent [][]byte) []*template.Template {
52-
var tpl []*template.Template
52+
var tpl = make([]*template.Template, 0, len(configContent))
5353

5454
for _, content := range configContent {
5555
tpltemp, err := template.New("").Parse(string(content))
@@ -78,7 +78,7 @@ func RenderConfigs(templates []*template.Template) []*bytes.Buffer {
7878
}
7979
}
8080

81-
var cfgsRendered []*bytes.Buffer
81+
var cfgsRendered = make([]*bytes.Buffer, 0, len(templates))
8282
for _, template := range templates {
8383
renderedCfg := new(bytes.Buffer)
8484
err := template.Execute(renderedCfg, &data)

pkg/restic/client.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,17 +55,18 @@ func (c *Client) DoResticBackup(ctx context.Context) error {
5555
c.Logger.Info("running 'restic backup'")
5656

5757
_, err := initBackup(ctx, c.Config.Global)
58-
if err == ErrRepoAlreadyInitialized {
58+
if errors.Is(err, ErrRepoAlreadyInitialized) {
5959
c.Logger.Info("restic repo is already initialized")
6060
} else if err != nil {
6161
return errors.WithStack(fmt.Errorf("error while initializing restic repository: %s", err.Error()))
6262
} else {
6363
c.Logger.Info("restic repo initialized successfully")
6464
}
6565

66-
_, _, err = CreateBackup(ctx, c.Config.Global, c.Config.Backup, true)
66+
var out []byte
67+
_, out, err = CreateBackup(ctx, c.Config.Global, c.Config.Backup, true)
6768
if err != nil {
68-
return errors.WithStack(fmt.Errorf("error while while running restic backup: %s", err.Error()))
69+
return errors.WithStack(fmt.Errorf("error while while running restic backup: %s - %s", err.Error(), out))
6970
}
7071

7172
c.Logger.Info("successfully saved restic stuff")
@@ -75,9 +76,9 @@ func (c *Client) DoResticBackup(ctx context.Context) error {
7576

7677
func (c *Client) DoResticRestore(ctx context.Context, backupPath string) error {
7778
c.Logger.Info("running 'restic restore'")
78-
_, err := RestoreBackup(ctx, c.Config.Global, c.Config.Restore, false)
79+
out, err := RestoreBackup(ctx, c.Config.Global, c.Config.Restore, false)
7980
if err != nil {
80-
return errors.WithStack(fmt.Errorf("error while while running restic restore: %s", err.Error()))
81+
return errors.WithStack(fmt.Errorf("error while while running restic restore: %s - %s", err.Error(), out))
8182
}
8283
return nil
8384
}

0 commit comments

Comments
 (0)