From 9b157ba3654539864684df1ef7578d302663f737 Mon Sep 17 00:00:00 2001 From: Sianwa Atemi Date: Thu, 18 Sep 2025 21:04:48 +0300 Subject: [PATCH 01/18] Edited README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index c2bec0368b..f1f2c79b16 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! + +Sianwa's version of Boot.dev's Notely app. From e74e554695c7143ed0af885b1671ef2a82b8526b Mon Sep 17 00:00:00 2001 From: Sianwa Atemi Date: Thu, 18 Sep 2025 23:53:53 +0300 Subject: [PATCH 02/18] Setting up github actions --- .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..a54d8248d5 --- /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.25.1" + + - name: Force Failure + run: (exit 1) \ No newline at end of file From 9c2a612428d8377bae38600aa59796d0ca356e3b Mon Sep 17 00:00:00 2001 From: Sianwa Atemi Date: Thu, 18 Sep 2025 23:57:13 +0300 Subject: [PATCH 03/18] Edited job's step --- .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 a54d8248d5..12066e72b7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,5 +18,5 @@ jobs: with: go-version: "1.25.1" - - 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 904f73696f2706147c3680527ed2a6b9c52b1de0 Mon Sep 17 00:00:00 2001 From: Sianwa Atemi Date: Fri, 19 Sep 2025 01:00:53 +0300 Subject: [PATCH 04/18] Testing broken tests --- .github/workflows/ci.yml | 4 +-- internal/auth/auth.go | 2 +- internal/auth/auth_test.go | 62 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 3 deletions(-) create mode 100644 internal/auth/auth_test.go diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 12066e72b7..10ec7225e1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,5 +18,5 @@ jobs: with: go-version: "1.25.1" - - 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/auth.go b/internal/auth/auth.go index f969aacf63..a4b6fef4c5 100644 --- a/internal/auth/auth.go +++ b/internal/auth/auth.go @@ -15,7 +15,7 @@ func GetAPIKey(headers http.Header) (string, error) { return "", ErrNoAuthHeaderIncluded } splitAuth := strings.Split(authHeader, " ") - if len(splitAuth) < 2 || splitAuth[0] != "ApiKey" { + if len(splitAuth) < 2 || splitAuth[0] != "Broken" { return "", errors.New("malformed authorization header") } diff --git a/internal/auth/auth_test.go b/internal/auth/auth_test.go new file mode 100644 index 0000000000..5ac1cd99d3 --- /dev/null +++ b/internal/auth/auth_test.go @@ -0,0 +1,62 @@ +package auth + +import ( + "fmt" + "net/http" + "strings" + "testing" +) + +func TestGetAPIKey(t *testing.T) { + tests := []struct { + key string + value string + expect string + expectErr string + }{ + { + expectErr: "no authorization header", + }, + { + key: "Authorization", + expectErr: "no authorization header", + }, + { + key: "Authorization", + value: "-", + expectErr: "malformed authorization header", + }, + { + key: "Authorization", + value: "Bearer xxxxxx", + expectErr: "malformed authorization header", + }, + { + key: "Authorization", + value: "ApiKey xxxxxx", + expect: "xxxxxx", + expectErr: "not expecting an error", + }, + } + + for i, test := range tests { + t.Run(fmt.Sprintf("TestGetAPIKey Case #%v:", i), func(t *testing.T) { + header := http.Header{} + header.Add(test.key, test.value) + + output, err := GetAPIKey(header) + if err != nil { + if strings.Contains(err.Error(), test.expectErr) { + return + } + t.Errorf("Unexpected: TestGetAPIKey:%v\n", err) + return + } + + if output != test.expect { + t.Errorf("Unexpected: TestGetAPIKey:%s", output) + return + } + }) + } +} From 6941b8577d317479bea513918da812e6675b4c1b Mon Sep 17 00:00:00 2001 From: Sianwa Atemi Date: Fri, 19 Sep 2025 01:02:05 +0300 Subject: [PATCH 05/18] Fixed broken tests --- 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 a4b6fef4c5..f969aacf63 100644 --- a/internal/auth/auth.go +++ b/internal/auth/auth.go @@ -15,7 +15,7 @@ func GetAPIKey(headers http.Header) (string, error) { return "", ErrNoAuthHeaderIncluded } splitAuth := strings.Split(authHeader, " ") - if len(splitAuth) < 2 || splitAuth[0] != "Broken" { + if len(splitAuth) < 2 || splitAuth[0] != "ApiKey" { return "", errors.New("malformed authorization header") } From af474253836cd5bce42cdde2a5b9a3a1bb855fb0 Mon Sep 17 00:00:00 2001 From: Sianwa Atemi Date: Fri, 19 Sep 2025 01:05:54 +0300 Subject: [PATCH 06/18] Added coverage flag to tests --- .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 10ec7225e1..2883422b54 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,4 +19,4 @@ jobs: go-version: "1.25.1" - name: Run tests - run: go test ./... \ No newline at end of file + run: go test -cover ./... \ No newline at end of file From 37647f8f3020c3ac49e537a37d0c89cb24b420c4 Mon Sep 17 00:00:00 2001 From: Sianwa Atemi Date: Fri, 19 Sep 2025 01:10:04 +0300 Subject: [PATCH 07/18] Added test badge to README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index f1f2c79b16..504cb45535 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +![Tests Status](https://github.com/sianwa11/Notely/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 b5a4f4bf105defec719ad87d0b5b6b720fc1d5f1 Mon Sep 17 00:00:00 2001 From: Sianwa Atemi Date: Fri, 19 Sep 2025 01:27:24 +0300 Subject: [PATCH 08/18] Added new formatting job --- .github/workflows/ci.yml | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2883422b54..1ad4eaee8a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,4 +19,20 @@ jobs: go-version: "1.25.1" - name: Run tests - run: go test -cover ./... \ No newline at end of file + 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.25.1" + + - name: Check formatting + run: test -z $(go fmt ./...) \ No newline at end of file From 4af48637252e52860218adcba118949920ce22c8 Mon Sep 17 00:00:00 2001 From: Sianwa Atemi Date: Fri, 19 Sep 2025 01:41:14 +0300 Subject: [PATCH 09/18] Code with failed staticcheck --- .github/workflows/ci.yml | 8 +++++++- main.go | 6 ++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1ad4eaee8a..b0a047dc7d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,5 +34,11 @@ jobs: with: go-version: "1.25.1" + - name: Install staticcheck + run: go install honnef.co/go/tools/cmd/staticcheck@latest + - name: Check formatting - run: test -z $(go fmt ./...) \ No newline at end of file + run: test -z $(go fmt ./...) + + - name: Run staticcheck + run: staticcheck ./... diff --git a/main.go b/main.go index 19d7366c5f..e2cb04fcc5 100644 --- a/main.go +++ b/main.go @@ -96,3 +96,9 @@ func main() { log.Printf("Serving on port: %s\n", port) log.Fatal(srv.ListenAndServe()) } + + +func unused() { + // this function does nothing + // and is called nowhere +} \ No newline at end of file From b2e85b0b1abd4a65269e64fe3cb47ebeac7b9e66 Mon Sep 17 00:00:00 2001 From: Sianwa Atemi Date: Fri, 19 Sep 2025 01:43:28 +0300 Subject: [PATCH 10/18] Removed unused function --- main.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/main.go b/main.go index e2cb04fcc5..19d7366c5f 100644 --- a/main.go +++ b/main.go @@ -96,9 +96,3 @@ func main() { log.Printf("Serving on port: %s\n", port) log.Fatal(srv.ListenAndServe()) } - - -func unused() { - // this function does nothing - // and is called nowhere -} \ No newline at end of file From 0ad9dfe3f93488e1967ad2377c727e7028ea0c05 Mon Sep 17 00:00:00 2001 From: Sianwa Atemi Date: Fri, 19 Sep 2025 01:51:02 +0300 Subject: [PATCH 11/18] Added gosec as 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 b0a047dc7d..8c6b380f03 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 d4d5441563ff5f3c01e8660abce45420ab5c1c34 Mon Sep 17 00:00:00 2001 From: Sianwa Atemi Date: Fri, 19 Sep 2025 01:59:03 +0300 Subject: [PATCH 12/18] Added gosec errors --- json.go | 5 ++++- main.go | 6 ++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/json.go b/json.go index 1e6e7985e1..c72d9a4f36 100644 --- a/json.go +++ b/json.go @@ -30,5 +30,8 @@ func respondWithJSON(w http.ResponseWriter, code int, payload interface{}) { return } w.WriteHeader(code) - w.Write(dat) + _, err = w.Write(dat) + if err != nil { + log.Printf("Error writing response: %s", err) + } } diff --git a/main.go b/main.go index 19d7366c5f..72873fee93 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" @@ -89,8 +90,9 @@ func main() { router.Mount("/v1", v1Router) srv := &http.Server{ - Addr: ":" + port, - Handler: router, + Addr: ":" + port, + Handler: router, + ReadHeaderTimeout: 10 * time.Second, } log.Printf("Serving on port: %s\n", port) From f28f9b4c383c4744875bfd504584444afc190b13 Mon Sep 17 00:00:00 2001 From: Sianwa Atemi Date: Fri, 19 Sep 2025 14:38:22 +0300 Subject: [PATCH 13/18] Added cd --- .github/workflows/cd.yml | 23 +++++++++++++++++++++++ 1 file changed, 23 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 0000000000..e4405b6327 --- /dev/null +++ b/.github/workflows/cd.yml @@ -0,0 +1,23 @@ +name: cd + +on: + push: + branches: [main] + +jobs: + Deploy: + 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.25.1" + + - name: Build go + run: scripts/buildprod.sh + + \ No newline at end of file From 0cc71c617ef74f07d1b48e53113fd912fcfd6e6f Mon Sep 17 00:00:00 2001 From: Sianwa Atemi Date: Sat, 20 Sep 2025 03:57:56 +0300 Subject: [PATCH 14/18] Automate builds --- .github/workflows/cd.yml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index e4405b6327..766e2a0494 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -20,4 +20,16 @@ jobs: - name: Build go run: scripts/buildprod.sh - \ No newline at end of file + - id: auth + uses: google-github-actions/auth@v2 + with: + credentials_json: ${{ secrets.GCP_CREDENTIALS }} + + - name: Set up Cloud SDK + uses: google-github-actions/setup-gcloud@v2 + + - name: Use gcloud CLI + run: gcloud info + + - name: Build and push Docker image + run: gcloud builds submit --tag us-central1-docker.pkg.dev/notely-472611/notely-ar-repo/notely-api:v1 \ No newline at end of file From 2b712ba7f061b5397e40d694d9ea72de3451dc2b Mon Sep 17 00:00:00 2001 From: Sianwa Atemi Date: Sat, 20 Sep 2025 13:06:43 +0300 Subject: [PATCH 15/18] Cloud Run Updates --- .github/workflows/cd.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 766e2a0494..894d4fb700 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -32,4 +32,7 @@ jobs: run: gcloud info - name: Build and push Docker image - run: gcloud builds submit --tag us-central1-docker.pkg.dev/notely-472611/notely-ar-repo/notely-api:v1 \ No newline at end of file + run: gcloud builds submit --tag us-central1-docker.pkg.dev/notely-472611/notely-ar-repo/notely-api:v1 + + - name: Deploy to Cloud Run + run: gcloud run deploy notely --image us-central1-docker.pkg.dev/notely-472611/notely-ar-repo/notely-api:v1 --region us-central1 --allow-unauthenticated --project notely-472611 --max-instances=4 \ No newline at end of file From 7d4f4a45838a6bd6089bdb57ff574fac6d29e02c Mon Sep 17 00:00:00 2001 From: Sianwa Atemi Date: Sat, 20 Sep 2025 13:07:33 +0300 Subject: [PATCH 16/18] Cloud Run Updates(2) --- static/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/static/index.html b/static/index.html index 72be101028..5d4ad73c09 100644 --- a/static/index.html +++ b/static/index.html @@ -7,7 +7,7 @@ -

