Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions .github/workflows/pr-coverage.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
name: pr-code-coverage

# Dogfoods this plugin on its own PRs: builds the plugin image from the PR
# source, computes coverage for only the lines changed in the PR, and posts a
# summary comment on the PR.

on:
pull_request:

permissions:
contents: read
pull-requests: write # required so the plugin can post the coverage comment

jobs:
coverage:
runs-on: ubuntu-latest
# Fork PRs only get a read-only GITHUB_TOKEN (can't comment) and no secrets,
# so restrict to same-repo PRs to avoid a guaranteed failure on forks.
if: github.event.pull_request.head.repo.full_name == github.repository
steps:
- name: Check out the repo
uses: actions/checkout@v4
with:
fetch-depth: 0 # need the base branch present to diff against it

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: 1.26.3

- name: Generate coverage profile
run: go test -coverpkg=./... -coverprofile=coverage.txt ./...

- name: Convert coverage to cobertura
# go run leaves no installed binary; boumenot emits <source> as the
# absolute build dir (== github.workspace) and class filenames relative
# to the module root, which is what PARAMETER_SOURCE_DIRS matches against.
run: go run github.com/boumenot/gocover-cobertura@v1.5.0 < coverage.txt > coverage.xml

- name: Build plugin image
# The published :latest image predates the public-github.com base-URL fix,
# so build from the PR source to test the exact code under review.
run: docker build -t pr-code-coverage:ci .

- name: Report coverage on changed lines
env:
PARAMETER_COVERAGE_TYPE: cobertura
PARAMETER_COVERAGE_FILE: coverage.xml
# Must equal the cobertura <source> path (the dir go test ran in).
PARAMETER_SOURCE_DIRS: ${{ github.workspace }}
# Omit PARAMETER_GH_API_BASE_URL -> defaults to https://api.github.com.
PARAMETER_GH_API_KEY: ${{ secrets.GITHUB_TOKEN }}
BUILD_PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number }}
REPOSITORY_ORG: ${{ github.repository_owner }}
REPOSITORY_NAME: ${{ github.event.repository.name }}
run: |
git fetch --no-tags origin "${{ github.base_ref }}"
git --no-pager diff --unified=0 "origin/${{ github.base_ref }}" -- '*.go' \
| docker run --rm -i \
-e PARAMETER_COVERAGE_TYPE \
-e PARAMETER_COVERAGE_FILE \
-e PARAMETER_SOURCE_DIRS \
-e PARAMETER_GH_API_KEY \
-e BUILD_PULL_REQUEST_NUMBER \
-e REPOSITORY_ORG \
-e REPOSITORY_NAME \
-v "${{ github.workspace }}:${{ github.workspace }}" \
-w "${{ github.workspace }}" \
--entrypoint /plugin \
pr-code-coverage:ci
10 changes: 5 additions & 5 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,17 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Check out the repo
uses: actions/checkout@v2
uses: actions/checkout@v4
- name: Docker Login
uses: docker/login-action@v1
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Docker Build and Push
id: docker_build
uses: docker/build-push-action@v2
uses: docker/build-push-action@v6
with:
push: true
tags: |
target/pull-request-code-coverage:latest
target/pull-request-code-coverage:${{ github.event.release.tag_name }}
pullrequestcc/pull-request-code-coverage:latest
pullrequestcc/pull-request-code-coverage:${{ github.event.release.tag_name }}
6 changes: 3 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v2
uses: actions/setup-go@v5
with:
go-version: 1.17
go-version: 1.26.3

- name: Build
run: go build -v ./...
Expand Down
34 changes: 15 additions & 19 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -1,39 +1,35 @@
version: "2"

linters:
disable-all: true
default: none
enable:
- bodyclose
- deadcode
- depguard
- dogsled
- errcheck
- gochecknoinits
- goconst
- gocritic
- gocyclo
- gofmt
- goimports
- golint
- goprintffuncname
- gosec
- govet
- ineffassign
- interfacer
- maligned
- misspell
- nakedret
- rowserrcheck
- scopelint
- staticcheck
- structcheck
- stylecheck
- typecheck
- unconvert
- unparam
- unused
- varcheck
issues:
exclude-rules:
- path: _test\.go
linters:
- scopelint
- funlen
exclusions:
rules:
- path: _test\.go
linters:
- funlen
- goconst
- gosec

formatters:
enable:
- gofmt
- goimports
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM golang:1.17-alpine as builder
FROM golang:1.26.3-alpine AS builder
WORKDIR /go/src/github.com/target/pull-request-code-coverage
COPY . .
ENV GO111MODULE=on
Expand Down
4 changes: 3 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@ check-gofmt:
echo "Success - way to run gofmt!"; \
fi

GOLANGCI_LINT_VERSION=v2.12.2

bin/golangci-lint:
mkdir -p bin
wget -O- -nv https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s v1.24.0
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/HEAD/install.sh | sh -s -- -b ./bin $(GOLANGCI_LINT_VERSION)

.PHONY: lint
lint: bin/golangci-lint
Expand Down
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -92,7 +96,7 @@ Once you have coverage.xml same can be passed as an input to plugin shown below

# Development

This project needs go (>= 1.17) to be installed. Make sure you run
This project needs go (>= 1.26.3) to be installed. Make sure you run
* make format
* make lint

Expand Down
13 changes: 6 additions & 7 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
module github.com/target/pull-request-code-coverage

go 1.17
go 1.26.3

require (
github.com/pkg/errors v0.9.1
github.com/sirupsen/logrus v1.8.1
github.com/stretchr/testify v1.7.0

github.com/sirupsen/logrus v1.9.4
github.com/stretchr/testify v1.11.1
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/stretchr/objx v0.1.0 // indirect
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 // indirect
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect
github.com/stretchr/objx v0.5.3 // indirect
golang.org/x/sys v0.44.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
22 changes: 10 additions & 12 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
github.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w=
github.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC42RjbV2g=
github.com/stretchr/objx v0.5.3 h1:jmXUvGomnU1o3W/V5h2VEradbpJDwGrzugQQvL0POH4=
github.com/stretchr/objx v0.5.3/go.mod h1:rDQraq+vQZU7Fde9LOZLr8Tax6zZvy4kuNKF+QYS+U0=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
golang.org/x/sys v0.44.0 h1:ildZl3J4uzeKP07r2F++Op7E9B29JRUy+a27EibtBTQ=
golang.org/x/sys v0.44.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
3 changes: 1 addition & 2 deletions internal/plugin/coverage/cobertura/report.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package cobertura
import (
"encoding/xml"
"io"
"io/ioutil"

"log"
"os"
Expand All @@ -22,7 +21,7 @@ type DefaultLoader struct {

func NewReportLoader(sourceDir string) *DefaultLoader {
return &DefaultLoader{
readAllFunc: ioutil.ReadAll,
readAllFunc: io.ReadAll,
sourceDir: sourceDir,
}
}
Expand Down
7 changes: 3 additions & 4 deletions internal/plugin/coverage/jacoco/report.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"encoding/xml"

"io"
"io/ioutil"

"log"
"os"
Expand All @@ -20,12 +19,12 @@ type DefaultLoader struct {

func NewReportLoader() *DefaultLoader {
return &DefaultLoader{
readAllFunc: ioutil.ReadAll,
readAllFunc: io.ReadAll,
}
}

func (l *DefaultLoader) Load(coverageFile string) (coverage.Report, error) {
// nolint: gosec
// nolint: gosec // coverageFile is a user-supplied report path; opening it is the intended behavior
xmlFile, openFileErr := os.Open(coverageFile)

if openFileErr != nil {
Expand Down Expand Up @@ -96,7 +95,7 @@ type SourceFile struct {
func (f SourceFile) GetCoverageData(lineNumber int) (*domain.CoverageData, bool) {
for _, l := range f.Lines {
if l.LineNumber == lineNumber {
coverageData := l.CoverageData.toDomain()
coverageData := l.toDomain()
return &coverageData, true
}
}
Expand Down
1 change: 1 addition & 0 deletions internal/plugin/pluginhttp/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@ func (c *DefaultClient) NewRequest(method string, url string, body io.Reader) (*
}

func (c *DefaultClient) Do(request *http.Request) (*http.Response, error) {
// nolint: gosec // the request targets the user-configured GitHub API URL, which is the intended behavior
return http.DefaultClient.Do(request)
}
Loading
Loading