From ebcfaeafc5fe7405acdaf0a52a7e156ade461e2a Mon Sep 17 00:00:00 2001 From: fikriihsan22 Date: Thu, 23 Jul 2026 15:15:16 +0700 Subject: [PATCH 01/17] add name inside readme file --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index c2bec0368b..be2d1f65d2 100644 --- a/README.md +++ b/README.md @@ -21,3 +21,5 @@ 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! + +Pikron's version of Boot.dev's Notely app. \ No newline at end of file From dd3db6aa417c0183b8cdfc1e2d65491ded23e34f Mon Sep 17 00:00:00 2001 From: fikriihsan22 Date: Thu, 23 Jul 2026 15:28:37 +0700 Subject: [PATCH 02/17] add ci file for automated testing --- .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 0000000000..664032071d --- /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@v6 + + - name: Set up Go + uses: actions/setup-go@v6 + with: + go-version: "1.26.0" + + - name: Force Failure + run: (exit 1) \ No newline at end of file From f5510f00964e4713efe3c1eba7b9f3872c597b80 Mon Sep 17 00:00:00 2001 From: fikriihsan22 Date: Thu, 23 Jul 2026 15:58:31 +0700 Subject: [PATCH 03/17] adjust ci file --- .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 664032071d..f0bd4764d7 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 - run: (exit 1) \ No newline at end of file + - name: Print go version + run: go version \ No newline at end of file From 673c6652ce047056440d0388274b72693a96dbd9 Mon Sep 17 00:00:00 2001 From: fikriihsan22 Date: Thu, 23 Jul 2026 17:18:00 +0700 Subject: [PATCH 04/17] add unit test for getApiKey --- .github/workflows/ci.yml | 4 +- internal/auth/auth.go | 2 +- internal/auth/get_api_key_test.go | 75 +++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+), 3 deletions(-) create mode 100644 internal/auth/get_api_key_test.go diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f0bd4764d7..c3d3bd5105 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,5 +18,5 @@ jobs: with: go-version: "1.26.0" - - name: Print go version - run: go version \ No newline at end of file + - name: run unit test + run: go test ./... \ No newline at end of file diff --git a/internal/auth/auth.go b/internal/auth/auth.go index f969aacf63..1b927e650a 100644 --- a/internal/auth/auth.go +++ b/internal/auth/auth.go @@ -14,7 +14,7 @@ func GetAPIKey(headers http.Header) (string, error) { if authHeader == "" { return "", ErrNoAuthHeaderIncluded } - splitAuth := strings.Split(authHeader, " ") + splitAuth := strings.Split(authHeader, "|") if len(splitAuth) < 2 || splitAuth[0] != "ApiKey" { return "", errors.New("malformed authorization header") } diff --git a/internal/auth/get_api_key_test.go b/internal/auth/get_api_key_test.go new file mode 100644 index 0000000000..90dc8c1c74 --- /dev/null +++ b/internal/auth/get_api_key_test.go @@ -0,0 +1,75 @@ +package auth + +import ( + "errors" + "net/http" + "testing" +) + +func TestGetAPIKey(t *testing.T) { + + tests := []struct { + name string + header string + expectedKey string + expectedErr error + }{ + { + name: "valid api key", + header: "ApiKey abc123", + expectedKey: "abc123", + expectedErr: nil, + }, + { + name: "missing authorization header", + header: "", + expectedKey: "", + expectedErr: ErrNoAuthHeaderIncluded, + }, + { + name: "wrong authorization scheme", + header: "Bearer abc123", + expectedKey: "", + expectedErr: errors.New("malformed authorization header"), + }, + { + name: "missing api key", + header: "ApiKey", + expectedKey: "", + expectedErr: errors.New("malformed authorization header"), + }, + { + // Sesuai implementasi GetAPIKey saat ini (strings.Split), + // "ApiKey " dianggap valid dan menghasilkan key kosong. + name: "empty api key", + header: "ApiKey ", + expectedKey: "", + expectedErr: nil, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + headers := http.Header{} + if tt.header != "" { + headers.Set("Authorization", tt.header) + } + key, err := GetAPIKey(headers) + if key != tt.expectedKey { + t.Errorf("expected key %q, got %q", tt.expectedKey, key) + } + if tt.expectedErr == nil { + if err != nil { + t.Fatalf("expected no error, got %v", err) + } + return + } + if err == nil { + t.Fatalf("expected error %v, got nil", tt.expectedErr) + } + if err.Error() != tt.expectedErr.Error() { + t.Errorf("expected error %q, got %q", tt.expectedErr.Error(), err.Error()) + } + }) + } + +} From e57884cf0e48edf5beae91edb241fdaedf20755e Mon Sep 17 00:00:00 2001 From: fikriihsan22 Date: Thu, 23 Jul 2026 17:23:43 +0700 Subject: [PATCH 05/17] fix getApiKey --- 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 1b927e650a..f969aacf63 100644 --- a/internal/auth/auth.go +++ b/internal/auth/auth.go @@ -14,7 +14,7 @@ func GetAPIKey(headers http.Header) (string, error) { if authHeader == "" { return "", ErrNoAuthHeaderIncluded } - splitAuth := strings.Split(authHeader, "|") + splitAuth := strings.Split(authHeader, " ") if len(splitAuth) < 2 || splitAuth[0] != "ApiKey" { return "", errors.New("malformed authorization header") } From a062102ec5cfcbd717542b18d485bf854307622f Mon Sep 17 00:00:00 2001 From: fikriihsan22 Date: Fri, 24 Jul 2026 14:38:44 +0700 Subject: [PATCH 06/17] add unit test coverage in git action --- .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 c3d3bd5105..d8778f792c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,4 +19,4 @@ jobs: go-version: "1.26.0" - name: run unit test - run: go test ./... \ No newline at end of file + run: go test ./... -cover \ No newline at end of file From 71f79021dcca053b25aa34d68f1c71a2f2d5c073 Mon Sep 17 00:00:00 2001 From: fikriihsan22 Date: Fri, 24 Jul 2026 14:48:30 +0700 Subject: [PATCH 07/17] add workflow badge --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index be2d1f65d2..01c521a6bd 100644 --- a/README.md +++ b/README.md @@ -22,4 +22,6 @@ go build -o notely && ./notely 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! -Pikron's version of Boot.dev's Notely app. \ No newline at end of file +Pikron's version of Boot.dev's Notely app. + +![alt text goes here](https://github.com/fikri220/learn-cicd-starter/actions/workflows/ci.yml/badge.svg) \ No newline at end of file From 50a7d77c0ad7837ede2e0314b4449c7084ca3150 Mon Sep 17 00:00:00 2001 From: fikriihsan22 Date: Fri, 24 Jul 2026 16:56:15 +0700 Subject: [PATCH 08/17] add style to github workflows --- .github/workflows/ci.yml | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d8778f792c..7386797694 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,4 +19,19 @@ jobs: go-version: "1.26.0" - name: run unit test - run: go test ./... -cover \ No newline at end of file + run: go test ./... -cover + +jobs: + style: + name: Style + runs-on: ubuntu-latest + + steps: + - name: Check out code + uses: actions/checkout@v6 + - name: Set up Go + uses: actions/setup-go@v6 + with: + go-version: "1.26.0" + - name: Code formatting cek + run: test -z $(go fmt ./...) From 4eeeef3db6ebcff15a35b59fd9edd183e602cce3 Mon Sep 17 00:00:00 2001 From: fikriihsan22 Date: Fri, 24 Jul 2026 16:59:53 +0700 Subject: [PATCH 09/17] test --- main.go | 1 + 1 file changed, 1 insertion(+) diff --git a/main.go b/main.go index 19d7366c5f..cd1bbfeae1 100644 --- a/main.go +++ b/main.go @@ -95,4 +95,5 @@ func main() { log.Printf("Serving on port: %s\n", port) log.Fatal(srv.ListenAndServe()) + //trigger testing PR } From d4fa4f329762c54d6da6a3f3d036215eea9a6980 Mon Sep 17 00:00:00 2001 From: fikriihsan22 Date: Fri, 24 Jul 2026 17:11:22 +0700 Subject: [PATCH 10/17] fix workflow .yaml --- .github/workflows/ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7386797694..c2043404ae 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,7 +21,6 @@ jobs: - name: run unit test run: go test ./... -cover -jobs: style: name: Style runs-on: ubuntu-latest From 6ec5eaf4846e633a201dbc271e8bb33008dfd193 Mon Sep 17 00:00:00 2001 From: fikriihsan22 Date: Thu, 30 Jul 2026 16:44:22 +0700 Subject: [PATCH 11/17] add linting test to the workflow --- .github/workflows/ci.yml | 16 ++++++++++++++++ main.go | 5 +++++ 2 files changed, 21 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c2043404ae..e07d2d0900 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,3 +34,19 @@ jobs: go-version: "1.26.0" - name: Code formatting cek run: test -z $(go fmt ./...) + + linting: + name: linting + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v6 + - name: Set up Go + uses: actions/setup-go@v6 + with: + go-version: "1.26.0" + - name: Install Static Check + run: go install honnef.co/go/tools/cmd/staticcheck@latest + - name: linting with Static Check + run: staticcheck ./... diff --git a/main.go b/main.go index cd1bbfeae1..b52cfa10b9 100644 --- a/main.go +++ b/main.go @@ -24,6 +24,11 @@ type apiConfig struct { //go:embed static/* var staticFiles embed.FS +func unused() { + // this function does nothing + // and is called nowhere +} + func main() { err := godotenv.Load(".env") if err != nil { From f37a142037a961818b1d38ba6eb6292ef03eec51 Mon Sep 17 00:00:00 2001 From: fikriihsan22 Date: Thu, 30 Jul 2026 16:52:38 +0700 Subject: [PATCH 12/17] remove unused code --- main.go | 5 ----- 1 file changed, 5 deletions(-) diff --git a/main.go b/main.go index b52cfa10b9..cd1bbfeae1 100644 --- a/main.go +++ b/main.go @@ -24,11 +24,6 @@ type apiConfig struct { //go:embed static/* var staticFiles embed.FS -func unused() { - // this function does nothing - // and is called nowhere -} - func main() { err := godotenv.Load(".env") if err != nil { From 4d675ae3028f8131fb606c303c2be4d6409c15a4 Mon Sep 17 00:00:00 2001 From: fikriihsan22 Date: Thu, 30 Jul 2026 16:55:31 +0700 Subject: [PATCH 13/17] fix github workflow --- .github/workflows/ci.yml | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e07d2d0900..809dc350f3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,19 +34,7 @@ jobs: go-version: "1.26.0" - name: Code formatting cek run: test -z $(go fmt ./...) - - linting: - name: linting - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v6 - - name: Set up Go - uses: actions/setup-go@v6 - with: - go-version: "1.26.0" - - name: Install Static Check - run: go install honnef.co/go/tools/cmd/staticcheck@latest - - name: linting with Static Check - run: staticcheck ./... + - name: Install Static Check + run: go install honnef.co/go/tools/cmd/staticcheck@latest + - name: linting with Static Check + run: staticcheck ./... From 4666a258f308608cdbdefec3a3c8c6d11d12f445 Mon Sep 17 00:00:00 2001 From: fikriihsan22 Date: Thu, 30 Jul 2026 17:10:52 +0700 Subject: [PATCH 14/17] add gosec to ci workflow --- .github/workflows/ci.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 809dc350f3..b7bf800a87 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -38,3 +38,19 @@ jobs: run: go install honnef.co/go/tools/cmd/staticcheck@latest - name: linting with Static Check run: staticcheck ./... + + tests: + name: Tests + runs-on: ubuntu-latest + + steps: + - name: checkout code + uses: actions/checkout@v6 + - name: Setup go + uses: actions/setup-go@v6 + with: + go-version: "1.26.0" + - name: install gosec + run: go install github.com/securego/gosec/v2/cmd/gosec@latest + - name: run test with gosec + run: gosec ./... From 021914864c627d6d8ea4c3e7e8a839f54cecb248 Mon Sep 17 00:00:00 2001 From: fikriihsan22 Date: Thu, 30 Jul 2026 17:13:20 +0700 Subject: [PATCH 15/17] tetsing --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index cd1bbfeae1..0960cd7a3e 100644 --- a/main.go +++ b/main.go @@ -32,7 +32,7 @@ func main() { port := os.Getenv("PORT") if port == "" { - log.Fatal("PORT environment variable is not set") + log.Fatal("PORT environment variable is not set yet") } apiCfg := apiConfig{} From 4eefd573b0bdf5a9bd01b14d6feedec8a07f0ce4 Mon Sep 17 00:00:00 2001 From: fikriihsan22 Date: Thu, 30 Jul 2026 17:17:36 +0700 Subject: [PATCH 16/17] fix workflows --- .github/workflows/ci.yml | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b7bf800a87..4925ac6a86 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,14 +12,16 @@ jobs: steps: - name: Check out code uses: actions/checkout@v6 - - name: Set up Go uses: actions/setup-go@v6 with: go-version: "1.26.0" - - name: run unit test run: go test ./... -cover + - name: install gosec + run: go install github.com/securego/gosec/v2/cmd/gosec@latest + - name: run test with gosec + run: gosec ./... style: name: Style @@ -39,18 +41,4 @@ jobs: - name: linting with Static Check run: staticcheck ./... - tests: - name: Tests - runs-on: ubuntu-latest - - steps: - - name: checkout code - uses: actions/checkout@v6 - - name: Setup go - uses: actions/setup-go@v6 - with: - go-version: "1.26.0" - - name: install gosec - run: go install github.com/securego/gosec/v2/cmd/gosec@latest - - name: run test with gosec - run: gosec ./... + From 2c610c35f2913c470414e22dee5220791f11e101 Mon Sep 17 00:00:00 2001 From: fikriihsan22 Date: Thu, 30 Jul 2026 17:27:46 +0700 Subject: [PATCH 17/17] fix scurity issue --- json.go | 4 +++- main.go | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/json.go b/json.go index 1e6e7985e1..30eae27359 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("failed to write response: %v", err) + } } diff --git a/main.go b/main.go index 0960cd7a3e..eb5053ceec 100644 --- a/main.go +++ b/main.go @@ -7,6 +7,7 @@ import ( "log" "net/http" "os" + "time" "github.com/go-chi/chi" "github.com/go-chi/cors" @@ -91,9 +92,9 @@ func main() { srv := &http.Server{ Addr: ":" + port, Handler: router, + ReadHeaderTimeout: 5 * time.Second, } - log.Printf("Serving on port: %s\n", port) log.Fatal(srv.ListenAndServe()) //trigger testing PR }