From cc7af33f4e766203dd5b90872041c2c7ab40b942 Mon Sep 17 00:00:00 2001 From: AmirAgassi <33383085+AmirAgassi@users.noreply.github.com> Date: Sun, 10 Nov 2024 11:41:57 -0500 Subject: [PATCH 01/14] Add global error handler --- internal/server/error_handler.go | 79 +++++++++++++++++++++++++++ internal/server/error_handler_test.go | 76 ++++++++++++++++++++++++++ internal/server/index.go | 2 + 3 files changed, 157 insertions(+) create mode 100644 internal/server/error_handler.go create mode 100644 internal/server/error_handler_test.go diff --git a/internal/server/error_handler.go b/internal/server/error_handler.go new file mode 100644 index 0000000..2bd49cd --- /dev/null +++ b/internal/server/error_handler.go @@ -0,0 +1,79 @@ +package server + +import ( + "net/http" + + "github.com/go-playground/validator/v10" + "github.com/labstack/echo/v4" + "github.com/rs/zerolog/log" +) + +type ErrorResponse struct { + Status int `json:"status"` + Message string `json:"message"` + RequestID string `json:"request_id,omitempty"` + Errors []string `json:"errors,omitempty"` +} + +func globalErrorHandler(err error, c echo.Context) { + req := c.Request() + requestID := req.Header.Get(echo.HeaderXRequestID) + + // default error response + status := http.StatusInternalServerError + message := "internal server error" + var validationErrors []string + + // handle different error types + switch e := err.(type) { + case *echo.HTTPError: + status = e.Code + message = e.Message.(string) + + case validator.ValidationErrors: + // handle validation errors specially + status = http.StatusBadRequest + message = "validation failed" + validationErrors = make([]string, len(e)) + for i, err := range e { + validationErrors[i] = err.Error() + } + + case error: + message = e.Error() + } + + // log with more context + logger := log.Error() + if status < 500 { + logger = log.Warn() + } + + logger. + Err(err). + Str("request_id", requestID). + Str("method", req.Method). + Str("path", req.URL.Path). + Int("status", status). + Str("user_agent", req.UserAgent()). + Msg("request error") + + // return json response + if !c.Response().Committed { + response := ErrorResponse{ + Status: status, + Message: message, + RequestID: requestID, + } + if len(validationErrors) > 0 { + response.Errors = validationErrors + } + + if err := c.JSON(status, response); err != nil { + log.Error(). + Err(err). + Str("request_id", requestID). + Msg("failed to send error response") + } + } +} diff --git a/internal/server/error_handler_test.go b/internal/server/error_handler_test.go new file mode 100644 index 0000000..65ae076 --- /dev/null +++ b/internal/server/error_handler_test.go @@ -0,0 +1,76 @@ +package server + +import ( + "net/http" + "net/http/httptest" + "testing" + + "github.com/go-playground/validator/v10" + "github.com/labstack/echo/v4" + "github.com/stretchr/testify/assert" +) + +func TestGlobalErrorHandler(t *testing.T) { + // setup + e := echo.New() + e.HTTPErrorHandler = globalErrorHandler + + // test cases + tests := []struct { + name string + handler echo.HandlerFunc + expectedStatus int + expectedBody string + }{ + { + name: "http error", + handler: func(c echo.Context) error { + return echo.NewHTTPError(http.StatusBadRequest, "bad request") + }, + expectedStatus: http.StatusBadRequest, + expectedBody: `{"status":400,"message":"bad request"}`, + }, + { + name: "generic error", + handler: func(c echo.Context) error { + return echo.NewHTTPError(http.StatusInternalServerError, "something went wrong") + }, + expectedStatus: http.StatusInternalServerError, + expectedBody: `{"status":500,"message":"something went wrong"}`, + }, + { + name: "validation error", + handler: func(c echo.Context) error { + return validator.ValidationErrors{} + }, + expectedStatus: http.StatusBadRequest, + expectedBody: `{"status":400,"message":"validation failed"}`, + }, + { + name: "with request id", + handler: func(c echo.Context) error { + c.Request().Header.Set(echo.HeaderXRequestID, "test-123") + return echo.NewHTTPError(http.StatusBadRequest, "bad request") + }, + expectedStatus: http.StatusBadRequest, + expectedBody: `{"status":400,"message":"bad request","request_id":"test-123"}`, + }, + } + + // run tests + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + req := httptest.NewRequest(http.MethodGet, "/", nil) + rec := httptest.NewRecorder() + c := e.NewContext(req, rec) + + err := tt.handler(c) + if err != nil { + e.HTTPErrorHandler(err, c) + } + + assert.Equal(t, tt.expectedStatus, rec.Code) + assert.JSONEq(t, tt.expectedBody, rec.Body.String()) + }) + } +} diff --git a/internal/server/index.go b/internal/server/index.go index f4f84a6..41778d2 100644 --- a/internal/server/index.go +++ b/internal/server/index.go @@ -41,6 +41,8 @@ func New() (*Server, error) { e := echo.New() + e.HTTPErrorHandler = globalErrorHandler + e.Use(middleware.Logger()) e.Use(echoMiddleware.Recover()) From 29d8719d9ae4f872b09e40ee0a24f4bbafb48da4 Mon Sep 17 00:00:00 2001 From: AmirAgassi <33383085+AmirAgassi@users.noreply.github.com> Date: Sun, 10 Nov 2024 23:35:56 -0500 Subject: [PATCH 02/14] Add error message check to validation test case --- internal/server/error_handler_test.go | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/internal/server/error_handler_test.go b/internal/server/error_handler_test.go index 65ae076..7544de9 100644 --- a/internal/server/error_handler_test.go +++ b/internal/server/error_handler_test.go @@ -41,10 +41,28 @@ func TestGlobalErrorHandler(t *testing.T) { { name: "validation error", handler: func(c echo.Context) error { - return validator.ValidationErrors{} + type TestStruct struct { + Email string `validate:"required,email"` + Age int `validate:"required,gt=0"` + } + + v := validator.New() + err := v.Struct(TestStruct{ + Email: "invalid-email", + Age: -1, + }) + + return err }, expectedStatus: http.StatusBadRequest, - expectedBody: `{"status":400,"message":"validation failed"}`, + expectedBody: `{ + "status": 400, + "message": "validation failed", + "errors": [ + "Key: 'TestStruct.Email' Error:Field validation for 'Email' failed on the 'email' tag", + "Key: 'TestStruct.Age' Error:Field validation for 'Age' failed on the 'gt' tag" + ] + }`, }, { name: "with request id", From 7d9e2cffe37d94fa6135519dc1d5820ecdccd857 Mon Sep 17 00:00:00 2001 From: AmirAgassi <33383085+AmirAgassi@users.noreply.github.com> Date: Mon, 11 Nov 2024 00:15:55 -0500 Subject: [PATCH 03/14] Update run-tests.yaml --- .github/workflows/run-tests.yaml | 49 +++++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 7 deletions(-) diff --git a/.github/workflows/run-tests.yaml b/.github/workflows/run-tests.yaml index 1bf8d23..a9f8106 100644 --- a/.github/workflows/run-tests.yaml +++ b/.github/workflows/run-tests.yaml @@ -1,8 +1,5 @@ name: Run Tests on: - push: - branches: - - 'main' pull_request: branches: ["main"] jobs: @@ -35,11 +32,49 @@ jobs: - name: Run migrations run: goose -dir .sqlc/migrations postgres "postgres://postgres:postgres@localhost:5432/postgres?sslmode=disable" up - name: Run tests - run: go test -v ./... - # Comment test results on the PR + run: go test -v -coverprofile=coverage.out ./... + - name: Generate coverage report + run: go tool cover -html=coverage.out -o coverage.html + - name: Upload coverage report + if: ${{ !env.ACT && github.event_name == 'pull_request' }} + uses: actions/upload-artifact@v4 + with: + name: coverage-report + path: coverage.html - name: Comment PR - if: github.event_name == 'pull_request' && always() + if: ${{ !env.ACT && github.event_name == 'pull_request' && always() }} uses: actions/github-script@v7 with: github-token: ${{ secrets.GITHUB_TOKEN }} - script: "const output = `#### Test Results\nTests: ${{ job.status }}\n\n*Workflow triggered by @${{ github.actor }}, ran on \\`${{ runner.os }}\\`*`;\n \ngithub.rest.issues.createComment({\n issue_number: context.issue.number,\n owner: context.repo.owner,\n repo: context.repo.repo,\n body: output\n})\n" + script: | + const testStatus = '${{ job.status }}'; + const color = testStatus === 'success' ? '✅' : '❌'; + const output = `### Test Results ${color} + + **Status**: ${testStatus} + **Coverage**: $(cat coverage.out | grep total | awk '{print $3}') + **OS**: \`${{ runner.os }}\` + +
+ Test Details + + * Triggered by: @${{ github.actor }} + * Commit: ${{ github.sha }} + * Branch: ${{ github.ref }} + * Workflow: ${{ github.workflow }} +
`; + + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: output + }) + - uses: actions/cache@v4 + with: + path: | + ~/.cache/go-build + ~/go/pkg/mod + key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} + restore-keys: | + ${{ runner.os }}-go- From 91144bdae5ccaefddd409429cdc3678041931429 Mon Sep 17 00:00:00 2001 From: AmirAgassi <33383085+AmirAgassi@users.noreply.github.com> Date: Mon, 11 Nov 2024 00:19:19 -0500 Subject: [PATCH 04/14] Fix coverage variable --- .github/workflows/run-tests.yaml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/run-tests.yaml b/.github/workflows/run-tests.yaml index a9f8106..9dff37e 100644 --- a/.github/workflows/run-tests.yaml +++ b/.github/workflows/run-tests.yaml @@ -47,12 +47,18 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | + const fs = require('fs'); + const coverage = fs.readFileSync('coverage.out', 'utf8') + .split('\n') + .find(line => line.includes('total:')) + ?.split('\t')[1] || 'N/A'; + const testStatus = '${{ job.status }}'; const color = testStatus === 'success' ? '✅' : '❌'; const output = `### Test Results ${color} **Status**: ${testStatus} - **Coverage**: $(cat coverage.out | grep total | awk '{print $3}') + **Coverage**: ${coverage} **OS**: \`${{ runner.os }}\`
From 3de1e304330d1ea52b02f0fca7d2d25755860f69 Mon Sep 17 00:00:00 2001 From: AmirAgassi <33383085+AmirAgassi@users.noreply.github.com> Date: Mon, 11 Nov 2024 00:27:35 -0500 Subject: [PATCH 05/14] Test coverage fix --- .github/workflows/run-tests.yaml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/run-tests.yaml b/.github/workflows/run-tests.yaml index 9dff37e..a963503 100644 --- a/.github/workflows/run-tests.yaml +++ b/.github/workflows/run-tests.yaml @@ -48,10 +48,8 @@ jobs: github-token: ${{ secrets.GITHUB_TOKEN }} script: | const fs = require('fs'); - const coverage = fs.readFileSync('coverage.out', 'utf8') - .split('\n') - .find(line => line.includes('total:')) - ?.split('\t')[1] || 'N/A'; + const coverageCmd = require('child_process').execSync('go tool cover -func=coverage.out | grep total:').toString(); + const coverage = coverageCmd.split('\t').pop().trim(); const testStatus = '${{ job.status }}'; const color = testStatus === 'success' ? '✅' : '❌'; From c357d6b32878fc86da5d3529750f6f8d918e91f1 Mon Sep 17 00:00:00 2001 From: AmirAgassi <33383085+AmirAgassi@users.noreply.github.com> Date: Mon, 11 Nov 2024 00:31:29 -0500 Subject: [PATCH 06/14] Test verbose fail output --- .github/workflows/run-tests.yaml | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/.github/workflows/run-tests.yaml b/.github/workflows/run-tests.yaml index a963503..ce590de 100644 --- a/.github/workflows/run-tests.yaml +++ b/.github/workflows/run-tests.yaml @@ -32,7 +32,12 @@ jobs: - name: Run migrations run: goose -dir .sqlc/migrations postgres "postgres://postgres:postgres@localhost:5432/postgres?sslmode=disable" up - name: Run tests - run: go test -v -coverprofile=coverage.out ./... + id: tests + continue-on-error: true # allows the workflow to continue even if tests fail + run: | + # run tests and tee output to both console and file + go test -v ./... 2>&1 | tee test_output.txt + echo "status=${?}" >> $GITHUB_OUTPUT # save exit code - name: Generate coverage report run: go tool cover -html=coverage.out -o coverage.html - name: Upload coverage report @@ -50,15 +55,34 @@ jobs: const fs = require('fs'); const coverageCmd = require('child_process').execSync('go tool cover -func=coverage.out | grep total:').toString(); const coverage = coverageCmd.split('\t').pop().trim(); - - const testStatus = '${{ job.status }}'; + + const testStatus = '${{ steps.tests.outputs.status }}' === '0' ? 'success' : 'failure'; const color = testStatus === 'success' ? '✅' : '❌'; + + let failureDetails = ''; + if (testStatus !== 'success') { + const testOutput = fs.readFileSync('test_output.txt', 'utf8'); + const failureMatches = testOutput.match(/--- FAIL:.*?(?=---|\z)/gs) || []; + + failureDetails = ` +
+ ❌ Test Failures + + \`\`\` + ${failureMatches.join('\n')} + \`\`\` +
+ `; + } + const output = `### Test Results ${color} **Status**: ${testStatus} **Coverage**: ${coverage} **OS**: \`${{ runner.os }}\` + ${failureDetails} +
Test Details From 431a4017e86880ece3401a2545d083b7c601ba49 Mon Sep 17 00:00:00 2001 From: AmirAgassi <33383085+AmirAgassi@users.noreply.github.com> Date: Mon, 11 Nov 2024 00:33:09 -0500 Subject: [PATCH 07/14] Actually generate the file --- .github/workflows/run-tests.yaml | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/.github/workflows/run-tests.yaml b/.github/workflows/run-tests.yaml index ce590de..fab12f9 100644 --- a/.github/workflows/run-tests.yaml +++ b/.github/workflows/run-tests.yaml @@ -35,8 +35,8 @@ jobs: id: tests continue-on-error: true # allows the workflow to continue even if tests fail run: | - # run tests and tee output to both console and file - go test -v ./... 2>&1 | tee test_output.txt + # run tests with coverage and tee output to both console and file + go test -v -coverprofile=coverage.out ./... 2>&1 | tee test_output.txt echo "status=${?}" >> $GITHUB_OUTPUT # save exit code - name: Generate coverage report run: go tool cover -html=coverage.out -o coverage.html @@ -53,8 +53,14 @@ jobs: github-token: ${{ secrets.GITHUB_TOKEN }} script: | const fs = require('fs'); - const coverageCmd = require('child_process').execSync('go tool cover -func=coverage.out | grep total:').toString(); - const coverage = coverageCmd.split('\t').pop().trim(); + let coverage = 'N/A'; + + try { + const coverageCmd = require('child_process').execSync('go tool cover -func=coverage.out | grep total:').toString(); + coverage = coverageCmd.split('\t').pop().trim(); + } catch (error) { + console.log('Failed to get coverage:', error); + } const testStatus = '${{ steps.tests.outputs.status }}' === '0' ? 'success' : 'failure'; const color = testStatus === 'success' ? '✅' : '❌'; From 0a92529a39e82e67e8eedcb4caa088fc01f93324 Mon Sep 17 00:00:00 2001 From: AmirAgassi <33383085+AmirAgassi@users.noreply.github.com> Date: Mon, 11 Nov 2024 00:34:29 -0500 Subject: [PATCH 08/14] Intentionally fail a test case to see output --- internal/server/auth_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/server/auth_test.go b/internal/server/auth_test.go index edf3b5b..de90937 100644 --- a/internal/server/auth_test.go +++ b/internal/server/auth_test.go @@ -95,7 +95,7 @@ func TestAuth(t *testing.T) { rec := httptest.NewRecorder() s.echoInstance.ServeHTTP(rec, req) - assert.Equal(t, http.StatusOK, rec.Code) + assert.Equal(t, http.StatusCreated, rec.Code) var response AuthResponse err := json.Unmarshal(rec.Body.Bytes(), &response) From 57d4df9da6da2c6051d8978ae102e4ebf6617181 Mon Sep 17 00:00:00 2001 From: AmirAgassi <33383085+AmirAgassi@users.noreply.github.com> Date: Mon, 11 Nov 2024 00:38:15 -0500 Subject: [PATCH 09/14] I understand it now --- .github/workflows/run-tests.yaml | 37 +++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/.github/workflows/run-tests.yaml b/.github/workflows/run-tests.yaml index fab12f9..3bffc42 100644 --- a/.github/workflows/run-tests.yaml +++ b/.github/workflows/run-tests.yaml @@ -33,11 +33,12 @@ jobs: run: goose -dir .sqlc/migrations postgres "postgres://postgres:postgres@localhost:5432/postgres?sslmode=disable" up - name: Run tests id: tests - continue-on-error: true # allows the workflow to continue even if tests fail + continue-on-error: true run: | - # run tests with coverage and tee output to both console and file + # run tests and capture output go test -v -coverprofile=coverage.out ./... 2>&1 | tee test_output.txt - echo "status=${?}" >> $GITHUB_OUTPUT # save exit code + # store the exit code explicitly + echo "::set-output name=exit_code::${PIPESTATUS[0]}" - name: Generate coverage report run: go tool cover -html=coverage.out -o coverage.html - name: Upload coverage report @@ -53,29 +54,39 @@ jobs: github-token: ${{ secrets.GITHUB_TOKEN }} script: | const fs = require('fs'); - let coverage = 'N/A'; + // Read test output + const testOutput = fs.readFileSync('test_output.txt', 'utf8'); + + // Check if any tests failed + const hasFailed = testOutput.includes('FAIL') && !testOutput.includes('FAIL\t[build failed]'); + const testStatus = hasFailed ? 'failure' : 'success'; + const color = testStatus === 'success' ? '✅' : '❌'; + + // Get coverage + let coverage = 'N/A'; try { - const coverageCmd = require('child_process').execSync('go tool cover -func=coverage.out | grep total:').toString(); - coverage = coverageCmd.split('\t').pop().trim(); + const coverageMatch = testOutput.match(/coverage: (\d+\.\d+)% of statements/); + coverage = coverageMatch ? coverageMatch[1] + '%' : 'N/A'; } catch (error) { console.log('Failed to get coverage:', error); } - const testStatus = '${{ steps.tests.outputs.status }}' === '0' ? 'success' : 'failure'; - const color = testStatus === 'success' ? '✅' : '❌'; - + // Parse test failures let failureDetails = ''; - if (testStatus !== 'success') { - const testOutput = fs.readFileSync('test_output.txt', 'utf8'); - const failureMatches = testOutput.match(/--- FAIL:.*?(?=---|\z)/gs) || []; + if (hasFailed) { + const failures = testOutput.match(/--- FAIL:.*?(?=(?:---|\z))/gs) || []; + const errors = testOutput.match(/\s+.*?_test\.go:\d+:.*?(?=\n\s*$)/gm) || []; failureDetails = `
❌ Test Failures \`\`\` - ${failureMatches.join('\n')} + ${failures.join('\n')} + + Error Details: + ${errors.join('\n')} \`\`\`
`; From 3d447eb751153280697752deeca4fac1cf996802 Mon Sep 17 00:00:00 2001 From: AmirAgassi <33383085+AmirAgassi@users.noreply.github.com> Date: Mon, 11 Nov 2024 00:40:38 -0500 Subject: [PATCH 10/14] Fix trace match --- .github/workflows/run-tests.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/run-tests.yaml b/.github/workflows/run-tests.yaml index 3bffc42..1bfaadd 100644 --- a/.github/workflows/run-tests.yaml +++ b/.github/workflows/run-tests.yaml @@ -75,8 +75,8 @@ jobs: // Parse test failures let failureDetails = ''; if (hasFailed) { - const failures = testOutput.match(/--- FAIL:.*?(?=(?:---|\z))/gs) || []; - const errors = testOutput.match(/\s+.*?_test\.go:\d+:.*?(?=\n\s*$)/gm) || []; + const errorTraces = testOutput.match(/\s+.*?_test\.go:\d+:[\s\S]*?Test:\s+.*$/gm) || []; + const failures = testOutput.match(/--- FAIL: .*?(?=(?:---|\z))/gs) || []; failureDetails = `
@@ -86,7 +86,7 @@ jobs: ${failures.join('\n')} Error Details: - ${errors.join('\n')} + ${errorTraces.map(trace => trace.trim()).join('\n')} \`\`\`
`; From 671790fa6f0a75b817e412098488463873a95813 Mon Sep 17 00:00:00 2001 From: AmirAgassi <33383085+AmirAgassi@users.noreply.github.com> Date: Mon, 11 Nov 2024 00:42:25 -0500 Subject: [PATCH 11/14] Fix coverage --- .github/workflows/run-tests.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/run-tests.yaml b/.github/workflows/run-tests.yaml index 1bfaadd..216ebdc 100644 --- a/.github/workflows/run-tests.yaml +++ b/.github/workflows/run-tests.yaml @@ -63,10 +63,10 @@ jobs: const testStatus = hasFailed ? 'failure' : 'success'; const color = testStatus === 'success' ? '✅' : '❌'; - // Get coverage + // Get coverage from the server package test output let coverage = 'N/A'; try { - const coverageMatch = testOutput.match(/coverage: (\d+\.\d+)% of statements/); + const coverageMatch = testOutput.match(/github\.com\/KonferCA\/NoKap\/internal\/server\s+(\d+\.\d+)%/); coverage = coverageMatch ? coverageMatch[1] + '%' : 'N/A'; } catch (error) { console.log('Failed to get coverage:', error); From cd901eaef97a33ec9dc1d0957806c29311d11e66 Mon Sep 17 00:00:00 2001 From: AmirAgassi <33383085+AmirAgassi@users.noreply.github.com> Date: Mon, 11 Nov 2024 00:44:34 -0500 Subject: [PATCH 12/14] Actually fix coverage lol --- .github/workflows/run-tests.yaml | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/.github/workflows/run-tests.yaml b/.github/workflows/run-tests.yaml index 216ebdc..2f3bb4a 100644 --- a/.github/workflows/run-tests.yaml +++ b/.github/workflows/run-tests.yaml @@ -58,20 +58,19 @@ jobs: // Read test output const testOutput = fs.readFileSync('test_output.txt', 'utf8'); + // Get coverage - look for the last coverage number in the output + let coverage = 'N/A'; + const coverageMatches = testOutput.match(/coverage: (\d+\.\d+)% of statements/g) || []; + if (coverageMatches.length > 0) { + const lastMatch = coverageMatches[coverageMatches.length - 1]; + coverage = lastMatch.match(/(\d+\.\d+)%/)[1] + '%'; + } + // Check if any tests failed const hasFailed = testOutput.includes('FAIL') && !testOutput.includes('FAIL\t[build failed]'); const testStatus = hasFailed ? 'failure' : 'success'; const color = testStatus === 'success' ? '✅' : '❌'; - // Get coverage from the server package test output - let coverage = 'N/A'; - try { - const coverageMatch = testOutput.match(/github\.com\/KonferCA\/NoKap\/internal\/server\s+(\d+\.\d+)%/); - coverage = coverageMatch ? coverageMatch[1] + '%' : 'N/A'; - } catch (error) { - console.log('Failed to get coverage:', error); - } - // Parse test failures let failureDetails = ''; if (hasFailed) { From 9b75e208078be8ddd73f6531040008f8053b8357 Mon Sep 17 00:00:00 2001 From: AmirAgassi <33383085+AmirAgassi@users.noreply.github.com> Date: Mon, 11 Nov 2024 00:46:11 -0500 Subject: [PATCH 13/14] "Fix" (undo) the test error --- internal/server/auth_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/server/auth_test.go b/internal/server/auth_test.go index de90937..edf3b5b 100644 --- a/internal/server/auth_test.go +++ b/internal/server/auth_test.go @@ -95,7 +95,7 @@ func TestAuth(t *testing.T) { rec := httptest.NewRecorder() s.echoInstance.ServeHTTP(rec, req) - assert.Equal(t, http.StatusCreated, rec.Code) + assert.Equal(t, http.StatusOK, rec.Code) var response AuthResponse err := json.Unmarshal(rec.Body.Bytes(), &response) From 742a85414088ba4d2bf5843acf580fdc2dc874ec Mon Sep 17 00:00:00 2001 From: AmirAgassi <33383085+AmirAgassi@users.noreply.github.com> Date: Mon, 11 Nov 2024 21:18:16 -0500 Subject: [PATCH 14/14] Update comments --- .github/workflows/run-tests.yaml | 34 ++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/.github/workflows/run-tests.yaml b/.github/workflows/run-tests.yaml index 2f3bb4a..445a5f7 100644 --- a/.github/workflows/run-tests.yaml +++ b/.github/workflows/run-tests.yaml @@ -1,5 +1,8 @@ name: Run Tests on: + push: + branches: + - 'main' pull_request: branches: ["main"] jobs: @@ -108,12 +111,35 @@ jobs: * Workflow: ${{ github.workflow }}
`; - github.rest.issues.createComment({ - issue_number: context.issue.number, + // Find existing comment + const { data: comments } = await github.rest.issues.listComments({ owner: context.repo.owner, repo: context.repo.repo, - body: output - }) + issue_number: context.issue.number, + }); + + const botComment = comments.find(comment => + comment.user.type === 'Bot' && + comment.body.includes('### Test Results') + ); + + if (botComment) { + // Update existing comment + await github.rest.issues.updateComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: botComment.id, + body: output + }); + } else { + // Create new comment + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + body: output + }); + } - uses: actions/cache@v4 with: path: |