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
64 changes: 64 additions & 0 deletions .github/actions/weekly-report/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# QuantEcon Weekly Report Action

A GitHub Action that generates a weekly report summarizing activity across all repositories in the QuantEcon organization.

## Features

This action generates a report containing:
- Number of issues opened by repository (last 7 days)
- Number of issues closed by repository (last 7 days)
- Number of PRs merged by repository (last 7 days)
- Summary totals across all repositories

### Efficiency Features
- **Smart repository filtering**: Uses GitHub Search API to identify repositories with recent activity (commits in the last 7 days) before checking for issues and PRs
- **Fallback mechanism**: If no repositories are found with recent commits, falls back to checking all organization repositories to ensure complete coverage
- **Activity-based reporting**: Only includes repositories with actual activity in the generated report

## Usage

```yaml
- name: Generate weekly report
uses: QuantEcon/meta/.github/actions/weekly-report@main
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
organization: 'QuantEcon'
output-format: 'markdown'
exclude-repos: 'lecture-python.notebooks,auto-updated-repo'
```

## Inputs

| Input | Description | Required | Default |
|-------|-------------|----------|---------|
| `github-token` | GitHub token with access to the organization | Yes | - |
| `organization` | GitHub organization name | No | `QuantEcon` |
| `output-format` | Output format (`markdown` or `json`) | No | `markdown` |
| `exclude-repos` | Comma-separated list of repository names to exclude from the report | No | `''` |

## Outputs

| Output | Description |
|--------|-------------|
| `report-content` | The full generated report content |
| `report-summary` | A brief summary of the report metrics |

## Permissions

The GitHub token must have read access to:
- Organization repositories
- Repository issues
- Repository pull requests

## Example Workflow

See the [weekly report workflow](../../workflows/weekly-report.yml) for a complete example that runs every Saturday and creates an issue with the report.

## Report Format

The generated markdown report includes:
- A summary table showing activity by repository
- Total counts across all repositories
- Report metadata (generation date, period covered)

Only repositories with activity in the reporting period are included in the detailed table.
38 changes: 38 additions & 0 deletions .github/actions/weekly-report/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: 'QuantEcon Weekly Report'
description: 'Generate a weekly report of issues and PRs across QuantEcon repositories'
author: 'QuantEcon'

inputs:
github-token:
description: 'GitHub token with access to the QuantEcon organization'
required: true
organization:
description: 'GitHub organization name'
required: false
default: 'QuantEcon'
output-format:
description: 'Output format for the report (markdown, json)'
required: false
default: 'markdown'
exclude-repos:
description: 'Comma-separated list of repository names to exclude from the report'
required: false
default: ''

outputs:
report-content:
description: 'The generated weekly report content'
report-summary:
description: 'A brief summary of the report metrics'

runs:
using: 'composite'
steps:
- name: Generate weekly report
shell: bash
run: ${{ github.action_path }}/generate-report.sh
env:
INPUT_GITHUB_TOKEN: ${{ inputs.github-token }}
INPUT_ORGANIZATION: ${{ inputs.organization }}
INPUT_OUTPUT_FORMAT: ${{ inputs.output-format }}
INPUT_EXCLUDE_REPOS: ${{ inputs.exclude-repos }}
162 changes: 162 additions & 0 deletions .github/actions/weekly-report/generate-report.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
#!/bin/bash
set -e

# Get inputs
GITHUB_TOKEN="${INPUT_GITHUB_TOKEN}"
ORGANIZATION="${INPUT_ORGANIZATION:-QuantEcon}"
OUTPUT_FORMAT="${INPUT_OUTPUT_FORMAT:-markdown}"
EXCLUDE_REPOS="${INPUT_EXCLUDE_REPOS:-}"

# Date calculations for last week
WEEK_AGO=$(date -d "7 days ago" -u +"%Y-%m-%dT%H:%M:%SZ")
NOW=$(date -u +"%Y-%m-%dT%H:%M:%SZ")

