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

Restore missing commits #263

Merged
merged 15 commits into from
Sep 13, 2023
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
115 changes: 111 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ jobs:
### Basic usage without external contributors

If you don't expect external contributors, you don't need all the shenanigans
with the artifacts and the 2nd workflow. This is likely to be the most straightfoward
with the artifacts and the 2nd workflow. This is likely to be the most straightforward
way to configure it for private repositories. It might look like this:

```yaml
Expand Down Expand Up @@ -198,7 +198,6 @@ jobs:
run: make test # This is the part where you put your own test command

- name: Coverage comment
id: coverage_comment
uses: py-cov-action/python-coverage-comment-action@v3
with:
GITHUB_TOKEN: ${{ github.token }}
Expand Down Expand Up @@ -327,14 +326,25 @@ jobs:
COMMENT_ARTIFACT_NAME: python-coverage-comment-action

# Name of the file in which the body of the comment to post on the PR is stored.
# You typically don't have to change this unless you're already using this name for something else.
# In monorepo setting, see SUBPROJECT_ID.
COMMENT_FILENAME: python-coverage-comment-action.txt

# This setting is only necessary if you plan to run the action multiple times
# in the same repository. It will be appended to the value of all the
# settings that need to be unique, so as for the action to avoid mixing
# up results of multiple runs.
# Affects `COMMENT_FILENAME`, `COVERAGE_DATA_BRANCH`.
# Ideally, use dashes (`-`) rather than underscrores (`_`) to split words,
# for consistency
SUBPROJECT_ID: null / "lib-name"

# An alternative template for the comment for pull requests. See details below.
COMMENT_TEMPLATE: The coverage rate is `{{ coverage.info.percent_covered | pct }}`{{ marker }}

# Name of the branch in which coverage data will be stored on the repository.
# Please make sure that this branch is not protected.
# Default is 'python-coverage-comment-action-data'. Please make sure that this
# branch is not protected.
# In monorepo setting, see SUBPROJECT_ID.
COVERAGE_DATA_BRANCH: python-coverage-comment-action-data

# Deprecated, see https://docs.github.com/en/actions/monitoring-and-troubleshooting-workflows/enabling-debug-logging
Expand Down Expand Up @@ -383,6 +393,103 @@ coverage (percentage) of the whole project from the PR build:
"Coverage: {{ coverage.info.percent_covered | pct }}{{ marker }}"
```

## Monorepo setting

In case you want to use the action multiple times with different parts of your
source (so you have multiple codebases into a single repo), you'll
need to use SUBPROJECT_ID with a different value for each launch. You may
still use the same step for storing all files as artifacts. You'll end up with
a different comment for each launch. Feel free to use the `COMMENT_TEMPLATE` if
you want each comment to clearly state what it relates to.

```yaml
# .github/workflows/ci.yml
name: CI

on:
pull_request:
push:
branches:
- "main"

jobs:
test:
name: Run tests & display coverage
runs-on: ubuntu-latest
permissions:
pull-requests: write
contents: write
steps:
- uses: actions/checkout@v3

- name: Test project 1
run: make -C project_1 test

- name: Test project 2
run: make -C project_2 test

- name: Coverage comment (project 1)
id: coverage_comment_1
uses: py-cov-action/python-coverage-comment-action@v3
with:
COVERAGE_PATH: project_1
SUBPROJECT_ID: project-1
GITHUB_TOKEN: ${{ github.token }}

- name: Coverage comment (project 2)
id: coverage_comment_2
uses: py-cov-action/python-coverage-comment-action@v3
with:
COVERAGE_PATH: project_2/src
SUBPROJECT_ID: project-2
GITHUB_TOKEN: ${{ github.token }}

- name: Store Pull Request comment to be posted
uses: actions/upload-artifact@v3
if: steps.coverage_comment_1.outputs.COMMENT_FILE_WRITTEN == 'true' || steps.coverage_comment_2.outputs.COMMENT_FILE_WRITTEN == 'true'
with:
name: python-coverage-comment-action
# Note the star
path: python-coverage-comment-action*.txt
```

```yaml
# .github/workflows/coverage.yml
name: Post coverage comment

on:
workflow_run:
workflows: ["CI"]
types:
- completed

jobs:
test:
name: Run tests & display coverage
runs-on: ubuntu-latest
if: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success'
permissions:
pull-requests: write
contents: write
actions: read
steps:
- name: Post comment
uses: py-cov-action/python-coverage-comment-action@v3
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_PR_RUN_ID: ${{ github.event.workflow_run.id }}
SUBPROJECT_ID: project-1
COVERAGE_PATH: project_1

- name: Post comment
uses: py-cov-action/python-coverage-comment-action@v3
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_PR_RUN_ID: ${{ github.event.workflow_run.id }}
SUBPROJECT_ID: project-2
COVERAGE_PATH: project_2/src
```

