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
7 changes: 4 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,16 @@ jobs:

- name: Install CLI
run: |
pip install codecov-cli
pip install uv
uv sync --project codecov-cli

- name: Create commit in codecov
run: |
codecovcli create-commit -t ${{ secrets.CODECOV_TOKEN }} --git-service github
uv run --project codecov-cli codecovcli -v create-commit -t ${{ secrets.CODECOV_TOKEN }} --git-service github

- name: Create commit report in codecov
run: |
codecovcli create-report -t ${{ secrets.CODECOV_TOKEN }} --git-service github
uv run --project codecov-cli codecovcli -v create-report -t ${{ secrets.CODECOV_TOKEN }} --git-service github

build-test-upload:
strategy:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ def _get_commit_sha(self):
completed_subprocess = subprocess.run(
["git", "rev-parse", "HEAD^@"], capture_output=True
)

parents_hash = completed_subprocess.stdout.decode().strip().splitlines()
if len(parents_hash) == 2:
return parents_hash[1]
Expand Down
2 changes: 1 addition & 1 deletion prevent-cli/preventcli_commands
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ Options:
brackets)
-b, --build, --build-code TEXT Specify the build number manually
--build-url TEXT The URL of the build where this is running
--job-code TEXT
--job-code TEXT Specify the job code manually
-n, --name TEXT Custom defined name of the upload. Visible
in Codecov UI
-B, --branch TEXT Branch to which this commit belongs to
Expand Down
2 changes: 2 additions & 0 deletions prevent-cli/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ authors = [{ name = "Sentry", email = "oss@sentry.io" }]
requires-python = ">=3.9"
dependencies = [
"codecov-cli==11.2.0",
"click==8.*",
"sentry-sdk==2.*",
]

[dependency-groups]
Expand Down
Empty file.
324 changes: 324 additions & 0 deletions prevent-cli/src/prevent_cli/commands/upload.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,324 @@
import logging
import os
import pathlib
import typing

import click
import sentry_sdk
from codecov_cli.fallbacks import CodecovOption, FallbackFieldEnum
from codecov_cli.helpers.args import get_cli_args
from codecov_cli.helpers.upload_type import report_type_from_str
from codecov_cli.opentelemetry import close_telem
from codecov_cli.services.upload_coverage import upload_coverage_logic

from prevent_cli.options import global_options


def _turn_env_vars_into_dict(ctx, params, value):
return dict((v, os.getenv(v, None)) for v in value)


_global_upload_options = [
click.option(
"--code",
"--report-code",
"report_code",
help="The code of the report. If unsure, leave default",
default="default",
hidden=True,
),
click.option(
"--network-root-folder",
help="Root folder from which to consider paths on the network section",
type=click.Path(path_type=pathlib.Path),
default=pathlib.Path.cwd,
show_default="Current working directory",
),
click.option(
"-s",
"--dir",
"--coverage-files-search-root-folder",
"--files-search-root-folder",
"files_search_root_folder",
help="Folder where to search for coverage files",
type=click.Path(path_type=pathlib.Path),
default=pathlib.Path.cwd,
show_default="Current Working Directory",
),
click.option(
"--exclude",
"--coverage-files-search-exclude-folder",
"--files-search-exclude-folder",
"files_search_exclude_folders",
help="Folders to exclude from search",
type=click.Path(path_type=pathlib.Path),
multiple=True,
default=[],
),
click.option(
"-f",
"--file",
"--coverage-files-search-direct-file",
"--files-search-direct-file",
"files_search_explicitly_listed_files",
help="Explicit files to upload. These will be added to the coverage files found for upload. If you wish to only upload the specified files, please consider using --disable-search to disable uploading other files.",
type=click.Path(path_type=pathlib.Path),
multiple=True,
default=[],
),
click.option(
"--recurse-submodules",
help="Whether to enumerate files inside of submodules for path-fixing purposes. Off by default.",
is_flag=True,
default=False,
),
click.option(
"--disable-search",
help="Disable search for coverage files. This is helpful when specifying what files you want to upload with the --file option.",
is_flag=True,
default=False,
),
click.option(
"--disable-file-fixes",
help="Disable file fixes to ignore common lines from coverage (e.g. blank lines or empty brackets)",
is_flag=True,
default=False,
),
click.option(
"-b",
"--build",
"--build-code",
"build_code",
cls=CodecovOption,
help="Specify the build number manually",
fallback_field=FallbackFieldEnum.build_code,
),
click.option(
"--build-url",
"build_url",
cls=CodecovOption,
help="The URL of the build where this is running",
fallback_field=FallbackFieldEnum.build_url,
),
click.option(
"--job-code",
cls=CodecovOption,
help="Specify the job code manually",
fallback_field=FallbackFieldEnum.job_code,
),
click.option(
"-n",
"--name",
help="Custom defined name of the upload. Visible in Codecov UI",
),
click.option(
"-B",
"--branch",
cls=CodecovOption,
help="Branch to which this commit belongs to",
fallback_field=FallbackFieldEnum.branch,
),
click.option(
"-P",
"--pr",
"--pull-request-number",
"pull_request_number",
cls=CodecovOption,
help="Specify the pull request number manually. Used to override pre-existing CI environment variables",
fallback_field=FallbackFieldEnum.pull_request_number,
),
click.option(
"-e",
"--env",
"--env-var",
"env_vars",
multiple=True,
callback=_turn_env_vars_into_dict,
help="Specify environment variables to be included with this build.",
),
click.option(
"-F",
"--flag",
"flags",
multiple=True,
default=[],
help="Flag the upload to group coverage metrics. Multiple flags allowed.",
),
click.option(
"--plugin",
"plugin_names",
multiple=True,
default=["xcode", "gcov", "pycoverage"],
),
click.option(
"-d",
"--dry-run",
"dry_run",
is_flag=True,
help="Don't upload files to Codecov",
),
click.option(
"--legacy",
"--use-legacy-uploader",
"use_legacy_uploader",
is_flag=True,
help="Use the legacy upload endpoint",
),
click.option(
"--handle-no-reports-found",
"handle_no_reports_found",
is_flag=True,
help="Raise no exceptions when no coverage reports found.",
),
click.option(
"--report-type",
"report_type_str",
help="The type of report to upload",
default="coverage",
type=click.Choice(["coverage", "test-results", "test_results"]),
),
click.option(
"--network-filter",
help="Specify a filter on the files listed in the network section of the Codecov report. This will only add files whose path begin with the specified filter. Useful for upload-specific path fixing",
),
click.option(
"--network-prefix",
help="Specify a prefix on files listed in the network section of the Codecov report. Useful to help resolve path fixing",
),
click.option(
"--gcov-args",
help="Extra arguments to pass to gcov",
),
click.option(
"--gcov-ignore",
help="Paths to ignore during gcov gathering",
),
click.option(
"--gcov-include",
help="Paths to include during gcov gathering",
),
click.option(
"--gcov-executable",
help="gcov executable to run. Defaults to 'gcov'",
),
click.option(
"--swift-project",
help="Specify the swift project",
),
click.option(
"--parent-sha",
help="SHA (with 40 chars) of what should be the parent of this commit",
),
]