Notely

+

Welcome to Notely

From ce609776ec77b7a749b6ea0f2b9380a0f48ede80 Mon Sep 17 00:00:00 2001 From: Sianwa Atemi Date: Sat, 20 Sep 2025 14:06:10 +0300 Subject: [PATCH 17/18] Migrate automatically --- .github/workflows/cd.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 894d4fb700..839571c4aa 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -6,6 +6,7 @@ on: jobs: Deploy: + name: Deploy runs-on: ubuntu-latest steps: @@ -17,6 +18,9 @@ jobs: with: go-version: "1.25.1" + - name: Install goose + run: go install github.com/pressly/goose/v3/cmd/goose@latest + - name: Build go run: scripts/buildprod.sh @@ -34,5 +38,8 @@ jobs: - name: Build and push Docker image run: gcloud builds submit --tag us-central1-docker.pkg.dev/notely-472611/notely-ar-repo/notely-api:v1 + env: + DATABASE_URL: ${{ secrets.DATABASE_URL }} + - name: Deploy to Cloud Run run: gcloud run deploy notely --image us-central1-docker.pkg.dev/notely-472611/notely-ar-repo/notely-api:v1 --region us-central1 --allow-unauthenticated --project notely-472611 --max-instances=4 \ No newline at end of file From c8308eb6c946fbb3591604ce568bcb98c05883d0 Mon Sep 17 00:00:00 2001 From: Sianwa Atemi Date: Sat, 20 Sep 2025 14:20:30 +0300 Subject: [PATCH 18/18] Added correct migrate script --- .github/workflows/cd.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 839571c4aa..8fa0bf9ef6 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -9,6 +9,9 @@ jobs: name: Deploy runs-on: ubuntu-latest + env: + DATABASE_URL: ${{ secrets.DATABASE_URL }} + steps: - name: Check out code uses: actions/checkout@v4 @@ -38,8 +41,8 @@ jobs: - name: Build and push Docker image run: gcloud builds submit --tag us-central1-docker.pkg.dev/notely-472611/notely-ar-repo/notely-api:v1 - env: - DATABASE_URL: ${{ secrets.DATABASE_URL }} + - name: Run database migrations + run: ./scripts/migrateup.sh - name: Deploy to Cloud Run run: gcloud run deploy notely --image us-central1-docker.pkg.dev/notely-472611/notely-ar-repo/notely-api:v1 --region us-central1 --allow-unauthenticated --project notely-472611 --max-instances=4 \ No newline at end of file