# Other topics

## Pinning
Expand Down
23 changes: 20 additions & 3 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ inputs:
Name of the branch in which coverage data will be stored on the repository.
Default is 'python-coverage-comment-action-data'. Please make sure that this
branch is not protected.
In monorepo setting, see SUBPROJECT_ID.
default: python-coverage-comment-action-data
required: false
COVERAGE_PATH:
Expand All @@ -38,13 +39,25 @@ inputs:
COMMENT_ARTIFACT_NAME:
description: >
Name of the artifact in which the body of the comment to post on the PR is stored.
You typically don't have to change this unless you're already using this name for something else.
default: python-coverage-comment-action
required: false
COMMENT_FILENAME:
description: >
Name of the file in which the body of the comment to post on the PR is stored.
In monorepo setting, see SUBPROJECT_ID.
default: python-coverage-comment-action.txt
required: false
SUBPROJECT_ID:
description: >
This setting is only necessary if you plan to run the action multiple
times in the same repository. It will be appended to the value of all the
settings that need to be unique, so as for the action to avoid mixing up
results of multiple runs. Ideally, use dashes (`-`) rather than
underscrores (`_`) to split words, for consistency.
Affects `COMMENT_FILENAME`, `COVERAGE_DATA_BRANCH`.
default: null
required: false
MINIMUM_GREEN:
description: >
If the coverage percentage is above or equal to this value, the badge
Expand All @@ -67,7 +80,7 @@ inputs:
default: false
ANNOTATION_TYPE:
description: >
Only needed if ANNOTATE_MISSING_LINES is set to true. This parameter allows you to choose between
Only relevant if ANNOTATE_MISSING_LINES is set to true. This parameter allows you to choose between
notice, warning and error as annotation type. For more information look here:
https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-a-notice-message
default: warning
Expand All @@ -78,8 +91,11 @@ inputs:
outputs:
COMMENT_FILE_WRITTEN:
description: >
If "true", a comment file was written to COMMENT_FILENAME. If "false",
no comment file was written (because the comment was already posted).
This output is only set when running in PR mode. It's a boolean indicating
whether a comment file was written to COMMENT_FILENAME or not. If so,
you'll need to run the action in workflow_run mode to post it. If
"false", no comment file was written (likely because the comment was
already posted to the PR).
runs:
using: docker
image: Dockerfile
Expand All @@ -91,6 +107,7 @@ runs:
COVERAGE_PATH: ${{ inputs.COVERAGE_PATH }}
COMMENT_ARTIFACT_NAME: ${{ inputs.COMMENT_ARTIFACT_NAME }}
COMMENT_FILENAME: ${{ inputs.COMMENT_FILENAME }}
SUBPROJECT_ID: ${{ inputs.SUBPROJECT_ID }}
MINIMUM_GREEN: ${{ inputs.MINIMUM_GREEN }}
MINIMUM_ORANGE: ${{ inputs.MINIMUM_ORANGE }}
MERGE_COVERAGE_FILES: ${{ inputs.MERGE_COVERAGE_FILES }}
Expand Down
3 changes: 3 additions & 0 deletions coverage_comment/communication.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ def get_readme_and_log(
html_report_url: str,
markdown_report: str,
is_public: bool,
subproject_id: str | None = None,
) -> tuple[files.WriteFile, str]:
readme_markdown = template.get_readme_markdown(
is_public=is_public,
Expand All @@ -18,6 +19,7 @@ def get_readme_and_log(
direct_image_url=image_urls["direct"],
endpoint_image_url=image_urls["endpoint"],
dynamic_image_url=image_urls["dynamic"],
subproject_id=subproject_id,
)
log_message = template.get_log_message(
is_public=is_public,
Expand All @@ -26,6 +28,7 @@ def get_readme_and_log(
direct_image_url=image_urls["direct"],
endpoint_image_url=image_urls["endpoint"],
dynamic_image_url=image_urls["dynamic"],
subproject_id=subproject_id,
)
readme = files.WriteFile(
path=pathlib.Path("README.md"),
Expand Down
22 changes: 13 additions & 9 deletions coverage_comment/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,13 +131,14 @@ def process_pr(
previous_coverage_data_file = storage.get_datafile_contents(
github=gh,
repository=config.GITHUB_REPOSITORY,
branch=config.COVERAGE_DATA_BRANCH,
branch=config.FINAL_COVERAGE_DATA_BRANCH,
)

previous_coverage = None
if previous_coverage_data_file:
previous_coverage = files.parse_datafile(contents=previous_coverage_data_file)

marker = template.get_marker(marker_id=config.SUBPROJECT_ID)
try:
comment = template.get_comment_markdown(
coverage=coverage,
Expand All @@ -146,6 +147,8 @@ def process_pr(
base_template=template.read_template_file("comment.md.j2"),
custom_template=config.COMMENT_TEMPLATE,
pr_targets_default_branch=pr_targets_default_branch,
marker=marker,
subproject_id=config.SUBPROJECT_ID,
)
except template.MissingMarker:
log.error(
Expand Down Expand Up @@ -198,7 +201,7 @@ def process_pr(
repository=config.GITHUB_REPOSITORY,
pr_number=pr_number,
contents=comment,
marker=template.MARKER,
marker=marker,
)
except github.CannotPostComment:
log.debug("Exception when posting comment", exc_info=True)
Expand All @@ -209,7 +212,7 @@ def process_pr(
"on PR comments for external PRs)."
)
comment_file.store_file(
filename=config.COMMENT_FILENAME,
filename=config.FINAL_COMMENT_FILENAME,
content=comment,
)
github.set_output(github_output=config.GITHUB_OUTPUT, COMMENT_FILE_WRITTEN=True)
Expand Down Expand Up @@ -263,7 +266,7 @@ def post_comment(
repository=config.GITHUB_REPOSITORY,
artifact_name=config.COMMENT_ARTIFACT_NAME,
run_id=config.GITHUB_PR_RUN_ID,
filename=config.COMMENT_FILENAME,
filename=config.FINAL_COMMENT_FILENAME,
)
except github.NoArtifact:
log.info(
Expand All @@ -279,7 +282,7 @@ def post_comment(
repository=config.GITHUB_REPOSITORY,
pr_number=pr_number,
contents=comment,
marker=template.MARKER,
marker=template.get_marker(marker_id=config.SUBPROJECT_ID),
)
log.info("Comment posted in PR")

Expand Down Expand Up @@ -327,14 +330,14 @@ def save_coverage_data_files(
storage.get_raw_file_url,
is_public=is_public,
repository=config.GITHUB_REPOSITORY,
branch=config.COVERAGE_DATA_BRANCH,
branch=config.FINAL_COVERAGE_DATA_BRANCH,
)
readme_url = storage.get_repo_file_url(
branch=config.COVERAGE_DATA_BRANCH,
branch=config.FINAL_COVERAGE_DATA_BRANCH,
repository=config.GITHUB_REPOSITORY,
)
html_report_url = storage.get_html_report_url(
branch=config.COVERAGE_DATA_BRANCH,
branch=config.FINAL_COVERAGE_DATA_BRANCH,
repository=config.GITHUB_REPOSITORY,
)
readme_file, log_message = communication.get_readme_and_log(
Expand All @@ -343,12 +346,13 @@ def save_coverage_data_files(
image_urls=files.get_urls(url_getter=url_getter),
html_report_url=html_report_url,
markdown_report=markdown_report,
subproject_id=config.SUBPROJECT_ID,
)
operations.append(readme_file)
storage.commit_operations(
operations=operations,
git=git,
branch=config.COVERAGE_DATA_BRANCH,
branch=config.FINAL_COVERAGE_DATA_BRANCH,
)

log.info(log_message)
Expand Down
15 changes: 15 additions & 0 deletions coverage_comment/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class Config:
COVERAGE_PATH: pathlib.Path = pathlib.Path(".")
COMMENT_ARTIFACT_NAME: str = "python-coverage-comment-action"
COMMENT_FILENAME: pathlib.Path = pathlib.Path("python-coverage-comment-action.txt")
SUBPROJECT_ID: str | None = None
GITHUB_OUTPUT: pathlib.Path | None = None
MINIMUM_GREEN: decimal.Decimal = decimal.Decimal("100")
MINIMUM_ORANGE: decimal.Decimal = decimal.Decimal("70")
Expand Down Expand Up @@ -132,6 +133,20 @@ def GITHUB_BRANCH_NAME(self) -> str | None:
return self.GITHUB_REF.split("/", 2)[2]
return None

@property
def FINAL_COMMENT_FILENAME(self):
filename = self.COMMENT_FILENAME
if self.SUBPROJECT_ID:
new_name = f"{filename.stem}-{self.SUBPROJECT_ID}{filename.suffix}"
return filename.parent / new_name
return filename

@property
def FINAL_COVERAGE_DATA_BRANCH(self):
return self.COVERAGE_DATA_BRANCH + (
f"-{self.SUBPROJECT_ID}" if self.SUBPROJECT_ID else ""
)

# We need to type environ as a MutableMapping because that's what
# os.environ is, and just saying `dict[str, str]` is not enough to make
# mypy happy
Expand Down
Loading
Loading