Skip to content
Snippets Groups Projects
Commit 56312b07 authored by Erick Hitter's avatar Erick Hitter
Browse files

Merge branch 'add/ci' into 'master'

Add CI

Closes #5

See merge request !1
parents d21051d6 c91dc6b3
Branches
No related tags found
1 merge request!1Add CI
Pipeline #579 passed
image: containers.ethitter.com:443/docker/images/golang:latest
variables:
REPO_NAME: git.ethitter.com/open-source/dyndnsd-client
cache:
paths:
- /apt-cache
- $GOPATH/src/github.com
- $GOPATH/src/golang.org
- $GOPATH/src/google.golang.org
- $GOPATH/src/gopkg.in
stages:
- test
- build
before_script:
- mkdir -p $GOPATH/src/$(dirname $REPO_NAME)
- cp -R $CI_PROJECT_DIR $GOPATH/src/$REPO_NAME
- cd $GOPATH/src/$REPO_NAME
- cp config-sample.json config.json
- export CC=clang-5.0
- make dep
unit_tests:
stage: test
script:
- make test
race_detector:
stage: test
script:
- make race
memory_sanitizer:
stage: test
script:
- make msan
code_coverage:
stage: test
script:
- make coverage
code_coverage_report:
stage: test
script:
- make coverhtml
only:
- master
lint_code:
stage: test
script:
- make lint
build:
stage: build
script:
- make
artifacts:
paths:
- dyndnsd-client/
\ No newline at end of file
Makefile 0 → 100644
PROJECT_NAME := "dyndnsd-client"
PKG := "git.ethitter.com/debian/$(PROJECT_NAME)"
PKG_LIST := $(shell go list ${PKG}/... | grep -v /vendor/)
GO_FILES := $(shell find . -name '*.go' | grep -v /vendor/ | grep -v _test.go)
.PHONY: all dep build clean test coverage coverhtml lint
all: build
lint:
@golint -set_exit_status ${PKG_LIST}
test:
@go test -v ${PKG_LIST}
race: dep
@go test -v -race ${PKG_LIST}
msan: dep
@go test -v -msan ${PKG_LIST}
coverage:
./tools/coverage.sh;
coverhtml:
./tools/coverage.sh html;
dep:
@go get -v -d ./...
@go get github.com/mitchellh/gox
build: dep
@gox -output="${CI_PROJECT_DIR}/${PROJECT_NAME}/{{.Dir}}_{{.OS}}_{{.Arch}}" -parallel=6
clean:
@rm -f $(PROJECT_NAME)
help:
@grep -h -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
`dyndnsd-client` `dyndnsd-client` [![pipeline status](https://git.ethitter.com/open-source/dyndnsd-client/badges/master/pipeline.svg)](https://git.ethitter.com/open-source/dyndnsd-client/commits/master)
================ ================
Client for the [`dyndnsd`](https://github.com/cmur2/dyndnsd) daemon. Set up `dyndnsd` first, otherwise this is useless. Client for the [`dyndnsd`](https://github.com/cmur2/dyndnsd) daemon. Set up `dyndnsd` first, otherwise this is useless.
......
...@@ -35,7 +35,7 @@ func init() { ...@@ -35,7 +35,7 @@ func init() {
flag.Parse() flag.Parse()
if _, err := os.Stat(configPath); os.IsNotExist(err) { if _, err := os.Stat(configPath); os.IsNotExist(err) {
fmt.Println("Config path does not exist. Aborting!\n") fmt.Println("Config path does not exist. Aborting!")
flag.Usage() flag.Usage()
os.Exit(3) os.Exit(3)
} }
...@@ -48,7 +48,7 @@ func init() { ...@@ -48,7 +48,7 @@ func init() {
// Do the update! // Do the update!
func main() { func main() {
// Base URL // Base URL
endpoint, err := buildEndpointUrl() endpoint, err := buildEndpointURL()
if err != nil { if err != nil {
logger.Println("Couldn't build endpoint URL") logger.Println("Couldn't build endpoint URL")
logger.Printf("%s", err) logger.Printf("%s", err)
...@@ -56,16 +56,17 @@ func main() { ...@@ -56,16 +56,17 @@ func main() {
} }
// IPv4 is required // IPv4 is required
if ipv4, err := getUrl(ipv4Endpoint); err == nil { if ipv4, err := getURL(ipv4Endpoint); err == nil {
if ipv4Valid := net.ParseIP(ipv4); ipv4Valid == nil { ipv4Valid := net.ParseIP(ipv4)
if ipv4Valid == nil {
logger.Println("Invalid IPv4 address returned by endpoint") logger.Println("Invalid IPv4 address returned by endpoint")
logger.Printf("%s", err) logger.Printf("%s", err)
return return
} else {
query := endpoint.Query()
query.Set("myip", ipv4Valid.String())
endpoint.RawQuery = query.Encode()
} }
query := endpoint.Query()
query.Set("myip", ipv4Valid.String())
endpoint.RawQuery = query.Encode()
} else { } else {
logger.Println("Couldn't retrieve IPv4 address") logger.Println("Couldn't retrieve IPv4 address")
logger.Printf("%s", err) logger.Printf("%s", err)
...@@ -75,7 +76,7 @@ func main() { ...@@ -75,7 +76,7 @@ func main() {
// IPv6 is optional // IPv6 is optional
// Leave empty to skip // Leave empty to skip
if len(ipv6Endpoint) > 0 { if len(ipv6Endpoint) > 0 {
if ipv6, err := getUrl(ipv6Endpoint); err == nil { if ipv6, err := getURL(ipv6Endpoint); err == nil {
if ipv6Valid := net.ParseIP(ipv6); ipv6Valid == nil { if ipv6Valid := net.ParseIP(ipv6); ipv6Valid == nil {
logger.Println("Invalid IPv6 address returned by endpoint") logger.Println("Invalid IPv6 address returned by endpoint")
logger.Printf("%s", err) logger.Printf("%s", err)
...@@ -103,7 +104,7 @@ func main() { ...@@ -103,7 +104,7 @@ func main() {
} }
// Send the update // Send the update
dyndns, err := getUrl(endpoint.String()) dyndns, err := getURL(endpoint.String())
if err != nil { if err != nil {
logger.Println("Couldn't update dyndnsd endpoint") logger.Println("Couldn't update dyndnsd endpoint")
logger.Printf("%s", err) logger.Printf("%s", err)
...@@ -115,7 +116,7 @@ func main() { ...@@ -115,7 +116,7 @@ func main() {
} }
// Build endpoint URL from configuration // Build endpoint URL from configuration
func buildEndpointUrl() (*url.URL, error) { func buildEndpointURL() (*url.URL, error) {
var username string var username string
var password string var password string
var protocol string var protocol string
...@@ -132,27 +133,27 @@ func buildEndpointUrl() (*url.URL, error) { ...@@ -132,27 +133,27 @@ func buildEndpointUrl() (*url.URL, error) {
cfg.Get("path", &path) cfg.Get("path", &path)
cfg.Get("dns_hostname", &hostname) cfg.Get("dns_hostname", &hostname)
daemonUrl, err := url.Parse("") daemonURL, err := url.Parse("")
if err != nil { if err != nil {
return nil, err return nil, err
} }
daemonUrl.Scheme = protocol daemonURL.Scheme = protocol
daemonUrl.Host = fmt.Sprintf("%s:%d", host, port) daemonURL.Host = fmt.Sprintf("%s:%d", host, port)
daemonUrl.Path = path daemonURL.Path = path
userInfo := url.UserPassword(username, password) userInfo := url.UserPassword(username, password)
daemonUrl.User = userInfo daemonURL.User = userInfo
query := daemonUrl.Query() query := daemonURL.Query()
query.Set("hostname", hostname) query.Set("hostname", hostname)
daemonUrl.RawQuery = query.Encode() daemonURL.RawQuery = query.Encode()
return daemonUrl, nil return daemonURL, nil
} }
// Retrieve given URL // Retrieve given URL
func getUrl(url string) (string, error) { func getURL(url string) (string, error) {
resp, err := http.Get(url) resp, err := http.Get(url)
if err != nil { if err != nil {
return "", err return "", err
......
#!/bin/bash
#
# Code coverage generation
COVERAGE_DIR="${COVERAGE_DIR:-coverage}"
PKG_LIST=$(go list ./... | grep -v /vendor/)
# Create the coverage files directory
mkdir -p "$COVERAGE_DIR";
# Create a coverage file for each package
for package in ${PKG_LIST}; do
go test -covermode=count -coverprofile "${COVERAGE_DIR}/${package##*/}.cov" "$package" ;
done ;
# Merge the coverage profile files
echo 'mode: count' > "${COVERAGE_DIR}"/coverage.cov ;
tail -q -n +2 "${COVERAGE_DIR}"/*.cov >> "${COVERAGE_DIR}"/coverage.cov ;
# Display the global code coverage
go tool cover -func="${COVERAGE_DIR}"/coverage.cov ;
# If needed, generate HTML report
if [ "$1" == "html" ]; then
go tool cover -html="${COVERAGE_DIR}"/coverage.cov -o coverage.html ;
fi
# Remove the coverage files directory
rm -rf "$COVERAGE_DIR";
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment