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
21 changes: 13 additions & 8 deletions github_activity/github_activity.py
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,8 @@ def generate_activity_md(
bot_users = data.attrs["bot_users"]

def ignored_user(username):
if not username:
# Handle None, empty strings, and non-string types (like NaN)
if not username or not isinstance(username, str):
return False

# First check against GraphQL-detected bot users
Expand Down Expand Up @@ -561,17 +562,19 @@ def filter_ignored(userlist):
item_commenters_counts >= comment_response_cutoff
].index.tolist()
for person in item_commenters_counts:
all_contributors.add(person)
# Filter out NaN values and non-strings
if isinstance(person, str):
all_contributors.add(person)

# record contributor list (ordered, unique)
data.at[ix, "contributors"] = list(item_contributors)

comment_contributor_counts = pd.Series(comment_helpers).value_counts()
all_contributors |= set(
comment_contributor_counts[
comment_contributor_counts >= comment_others_cutoff
].index.tolist()
)
# Filter out NaN values and non-strings
comment_contributors = comment_contributor_counts[
comment_contributor_counts >= comment_others_cutoff
].index.tolist()
all_contributors |= set(c for c in comment_contributors if isinstance(c, str))

# Filter the PRs by branch (or ref) if given
if branch is not None:
Expand Down Expand Up @@ -610,7 +613,9 @@ def filter_ignored(userlist):
closed_prs = closed_prs.query("state != 'CLOSED'")

# Add any contributors to a merged PR to our contributors list
all_contributors |= set(closed_prs["contributors"].explode().unique().tolist())
# Filter out NaN values and non-strings
pr_contributors = closed_prs["contributors"].explode().unique().tolist()
all_contributors |= set(c for c in pr_contributors if isinstance(c, str))

# Define categories for a few labels
if tags is None:
Expand Down
110 changes: 35 additions & 75 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,83 +92,43 @@ def test_cli_nonexistent_branch(tmpdir):
assert "Merged PRs" not in md


def test_pr_split(tmpdir, file_regression):
"""Test that PRs are properly split by tags/prefixes."""
path_tmp = Path(tmpdir)
path_output = path_tmp.joinpath("out.md")

url = "https://github.com/executablebooks/github-activity"

# Test PR tag/prefix splitting using recent consecutive releases
cmd = f"github-activity {url} -s v1.0.2 -u v1.0.3 -o {path_output}"
run(cmd.split(), check=True)
md = path_output.read_text()
md = md.split("## Contributors to this release")[0]
file_regression.check(md, extension=".md")


def test_cli_all(tmpdir, file_regression):
"""Test that a full changelog is created"""
path_tmp = Path(tmpdir)
path_output = path_tmp.joinpath("out.md")
# Use recent consecutive releases to reduce API calls
cmd = f"github-activity executablebooks/github-activity -s v1.0.2 -u v1.0.3 -o {path_output}"
run(cmd.split(), check=True)
md = path_output.read_text()
file_regression.check(md, extension=".md")


def test_cli_ignore_user(tmpdir):
"""Test that a full changelog is created"""
path_tmp = Path(tmpdir)
path_output = path_tmp.joinpath("out.md")
# Add end date to limit query range
cmd = f"github-activity executablebooks/github-activity --ignore-contributor choldgraf -s v1.0.2 -u v1.0.3 -o {path_output}"
run(cmd.split(), check=True)
md = path_output.read_text()
assert "@choldgraf" not in md


def test_contributor_sorting(tmpdir, file_regression):
"""Test that PR author appears first, then rest of contributors, sorted"""
path_tmp = Path(tmpdir)
path_output = path_tmp.joinpath("out.md")

org, repo = ("executablebooks", "github-activity")

# Test contributor sorting using recent consecutive releases
cmd = f"github-activity {org}/{repo} -s v0.2.0 -u v0.3.0 -o {path_output}"
run(cmd.split(), check=True)
md = path_output.read_text()
file_regression.check(md, extension=".md")


@mark.integration
def test_bot_filtering(file_regression):
"""Test that bot users are detected and filtered from output."""
from github_activity.github_activity import get_activity, generate_activity_md

