Skip to content

Commit

Permalink
Add release workflow (#25)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
YannikBramkamp authored Feb 2, 2021
1 parent ff81b6c commit 051583d
Show file tree
Hide file tree
Showing 26 changed files with 334 additions and 384 deletions.
19 changes: 19 additions & 0 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: Release

on:
push:
tags:
- '*'

jobs:
build:
name: Build and release image
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2

- run: docker login -u "${{ secrets.DOCKER_LOGIN_USER }}" -p "${{ secrets.DOCKER_LOGIN_PASSWORD }}" quay.io

- run: curl -sL https://git.io/goreleaser | bash -s -- --config build/ci/.goreleaser.yml --rm-dist
env:
GITHUB_TOKEN: ${{ secrets.RELEASE_USER_TOKEN }}
25 changes: 16 additions & 9 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
BINARY_NAME = brudi
COMMIT_HASH = $(shell git rev-parse --verify HEAD)
CURDIR = $(shell pwd)
GOLANGCI_LINT_VER = v1.33.0
GOLANGCI_LINT_VER = v1.35.0

.PHONY: build test

Expand All @@ -25,14 +25,21 @@ build:
test:
go test -v ./...

lintpull:
docker pull golangci/golangci-lint:$(GOLANGCI_LINT_VER)

lint: lintpull
docker run --rm -v $(CURDIR):/app -w /app golangci/golangci-lint:$(GOLANGCI_LINT_VER) golangci-lint -c build/ci/.golangci.yml run -v

lintfix: lintpull
docker run --rm -v $(CURDIR):/app -w /app golangci/golangci-lint:$(GOLANGCI_LINT_VER) golangci-lint -c build/ci/.golangci.yml run -v --fix
lintci:
docker run --rm \
-v $(CURDIR):/app \
-w /app \
-e GOLANGCI_ADDITIONAL_YML=/app/build/package/ci/.golangci.yml \
quay.io/mittwald/golangci-lint:0.0.8 \
golangci-lint run -v --fix ./...

lint:
docker run --rm \
-v $(shell go env GOPATH):/go \
-v ${CURDIR}:/app -w /app \
-e GOLANGCI_ADDITIONAL_YML=/app/build/package/ci/.golangci.yml \
quay.io/mittwald/golangci-lint:0.0.8 \
golangci-lint run -v --fix ./...

goreleaser:
curl -sL https://git.io/goreleaser | bash -s -- --snapshot --skip-publish --rm-dist
Expand Down
55 changes: 29 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,30 +13,33 @@ Besides creating backups, `brudi` can also be used to restore your data from bac

## Table of contents

- [Usage](#usage)
- [CLI](#cli)
- [Configuration](#configuration)
- [Sources](#sources)
- [Tar](#tar)
- [MySQLDump](#mysqldump)
- [MongoDump](#mongodump)
- [PgDump](#pgdump)
- [Limitations](#limitations)
- [Redis](#redis)
- [Restic](#restic)
- [Forget](#forget)
- [Sensitive data: Environment variables](#sensitive-data--environment-variables)
- [Restoring from backup](#restoring-from-backup)
- [TarRestore](#tarrestore)
- [MongoRestore](#mongorestore)
- [MySQLRestore](#mysqlrestore)
- [PgRestore](#pgrestore)
- [Restore using pg_restore](#restore-using-pg_restore)
- [Restore using psql](#restore-using-psql)
- [Featurestate](#featurestate)
- [Source backup methods](#source-backup-methods)
- [Restore backup methods](#restore-backup-methods)
- [Incremental backup of the source backups](#incremental-backup-of-the-source-backups)
- [Usage](#usage)
- [CLI](#cli)
- [Docker](#docker)
- [Configuration](#configuration)
- [Sources](#sources)
- [Tar](#tar)
- [MySQLDump](#mysqldump)
- [MongoDump](#mongodump)
- [PgDump](#pgdump)
- [Limitations](#limitations)
- [Redis](#redis)
- [Restic](#restic)
- [Forget](#forget)
- [Sensitive data: Environment variables](#sensitive-data-environment-variables)
- [Gzip support for binaries without native gzip support](#gzip-support-for-binaries-without-native-gzip-support)
- [Restoring from backup](#restoring-from-backup)
- [TarRestore](#tarrestore)
- [MongoRestore](#mongorestore)
- [MySQLRestore](#mysqlrestore)
- [PgRestore](#pgrestore)
- [Restore using pg_restore](#restore-using-pg_restore)
- [Restore using psql](#restore-using-psql)
- [Restoring using restic](#restoring-using-restic)
- [Featurestate](#featurestate)
- [Source backup methods](#source-backup-methods)
- [Restore backup methods](#restore-backup-methods)
- [Incremental backup of the source backups](#incremental-backup-of-the-source-backups)

## Usage

Expand Down Expand Up @@ -411,7 +414,7 @@ Restoration for PostgreSQL databases is split into two commands, `psql` and `pgr
`pgrestore` can be used if the `format` option of `pg_dump` was set to `tar`, `directory` or `custom`.
##### Restore using pg_restore
###### Restore using pg_restore
```yaml
pgrestore:
Expand All @@ -435,7 +438,7 @@ This command has to be used if the `format` option was set to `tar`, `directory`
All available flags to be set in the `.yaml`-configuration can be found [here](pkg/source/pgrestore/cli.go#L7).
##### Restore using psql
###### Restore using psql
```yaml
psql:
Expand Down
82 changes: 3 additions & 79 deletions build/ci/.golangci.yml
Original file line number Diff line number Diff line change
@@ -1,83 +1,7 @@
linters-settings:
dupl:
threshold: 100
funlen:
lines: 100
statements: 50
goconst:
min-len: 2
min-occurrences: 2
gocritic:
enabled-tags:
- diagnostic
- experimental
- opinionated
- performance
- style
disabled-checks:
- dupImport # https://github.com/go-critic/go-critic/issues/845
- ifElseChain
- octalLiteral
- whyNoLint
- wrapperFunc
gocyclo:
min-complexity: 20
goimports:
local-prefixes: github.com/mittwald/brudi
golint:
min-confidence: 0
gomnd:
settings:
mnd:
# don't include the "operation" and "assign"
checks: argument,case,return
lll:
line-length: 140
maligned:
suggest-new: true
misspell:
locale: US

linters:
disable-all: true
enable:
- bodyclose
- deadcode
- depguard
- dogsled
- dupl
- errcheck
- funlen
- goconst
- gocritic
- gocyclo
- gofmt
- goimports
- golint
- gomnd
- goprintffuncname
- gosimple
- govet
- ineffassign
- interfacer
- lll
- misspell
- nakedret
- rowserrcheck
- scopelint
- staticcheck
- structcheck
- stylecheck
- typecheck
- unconvert
- unparam
- unused
- varcheck
- whitespace
# tested with golangci/golangci-lint:v1.35

run:
skip-dirs:
- example/
- .github/
- dist/
- test/
timeout: 10m

2 changes: 1 addition & 1 deletion build/ci/.goreleaser.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
before:
hooks:
- go mod download
- make lint
- make lintci
builds:
-
env:
Expand Down
5 changes: 3 additions & 2 deletions main.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package main

import (
"github.com/spf13/cobra"
"errors"

"github.com/mittwald/brudi/cmd"
"github.com/mittwald/brudi/internal"
"github.com/spf13/cobra"
)

func init() {
Expand All @@ -13,7 +14,7 @@ func init() {

func main() {
err := cmd.Execute()
if err != nil && err != cobra.ErrSubCommandRequired {
if err != nil && !errors.Is(err, cobra.ErrSubCommandRequired) {
panic(err)
}
}
20 changes: 8 additions & 12 deletions pkg/cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ func includeFlag(flag, val string) []string {
// Notice:
// ----------------------------------------------------
// Zero values (0, "", nil, false) and "-" will be ignored
func StructToCLI(optionStruct interface{}) []string { // nolint: gocyclo
func StructToCLI(optionStruct interface{}) []string {
if optionStruct == reflect.Zero(reflect.TypeOf(optionStruct)).Interface() {
return nil
}
Expand Down Expand Up @@ -201,12 +201,12 @@ func Run(ctx context.Context, cmd CommandType) ([]byte, error) {
commandLine := ParseCommandLine(cmd)
log.WithField("command", strings.Join(commandLine, " ")).Debug("executing command")
if ctx != nil {
out, err = exec.CommandContext(ctx, commandLine[0], commandLine[1:]...).CombinedOutput()
out, err = exec.CommandContext(ctx, commandLine[0], commandLine[1:]...).CombinedOutput() // nolint: gosec
if ctx.Err() != nil {
return out, fmt.Errorf("failed to execute command: timed out or canceled")
}
} else {
out, err = exec.Command(commandLine[0], commandLine[1:]...).CombinedOutput()
out, err = exec.Command(commandLine[0], commandLine[1:]...).CombinedOutput() // nolint: gosec
}
if err != nil {
return out, fmt.Errorf("failed to execute command: %s", err)
Expand Down Expand Up @@ -251,13 +251,8 @@ func RunPiped(ctx context.Context, cmd1, cmd2 CommandType, pids *PipedCommandsPi
),
).Debug("executing command")

if ctx != nil {
cmd1Exec = exec.CommandContext(ctx, cmdLine1[0], cmdLine1[1:]...)
cmd2Exec = exec.CommandContext(ctx, cmdLine2[0], cmdLine2[1:]...)
} else {
cmd1Exec = exec.Command(cmdLine1[0], cmdLine1[1:]...)
cmd2Exec = exec.Command(cmdLine2[0], cmdLine2[1:]...)
}
cmd1Exec = exec.CommandContext(ctx, cmdLine1[0], cmdLine1[1:]...) // nolint: gosec
cmd2Exec = exec.CommandContext(ctx, cmdLine2[0], cmdLine2[1:]...) // nolint: gosec

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

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

// write unzipped file to file system
_, err = io.Copy(outFile, archiveReader)
_, err = io.Copy(outFile, archiveReader) // nolint: gosec // we work with potentially large backups
if err != nil {
return "", errors.WithStack(err)
}
Expand Down
6 changes: 3 additions & 3 deletions pkg/config/config_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func ReadPaths(cfgFiles ...string) [][]byte {
}
}

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

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

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

var cfgsRendered []*bytes.Buffer
var cfgsRendered = make([]*bytes.Buffer, 0, len(templates))
for _, template := range templates {
renderedCfg := new(bytes.Buffer)
err := template.Execute(renderedCfg, &data)
Expand Down
11 changes: 6 additions & 5 deletions pkg/restic/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,17 +55,18 @@ func (c *Client) DoResticBackup(ctx context.Context) error {
c.Logger.Info("running 'restic backup'")

_, err := initBackup(ctx, c.Config.Global)
if err == ErrRepoAlreadyInitialized {
if errors.Is(err, ErrRepoAlreadyInitialized) {
c.Logger.Info("restic repo is already initialized")
} else if err != nil {
return errors.WithStack(fmt.Errorf("error while initializing restic repository: %s", err.Error()))
} else {
c.Logger.Info("restic repo initialized successfully")
}

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

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

func (c *Client) DoResticRestore(ctx context.Context, backupPath string) error {
c.Logger.Info("running 'restic restore'")
_, err := RestoreBackup(ctx, c.Config.Global, c.Config.Restore, false)
out, err := RestoreBackup(ctx, c.Config.Global, c.Config.Restore, false)
if err != nil {
return errors.WithStack(fmt.Errorf("error while while running restic restore: %s", err.Error()))
return errors.WithStack(fmt.Errorf("error while while running restic restore: %s - %s", err.Error(), out))
}
return nil
}
Expand Down
Loading

0 comments on commit 051583d

Please sign in to comment.