diff --git a/agentic-workflows/README.md b/agentic-workflows/README.md new file mode 100644 index 000000000..c2706db45 --- /dev/null +++ b/agentic-workflows/README.md @@ -0,0 +1,87 @@ +# GitHub Agentic Workflows + +> AI-powered automation for GitHub — write workflows in natural language, not YAML. + +## What Are Agentic Workflows? + +GitHub Agentic Workflows are a new way to build CI/CD automation. Instead of writing complex YAML with shell scripts, you describe what you want in **Markdown** and an AI agent (GitHub Copilot) interprets and executes your instructions using GitHub APIs. + +Each workflow is a `.md` file with two parts: + +1. **YAML frontmatter** — triggers, permissions, tools, and guardrails +2. **Markdown body** — natural language instructions the AI follows + +```markdown +--- +on: + schedule: + - cron: "0 10 1 * *" # When to run + workflow_dispatch: # Allow manual trigger + +permissions: + contents: read + issues: write + +engine: copilot # AI engine + +tools: + github: + toolsets: [repos, issues] # Which GitHub APIs are available + bash: true # Shell access for date math, etc. + +safe-outputs: + create-issue: + max: 1 # Guardrail: create at most 1 issue per run + title-prefix: "[Report] " + +timeout-minutes: 30 +--- + +## Step 1: Gather Data + +List all public, non-archived repositories in the organization. +For each repo, count open issues and pull requests. + +## Step 2: Generate Report + +Create a markdown table summarizing repo activity. +Create a GitHub issue with the report. +``` + +## How It Differs from Traditional GitHub Actions + +| | Traditional Actions | Agentic Workflows | +|---|---|---| +| **Format** | YAML + shell scripts | Markdown + natural language | +| **Logic** | You write every step explicitly | AI interprets your intent | +| **API calls** | Manual REST/GraphQL calls | AI handles API calls, pagination, error handling | +| **Customization** | Edit YAML/scripts | Edit plain English instructions | +| **Guardrails** | None built-in | `safe-outputs` limits write operations per run | + +## Prerequisites + +- **GitHub CLI** (`gh`) — [install guide](https://cli.github.com/) +- **Agentic Workflows extension** — `gh extension install githubnext/gh-aw` +- **GitHub Copilot** access on your repository + +## Quick Start + +1. **Copy** a workflow `.md` file into your repo's `.github/workflows/` directory +2. **Customize** the instructions (edit the Markdown — it's plain English) +3. **Compile** to generate the Actions lock file: + ```bash + gh aw compile workflow-name + ``` +4. **Commit both files** — the `.md` source and the generated `.lock.yml` +5. **Push** — the workflow runs on the triggers you defined + +## Examples + +| Category | Description | +|---|---| +| **[OSPO](ospo/)** | Open Source Program Office — org health, contributor metrics, compliance, repo hygiene | + +## Learn More + +- [GitHub Agentic Workflows Documentation](https://githubnext.github.io/gh-aw/) +- [GitHub Next — Agentic Workflows](https://githubnext.com/projects/agentic-workflows) diff --git a/agentic-workflows/ospo/README.md b/agentic-workflows/ospo/README.md new file mode 100644 index 000000000..b6fb524b1 --- /dev/null +++ b/agentic-workflows/ospo/README.md @@ -0,0 +1,26 @@ +# OSPO Agentic Workflows + +> AI-powered automation for Open Source Program Offices — org health, contributor metrics, compliance, and more. + +These workflows automate common OSPO tasks using [GitHub Agentic Workflows](../README.md). Copy any workflow into your repo's `.github/workflows/` directory, customize the organization name, and compile with `gh aw compile`. + +## Workflows + +| Workflow | Schedule | What It Does | +|----------|----------|-------------| +| [**org-health**](org-health.md) | Weekly (Monday) | Comprehensive org health report — stale issues/PRs, merge time analysis, contributor leaderboards, health alerts | +| [**contributors-report**](contributors-report.md) | Monthly (1st) | New vs. returning contributor metrics, commit counts, optional Sponsors info | +| [**release-compliance-checker**](release-compliance-checker.md) | On issue open | Audits a repo for OSS release readiness — required files, security config, license compliance, risk assessment | +| [**stale-repos**](stale-repos.md) | Monthly (1st) | Finds repositories with no activity in X days (default: 365) | + +## Customization + +- **Change the org**: Most workflows default to `"my-org"` — update to your org name +- **Adjust schedules**: Edit the `cron` in the YAML frontmatter +- **Tune thresholds**: Stale days, exempt repos, activity methods — all configurable via `workflow_dispatch` inputs +- **Add/remove checks**: Edit the Markdown instructions directly + +## See Also + +- [ospo-readiness skill](../../skills/ospo-readiness/) — Interactive repo scanner (graded A–F) for Copilot chat +- [GitHub Agentic Workflows docs](https://githubnext.github.io/gh-aw/) diff --git a/agentic-workflows/ospo/contributors-report.md b/agentic-workflows/ospo/contributors-report.md new file mode 100644 index 000000000..9a78834f7 --- /dev/null +++ b/agentic-workflows/ospo/contributors-report.md @@ -0,0 +1,138 @@ +--- +name: Contributors Report +on: + schedule: + - cron: "3 2 1 * *" + workflow_dispatch: + inputs: + organization: + description: "GitHub organization to analyze (e.g. github)" + required: false + type: string + repositories: + description: "Comma-separated list of repos to analyze (e.g. owner/repo1,owner/repo2)" + required: false + type: string + start_date: + description: "Start date for the report period (YYYY-MM-DD)" + required: false + type: string + end_date: + description: "End date for the report period (YYYY-MM-DD)" + required: false + type: string + sponsor_info: + description: "Include GitHub Sponsors information for contributors" + required: false + type: boolean + default: false + +permissions: + contents: read + issues: write + pull-requests: read + +engine: copilot + +tools: + github: + toolsets: + - repos + - issues + - pull_requests + - orgs + - users + bash: true + +safe-outputs: + create-issue: + max: 1 + title-prefix: "[Contributors Report] " + +timeout-minutes: 60 +--- + +# Contributors Report + +Generate a contributors report for the specified organization or repositories. + +## Step 1: Validate Configuration + +Check the workflow inputs. Either `organization` or `repositories` must be provided. + +- If **both** are empty and this is a **scheduled run**, default to analyzing all public repositories in the organization that owns the current repository. Determine the org from the `GITHUB_REPOSITORY` environment variable (the part before the `/`). +- If **both** are empty and this is a **manual dispatch**, fail with a clear error message: "You must provide either an organization or a comma-separated list of repositories." +- If **both** are provided, prefer `repositories` and ignore `organization`. + +## Step 2: Determine Date Range + +- If `start_date` and `end_date` are provided, use them. +- Otherwise, default to the **previous calendar month**. For example, if today is 2025-03-15, the range is 2025-02-01 to 2025-02-28. +- Use bash to compute the dates if needed. Store them as `START_DATE` and `END_DATE`. + +## Step 3: Enumerate Repositories + +- If `repositories` input was provided, split the comma-separated string into a list. Each entry should be in `owner/repo` format. +- If `organization` input was provided (or defaulted from Step 1), list all **public, non-archived, non-fork** repositories in the organization using the GitHub API. Collect their `owner/repo` identifiers. + +## Step 4: Collect Contributors from Commit History + +For each repository in scope: + +1. Use the GitHub API to list commits between `START_DATE` and `END_DATE` (use the `since` and `until` parameters on the commits endpoint). +2. For each commit, extract the **author login** (from `author.login` on the commit object). +3. **Exclude bot accounts**: skip any contributor whose username contains `[bot]` or whose `type` field is `"Bot"`. +4. Track per-contributor: + - Total number of commits across all repos. + - The set of repos they contributed to. + +Use bash to aggregate and deduplicate the contributor data across all repositories. + +## Step 5: Determine New vs Returning Contributors + +For each contributor found in Step 4, check whether they have **any commits before `START_DATE`** in any of the in-scope repositories. + +- If a contributor has **no commits before `START_DATE`**, mark them as a **New Contributor**. +- Otherwise, mark them as a **Returning Contributor**. + +## Step 6: Collect Sponsor Information (Optional) + +If the `sponsor_info` input is `true`: + +1. For each contributor, check whether they have a GitHub Sponsors profile by querying the user's profile via the GitHub API. +2. If the user has sponsorship enabled, record their sponsor URL as `https://github.com/sponsors/`. +3. If not, leave the sponsor field empty. + +## Step 7: Generate Markdown Report + +Build a markdown report with the following structure: + +### Summary Table + +| Metric | Value | +|---|---| +| Total Contributors | count | +| Total Contributions (Commits) | count | +| New Contributors | count | +| Returning Contributors | count | +| % New Contributors | percentage | + +### Contributors Detail Table + +Sort contributors by commit count descending. + +| # | Username | Contribution Count | New Contributor | Sponsor URL | Commits | +|---|---|---|---|---|---| +| 1 | @username | 42 | Yes | [Sponsor](url) | [View](commits-url) | + +- The **Username** column should link to the contributor's GitHub profile. +- The **Sponsor URL** column should show "N/A" if `sponsor_info` is false or the user has no Sponsors page. +- The **Commits** column should link to a filtered commits view. + +## Step 8: Create Issue with Report + +Create an issue in the **current repository** with: + +- **Title:** `[Contributors Report] — START_DATE to END_DATE` +- **Body:** The full markdown report from Step 7. +- **Labels:** Add the label `contributors-report` if it exists; do not fail if it does not. diff --git a/agentic-workflows/ospo/org-health.md b/agentic-workflows/ospo/org-health.md new file mode 100644 index 000000000..2f6471f04 --- /dev/null +++ b/agentic-workflows/ospo/org-health.md @@ -0,0 +1,231 @@ +--- +name: Weekly Organization Health Report +description: > + Comprehensive weekly health report for a GitHub organization. + Surfaces stale issues/PRs, merge time analysis, contributor leaderboards, + and actionable items needing human attention. + +on: + schedule: + - cron: "0 10 * * 1" + workflow_dispatch: + inputs: + organization: + description: "GitHub organization to report on" + type: string + required: true + +permissions: + contents: read + issues: write + pull-requests: read + actions: read + +engine: copilot + +tools: + github: + toolsets: + - repos + - issues + - pull_requests + - orgs + bash: true + +safe-outputs: + create-issue: + max: 1 + title-prefix: "[Org Health] " + +timeout-minutes: 60 + +network: + allowed: + - defaults + - python +--- + +You are an expert GitHub organization analyst. Your job is to produce a +comprehensive weekly health report for your GitHub organization +(provided via workflow input). + +## Primary Goal + +**Surface issues and PRs that need human attention**, celebrate wins, and +provide actionable metrics so maintainers can prioritize their time. + +--- + +## Step 1 — Determine the Organization + +``` +ORG = inputs.organization OR "my-org" +PERIOD_DAYS = 30 +SINCE = date 30 days ago (ISO 8601) +STALE_ISSUE_DAYS = 60 +STALE_PR_DAYS = 30 +``` + +## Step 2 — Gather Organization-Wide Aggregates (Search API) + +Use GitHub search APIs for fast org-wide counts. These are efficient and +avoid per-repo iteration for basic aggregates. + +Collect the following using search queries: + +| Metric | Search Query | +|--------|-------------| +| Total open issues | `org: is:issue is:open` | +| Total open PRs | `org: is:pr is:open` | +| Issues opened (last 30d) | `org: is:issue created:>={SINCE}` | +| Issues closed (last 30d) | `org: is:issue is:closed closed:>={SINCE}` | +| PRs opened (last 30d) | `org: is:pr created:>={SINCE}` | +| PRs merged (last 30d) | `org: is:pr is:merged merged:>={SINCE}` | +| PRs closed unmerged (last 30d) | `org: is:pr is:closed is:unmerged closed:>={SINCE}` | +| Stale issues (60+ days) | `org: is:issue is:open updated:<={60_DAYS_AGO}` | +| Stale PRs (30+ days) | `org: is:pr is:open updated:<={30_DAYS_AGO}` | + +**Performance tip:** Add 1–2 second delays between search API calls to +stay well within rate limits. + +## Step 3 — Stale Issues & PRs (Heat Scores) + +For stale issues and stale PRs found above, retrieve the top results and +sort them by **heat score** (comment count). The heat score helps +maintainers prioritize: a stale issue with many comments signals community +interest that is going unaddressed. + +- **Stale issues**: Retrieve up to 50, sort by `comments` descending, + keep top 10. For each, record: repo, number, title, days since last + update, comment count (heat score), author, labels. +- **Stale PRs**: Same approach — retrieve up to 50, sort by `comments` + descending, keep top 10. + +## Step 4 — PR Merge Time Analysis + +From the PRs merged in the last 30 days (Step 2), retrieve a sample of +recently merged PRs (up to 100). For each, calculate: + +``` +merge_time = merged_at - created_at (in hours) +``` + +Then compute percentiles: +- **p50** (median merge time) +- **p75** +- **p95** + +Use bash with Python for percentile calculations: + +```bash +python3 -c " +import json, sys, math + +times = json.loads(sys.stdin.read()) +times.sort() +n = len(times) + +def percentile(data, p): + if not data: + raise ValueError('percentile() arg is an empty sequence') + k = (len(data) - 1) * p + f = math.floor(k) + c = math.ceil(k) + if f == c: + return data[int(k)] + d0 = data[f] * (c - k) + d1 = data[c] * (k - f) + return d0 + d1 + +if n == 0: + print('No data') +else: + p50 = percentile(times, 0.50) + p75 = percentile(times, 0.75) + p95 = percentile(times, 0.95) if n >= 20 else times[-1] + print(f'p50={p50:.1f}h, p75={p75:.1f}h, p95={p95:.1f}h') +" +``` + +## Step 5 — First Response Time + +For issues and PRs opened in the last 30 days, sample up to 50 of each. +For each item, find the first comment (excluding the author). Calculate: + +``` +first_response_time = first_comment.created_at - item.created_at (in hours) +``` + +Report median first response time for issues and PRs separately. + +## Step 6 — Repository Activity & Contributor Leaderboard + +### Top 10 Active Repos +List all non-archived repos in the org. For each, count pushes / commits / +issues+PRs opened in the last 30 days. Sort by total activity, keep top 10. + +### Contributor Leaderboard +From the top 10 active repos, aggregate commit authors over the last 30 +days. Rank by commit count, keep top 10. Award: +- 🥇 for #1 +- 🥈 for #2 +- 🥉 for #3 + +### Inactive Repos +Repos with 0 pushes, 0 issues, 0 PRs in the last 30 days. List them +(name + last push date) so the org can decide whether to archive. + +## Step 7 — Health Alerts & Trends + +Compute velocity indicators and assign status: + +| Indicator | 🟢 Green | 🟡 Yellow | 🔴 Red | +|-----------|----------|-----------|--------| +| Issue close rate | closed ≥ opened | closed ≥ 70% opened | closed < 70% opened | +| PR merge rate | merged ≥ opened | merged ≥ 60% opened | merged < 60% opened | +| Median merge time | < 24h | 24–72h | > 72h | +| Median first response | < 24h | 24–72h | > 72h | +| Stale issue count | < 10 | 10–50 | > 50 | +| Stale PR count | < 5 | 5–20 | > 20 | + +## Step 8 — Wins & Shoutouts + +Celebrate positive signals: +- PRs merged with fast turnaround (< 4 hours) +- Issues closed quickly (< 24 hours from open to close) +- Top contributors (from leaderboard) +- Repos with zero stale items + +## Step 9 — Compose the Report + +Create a single issue in the org's `.github` repository (or the most +appropriate central repo) with the title: + +``` +[Org Health] Weekly Report — +``` + +The issue body should include these sections in order: + +1. **Header** — org name, period, generation date +2. **🚨 Health Alerts** — table of indicators with 🟢/🟡/🔴 status and values +3. **🏆 Wins & Shoutouts** — fast merges, quick closes, top contributors +4. **📋 Stale Issues** — top 10 by heat score (repo, issue, days stale, comment count, labels) +5. **📋 Stale PRs** — top 10 by heat score (repo, PR, days stale, comment count, author) +6. **⏱️ PR Merge Time** — p50, p75, p95 percentiles +7. **⚡ First Response Time** — median for issues and PRs +8. **📊 Top 10 Active Repos** — sorted by total activity (issues + PRs + commits) +9. **👥 Contributor Leaderboard** — top 10 by commits with 🥇🥈🥉 +10. **😴 Inactive Repos** — repos with 0 activity in 30 days + +Use markdown tables for all data sections. + +## Important Notes + +- **Update the organization name** in the frontmatter before use. +- If any API call fails, note it in the report and continue with available + data. Do not let a single failure block the entire report. +- Keep the issue body under 65,000 characters (GitHub issue body limit). +- All times should be reported in hours. Convert to days only if > 72 hours. +- Use the `safe-outputs` constraint: only create 1 issue, with title + prefixed `[Org Health] `. diff --git a/agentic-workflows/ospo/release-compliance-checker.md b/agentic-workflows/ospo/release-compliance-checker.md new file mode 100644 index 000000000..c2a365a33 --- /dev/null +++ b/agentic-workflows/ospo/release-compliance-checker.md @@ -0,0 +1,127 @@ +--- +name: OSS Release Compliance Checker +description: > + Analyzes a target repository against open source release requirements and + posts a detailed compliance report as an issue comment. Checks for required + files, security settings, license compliance, and generates a risk assessment. + +on: + issues: + types: [opened, labeled] + workflow_dispatch: + +permissions: + contents: read + issues: write + pull-requests: read + actions: read + +engine: copilot + +tools: + github: + toolsets: + - repos + - issues + bash: true + +safe-outputs: + add-comment: + max: 1 + +timeout-minutes: 20 +--- + +You are an open source release compliance checker. Your job is to analyze a +repository that has been proposed for open source release and post a thorough, +constructive compliance report as a comment on the triggering issue. + +## 1. Trigger Guard + +First, determine whether this workflow should proceed: + +- If the event is `workflow_dispatch`, proceed. +- If the event is `issues` with type `opened`, proceed. +- If the event is `issues` with type `labeled`, only proceed if the label that + was just added is **`ospo-release-check`**. +- Otherwise, stop and do nothing. + +## 2. Extract Target Repository + +Read the body of the triggering issue. Look for the repository that is being +proposed for release. It may appear as: + +- A full GitHub URL such as `https://github.com/org/repo-name` +- An `owner/repo` shorthand such as `org/repo-name` + +Extract the **owner** and **repo name**. If you cannot find a repository +reference, post a comment asking the issue author to include one and stop. + +## 3. File Compliance Check + +For the target repository, check whether each of the following files exists at +the repository root (or in `.github/` where conventional). For each file that +exists, also assess whether it has meaningful content. + +| File | What to look for | +|------|-----------------| +| `LICENSE` | Must be present. Contents must match the license declared in the repo metadata. | +| `README.md` | Must be present and substantial (>100 lines recommended). Should contain sections for usage, install, and contributing. | +| `CODEOWNERS` | Must list at least one maintainer or team. | +| `CONTRIBUTING.md` | Must describe how to contribute (issues, PRs, CLA/DCO, code style). | +| `SUPPORT.md` | Must explain how users can get help. | +| `CODE_OF_CONDUCT.md` | Must adopt a recognized code of conduct. | +| `SECURITY.md` | Must describe the security vulnerability disclosure process. | + +## 4. Security Configuration Check + +Using the GitHub API, check the following security settings on the target +repository: + +- **Secret scanning** — Is secret scanning enabled? +- **Dependabot** — Are Dependabot alerts and/or security updates enabled? +- **Code scanning (CodeQL)** — Are any code scanning analyses present? +- **Branch protection** — Is the default branch protected? Are required reviews, + status checks, or signed commits configured? + +Handle `404` or `403` responses gracefully — they typically mean the feature is +not enabled or you lack permission to check it. + +## 5. License & Legal Analysis + +- Compare the contents of the `LICENSE` file against the license declared in + the repository metadata (`license.spdx_id` from the repo API response). + Flag any mismatch. +- Look for dependency manifests (`package.json`, `requirements.txt`, `go.mod`, + `Cargo.toml`, `pom.xml`, `Gemfile`, `*.csproj`, etc.) in the repository. +- For each manifest found, attempt to identify declared dependency licenses. + Specifically flag any **GPL**, **AGPL**, **LGPL**, or other strong-copyleft + licenses that would require legal review before an open source release. + +## 6. Risk Assessment + +Based on your findings, assign a risk level (**Low**, **Medium**, or **High**) +to each of the following categories: + +| Category | Low 🟢 | Medium 🟡 | High 🔴 | +|----------|--------|-----------|---------| +| **Business Risk** | No secrets, no proprietary code patterns | Some internal references found | Secrets detected, proprietary code | +| **Legal Risk** | Permissive license, no copyleft deps | Minor license inconsistencies | GPL/AGPL deps, license mismatch | +| **Open Source Risk** | All files present, active maintainers | Some files missing or thin | No README, no CODEOWNERS | + +## 7. Generate Compliance Report + +Post **one** comment on the triggering issue with these sections: + +1. **Header** — repo name, timestamp, overall status (PASS ✅ / NEEDS WORK ⚠️ / BLOCKED 🚫) +2. **📄 File Compliance** — table of 7 files with ✅/❌ status and notes +3. **🔒 Security Configuration** — table of 4 settings with status +4. **⚖️ License Analysis** — declared license, LICENSE file match, copyleft flags +5. **📊 Risk Assessment** — Business/Legal/Open Source risk levels (🟢/🟡/🔴) with details +6. **📋 Recommendations** — prioritized as Must Fix (blocking), Should Address, Nice to Have + +### Tone Guidelines + +- Be **constructive** — help teams succeed, don't gatekeep. +- Explain *why* missing items matter and link to guidance. +- Celebrate what the team has already done well. diff --git a/agentic-workflows/ospo/stale-repos.md b/agentic-workflows/ospo/stale-repos.md new file mode 100644 index 000000000..fb579f5f9 --- /dev/null +++ b/agentic-workflows/ospo/stale-repos.md @@ -0,0 +1,117 @@ +--- +name: Stale Repository Report +on: + schedule: + - cron: "3 2 1 * *" + workflow_dispatch: + inputs: + organization: + description: "GitHub organization to scan" + required: true + type: string + default: "my-org" + inactive_days: + description: "Number of days of inactivity before a repo is considered stale" + required: false + type: string + default: "365" + exempt_repos: + description: "Comma-separated list of repos to exempt from the report" + required: false + type: string + default: "" + exempt_topics: + description: "Comma-separated list of topics — repos with any of these topics are exempt" + required: false + type: string + default: "" + activity_method: + description: "Method to determine last activity" + required: false + type: choice + options: + - pushed + - default_branch_updated + default: pushed + +permissions: + contents: read + issues: write + +engine: copilot +tools: + github: + toolsets: + - repos + - issues + bash: true + +safe-outputs: + create-issue: + max: 1 + title-prefix: "[Stale Repos] " + labels: + - stale-repos + +timeout-minutes: 30 +--- + +You are an assistant that audits GitHub repositories for staleness. + +## Inputs + +| Input | Default | +|---|---| +| `organization` | `my-org` | +| `inactive_days` | `365` | +| `exempt_repos` | _(none)_ | +| `exempt_topics` | _(none)_ | +| `activity_method` | `pushed` | + +Use the workflow dispatch inputs if provided; otherwise fall back to the defaults above. + +## Instructions + +### 1. Enumerate repositories + +List **all** repositories in the `organization`. Exclude any repo that is: + +- **Archived** — skip it entirely. +- **Listed in `exempt_repos`** — compare repo names (case-insensitive) against the comma-separated list. +- **Tagged with an exempt topic** — if the repo has any topic that appears in the comma-separated `exempt_topics` list, skip it. + +### 2. Determine last activity date + +For each remaining repo, determine the **last activity date** based on `activity_method`: + +- **`pushed`** — use the repository's `pushed_at` timestamp (this is the default and most efficient method). +- **`default_branch_updated`** — fetch the most recent commit on the repo's default branch and use that commit's `committer.date`. + +### 3. Identify stale repos + +Calculate the number of days between the last activity date and **today**. If the number of days exceeds `inactive_days`, mark the repo as **stale**. + +### 4. Generate report + +Build a **Markdown report** with a summary and a table: + +> **Stale Repository Report — \** +> Found **N** repositories with no activity in the last **inactive_days** days. + +| Repository | Days Inactive | Last Push Date | Visibility | +|---|---|---|---| +| [owner/repo](https://github.com/owner/repo) | 420 | 2024-01-15 | public | + +Sort the table by **Days Inactive** descending (most stale first). + +If there are **no stale repos**, still create the issue but note that all repositories are active. + +### 5. Create or update issue + +Search for an existing **open** issue in the `organization/.github` repo (or the repo this workflow runs in) with the label `stale-repos` and a title starting with `[Stale Repos]`. + +- If an **existing open issue** is found, **update its body** with the new report. +- If **no open issue** exists, **create a new issue** with: + - Title: `[Stale Repos] Inactive Repository Report — ` + - Label: `stale-repos` + - Body: the full Markdown report from step 4. diff --git a/docs/README.skills.md b/docs/README.skills.md index e55085b72..94fc7a24d 100644 --- a/docs/README.skills.md +++ b/docs/README.skills.md @@ -48,6 +48,7 @@ Skills differ from other primitives by supporting bundled assets (scripts, code | [microsoft-skill-creator](../skills/microsoft-skill-creator/SKILL.md) | Create agent skills for Microsoft technologies using Learn MCP tools. Use when users want to create a skill that teaches agents about any Microsoft technology, library, framework, or service (Azure, .NET, M365, VS Code, Bicep, etc.). Investigates topics deeply, then generates a hybrid skill storing essential knowledge locally while enabling dynamic deeper investigation. | `references/skill-templates.md` | | [nano-banana-pro-openrouter](../skills/nano-banana-pro-openrouter/SKILL.md) | Generate or edit images via OpenRouter with the Gemini 3 Pro Image model. Use for prompt-only image generation, image edits, and multi-image compositing; supports 1K/2K/4K output. | `assets/SYSTEM_TEMPLATE`
`scripts/generate_image.py` | | [nuget-manager](../skills/nuget-manager/SKILL.md) | Manage NuGet packages in .NET projects/solutions. Use this skill when adding, removing, or updating NuGet package versions. It enforces using `dotnet` CLI for package management and provides strict procedures for direct file edits only when updating versions. | None | +| [ospo-readiness](../skills/ospo-readiness/SKILL.md) | Scan any GitHub repository for open source readiness. Evaluates LICENSE, CONTRIBUTING.md, dependency license compatibility, README quality, SECURITY.md, CODE_OF_CONDUCT.md, CI/CD workflows, and issue/PR templates. Produces a scored readiness report with a letter grade (A–F) and actionable recommendations. Use when evaluating a repo for open source compliance, OSPO review, or community health. Invoke by providing a GitHub owner/repo (e.g. "scan expressjs/express for open source readiness"). | None | | [penpot-uiux-design](../skills/penpot-uiux-design/SKILL.md) | Comprehensive guide for creating professional UI/UX designs in Penpot using MCP tools. Use this skill when: (1) Creating new UI/UX designs for web, mobile, or desktop applications, (2) Building design systems with components and tokens, (3) Designing dashboards, forms, navigation, or landing pages, (4) Applying accessibility standards and best practices, (5) Following platform guidelines (iOS, Android, Material Design), (6) Reviewing or improving existing Penpot designs for usability. Triggers: "design a UI", "create interface", "build layout", "design dashboard", "create form", "design landing page", "make it accessible", "design system", "component library". | `references/accessibility.md`
`references/component-patterns.md`
`references/platform-guidelines.md`
`references/setup-troubleshooting.md` | | [plantuml-ascii](../skills/plantuml-ascii/SKILL.md) | Generate ASCII art diagrams using PlantUML text mode. Use when user asks to create ASCII diagrams, text-based diagrams, terminal-friendly diagrams, or mentions plantuml ascii, text diagram, ascii art diagram. Supports: Converting PlantUML diagrams to ASCII art, Creating sequence diagrams, class diagrams, flowcharts in ASCII format, Generating Unicode-enhanced ASCII art with -utxt flag | None | | [powerbi-modeling](../skills/powerbi-modeling/SKILL.md) | Power BI semantic modeling assistant for building optimized data models. Use when working with Power BI semantic models, creating measures, designing star schemas, configuring relationships, implementing RLS, or optimizing model performance. Triggers on queries about DAX calculations, table relationships, dimension/fact table design, naming conventions, model documentation, cardinality, cross-filter direction, calculation groups, and data model best practices. Always connects to the active model first using power-bi-modeling MCP tools to understand the data structure before providing guidance. | `references/MEASURES-DAX.md`
`references/PERFORMANCE.md`
`references/RELATIONSHIPS.md`
`references/RLS.md`
`references/STAR-SCHEMA.md` | diff --git a/skills/ospo-readiness/SKILL.md b/skills/ospo-readiness/SKILL.md new file mode 100644 index 000000000..930b23f06 --- /dev/null +++ b/skills/ospo-readiness/SKILL.md @@ -0,0 +1,313 @@ +--- +name: ospo-readiness +description: 'Scan any GitHub repository for open source readiness. Evaluates LICENSE, CONTRIBUTING.md, dependency license compatibility, README quality, SECURITY.md, CODE_OF_CONDUCT.md, CI/CD workflows, and issue/PR templates. Produces a scored readiness report with a letter grade (A–F) and actionable recommendations. Use when evaluating a repo for open source compliance, OSPO review, or community health. Invoke by providing a GitHub owner/repo (e.g. "scan expressjs/express for open source readiness").' +--- + +# Open Source Readiness Scanner + +Evaluate any GitHub repository for open source readiness. Accepts a GitHub `owner/repo`, inspects it remotely using the GitHub MCP tools, and produces a scored readiness report with actionable recommendations. + +## Your Workflow + +When the user provides a repository in `owner/repo` format: + +1. **Parse the input** — Extract the `owner` and `repo` from the user's message. +2. **Run all checks** (detailed below) by fetching files from the repo using the GitHub MCP tools. +3. **Score each check** using the scoring model. +4. **Output the readiness report** in the format specified below. +5. **If the user asks**, create a GitHub Issue on the repo with the report. + +Always run ALL checks before producing the report. Do not stop early. + +--- + +## Check 1: LICENSE File (Weight: High — 3 pts) + +Use `get_file_contents` to look for a license file at these paths (try in order, stop at first match): +- `LICENSE` +- `LICENSE.md` +- `LICENSE.txt` +- `COPYING` + +### Scoring +- **✅ Pass (3 pts):** File exists AND contains a recognized OSI-approved license. Identify it by matching against these SPDX identifiers: `MIT`, `Apache-2.0`, `BSD-2-Clause`, `BSD-3-Clause`, `ISC`, `MPL-2.0`, `LGPL-2.1`, `LGPL-3.0`, `GPL-2.0`, `GPL-3.0`, `AGPL-3.0`, `Unlicense`, `0BSD`, `Artistic-2.0`, `Zlib`, `BSL-1.0`, `PostgreSQL`, `EUPL-1.2`. Look for the license name or SPDX identifier in the file text. +- **⚠️ Partial (1.5 pts):** File exists but the license is not recognized or could not be identified. +- **❌ Fail (0 pts):** No license file found. + +### Recommendation on Fail +> Add a LICENSE file to the repository root. Use https://choosealicense.com to select an appropriate OSI-approved license. + +--- + +## Check 2: CONTRIBUTING.md (Weight: High — 3 pts) + +Use `get_file_contents` to look for: +- `CONTRIBUTING.md` +- `.github/CONTRIBUTING.md` +- `docs/CONTRIBUTING.md` + +Then analyze the content for these key sections (case-insensitive header matching): +- **How to contribute** (look for: "how to", "getting started", "contribute", "contributing") +- **Pull request process** (look for: "pull request", "PR", "submit", "review") +- **Code of Conduct reference** (look for: "code of conduct", "CoC", "behavior") + +### Scoring +- **✅ Pass (3 pts):** File exists AND contains all 3 key sections. +- **⚠️ Partial (1.5 pts):** File exists but is missing 1 or more key sections. +- **❌ Fail (0 pts):** No CONTRIBUTING.md found. + +### Recommendation on Fail +> Add a CONTRIBUTING.md that explains how to contribute, the PR review process, and links to the Code of Conduct. See https://mozillascience.github.io/working-open-workshop/contributing/ for a template. + +--- + +## Check 3: Dependency License Compatibility (Weight: High — 3 pts) + +### Step 1: Detect manifest files +Use `get_file_contents` on the repo root `/` to list files. Look for any of these manifest files: +- `package.json` (Node.js/npm) +- `requirements.txt` or `setup.py` or `pyproject.toml` (Python) +- `go.mod` (Go) +- `Gemfile` (Ruby) +- `pom.xml` or `build.gradle` (Java) +- `Cargo.toml` (Rust) +- `composer.json` (PHP) +- `*.csproj` or `packages.config` (C#/.NET) + +### Step 2: Parse dependencies +Fetch the manifest file contents and extract dependency names. For `package.json`, look at `dependencies` and `devDependencies`. For other formats, extract package names from the relevant fields. + +### Step 3: Check dependency licenses +For each dependency (sample up to 15 to stay efficient): +- For npm packages: use `web_fetch` on `https://registry.npmjs.org/{package}/latest` and check the `license` field. +- For other ecosystems: use `get_file_contents` to check the dependency's GitHub repo LICENSE file if the repo URL is available in the manifest, or use `web_search` to find the license. + +### Step 4: Evaluate compatibility +Flag any dependencies with: +- **Copyleft licenses** (GPL, AGPL) in a project using a permissive license (MIT, Apache, BSD) — this is a compatibility issue. +- **No license / unknown license** — this is a risk. +- **Non-OSI-approved licenses** — flag for review. + +### Scoring +- **✅ Pass (3 pts):** Manifest found, all sampled dependencies have compatible OSI-approved licenses. +- **⚠️ Partial (1.5 pts):** Manifest found, but some dependencies have unknown or potentially incompatible licenses. +- **❌ Fail (0 pts):** No manifest file found, OR multiple dependencies have incompatible or missing licenses. + +### Recommendation on Partial/Fail +> Review flagged dependencies and ensure license compatibility. Consider using a tool like `license-checker` (npm), `pip-licenses` (Python), or `go-licenses` (Go) for a full audit. + +--- + +## Check 4: README.md Quality (Weight: Medium — 2 pts) + +Use `get_file_contents` for `README.md` (or `readme.md`, `Readme.md`). + +Check for these sections (case-insensitive header matching): +- **Project description** (first paragraph or section with "about", "description", "overview", "what is") +- **Installation instructions** (look for: "install", "getting started", "setup", "quick start") +- **Usage examples** (look for: "usage", "example", "how to use", "demo") +- **License mention** (look for: "license" section or badge) + +### Scoring +- **✅ Pass (2 pts):** README exists AND has all 4 sections. +- **⚠️ Partial (1 pt):** README exists but missing 1-2 sections. +- **❌ Fail (0 pts):** No README, or missing 3+ sections. + +### Recommendation on Fail/Partial +> Improve your README with: a project description, installation steps, usage examples, and a license section. See https://www.makeareadme.com for best practices. + +--- + +## Check 5: SECURITY.md (Weight: Medium — 2 pts) + +Use `get_file_contents` to look for: +- `SECURITY.md` +- `.github/SECURITY.md` +- `docs/SECURITY.md` + +### Scoring +- **✅ Pass (2 pts):** Security policy file exists and includes how to report vulnerabilities (look for: "report", "vulnerability", "security", "disclosure", "email", "contact"). +- **⚠️ Partial (1 pt):** File exists but is very short (< 50 words) or lacks reporting instructions. +- **❌ Fail (0 pts):** No security policy found. + +### Recommendation on Fail +> Add a SECURITY.md explaining how to report security vulnerabilities privately. See https://docs.github.com/en/code-security/getting-started/adding-a-security-policy-to-your-repository. + +--- + +## Check 6: CODE_OF_CONDUCT.md (Weight: Medium — 2 pts) + +Use `get_file_contents` to look for: +- `CODE_OF_CONDUCT.md` +- `.github/CODE_OF_CONDUCT.md` + +### Scoring +- **✅ Pass (2 pts):** Code of Conduct file exists. +- **⚠️ Partial (1 pt):** CONTRIBUTING.md references a Code of Conduct, but no standalone CoC file exists. +- **❌ Fail (0 pts):** No Code of Conduct found anywhere. + +### Recommendation on Fail +> Add a CODE_OF_CONDUCT.md. The Contributor Covenant (https://www.contributor-covenant.org) is the most widely adopted standard. + +--- + +## Check 7: CI/CD Workflows (Weight: Low — 1 pt) + +Use `get_file_contents` on `.github/workflows/` to list directory contents. + +### Scoring +- **✅ Pass (1 pt):** At least one `.yml` or `.yaml` workflow file exists. +- **❌ Fail (0 pts):** No workflows directory or no workflow files. + +### Recommendation on Fail +> Add a GitHub Actions workflow for CI (build + test). See https://docs.github.com/en/actions/quickstart. + +--- + +## Check 8: Issue/PR Templates (Weight: Low — 1 pt) + +Use `get_file_contents` to check for any of: +- `.github/ISSUE_TEMPLATE/` (directory with templates) +- `.github/ISSUE_TEMPLATE.md` +- `.github/pull_request_template.md` +- `.github/PULL_REQUEST_TEMPLATE/` + +### Scoring +- **✅ Pass (1 pt):** At least one issue template AND one PR template exist. +- **⚠️ Partial (0.5 pts):** Only one of issue or PR template exists. +- **❌ Fail (0 pts):** No templates found. + +### Recommendation on Fail +> Add issue and PR templates to standardize contributions. See https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests. + +--- + +## Org-Level Community Health Files + +Many organizations host CONTRIBUTING.md, CODE_OF_CONDUCT.md, and SECURITY.md in a `.github` repository at the org level (e.g., `expressjs/.github`). If a file is not found in the repo itself: + +1. Check if the README references it via a link (e.g., `[Code of Conduct]: https://github.com/{org}/.github/blob/HEAD/CODE_OF_CONDUCT.md`). +2. If so, try fetching it from `{org}/.github` using `get_file_contents`. +3. If found at the org level, count it as ✅ Pass but note in details: "Found at org level ({org}/.github)". +4. If not found anywhere, score as ❌ Fail. + +--- + +## Scoring Model + +| Weight | Points | +|--------|--------| +| High | 3 pts | +| Medium | 2 pts | +| Low | 1 pt | + +**Maximum total: 18 points** + +Calculate percentage: `(earned / 18) × 100` + +| Grade | Percentage | +|-------|-----------| +| A | 90–100% | +| B | 75–89% | +| C | 60–74% | +| D | 40–59% | +| F | 0–39% | + +--- + +## Output Format + +Always produce the report in this exact format: + +``` +# 📋 Open Source Readiness Report + +**Repository:** {owner}/{repo} +**Scanned:** {current date} +**Grade:** {letter grade} ({percentage}% — {earned}/{max} pts) + +--- + +## Checklist + +| # | Check | Status | Score | Details | +|---|-------|--------|-------|---------| +| 1 | LICENSE | {✅/⚠️/❌} | {score}/3 | {license type or issue found} | +| 2 | CONTRIBUTING.md | {✅/⚠️/❌} | {score}/3 | {sections found/missing} | +| 3 | Dependency Licenses | {✅/⚠️/❌} | {score}/3 | {summary of findings} | +| 4 | README Quality | {✅/⚠️/❌} | {score}/2 | {sections found/missing} | +| 5 | SECURITY.md | {✅/⚠️/❌} | {score}/2 | {exists/missing} | +| 6 | CODE_OF_CONDUCT.md | {✅/⚠️/❌} | {score}/2 | {exists/missing} | +| 7 | CI/CD Workflows | {✅/⚠️/❌} | {score}/1 | {count of workflows found} | +| 8 | Issue/PR Templates | {✅/⚠️/❌} | {score}/1 | {which templates found} | + +--- + +## 🔍 Detailed Findings + +### 1. LICENSE — {status} +{Detailed explanation of what was found} + +### 2. CONTRIBUTING.md — {status} +{Detailed explanation} + +### 3. Dependency Licenses — {status} +{Table of sampled dependencies and their licenses, flagging any issues} + +### 4. README Quality — {status} +{Sections found and missing} + +### 5. SECURITY.md — {status} +{What was found} + +### 6. CODE_OF_CONDUCT.md — {status} +{What was found} + +### 7. CI/CD Workflows — {status} +{Workflow files found} + +### 8. Issue/PR Templates — {status} +{Templates found} + +--- + +## 📌 Recommendations + +{Numbered list of actionable recommendations, ordered by priority (High → Medium → Low weight items first). Only include recommendations for checks that did not fully pass.} + +--- + +## 🏆 Summary + +{2-3 sentence summary of the repo's open source readiness, highlighting strengths and the most important areas for improvement.} +``` + +--- + +## Creating a GitHub Issue (Optional) + +If the user explicitly asks to create a GitHub Issue with the findings, create an issue on the target repo with: +- **Title:** `Open Source Readiness Report — Grade: {letter grade}` +- **Body:** The full report from above +- **Labels:** If possible, add the label `ospo` or `open-source-readiness` (create the label if needed, or skip labeling if you can't) + +Only do this if the user asks. Never create issues automatically. + +--- + +## Error Handling + +- If `get_file_contents` returns a 404 or permission error for the repo itself, inform the user that the repository may not exist or may be private/inaccessible. +- If a specific file is not found, that's expected — score it as ❌ and move on. +- If the npm registry or other external API is unreachable, note it in the dependency check details and score as ⚠️. +- Always complete all 8 checks even if some fail — never stop early. + +--- + +## Important Rules + +1. **Always use the GitHub MCP tools** — never try to clone, download, or shell out to access the repo. +2. **Be thorough but efficient** — for dependency scanning, sample up to 15 dependencies to avoid excessive API calls. +3. **Be precise in scoring** — follow the scoring rubric exactly. Do not inflate or deflate scores. +4. **Be actionable** — every failing check should have a specific, helpful recommendation. +5. **Stay in scope** — only evaluate what's defined in the 8 checks. Don't add extra opinions unless asked.