build: use make for building the project (#1304)

pull/1305/head
Oleg Lobanov 4 years ago committed by GitHub
parent 2d2c598fa6
commit 23f84642e6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,55 +1,39 @@
version: 2
version: 2.1
references:
base_container: &base_container
docker:
- image: filebrowser/builder:v1.1.0
jobs:
lint:
docker:
- image: golangci/golangci-lint:v1.31.0
<<: *base_container
steps:
- checkout
- run: golangci-lint run -v
build-node:
docker:
- image: circleci/node
steps:
- checkout
- run:
name: "Build"
command: ./wizard.sh -a
- run:
name: "Cleanup"
command: rm -rf frontend/node_modules
- persist_to_workspace:
root: .
paths:
- '*'
- run: make lint
test:
docker:
- image: circleci/golang:1.15.2
<<: *base_container
steps:
- checkout
- run:
name: "Test"
command: go test ./...
build-go:
docker:
- image: circleci/golang:1.15.2
command: make test
build:
<<: *base_container
steps:
- attach_workspace:
at: '~/project'
- checkout
- run:
name: "Compile"
command: GOOS=linux GOARCH=amd64 ./wizard.sh -c
name: "Build"
command: make build
- run:
name: "Cleanup"
command: |
rm -rf frontend/build
git checkout -- go.sum # TODO: why is it being changed?
rm -rf frontend/node_modules
rm -rf bin/
- persist_to_workspace:
root: .
paths:
- '*'
release:
docker:
- image: circleci/golang:1.15.2
<<: *base_container
steps:
- attach_workspace:
at: '~/project'
@ -69,22 +53,16 @@ workflows:
filters:
tags:
only: /.*/
- build-node:
filters:
tags:
only: /.*/
- build-go:
- build:
filters:
tags:
only: /.*/
requires:
- build-node
- lint
- test
- release:
context: deploy
requires:
- build-go
- build
- test
- lint
filters:
tags:
only: /^v.*/

2
.gitignore vendored

@ -28,3 +28,5 @@ yarn-error.log*
*.njsproj
*.sln
*.sw*
bin/
build/

@ -63,7 +63,6 @@ linters:
- goconst
- gocritic
- gocyclo
- gofmt
- goimports
- golint
- gomnd

@ -0,0 +1,14 @@
{
"types": [
{ "type": "feat", "section": "Features" },
{ "type": "fix", "section": "Bug Fixes" },
{ "type": "perf", "section": "Performance improvements" },
{ "type": "revert", "section": "Reverts" },
{ "type": "refactor", "section": "Refactorings" },
{ "type": "build", "section": "Build" },
{ "type": "ci", "hidden": true },
{ "type": "test", "hidden": true },
{ "type": "chore", "hidden": true },
{ "type": "docs", "hidden": true }
]
}

@ -0,0 +1,98 @@
SHELL := /bin/bash
BASE_PATH := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
VERSION ?= $(shell git describe --tags --always --match=v* 2> /dev/null || \
cat $(CURDIR)/.version 2> /dev/null || echo v0)
VERSION_HASH = $(shell git rev-parse HEAD)
BIN = $(BASE_PATH)/bin
PATH := $(BIN):$(PATH)
export PATH
# printing
V = 0
Q = $(if $(filter 1,$V),,@)
M = $(shell printf "\033[34;1m▶\033[0m")
GO = GOGC=off go
# go module
MODULE = $(shell env GO111MODULE=on $(GO) list -m)
DATE ?= $(shell date +%FT%T%z)
VERSION ?= $(shell git describe --tags --always --match=v* 2> /dev/null || \
cat $(CURDIR)/.version 2> /dev/null || echo v0)
VERSION_HASH = $(shell git rev-parse HEAD)
BRANCH = $(shell git rev-parse --abbrev-ref HEAD)
LDFLAGS += -X "$(MODULE)/varsion.Version=$(VERSION)" -X "$(MODULE)/varsion.CommitSHA=$(VERSION_HASH)"
# tools
$(BIN):
@mkdir -p $@
$(BIN)/%: | $(BIN) ; $(info $(M) installing $(PACKAGE))
$Q env GOBIN=$(BIN) $(GO) install $(PACKAGE)
GOLANGCI_LINT = $(BIN)/golangci-lint
$(BIN)/golangci-lint: PACKAGE=github.com/golangci/golangci-lint/cmd/golangci-lint@v1.37.1
GOIMPORTS = $(BIN)/goimports
$(BIN)/goimports: PACKAGE=golang.org/x/tools/cmd/goimports@v0.1.0
RICE = $(BIN)/rice
$(BIN)/rice: PACKAGE=github.com/GeertJohan/go.rice/rice@v1.0.2
## build: Build
.PHONY: build
build: | build-frontend build-backend ; $(info $(M) building)
## build-frontend: Build frontend
.PHONY: build-frontend
build-frontend: | ; $(info $(M) building frontend)
$Q cd frontend && npm ci && npm run build
## build-backend: Build backend
.PHONY: build-backend
build-backend: | $(RICE) ; $(info $(M) building backend)
$Q cd ./http && rm -rf rice-box.go && $(RICE) embed-go
$Q $(GO) build -ldflags '$(LDFLAGS)' -o filebrowser
## test: Run all tests
.PHONY: test
test: | test-frontend test-backend ; $(info $(M) running tests)
## test-frontend: Run frontend tests
.PHONY: test-frontend
test-frontend: | ; $(info $(M) running frontend tests)
## test-backend: Run backend tests
.PHONY: test-backend
test-backend: | $(RICE) ; $(info $(M) running backend tests)
$Q $(GO) test -v ./...
## lint: Lint
.PHONY: lint
lint: lint-frontend lint-backend lint-commits | ; $(info $(M) running all linters)
## lint-frontend: Lint frontend
.PHONY: lint-frontend
lint-frontend: | ; $(info $(M) running frontend linters)
$Q cd frontend && npm ci && npm run lint
## lint-backend: Lint backend
.PHONY: lint-backend
lint-backend: | $(GOLANGCI_LINT) ; $(info $(M) running backend linters)
$Q $(GOLANGCI_LINT) run
## lint-commits: Lint commits
.PHONY: lint-commits
lint-commits: | ; $(info $(M) running commitlint)
$Q ./scripts/commitlint.sh
## bump-version: Bump app version
.PHONY: bump-version
bump-version: | ; $(info $(M) creating a new release)
$Q ./scripts/bump_version.sh
## help: Show this help
.PHONY: help
help:
@sed -n 's/^## //p' $(MAKEFILE_LIST) | column -t -s ':' | sed -e 's/^/ /' | sort

@ -40,7 +40,7 @@ func (a JSONAuth) Auth(r *http.Request, sto users.Store, root string) (*users.Us
// If ReCaptcha is enabled, check the code.
if a.ReCaptcha != nil && len(a.ReCaptcha.Secret) > 0 {
ok, err := a.ReCaptcha.Ok(cred.ReCaptcha) //nolint:shadow
ok, err := a.ReCaptcha.Ok(cred.ReCaptcha) //nolint:govet
if err != nil {
return nil, err

@ -14,7 +14,7 @@ var cmdsAddCmd = &cobra.Command{
Use: "add <event> <command>",
Short: "Add a command to run on a specific event",
Long: `Add a command to run on a specific event.`,
Args: cobra.MinimumNArgs(2), //nolint:mnd
Args: cobra.MinimumNArgs(2), //nolint:gomnd
Run: python(func(cmd *cobra.Command, args []string, d pythonData) {
s, err := d.store.Settings.Get()
checkErr(err)

@ -23,7 +23,7 @@ You can also specify an optional parameter (index_end) so
you can remove all commands from 'index' to 'index_end',
including 'index_end'.`,
Args: func(cmd *cobra.Command, args []string) error {
if err := cobra.RangeArgs(2, 3)(cmd, args); err != nil { //nolint:mnd
if err := cobra.RangeArgs(2, 3)(cmd, args); err != nil { //nolint:gomnd
return err
}
@ -43,7 +43,7 @@ including 'index_end'.`,
i, err := strconv.Atoi(args[1])
checkErr(err)
f := i
if len(args) == 3 { //nolint:mnd
if len(args) == 3 { //nolint:gomnd
f, err = strconv.Atoi(args[2])
checkErr(err)
}

@ -152,12 +152,15 @@ user created with the credentials from options "username" and "password".`,
err = os.Chmod(server.Socket, os.FileMode(socketPerm))
checkErr(err)
case server.TLSKey != "" && server.TLSCert != "":
cer, err := tls.LoadX509KeyPair(server.TLSCert, server.TLSKey) //nolint:shadow
cer, err := tls.LoadX509KeyPair(server.TLSCert, server.TLSKey) //nolint:govet
checkErr(err)
listener, err = tls.Listen("tcp", adr, &tls.Config{Certificates: []tls.Certificate{cer}}) //nolint:shadow
listener, err = tls.Listen("tcp", adr, &tls.Config{
MinVersion: tls.VersionTLS12,
Certificates: []tls.Certificate{cer}},
)
checkErr(err)
default:
listener, err = net.Listen("tcp", adr) //nolint:shadow
listener, err = net.Listen("tcp", adr)
checkErr(err)
}

@ -44,7 +44,7 @@ including 'index_end'.`,
i, err := strconv.Atoi(args[0])
checkErr(err)
f := i
if len(args) == 2 { //nolint:mnd
if len(args) == 2 { //nolint:gomnd
f, err = strconv.Atoi(args[1])
checkErr(err)
}

@ -15,7 +15,7 @@ var usersAddCmd = &cobra.Command{
Use: "add <username> <password>",
Short: "Create a new user",
Long: `Create a new user and add it to the database.`,
Args: cobra.ExactArgs(2), //nolint:mnd
Args: cobra.ExactArgs(2), //nolint:gomnd
Run: python(func(cmd *cobra.Command, args []string, d pythonData) {
s, err := d.store.Settings.Get()
checkErr(err)

@ -67,7 +67,7 @@ list or set it to 0.`,
// with the new username. If there is, print an error and cancel the
// operation
if user.Username != onDB.Username {
if conflictuous, err := d.store.Users.Get("", user.Username); err == nil { //nolint:shadow
if conflictuous, err := d.store.Users.Get("", user.Username); err == nil { //nolint:govet
checkErr(usernameConflictError(user.Username, conflictuous.ID, user.ID))
}
}

@ -72,7 +72,7 @@ func dbExists(path string) (bool, error) {
d := filepath.Dir(path)
_, err = os.Stat(d)
if os.IsNotExist(err) {
if err := os.MkdirAll(d, 0700); err != nil { //nolint:shadow
if err := os.MkdirAll(d, 0700); err != nil { //nolint:govet
return false, err
}
return false, nil

@ -0,0 +1,34 @@
module.exports = {
rules: {
'body-leading-blank': [1, 'always'],
'body-max-line-length': [2, 'always', 100],
'footer-leading-blank': [1, 'always'],
'footer-max-line-length': [2, 'always', 100],
'header-max-length': [2, 'always', 100],
'scope-case': [2, 'always', 'lower-case'],
'subject-case': [
2,
'never',
['sentence-case', 'start-case', 'pascal-case', 'upper-case'],
],
'subject-full-stop': [2, 'never', '.'],
'type-case': [2, 'always', 'lower-case'],
'type-empty': [2, 'never'],
'type-enum': [
2,
'always',
[
'feat',
'fix',
'perf',
'revert',
'refactor',
'build',
'ci',
'test',
'chore',
'docs',
],
],
},
};

@ -79,7 +79,7 @@ func NewFileInfo(opts FileOptions) (*FileInfo, error) {
if opts.Expand {
if file.IsDir {
if err := file.readListing(opts.Checker, opts.ReadHeader); err != nil { //nolint:shadow
if err := file.readListing(opts.Checker, opts.ReadHeader); err != nil { //nolint:govet
return nil, err
}
return file, nil

@ -32,7 +32,7 @@ func wsErr(ws *websocket.Conn, r *http.Request, status int, err error) { //nolin
if err != nil || status >= 400 {
log.Printf("%s: %v %s %v", r.URL.Path, status, r.RemoteAddr, err)
}
if err := ws.WriteControl(websocket.CloseInternalServerErr, []byte(txt), time.Now().Add(WSWriteDeadline)); err != nil { //nolint:shadow
if err := ws.WriteControl(websocket.CloseInternalServerErr, []byte(txt), time.Now().Add(WSWriteDeadline)); err != nil {
log.Print(err)
}
}
@ -47,7 +47,7 @@ var commandsHandler = withUser(func(w http.ResponseWriter, r *http.Request, d *d
var raw string
for {
_, msg, err := conn.ReadMessage() //nolint:shadow
_, msg, err := conn.ReadMessage() //nolint:govet
if err != nil {
wsErr(conn, r, http.StatusInternalServerError, err)
return 0, nil
@ -60,7 +60,7 @@ var commandsHandler = withUser(func(w http.ResponseWriter, r *http.Request, d *d
}
if !d.server.EnableExec || !d.user.CanExecute(strings.Split(raw, " ")[0]) {
if err := conn.WriteMessage(websocket.TextMessage, cmdNotAllowed); err != nil { //nolint:shadow
if err := conn.WriteMessage(websocket.TextMessage, cmdNotAllowed); err != nil { //nolint:govet
wsErr(conn, r, http.StatusInternalServerError, err)
}
@ -69,7 +69,7 @@ var commandsHandler = withUser(func(w http.ResponseWriter, r *http.Request, d *d
command, err := runner.ParseCommand(d.settings, raw)
if err != nil {
if err := conn.WriteMessage(websocket.TextMessage, []byte(err.Error())); err != nil { //nolint:shadow
if err := conn.WriteMessage(websocket.TextMessage, []byte(err.Error())); err != nil { //nolint:govet
wsErr(conn, r, http.StatusInternalServerError, err)
}
return 0, nil

@ -70,7 +70,7 @@ func TestPublicShareHandlerAuthentication(t *testing.T) {
}
t.Cleanup(func() {
if err := db.Close(); err != nil { //nolint:shadow
if err := db.Close(); err != nil { //nolint:govet
t.Errorf("failed to close db: %v", err)
}
})

@ -33,7 +33,7 @@ func parseQueryFiles(r *http.Request, f *files.FileInfo, _ *users.User) ([]strin
fileSlice = append(fileSlice, f.Path)
} else {
for _, name := range names {
name, err := url.QueryUnescape(strings.Replace(name, "+", "%2B", -1)) //nolint:shadow
name, err := url.QueryUnescape(strings.Replace(name, "+", "%2B", -1)) //nolint:govet
if err != nil {
return nil, err
}

@ -46,7 +46,7 @@ func handleWithStaticData(w http.ResponseWriter, _ *http.Request, d *data, box *
if d.settings.Branding.Files != "" {
fPath := filepath.Join(d.settings.Branding.Files, "custom.css")
_, err := os.Stat(fPath) //nolint:shadow
_, err := os.Stat(fPath) //nolint:govet
if err != nil && !os.IsNotExist(err) {
log.Printf("couldn't load custom styles: %v", err)
@ -58,7 +58,7 @@ func handleWithStaticData(w http.ResponseWriter, _ *http.Request, d *data, box *
}
if d.settings.AuthMethod == auth.MethodJSONAuth {
raw, err := d.store.Auth.Get(d.settings.AuthMethod) //nolint:shadow
raw, err := d.store.Auth.Get(d.settings.AuthMethod) //nolint:govet
if err != nil {
return http.StatusInternalServerError, err
}

@ -0,0 +1,14 @@
#!/usr/bin/env bash
set -e
if ! [ -x "$(command -v standard-version)" ]; then
echo "standard-version is not installed. please run 'npm i -g standard-version'"
exit 1
fi
standard-version --dry-run --skip
read -p "Continue (y/n)? " -n 1 -r
echo ;
if [[ $REPLY =~ ^[Yy]$ ]]; then
standard-version -s ;
fi

@ -0,0 +1,11 @@
#!/usr/bin/env bash
set -e
if ! [ -x "$(command -v commitlint)" ]; then
echo "commitlint is not installed. please run 'npm i -g commitlint'"
exit 1
fi
for commit_hash in $(git log --pretty=format:%H origin/master..HEAD); do
commitlint -f ${commit_hash}~1 -t ${commit_hash}
done

@ -63,7 +63,7 @@ func (s *Storage) Gets(baseScope string) ([]*User, error) {
}
for _, user := range users {
if err := user.Clean(baseScope); err != nil { //nolint:shadow
if err := user.Clean(baseScope); err != nil { //nolint:govet
return nil, err
}
}

@ -1,129 +0,0 @@
#!/usr/bin/env sh
set -e
untracked="(untracked)"
REPO=$(cd $(dirname $0); pwd)
COMMIT_SHA=$(git rev-parse --short HEAD)
ASSETS="false"
BINARY="false"
RELEASE=""
debugInfo () {
echo "Repo: $REPO"
echo "Build assets: $ASSETS"
echo "Build binary: $BINARY"
echo "Release: $RELEASE"
}
buildAssets () {
cd $REPO
rm -rf frontend/dist
rm -f http/rice-box.go
cd $REPO/frontend
if [ "$CI" = "true" ]; then
npm ci
else
npm install
fi
npm run lint
npm run build
}
buildBinary () {
if ! [ -x "$(command -v rice)" ]; then
go install github.com/GeertJohan/go.rice/rice
fi
cd $REPO/http
rm -rf rice-box.go
rice embed-go
cd $REPO
go build -a -o filebrowser -ldflags "-s -w -X github.com/filebrowser/filebrowser/v2/version.CommitSHA=$COMMIT_SHA"
}
release () {
cd $REPO
echo "👀 Checking semver format"
if [ $# -ne 1 ]; then
echo "❌ This release script requires a single argument corresponding to the semver to be released. See semver.org"
exit 1
fi
GREP="grep"
if [ -x "$(command -v ggrep)" ]; then
GREP="ggrep"
fi
semver=$(echo "$1" | $GREP -P '^v(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)')
if [ $? -ne 0 ]; then
echo "❌ Not valid semver format. See semver.org"
exit 1
fi
echo "🧼 Tidying up go modules"
go mod tidy
echo "🐑 Creating a new commit for the new release"
git commit --allow-empty -am "chore: version $semver"
git tag "$1"
git push
git push --tags origin
echo "📦 Done! $semver released."
}
usage() {
echo "Usage: $0 [-a] [-c] [-b] [-r <string>]" 1>&2;
exit 1;
}
DEBUG="false"
while getopts "bacr:d" o; do
case "${o}" in
b)
ASSETS="true"
BINARY="true"
;;
a)
ASSETS="true"
;;
c)
BINARY="true"
;;
r)
RELEASE=${OPTARG}
;;
d)
DEBUG="true"
;;
*)
usage
;;
esac
done
shift $((OPTIND-1))
if [ "$DEBUG" = "true" ]; then
debugInfo
fi
if [ "$ASSETS" = "true" ]; then
buildAssets
fi
if [ "$BINARY" = "true" ]; then
buildBinary
fi
if [ "$RELEASE" != "" ]; then
release $RELEASE
fi
Loading…
Cancel
Save