# Use jupyter-book/mystmd because it's a small release, and know theres bot activity
data = get_activity(
target="jupyter-book/mystmd",
since="mystmd@1.6.5",
until="mystmd@1.6.6",
def test_changelog_features(file_regression):
"""Combined test for multiple changelog features to minimize API calls.

This tests a few things in one regression test.
"""
from github_activity.github_activity import generate_activity_md

# This is a release that has dependabot activity, so we test that it no longer
# shows up in the changelog. It *will* show up in the release below because it's
# from before this feature was implemented.
# ref: https://github.com/executablebooks/github-activity/releases/tag/v1.1.0
org = "executablebooks"
repo = "github-activity"
since = "v1.0.2"
until = "v1.1.0"

# Test general changelog structure with a regression test
# PRs should be split by issue label.
md_full = generate_activity_md(
target=f"{org}/{repo}",
since=since,
until=until,
ignored_contributors=["choldgraf"],
)
file_regression.check(md_full, basename="test_cli_all", extension=".md")

# Verify bot_users attrs exists and was preserved (catches the concat bug)
assert "bot_users" in data.attrs, "bot_users should be in DataFrame attrs"
# Test that contributor sorting works, minus @choldgraf since we filtered him out (sorry Chris)
assert (
"- Allow excluding certain usernames from changelog [#128](https://github.com/executablebooks/github-activity/pull/128) ([@stefanv](https://github.com/stefanv), [@bsipocz](https://github.com/bsipocz), [@nabobalis](https://github.com/nabobalis))"
in md_full
), "Contributors should be sorted as expected"

# Verify we actually detected some bots
assert len(data.attrs["bot_users"]) > 0, (
"Should have detected bot users in this release"
# Test that ignored usernames are ignored
assert "@choldgraf" not in md_full.lower(), (
"Ignored contributor should not appear in output"
)

# Generate markdown and save as regression baseline
md = generate_activity_md(
target="jupyter-book/mystmd",
since="mystmd@1.6.5",
until="mystmd@1.6.6",
# Test that bots are removed
assert "@dependabot" not in md_full.lower(), (
"Bot user dependabot should not appear in output"
)

# Use this regression test to make sure no bots are in the output
file_regression.check(md, extension=".md")
23 changes: 0 additions & 23 deletions tests/test_cli/test_bot_filtering.md

This file was deleted.

38 changes: 34 additions & 4 deletions tests/test_cli/test_cli_all.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,27 @@
# v1.0.2...v1.0.3
# v1.0.2...v1.1.0

([full changelog](https://github.com/executablebooks/github-activity/compare/v1.0.2...v1.0.3))
([full changelog](https://github.com/executablebooks/github-activity/compare/v1.0.2...v1.1.0))

## Enhancements made

- Allow excluding certain usernames from changelog [#128](https://github.com/executablebooks/github-activity/pull/128) ([@stefanv](https://github.com/stefanv), [@bsipocz](https://github.com/bsipocz), [@nabobalis](https://github.com/nabobalis))

## Bugs fixed

- Add `pytz` to requirements [#147](https://github.com/executablebooks/github-activity/pull/147) ([@jtpio](https://github.com/jtpio), [@bsipocz](https://github.com/bsipocz), [@nabobalis](https://github.com/nabobalis))
- Ensure PRs only show up once per changelog [#130](https://github.com/executablebooks/github-activity/pull/130) ([@bsipocz](https://github.com/bsipocz), [@nabobalis](https://github.com/nabobalis))

## Maintenance and upkeep improvements

- MAINT: group the dependabot updates into one PR [#141](https://github.com/executablebooks/github-activity/pull/141) ([@bsipocz](https://github.com/bsipocz))
- Expose GitHub API call error [#138](https://github.com/executablebooks/github-activity/pull/138) ([@stefanv](https://github.com/stefanv))
- Update pre-commit to use Ruff; update versions and add a few rules [#137](https://github.com/executablebooks/github-activity/pull/137) ([@stefanv](https://github.com/stefanv), [@bsipocz](https://github.com/bsipocz))
- Change token to readonly PAT so we don't hit rate limits [#134](https://github.com/executablebooks/github-activity/pull/134) ([@bsipocz](https://github.com/bsipocz))
- Fix tests and move contributing docs into our docs [#133](https://github.com/executablebooks/github-activity/pull/133) ()

## Documentation improvements

- make sure generated anchor links resolve [#122](https://github.com/executablebooks/github-activity/pull/122) ([@minrk](https://github.com/minrk), [@consideRatio](https://github.com/consideRatio))
- Add changelog for v1.0.3 [#120](https://github.com/executablebooks/github-activity/pull/120) ([@consideRatio](https://github.com/consideRatio))
- Add changelog for v1.0.2 [#117](https://github.com/executablebooks/github-activity/pull/117) ([@consideRatio](https://github.com/consideRatio))

Expand All @@ -12,11 +30,23 @@
- ci: fix github action tag in publish workflow [#119](https://github.com/executablebooks/github-activity/pull/119) ([@consideRatio](https://github.com/consideRatio))
- ci: fix location of dependabot.yaml [#118](https://github.com/executablebooks/github-activity/pull/118) ([@consideRatio](https://github.com/consideRatio))

## Other merged PRs

- RLS: v1.1.0 [#149](https://github.com/executablebooks/github-activity/pull/149) ()
- Use GraphQL API for bot detection [#146](https://github.com/executablebooks/github-activity/pull/146) ([@stefanv](https://github.com/stefanv))
- Update test suite to use fewer GitHub API calls [#144](https://github.com/executablebooks/github-activity/pull/144) ([@bsipocz](https://github.com/bsipocz), [@stefanv](https://github.com/stefanv))
- Bump actions/checkout from 5 to 6 in the actions group [#143](https://github.com/executablebooks/github-activity/pull/143) ([@bsipocz](https://github.com/bsipocz))
- Bump actions/checkout from 4 to 5 [#140](https://github.com/executablebooks/github-activity/pull/140) ([@bsipocz](https://github.com/bsipocz))
- Bump actions/setup-python from 5 to 6 [#139](https://github.com/executablebooks/github-activity/pull/139) ([@bsipocz](https://github.com/bsipocz))
- add pyproject.toml [#132](https://github.com/executablebooks/github-activity/pull/132) ([@minrk](https://github.com/minrk))
- [DOC] Clarify some intended functionality in docs [#127](https://github.com/executablebooks/github-activity/pull/127) ([@manics](https://github.com/manics))
- Use latest github release first instead of github tag [#125](https://github.com/executablebooks/github-activity/pull/125) ([@nabobalis](https://github.com/nabobalis))

## Contributors to this release

The following people contributed discussions, new ideas, code and documentation contributions, and review.
See [our definition of contributors](https://github-activity.readthedocs.io/en/latest/#how-does-this-tool-define-contributions-in-the-reports).

([GitHub contributors page for this release](https://github.com/executablebooks/github-activity/graphs/contributors?from=2025-04-11&to=2025-04-11&type=c))
([GitHub contributors page for this release](https://github.com/executablebooks/github-activity/graphs/contributors?from=2025-04-11&to=2025-12-09&type=c))

@consideRatio ([activity](https://github.com/search?q=repo%3Aexecutablebooks%2Fgithub-activity+involves%3AconsideRatio+updated%3A2025-04-11..2025-04-11&type=Issues))
@bsipocz ([activity](https://github.com/search?q=repo%3Aexecutablebooks%2Fgithub-activity+involves%3Absipocz+updated%3A2025-04-11..2025-12-09&type=Issues)) | @consideRatio ([activity](https://github.com/search?q=repo%3Aexecutablebooks%2Fgithub-activity+involves%3AconsideRatio+updated%3A2025-04-11..2025-12-09&type=Issues)) | @jtpio ([activity](https://github.com/search?q=repo%3Aexecutablebooks%2Fgithub-activity+involves%3Ajtpio+updated%3A2025-04-11..2025-12-09&type=Issues)) | @manics ([activity](https://github.com/search?q=repo%3Aexecutablebooks%2Fgithub-activity+involves%3Amanics+updated%3A2025-04-11..2025-12-09&type=Issues)) | @minrk ([activity](https://github.com/search?q=repo%3Aexecutablebooks%2Fgithub-activity+involves%3Aminrk+updated%3A2025-04-11..2025-12-09&type=Issues)) | @nabobalis ([activity](https://github.com/search?q=repo%3Aexecutablebooks%2Fgithub-activity+involves%3Anabobalis+updated%3A2025-04-11..2025-12-09&type=Issues)) | @stefanv ([activity](https://github.com/search?q=repo%3Aexecutablebooks%2Fgithub-activity+involves%3Astefanv+updated%3A2025-04-11..2025-12-09&type=Issues))
28 changes: 0 additions & 28 deletions tests/test_cli/test_contributor_sorting.md

This file was deleted.

14 changes: 0 additions & 14 deletions tests/test_cli/test_pr_split.md

This file was deleted.