From 86ca819a4ae6b8312fad2e27493f5adff6b365c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BD=D0=B0=D1=80=20=D0=A1=D0=B0=D0=BB=D0=B8?= =?UTF-8?q?=D0=BC=D0=B7=D1=8F=D0=BD=D0=BE=D0=B2?= Date: Thu, 30 Apr 2026 17:38:08 -0700 Subject: [PATCH 01/20] add new line to readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index c2bec0368b7..d7451936e03 100644 --- a/README.md +++ b/README.md @@ -21,3 +21,4 @@ go build -o notely && ./notely *This starts the server in non-database mode.* It will serve a simple webpage at `http://localhost:8080`. You do *not* need to set up a database or any interactivity on the webpage yet. Instructions for that will come later in the course! +MYNAME's version of Boot.dev's Notely app. \ No newline at end of file From a11b599f672ab1bc701de3230e78d5497ac36687 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BD=D0=B0=D1=80=20=D0=A1=D0=B0=D0=BB=D0=B8?= =?UTF-8?q?=D0=BC=D0=B7=D1=8F=D0=BD=D0=BE=D0=B2?= Date: Thu, 30 Apr 2026 17:56:07 -0700 Subject: [PATCH 02/20] add ci:w --- .github/workflows/ci.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000000..be74c5778f7 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,22 @@ +name: ci + +on: + pull_request: + branches: [main] + +jobs: + tests: + name: Tests + runs-on: ubuntu-latest + + steps: + - name: Check out code + uses: actions/checkout@v4 + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: "1.26.0" + + - name: Force Failure + run: (exit 1) \ No newline at end of file From af758f48383499ff13851cc4a762c2d0f865c8c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BD=D0=B0=D1=80=20=D0=A1=D0=B0=D0=BB=D0=B8?= =?UTF-8?q?=D0=BC=D0=B7=D1=8F=D0=BD=D0=BE=D0=B2?= Date: Thu, 30 Apr 2026 18:10:12 -0700 Subject: [PATCH 03/20] update ci file --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index be74c5778f7..409446a910c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,4 +19,4 @@ jobs: go-version: "1.26.0" - name: Force Failure - run: (exit 1) \ No newline at end of file + run: go version \ No newline at end of file From 88ea295950aa13c7292640fab28aac7e16333978 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BD=D0=B0=D1=80=20=D0=A1=D0=B0=D0=BB=D0=B8?= =?UTF-8?q?=D0=BC=D0=B7=D1=8F=D0=BD=D0=BE=D0=B2?= Date: Thu, 30 Apr 2026 18:21:53 -0700 Subject: [PATCH 04/20] adjust step name --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 409446a910c..33a06ebcdf7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,5 +18,5 @@ jobs: with: go-version: "1.26.0" - - name: Force Failure + - name: Echo Go Version run: go version \ No newline at end of file From d0679c7b404ce30bfc1aee69faf10b1f2031f4ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BD=D0=B0=D1=80=20=D0=A1=D0=B0=D0=BB=D0=B8?= =?UTF-8?q?=D0=BC=D0=B7=D1=8F=D0=BD=D0=BE=D0=B2?= Date: Thu, 30 Apr 2026 18:25:03 -0700 Subject: [PATCH 05/20] add new step --- .github/workflows/ci.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 33a06ebcdf7..14406d262de 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,4 +19,7 @@ jobs: go-version: "1.26.0" - name: Echo Go Version - run: go version \ No newline at end of file + run: go version + + - name: Echo artem loh + run: echo artem loh \ No newline at end of file From b673ed5d54feb07d9c0d782028d8667c78e16b4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BD=D0=B0=D1=80=20=D0=A1=D0=B0=D0=BB=D0=B8?= =?UTF-8?q?=D0=BC=D0=B7=D1=8F=D0=BD=D0=BE=D0=B2?= Date: Thu, 30 Apr 2026 18:26:26 -0700 Subject: [PATCH 06/20] delete useless step --- .github/workflows/ci.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 14406d262de..b42470cba38 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,6 +20,3 @@ jobs: - name: Echo Go Version run: go version - - - name: Echo artem loh - run: echo artem loh \ No newline at end of file From 53eeaca2114f5eccd5579e7fe96680723172a93f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BD=D0=B0=D1=80=20=D0=A1=D0=B0=D0=BB=D0=B8?= =?UTF-8?q?=D0=BC=D0=B7=D1=8F=D0=BD=D0=BE=D0=B2?= Date: Thu, 30 Apr 2026 18:55:23 -0700 Subject: [PATCH 07/20] feat: add tests --- internal/auth/get_api_key_test.go | 57 +++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 internal/auth/get_api_key_test.go diff --git a/internal/auth/get_api_key_test.go b/internal/auth/get_api_key_test.go new file mode 100644 index 00000000000..75a1a9685db --- /dev/null +++ b/internal/auth/get_api_key_test.go @@ -0,0 +1,57 @@ +package auth + +import ( + "errors" + "net/http" + "testing" +) + +func TestGetAPIKey(t *testing.T) { + tests := []struct { + name string + headers http.Header + expectedKey string + expectedErr error + }{ + { + name: "No authorization header", + headers: http.Header{}, // пустой заголовок + expectedKey: "", + expectedErr: ErrNoAuthHeaderIncluded, + }, + { + name: "Malformed authorization header", + headers: http.Header{ + "Authorization": []string{"Bearer token"}, + }, + expectedKey: "", + expectedErr: errors.New("malformed authorization header"), + }, + { + name: "Valid authorization header", + headers: http.Header{ + "Authorization": []string{"ApiKey 12345"}, + }, + expectedKey: "12345", + expectedErr: nil, + }, + { + name: "Invalid authorization scheme", + headers: http.Header{ + "Authorization": []string{"Bearer 12345"}, + }, + expectedKey: "", + expectedErr: errors.New("malformed authorization header"), + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + gotKey, gotErr := GetAPIKey(tt.headers) + // Проверяем, что ключ и ошибка совпадают с ожидаемыми значениями + if gotKey != tt.expectedKey || (gotErr != nil && gotErr.Error() != tt.expectedErr.Error()) { + t.Errorf("GetAPIKey() = (%v, %v), want (%v, %v)", gotKey, gotErr, tt.expectedKey, tt.expectedErr) + } + }) + } +} From 8107f4665247cf5ac0cd3d55c18355705ef58139 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BD=D0=B0=D1=80=20=D0=A1=D0=B0=D0=BB=D0=B8?= =?UTF-8?q?=D0=BC=D0=B7=D1=8F=D0=BD=D0=BE=D0=B2?= Date: Sat, 2 May 2026 13:28:58 +0400 Subject: [PATCH 08/20] run go tests --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b42470cba38..a9093606a81 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,5 +18,5 @@ jobs: with: go-version: "1.26.0" - - name: Echo Go Version - run: go version + - name: Run tests + run: go test ./... From 4c21605f2e3fc6265114ed7a209fc09f773fa0b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BD=D0=B0=D1=80=20=D0=A1=D0=B0=D0=BB=D0=B8?= =?UTF-8?q?=D0=BC=D0=B7=D1=8F=D0=BD=D0=BE=D0=B2?= Date: Sat, 2 May 2026 13:32:01 +0400 Subject: [PATCH 09/20] fail tests --- internal/auth/auth.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/internal/auth/auth.go b/internal/auth/auth.go index f969aacf638..8d0b79f7ba9 100644 --- a/internal/auth/auth.go +++ b/internal/auth/auth.go @@ -18,6 +18,8 @@ func GetAPIKey(headers http.Header) (string, error) { if len(splitAuth) < 2 || splitAuth[0] != "ApiKey" { return "", errors.New("malformed authorization header") } + fail := "failing" + return fail, nil - return splitAuth[1], nil + // return splitAuth[1], nil } From 247eb284d2d17bfd5572097adb72cc789bb0ab60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BD=D0=B0=D1=80=20=D0=A1=D0=B0=D0=BB=D0=B8?= =?UTF-8?q?=D0=BC=D0=B7=D1=8F=D0=BD=D0=BE=D0=B2?= Date: Sat, 2 May 2026 13:34:47 +0400 Subject: [PATCH 10/20] fix tests --- internal/auth/auth.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/internal/auth/auth.go b/internal/auth/auth.go index 8d0b79f7ba9..f969aacf638 100644 --- a/internal/auth/auth.go +++ b/internal/auth/auth.go @@ -18,8 +18,6 @@ func GetAPIKey(headers http.Header) (string, error) { if len(splitAuth) < 2 || splitAuth[0] != "ApiKey" { return "", errors.New("malformed authorization header") } - fail := "failing" - return fail, nil - // return splitAuth[1], nil + return splitAuth[1], nil } From 7d44fe5e236c15f2cc850bf4360624f7778bbf43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BD=D0=B0=D1=80=20=D0=A1=D0=B0=D0=BB=D0=B8?= =?UTF-8?q?=D0=BC=D0=B7=D1=8F=D0=BD=D0=BE=D0=B2?= Date: Sat, 2 May 2026 13:43:03 +0400 Subject: [PATCH 11/20] add coverage --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a9093606a81..a4fbd349540 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,4 +19,4 @@ jobs: go-version: "1.26.0" - name: Run tests - run: go test ./... + run: go test ./... -cover From fea0c635b775349d8b88bab348608b7594fab3df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BD=D0=B0=D1=80=20=D0=A1=D0=B0=D0=BB=D0=B8?= =?UTF-8?q?=D0=BC=D0=B7=D1=8F=D0=BD=D0=BE=D0=B2?= Date: Sat, 2 May 2026 13:48:05 +0400 Subject: [PATCH 12/20] add badge --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index d7451936e03..a61d69160f9 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +https://github.com/Salimzyanov-Lenar/learn-cicd-starter/actions/workflows/ci.yml/badge.svg + # learn-cicd-starter (Notely) This repo contains the starter code for the "Notely" application for the "Learn CICD" course on [Boot.dev](https://boot.dev). From 6800d991e4d245a39e0a1236a12d506035293a04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BD=D0=B0=D1=80=20=D0=A1=D0=B0=D0=BB=D0=B8?= =?UTF-8?q?=D0=BC=D0=B7=D1=8F=D0=BD=D0=BE=D0=B2?= Date: Sat, 2 May 2026 14:15:03 +0400 Subject: [PATCH 13/20] add style job and try to fail it --- .github/workflows/ci.yml | 18 ++++++++++++++++++ internal/auth/auth.go | 2 +- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a4fbd349540..286d74e2d69 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,3 +20,21 @@ jobs: - name: Run tests run: go test ./... -cover + + style: + name: Style + runs-on: ubuntu-latest + + steps: + - name: Check out code + uses: actions/checkout@v4 + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: "1.26.0" + + - name: Run style check + run: | + test -z $(go fmt ./...) + echo $? \ No newline at end of file diff --git a/internal/auth/auth.go b/internal/auth/auth.go index f969aacf638..60925c84f23 100644 --- a/internal/auth/auth.go +++ b/internal/auth/auth.go @@ -9,7 +9,7 @@ import ( var ErrNoAuthHeaderIncluded = errors.New("no authorization header included") // GetAPIKey - -func GetAPIKey(headers http.Header) (string, error) { +func GetAPIKey(headers http.Header) (string, error){ authHeader := headers.Get("Authorization") if authHeader == "" { return "", ErrNoAuthHeaderIncluded From 2e40ed5b943113a18d4417948411d7b7bb4c0f67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BD=D0=B0=D1=80=20=D0=A1=D0=B0=D0=BB=D0=B8?= =?UTF-8?q?=D0=BC=D0=B7=D1=8F=D0=BD=D0=BE=D0=B2?= Date: Sat, 2 May 2026 14:17:07 +0400 Subject: [PATCH 14/20] fix style --- internal/auth/auth.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/auth/auth.go b/internal/auth/auth.go index 60925c84f23..f969aacf638 100644 --- a/internal/auth/auth.go +++ b/internal/auth/auth.go @@ -9,7 +9,7 @@ import ( var ErrNoAuthHeaderIncluded = errors.New("no authorization header included") // GetAPIKey - -func GetAPIKey(headers http.Header) (string, error){ +func GetAPIKey(headers http.Header) (string, error) { authHeader := headers.Get("Authorization") if authHeader == "" { return "", ErrNoAuthHeaderIncluded From 5aaa49ec584cc02836ffbe597b5e166cd97bf4ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BD=D0=B0=D1=80=20=D0=A1=D0=B0=D0=BB=D0=B8?= =?UTF-8?q?=D0=BC=D0=B7=D1=8F=D0=BD=D0=BE=D0=B2?= Date: Sat, 2 May 2026 14:26:51 +0400 Subject: [PATCH 15/20] add staticcheck --- .github/workflows/ci.yml | 8 ++++++++ internal/auth/auth.go | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 286d74e2d69..5a84a735d57 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,7 +34,15 @@ jobs: with: go-version: "1.26.0" + - name: Install staticcheck + run: go install honnef.co/go/tools/cmd/staticcheck@latest + - name: Run style check run: | test -z $(go fmt ./...) + echo $? + + - name: staticcheck + run: | + staticcheck ./... echo $? \ No newline at end of file diff --git a/internal/auth/auth.go b/internal/auth/auth.go index f969aacf638..51955b952aa 100644 --- a/internal/auth/auth.go +++ b/internal/auth/auth.go @@ -21,3 +21,7 @@ func GetAPIKey(headers http.Header) (string, error) { return splitAuth[1], nil } + +func unused() { + /// +} From e9e3187378c9930fa918cbc0c20e9e3f41b59442 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BD=D0=B0=D1=80=20=D0=A1=D0=B0=D0=BB=D0=B8?= =?UTF-8?q?=D0=BC=D0=B7=D1=8F=D0=BD=D0=BE=D0=B2?= Date: Sat, 2 May 2026 14:28:16 +0400 Subject: [PATCH 16/20] fix staticcheck --- internal/auth/auth.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/internal/auth/auth.go b/internal/auth/auth.go index 51955b952aa..f969aacf638 100644 --- a/internal/auth/auth.go +++ b/internal/auth/auth.go @@ -21,7 +21,3 @@ func GetAPIKey(headers http.Header) (string, error) { return splitAuth[1], nil } - -func unused() { - /// -} From 7b5f8cdd026a42ec06399ca1312de5318b0a8b09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BD=D0=B0=D1=80=20=D0=A1=D0=B0=D0=BB=D0=B8?= =?UTF-8?q?=D0=BC=D0=B7=D1=8F=D0=BD=D0=BE=D0=B2?= Date: Sat, 2 May 2026 14:31:05 +0400 Subject: [PATCH 17/20] update steps --- .github/workflows/ci.yml | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5a84a735d57..c462013a620 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,15 +34,13 @@ jobs: with: go-version: "1.26.0" - - name: Install staticcheck - run: go install honnef.co/go/tools/cmd/staticcheck@latest - - name: Run style check run: | test -z $(go fmt ./...) echo $? + + - name: Install staticcheck + run: go install honnef.co/go/tools/cmd/staticcheck@latest - - name: staticcheck - run: | - staticcheck ./... - echo $? \ No newline at end of file + - name: Run staticcheck + run: staticcheck ./... \ No newline at end of file From e65aebb41a8ffaa8c50ac88cb5dc19c24f78fc3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BD=D0=B0=D1=80=20=D0=A1=D0=B0=D0=BB=D0=B8?= =?UTF-8?q?=D0=BC=D0=B7=D1=8F=D0=BD=D0=BE=D0=B2?= Date: Sat, 2 May 2026 14:44:33 +0400 Subject: [PATCH 18/20] add goces --- .github/workflows/ci.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c462013a620..e429e31972a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,6 +20,12 @@ jobs: - name: Run tests run: go test ./... -cover + + - name: Install gosec + run: go install github.com/securego/gosec/v2/cmd/gosec@latest + + - name: Run gosec + run: gosec ./... style: name: Style From 1b1ae782ea934cd299d98b0e3f67415c79053789 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BD=D0=B0=D1=80=20=D0=A1=D0=B0=D0=BB=D0=B8?= =?UTF-8?q?=D0=BC=D0=B7=D1=8F=D0=BD=D0=BE=D0=B2?= Date: Sat, 2 May 2026 14:56:33 +0400 Subject: [PATCH 19/20] fix gosec issues --- json.go | 4 +++- main.go | 16 ++++++++++------ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/json.go b/json.go index 1e6e7985e18..a0f282e06b9 100644 --- a/json.go +++ b/json.go @@ -30,5 +30,7 @@ func respondWithJSON(w http.ResponseWriter, code int, payload interface{}) { return } w.WriteHeader(code) - w.Write(dat) + if _, err := w.Write(dat); err != nil { + log.Printf("write error: %v", err) + } } diff --git a/main.go b/main.go index 19d7366c5f7..641cd3abcb3 100644 --- a/main.go +++ b/main.go @@ -7,6 +7,8 @@ import ( "log" "net/http" "os" + "strconv" + "time" "github.com/go-chi/chi" "github.com/go-chi/cors" @@ -30,9 +32,10 @@ func main() { log.Printf("warning: assuming default configuration. .env unreadable: %v", err) } - port := os.Getenv("PORT") - if port == "" { - log.Fatal("PORT environment variable is not set") + portEnv := os.Getenv("PORT") + port, err := strconv.Atoi(portEnv) + if err != nil { + log.Fatal("Invalid port") } apiCfg := apiConfig{} @@ -89,10 +92,11 @@ func main() { router.Mount("/v1", v1Router) srv := &http.Server{ - Addr: ":" + port, - Handler: router, + Addr: ":" + port, + Handler: router, + ReadHeaderTimeout: 5 * time.Second, } - log.Printf("Serving on port: %s\n", port) + log.Printf("Serving on port: %q\n", port) log.Fatal(srv.ListenAndServe()) } From 889228ca2edd28d613924d9b4ccae77c1c9861e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BD=D0=B0=D1=80=20=D0=A1=D0=B0=D0=BB=D0=B8?= =?UTF-8?q?=D0=BC=D0=B7=D1=8F=D0=BD=D0=BE=D0=B2?= Date: Sat, 2 May 2026 14:58:57 +0400 Subject: [PATCH 20/20] fix pipelines --- main.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/main.go b/main.go index 641cd3abcb3..fc83c2426a5 100644 --- a/main.go +++ b/main.go @@ -33,10 +33,11 @@ func main() { } portEnv := os.Getenv("PORT") - port, err := strconv.Atoi(portEnv) + portInt, err := strconv.Atoi(portEnv) if err != nil { log.Fatal("Invalid port") } + port := strconv.Itoa(portInt) apiCfg := apiConfig{}