From b6319c2a7857691a6df5593bf51d13efad2192ef Mon Sep 17 00:00:00 2001 From: WEku Date: Wed, 6 Aug 2025 15:03:02 +0200 Subject: [PATCH 01/34] updated README --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index c2bec0368b..40963720ef 100644 --- a/README.md +++ b/README.md @@ -21,3 +21,7 @@ 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! + + +ev's Notely app." +"robbieMYNAME's version of Boot.dev's Notely app."app." From 4343e530c036360eb387e4e36e4a108fbd29802f Mon Sep 17 00:00:00 2001 From: WEku Date: Fri, 8 Aug 2025 11:59:24 +0200 Subject: [PATCH 02/34] Add CI workflow for pull requests --- .github/workflows/ci.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) 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..e69de29bb2 From 6090920ee8baee83ff7c435eb7e42017aec82481 Mon Sep 17 00:00:00 2001 From: WEku Date: Fri, 8 Aug 2025 12:10:37 +0200 Subject: [PATCH 03/34] Update CI job to print Go version --- .github/workflows/ci.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e69de29bb2..0806a91916 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -0,0 +1,19 @@ +name: ci + +on: + pull_request: + branches: [main] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - name: Set up Go + uses: actions/setup-go@v4 + with: + go-version: '1.20' # or the version your project needs + + - name: Print Go version + run: go version From 9ffb0530bb071ec28f932953c582727dada7eff4 Mon Sep 17 00:00:00 2001 From: WEku Date: Tue, 12 Aug 2025 10:08:35 +0200 Subject: [PATCH 04/34] tests: add unit tests for GetAPIKey --- internal/auth/auth.go | 27 +++----------- internal/auth/auth_test.go | 74 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+), 22 deletions(-) create mode 100644 internal/auth/auth_test.go diff --git a/internal/auth/auth.go b/internal/auth/auth.go index f969aacf63..2c2abae699 100644 --- a/internal/auth/auth.go +++ b/internal/auth/auth.go @@ -1,23 +1,6 @@ -package auth - -import ( - "errors" - "net/http" - "strings" -) - -var ErrNoAuthHeaderIncluded = errors.New("no authorization header included") - -// GetAPIKey - -func GetAPIKey(headers http.Header) (string, error) { - authHeader := headers.Get("Authorization") - if authHeader == "" { - return "", ErrNoAuthHeaderIncluded - } - splitAuth := strings.Split(authHeader, " ") - if len(splitAuth) < 2 || splitAuth[0] != "ApiKey" { - return "", errors.New("malformed authorization header") - } - - return splitAuth[1], nil +func GetAPIKey(r *http.Request) (string, error) { + // something like: + // - get "Authorization" header + // - check if it starts with "ApiKey " + // - return the key or an error } diff --git a/internal/auth/auth_test.go b/internal/auth/auth_test.go new file mode 100644 index 0000000000..68753ac33b --- /dev/null +++ b/internal/auth/auth_test.go @@ -0,0 +1,74 @@ +package auth + +import ( + "net/http" + "testing" +) + +func TestGetAPIKey(t *testing.T) { + tests := []struct { + name string + header string // full Authorization header value; if empty -> header not set + want string + wantErr bool + }{ + { + name: "valid APIkey", + header: "ApiKey my-secret-key", + want: "my-secret-key", + wantErr: false, + }, + { + name: "missing Authorization header", + header: "", + want: "", + wantErr: true, + }, + { + name: "wrong prefix", + header: "Bearer somethingelse", + want: "", + wantErr: true, + }, + { + name: "no key after prefix", + header: "ApiKey ", + want: "", + wantErr: true, + }, + { + name: "extra spaces before key", + header: "ApiKey spaced-key", + want: "spaced-key", + wantErr: false, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + req, err := http.NewRequest("GET", "/", nil) + if err != nil { + t.Fatalf("failed to create request: %v", err) + } + if tc.header != "" { + req.Header.Set("Authorization", tc.header) + } + + got, err := GetAPIKey(req) + if tc.wantErr { + if err == nil { + t.Fatalf("expected error but got none (got=%q)", got) + } + // OK: error expected + return + } + // no error expected + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if got != tc.want { + t.Fatalf("want key %q, got %q", tc.want, got) + } + }) + } +} From aa60d0b8d62d595edc2917cb9b2527ef22a738fa Mon Sep 17 00:00:00 2001 From: WEku Date: Tue, 12 Aug 2025 11:51:48 +0200 Subject: [PATCH 05/34] Add unit tests for GetAPIKey --- internal/auth/auth_test.go | 89 ++++++++++++++++++++------------------ 1 file changed, 48 insertions(+), 41 deletions(-) diff --git a/internal/auth/auth_test.go b/internal/auth/auth_test.go index 68753ac33b..1a84551b12 100644 --- a/internal/auth/auth_test.go +++ b/internal/auth/auth_test.go @@ -7,68 +7,75 @@ import ( func TestGetAPIKey(t *testing.T) { tests := []struct { - name string - header string // full Authorization header value; if empty -> header not set - want string - wantErr bool + name string + authHeader string + wantKey string + wantErrSubstr string }{ { - name: "valid APIkey", - header: "ApiKey my-secret-key", - want: "my-secret-key", - wantErr: false, + name: "missing header", + authHeader: "", + wantErrSubstr: "authorization header is missing", }, { - name: "missing Authorization header", - header: "", - want: "", - wantErr: true, + name: "wrong prefix", + authHeader: "Bearer abc123", + wantErrSubstr: "must start with 'ApiKey '", }, { - name: "wrong prefix", - header: "Bearer somethingelse", - want: "", - wantErr: true, + name: "empty key after prefix", + authHeader: "ApiKey ", + wantErrSubstr: "API key is missing", }, { - name: "no key after prefix", - header: "ApiKey ", - want: "", - wantErr: true, - }, - { - name: "extra spaces before key", - header: "ApiKey spaced-key", - want: "spaced-key", - wantErr: false, + name: "valid key", + authHeader: "ApiKey my-secret-key", + wantKey: "my-secret-key", }, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { - req, err := http.NewRequest("GET", "/", nil) - if err != nil { - t.Fatalf("failed to create request: %v", err) - } - if tc.header != "" { - req.Header.Set("Authorization", tc.header) + req, _ := http.NewRequest("GET", "/", nil) + if tc.authHeader != "" { + req.Header.Set("Authorization", tc.authHeader) } - got, err := GetAPIKey(req) - if tc.wantErr { - if err == nil { - t.Fatalf("expected error but got none (got=%q)", got) + gotKey, err := GetAPIKey(req) + + if tc.wantErrSubstr != "" { + if err == nil || !contains(err.Error(), tc.wantErrSubstr) { + t.Errorf("expected error containing %q, got %v", tc.wantErrSubstr, err) } - // OK: error expected return } - // no error expected + if err != nil { - t.Fatalf("unexpected error: %v", err) + t.Errorf("unexpected error: %v", err) } - if got != tc.want { - t.Fatalf("want key %q, got %q", tc.want, got) + if gotKey != tc.wantKey { + t.Errorf("expected key %q, got %q", tc.wantKey, gotKey) } }) } } + +func contains(s, substr string) bool { + return len(substr) == 0 || (len(s) >= len(substr) && stringContains(s, substr)) +} + +func stringContains(s, substr string) bool { + return len(substr) <= len(s) && (indexOf(s, substr) >= 0) +} + +func indexOf(s, substr string) int { + for i := range s { + if len(s)-i < len(substr) { + return -1 + } + if s[i:i+len(substr)] == substr { + return i + } + } + return -1 +} From 0af7823643434ed4532cfc6072c2c993b586eb93 Mon Sep 17 00:00:00 2001 From: WEku Date: Tue, 12 Aug 2025 12:04:40 +0200 Subject: [PATCH 06/34] Intentionally break tests for CI check --- .github/workflows/ci.yml | 7 +++- .idea/.gitignore | 5 +++ .../inspectionProfiles/profiles_settings.xml | 6 +++ .idea/learn-cicd-starter.iml | 8 ++++ .idea/misc.xml | 7 ++++ .idea/modules.xml | 8 ++++ .idea/vcs.xml | 6 +++ internal/auth/auth.go | 37 +++++++++++++++++-- middleware_auth.go | 14 ++++--- 9 files changed, 86 insertions(+), 12 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/inspectionProfiles/profiles_settings.xml create mode 100644 .idea/learn-cicd-starter.iml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0806a91916..cc018e3b59 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,10 +10,13 @@ jobs: steps: - uses: actions/checkout@v2 - - name: Set up Go - uses: actions/setup-go@v4 + - name: Setup Go + uses: actions/setup-go@v2 with: go-version: '1.20' # or the version your project needs + - name: Run tests + run: go test ./... + - name: Print Go version run: go version diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000000..b58b603fea --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,5 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000000..105ce2da2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/learn-cicd-starter.iml b/.idea/learn-cicd-starter.iml new file mode 100644 index 0000000000..8388dbc88e --- /dev/null +++ b/.idea/learn-cicd-starter.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000000..812ab5a681 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000000..d0adac68cd --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000000..35eb1ddfbb --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/internal/auth/auth.go b/internal/auth/auth.go index 2c2abae699..13d9737f7c 100644 --- a/internal/auth/auth.go +++ b/internal/auth/auth.go @@ -1,6 +1,35 @@ +package auth + +import ( + "errors" + "net/http" + "strings" +) + +// GetAPIKey extracts an API key from the Authorization header. +// The expected format is: "Authorization: ApiKey " func GetAPIKey(r *http.Request) (string, error) { - // something like: - // - get "Authorization" header - // - check if it starts with "ApiKey " - // - return the key or an error + const prefix = "ApiKey " + + // Get the Authorization header value + authHeader := r.Header.Get("Authorization") + if authHeader == "" { + return "", errors.New("authorization header is missing") + } + + // Check for the correct prefix + if !strings.HasPrefix(authHeader, prefix) { + return "", errors.New("authorization header must start with 'ApiKey '") + } + + // Trim the prefix to get the actual key + apiKey := strings.TrimPrefix(authHeader, prefix) + apiKey = strings.TrimSpace(apiKey) + + if apiKey == "" { + return "", errors.New("API key is missing after prefix") + } + + return apiKey + "oops", nil } + diff --git a/middleware_auth.go b/middleware_auth.go index 6cbe03f867..3aa872402f 100644 --- a/middleware_auth.go +++ b/middleware_auth.go @@ -7,22 +7,24 @@ import ( "github.com/bootdotdev/learn-cicd-starter/internal/database" ) -type authedHandler func(http.ResponseWriter, *http.Request, database.User) - -func (cfg *apiConfig) middlewareAuth(handler authedHandler) http.HandlerFunc { +func (cfg *apiConfig) middlewareAuth( + handler func(http.ResponseWriter, *http.Request, database.User), +) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - apiKey, err := auth.GetAPIKey(r.Header) + apiKey, err := auth.GetAPIKey(r) if err != nil { - respondWithError(w, http.StatusUnauthorized, "Couldn't find api key", err) + http.Error(w, err.Error(), http.StatusUnauthorized) return } + // Look up the user in the database user, err := cfg.DB.GetUser(r.Context(), apiKey) if err != nil { - respondWithError(w, http.StatusNotFound, "Couldn't get user", err) + http.Error(w, "invalid API key", http.StatusUnauthorized) return } + // Call the actual handler with the authenticated user handler(w, r, user) } } From 7d16b0f7508ad1ce1832f10d1a02513bf9984542 Mon Sep 17 00:00:00 2001 From: WEku Date: Tue, 12 Aug 2025 12:05:24 +0200 Subject: [PATCH 07/34] Fix tests --- internal/auth/auth.go | 37 ++++--------------------------------- 1 file changed, 4 insertions(+), 33 deletions(-) diff --git a/internal/auth/auth.go b/internal/auth/auth.go index 13d9737f7c..2c2abae699 100644 --- a/internal/auth/auth.go +++ b/internal/auth/auth.go @@ -1,35 +1,6 @@ -package auth - -import ( - "errors" - "net/http" - "strings" -) - -// GetAPIKey extracts an API key from the Authorization header. -// The expected format is: "Authorization: ApiKey " func GetAPIKey(r *http.Request) (string, error) { - const prefix = "ApiKey " - - // Get the Authorization header value - authHeader := r.Header.Get("Authorization") - if authHeader == "" { - return "", errors.New("authorization header is missing") - } - - // Check for the correct prefix - if !strings.HasPrefix(authHeader, prefix) { - return "", errors.New("authorization header must start with 'ApiKey '") - } - - // Trim the prefix to get the actual key - apiKey := strings.TrimPrefix(authHeader, prefix) - apiKey = strings.TrimSpace(apiKey) - - if apiKey == "" { - return "", errors.New("API key is missing after prefix") - } - - return apiKey + "oops", nil + // something like: + // - get "Authorization" header + // - check if it starts with "ApiKey " + // - return the key or an error } - From 4697aad779649b49dbf254b8ac1e5d1a60be6faa Mon Sep 17 00:00:00 2001 From: WEku Date: Tue, 12 Aug 2025 12:14:40 +0200 Subject: [PATCH 08/34] Fix tests --- internal/auth/auth.go | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/internal/auth/auth.go b/internal/auth/auth.go index 2c2abae699..13d9737f7c 100644 --- a/internal/auth/auth.go +++ b/internal/auth/auth.go @@ -1,6 +1,35 @@ +package auth + +import ( + "errors" + "net/http" + "strings" +) + +// GetAPIKey extracts an API key from the Authorization header. +// The expected format is: "Authorization: ApiKey " func GetAPIKey(r *http.Request) (string, error) { - // something like: - // - get "Authorization" header - // - check if it starts with "ApiKey " - // - return the key or an error + const prefix = "ApiKey " + + // Get the Authorization header value + authHeader := r.Header.Get("Authorization") + if authHeader == "" { + return "", errors.New("authorization header is missing") + } + + // Check for the correct prefix + if !strings.HasPrefix(authHeader, prefix) { + return "", errors.New("authorization header must start with 'ApiKey '") + } + + // Trim the prefix to get the actual key + apiKey := strings.TrimPrefix(authHeader, prefix) + apiKey = strings.TrimSpace(apiKey) + + if apiKey == "" { + return "", errors.New("API key is missing after prefix") + } + + return apiKey + "oops", nil } + From 62b90c5408dcfa24836091fcff4630de0070c87c Mon Sep 17 00:00:00 2001 From: WEku Date: Wed, 13 Aug 2025 10:41:26 +0200 Subject: [PATCH 09/34] Intentionally break test to check CI --- internal/auth/auth_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/auth/auth_test.go b/internal/auth/auth_test.go index 1a84551b12..19a2525d92 100644 --- a/internal/auth/auth_test.go +++ b/internal/auth/auth_test.go @@ -28,7 +28,7 @@ func TestGetAPIKey(t *testing.T) { wantErrSubstr: "API key is missing", }, { - name: "valid key", + name: "wrong key", authHeader: "ApiKey my-secret-key", wantKey: "my-secret-key", }, From de29021ce18bd027f4ade8a84a017ab1cb2d16db Mon Sep 17 00:00:00 2001 From: WEku Date: Wed, 13 Aug 2025 10:49:05 +0200 Subject: [PATCH 10/34] Run Go tests in CI instead of printing version --- .github/workflows/ci.yml | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cc018e3b59..0206330aad 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -5,18 +5,16 @@ on: branches: [main] jobs: - build: + tests: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - name: Setup Go - uses: actions/setup-go@v2 + - name: Set up Go + uses: actions/setup-go@v4 with: - go-version: '1.20' # or the version your project needs + go-version: '1.20' # Or whatever you use locally - name: Run tests run: go test ./... - - name: Print Go version - run: go version From 44c74cd864dcdb03c5fce6273485d7f94cb1377b Mon Sep 17 00:00:00 2001 From: WEku Date: Wed, 13 Aug 2025 10:53:44 +0200 Subject: [PATCH 11/34] Break code to test CI failure --- internal/auth/auth_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/auth/auth_test.go b/internal/auth/auth_test.go index 19a2525d92..ec5e3b86b5 100644 --- a/internal/auth/auth_test.go +++ b/internal/auth/auth_test.go @@ -28,7 +28,7 @@ func TestGetAPIKey(t *testing.T) { wantErrSubstr: "API key is missing", }, { - name: "wrong key", + name: "Valid key", authHeader: "ApiKey my-secret-key", wantKey: "my-secret-key", }, From 20b9c6cff6e392bf6822a271c6c0b8162325146d Mon Sep 17 00:00:00 2001 From: WEku Date: Wed, 13 Aug 2025 11:07:50 +0200 Subject: [PATCH 12/34] Intentionally break test to check CI --- internal/auth/auth_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/auth/auth_test.go b/internal/auth/auth_test.go index ec5e3b86b5..2662a03fb4 100644 --- a/internal/auth/auth_test.go +++ b/internal/auth/auth_test.go @@ -30,7 +30,7 @@ func TestGetAPIKey(t *testing.T) { { name: "Valid key", authHeader: "ApiKey my-secret-key", - wantKey: "my-secret-key", + wantKey: "wrong key", }, } From 9b21c739c9e66c86dd146058020ae0f31316e709 Mon Sep 17 00:00:00 2001 From: WEku Date: Wed, 13 Aug 2025 11:18:55 +0200 Subject: [PATCH 13/34] Intentionally break test to check CI --- internal/auth/auth_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/auth/auth_test.go b/internal/auth/auth_test.go index 2662a03fb4..ec5e3b86b5 100644 --- a/internal/auth/auth_test.go +++ b/internal/auth/auth_test.go @@ -30,7 +30,7 @@ func TestGetAPIKey(t *testing.T) { { name: "Valid key", authHeader: "ApiKey my-secret-key", - wantKey: "wrong key", + wantKey: "my-secret-key", }, } From e069c9a2b18eb5460ba861a5a9498e89962d86bf Mon Sep 17 00:00:00 2001 From: WEku Date: Wed, 13 Aug 2025 11:25:05 +0200 Subject: [PATCH 14/34] Update CI to run Go tests --- .github/workflows/ci.yml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0206330aad..6b5a89ee59 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,18 +3,22 @@ name: ci on: pull_request: branches: [main] + push: + branches: [main] jobs: - tests: + build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Set up Go uses: actions/setup-go@v4 with: - go-version: '1.20' # Or whatever you use locally + go-version: '1.20' - name: Run tests run: go test ./... + - name: Print Go version + run: go version From f7ee241f8b1ae578252d2d8dd32c89a68e59be4b Mon Sep 17 00:00:00 2001 From: WEku Date: Wed, 13 Aug 2025 11:28:21 +0200 Subject: [PATCH 15/34] Temporarily break test to check CI fails --- internal/auth/auth_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/auth/auth_test.go b/internal/auth/auth_test.go index ec5e3b86b5..cda153721e 100644 --- a/internal/auth/auth_test.go +++ b/internal/auth/auth_test.go @@ -30,7 +30,7 @@ func TestGetAPIKey(t *testing.T) { { name: "Valid key", authHeader: "ApiKey my-secret-key", - wantKey: "my-secret-key", + wantKey: "wrong-key", }, } From eb85e972deea1e25efa425b2f210483ae7e58813 Mon Sep 17 00:00:00 2001 From: WEku Date: Wed, 13 Aug 2025 11:31:47 +0200 Subject: [PATCH 16/34] Fix test to pass again --- internal/auth/auth_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/auth/auth_test.go b/internal/auth/auth_test.go index cda153721e..ec5e3b86b5 100644 --- a/internal/auth/auth_test.go +++ b/internal/auth/auth_test.go @@ -30,7 +30,7 @@ func TestGetAPIKey(t *testing.T) { { name: "Valid key", authHeader: "ApiKey my-secret-key", - wantKey: "wrong-key", + wantKey: "my-secret-key", }, } From efd17cb4ca592621e32c36254fe254647b272a97 Mon Sep 17 00:00:00 2001 From: WEku Date: Wed, 13 Aug 2025 13:51:41 +0200 Subject: [PATCH 17/34] Temporarily break test to verify CI fails --- internal/auth/auth_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/auth/auth_test.go b/internal/auth/auth_test.go index ec5e3b86b5..470da5a88d 100644 --- a/internal/auth/auth_test.go +++ b/internal/auth/auth_test.go @@ -30,7 +30,7 @@ func TestGetAPIKey(t *testing.T) { { name: "Valid key", authHeader: "ApiKey my-secret-key", - wantKey: "my-secret-key", + wantKey: "my-secret-keyoops", // purposely wrong for CI test }, } From 89d87e45fb6b0f8e3fa39ad85d9d6414841c3e91 Mon Sep 17 00:00:00 2001 From: WEku Date: Wed, 13 Aug 2025 13:59:40 +0200 Subject: [PATCH 18/34] Fix test to pass CI --- internal/auth/auth_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/auth/auth_test.go b/internal/auth/auth_test.go index 470da5a88d..450a74dd2f 100644 --- a/internal/auth/auth_test.go +++ b/internal/auth/auth_test.go @@ -30,7 +30,7 @@ func TestGetAPIKey(t *testing.T) { { name: "Valid key", authHeader: "ApiKey my-secret-key", - wantKey: "my-secret-keyoops", // purposely wrong for CI test + wantKey: "my-secret-key", // correct value }, } From b23c6bcb0addca95c2ff9f45321224ce2ddc03f6 Mon Sep 17 00:00:00 2001 From: WEku Date: Wed, 13 Aug 2025 15:01:55 +0200 Subject: [PATCH 19/34] ci test yml --- internal/auth/auth_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/auth/auth_test.go b/internal/auth/auth_test.go index 450a74dd2f..470da5a88d 100644 --- a/internal/auth/auth_test.go +++ b/internal/auth/auth_test.go @@ -30,7 +30,7 @@ func TestGetAPIKey(t *testing.T) { { name: "Valid key", authHeader: "ApiKey my-secret-key", - wantKey: "my-secret-key", // correct value + wantKey: "my-secret-keyoops", // purposely wrong for CI test }, } From 2f00d3575bc163bed619de34b40b3b3d9232324a Mon Sep 17 00:00:00 2001 From: WEku Date: Wed, 13 Aug 2025 15:04:56 +0200 Subject: [PATCH 20/34] ci test yml --- internal/auth/auth_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/auth/auth_test.go b/internal/auth/auth_test.go index 470da5a88d..18d051d9cf 100644 --- a/internal/auth/auth_test.go +++ b/internal/auth/auth_test.go @@ -30,7 +30,7 @@ func TestGetAPIKey(t *testing.T) { { name: "Valid key", authHeader: "ApiKey my-secret-key", - wantKey: "my-secret-keyoops", // purposely wrong for CI test + wantKey: "my-secret-key", // correct for CI test }, } From 24c965774a98d5784eb4714298f21561929f334a Mon Sep 17 00:00:00 2001 From: WEku Date: Wed, 13 Aug 2025 15:13:23 +0200 Subject: [PATCH 21/34] ci test yml --- internal/auth/auth_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/auth/auth_test.go b/internal/auth/auth_test.go index 18d051d9cf..b873d58190 100644 --- a/internal/auth/auth_test.go +++ b/internal/auth/auth_test.go @@ -30,7 +30,7 @@ func TestGetAPIKey(t *testing.T) { { name: "Valid key", authHeader: "ApiKey my-secret-key", - wantKey: "my-secret-key", // correct for CI test + wantKey: "my-secret-keyoops", // incorrect for CI test }, } From fa6ac33ec7b6ef83a3e50e3862878e028f44ede6 Mon Sep 17 00:00:00 2001 From: WEku Date: Wed, 13 Aug 2025 15:37:25 +0200 Subject: [PATCH 22/34] ci test yml --- internal/auth/auth_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/auth/auth_test.go b/internal/auth/auth_test.go index b873d58190..18d051d9cf 100644 --- a/internal/auth/auth_test.go +++ b/internal/auth/auth_test.go @@ -30,7 +30,7 @@ func TestGetAPIKey(t *testing.T) { { name: "Valid key", authHeader: "ApiKey my-secret-key", - wantKey: "my-secret-keyoops", // incorrect for CI test + wantKey: "my-secret-key", // correct for CI test }, } From 09c577bcc7e1a562825be5cfdb4f01a5ffc474b6 Mon Sep 17 00:00:00 2001 From: WEku Date: Wed, 13 Aug 2025 15:49:53 +0200 Subject: [PATCH 23/34] Trigger CI with broken test --- internal/auth/auth_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/auth/auth_test.go b/internal/auth/auth_test.go index 18d051d9cf..2b4df83dfd 100644 --- a/internal/auth/auth_test.go +++ b/internal/auth/auth_test.go @@ -79,3 +79,4 @@ func indexOf(s, substr string) int { } return -1 } +// trigger CI From 90eb4f02a09d15f8ac7b466ddbfc369154f75b47 Mon Sep 17 00:00:00 2001 From: WEku Date: Wed, 13 Aug 2025 16:09:41 +0200 Subject: [PATCH 24/34] ci test yml --- 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 13d9737f7c..b86f4693fa 100644 --- a/internal/auth/auth.go +++ b/internal/auth/auth.go @@ -30,6 +30,6 @@ func GetAPIKey(r *http.Request) (string, error) { return "", errors.New("API key is missing after prefix") } - return apiKey + "oops", nil + return apiKey, nil } From fe5e43655d6b130ec6f719143dcb5d5087cffb40 Mon Sep 17 00:00:00 2001 From: WEku Date: Wed, 13 Aug 2025 16:18:24 +0200 Subject: [PATCH 25/34] ci test yml --- .github/workflows/ci.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6b5a89ee59..6460d0a520 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,19 +3,17 @@ name: ci on: pull_request: branches: [main] - push: - branches: [main] jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v2 - name: Set up Go uses: actions/setup-go@v4 with: - go-version: '1.20' + go-version: '1.22' - name: Run tests run: go test ./... From 3fc08891fdbaa950da4064b08edbf8b5abc736a0 Mon Sep 17 00:00:00 2001 From: WEku Date: Wed, 13 Aug 2025 16:23:56 +0200 Subject: [PATCH 26/34] ci test yml --- internal/auth/auth_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/auth/auth_test.go b/internal/auth/auth_test.go index 2b4df83dfd..1b559b848e 100644 --- a/internal/auth/auth_test.go +++ b/internal/auth/auth_test.go @@ -30,7 +30,7 @@ func TestGetAPIKey(t *testing.T) { { name: "Valid key", authHeader: "ApiKey my-secret-key", - wantKey: "my-secret-key", // correct for CI test + wantKey: "wrong key", // "instead of my secret key" }, } From 1fb1cc673eced96efb6416da926f2c37939f44e5 Mon Sep 17 00:00:00 2001 From: WEku Date: Wed, 13 Aug 2025 16:28:30 +0200 Subject: [PATCH 27/34] ci test yml --- internal/auth/auth_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/auth/auth_test.go b/internal/auth/auth_test.go index 1b559b848e..dc2a67eeba 100644 --- a/internal/auth/auth_test.go +++ b/internal/auth/auth_test.go @@ -30,7 +30,7 @@ func TestGetAPIKey(t *testing.T) { { name: "Valid key", authHeader: "ApiKey my-secret-key", - wantKey: "wrong key", // "instead of my secret key" + wantKey: "my-secret-key", //correct }, } From 05b2b403aed6911b4f44d97dd521918fe090ac5e Mon Sep 17 00:00:00 2001 From: WEku Date: Wed, 13 Aug 2025 16:52:59 +0200 Subject: [PATCH 28/34] ci test yml --- .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 6460d0a520..32d1864796 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,7 +13,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v4 with: - go-version: '1.22' + go-version: '1.24.5' - name: Run tests run: go test ./... From fdb7061a086a9b4c8f132945c4b2209e476245e6 Mon Sep 17 00:00:00 2001 From: WEku Date: Wed, 13 Aug 2025 16:56:30 +0200 Subject: [PATCH 29/34] ci test yml --- .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 32d1864796..6460d0a520 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,7 +13,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v4 with: - go-version: '1.24.5' + go-version: '1.22' - name: Run tests run: go test ./... From f57c1dac090d91ce567c0c8e0b5290524656a814 Mon Sep 17 00:00:00 2001 From: WEku Date: Wed, 13 Aug 2025 18:32:02 +0200 Subject: [PATCH 30/34] ci test yml --- .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 6460d0a520..294b47f6f7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,7 +13,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v4 with: - go-version: '1.22' + go-version: '1.24' - name: Run tests run: go test ./... From de3369e2fe1331fc64fd86411f5c5bbf3204ef73 Mon Sep 17 00:00:00 2001 From: WEku Date: Wed, 13 Aug 2025 18:35:23 +0200 Subject: [PATCH 31/34] ci test yml --- .github/workflows/ci.yml | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 294b47f6f7..a09ea7eb6a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,22 +1,24 @@ -name: ci +name: CI on: + push: + branches: [ main, ci-test, test-ci-failure ] pull_request: - branches: [main] + branches: [ main ] jobs: - build: + tests: runs-on: ubuntu-latest + steps: - - uses: actions/checkout@v2 + - name: Checkout repository + uses: actions/checkout@v3 - name: Set up Go uses: actions/setup-go@v4 with: - go-version: '1.24' + go-version: 1.24 - name: Run tests run: go test ./... - - name: Print Go version - run: go version From b44d6d2a3ec37659d7fe30d91180485b480c8105 Mon Sep 17 00:00:00 2001 From: WEku Date: Wed, 13 Aug 2025 18:52:44 +0200 Subject: [PATCH 32/34] ci test yml --- .github/workflows/ci.yml | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a09ea7eb6a..5c6f0b3041 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,12 +2,16 @@ name: CI on: push: - branches: [ main, ci-test, test-ci-failure ] + branches: + - main + - ci-test pull_request: - branches: [ main ] + branches: + - main jobs: tests: + name: Tests runs-on: ubuntu-latest steps: @@ -20,5 +24,6 @@ jobs: go-version: 1.24 - name: Run tests - run: go test ./... - + run: | + echo "'Tests' job: go test" + go test ./... From 62eaea57333f90c828d293c79a005608b1b5448f Mon Sep 17 00:00:00 2001 From: WEku Date: Thu, 14 Aug 2025 10:35:23 +0200 Subject: [PATCH 33/34] Add coverage reporting to CI 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 5c6f0b3041..4052297f9c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,7 +23,7 @@ jobs: with: go-version: 1.24 - - name: Run tests + - name: Run tests with coverage run: | echo "'Tests' job: go test" - go test ./... + go test -cover ./... From 60671be5dd248592734e985d4ffee34d5ad7c549 Mon Sep 17 00:00:00 2001 From: WEku Date: Fri, 22 Aug 2025 12:55:32 +0200 Subject: [PATCH 34/34] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 40963720ef..854e6efba6 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ +[![Tests](https://github.com/robaweku-bit/learn-cicd-starter/actions/workflows/ci.yml/badge.svg)](https://github.com/robaweku-bit/learn-cicd-starter/actions) # 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).