From 68826fbe058a2cec5110f7946b644fe4093a706b Mon Sep 17 00:00:00 2001 From: Gilbert Sanchez Date: Tue, 21 Apr 2026 14:22:13 -0700 Subject: [PATCH 1/6] feat: add governance model and CoC placeholder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Full governance doc covering roles (Steward, Council, Maintainer, Contributor), decision-making (72h silent-assent, council-gated list), maintainer lifecycle, succession, and repo lifecycle states. CODE_OF_CONDUCT.md is a placeholder — paste CC 3.0 text before publishing. --- .github/CODE_OF_CONDUCT.md | 205 +++++++++++++++++++++++++++++++++ .github/GOVERNANCE.md | 225 +++++++++++++++++++++++++++++++++++++ 2 files changed, 430 insertions(+) create mode 100644 .github/CODE_OF_CONDUCT.md create mode 100644 .github/GOVERNANCE.md diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..a4aeb02 --- /dev/null +++ b/.github/CODE_OF_CONDUCT.md @@ -0,0 +1,205 @@ +# PowerShellOrg Code of Conduct + +PowerShellOrg has adopted the Contributor Covenant version 3.0 as our Code of +Conduct. The full text follows, with PowerShellOrg-specific reporting and +enforcement details filled in. + +## Our Pledge + +We as members, contributors, leaders, and participants in the PowerShellOrg +community pledge to make participation in our community a harassment-free +experience for everyone, regardless of age, body size, visible or invisible +disability, ethnicity, sex characteristics, gender identity and expression, +level of experience, education, socio-economic status, nationality, personal +appearance, race, caste, color, religion, sexual identity and orientation, or +any other dimension of diversity. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community, focused on the shared goal of +building and maintaining open source PowerShell tooling. + +## Encouraged Behaviors + +We encourage all community members to: + +- Demonstrate empathy, kindness, and respect toward other people +- Be respectful of differing opinions, viewpoints, and experiences +- Give and gracefully accept constructive feedback +- Accept responsibility, apologize to those affected by our mistakes, and learn + from the experience +- Focus on what is best not just for us as individuals, but for the overall + community +- Use welcoming and inclusive language +- Help newcomers feel welcome and supported +- Credit others' contributions generously + +## Unacceptable Behaviors + +The following behaviors are considered violations of this Code of Conduct: + +- Harassment of any participant, in any form +- Discrimination, particularly against members of vulnerable or underrepresented + groups +- The use of sexualized language or imagery, and sexual attention or advances of + any kind +- Trolling, insulting or derogatory comments, and personal or political attacks +- Public or private harassment, including stalking, doxxing, or sustained + disruption of discussions +- Publishing others' private information, such as a physical or email address, + without their explicit permission +- Advocating for, or encouraging, any of the above behavior +- Other conduct which could reasonably be considered inappropriate in a + professional setting + +We recognize that even well-intentioned actions can cause harm. Impact matters +more than intent. When informed that our behavior has caused harm, the +appropriate response is to listen, take responsibility, apologize sincerely, and +change the behavior — not to defend the original intent. + +## Consent and Boundaries + +Community members must respect stated boundaries immediately. When a member asks +another to stop a behavior, end a line of conversation, or leave them alone, the +request must be honored without argument. + +Repeated boundary violations after a clear request to stop will be treated as +harassment. + +## Scope + +This Code of Conduct applies within all PowerShellOrg community spaces, +including: + +- All repositories within github.com/PowerShellOrg +- GitHub Discussions, Issues, and Pull Requests +- Any official PowerShellOrg communication channels (chat platforms, mailing + lists, video calls) +- Public events where someone is officially representing PowerShellOrg + +It also applies when an individual is officially representing the community in +public spaces. Examples of representing our community include using an official +email address, posting via an official social media account, or acting as an +appointed representative at an online or offline event. + +This Code of Conduct also applies to behavior outside these spaces when that +behavior has the potential to adversely affect the safety and well-being of +community members. + +## Reporting Concerns + +If you experience or witness behavior that violates this Code of Conduct, please +report it. You will not be retaliated against for making a good-faith report. + +**Primary contact:** + +**Alternate contact:** Direct message to the Steward via GitHub or Discord. + +When reporting, please include: + +- Your contact information (so we can follow up) +- Names (real or usernames) of any individuals involved, including witnesses +- A description of what happened, with as much specificity as possible +- The approximate date and time +- Links to any relevant public records (issues, pull requests, chat messages) +- Any additional context that would help us understand the situation +- Whether you believe the situation is ongoing + +Reports will be acknowledged within 72 hours. + +All reports will be handled with discretion. We will not share your identity +with the person you are reporting without your explicit consent, except where +required by law. + +## Addressing and Repairing Harm + +When a Code of Conduct violation is reported, the Steward (with input from the +Council where appropriate) will determine an appropriate response. Our goal is +to address harm, support those affected, and where possible find a path for the +person who caused harm to repair the relationship and reintegrate into the +community. + +The following is a guideline. The Steward retains discretion to apply responses +appropriate to the specific situation, including responses not listed here. + +### 1. Private Conversation + +**Community impact:** Use of inappropriate language, a single instance of +unprofessional behavior, or behavior that, while not severe, was unwelcome. + +**Response:** A private written communication from the Steward, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community impact:** A violation through a single incident or series of +actions, or a pattern of behavior that has caused harm to one or more community +members. + +**Response:** A written warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or permanent +ban. + +### 3. Temporary Ban + +**Community impact:** A serious violation of community standards, including +sustained inappropriate behavior or harassment of an individual. + +**Response:** A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community impact:** Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Response:** A permanent ban from any sort of public interaction within the +community. + +## Restorative Paths + +Where appropriate, and at the discretion of the Steward and the affected +parties, we may offer paths for community members who have caused harm to repair +the relationship and re-engage with the community. This may include: + +- A private acknowledgment of the harm caused +- A public apology, when requested by those harmed +- A defined period of restricted participation +- A clear set of expectations for re-engagement + +Restorative paths are not available for severe violations, including but not +limited to harassment, doxxing, threats of violence, or sexual misconduct. + +## Appeals + +A person who has been subject to enforcement action may appeal the decision by +writing to the Steward within 30 days. The Steward will review the appeal with +input from the Council and respond within 30 days. + +If the appeal involves the Steward's own decision and the appellant believes the +Steward cannot review it impartially, they may request that the Council review +the appeal collectively. In that case, the Council reviews and decides by +majority, and the Steward does not vote. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 3.0, available at +. + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this Code of Conduct, see the FAQ at +. Translations are available at +. + +--- + +*Last updated: 2026/04/21. Reports go to .* diff --git a/.github/GOVERNANCE.md b/.github/GOVERNANCE.md new file mode 100644 index 0000000..6217363 --- /dev/null +++ b/.github/GOVERNANCE.md @@ -0,0 +1,225 @@ +# PowerShellOrg Governance + +PowerShellOrg is a community-run GitHub organization that adopts and maintains +open source PowerShell tooling. This document describes how decisions get made, +how people join and leave, and how projects move through their lifecycle. + +The model is deliberately lightweight. We are a small volunteer community, not a +foundation. Speed and clarity matter more than process. + +## Roles + +### Steward + +One person. The Steward is the org's tiebreaker, external face, and +direction-setter. + +Responsibilities: + +- Holds the GitHub org admin role +- Owns the PowerShell Gallery account that issues per-repo scoped API keys +- Decides contested questions with input from the Council +- Represents PowerShellOrg externally +- Maintains the private API key tracking record + +The role is named ("Steward of PowerShellOrg") rather than tied to an individual +so that succession is possible without renaming the role. + +### Council + +Up to seven people. Active maintainers across the org's repositories. + +By default, one Council seat per actively-maintained repository. The Steward may +invite additional members for cross-cutting work (CI infrastructure, security +response, documentation). The Council's role is **input, not consensus** — they +raise issues, propose changes, review adoption requests, and surface concerns. +The Steward decides. + +Council members are expected to: + +- Be reachable on the Council channel +- Respond to adoption requests and governance proposals within the comment + window +- Flag concerns about other maintainers, repositories, or the direction of the + org + +### Maintainer + +Per-repository role. Has write access to a specific repository, can merge pull +requests, can cut releases. + +Maintainers are added per-repo, not org-wide. A maintainer on one repository has +no special standing on others. + +### Contributor + +Anyone with a merged pull request to any PowerShellOrg repository. No special +permissions; recognition only. + +## How decisions get made + +**Default: Steward decides with Council input.** Speed is the explicit priority. + +For non-urgent decisions, the Steward will normally: + +1. Post a "thinking about doing X" note in the Council channel +2. Wait 72 hours for input +3. Act + +Silence is assent. The Steward may act immediately for urgent matters and post +the rationale afterward. + +### Decisions that require Council input before action + +The Steward may not act unilaterally on these. Each requires a posted proposal +and a comment window before action. + +- Adopting a new tool into the org +- Adding or removing a maintainer +- Graduating a tool to the `stable` lifecycle state +- Archiving or deprecating a tool +- Changing this governance document +- Changing the Code of Conduct +- Changing the standard build stack + +Comment windows: + +- Adoption decisions: 7 to 30 days from the adoption request being filed +- Maintainer changes: 72 hours +- Graduation: 7 days +- Archival: 30 days +- Governance, Code of Conduct, or standard stack changes: 14 days + +### Decisions at maintainer discretion + +Within a repository, maintainers have full discretion over: + +- Routine pull request review and merge +- Releases (within the standard pipeline) +- Issue triage and labeling +- Day-to-day technical direction +- Repository-specific contributing guidelines that supplement the org-wide ones + +## How maintainers get added + +Three paths. + +**Sustained contribution.** Several merged pull requests and demonstrated +judgment over weeks to months. An existing maintainer nominates the contributor +in the Council channel; the Steward confirms within 72 hours. + +**Adoption.** When PowerShellOrg adopts a tool, the submitter is offered +maintainer status on that repository by default. This is part of the adoption +commitment. + +**Steward appointment.** For repositories with no active maintainer (typically +newly adopted or a maintainer departure), the Steward can directly appoint +someone willing to take it on. This is announced to the Council, not gated by +it. + +## How maintainers get removed + +Three paths. All preserve the contributor's commit history and credit. + +**Self-departure.** Anyone can step down at any time. We thank them, remove +access, archive their context, and move on. No questions asked. + +**Inactivity.** No commits, reviews, or Council participation for nine months +triggers a Steward check-in. No response within thirty days of that check-in +results in write access being removed. Access can be reinstated at any time on +request. + +**For cause.** Code of Conduct violation, security incident, or sustained +pattern of behavior that damages the project. This is a Steward decision after +Council input. We document the decision privately for the Council and +communicate it publicly only to the extent necessary. + +## Succession + +If the Steward steps down, the Council selects a new Steward by majority vote. +The outgoing Steward, if available, confirms the selection. + +If the Steward becomes unavailable without stepping down (extended +unresponsiveness, incapacity), the Council may proceed with selection after a +thirty-day attempt to reach them. The selection is documented publicly. + +To make this resilient: the Steward designates a backup with org admin access at +all times. The backup is not formally the Steward but has the technical access +to keep operations running during a transition. + +## Lifecycle states + +Every repository in the org is in one of four lifecycle states, tracked via a +topic tag on the repository. + +**`status-incoming`** — Just adopted, working through the revival playbook. +Time-bounded; should not exceed 90 days. + +**`status-active`** — Default working state. Modernized build, clean releases, +responsive maintainership. First-response targets apply (7 days for issues and +PRs). + +**`status-stable`** — Graduated. Mature, slow-changing tool that does not need +active feature development. Stays in the org with reduced stewardship cadence. +First-response target relaxes to 30 days. Security response time stays at the +SECURITY.md baseline regardless of state. + +**`status-archived`** — No longer maintained. Repository is read-only on GitHub. +PowerShell Gallery package is left in place (existing users would otherwise +break) with a deprecation note added to the package description. + +State transitions follow the criteria in the Revival Playbook (`incoming` to +`active`), the graduation criteria below, and the archival process below. + +### Graduation criteria + +Moving from `active` to `stable` requires all of the following to be true. + +- At least 12 months in `active` state with consistent maintenance +- At least 2 clean releases under PowerShellOrg +- Test coverage adequate to catch regressions (judgment, not a percentage) +- No critical open issues, no known unaddressed security issues +- At least 2 active maintainers (so the project is not a single point of + failure) +- Documentation reasonably complete + +The repository's maintainers propose graduation in the Council channel. After a +7-day comment window, the Steward decides. + +### Archival process + +A repository may be considered for archival when any of the following is true. + +- No commits, releases, or substantive issue activity for 24 months +- Superseded by a clearly better in-org or external tool +- No willing maintainer found after a 90-day open call +- The original problem space no longer exists + +The Steward proposes archival in the Council channel. After a 30-day comment +window, if no compelling objection is raised, the repository is archived: marked +read-only on GitHub, README updated to point at successors where applicable, +deprecation note added to the PowerShell Gallery package description, repository +topic tag updated to `status-archived`. + +## Scope + +PowerShellOrg adopts and maintains community PowerShell tooling — modules, build +tools, and developer utilities. + +Out of scope: + +- Microsoft-owned tooling or anything that would compete with active first-party + maintenance +- Single-vendor commercial tools +- Anything that would compete with an active upstream maintainer +- Anything we do not have the bandwidth to actually maintain + +## Changing this document + +Changes to this governance document follow the rules above: Council comment +window of 14 days, Steward decides. Material changes are announced on the org +profile and in a pinned discussion. + +--- + +*Last updated: 2026/04/21. Maintained by the Steward with input from the Council.* From 5e79d1d4dca0211cf87dd64b88039a9ea51e7066 Mon Sep 17 00:00:00 2001 From: Gilbert Sanchez Date: Tue, 21 Apr 2026 14:35:28 -0700 Subject: [PATCH 2/6] feat: add community health files CONTRIBUTING.md: dev setup, branching conventions, PR expectations, review SLAs (7d active / 30d stable), release process, license-by-contribution. SECURITY.md: GitHub PVR as primary channel, fallback email, 72h ack / 7d update / 14d critical fix SLA, coordinated disclosure, CVE commitment. SUPPORT.md: Discussions for questions, Issues for bugs, no-DM policy. FUNDING.yml: commented placeholder for future sponsorship setup. Also includes updated GOVERNANCE.md and CODE_OF_CONDUCT.md from post-commit revision. --- .github/CONTRIBUTING.md | 135 ++++++++++++++++++++++++++++++++++++++++ .github/FUNDING.yml | 10 +++ .github/SECURITY.md | 107 +++++++++++++++++++++++++++++++ .github/SUPPORT.md | 40 ++++++++++++ 4 files changed, 292 insertions(+) create mode 100644 .github/CONTRIBUTING.md create mode 100644 .github/FUNDING.yml create mode 100644 .github/SECURITY.md create mode 100644 .github/SUPPORT.md diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md new file mode 100644 index 0000000..44bc986 --- /dev/null +++ b/.github/CONTRIBUTING.md @@ -0,0 +1,135 @@ +# Contributing to PowerShellOrg Projects + +Welcome — and thank you for considering a contribution. PowerShellOrg maintains PowerShell open-source tools that depend on community involvement to survive. Every bug report, doc fix, and pull request matters. + +This document covers org-wide expectations. Individual repos may add project-specific guidance in their own `README.md` or `CONTRIBUTING.md`; where they conflict with this document, the repo-level doc takes precedence. + +--- + +## Scope and governance + +PowerShellOrg focuses on PowerShell tooling. Before proposing a large feature or a significant design change, read [GOVERNANCE.md](GOVERNANCE.md) to understand how decisions get made. For substantial proposals, open an issue first so we can align before you invest time writing code. + +--- + +## Before you contribute + +1. **Check existing issues and PRs.** Someone may already be working on it. +2. **Read the repo's README.** Each project documents its purpose, status, and any project-specific constraints. +3. **Agree to the license terms.** By submitting a contribution you agree that your work is licensed under the repo's license (MIT unless noted otherwise). See [License by contribution](#license-by-contribution) below. + +--- + +## Development setup + +All PowerShellOrg projects use the same build stack: + +| Tool | Purpose | +|---|---| +| [psake](https://github.com/psake/psake) | Build automation | +| [PowerShellBuild](https://github.com/psake/PowerShellBuild) | Shared psake task library | +| [Pester 5](https://pester.dev) | Testing | +| [PSScriptAnalyzer](https://github.com/PowerShell/PSScriptAnalyzer) | Static analysis | + +**Install build dependencies:** + +```powershell +Install-Module psake -Scope CurrentUser -Force +Install-Module PowerShellBuild -Scope CurrentUser -Force +Install-Module Pester -Scope CurrentUser -Force -MinimumVersion '5.0' +Install-Module PSScriptAnalyzer -Scope CurrentUser -Force +``` + +**Common psake tasks** (every repo exposes these): + +```powershell +Invoke-psake Init # First-time setup +Invoke-psake Clean # Remove build artifacts +Invoke-psake Build # Compile / stage the module +Invoke-psake Test # Run Pester tests +Invoke-psake Analyze # Run PSScriptAnalyzer +Invoke-psake Publish # Publish to PSGallery (maintainers only) +``` + +Run `Invoke-psake ?` to see all available tasks and their descriptions. + +**Target platforms:** Windows PowerShell 5.1 and PowerShell 7.x on Windows, Linux, and macOS. Write code that runs on all six combinations. + +--- + +## Branching and commits + +- **Fork the repo** and work on a branch named for the thing you're changing: `fix/null-ref-in-invoke`, `feat/add-verbose-output`, `docs/update-readme`. +- **Keep commits focused.** One logical change per commit. Use the [Conventional Commits](https://www.conventionalcommits.org/) style: + - `fix: correct null reference in Invoke-PSDepend` + - `feat: add -WhatIf support to Install task` + - `docs: clarify quickstart example` + - `chore: bump Pester to 5.6` + - `test: add coverage for empty dependency file` +- **Do not squash history prematurely.** Maintainers may squash on merge if appropriate. +- **Keep `main` green.** Never force-push to `main` or shared branches. + +--- + +## Pull request expectations + +Before opening a PR: + +- [ ] `Invoke-psake Test` passes locally on at least one platform +- [ ] `Invoke-psake Analyze` passes with no new warnings +- [ ] New behavior has Pester test coverage +- [ ] `CHANGELOG.md` is updated for user-facing changes +- [ ] Docs are updated if behavior changed + +Fill out the PR template completely. PRs with empty templates or no linked issue for non-trivial changes will be asked to complete the template before review starts. + +**Draft PRs** are welcome for early feedback. Mark them ready for review when you want the full review pass. + +--- + +## Code review expectations + +### For contributors + +- Respond to review comments within **14 days**. If you need more time, say so — we will wait. +- If a comment is a question, answer it. If it is a request, either make the change or explain why you disagree. +- A maintainer will make the final call. Disagreements are discussed, not escalated. + +### For maintainers + +| Repo status | First response SLA | Review completion SLA | +|---|---|---| +| `status-active` | 7 days | 30 days | +| `status-stable` | 30 days | 60 days | + +SLAs are best-effort commitments, not guarantees. If a repo is understaffed, the Steward will note this in the repo's README. + +If a PR sits without response past the SLA, ping `@PowerShellOrg/maintainers` or open a discussion. + +--- + +## Releases + +Releases are cut by maintainers. The process: + +1. Maintainer updates `CHANGELOG.md` and bumps the module version in the manifest. +2. Maintainer opens a PR titled `chore: release vX.Y.Z`. +3. PR is reviewed and merged to `main`. +4. Maintainer pushes a version tag (`vX.Y.Z`) to `main`. +5. The tag triggers `powershell-release.yml`, which builds, publishes to PSGallery, and creates a GitHub Release. + +Contributors do not cut releases. If you believe a release is overdue, open an issue and tag the maintainers. + +--- + +## License by contribution + +By submitting a pull request or other contribution, you agree that your contribution is made under the same license as the project you are contributing to (MIT unless the repo states otherwise). You represent that you have the right to make the contribution under those terms. + +If your employer has rights to code you write, ensure you have permission to contribute it before submitting. + +--- + +## Questions? + +See [SUPPORT.md](SUPPORT.md). diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..faeb3c5 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,10 @@ +# PowerShellOrg funding configuration +# +# Uncomment and fill in the appropriate platform(s) if/when sponsorship +# is set up. See: https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/displaying-a-sponsor-button-in-your-repository +# +# github: # GitHub Sponsors username(s) +# open_collective: # Open Collective handle +# ko_fi: # Ko-fi username +# tidelift: # Tidelift package name (e.g. npm/package-name) +# custom: # Array of custom sponsorship URLs diff --git a/.github/SECURITY.md b/.github/SECURITY.md new file mode 100644 index 0000000..5a53c37 --- /dev/null +++ b/.github/SECURITY.md @@ -0,0 +1,107 @@ +# Security Policy + +## Supported versions + +By default, PowerShellOrg supports the **latest minor release of the latest major version** of each module. Individual repositories may define a broader support window in their own `SECURITY.md`; where they do, the repo-level policy takes precedence over this document. + +| Version policy | Receives security fixes? | +|---|---| +| Latest release | Yes | +| Previous minor (same major) | Best-effort; patch may not be backported | +| Older majors | No | + +If you are unsure whether a version is covered, open a discussion or check the repo's own `SECURITY.md`. + +--- + +## Reporting a vulnerability + +**Please do not report security vulnerabilities in public GitHub issues.** + +### Preferred method: GitHub Private Vulnerability Reporting + +Use GitHub's built-in [Private Vulnerability Reporting](https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing/privately-reporting-a-security-vulnerability) on the affected repository: + +1. Navigate to the repository on GitHub. +2. Click **Security** → **Advisories** → **Report a vulnerability**. +3. Fill in the form with as much detail as you can provide. + +This creates an encrypted draft security advisory visible only to maintainers and the Steward. + +### Fallback method: email + +If GitHub Private Vulnerability Reporting is unavailable or you prefer email: + +**`security@powershellorg.example`** — `` + +Encrypt your report with our PGP key if possible: `` + +### What to include + +A useful report includes: + +- A description of the vulnerability and the potential impact +- The affected module name(s) and version(s) +- Steps to reproduce or a proof-of-concept +- Any known mitigations or workarounds +- Your preferred contact method for follow-up + +--- + +## Our commitments + +Once we receive your report: + +| Milestone | Target | +|---|---| +| Acknowledge receipt | 72 hours | +| Provide a status update | 7 days | +| Deliver fix or mitigation for **critical** severity | 14 days | +| Deliver fix or mitigation for **high** severity | 30 days | +| Deliver fix or mitigation for **medium/low** severity | 90 days | + +These are targets, not guarantees. If we need more time, we will tell you why. + +--- + +## Coordinated disclosure + +We follow a coordinated disclosure model: + +1. Reporter submits the vulnerability privately. +2. Maintainers validate and develop a fix. +3. We agree on an embargo period (typically 14–90 days depending on severity and fix complexity). +4. A patched release is published. +5. A GitHub Security Advisory is published, credited to the reporter unless they prefer to remain anonymous. +6. For serious vulnerabilities we will request a CVE from a CNA; this typically happens at or before public disclosure. + +We ask that reporters: + +- Allow us the agreed embargo window before public disclosure +- Avoid exploiting the vulnerability beyond what is needed to demonstrate it +- Avoid accessing or modifying data belonging to others + +In return, we commit to: + +- Keeping you informed throughout the process +- Crediting you in the advisory and release notes (unless you prefer anonymity) +- Acting in good faith to resolve the issue promptly + +--- + +## Out of scope + +The following are generally not in scope for security reports: + +- Vulnerabilities in PowerShell itself, the .NET runtime, or Windows — report those to Microsoft +- Issues that require the attacker to already have administrative or write access to the affected system +- Denial-of-service attacks that require significant resources from the attacker +- Social engineering of maintainers or contributors + +If you are unsure whether your finding is in scope, report it anyway — we would rather review a borderline finding than miss a real one. + +--- + +## Questions + +General security questions (not vulnerability reports) can be asked in GitHub Discussions on the relevant repository. diff --git a/.github/SUPPORT.md b/.github/SUPPORT.md new file mode 100644 index 0000000..401d807 --- /dev/null +++ b/.github/SUPPORT.md @@ -0,0 +1,40 @@ +# Getting Support + +## Where to ask questions + +**Use GitHub Discussions** for questions, how-to help, and general conversation about a project. Discussions are indexed by search engines, so your question and its answer may help future users. + +To ask a question: + +1. Navigate to the repository for the specific module you need help with. +2. Click **Discussions** → **New discussion** → choose the **Q&A** category. +3. Search existing discussions first — your question may already be answered. + +## Where to report bugs + +**Use GitHub Issues** for bugs: behavior that is clearly wrong, crashes, regressions, or documentation errors. + +Before opening a bug: + +- Check the existing issues (open and closed) for duplicates. +- Confirm you are using the latest release. +- Use the **Bug Report** issue template and fill it in completely. + +Incomplete bug reports (missing version, no reproduction steps) will be asked to provide more information before investigation begins. + +## Where NOT to ask + +- **Do not** open a GitHub Issue to ask a how-to question. Issues are for tracked work, not support conversations. How-to issues will be redirected to Discussions. +- **Do not** email maintainers directly for support. Maintainers are volunteers; email bypasses the community who might also be able to help. + +## Security vulnerabilities + +Do **not** report security vulnerabilities in public issues or discussions. See [SECURITY.md](SECURITY.md) for the responsible disclosure process. + +## Response times + +Response times depend on the repository's lifecycle state. See [CONTRIBUTING.md](CONTRIBUTING.md) for current SLAs. PowerShellOrg projects are maintained by volunteers; we appreciate your patience. + +## Contributing a fix + +If you have found a bug and want to fix it yourself, that is always welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) to get started. From f2f8d920ca831deda73a21ed4124a16cda47354a Mon Sep 17 00:00:00 2001 From: Gilbert Sanchez Date: Tue, 21 Apr 2026 14:38:26 -0700 Subject: [PATCH 3/6] feat: add issue templates, discussion templates, and PR template Issue templates (YAML forms): - bug_report.yml: PS version + OS dropdowns, module version, repro, logs - feature_request.yml: problem/solution/alternatives, contribution dropdown - question.yml: short form redirecting to Discussions - tool_adoption_request.yml: full adoption front-door form - config.yml: blank issues disabled, contact links to Discussions and SECURITY.md Discussion templates: announcements, general, ideas PULL_REQUEST_TEMPLATE.md: type checkboxes + psake-based checklist --- .github/DISCUSSION_TEMPLATE/announcements.yml | 18 +++ .github/DISCUSSION_TEMPLATE/general.yml | 16 +++ .github/DISCUSSION_TEMPLATE/ideas.yml | 26 ++++ .github/ISSUE_TEMPLATE/bug_report.yml | 91 ++++++++++++ .github/ISSUE_TEMPLATE/config.yml | 14 ++ .github/ISSUE_TEMPLATE/feature_request.yml | 59 ++++++++ .github/ISSUE_TEMPLATE/question.yml | 41 ++++++ .../ISSUE_TEMPLATE/tool_adoption_request.yml | 136 ++++++++++++++++++ .github/PULL_REQUEST_TEMPLATE.md | 28 ++++ 9 files changed, 429 insertions(+) create mode 100644 .github/DISCUSSION_TEMPLATE/announcements.yml create mode 100644 .github/DISCUSSION_TEMPLATE/general.yml create mode 100644 .github/DISCUSSION_TEMPLATE/ideas.yml create mode 100644 .github/ISSUE_TEMPLATE/bug_report.yml create mode 100644 .github/ISSUE_TEMPLATE/config.yml create mode 100644 .github/ISSUE_TEMPLATE/feature_request.yml create mode 100644 .github/ISSUE_TEMPLATE/question.yml create mode 100644 .github/ISSUE_TEMPLATE/tool_adoption_request.yml create mode 100644 .github/PULL_REQUEST_TEMPLATE.md diff --git a/.github/DISCUSSION_TEMPLATE/announcements.yml b/.github/DISCUSSION_TEMPLATE/announcements.yml new file mode 100644 index 0000000..6999536 --- /dev/null +++ b/.github/DISCUSSION_TEMPLATE/announcements.yml @@ -0,0 +1,18 @@ +title: "[Announcement]: " +labels: + - announcement +body: + - type: markdown + attributes: + value: | + Use this template for official announcements: new releases, adoption news, governance changes, maintainer changes, or other org-wide updates. + + Only maintainers and the Steward should post in this category. Community members can react and reply. + + - type: textarea + id: announcement + attributes: + label: Announcement + description: The full announcement text. Include links to relevant issues, PRs, or releases. + validations: + required: true diff --git a/.github/DISCUSSION_TEMPLATE/general.yml b/.github/DISCUSSION_TEMPLATE/general.yml new file mode 100644 index 0000000..a179fdb --- /dev/null +++ b/.github/DISCUSSION_TEMPLATE/general.yml @@ -0,0 +1,16 @@ +title: "" +labels: [] +body: + - type: markdown + attributes: + value: | + This is the place for general conversation about PowerShellOrg and its projects. + + For bug reports, use [Issues](../../issues/new/choose). For feature requests, use [Issues](../../issues/new/choose). For how-to questions, use the [Q&A category](../../discussions/new?category=q-a). + + - type: textarea + id: discussion + attributes: + label: What's on your mind? + validations: + required: true diff --git a/.github/DISCUSSION_TEMPLATE/ideas.yml b/.github/DISCUSSION_TEMPLATE/ideas.yml new file mode 100644 index 0000000..6230618 --- /dev/null +++ b/.github/DISCUSSION_TEMPLATE/ideas.yml @@ -0,0 +1,26 @@ +title: "[Idea]: " +labels: + - idea +body: + - type: markdown + attributes: + value: | + Share an idea that is not yet ready for a formal feature request. This is a good place to get early feedback, gauge interest, and shape a proposal before opening an Issue. + + If an idea gets strong support here, a maintainer may ask you to convert it into a Feature Request issue. + + - type: textarea + id: idea + attributes: + label: The idea + description: Describe the idea and the problem it solves. + validations: + required: true + + - type: textarea + id: context + attributes: + label: Why now / why this? + description: What prompted this idea? Is there a specific workflow or gap it addresses? + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000..f699ef6 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,91 @@ +name: Bug Report +description: Report incorrect or unexpected behavior in a PowerShellOrg module. +title: "[Bug]: " +labels: + - bug + - needs-triage +body: + - type: markdown + attributes: + value: | + Thank you for taking the time to report a bug. Please fill in as much detail as you can — complete reports get triaged and fixed faster. + + Before submitting, please [search existing issues](../../issues?q=is%3Aissue+label%3Abug) to avoid duplicates. + + - type: dropdown + id: ps-version + attributes: + label: PowerShell Version + description: Which PowerShell version(s) does this affect? + options: + - "5.1 (Windows PowerShell)" + - "7.x (PowerShell Core)" + - "Both 5.1 and 7.x" + validations: + required: true + + - type: dropdown + id: os + attributes: + label: Operating System + description: Which operating system(s) does this affect? + options: + - Windows + - Linux + - macOS + - All platforms + validations: + required: true + + - type: input + id: module-version + attributes: + label: Module Version + description: Output of `(Get-Module ModuleName).Version` or the version listed in `Import-Module -Verbose`. + placeholder: "e.g., 2.1.3" + validations: + required: true + + - type: textarea + id: what-happened + attributes: + label: What happened? + description: A clear and concise description of what the bug is. Include any error messages exactly as they appeared. + validations: + required: true + + - type: textarea + id: expected + attributes: + label: Expected behavior + description: What did you expect to happen instead? + validations: + required: true + + - type: textarea + id: repro + attributes: + label: Minimal reproduction + description: | + The smallest possible script that demonstrates the problem. Remove everything not needed to trigger the bug. + Tip: wrap sensitive values in variables — do not paste real credentials or tokens. + render: powershell + validations: + required: true + + - type: textarea + id: logs + attributes: + label: Error output / logs + description: Paste any relevant error output, stack traces, or verbose logs here. This will be automatically formatted as code. + render: text + validations: + required: false + + - type: textarea + id: additional-context + attributes: + label: Additional context + description: Anything else that might help — related issues, workarounds you have tried, recent changes to your environment. + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..633d165 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,14 @@ +blank_issues_enabled: false + +contact_links: + - name: Ask a question (GitHub Discussions) + url: https://github.com/PowerShellOrg/.github/discussions/new?category=q-a + about: Use Discussions for how-to questions. Issues are for bugs and feature requests only. + + - name: Support guide + url: https://github.com/PowerShellOrg/.github/blob/main/.github/SUPPORT.md + about: Not sure where to go? Read our support guide first. + + - name: Security vulnerability + url: https://github.com/PowerShellOrg/.github/blob/main/.github/SECURITY.md + about: Report a security issue privately — do NOT open a public issue. diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000..8e1f894 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,59 @@ +name: Feature Request +description: Suggest a new feature or improvement for a PowerShellOrg module. +title: "[Feature]: " +labels: + - enhancement + - needs-triage +body: + - type: markdown + attributes: + value: | + Thanks for taking the time to suggest an improvement. Before submitting, please [search existing issues and discussions](../../issues?q=is%3Aissue+label%3Aenhancement) to see if this has already been proposed. + + For large or breaking changes, consider opening a Discussion first to get early feedback before investing time in a detailed proposal. + + - type: textarea + id: problem + attributes: + label: Problem statement + description: | + What problem are you trying to solve? Describe the situation without assuming any particular solution. + Example: "When I have 50 dependency entries, I have no way to see which ones failed without parsing the verbose output manually." + validations: + required: true + + - type: textarea + id: solution + attributes: + label: Proposed solution + description: Describe the feature or change you would like to see. Include proposed parameter names, output format, behavior, or API changes if applicable. + validations: + required: true + + - type: textarea + id: alternatives + attributes: + label: Alternatives considered + description: What other approaches or workarounds have you tried or considered? Why do they fall short? + validations: + required: false + + - type: dropdown + id: contribution + attributes: + label: Willing to contribute? + description: Would you be willing to open a pull request implementing this feature? + options: + - "Yes — I plan to open a PR" + - "Maybe — I could, with guidance" + - "No — I am requesting someone else implement this" + validations: + required: true + + - type: textarea + id: additional-context + attributes: + label: Additional context + description: Links to related issues, prior art in other tools, screenshots, or anything else that helps illustrate the request. + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/question.yml b/.github/ISSUE_TEMPLATE/question.yml new file mode 100644 index 0000000..68d34bf --- /dev/null +++ b/.github/ISSUE_TEMPLATE/question.yml @@ -0,0 +1,41 @@ +name: Question +description: Ask a question about using a PowerShellOrg module. +title: "[Question]: " +labels: + - question +body: + - type: markdown + attributes: + value: | + ## Before you open an issue + + **Questions are better asked in [GitHub Discussions](../../discussions/new?category=q-a).** Discussions are searchable, so your question and its answer can help future users. Issues are reserved for tracked bugs and feature requests. + + If you have already checked Discussions and still need help, you are in the right place. + + - type: textarea + id: question + attributes: + label: Your question + description: What are you trying to do, and what have you tried so far? + validations: + required: true + + - type: input + id: module-version + attributes: + label: Module Version + placeholder: "e.g., 2.1.3" + validations: + required: false + + - type: dropdown + id: ps-version + attributes: + label: PowerShell Version + options: + - "5.1 (Windows PowerShell)" + - "7.x (PowerShell Core)" + - "Not applicable" + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/tool_adoption_request.yml b/.github/ISSUE_TEMPLATE/tool_adoption_request.yml new file mode 100644 index 0000000..e2b7227 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/tool_adoption_request.yml @@ -0,0 +1,136 @@ +name: Tool Adoption Request +description: Request that PowerShellOrg adopt and maintain an existing PowerShell tool. +title: "[Adoption]: " +labels: + - adoption-request + - needs-triage +body: + - type: markdown + attributes: + value: | + ## Requesting adoption of a PowerShell tool + + Thank you for your interest in bringing a tool under the PowerShellOrg umbrella. Please read [our adoption criteria](https://github.com/PowerShellOrg/.github/blob/main/docs/adoption-criteria.md) before submitting. + + Adoption requests are reviewed by the Council. We aim to respond within **7 days** and make a decision within **30 days**. The process is documented in [GOVERNANCE.md](https://github.com/PowerShellOrg/.github/blob/main/.github/GOVERNANCE.md). + + - type: input + id: tool-name + attributes: + label: Tool / Module Name + placeholder: "e.g., PSDepend" + validations: + required: true + + - type: input + id: repo-url + attributes: + label: Source Repository URL + placeholder: "https://github.com/owner/repo" + validations: + required: true + + - type: input + id: gallery-url + attributes: + label: PowerShell Gallery URL + description: Leave blank if not published to PSGallery. + placeholder: "https://www.powershellgallery.com/packages/ModuleName" + validations: + required: false + + - type: dropdown + id: license + attributes: + label: Current License + description: What license does the tool currently use? + options: + - MIT + - Apache 2.0 + - BSD 2-Clause + - BSD 3-Clause + - GPL v2 + - GPL v3 + - LGPL + - Other OSI-approved license + - No license / unlicensed + - Unknown + validations: + required: true + + - type: dropdown + id: submitter-relationship + attributes: + label: Your relationship to this tool + options: + - "I am the original author" + - "I am a current maintainer (not original author)" + - "I am a contributor (not current maintainer)" + - "I am a user with no prior contribution" + validations: + required: true + + - type: textarea + id: description + attributes: + label: What does this tool do? + description: A brief description of the tool's purpose and who it is for. + validations: + required: true + + - type: textarea + id: current-state + attributes: + label: Current state of the project + description: | + Please fill in what you know: + - Last commit date and last release date + - Number of open issues / open PRs + - Any known bugs or security issues + - Approximate test coverage and CI status + - Whether the original author is reachable and aware of this request + validations: + required: true + + - type: textarea + id: evidence-of-use + attributes: + label: Evidence of real-world use + description: | + Why should PowerShellOrg maintain this? Examples: PSGallery download counts, GitHub stars/forks, companies or projects that depend on it, forum posts or Stack Overflow questions, prominent users. + validations: + required: true + + - type: dropdown + id: original-author-status + attributes: + label: Original author status + description: Do you know whether the original author is aware of and supportive of this adoption request? + options: + - "Yes — author has been contacted and is supportive" + - "Yes — author has been contacted and has no objection" + - "Author is unresponsive / unreachable (please describe in additional notes)" + - "Author is unknown" + - "I am the original author" + validations: + required: true + + - type: dropdown + id: post-adoption-commitment + attributes: + label: Post-adoption maintainer commitment + description: If PowerShellOrg adopts this tool, are you willing to serve as a maintainer? + options: + - "Yes — I commit to at least 6 months of active maintenance" + - "Maybe — I can help but cannot commit to full maintainer responsibilities" + - "No — I am requesting adoption only and cannot maintain it" + validations: + required: true + + - type: textarea + id: additional-notes + attributes: + label: Additional notes + description: Anything else the Council should know — history of the project, why it went unmaintained, alternative tools considered, potential concerns. + validations: + required: false diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..5069e3a --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,28 @@ +## What this changes + + + +## Why + + + +Closes # + +## Type of change + +- [ ] Bug fix (non-breaking change that corrects incorrect behavior) +- [ ] New feature (non-breaking change that adds functionality) +- [ ] Breaking change (fix or feature that changes existing behavior) +- [ ] Chore / refactor / documentation (no behavior change) + +## Checklist + +- [ ] Pester tests added or updated to cover the change +- [ ] `Invoke-psake Analyze` passes locally with no new warnings +- [ ] `Invoke-psake Test` passes locally on at least one platform +- [ ] `CHANGELOG.md` updated (required for any user-facing change) +- [ ] Documentation updated if behavior changed + +## Additional notes + + From 07f55f668dc6add5554f46ad276e17ca23894179 Mon Sep 17 00:00:00 2001 From: Gilbert Sanchez Date: Tue, 21 Apr 2026 14:39:08 -0700 Subject: [PATCH 4/6] feat: add reusable CI and release workflows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit powershell-ci.yml: - Matrix: windows/ubuntu/macos x PS5.1(Win only)/PS7.x - NuGet bootstrap step for PS 5.1 - Fixed psake tasks: Init → Test → Analyze - Uploads test result artifacts per matrix leg powershell-release.yml: - Inputs: module-name (required), create-github-release (default true) - Secret: PSGALLERY_API_KEY (required, scoped per-repo) - Full CI gate (Init → Test → Analyze) before Build → Publish - Creates GitHub Release with auto-generated notes via gh CLI --- .github/workflows/powershell-ci.yml | 92 ++++++++++++++++++++ .github/workflows/powershell-release.yml | 106 +++++++++++++++++++++++ 2 files changed, 198 insertions(+) create mode 100644 .github/workflows/powershell-ci.yml create mode 100644 .github/workflows/powershell-release.yml diff --git a/.github/workflows/powershell-ci.yml b/.github/workflows/powershell-ci.yml new file mode 100644 index 0000000..f3ef0af --- /dev/null +++ b/.github/workflows/powershell-ci.yml @@ -0,0 +1,92 @@ +name: PowerShell CI + +# Reusable workflow. Call from a consuming repo: +# +# jobs: +# ci: +# uses: PowerShellOrg/.github/.github/workflows/powershell-ci.yml@main +# +# Task names are fixed convention across all PowerShellOrg repos: +# Init, Clean, Build, Test, Analyze, Publish +# See the org wiki for psake task naming requirements. + +on: + workflow_call: {} + +jobs: + ci: + name: PS ${{ matrix.ps-version }} / ${{ matrix.os }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + # Windows PowerShell 5.1 — only available on Windows runners + - os: windows-latest + ps-version: "5.1" + shell: powershell + + # PowerShell 7.x — all three platforms + - os: windows-latest + ps-version: "7.x" + shell: pwsh + + - os: ubuntu-latest + ps-version: "7.x" + shell: pwsh + + - os: macos-latest + ps-version: "7.x" + shell: pwsh + + steps: + - name: Checkout + uses: actions/checkout@v4 + + # PS 5.1 needs TLS 1.2 forced and the NuGet provider bootstrapped before + # PowerShellGet will talk to PSGallery reliably. + - name: Bootstrap NuGet provider (PS 5.1 only) + if: matrix.ps-version == '5.1' + shell: powershell + run: | + [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 + Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force -Scope CurrentUser + Set-PSRepository -Name PSGallery -InstallationPolicy Trusted + + - name: Install build dependencies + shell: ${{ matrix.shell }} + run: | + $ErrorActionPreference = 'Stop' + $installParams = @{ + Scope = 'CurrentUser' + Force = $true + SkipPublisherCheck = $true + } + Install-Module -Name psake @installParams + Install-Module -Name PowerShellBuild @installParams + Install-Module -Name PSScriptAnalyzer @installParams + Install-Module -Name Pester @installParams -MinimumVersion '5.0' -MaximumVersion '5.99' + + - name: Run psake Init + shell: ${{ matrix.shell }} + run: Invoke-psake Init + continue-on-error: false + + - name: Run tests + shell: ${{ matrix.shell }} + run: Invoke-psake Test + + - name: Run static analysis + shell: ${{ matrix.shell }} + run: Invoke-psake Analyze + + - name: Upload test results + uses: actions/upload-artifact@v4 + if: always() + with: + name: test-results-${{ matrix.os }}-ps${{ matrix.ps-version }} + path: | + **/testResults.xml + **/TestResults.xml + output/testResults*.xml + if-no-files-found: warn diff --git a/.github/workflows/powershell-release.yml b/.github/workflows/powershell-release.yml new file mode 100644 index 0000000..43cf32f --- /dev/null +++ b/.github/workflows/powershell-release.yml @@ -0,0 +1,106 @@ +name: PowerShell Release + +# Reusable workflow. Call from a tag-triggered workflow in a consuming repo: +# +# on: +# push: +# tags: ['v*'] +# +# jobs: +# release: +# uses: PowerShellOrg/.github/.github/workflows/powershell-release.yml@main +# with: +# module-name: MyModule +# secrets: +# PSGALLERY_API_KEY: ${{ secrets.PSGALLERY_API_KEY }} +# +# The PSGALLERY_API_KEY secret must be set in the consuming repository. +# See docs/maintainer-onboarding.md for the key naming and issuance process. +# +# Task names are fixed convention: Init, Build, Test, Analyze, Publish +# The Publish task must read $env:PSGALLERY_API_KEY. + +on: + workflow_call: + inputs: + module-name: + description: "Module name as it appears on PSGallery (e.g. PSDepend)" + required: true + type: string + create-github-release: + description: "Create a GitHub Release with auto-generated notes after publish" + required: false + type: boolean + default: true + secrets: + PSGALLERY_API_KEY: + description: "Scoped PSGallery API key for this module. See docs/maintainer-onboarding.md." + required: true + +jobs: + release: + name: Release ${{ inputs.module-name }} + runs-on: windows-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Install build dependencies + shell: pwsh + run: | + $ErrorActionPreference = 'Stop' + $installParams = @{ + Scope = 'CurrentUser' + Force = $true + SkipPublisherCheck = $true + } + Install-Module -Name psake @installParams + Install-Module -Name PowerShellBuild @installParams + Install-Module -Name PSScriptAnalyzer @installParams + Install-Module -Name Pester @installParams -MinimumVersion '5.0' -MaximumVersion '5.99' + + - name: Init + shell: pwsh + run: Invoke-psake Init + + - name: Test + shell: pwsh + run: Invoke-psake Test + + - name: Analyze + shell: pwsh + run: Invoke-psake Analyze + + - name: Upload test results + uses: actions/upload-artifact@v4 + if: always() + with: + name: release-test-results + path: | + **/testResults.xml + **/TestResults.xml + output/testResults*.xml + if-no-files-found: warn + + - name: Build + shell: pwsh + run: Invoke-psake Build + + - name: Publish to PSGallery + shell: pwsh + env: + PSGALLERY_API_KEY: ${{ secrets.PSGALLERY_API_KEY }} + run: Invoke-psake Publish + + - name: Create GitHub Release + if: ${{ inputs.create-github-release }} + env: + GH_TOKEN: ${{ github.token }} + run: | + gh release create "${{ github.ref_name }}" ` + --title "${{ inputs.module-name }} ${{ github.ref_name }}" ` + --generate-notes ` + --verify-tag From cd03103ffa9dc0b5ec4d550409292082eeea84ed Mon Sep 17 00:00:00 2001 From: Gilbert Sanchez Date: Tue, 21 Apr 2026 14:45:45 -0700 Subject: [PATCH 5/6] feat: add org profile landing page profile/README.md: tool roster (Plaster, PSDepend) with status badges, adopt-your-tool CTA linking to the adoption request template, help-wanted CTA linking to good-first-issues and help-wanted across the org, links to governance and CoC. --- profile/README.md | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 profile/README.md diff --git a/profile/README.md b/profile/README.md new file mode 100644 index 0000000..dbb5532 --- /dev/null +++ b/profile/README.md @@ -0,0 +1,32 @@ +# PowerShellOrg + +PowerShellOrg is a community-run GitHub organization that adopts and maintains open-source PowerShell tools that would otherwise go unmaintained. + +## Maintained tools + +| Module | Description | Status | +|---|---|---| +| [Plaster](https://github.com/PowerShellOrg/Plaster) | Template-based scaffolding engine for PowerShell projects and modules | ![Active](https://img.shields.io/badge/status-active-brightgreen) | +| [PSDepend](https://github.com/PowerShellOrg/PSDepend) | Dependency management for PowerShell scripts and modules | ![Active](https://img.shields.io/badge/status-active-brightgreen) | + +## Want us to adopt your tool? + +If you maintain (or used to maintain) a PowerShell tool that needs a new home, we want to hear from you. + +Read the [adoption criteria](https://github.com/PowerShellOrg/.github/blob/main/docs/adoption-criteria.md) first, then open an **[Adoption Request](https://github.com/PowerShellOrg/.github/issues/new?template=tool_adoption_request.yml)**. + +We respond to all requests within 7 days and make a decision within 30. + +## Want to help? + +Every project in this org accepts contributions. A good place to start: + +- **[Good first issues across the org](https://github.com/issues?q=is%3Aopen+is%3Aissue+org%3APowerShellOrg+label%3A%22good+first+issue%22)** — smaller, well-scoped tasks +- **[Help wanted across the org](https://github.com/issues?q=is%3Aopen+is%3Aissue+org%3APowerShellOrg+label%3A%22help+wanted%22)** — tasks where we've explicitly asked for a PR + +See [CONTRIBUTING.md](https://github.com/PowerShellOrg/.github/blob/main/.github/CONTRIBUTING.md) for how we work. + +## Governance and community + +- [Governance model](https://github.com/PowerShellOrg/.github/blob/main/.github/GOVERNANCE.md) — how decisions get made, roles, maintainer lifecycle +- [Code of Conduct](https://github.com/PowerShellOrg/.github/blob/main/.github/CODE_OF_CONDUCT.md) — how we treat each other From de5ceec81ee303179dd657609419bc28878256b2 Mon Sep 17 00:00:00 2001 From: Gilbert Sanchez Date: Tue, 21 Apr 2026 14:41:55 -0700 Subject: [PATCH 6/6] docs: add maintainer onboarding, revival playbook, and adoption criteria MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit maintainer-onboarding.md: day-1 access checklist, branch protection verification, PSGallery key issuance process (naming convention PowerShellOrg--), CI bootstrap, communication norms. revival-playbook.md: five-phase checklist — Phase 0 (inventory/transfer), Phase 1 (issue triage with comment templates), Phase 2 (PR triage with decision tree), Phase 3 (build modernization a–g), Phase 4 (first release gate), Phase 5 (ongoing cadence and graduation path). adoption-criteria.md: six must-be-true criteria, six org commitments, four submitter commitments, workflow with 7d ack / 30d decision. --- docs/adoption-criteria.md | 116 ++++++++++++++ docs/maintainer-onboarding.md | 137 +++++++++++++++++ docs/revival-playbook.md | 279 ++++++++++++++++++++++++++++++++++ 3 files changed, 532 insertions(+) create mode 100644 docs/adoption-criteria.md create mode 100644 docs/maintainer-onboarding.md create mode 100644 docs/revival-playbook.md diff --git a/docs/adoption-criteria.md b/docs/adoption-criteria.md new file mode 100644 index 0000000..a75ae81 --- /dev/null +++ b/docs/adoption-criteria.md @@ -0,0 +1,116 @@ +# Adoption Criteria + +This document describes how PowerShellOrg evaluates tools for adoption, what we commit to when we adopt something, and what the submitter commits to. + +Read this before submitting a [Tool Adoption Request](https://github.com/PowerShellOrg/.github/issues/new?template=tool_adoption_request.yml). + +--- + +## Must-be-true criteria + +All six of the following must be true before we will adopt a tool. These are not negotiable. + +### 1. Open-source license + +The tool must have an OSI-approved open-source license in place before or at the time of transfer. We strongly prefer MIT or Apache 2.0, which are compatible with the rest of the org's tooling and license stack. + +Tools with no license, or with proprietary or source-available licenses, are ineligible. If the original author is willing to relicense to MIT, that resolves the issue — we can help coordinate. + +### 2. Author consent or demonstrated abandonment + +We do not take over maintained projects without permission. + +- **If the original author is reachable and active:** We require explicit written consent (a GitHub comment, email, or issue) from the author or all current maintainers. This protects them and protects us. +- **If the project appears abandoned:** We require documented evidence that we made a reasonable good-faith effort to reach the author (GitHub @-mention, issue opened, email to the address in the git log or package metadata) and received no response after at least 30 days. + +When in doubt, we wait. Burning bridges with the original author is not worth any single tool. + +### 3. Real user base + +The tool must have evidence of real-world use: PSGallery downloads, GitHub stars/forks, dependent projects, forum mentions, or other signals that someone besides the submitter relies on it. + +We will not adopt a tool that has no users outside its author, because there would be no one to maintain it for. + +### 4. Manageable scope + +The tool's maintenance burden must be sustainable given the org's current maintainer pool. We consider: + +- Lines of code and architectural complexity +- Test coverage and CI state (a tool with no tests requires significant upfront investment) +- Open issue and PR backlog +- Dependency footprint + +We will not adopt a tool if doing so would overextend our maintainers. We would rather maintain a smaller number of tools well than a large number poorly. + +### 5. No unaddressed security issues + +We will not inherit a tool with known, unaddressed security vulnerabilities. Before adoption, the submitter must either: + +- Confirm there are no known security issues, or +- Document all known issues and commit to addressing them in the first release cycle + +This is not about perfection — it is about not knowingly shipping something unsafe to our users. + +### 6. No legal encumbrance + +The tool must not carry legal risks that would expose PowerShellOrg or its maintainers. Examples of disqualifying encumbrances: + +- Copyright claims from a third party +- Code copied from a non-compatible license without attribution +- Trademark issues +- Export control restrictions + +--- + +## What PowerShellOrg commits to + +When we adopt a tool, we commit to: + +1. **Maintaining it actively** — responding to issues within our SLA, reviewing PRs, and cutting releases when there are meaningful changes +2. **Not abandoning it silently** — if we decide we cannot maintain a tool, we will announce it publicly and give the community 90 days to find alternative stewardship before archiving +3. **Keeping it open source** — the tool will remain under its existing OSI license (or a compatible one with explicit permission) +4. **Not breaking the API or CLI interface without a major version bump** — we respect existing users' scripts and pipelines +5. **Giving credit** — the original author's contributions remain in git history and are acknowledged in the CHANGELOG and package metadata +6. **Handling security responsibly** — following our published security policy for vulnerability disclosure and response + +--- + +## What the submitter commits to + +Adoption requests that do not include a maintainer commitment are evaluated more skeptically. A tool with no one willing to maintain it is a higher-risk adoption. + +If you are submitting a request and are willing to maintain the tool: + +1. **Minimum 6 months of active maintenance** — you will triage issues, review PRs, and be reachable for at least 6 months after adoption +2. **On-boarding and knowledge transfer** — you will work with the PowerShellOrg maintainer team to document the tool's internals, known issues, and quirks before stepping back +3. **Good-faith participation** — you will engage with the community, respond to review comments, and follow PowerShellOrg's contribution norms +4. **Transparency about limitations** — if you know the tool has problems, you will document them upfront rather than letting us discover them post-adoption + +We understand life happens. If you need to step back before the 6 months are up, tell us early — we will work with you. + +--- + +## The adoption workflow + +| Step | Owner | Timeline | +|---|---|---| +| Submitter files a Tool Adoption Request | Submitter | — | +| Steward acknowledges the request and assigns it to the Council | Steward | 7 days | +| Council members review and comment | Council | 30 days | +| Steward makes a decision (adopt / decline / defer) | Steward | 30 days from submission | +| If adopted: repo transfer initiated, onboarding begins | Steward + submitter | Week of decision | +| Repo moves to `status-incoming`, Revival Playbook begins | Lead maintainer | Immediately after transfer | + +### What "declined" means + +A declined adoption request is not a judgment on the tool's quality or the submitter's intentions. Common reasons for declining: + +- The tool does not meet one of the must-be-true criteria +- Our current maintainer pool cannot take it on right now +- A better maintainer or org has already stepped up + +We will always explain the reason. Declined requests may be resubmitted when circumstances change. + +### What "deferred" means + +A deferred request means we are interested but there is a blocker we need to resolve first — usually the license, the author consent, or maintainer capacity. We will set a follow-up date and reopen the discussion then. diff --git a/docs/maintainer-onboarding.md b/docs/maintainer-onboarding.md new file mode 100644 index 0000000..4cb3d8c --- /dev/null +++ b/docs/maintainer-onboarding.md @@ -0,0 +1,137 @@ +# Maintainer Onboarding + +Welcome to PowerShellOrg. This checklist walks you through everything you need to be fully operational on day one and productive in the first week. + +--- + +## Day 1: Access and accounts + +### GitHub org access + +- [ ] Accept the org invite from the Steward (check your GitHub notifications and email) +- [ ] Verify you have **Write** access to your assigned repo(s) — navigate to the repo → **Settings** → **Collaborators and teams** +- [ ] Enable **two-factor authentication** on your GitHub account if not already enabled — this is a hard requirement for org membership ([docs.github.com/en/authentication/securing-your-account-with-two-factor-authentication](https://docs.github.com/en/authentication/securing-your-account-with-two-factor-authentication)) + +### Council channel + +- [ ] Introduce yourself in the Council channel: `` +- [ ] Note your timezone and typical availability (helps set realistic review expectations) + +### PSGallery account + +- [ ] Confirm you have a [PowerShell Gallery](https://www.powershellgallery.com/) account +- [ ] Share your PSGallery username with the Steward — you will need it for the API key issuance step below + +--- + +## Day 1: Repo familiarization + +- [ ] Clone the repo locally +- [ ] Read the repo's `README.md` and any existing `CONTRIBUTING.md` +- [ ] Read `CHANGELOG.md` to understand recent history +- [ ] Read open issues and PRs — look for anything labeled `needs-triage` or with recent activity + +--- + +## Day 1: Branch protection verification + +Verify the repo's default branch has the following protections enabled. Navigate to the repo → **Settings** → **Branches** → branch protection rule for `main`. + +- [ ] **Require a pull request before merging** — enabled +- [ ] **Require approvals** — at least 1 required reviewer +- [ ] **Dismiss stale pull request approvals when new commits are pushed** — enabled +- [ ] **Require status checks to pass before merging** — enabled; the CI workflow must be listed +- [ ] **Require branches to be up to date before merging** — enabled +- [ ] **Require linear history** — enabled +- [ ] **Do not allow force pushes** — enabled +- [ ] **Do not allow deletions** — enabled + +If any of these are missing, notify the Steward before merging anything. + +--- + +## Day 1: PSGallery API key + +PowerShellOrg uses **per-repo scoped API keys** for PSGallery. You do not get an org-wide key. + +### Key issuance process (Steward action) + +The Steward creates the key with these parameters: + +| Parameter | Value | +|---|---| +| Key name | `PowerShellOrg--` (e.g., `PowerShellOrg-PSDepend-2025-11`) | +| Glob pattern | The module name exactly (e.g., `PSDepend`) | +| Expiration | 365 days (the PSGallery maximum) | + +The Steward then: +1. Creates or updates the `PSGALLERY_API_KEY` Actions secret in the repo +2. Adds a rotation reminder to the private key tracking issue (pinned to this repo) +3. Notifies the maintainer that the key is in place + +### Maintainer steps + +- [ ] Confirm with the Steward that `PSGALLERY_API_KEY` is set in the repo's Actions secrets (**Settings** → **Secrets and variables** → **Actions**) +- [ ] Note the key expiration month — the Steward will initiate rotation, but you may be asked to trigger it + +### Key rotation + +Keys expire after 365 days. The Steward tracks rotation in a private pinned issue. When rotation is due: +1. Steward creates a new key on PSGallery with the same glob, new `YYYY-MM` suffix in the name +2. Steward updates the `PSGALLERY_API_KEY` secret in the repo +3. Old key is deleted from PSGallery +4. Tracking issue is updated + +--- + +## Day 1: CI bootstrap + +- [ ] Install the standard build stack locally: + + ```powershell + Install-Module psake -Scope CurrentUser -Force + Install-Module PowerShellBuild -Scope CurrentUser -Force + Install-Module PSScriptAnalyzer -Scope CurrentUser -Force + Install-Module Pester -Scope CurrentUser -Force -MinimumVersion '5.0' -MaximumVersion '5.99' + ``` + +- [ ] Run `Invoke-psake ?` in the repo root — confirm the standard tasks are listed (Init, Clean, Build, Test, Analyze, Publish) +- [ ] Run `Invoke-psake Test` — confirm all tests pass +- [ ] Run `Invoke-psake Analyze` — confirm no PSScriptAnalyzer warnings +- [ ] Navigate to the repo's **Actions** tab and confirm the CI workflow is running and green on `main` + +If the CI workflow is not present or not green, see the [Revival Playbook](revival-playbook.md) Phase 3 for modernization steps. + +--- + +## First week: Communication norms + +### Issue and PR triage + +| Repo status | First-response target | +|---|---| +| `status-active` | 7 days | +| `status-stable` | 30 days | + +First response means: a label applied, a comment acknowledging the issue, or a review comment on the PR — not necessarily a resolution. + +Set up GitHub notifications for your repo: **Watch** → **All activity**, or at minimum **Issues** and **Pull requests**. + +### Code review + +- Aim to complete (not just start) reviews within 30 days of assignment +- Use GitHub's "Request changes" only when a change is genuinely blocking — a comment thread is sufficient for most feedback +- When merging, prefer **Squash and merge** for single-commit PRs and **Merge commit** for multi-commit work where history is meaningful. Avoid **Rebase and merge** unless the branch is perfectly clean — it rewrites history and removes the merge traceability. + +### Releases + +- Announce releases in the Council channel when they go out +- Tag the release commit with `vX.Y.Z` — this triggers the release workflow +- The GitHub Release notes are auto-generated; add a brief human summary at the top if the automated notes are too sparse + +### Escalation + +- Blocked by a technical question? Post in the Council channel — another maintainer may know the answer. +- Blocked by a process question? Ask the Steward. +- Seeing behavior that might violate the Code of Conduct? Report to `conduct@powershellorg.example` or message the Steward directly. +- Need to step down or take a break? Tell the Steward as early as possible — we would rather hand off gracefully than have a repo go dark unexpectedly. diff --git a/docs/revival-playbook.md b/docs/revival-playbook.md new file mode 100644 index 0000000..74a157f --- /dev/null +++ b/docs/revival-playbook.md @@ -0,0 +1,279 @@ +# Revival Playbook + +This playbook describes how to bring an adopted tool from freshly transferred (`status-incoming`) to actively maintained (`status-active`). It is organized into five phases with explicit checklists. + +The phases overlap. Do not wait for Phase 1 to be fully complete before starting Phase 2. The timelines are guidelines; pace to the actual state of the repo. + +--- + +## Phase 0: Take inventory (week 1) + +Everything in this phase happens before or immediately after the repo transfer. It is primarily Steward and lead maintainer work. + +### Transfer and access + +- [ ] Repo transferred to `github.com/PowerShellOrg` +- [ ] Repo topic `status-incoming` applied +- [ ] Lead maintainer(s) added to the repo with **Write** access +- [ ] Branch protection rules verified (see [maintainer-onboarding.md](maintainer-onboarding.md)) +- [ ] Default branch confirmed as `main` (rename from `master` if needed) + +### PSGallery setup + +- [ ] PSGallery package ownership transferred to the PowerShellOrg PSGallery account (or new package created if publishing fresh) +- [ ] Scoped API key created by Steward: `PowerShellOrg--`, glob = module name, 365-day expiry +- [ ] `PSGALLERY_API_KEY` Actions secret set in the repo +- [ ] Rotation reminder added to the Steward's private tracking issue + +### Baseline metrics (capture before making changes) + +- [ ] Last commit date recorded +- [ ] Last PSGallery release date and version recorded +- [ ] Open issue count recorded +- [ ] Open PR count recorded +- [ ] GitHub Stars / Forks recorded +- [ ] PSGallery download count recorded +- [ ] Existing CI status noted (passing / failing / none) + +These numbers are the baseline for the first release announcement and are useful for gauging improvement. + +--- + +## Phase 1: Issue triage (weeks 1–4) + +Goal: every open issue is labeled, acknowledged, and either closed or has a clear next step. + +### Label framework + +Apply the org standard label set if it is not already present. Minimum required labels: + +| Label | Purpose | +|---|---| +| `bug` | Confirmed incorrect behavior | +| `enhancement` | Feature request or improvement | +| `needs-triage` | Newly opened; not yet evaluated | +| `needs-info` | Waiting on reporter for more detail | +| `wontfix` | Valid but outside scope or priority | +| `duplicate` | Duplicate of another issue | +| `good first issue` | Suitable for a new contributor | +| `help wanted` | Maintainer welcomes a PR | +| `question` | How-to or usage question | +| `adoption-request` | Tool adoption request (org-level only) | + +### Triage process + +For each open issue: + +- [ ] Read the issue and reproduce if a bug report +- [ ] Apply a primary label (`bug`, `enhancement`, `question`, `wontfix`, etc.) +- [ ] Remove `needs-triage` once evaluated +- [ ] Post a comment if action is needed from the reporter + +#### Comment templates + +**Needs more info:** +``` +Thanks for the report. To help us investigate, could you provide: +- [ ] PowerShell version (`$PSVersionTable`) +- [ ] Module version (`(Get-Module ModuleName).Version`) +- [ ] Minimal reproduction script +- [ ] Full error output + +We'll hold this open for 30 days. If we don't hear back, we'll close it — feel free to reopen if you have the info later. +``` + +**Closing as won't fix:** +``` +Thank you for taking the time to file this. After review, we've decided not to implement this because [reason]. + +If you'd like to discuss further, please open a GitHub Discussion. We're happy to reconsider if the use case evolves. +``` + +**Closing stale issue (pre-adoption backlog):** +``` +This issue was open before PowerShellOrg adopted this module. We're doing a triage pass to start fresh. + +If this is still relevant and reproducible on the latest version, please reopen with a current repro. Thanks for your patience during the transition. +``` + +### Phase 1 exit criteria + +- [ ] All open issues have at least one label +- [ ] `needs-triage` label is empty +- [ ] Issues older than 2 years with no recent activity are closed with the stale comment above + +--- + +## Phase 2: PR triage (weeks 1–4, parallel with Phase 1) + +Goal: no PR sits without a decision. Move every open PR to one of: merged, closed, or actively under review. + +### Decision tree + +For each open PR: + +1. **Does it still apply cleanly?** If not, ask the author to rebase. If no response in 14 days, close with note. +2. **Is it in scope?** If not, close with explanation. +3. **Does it have tests?** If adding behavior without tests, request them. +4. **Can you merge it as-is?** Merge it. +5. **Can you merge it with minor changes?** Request changes or take over the branch. +6. **Is the author unresponsive?** Close with a note explaining they can reopen when available. + +#### Comment template — taking over a PR: +``` +Thanks for this contribution — the direction is right. Since [this PR has been open for X months / the author is unresponsive / the branch needs a rebase], I'm going to close this and open a new PR that incorporates your approach. + +Your contribution will be credited in the commit message and CHANGELOG. Thank you for the starting point. +``` + +#### Comment template — closing pre-adoption PR: +``` +This PR was open before PowerShellOrg adopted this module. As part of our triage, we're closing it to start fresh. + +If you'd still like to contribute this change, please open a new PR against the current `main`. See CONTRIBUTING.md for our current guidelines. Thank you for the work you put into this. +``` + +### Phase 2 exit criteria + +- [ ] No open PR is older than 30 days without a maintainer comment +- [ ] All mergeable PRs are merged or have a clear decision + +--- + +## Phase 3: Build modernization (weeks 2–6) + +Goal: the repo builds with the standard stack, CI is green on all platforms. + +Work through these in order. Each step is a standalone PR. + +### 3a: Pester migration + +- [ ] Confirm existing tests use Pester (or add tests if none exist) +- [ ] Upgrade to Pester 5 if on an older version — see the [Pester 5 migration guide](https://pester.dev/docs/migrations/v4-to-v5) +- [ ] All tests pass locally with `Invoke-Pester` + +### 3b: psake bootstrap + +- [ ] Add `psakeFile.ps1` to the repo root with the standard tasks: `Init`, `Clean`, `Build`, `Test`, `Analyze`, `Publish` +- [ ] `Invoke-psake ?` lists all tasks +- [ ] `Invoke-psake Test` runs Pester and passes + +### 3c: PowerShellBuild integration + +- [ ] `build.ps1` or the `psakeFile.ps1` references PowerShellBuild for shared task logic +- [ ] Module manifest is valid (`Test-ModuleManifest` passes) +- [ ] `Invoke-psake Build` produces a clean staged module in `output/` + +### 3d: PSScriptAnalyzer clean pass + +- [ ] `Invoke-psake Analyze` runs PSScriptAnalyzer with the org default ruleset +- [ ] All warnings resolved or suppressed with documented justification +- [ ] No `SuppressMessage` attributes without a comment explaining the suppression + +### 3e: GitHub Actions CI + +- [ ] `.github/workflows/ci.yml` added to the repo, calling the reusable workflow: + ```yaml + name: CI + on: + push: + branches: [main] + pull_request: + branches: [main] + jobs: + ci: + uses: PowerShellOrg/.github/.github/workflows/powershell-ci.yml@main + ``` +- [ ] CI is green on `main` across all four matrix legs (Win/PS5.1, Win/PS7, Linux/PS7, macOS/PS7) +- [ ] Branch protection status check updated to require this CI workflow + +### 3f: GitHub Actions release workflow + +- [ ] `.github/workflows/release.yml` added, calling the reusable workflow: + ```yaml + name: Release + on: + push: + tags: ['v*'] + jobs: + release: + uses: PowerShellOrg/.github/.github/workflows/powershell-release.yml@main + with: + module-name: + secrets: + PSGALLERY_API_KEY: ${{ secrets.PSGALLERY_API_KEY }} + ``` +- [ ] Test release with a pre-release tag (e.g., `v1.0.0-beta.1`) to confirm the workflow runs end-to-end + +### 3g: Test coverage baseline + +- [ ] Coverage report generated (Pester's `-CodeCoverage` parameter or a coverage tool) +- [ ] Baseline coverage percentage recorded in the tracking issue +- [ ] At least critical public functions have tests; gaps documented as issues + +### Phase 3 exit criteria + +- [ ] All standard psake tasks exist and pass +- [ ] CI is green on `main` +- [ ] PSScriptAnalyzer clean +- [ ] Release workflow tested + +--- + +## Phase 4: First clean release (weeks 4–8) + +Goal: cut a release under the PowerShellOrg banner that you are proud to put your name on. + +### Release gate checklist + +- [ ] `CHANGELOG.md` exists and documents what has changed since the last release (even if that is just "Transferred to PowerShellOrg, CI modernized") +- [ ] Module version bumped appropriately (patch if no user-facing changes, minor if new features, major if breaking) +- [ ] All tests passing on CI +- [ ] PSScriptAnalyzer clean +- [ ] Module manifest is accurate: description, author (or organization), copyright, tags, PSGallery URLs +- [ ] `README.md` updated: installation instructions current, usage examples work, badges updated +- [ ] Any open critical bugs addressed or explicitly deferred with a documented reason +- [ ] At least one other maintainer has reviewed the release PR (or Steward if solo) + +### Release steps + +1. Open a PR titled `chore: release vX.Y.Z` +2. Update `CHANGELOG.md` and bump the version in the module manifest +3. Get at least one review +4. Merge to `main` +5. Push the tag: `git tag vX.Y.Z && git push origin vX.Y.Z` +6. Confirm the release workflow succeeds: PSGallery package updated, GitHub Release created +7. Announce in the Council channel + +### Phase 4 exit criteria + +- [ ] At least one release published to PSGallery under PowerShellOrg +- [ ] GitHub Release exists with human-readable notes +- [ ] PSGallery package description updated to reflect PowerShellOrg stewardship + +--- + +## Phase 5: Ongoing maintenance and transition to active + +Once Phase 4 is done, the repo transitions from `status-incoming` to `status-active`. + +### Transition checklist + +- [ ] Repo topic updated from `status-incoming` to `status-active` +- [ ] `README.md` status badge updated +- [ ] Steward notified (they will update any org-level tracking) +- [ ] Announcement posted in Council channel + +### Ongoing cadence + +| Activity | Frequency | +|---|---| +| Issue triage | Weekly (or within 7 days of new issues) | +| PR review | Within 7 days of opening | +| Dependency review | Monthly (check for PSGallery module updates) | +| Release | As needed; no more than 3 months between releases if there are merged changes | +| PSGallery API key rotation | Annually (Steward-driven, maintainer confirms) | + +### Graduation to stable + +When the repo has been in `status-active` for at least 12 months, has had 2+ clean releases, has 2+ active maintainers, and has no critical open issues, propose graduation to `status-stable` in the Council channel. See [GOVERNANCE.md](../.github/GOVERNANCE.md) for the graduation criteria.