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: |