echo "Generating weekly report for ${ORGANIZATION} organization"
echo "Period: ${WEEK_AGO} to ${NOW}"

# Function to make GitHub API calls
api_call() {
local endpoint="$1"
local page="${2:-1}"
curl -s -H "Authorization: token ${GITHUB_TOKEN}" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com${endpoint}?page=${page}&per_page=100"
}

# Get repositories with recent activity using GitHub Search API
echo "Fetching repositories with recent activity for ${ORGANIZATION}..."

# Search for repositories with recent commits, issues, or PRs in the last week
WEEK_AGO_DATE=$(date -d "7 days ago" -u +"%Y-%m-%d")

# Use search API to find repos with recent activity
search_query="org:${ORGANIZATION} pushed:>${WEEK_AGO_DATE}"
search_response=$(curl -s -H "Authorization: token ${GITHUB_TOKEN}" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/search/repositories?q=$(echo "$search_query" | sed 's/ /%20/g')&per_page=100")

repo_names=$(echo "$search_response" | jq -r '.items[]?.name // empty')

# If no repos found with recent commits, fall back to checking all org repos
# This ensures we don't miss repos that might have issues/PRs but no commits
if [ -z "$repo_names" ]; then
echo "No repositories found with recent commits, checking all organization repositories..."
repos_response=$(api_call "/orgs/${ORGANIZATION}/repos")
repo_names=$(echo "$repos_response" | jq -r '.[].name // empty')

if [ -z "$repo_names" ]; then
echo "No repositories found or API call failed"
exit 1
fi
else
echo "Found repositories with recent activity:"
echo "$repo_names" | head -10 # Show first 10 for logging
fi

# Filter out excluded repositories if any are specified
if [ -n "$EXCLUDE_REPOS" ]; then
echo "Excluding repositories: $EXCLUDE_REPOS"
# Convert comma-separated list to array and filter out excluded repos
IFS=',' read -ra exclude_array <<< "$EXCLUDE_REPOS"
filtered_repos=""
while IFS= read -r repo; do
[ -z "$repo" ] && continue
excluded=false
for exclude_repo in "${exclude_array[@]}"; do
# Trim whitespace and compare
exclude_repo=$(echo "$exclude_repo" | xargs)
if [ "$repo" = "$exclude_repo" ]; then
excluded=true
echo "Excluding repository: $repo"
break
fi
done
if [ "$excluded" = false ]; then
if [ -z "$filtered_repos" ]; then
filtered_repos="$repo"
else
filtered_repos="$filtered_repos"$'\n'"$repo"
fi
fi
done <<< "$repo_names"
repo_names="$filtered_repos"
fi

# Initialize report variables
total_opened_issues=0
total_closed_issues=0
total_merged_prs=0
report_content=""

# Start building the report
if [ "$OUTPUT_FORMAT" = "markdown" ]; then
report_content="# QuantEcon Weekly Report\n\n"
report_content+="**Report Period:** $(date -d "$WEEK_AGO" '+%B %d, %Y') - $(date -d "$NOW" '+%B %d, %Y')\n\n"
report_content+="## Summary\n\n"
report_content+="| Repository | Opened Issues | Closed Issues | Merged PRs |\n"
report_content+="|------------|---------------|---------------|------------|\n"
fi

# Process each repository
while IFS= read -r repo; do
[ -z "$repo" ] && continue

echo "Processing repository: $repo"

# Count opened issues in the last week
opened_issues=$(api_call "/repos/${ORGANIZATION}/${repo}/issues" | \
jq --arg since "$WEEK_AGO" '[.[] | select(.created_at >= $since and .pull_request == null)] | length')

# Count closed issues in the last week
closed_issues=$(api_call "/repos/${ORGANIZATION}/${repo}/issues?state=closed" | \
jq --arg since "$WEEK_AGO" '[.[] | select(.closed_at >= $since and .pull_request == null)] | length')

# Count merged PRs in the last week
merged_prs=$(api_call "/repos/${ORGANIZATION}/${repo}/pulls?state=closed" | \
jq --arg since "$WEEK_AGO" '[.[] | select(.merged_at != null and .merged_at >= $since)] | length')

# Handle null/empty values
opened_issues=${opened_issues:-0}
closed_issues=${closed_issues:-0}
merged_prs=${merged_prs:-0}

# Add to totals
total_opened_issues=$((total_opened_issues + opened_issues))
total_closed_issues=$((total_closed_issues + closed_issues))
total_merged_prs=$((total_merged_prs + merged_prs))

# Add to report if there's activity
if [ $((opened_issues + closed_issues + merged_prs)) -gt 0 ]; then
if [ "$OUTPUT_FORMAT" = "markdown" ]; then
report_content+="| $repo | $opened_issues | $closed_issues | $merged_prs |\n"
fi
fi

done <<< "$repo_names"

# Add summary to report
if [ "$OUTPUT_FORMAT" = "markdown" ]; then
report_content+="|**Total**|**$total_opened_issues**|**$total_closed_issues**|**$total_merged_prs**|\n\n"
report_content+="## Details\n\n"
report_content+="- **Total Repositories Checked:** $(echo "$repo_names" | wc -l)\n"
report_content+="- **Total Issues Opened:** $total_opened_issues\n"
report_content+="- **Total Issues Closed:** $total_closed_issues\n"
report_content+="- **Total PRs Merged:** $total_merged_prs\n\n"
report_content+="*Report generated on $(date) by QuantEcon Weekly Report Action*\n"
fi

# Create summary
summary="Week Summary: $total_opened_issues issues opened, $total_closed_issues issues closed, $total_merged_prs PRs merged"

# Save report to file
echo -e "$report_content" > weekly-report.md

# Set outputs
echo "report-content<<EOF" >> $GITHUB_OUTPUT
echo -e "$report_content" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT

echo "report-summary=$summary" >> $GITHUB_OUTPUT

echo "Weekly report generated successfully!"
echo "Summary: $summary"
6 changes: 6 additions & 0 deletions .github/workflows/test-warning-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,14 @@ name: Test Warning Check Action
on:
push:
branches: [ main ]
paths:
- '.github/actions/check-warnings/**'
- 'test/check-warnings/**'
pull_request:
branches: [ main ]
paths:
- '.github/actions/check-warnings/**'
- 'test/check-warnings/**'
workflow_dispatch:

jobs:
Expand Down
67 changes: 67 additions & 0 deletions .github/workflows/test-weekly-report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
name: Test Weekly Report Action

on:
push:
branches: [ main ]
paths:
- '.github/actions/weekly-report/**'
- '.github/workflows/test-weekly-report.yml'
pull_request:
branches: [ main ]
paths:
- '.github/actions/weekly-report/**'
- '.github/workflows/test-weekly-report.yml'
workflow_dispatch:

jobs:
test-basic:
runs-on: ubuntu-latest
name: Test basic weekly report functionality
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Run basic test
run: ./test/weekly-report/test-basic.sh

test-action-structure:
runs-on: ubuntu-latest
name: Test action structure and inputs
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Validate action.yml
run: |
# Check that action.yml exists and has required fields
if [ ! -f ".github/actions/weekly-report/action.yml" ]; then
echo "❌ action.yml not found"
exit 1
fi

# Check for required fields using basic grep
if ! grep -q "name:" .github/actions/weekly-report/action.yml; then
echo "❌ Missing name field"
exit 1
fi

if ! grep -q "github-token:" .github/actions/weekly-report/action.yml; then
echo "❌ Missing github-token input"
exit 1
fi

echo "βœ… Action structure validation passed"

- name: Test script exists and is executable
run: |
if [ ! -f ".github/actions/weekly-report/generate-report.sh" ]; then
echo "❌ generate-report.sh not found"
exit 1
fi

if [ ! -x ".github/actions/weekly-report/generate-report.sh" ]; then
echo "❌ generate-report.sh is not executable"
exit 1
fi

echo "βœ… Script validation passed"
Loading