From 885955af26dfde3668d49f2d3ec685684b5e0ff4 Mon Sep 17 00:00:00 2001 From: yogesh Date: Mon, 17 Aug 2026 18:10:51 +0530 Subject: [PATCH 01/17] change --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index c2bec0368b7..c7509c5c5a3 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! +"Yogesh Jangid's version of Boot.dev's Notely app." \ No newline at end of file From 0defd472e09dc3fd26122f6a13b9ff3190b54ebe Mon Sep 17 00:00:00 2001 From: yogesh Date: Tue, 18 Aug 2026 11:08:46 +0530 Subject: [PATCH 02/17] ci changes --- .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..664032071d1 --- /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 515da27a0a20387248e07c0956583b5d758bb8e0 Mon Sep 17 00:00:00 2001 From: yogesh Date: Tue, 18 Aug 2026 11:17:09 +0530 Subject: [PATCH 03/17] ci change update --- .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 664032071d1..d64b8281507 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: Check Go version + run: go version \ No newline at end of file From f61f6070315334f15e78bacfa2c5b3dec07d4a86 Mon Sep 17 00:00:00 2001 From: yogesh Date: Tue, 18 Aug 2026 11:55:33 +0530 Subject: [PATCH 04/17] broken changes --- .github/workflows/ci.yml | 4 +-- internal/auth/get_api_key_test.go | 46 +++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 internal/auth/get_api_key_test.go diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d64b8281507..c6ac79c0a4d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,5 +18,5 @@ jobs: with: go-version: "1.26.0" - - name: Check Go version - run: go version \ No newline at end of file + - name: Run tests + run: go test ./... \ No newline at end of file diff --git a/internal/auth/get_api_key_test.go b/internal/auth/get_api_key_test.go new file mode 100644 index 00000000000..b8bd19be172 --- /dev/null +++ b/internal/auth/get_api_key_test.go @@ -0,0 +1,46 @@ +package auth + +import ( + "net/http" + "testing" +) + +func TestGetAPIKey(t *testing.T) { + tests := []struct { + name string + headers http.Header + want string + wantErr bool + }{ + { + name: "valid API key", + headers: http.Header{ + "Authorization": []string{"ApiKey test-api-key"}, + }, + // INTENTIONALLY WRONG + want: "wrong-api-key", + wantErr: false, + }, + { + name: "missing API key", + headers: http.Header{}, + want: "", + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := GetAPIKey(tt.headers) + + if (err != nil) != tt.wantErr { + t.Errorf("GetAPIKey() error = %v, wantErr %v", err, tt.wantErr) + return + } + + if got != tt.want { + t.Errorf("GetAPIKey() = %q, want %q", got, tt.want) + } + }) + } +} \ No newline at end of file From d401da345c75105a38864e7ba365b68fecd99aef Mon Sep 17 00:00:00 2001 From: yogesh Date: Tue, 18 Aug 2026 11:56:49 +0530 Subject: [PATCH 05/17] ci test fixed --- internal/auth/get_api_key_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/internal/auth/get_api_key_test.go b/internal/auth/get_api_key_test.go index b8bd19be172..62ce22daf34 100644 --- a/internal/auth/get_api_key_test.go +++ b/internal/auth/get_api_key_test.go @@ -17,8 +17,7 @@ func TestGetAPIKey(t *testing.T) { headers: http.Header{ "Authorization": []string{"ApiKey test-api-key"}, }, - // INTENTIONALLY WRONG - want: "wrong-api-key", + want: "test-api-key", wantErr: false, }, { From 76ec536ca0b3cda7075a52339c9f2ee8009cfdf9 Mon Sep 17 00:00:00 2001 From: yogesh Date: Tue, 18 Aug 2026 12:04:52 +0530 Subject: [PATCH 06/17] -cover change added --- .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 c6ac79c0a4d..12897706b9e 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 ./... \ No newline at end of file + run: go test -cover ./... \ No newline at end of file From 66488793cfbc5292bd25f60785eb55325f190312 Mon Sep 17 00:00:00 2001 From: yogesh Date: Tue, 18 Aug 2026 12:09:19 +0530 Subject: [PATCH 07/17] change for the readme --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index c7509c5c5a3..a96241fca77 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,8 @@ +![Tests](https://github.com/coderyogesh27/learn-cicd-starter/actions/workflows/ci.yml/badge.svg) + +# Notely + +... # 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 d74ea1bcc88b9d53580bec30d704129312404162 Mon Sep 17 00:00:00 2001 From: yogesh Date: Tue, 18 Aug 2026 12:33:52 +0530 Subject: [PATCH 08/17] changes for the style tags and ci update --- .github/workflows/ci.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 12897706b9e..2ed08843177 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -5,6 +5,21 @@ on: branches: [main] 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: Run style checks + run: go fmt ./... tests: name: Tests runs-on: ubuntu-latest From 30fca2c27ea3286b9adedf2babf46516fa6f68cf Mon Sep 17 00:00:00 2001 From: yogesh Date: Tue, 18 Aug 2026 12:38:54 +0530 Subject: [PATCH 09/17] change for the test cases formatting --- .github/workflows/ci.yml | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2ed08843177..da05ce7b5f4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -5,8 +5,8 @@ on: branches: [main] jobs: - style: - name: Style + tests: + name: Tests runs-on: ubuntu-latest steps: @@ -18,10 +18,11 @@ jobs: with: go-version: "1.26.0" - - name: Run style checks - run: go fmt ./... - tests: - name: Tests + - name: Run tests + run: go test ./... + + style: + name: Style runs-on: ubuntu-latest steps: @@ -33,5 +34,5 @@ jobs: with: go-version: "1.26.0" - - name: Run tests - run: go test -cover ./... \ No newline at end of file + - name: Check formatting + run: test -z $(go fmt ./...) \ No newline at end of file From 98446b1be4b372ecfe4fb05edd4d33915f685c18 Mon Sep 17 00:00:00 2001 From: yogesh Date: Tue, 18 Aug 2026 12:46:50 +0530 Subject: [PATCH 10/17] updates for the test --- internal/auth/get_api_key_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/auth/get_api_key_test.go b/internal/auth/get_api_key_test.go index 62ce22daf34..ad2aab56154 100644 --- a/internal/auth/get_api_key_test.go +++ b/internal/auth/get_api_key_test.go @@ -17,7 +17,7 @@ func TestGetAPIKey(t *testing.T) { headers: http.Header{ "Authorization": []string{"ApiKey test-api-key"}, }, - want: "test-api-key", + want: "test-api-key", wantErr: false, }, { @@ -42,4 +42,4 @@ func TestGetAPIKey(t *testing.T) { } }) } -} \ No newline at end of file +} From a94fe777145829aee3532f520e65a547c0ce85dc Mon Sep 17 00:00:00 2001 From: yogeshedysor Date: Fri, 21 Aug 2026 11:16:20 +0530 Subject: [PATCH 11/17] changes for the main --- main.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/main.go b/main.go index 19d7366c5f7..56c493934dc 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 fceb6109646ea5e66596b7da7f7d3d4e5f9560d9 Mon Sep 17 00:00:00 2001 From: yogeshedysor Date: Fri, 21 Aug 2026 11:28:40 +0530 Subject: [PATCH 12/17] changes --- .github/workflows/ci.yml | 49 +++++++++++++--------------------------- 1 file changed, 16 insertions(+), 33 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index da05ce7b5f4..3e9796738a2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,38 +1,21 @@ -name: ci +style: + name: Style + runs-on: ubuntu-latest -on: - pull_request: - branches: [main] + steps: + - name: Check out code + uses: actions/checkout@v6 -jobs: - tests: - name: Tests - runs-on: ubuntu-latest + - name: Set up Go + uses: actions/setup-go@v6 + with: + go-version: "1.26.0" - steps: - - name: Check out code - uses: actions/checkout@v6 + - name: Check formatting + run: test -z $(go fmt ./...) - - name: Set up Go - uses: actions/setup-go@v6 - with: - go-version: "1.26.0" + - name: Install staticcheck + run: go install honnef.co/go/tools/cmd/staticcheck@latest - - name: Run tests - run: go test ./... - - 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: Check formatting - run: test -z $(go fmt ./...) \ No newline at end of file + - name: Run staticcheck + run: staticcheck ./... \ No newline at end of file From 34906a5034649f0665c574f910965b85a7eee918 Mon Sep 17 00:00:00 2001 From: yogeshedysor Date: Fri, 21 Aug 2026 11:29:34 +0530 Subject: [PATCH 13/17] changes for the success build --- main.go | 5 ----- 1 file changed, 5 deletions(-) diff --git a/main.go b/main.go index 56c493934dc..19d7366c5f7 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 0f6f45c64a372a02846599165560322d9f778d81 Mon Sep 17 00:00:00 2001 From: yogeshedysor Date: Fri, 21 Aug 2026 11:31:32 +0530 Subject: [PATCH 14/17] changes for the success --- .github/workflows/ci.yml | 55 ++++++++++++++++++++++++++++------------ 1 file changed, 39 insertions(+), 16 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3e9796738a2..7962e31a346 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,21 +1,44 @@ -style: - name: Style - runs-on: ubuntu-latest +name: ci - steps: - - name: Check out code - uses: actions/checkout@v6 +on: + pull_request: + branches: [main] - - name: Set up Go - uses: actions/setup-go@v6 - with: - go-version: "1.26.0" +jobs: + tests: + name: Tests + runs-on: ubuntu-latest - - name: Check formatting - run: test -z $(go fmt ./...) + steps: + - name: Check out code + uses: actions/checkout@v6 - - name: Install staticcheck - run: go install honnef.co/go/tools/cmd/staticcheck@latest + - name: Set up Go + uses: actions/setup-go@v6 + with: + go-version: "1.26.0" - - name: Run staticcheck - run: staticcheck ./... \ No newline at end of file + - name: Run tests + run: go test ./... + + 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: Check formatting + run: test -z $(go fmt ./...) + + - name: Install staticcheck + run: go install honnef.co/go/tools/cmd/staticcheck@latest + + - name: Run staticcheck + run: staticcheck ./... \ No newline at end of file From 00c93ce1d068fdedb0ed143c776d8578e16ca889 Mon Sep 17 00:00:00 2001 From: yogeshedysor Date: Fri, 21 Aug 2026 11:38:56 +0530 Subject: [PATCH 15/17] changes for the failure of the CI security --- .github/workflows/ci.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7962e31a346..81fff5b17f5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,6 +21,12 @@ jobs: - name: Run tests run: go test ./... + - name: Install gosec + run: go install github.com/securego/gosec/v2/cmd/gosec@latest + + - name: Run gosec + run: gosec ./... + style: name: Style runs-on: ubuntu-latest From be0a8c994f4a8a98abd80513c7d1fc467ec05279 Mon Sep 17 00:00:00 2001 From: yogeshedysor Date: Fri, 21 Aug 2026 11:45:35 +0530 Subject: [PATCH 16/17] fix security checks --- json.go | 11 +++++++++-- main.go | 16 +++++++++++++--- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/json.go b/json.go index 1e6e7985e18..1471f953a2d 100644 --- a/json.go +++ b/json.go @@ -13,9 +13,11 @@ func respondWithError(w http.ResponseWriter, code int, msg string, logErr error) if code > 499 { log.Printf("Responding with 5XX error: %s", msg) } + type errorResponse struct { Error string `json:"error"` } + respondWithJSON(w, code, errorResponse{ Error: msg, }) @@ -23,12 +25,17 @@ func respondWithError(w http.ResponseWriter, code int, msg string, logErr error) func respondWithJSON(w http.ResponseWriter, code int, payload interface{}) { w.Header().Set("Content-Type", "application/json") + dat, err := json.Marshal(payload) if err != nil { log.Printf("Error marshalling JSON: %s", err) - w.WriteHeader(500) + w.WriteHeader(http.StatusInternalServerError) return } + w.WriteHeader(code) - w.Write(dat) + + if _, err := w.Write(dat); err != nil { + log.Printf("Error writing JSON response: %s", err) + } } diff --git a/main.go b/main.go index 19d7366c5f7..c24ae1a2630 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" @@ -35,6 +37,11 @@ func main() { log.Fatal("PORT environment variable is not set") } + portNum, err := strconv.Atoi(port) + if err != nil || portNum < 1 || portNum > 65535 { + log.Fatal("PORT must be a valid port number") + } + apiCfg := apiConfig{} // https://github.com/libsql/libsql-client-go/#open-a-connection-to-sqld @@ -71,6 +78,7 @@ func main() { return } defer f.Close() + if _, err := io.Copy(w, f); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } @@ -88,11 +96,13 @@ func main() { v1Router.Get("/healthz", handlerReadiness) 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: %d\n", portNum) log.Fatal(srv.ListenAndServe()) } From a8bebb8b79b1796ac5a419e0ec99ca790a72438b Mon Sep 17 00:00:00 2001 From: yogeshedysor Date: Fri, 21 Aug 2026 12:41:25 +0530 Subject: [PATCH 17/17] add continuous deployment workflow --- .github/workflows/cd.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 .github/workflows/cd.yml diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml new file mode 100644 index 00000000000..3d9f2c04f50 --- /dev/null +++ b/.github/workflows/cd.yml @@ -0,0 +1,22 @@ +name: cd + +on: + push: + branches: [main] + +jobs: + Deploy: + name: Deploy + 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: Build production binary + run: ./scripts/buildprod.sh \ No newline at end of file