def global_upload_options(func):
for option in reversed(_global_upload_options):
func = option(func)
return func


logger = logging.getLogger("codecovcli")


@click.command()
@global_options
@global_upload_options
@click.pass_context
def upload(
ctx: click.Context,
branch: typing.Optional[str],
build_code: typing.Optional[str],
build_url: typing.Optional[str],
commit_sha: str,
disable_file_fixes: bool,
disable_search: bool,
dry_run: bool,
env_vars: typing.Dict[str, str],
fail_on_error: bool,
files_search_exclude_folders: typing.List[pathlib.Path],
files_search_explicitly_listed_files: typing.List[pathlib.Path],
files_search_root_folder: pathlib.Path,
flags: typing.List[str],
gcov_args: typing.Optional[str],
gcov_executable: typing.Optional[str],
gcov_ignore: typing.Optional[str],
gcov_include: typing.Optional[str],
git_service: typing.Optional[str],
handle_no_reports_found: bool,
job_code: typing.Optional[str],
name: typing.Optional[str],
network_filter: typing.Optional[str],
network_prefix: typing.Optional[str],
network_root_folder: pathlib.Path,
parent_sha: typing.Optional[str],
plugin_names: typing.List[str],
pull_request_number: typing.Optional[str],
recurse_submodules: bool,
report_code: str,
report_type_str: str,
slug: typing.Optional[str],
swift_project: typing.Optional[str],
token: typing.Optional[str],
use_legacy_uploader: bool,
):
with sentry_sdk.start_transaction(op="task", name="Upload"):
with sentry_sdk.start_span(name="upload"):
args = get_cli_args(ctx)
logger.debug(
"Starting upload",
extra=dict(
extra_log_attributes=args,
),
)

report_type = report_type_from_str(report_type_str)

versioning_system = ctx.obj["versioning_system"]
codecov_yaml = ctx.obj["codecov_yaml"] or {}
cli_config = codecov_yaml.get("cli", {})
ci_adapter = ctx.obj.get("ci_adapter")
enterprise_url = ctx.obj.get("enterprise_url")

upload_coverage_logic(
cli_config,
versioning_system,
ci_adapter,
branch=branch,
build_code=build_code,
build_url=build_url,
commit_sha=commit_sha,
disable_file_fixes=disable_file_fixes,
disable_search=disable_search,
dry_run=dry_run,
enterprise_url=enterprise_url,
env_vars=env_vars,
fail_on_error=fail_on_error,
files_search_exclude_folders=files_search_exclude_folders,
files_search_explicitly_listed_files=files_search_explicitly_listed_files,
files_search_root_folder=files_search_root_folder,
flags=flags,
gcov_args=gcov_args,
gcov_executable=gcov_executable,
gcov_ignore=gcov_ignore,
gcov_include=gcov_include,
git_service=git_service,
handle_no_reports_found=handle_no_reports_found,
job_code=job_code,
name=name,
network_filter=network_filter,
network_prefix=network_prefix,
network_root_folder=network_root_folder,
parent_sha=parent_sha,
plugin_names=plugin_names,
pull_request_number=pull_request_number,
recurse_submodules=recurse_submodules,
report_code=report_code,
slug=slug,
swift_project=swift_project,
token=token,
report_type=report_type,
use_legacy_uploader=use_legacy_uploader,
args=args,
)
close_telem()
Loading
Loading