From 6c78ba16d8cb4bba2825febd1f9c6e943c6cce18 Mon Sep 17 00:00:00 2001 From: Vishal Vaibhav Date: Thu, 21 May 2026 14:27:40 +0530 Subject: [PATCH] feat: github url --- README.md | 8 +++- internal/plugin/reporter/github_pr.go | 2 +- internal/plugin/reporter/github_pr_test.go | 44 ++++++++++++++++++++++ internal/plugin/runner.go | 12 ++++-- internal/plugin/runner_test.go | 12 +++--- 5 files changed, 66 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index a351c2a..75e11cd 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,9 @@ this project. Once you have that jacoco file, you can pass that path to coverage source_dirs: - src/main/java - src/main/kotlin - gh_api_base_url: https://git.target.com + # omit for public github.com (defaults to https://api.github.com) + # for GitHub Enterprise, use the full API root including /api/v3 + gh_api_base_url: https://git.target.com/api/v3 module: some-sub-module secrets: - source: pull_request_api_key @@ -73,7 +75,9 @@ Once you have coverage.xml same can be passed as an input to plugin shown below coverage_file: coverage.xml source_dirs: - /vela/src/github.com/targetOSS/pull-request-code-coverage - gh_api_base_url: https://git.target.com + # omit for public github.com (defaults to https://api.github.com) + # for GitHub Enterprise, use the full API root including /api/v3 + gh_api_base_url: https://git.target.com/api/v3 secrets: - source: pull_request_api_key target: plugin_gh_api_key diff --git a/internal/plugin/reporter/github_pr.go b/internal/plugin/reporter/github_pr.go index addaaee..5aca6b8 100644 --- a/internal/plugin/reporter/github_pr.go +++ b/internal/plugin/reporter/github_pr.go @@ -50,7 +50,7 @@ func (s *GithubPullRequest) Write(changedLinesWithCoverage domain.SourceLineCove return errors.Wrap(bodyErr, "Failed creating payload for github") } - url := fmt.Sprintf("%v/api/v3/repos/%v/%v/issues/%v/comments", s.apiBaseURL, s.owner, s.repo, s.pr) + url := fmt.Sprintf("%v/repos/%v/%v/issues/%v/comments", strings.TrimRight(s.apiBaseURL, "/"), s.owner, s.repo, s.pr) req, newErr := s.httpClient.NewRequest( "POST", diff --git a/internal/plugin/reporter/github_pr_test.go b/internal/plugin/reporter/github_pr_test.go index e342038..be239c1 100644 --- a/internal/plugin/reporter/github_pr_test.go +++ b/internal/plugin/reporter/github_pr_test.go @@ -87,6 +87,50 @@ func TestGithubPullRequest_Write_FailedDo_BadStatus(t *testing.T) { assert.EqualError(t, e, "Failed calling github: bad status code: 400") } +func TestGithubPullRequest_Write_BuildsPublicGithubURL(t *testing.T) { + + mockClient := &pluginhttp.MockClient{} + request := httptest.NewRequest("POST", "http://anywhere", nil) + + mockClient.On("NewRequest", "POST", "https://api.github.com/repos/some_owner/some_repo/issues/42/comments", mock.Anything).Return(request, nil) + mockClient.On("Do", request).Return(&http.Response{StatusCode: 201, Body: io.NopCloser(strings.NewReader(""))}, nil) + + writer := NewGithubPullRequest("KEY", "https://api.github.com", "42", "some_owner", "some_repo", mockClient, &pluginjson.DefaultClient{}) + + e := writer.Write(domain.SourceLineCoverageReport{ + domain.SourceLineCoverage{ + CoverageData: domain.CoverageData{ + CoveredInstructionCount: 1, + }, + }, + }) + + assert.NoError(t, e) + mockClient.AssertExpectations(t) +} + +func TestGithubPullRequest_Write_TrimsTrailingSlashFromEnterpriseURL(t *testing.T) { + + mockClient := &pluginhttp.MockClient{} + request := httptest.NewRequest("POST", "http://anywhere", nil) + + mockClient.On("NewRequest", "POST", "https://git.target.com/api/v3/repos/some_owner/some_repo/issues/42/comments", mock.Anything).Return(request, nil) + mockClient.On("Do", request).Return(&http.Response{StatusCode: 201, Body: io.NopCloser(strings.NewReader(""))}, nil) + + writer := NewGithubPullRequest("KEY", "https://git.target.com/api/v3/", "42", "some_owner", "some_repo", mockClient, &pluginjson.DefaultClient{}) + + e := writer.Write(domain.SourceLineCoverageReport{ + domain.SourceLineCoverage{ + CoverageData: domain.CoverageData{ + CoveredInstructionCount: 1, + }, + }, + }) + + assert.NoError(t, e) + mockClient.AssertExpectations(t) +} + func TestGithubPullRequest_Write_FailedJsonMarshal(t *testing.T) { mockClient := &pluginjson.MockClient{} diff --git a/internal/plugin/runner.go b/internal/plugin/runner.go index 032a99b..a8aea04 100644 --- a/internal/plugin/runner.go +++ b/internal/plugin/runner.go @@ -18,6 +18,11 @@ import ( "github.com/target/pull-request-code-coverage/internal/plugin/sourcelines/unifieddiff" ) +// defaultGithubAPIBaseURL is the public GitHub REST API root. GitHub Enterprise +// users should set PARAMETER_GH_API_BASE_URL to their API root (e.g. +// https://git.example.com/api/v3). +const defaultGithubAPIBaseURL = "https://api.github.com" + type DefaultRunner struct{} func NewRunner() *DefaultRunner { @@ -66,8 +71,9 @@ func (*DefaultRunner) Run(propertyGetter func(string) (string, bool), changedSou } ghAPIBaseURL, ghAPIBaseURLFound := propertyGetter("PARAMETER_GH_API_BASE_URL") - if !ghAPIBaseURLFound { - logrus.Info("PARAMETER_GH_API_BASE_URL was missing, will not send report to PR comments") + if !ghAPIBaseURLFound || ghAPIBaseURL == "" { + ghAPIBaseURL = defaultGithubAPIBaseURL + logrus.Info(fmt.Sprintf("PARAMETER_GH_API_BASE_URL was missing, defaulting to %v", ghAPIBaseURL)) } repoPR, repoPRFound := propertyGetter("BUILD_PULL_REQUEST_NUMBER") @@ -112,7 +118,7 @@ func (*DefaultRunner) Run(propertyGetter func(string) (string, bool), changedSou reporters := []reporter.Reporter{reporter.NewSimple(reportDefaultOut)} - if ghAPIKeyFound && ghAPIBaseURLFound && repoPRFound && repoOwnerFound && repoNameFound { + if ghAPIKeyFound && repoPRFound && repoOwnerFound && repoNameFound { reporters = append(reporters, reporter.NewGithubPullRequest(ghAPIKey, ghAPIBaseURL, repoPR, repoOwner, repoName, &pluginhttp.DefaultClient{}, &pluginjson.DefaultClient{})) } logrus.Info("enabled reporters are ") diff --git a/internal/plugin/runner_test.go b/internal/plugin/runner_test.go index 7529ed6..381a2d8 100644 --- a/internal/plugin/runner_test.go +++ b/internal/plugin/runner_test.go @@ -107,7 +107,7 @@ Covered Instructions -> 97% (177) Missed Instructions -> 3% (5) `, buf.String()) - requestAsserter.AssertRequestWasMade(t, "/api/v3/repos/some_org/some_repo/issues/123/comments", "SOME_API_KEY", map[string]interface{}{ + requestAsserter.AssertRequestWasMade(t, "/repos/some_org/some_repo/issues/123/comments", "SOME_API_KEY", map[string]interface{}{ "body": `Code Coverage Summary: Lines Without Coverage Data -> 92% (2216) @@ -178,7 +178,7 @@ Covered Instructions -> 97% (177) Missed Instructions -> 3% (5) `, buf.String()) - requestAsserter.AssertRequestWasMade(t, "/api/v3/repos/some_org/some_repo/issues/123/comments", "SOME_API_KEY", map[string]interface{}{ + requestAsserter.AssertRequestWasMade(t, "/repos/some_org/some_repo/issues/123/comments", "SOME_API_KEY", map[string]interface{}{ "body": `Code Coverage Summary: Lines Without Coverage Data -> 92% (2216) @@ -239,7 +239,7 @@ Covered Instructions -> 73% (8) Missed Instructions -> 27% (3) `, buf.String()) - requestAsserter.AssertRequestWasMade(t, "/api/v3/repos/some_org/some_repo/issues/123/comments", "SOME_API_KEY", map[string]interface{}{ + requestAsserter.AssertRequestWasMade(t, "/repos/some_org/some_repo/issues/123/comments", "SOME_API_KEY", map[string]interface{}{ "body": `*Modules: category-search* Code Coverage Summary: @@ -295,7 +295,7 @@ Covered Instructions -> 73% (8) Missed Instructions -> 27% (3) `, buf.String()) - requestAsserter.AssertRequestWasMade(t, "/api/v3/repos/some_org/some_repo/issues/123/comments", "SOME_API_KEY", map[string]interface{}{ + requestAsserter.AssertRequestWasMade(t, "/repos/some_org/some_repo/issues/123/comments", "SOME_API_KEY", map[string]interface{}{ "body": `*Modules: category-search* Code Coverage Summary: @@ -353,7 +353,7 @@ Covered Instructions -> 88% (42) Missed Instructions -> 12% (6) `, buf.String()) - requestAsserter.AssertRequestWasMade(t, "/api/v3/repos/some_org/some_repo/issues/123/comments", "SOME_API_KEY", map[string]interface{}{ + requestAsserter.AssertRequestWasMade(t, "/repos/some_org/some_repo/issues/123/comments", "SOME_API_KEY", map[string]interface{}{ "body": `*Modules: category-search* Code Coverage Summary: @@ -413,7 +413,7 @@ Covered Instructions -> 88% (42) Missed Instructions -> 12% (6) `, buf.String()) - requestAsserter.AssertRequestWasMade(t, "/api/v3/repos/some_org/some_repo/issues/123/comments", "SOME_API_KEY", map[string]interface{}{ + requestAsserter.AssertRequestWasMade(t, "/repos/some_org/some_repo/issues/123/comments", "SOME_API_KEY", map[string]interface{}{ "body": `*Modules: category-search* Code Coverage Summary: