Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Code coverage: fix the code coverage pipeline #41375

Merged
merged 2 commits into from
Jun 26, 2021
Merged
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
136 changes: 120 additions & 16 deletions .buildkite/coverage-linux64/upload_coverage.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,24 @@ Pkg.precompile()

import Coverage

function process_folders()
# `Coverage.process_folder` will have a LOT of `@info` statements that will make the log
# way too long. So before we run `Coverage.process_folder`, we disable logging for `@info`
# statements. After we run `Coverage.process_folder`, we re-enable logging for `@info`
# statements.
Logging.disable_logging(Logging.Info)
fcs_base = Coverage.process_folder("base");
fcs_stdlib = Coverage.process_folder("stdlib");
Logging.disable_logging(Logging.Debug)

fcs = Coverage.merge_coverage_counts(
fcs_base,
fcs_stdlib,
);

return fcs
end

function get_external_stdlib_names(stdlib_dir::AbstractString)
filename_list = filter(x -> isfile(joinpath(stdlib_dir, x)), readdir(stdlib_dir))
# find all of the files like `Pkg.version`, `Statistics.version`, etc.
Expand Down Expand Up @@ -76,16 +94,90 @@ function print_coverage_summary(
return nothing
end

# `Coverage.process_folder` will have a LOT of `@info` statements that will make the log
# way too long. So before we run `Coverage.process_folder`, we disable logging for `@info`
# statements. After we run `Coverage.process_folder`, we re-enable logging for `@info`
# statements.
Logging.disable_logging(Logging.Info)
const fcs = Coverage.merge_coverage_counts(
Coverage.process_folder("base"),
Coverage.process_folder("stdlib"),
);
Logging.disable_logging(Logging.Debug)
function buildkite_env(name::String)
value = String(strip(ENV[name]))
if isempty(value)
throw(ErrorException("environment variable $(name) is empty"))
end
return value
end

function buildkite_env(name_1::String, name_2::String, default::String)
value_1 = String(strip(ENV[name_1]))
value_2 = String(strip(ENV[name_2]))
!isempty(value_1) && return value_1
!isempty(value_2) && return value_2
return default
end

function buildkite_branch_and_commit()
branch = buildkite_env("BUILDKITE_BRANCH")
commit = buildkite_env("BUILDKITE_COMMIT")
head_rev_parse = String(strip(read(`git rev-parse HEAD`, String)))
if strip(commit) == "HEAD"
commit = head_rev_parse
end
if commit !== head_rev_parse
msg = "mismatch"
@error msg commit head_rev_parse
throw(ErrorException(msg))
end
if !occursin(r"^[a-f0-9]{40}$", commit)
msg = "BUILDKITE_COMMIT does not look like a long commit SHA"
@error msg commit
throw(ErrorException(msg))
end
return (; branch, commit)
end

function codecov_buildkite_add_local_to_kwargs()
branch, commit = buildkite_branch_and_commit()
kwargs = Coverage.Codecov.set_defaults(
Dict();
branch,
commit,
)
return kwargs
end

function coveralls_buildkite_query_git_info()
branch, commit = buildkite_branch_and_commit()
remote_name = "origin"
remote = buildkite_env("BUILDKITE_REPO")
message = buildkite_env("BUILDKITE_MESSAGE")
author_name = buildkite_env(
"BUILDKITE_BUILD_AUTHOR",
"BUILDKITE_BUILD_CREATOR",
"",
)
author_email = buildkite_env(
"BUILDKITE_BUILD_AUTHOR_EMAIL",
"BUILDKITE_BUILD_CREATOR_EMAIL",
"",
)
remotes = [
Dict(
"name" => remote_name,
"url" => remote,
)
]
head = Dict(
"id" => commit,
"author_name" => author_name,
"author_email" => author_email,
"committer_name" => author_name,
"committer_email" => author_email,
"message" => message,
)
git_info = Dict(
"branch" => branch,
"remotes" => remotes,
"head" => head,
)
return git_info
end

const fcs = process_folders()

# Only include source code files. Exclude test files, benchmarking files, etc.
filter!(fcs) do fc
Expand All @@ -101,15 +193,27 @@ end;
# Exclude all stdlib JLLs (stdlibs of the form `stdlib/*_jll/`).
filter!(fcs) do fc
!occursin(r"^stdlib\/[A-Za-z0-9]*?_jll\/", fc.filename)
end
end;

sort!(fcs; by = fc -> fc.filename)
sort!(fcs; by = fc -> fc.filename);

print_coverage_summary.(fcs);
print_coverage_summary(fcs, "Total")

# In order to upload to Codecov, you need to have the `CODECOV_TOKEN` environment variable defined.
Coverage.Codecov.submit_local(fcs)
let
git_info = coveralls_buildkite_query_git_info()
@info "" git_info
@info "" git_info["branch"]
@info "" git_info["head"]

# In order to upload to Coveralls, you need to have the `COVERALLS_TOKEN` environment variable defined.
Coverage.Coveralls.submit_local(fcs)
# In order to upload to Coveralls, you need to have the `COVERALLS_TOKEN` environment variable defined.
Coverage.Coveralls.submit_local(fcs, git_info)
end

let
kwargs = codecov_buildkite_add_local_to_kwargs()
@info "" kwargs

# In order to upload to Codecov, you need to have the `CODECOV_TOKEN` environment variable defined.
Coverage.Codecov.submit_generic(fcs, kwargs)
end