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
20 changes: 16 additions & 4 deletions docs/use.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,20 @@ github-activity jupyter/notebook -s 6.0.0 -u 6.0.1 -o sample_notebook_activity.m

You can find the [resulting markdown here](sample_notebook_activity).

```{tip}
For repositories that use multiple branches, it may be necessary to filter PRs by a branch name. This can be done using the `--branch` parameter in the CLI. Other git references can be used as well in place of a branch name.
## Filter pull requests by branch

Many repositories work with multiple active branches (e.g., `main`, `develop`, feature branches). When generating a changelog for a specific release, you typically only want to include pull requests that were merged into the release branch.

Use the `--branch` (or `-b`) parameter to filter pull requests by their target branch:

```bash
github-activity org/repo --since v1.0.0 --until v2.0.0 --branch main
```

This will **only include pull requests that targeted the `main` branch**, excluding any PRs merged to other branches like `develop` or feature branches.

```{note}
You can use any git reference (tag, commit hash, etc.) in place of a branch name.
Comment on lines +44 to +57
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just documenting pre-existing functionality

```

## Choose a date or a tag to filter activity
Expand Down Expand Up @@ -217,7 +229,7 @@ This is not as well-documented as the CLI, but should have most functionality av

For generating markdown changelogs from Python, here's an example:

```
```python
from github_activity import generate_activity_md

markdown = generate_activity_md(
Expand All @@ -231,7 +243,7 @@ markdown = generate_activity_md(
include_opened=True,
strip_brackets=True,
heading_level=1,
branch=None,
branch="main", # Filter PRs by target branch (optional, use None for all branches)
)

# Print or save the markdown
Expand Down
55 changes: 31 additions & 24 deletions github_activity/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,9 @@
"--branch",
"-b",
default=None,
help=("""The branch or reference name to filter pull requests by"""),
help=(
"""Filter pull requests by their target branch. Only PRs merged into this branch will be included. """
),
)
parser.add_argument(
"--all",
Expand Down Expand Up @@ -223,31 +225,36 @@ def main():
ignored_contributors=args.ignore_contributor,
)

if args.all:
md = generate_all_activity_md(args.target, **common_kwargs)
# Wrap in a try/except so we don't have an ugly stack trace if there's an error
try:
if args.all:
md = generate_all_activity_md(args.target, **common_kwargs)
Comment on lines +228 to +231
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is all just tab-adding. The only difference is the try/except statement, so that if valueerrors happen down below we can display them nicely.


else:
md = generate_activity_md(
args.target,
since=args.since,
until=args.until,
heading_level=args.heading_level,
**common_kwargs,
)
else:
md = generate_activity_md(
args.target,
since=args.since,
until=args.until,
heading_level=args.heading_level,
**common_kwargs,
)

if not md:
return

if args.output:
output = os.path.abspath(args.output)
output_dir = os.path.dirname(output)
if not os.path.exists(output_dir):
os.makedirs(output_dir)
with open(args.output, "w") as ff:
ff.write(md)
print(f"Finished writing markdown to: {args.output}", file=sys.stderr)
else:
print(md)
if not md:
return

if args.output:
output = os.path.abspath(args.output)
output_dir = os.path.dirname(output)
if not os.path.exists(output_dir):
os.makedirs(output_dir)
with open(args.output, "w") as ff:
ff.write(md)
print(f"Finished writing markdown to: {args.output}", file=sys.stderr)
else:
print(md)
except ValueError as e:
print(f"Error: {e}", file=sys.stderr)
sys.exit(1)


if __name__ == "__main__":
Expand Down
30 changes: 20 additions & 10 deletions github_activity/github_activity.py
Original file line number Diff line number Diff line change
Expand Up @@ -462,8 +462,27 @@ def generate_activity_md(
data = get_activity(
target, since=since, until=until, kind=kind, auth=auth, cache=False
)

# Raise error if GitHub API returned no activity at all
# This happens when the repository has no issues/PRs in the date range
if data.empty:
return
raise ValueError(
f"No activity found for {org}/{repo} between {since} and {until}."
)

# Filter the PRs by branch (or ref) if given
if branch is not None:
index_names = data[
(data["kind"] == "pr") & (data["baseRefName"] != branch)
].index
data.drop(index_names, inplace=True)

# Raise error if branch filter removed all data
# This happens when PRs exist but none targeted the specified branch
if data.empty:
raise ValueError(
f"Found activity, but none for the --branch target specified for {org}/{repo} on branch '{branch}' between {since} and {until}.\n"
)

# Collect authors of comments on issues/prs that they didn't open for our attribution list
comment_response_cutoff = 6 # Comments on a single issue
Expand Down Expand Up @@ -581,15 +600,6 @@ def filter_ignored(userlist):
].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:
index_names = data[
(data["kind"] == "pr") & (data["baseRefName"] != branch)
].index
data.drop(index_names, inplace=True)
if data.empty:
return

# Extract datetime strings from data attributes for pandas query
since_dt_str = data.since_dt_str # noqa: F841
until_dt_str = data.until_dt_str # noqa: F841
Expand Down