From 835fbb9ef6cb918f7066b1b644c5e8e6a25608fc Mon Sep 17 00:00:00 2001 From: Joona Hoikkala Date: Mon, 11 Jan 2021 17:31:09 +0200 Subject: [PATCH] Migrate to GitHub actions for coverage & unit test automation (#251) --- .github/workflows/go_cov.yml | 33 +++++++++++++++++++++++++++++ .github/workflows/golangci-lint.yml | 25 ++++++++++++++++++++++ .travis.yml | 13 ------------ api.go | 10 ++++----- api_test.go | 12 ++--------- auth.go | 2 +- db.go | 22 +++++++++---------- dns.go | 10 +++------ dns_test.go | 3 --- main.go | 5 ++--- main_test.go | 2 +- types.go | 3 --- util.go | 4 ++-- util_test.go | 4 ++-- validation.go | 4 +--- 15 files changed, 88 insertions(+), 64 deletions(-) create mode 100644 .github/workflows/go_cov.yml create mode 100644 .github/workflows/golangci-lint.yml delete mode 100644 .travis.yml diff --git a/.github/workflows/go_cov.yml b/.github/workflows/go_cov.yml new file mode 100644 index 0000000..2c185c3 --- /dev/null +++ b/.github/workflows/go_cov.yml @@ -0,0 +1,33 @@ +name: Go +on: + push: + pull_request: + schedule: + # Run every 12 hours, at the 15 minute mark. E.g. + # 2020-11-29 00:15:00 UTC, 2020-11-29 12:15:00 UTC, 2020-11-30 00:15:00 UTC + - cron: '15 */12 * * *' +jobs: + + build: + name: Build and Unit Test + runs-on: ubuntu-latest + steps: + + - name: Set up Go + uses: actions/setup-go@v2 + with: + go-version: ^1.13 + + - name: Check out code + uses: actions/checkout@v2 + + - name: Build + run: go build -v ./... + + - name: Test + run: go test -v -race -covermode=atomic -coverprofile=coverage.out ./... + + - name: Upload Coverage + uses: shogo82148/actions-goveralls@v1 + with: + path-to-profile: coverage.out diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml new file mode 100644 index 0000000..12323d1 --- /dev/null +++ b/.github/workflows/golangci-lint.yml @@ -0,0 +1,25 @@ +name: golangci-lint +on: + push: + tags: + - v* + branches: + - master + pull_request: + schedule: + # Run every 12 hours, at the 15 minute mark. E.g. + # 2020-11-29 00:15:00 UTC, 2020-11-29 12:15:00 UTC, 2020-11-30 00:15:00 UTC + - cron: '15 */12 * * *' +jobs: + golangci: + name: Lint Sourcecode + runs-on: ubuntu-latest + steps: + + - name: Check out code + uses: actions/checkout@v2 + + - name: Run golangci-lint + uses: golangci/golangci-lint-action@v2 + with: + version: v1.35 diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index bf0c4bf..0000000 --- a/.travis.yml +++ /dev/null @@ -1,13 +0,0 @@ -language: go -go: - - 1.13 -env: - - "PATH=/home/travis/gopath/bin:$PATH" -before_install: - - go get golang.org/x/lint/golint - - go get github.com/mattn/goveralls -script: - - go vet - - golint -set_exit_status - - go test -race -v - - $HOME/gopath/bin/goveralls -ignore main.go -v -service=travis-ci diff --git a/api.go b/api.go index edff337..864256c 100644 --- a/api.go +++ b/api.go @@ -25,14 +25,14 @@ func webRegisterPost(w http.ResponseWriter, r *http.Request, _ httprouter.Params var err error aTXT := ACMETxt{} bdata, _ := ioutil.ReadAll(r.Body) - if bdata != nil && len(bdata) > 0 { + if len(bdata) > 0 { err = json.Unmarshal(bdata, &aTXT) if err != nil { regStatus = http.StatusBadRequest reg = jsonError("malformed_json_payload") w.Header().Set("Content-Type", "application/json") w.WriteHeader(regStatus) - w.Write(reg) + _, _ = w.Write(reg) return } } @@ -44,7 +44,7 @@ func webRegisterPost(w http.ResponseWriter, r *http.Request, _ httprouter.Params reg = jsonError("invalid_allowfrom_cidr") w.Header().Set("Content-Type", "application/json") w.WriteHeader(regStatus) - w.Write(reg) + _, _ = w.Write(reg) return } @@ -68,7 +68,7 @@ func webRegisterPost(w http.ResponseWriter, r *http.Request, _ httprouter.Params } w.Header().Set("Content-Type", "application/json") w.WriteHeader(regStatus) - w.Write(reg) + _, _ = w.Write(reg) } func webUpdatePost(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { @@ -104,7 +104,7 @@ func webUpdatePost(w http.ResponseWriter, r *http.Request, _ httprouter.Params) } w.Header().Set("Content-Type", "application/json") w.WriteHeader(updStatus) - w.Write(upd) + _, _ = w.Write(upd) } // Endpoint used to check the readiness and/or liveness (health) of the server. diff --git a/api_test.go b/api_test.go index b7cfd0e..119ab98 100644 --- a/api_test.go +++ b/api_test.go @@ -325,10 +325,6 @@ func TestApiUpdateWithCredentialsMockDB(t *testing.T) { func TestApiManyUpdateWithCredentials(t *testing.T) { validTxtData := "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - updateJSON := map[string]interface{}{ - "subdomain": "", - "txt": ""} - router := setupRouter(true, false) server := httptest.NewServer(router) defer server.Close() @@ -370,7 +366,7 @@ func TestApiManyUpdateWithCredentials(t *testing.T) { {newUserWithValidCIDR.Username.String(), newUserWithValidCIDR.Password, newUserWithValidCIDR.Subdomain, validTxtData, 200}, {newUser.Username.String(), "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", newUser.Subdomain, validTxtData, 401}, } { - updateJSON = map[string]interface{}{ + updateJSON := map[string]interface{}{ "subdomain": test.subdomain, "txt": test.txt} e.POST("/update"). @@ -385,10 +381,6 @@ func TestApiManyUpdateWithCredentials(t *testing.T) { func TestApiManyUpdateWithIpCheckHeaders(t *testing.T) { - updateJSON := map[string]interface{}{ - "subdomain": "", - "txt": ""} - router := setupRouter(false, false) server := httptest.NewServer(router) defer server.Close() @@ -425,7 +417,7 @@ func TestApiManyUpdateWithIpCheckHeaders(t *testing.T) { {newUserWithIP6CIDR, "2002:c0a7:0ff::0", 401}, {newUserWithIP6CIDR, "2002:c0a8:d3ad:b33f:c0ff:33b4:dc0d:3b4d", 200}, } { - updateJSON = map[string]interface{}{ + updateJSON := map[string]interface{}{ "subdomain": test.user.Subdomain, "txt": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"} e.POST("/update"). diff --git a/auth.go b/auth.go index 162f927..c09f8b4 100644 --- a/auth.go +++ b/auth.go @@ -50,7 +50,7 @@ func Auth(update httprouter.Handle) httprouter.Handle { } else { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusUnauthorized) - w.Write(jsonError("forbidden")) + _, _ = w.Write(jsonError("forbidden")) } } } diff --git a/db.go b/db.go index 358bde7..3534728 100644 --- a/db.go +++ b/db.go @@ -50,7 +50,7 @@ var txtTablePG = ` // getSQLiteStmt replaces all PostgreSQL prepared statement placeholders (eg. $1, $2) with SQLite variant "?" func getSQLiteStmt(s string) string { - re, _ := regexp.Compile("\\$[0-9]") + re, _ := regexp.Compile(`\$[0-9]`) return re.ReplaceAllString(s, "?") } @@ -68,12 +68,12 @@ func (d *acmedb) Init(engine string, connection string) error { if versionString == "" { versionString = "0" } - _, err = d.DB.Exec(acmeTable) - _, err = d.DB.Exec(userTable) + _, _ = d.DB.Exec(acmeTable) + _, _ = d.DB.Exec(userTable) if Config.Database.Engine == "sqlite3" { - _, err = d.DB.Exec(txtTable) + _, _ = d.DB.Exec(txtTable) } else { - _, err = d.DB.Exec(txtTablePG) + _, _ = d.DB.Exec(txtTablePG) } // If everything is fine, handle db upgrade tasks if err == nil { @@ -136,10 +136,10 @@ func (d *acmedb) handleDBUpgradeTo1() error { // Rollback if errored, commit if not defer func() { if err != nil { - tx.Rollback() + _ = tx.Rollback() return } - tx.Commit() + _ = tx.Commit() }() _, _ = tx.Exec("DELETE FROM txt") for _, subdomain := range subdomains { @@ -165,8 +165,8 @@ func (d *acmedb) handleDBUpgradeTo1() error { func (d *acmedb) NewTXTValuesInTransaction(tx *sql.Tx, subdomain string) error { var err error instr := fmt.Sprintf("INSERT INTO txt (Subdomain, LastUpdate) values('%s', 0)", subdomain) - _, err = tx.Exec(instr) - _, err = tx.Exec(instr) + _, _ = tx.Exec(instr) + _, _ = tx.Exec(instr) return err } @@ -178,10 +178,10 @@ func (d *acmedb) Register(afrom cidrslice) (ACMETxt, error) { // Rollback if errored, commit if not defer func() { if err != nil { - tx.Rollback() + _ = tx.Rollback() return } - tx.Commit() + _ = tx.Commit() }() a := newACMETxt() a.AllowFrom = cidrslice(afrom.ValidEntries()) diff --git a/dns.go b/dns.go index 1a7e0e0..a01fb9c 100644 --- a/dns.go +++ b/dns.go @@ -108,7 +108,7 @@ func (d *DNSServer) handleRequest(w dns.ResponseWriter, r *dns.Msg) { d.readQuery(m) } } - w.WriteMsg(m) + _ = w.WriteMsg(m) } func (d *DNSServer) readQuery(m *dns.Msg) { @@ -119,9 +119,7 @@ func (d *DNSServer) readQuery(m *dns.Msg) { authoritative = auth } m.MsgHdr.Rcode = rc - for _, r := range rr { - m.Answer = append(m.Answer, r) - } + m.Answer = append(m.Answer, rr...) } } m.MsgHdr.Authoritative = authoritative @@ -208,9 +206,7 @@ func (d *DNSServer) answer(q dns.Question) ([]dns.RR, int, bool, error) { txtRRs, err = d.answerTXT(q) } if err == nil { - for _, txtRR := range txtRRs { - r = append(r, txtRR) - } + r = append(r, txtRRs...) } } if len(r) > 0 { diff --git a/dns_test.go b/dns_test.go index aca82bb..ba42a5d 100644 --- a/dns_test.go +++ b/dns_test.go @@ -11,9 +11,6 @@ import ( "github.com/miekg/dns" ) -var resolv resolver -var server *dns.Server - type resolver struct { server string } diff --git a/main.go b/main.go index e93f465..6ef56f2 100644 --- a/main.go +++ b/main.go @@ -92,13 +92,12 @@ func main() { go startHTTPAPI(errChan, Config, dnsservers) // block waiting for error - select { - case err = <-errChan: + for { + err = <-errChan if err != nil { log.Fatal(err) } } - log.Debugf("Shutting down...") } func startHTTPAPI(errChan chan error, config DNSConfig, dnsservers []*DNSServer) { diff --git a/main_test.go b/main_test.go index a8642a0..66f4d6e 100644 --- a/main_test.go +++ b/main_test.go @@ -56,7 +56,7 @@ func TestMain(m *testing.M) { go dnsserver.Start(make(chan error, 1)) wg.Wait() exitval := m.Run() - dnsserver.Server.Shutdown() + _ = dnsserver.Server.Shutdown() DB.Close() os.Exit(exitval) } diff --git a/types.go b/types.go index 235b72a..f99b84d 100644 --- a/types.go +++ b/types.go @@ -21,9 +21,6 @@ type DNSConfig struct { Logconfig logconfig } -// Auth middleware -type authMiddleware struct{} - // Config file general section type general struct { Listen string diff --git a/util.go b/util.go index c835a0d..163683d 100644 --- a/util.go +++ b/util.go @@ -59,13 +59,13 @@ func prepareConfig(conf DNSConfig) (DNSConfig, error) { func sanitizeString(s string) string { // URL safe base64 alphabet without padding as defined in ACME - re, _ := regexp.Compile("[^A-Za-z\\-\\_0-9]+") + re, _ := regexp.Compile(`[^A-Za-z\-\_0-9]+`) return re.ReplaceAllString(s, "") } func sanitizeIPv6addr(s string) string { // Remove brackets from IPv6 addresses, net.ParseCIDR needs this - re, _ := regexp.Compile("[\\[\\]]+") + re, _ := regexp.Compile(`[\[\]]+`) return re.ReplaceAllString(s, "") } diff --git a/util_test.go b/util_test.go index 4aecf00..1eb4b67 100644 --- a/util_test.go +++ b/util_test.go @@ -104,11 +104,11 @@ func TestFileCheckPermissionDenied(t *testing.T) { t.Error("Could not create temporary file") } defer os.Remove(tmpfile.Name()) - syscall.Chmod(tmpfile.Name(), 0000) + _ = syscall.Chmod(tmpfile.Name(), 0000) if fileIsAccessible(tmpfile.Name()) { t.Errorf("File should not be accessible") } - syscall.Chmod(tmpfile.Name(), 0644) + _ = syscall.Chmod(tmpfile.Name(), 0644) } func TestFileCheckNotExists(t *testing.T) { diff --git a/validation.go b/validation.go index df39e85..2cec5a9 100644 --- a/validation.go +++ b/validation.go @@ -2,11 +2,10 @@ package main import ( "unicode/utf8" + "regexp" "github.com/google/uuid" "golang.org/x/crypto/bcrypt" - - "regexp" ) func getValidUsername(u string) (uuid.UUID, error) { @@ -32,7 +31,6 @@ func validSubdomain(s string) bool { return RegExp.MatchString(s) } - func validTXT(s string) bool { sn := sanitizeString(s) if utf8.RuneCountInString(s) == 43 && utf8.RuneCountInString(sn) == 43 {