From c50f6d7c46149db07568ab2bff78487985385027 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 3 Aug 2026 04:09:26 +0200 Subject: [PATCH 1/2] docs(specs): add v1 functional specification Defines the initial public API for the PowerShellGallery module: - API metadata discovery - Package search and metadata retrieval - Listing management (hide/show) for package owners Includes naming conventions, parameter design, error handling, testing strategy, and migration notes from current stubs. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- docs/specs/v1.md | 270 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 270 insertions(+) create mode 100644 docs/specs/v1.md diff --git a/docs/specs/v1.md b/docs/specs/v1.md new file mode 100644 index 0000000..b33467f --- /dev/null +++ b/docs/specs/v1.md @@ -0,0 +1,270 @@ +# PowerShellGallery v1 Specification + +## Overview + +`PowerShellGallery` is a PowerShell module for interacting with the [PowerShell Gallery](https://www.powershellgallery.com). Version 1 focuses on two publisher-oriented workflows: + +1. **Discovery** — read package and API metadata from the public OData v2 endpoint. +2. **Listing management** — list and unlist package versions you own, using gallery API credentials. + +This spec defines the public API, expected behavior, error handling, and testing strategy for the v1 release. + +## Supported PowerShell version + +Latest PowerShell Long-Term Support (LTS) release, per the PSModule module standard. Windows PowerShell 5.1 is not a v1 target. + +## Out of scope for v1 + +- Installing, updating, or saving packages (covered by `PowerShellGet`). +- Publishing packages to the gallery. +- User or organization management. +- Admin-level gallery operations. +- Cross-gallery support (e.g., private NuGet feeds). + +## Naming convention + +Public nouns are prefixed with the module term of art: `PowerShellGallery`. + +Existing stub names `Hide-PowerShellGalleryItem` and `Show-PowerShellGalleryItem` are renamed to use the more precise noun `Package`, with backward-compatible aliases retained for the v1 major release. + +## Public API + +### `Get-PowerShellGalleryAPI` + +Get metadata from the PowerShell Gallery v2 API root. + +#### Synopsis + +```text +Get-PowerShellGalleryAPI [[-Uri] ] [] +``` + +#### Parameters + +| Name | Type | Mandatory | Default | Description | +| ---- | ---- | --------- | ------- | ----------- | +| `Uri` | `string` | No | `https://www.powershellgallery.com/api/v2/` | Base URI of the gallery OData endpoint. | + +#### Behavior + +- Performs an HTTP `GET` against the provided URI with `application/json` content negotiation. +- Returns the raw service response (commonly an OData service document / JSON). +- Throws a terminating error if the endpoint is unreachable or returns a non-success status code. + +#### Example + +```powershell +Get-PowerShellGalleryAPI +``` + +--- + +### `Find-PowerShellGalleryPackage` + +Search for packages on the PowerShell Gallery. + +#### Synopsis + +```text +Find-PowerShellGalleryPackage [[-Name] ] [-Tag ] [-IncludePrerelease] [-First ] + [-Skip ] [-OrderBy ] [] +``` + +#### Parameters + +| Name | Type | Mandatory | Default | Description | +| ---- | ---- | --------- | ------- | ----------- | +| `Name` | `string` | No | `*` | Package ID or search term. Supports wildcards. | +| `Tag` | `string[]` | No | none | Filter to packages that declare all specified tags. | +| `IncludePrerelease` | `switch` | No | false | Include prerelease versions in results. | +| `First` | `uint` | No | `50` | Maximum number of results to return. Capped at `1000`. | +| `Skip` | `uint` | No | `0` | Number of results to skip for pagination. | +| `OrderBy` | `string` | No | `DownloadCount desc` | OData `$orderby` expression. | + +#### Behavior + +- Queries `https://www.powershellgallery.com/api/v2/Packages()`. +- Supports pipeline input for `Name`. +- Returns one object per package version by default. +- Use `Get-PowerShellGalleryPackage` when you need a single package/version. + +#### Example + +```powershell +Find-PowerShellGalleryPackage -Name 'Pester' -First 5 +'Az.*' | Find-PowerShellGalleryPackage -First 10 +``` + +--- + +### `Get-PowerShellGalleryPackage` + +Get detailed metadata for a specific package and optionally a specific version. + +#### Synopsis + +```text +Get-PowerShellGalleryPackage [-Name] [[-Version] ] [-IncludePrerelease] + [] +``` + +#### Parameters + +| Name | Type | Mandatory | Default | Description | +| ---- | ---- | --------- | ------- | ----------- | +| `Name` | `string` | Yes | — | Exact package ID. | +| `Version` | `string` | No | latest stable | Specific version to retrieve. Accepts NuGet version strings including prerelease labels. | +| `IncludePrerelease` | `switch` | No | false | When `Version` is omitted, return the latest prerelease instead of the latest stable. | + +#### Behavior + +- If `Version` is provided, queries `Packages(Id='{Name}',Version='{Version}')`. +- If `Version` is omitted, queries the package feed filtered by ID, ordered by published date, and returns the newest item. +- Throws a terminating error if the package or version does not exist. + +#### Example + +```powershell +Get-PowerShellGalleryPackage -Name 'Pester' +Get-PowerShellGalleryPackage -Name 'Pester' -Version '5.5.0' +``` + +--- + +### `Hide-PowerShellGalleryPackage` + +Unlist a package version on the PowerShell Gallery. + +#### Synopsis + +```text +Hide-PowerShellGalleryPackage [-Name] [-Version] [-APIKey] + [-WhatIf] [-Confirm] [] +``` + +#### Aliases + +- `Unlist-PowerShellGalleryPackage` + +#### Parameters + +| Name | Type | Mandatory | Default | Description | +| ---- | ---- | --------- | ------- | ----------- | +| `Name` | `string` | Yes | — | Exact package ID. | +| `Version` | `string` | Yes | — | Exact version to unlist. | +| `APIKey` | `string` | Yes | — | PowerShell Gallery API key for the package owner. | + +#### Behavior + +- Requires ownership of the package. +- Uses the gallery listing endpoint to mark the version as unlisted. +- Supports `-WhatIf` and `-Confirm` via `SupportsShouldProcess`. +- Writes a non-terminating warning if the operation is not yet implemented or the gallery endpoint is unavailable. + +#### Example + +```powershell +Hide-PowerShellGalleryPackage -Name 'MyModule' -Version '1.0.0' -APIKey $env:PSGalleryAPIKey +``` + +--- + +### `Show-PowerShellGalleryPackage` + +List a package version on the PowerShell Gallery. + +#### Synopsis + +```text +Show-PowerShellGalleryPackage [-Name] [-Version] [-APIKey] + [-WhatIf] [-Confirm] [] +``` + +#### Aliases + +- `List-PowerShellGalleryPackage` + +#### Parameters + +| Name | Type | Mandatory | Default | Description | +| ---- | ---- | --------- | ------- | ----------- | +| `Name` | `string` | Yes | — | Exact package ID. | +| `Version` | `string` | Yes | — | Exact version to list. | +| `APIKey` | `string` | Yes | — | PowerShell Gallery API key for the package owner. | + +#### Behavior + +- Requires ownership of the package. +- Uses the gallery listing endpoint to mark the version as listed. +- Supports `-WhatIf` and `-Confirm` via `SupportsShouldProcess`. + +#### Example + +```powershell +Show-PowerShellGalleryPackage -Name 'MyModule' -Version '1.0.0' -APIKey $env:PSGalleryAPIKey +``` + +## Private helpers + +Private functions are grouped under `src/functions/private/Gallery/`. + +| Function | Responsibility | +| -------- | -------------- | +| `Invoke-PowerShellGalleryAPI` | Shared REST wrapper: handles URI building, headers, content negotiation, timeout, and error translation. | +| `Get-PowerShellGalleryResource` | Generic OData resource GET (to be merged into or replaced by `Invoke-PowerShellGalleryAPI`). | +| `Update-PowerShellGalleryResourceListing` | Shared POST to the gallery listing endpoint used by `Hide`/`Show`. | + +## Return types + +Commands return plain objects deserialized from OData JSON by default. A future release may introduce typed output classes; v1 does not. + +## Error handling + +- Use `ErrorAction` semantics consistently. +- Wrap `Invoke-RestMethod` failures in descriptive error records where the gallery response adds useful context. +- Authentication or authorization failures from listing endpoints produce clear, actionable messages. +- Discovery commands must not throw on empty result sets; they return nothing. + +## Authentication + +- Read commands require no authentication. +- Listing-management commands require a PowerShell Gallery API key with ownership of the target package. +- The API key is passed via the `APIKey` parameter. Do not persist keys in the module; callers supply them per command. + +## Logging and progress + +- Emit `Verbose` output for URIs, pagination, and auth-skipping details. +- Emit `Warning` when a listing command cannot complete because the gallery endpoint is unavailable. +- Do not emit progress bars for simple HTTP calls. + +## Testing + +Follow the [PSModule Test Specification](https://psmodule.github.io/docs/Modules/Test-Specification/): + +- No mocks; use real inputs and the public gallery endpoint. +- Test each public command with `Describe`/`Context`/`It` hierarchy. +- Discovery tests use well-known packages (e.g., `Pester`, `PowerShellGet`) to ensure stable results. +- Listing-management tests validate parameter binding and `-WhatIf` behavior; they do not mutate real packages. +- Code coverage target remains 50% as configured in `.github/PSModule.yml` for v1. + +## Documentation + +- Each public function has full comment-based help with synopsis, description, examples, and parameter help. +- A `.md` overview file is added alongside public functions. +- README is updated to describe v1 capabilities. + +## Migration from current stubs + +| Current file | v1 disposition | +| ------------ | -------------- | +| `Get-PSGalleryAPI.ps1` | Rename to `Get-PowerShellGalleryAPI.ps1`; keep URI default. | +| `Hide-PowerShellGalleryItem.ps1` | Rename to `Hide-PowerShellGalleryPackage.ps1`; add `Unlist-PowerShellGalleryPackage` alias. | +| `Show-PowerShellGalleryItem.ps1` | Rename to `Show-PowerShellGalleryPackage.ps1`; add `List-PowerShellGalleryPackage` alias. | +| `Get-PSGalleryResource.ps1` | Refactor into `Invoke-PowerShellGalleryAPI` or retain as private helper. | +| `Update-PSGalleryResourceListing.ps1` | Retain as private helper; fix auth and parameter handling. | + +## Open questions + +1. Does the gallery expose a stable, API-key-only listing endpoint, or do we need a full web-login + anti-forgery token flow? +2. Should `Find-PowerShellGalleryPackage` collapse multiple versions of the same package ID by default? +3. Should v1 include `Save-PowerShellGalleryPackage` (download `.nupkg`) or leave that to `PowerShellGet`? From 94e3fd589df7f84d7e78a79b8b22f4391e4d43cc Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 29 Aug 2026 01:56:15 +0200 Subject: [PATCH 2/2] build(deps): upgrade Process-PSModule caller to v8 - Replace .github/workflows/Process-PSModule.yml with the v8 caller contract (exact triggers, permissions, concurrency, and secrets; no secrets inherit). - Migrate tests to Pester 6: add #Requires, suppress PSSA attributes, and update assertions to v6-compatible syntax. - Add missing repository baseline files: AGENTS.md, CONTRIBUTING.md, and .github/pull_request_template.md. - Migrate documentation from MkDocs to Zensical: - Remove .github/mkdocs.yml - Add docs/zensical.toml with docs_dir = 'content' - Add docs/content/index.md and move docs/specs/v1.md to docs/content/specs/v1.md - Copy icon/icon.png to docs/content/Assets/icon.png - Ignore generated docs/site/ Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .github/mkdocs.yml | 75 ------------------------- .github/pull_request_template.md | 36 ++++++++++++ .github/workflows/Process-PSModule.yml | 26 +++++---- .gitignore | 3 + AGENTS.md | 31 ++++++++++ CONTRIBUTING.md | 44 +++++++++++++++ docs/content/Assets/icon.png | Bin 0 -> 5882 bytes docs/content/index.md | 37 ++++++++++++ docs/{ => content}/specs/v1.md | 0 docs/zensical.toml | 64 +++++++++++++++++++++ tests/PowerShellGallery.Tests.ps1 | 21 +++++-- 11 files changed, 248 insertions(+), 89 deletions(-) delete mode 100644 .github/mkdocs.yml create mode 100644 .github/pull_request_template.md create mode 100644 AGENTS.md create mode 100644 CONTRIBUTING.md create mode 100644 docs/content/Assets/icon.png create mode 100644 docs/content/index.md rename docs/{ => content}/specs/v1.md (100%) create mode 100644 docs/zensical.toml diff --git a/.github/mkdocs.yml b/.github/mkdocs.yml deleted file mode 100644 index df5e17a..0000000 --- a/.github/mkdocs.yml +++ /dev/null @@ -1,75 +0,0 @@ -site_name: -{{ REPO_NAME }}- -theme: - name: material - language: en - font: - text: Roboto - code: Sono - logo: Assets/icon.png - favicon: Assets/icon.png - palette: - # Palette toggle for automatic mode - - media: "(prefers-color-scheme)" - toggle: - icon: material/link - name: Switch to dark mode - # Palette toggle for dark mode - - media: '(prefers-color-scheme: dark)' - scheme: slate - toggle: - primary: black - accent: green - icon: material/toggle-switch-off-outline - name: Switch to light mode - # Palette toggle for light mode - - media: '(prefers-color-scheme: light)' - scheme: default - toggle: - primary: indigo - accent: green - icon: material/toggle-switch - name: Switch to system preference - icon: - repo: material/github - features: - - navigation.instant - - navigation.instant.progress - - navigation.indexes - - navigation.top - - navigation.tracking - - navigation.expand - - search.suggest - - search.highlight - -repo_name: -{{ REPO_OWNER }}-/-{{ REPO_NAME }}- -repo_url: https://github.com/-{{ REPO_OWNER }}-/-{{ REPO_NAME }}- - -plugins: - - search - -markdown_extensions: - - toc: - permalink: true # Adds a link icon to headings - - attr_list - - admonition - - md_in_html - - pymdownx.details # Enables collapsible admonitions - -extra: - social: - - icon: fontawesome/brands/discord - link: https://discord.gg/jedJWCPAhD - name: -{{ REPO_OWNER }}- on Discord - - icon: fontawesome/brands/github - link: https://github.com/-{{ REPO_OWNER }}-/ - name: -{{ REPO_OWNER }}- on GitHub - consent: - title: Cookie consent - description: >- - We use cookies to recognize your repeated visits and preferences, as well - as to measure the effectiveness of our documentation and whether users - find what they're searching for. With your consent, you're helping us to - make our documentation better. - actions: - - accept - - reject diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..ff2067e --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,36 @@ + + + + + +## New: + + + +## Technical Details + + + +
+Related issues + + + +
diff --git a/.github/workflows/Process-PSModule.yml b/.github/workflows/Process-PSModule.yml index 9462763..f0ca651 100644 --- a/.github/workflows/Process-PSModule.yml +++ b/.github/workflows/Process-PSModule.yml @@ -4,6 +4,9 @@ on: workflow_dispatch: schedule: - cron: '0 0 * * *' + push: + branches: + - main pull_request: branches: - main @@ -13,19 +16,22 @@ on: - reopened - synchronize - labeled + - unlabeled concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} -permissions: - contents: write - pull-requests: write - statuses: write - pages: write - id-token: write +permissions: {} jobs: Process-PSModule: - uses: PSModule/Process-PSModule/.github/workflows/workflow.yml@205d193f34cbbaf9992955c21d842bcf98a1859f # v5.4.6 - secrets: inherit + permissions: + contents: read + pages: write + id-token: write + uses: PSModule/Process-PSModule/.github/workflows/workflow.yml@v8 + secrets: + PSGALLERY_API_KEY: ${{ secrets.PSGALLERY_API_KEY }} + GitHubAppClientId: ${{ secrets.SHELLY_CLIENT_ID }} + GitHubAppPrivateKey: ${{ secrets.SHELLY_PRIVATE_KEY }} diff --git a/.gitignore b/.gitignore index 8af6555..bcf4801 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,9 @@ # PSModule framework outputs folder outputs/* +# Zensical generated site +docs/site/ + # .Net build output bin/ obj/ diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..db6785f --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,31 @@ +# Agents + +## Main directive + +Everything is a work in progress and can be improved. +If you find a problem or improvement, fix if small; otherwise open an issue. + +## Repo guidance + +- [`README.md`](README.md) — what this module is and how to use it. +- [`CONTRIBUTING.md`](CONTRIBUTING.md) — how to contribute to this repository. + +## PSModule Framework guidance + +For PSModule-specific build, layout, and process guidance: + +- [Template quickstart](https://psmodule.github.io/docs/Modules/Process-PSModule/template-quickstart/) +- [Repository defaults](https://psmodule.github.io/docs/Modules/Repository-Defaults/) +- [Module anatomy](https://psmodule.github.io/docs/Modules/Process-PSModule/module-anatomy/) +- [Build, test, pack, publish](https://psmodule.github.io/docs/Modules/Process-PSModule/build-test-pack-publish/) +- [Standards](https://psmodule.github.io/docs/Modules/Standards/) +- [PSModule/memory](https://github.com/PSModule/memory) + +## Org-wide guidance + +For cross-cutting ways of working and standards: + +- [Agentic Development](https://msxorg.github.io/docs/Ways-of-Working/Agentic-Development/) +- [Ways of Working](https://msxorg.github.io/docs/Ways-of-Working/) +- [Coding Standards](https://msxorg.github.io/docs/Coding-Standards/) +- [MSXOrg/memory](https://github.com/MSXOrg/memory) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..15f724a --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,44 @@ +# Contributing + +Thank you for contributing to this module. +Read [`AGENTS.md`](AGENTS.md) first for the full guidance chain and documentation references. + +## Before you start + +1. Read [`README.md`](README.md) to understand what the module does. +2. Familiarise yourself with the [repository defaults](https://psmodule.github.io/docs/Modules/Repository-Defaults/) that this repository must satisfy. +3. Check the open issues and pull requests to avoid duplicate work. + +## Workflow + +This project follows the [MSXOrg contribution workflow](https://msxorg.github.io/docs/Ways-of-Working/Contribution-Workflow/): + +1. Open or pick up an issue that describes the change. +2. Create a branch from `main` following the `/-` convention (e.g. `feat/42-add-security-md`). +3. Make small, focused commits and push often. +4. Open a **draft PR** as soon as the change has a basic shape — early feedback is preferred. +5. Run the **Copilot review loop**: request a Copilot review, address its feedback, and repeat until it reports a clean round. File an issue for any out-of-scope findings rather than expanding the PR. +6. Mark the PR ready for review and enable auto-merge. It lands automatically once the required checks pass and a reviewer approves. + +For branching details, see [Branching and Merging](https://msxorg.github.io/docs/Ways-of-Working/Branching-and-Merging/). + +## Pull requests + +- Keep PRs small and focused on a single deliverable. +- The PR title should follow the [commit conventions](https://msxorg.github.io/docs/Ways-of-Working/Commit-Conventions/). + +For PR format guidance, see [PR Format](https://msxorg.github.io/docs/Ways-of-Working/PR-Format/). + +## Issues + +Use GitHub Issues to report bugs, request features, or propose improvements. +Follow the [issue format](https://msxorg.github.io/docs/Ways-of-Working/Issue-Format/) guidance. + +## Code standards + +PowerShell in this module follows the [PSModule Standards](https://psmodule.github.io/docs/Modules/Standards/) and the +[MSXOrg Coding Standards](https://msxorg.github.io/docs/Coding-Standards/). + +## Questions + +Open a GitHub Discussion or file an issue if something is unclear. diff --git a/docs/content/Assets/icon.png b/docs/content/Assets/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..be83fd5fd3914846c735d44415569b86c254ccad GIT binary patch literal 5882 zcmX9?dpy(c7oQBnHlr{aVJ<}&ks^v^LfrW&q;8wvw#Um3V=W$n3W~Y5d`9b?L81) zU`A8~0|8!KA&wTNpch|JQvd<>H?cJVfhyAk|DNXoXnvBVTL=gQXYM^*Emul?K_Ia- zE1ZebO|RLXVWCbJ9<(f$+?~;P`-E$RiMrEfL2^Mp>!nfVJpRSoLfK6*Mb}kIEx;!3 zV&V<~CO?Xf(oWk`M!60Q8b@Tky@skO)^r=&VJo{odrPC&CrYl>wToj|-e6B3mgJY^+ zADmA!fLi@l*gJuSUE^t#jV%kaecbD^8_T9?0TDXXZAagx{{`+u=NhI%a= z1j+DBhlPC#zuCPd`SaZs@0#fsAIQ^{iMo=1gDEEiB@ReR$n=51lck3SPQU)D<((pa@K+~(`cxB1`iZ%soHe0=%^S)3N>y}KBI5$QwUuNAAhy~5e(vjemgZ6DyYwYAmVnZq;} zkgC$lJb>v5}Q=o!(uED{p@13vWGw&xt9Q5JQ; z+@DbF(@m|9^l!|0RS`4J>YnZ=F6bsp>0hr6H1JZq3o;II!Q3n|UR_-^&Qq#J$J+Om1Cm=kVumR7Fzop!i@W#d+dJB%Zl~m#; zu%@fCOPibY?zaDfzfD6dvgn#HQB%oBR)oHNLk8m0^Sm>@kU0zWa|f355bAeSCSd5mFFU!%GRX zK6Q$l0BxCK74fZ3_odm*tsng3mTrFAtt~5a{PFiKzh|XE#q(d%y6QV#cC(**Of7Jj zqc8V$Poa{Fi;ER;=;Wcgi0&)qKTRoiox&5l9pWmifFS;^=qrO}4_(>?sNi;b1O{orJ)sphI!dV7-nAgW zd6&0OXzjkr)0)c*V}N3HZ6H(_t0F5at80AQuj>d;0O9c^HLOb7T<$L9*YDqnqFoaC zOpF4ueS_%h=l3lx;mna^z3MKbV?7O8H9JEC5ZdohLtul(iZuSPjaY3z9h;8Uhr4mA zeFPc`RrXUD$*Ij@6OSyIonQCAZX7X_p24p8T*TaGu{PdKTQ?o9tQhM`YGdG=&Bv0D zeJ!Y0$RXUlSvzKo?eP!C+^=M{9*nF*>hf_M4w8ilfm&))-L}cO7ieg8^~woHnfeVq zC>Y(?Ph3gt)|RM*JVHIXEk%>FsUfL|n46=uwX?sS8LaaV)rV`#AeA&VB?AKHW;MUR zx`BewauLZ3$;nikmM8y>*CZrTnwy(PA_%SfIO&39mWGdg++2UOQ}Q@MuO*gL4P#8^ zzGrRx_0-6;=!~4f4#wee&Hco{fmbJ!$H`JOeMEAr#K9EL57$}#`ejWvYI|1XQt-Hz zeqzNtS3|VF{1z zRE-&?2F^mP%?y|cN@we%)(Qn0gb#wzhKQ8o2zZn%a*;wr(U^;kC*F5nl|ivgFr$Jj zh|l~`9Xpkq)5S#=j*d6icM`C;b!+C3!qa15v<4ytet3UsgufiB#RMb5$C`{2;2bu= zrpDss#puFZab{8w^HEtzVN>il4Ugq!#qVp7RR=S5lN z&d$ydY7!y^3;2`Cz=k`$=q%TO(S?ZmIFy(2Fw(i{!WP%DaJHp%YFo6U8VW)^ z0RYBG3)fJZv@!Xn28NP>Ff>d?l0SyjDCDJ(AwhFSLe*9f>ExlkI%Q~&~NGhm&=emY0)3{w~aMnG@NN~#@G zMWLXBr|8FVX8W#Vm7lG``N)NQI5QDcD$jBc#NzbnjI#+Sa-k5;Ozv46MO`;d5iraP z0c)ESgM-bC;;C^xx=vGAU@{K@vwDh1oztBK^mK{SWi{X}`$PP{?J{A6lZKpzSo|c6 zm3}TPER57rXo{`5F`tS@f>;hQ%D_=wf?C_#TVS+k#KWf9B%6nunCz^qc+oCldLcrz zfmP(8*b(k)*ifi}Gt+n$=d(6wgho9u)jCkzSZM9VYp~EYmi6$Vii@#$Je58}$~uKg z9VH)q5c;oZe0{q~U=mP+r1=z%bC8jC8YxoxF73vA@zhZ#NXtj>Yqm~0)vIZ0aZWB*ELrXn?c95VK%EDV3!j^6q`JaA^+ymIQA>s8Sf<1t^WaeVp4R%7#wq|!` z6U2#1BnGyo%ZAQI|1G)yejcwKl+(vWFFXP_pW5IbUk-0f++K6-O%N`Hvbwsu3e5s) zeHr-d;pn601)4asW2oeZ)-88jU*Rj#jLfw{V~E7@zssE^jw;AkvzW6ddxf{=KFkAl z0BXpTtKGJb9p^Cpmo9k;)K6hbg;-rNGmOJVP8OH?UWguZkfIl2fmD^}@mKs}VAi@> zzKmWxwZRF}{LHzGIM$p(;MFtMI`G&OGqf4Xr|R+6rhU)dWPssA{%moH-*Cd6d`VzW zimWkW?YTHxTU!E8D4BTJx4+^%gtr>basc!B3|2oJH>6cg<*#&&^Fye=5ip)okz}{^ zK~ta@b8@8}><*<8E$7IBY7UCXwKqthdV-N`Z^^7%1R51XAR zF$rd+XDKu88*H+#zg!C>5{?U9G# zsq#Ji%?U~d=-Z@8E>`*{AOU9co4cwHnqq-ns!pb8__d!!lh2!Bd#J=}%iH+!e+yr# zd6`sFsUVA#0B8)Ef6o8m9+7R9KLMFj)oBt1#ZQ4T3& zm!Y&L$}8TSOv0F_NvGgLxf*1ZaA+&VFzQ0jmE$#cX!2}?-`s+BjT*G@h48K3Vr7TEW`=| z;g>9{9=8{M2RE=yh4ZPIM&@@JnAayZ$+65@k^dV@Fg~n_gZ-DuaD~Hg{6=lY#28aQ)?UcDJU5lQC)^ z{{}19U6WhYJK|kFIX%KbuPh}_OaVS4T~kszh#SK~%x`XPZmxW)Eg>$vwA-)pd*l4D zYsYXqfL#gES~_ zxAF%JHbQ(feTo?3JLhh7%s1K?2Jui*>My_QpkUUX%+zQ;i6Wc&E2 zA7*K3X)@EqKS?4k^Ov~ZBaQEd}_4@VovVUt&vlw`z%iBg871r0X_J!L#k?iwT~^a6A;v#2if7!4o$v{&av(2Ncec1(5wFk zOnH9pedb!0YobJz^Np%lF;(}yJ1(K=MDs}|ocH6owXrm#Z_AxVO7(Y;sN@#^(*00& zf4`;u*ZibTD8J9tsQ=UmgTnAepJ8$iVo4+1gz~z#jEc)cwK?HyQr7-!GiolQ7ESp6 z>$BfQYYm3BHW4ZdOH_Lzt09aawiPz|GV6fu{9QY6erMmsc02Sr4Dw%)-i-|mFWiM{r|Upj+M}eSyTvhe?%J?0@si~5DHX-6;z?cWa`<)4eS7N*QM48KTy6&+jRokq4 zinG|8C52I1dVW@`4`u$W4C|Emk9 z7Rvetc1lYh>grVOoOQ8E>xhc?y2-h17tM`PK%rpIjgB7qhDWIb)x3F%c^v&KBJkU)l075{`8g= z?GA7r%5E-SzV>)ksk})tdF)Z}=Oc_80i$VpmPh{B4oEx=t$21?%aDS6?D%-m{rRLT>RI8|(v^VW`Y6V~{J;I8dNi{iK;xp} z(F&N9_=3~5rUHDm@k-(;g~FTVfew zjCuYpKmC$jWNiU_&0c6bE!9vMsD*$!WWYHNnvy7JJxP!O5*^?;tPaWlqBC@0O=H&f zAf17}tEEWzV>*K|VkQFS4lTHd%}U@UbLly1psaBeN~KQ=9L!x+?2au?qe?+@SHO>+ z9)LeB0#pNOiB<)u{)AJGGy4oI5U)AFl=alYBCEgcw^0hg7AFFTT^?@CqjFBVqU2hg zJcRd?x-XP=fK@TCV1fbJ$$MbWr2*QybaNUw7lGx*w6=-B`vAj0ID0CoS_B5>mbo4T zTsQ#nAkPUuEGh+HM;Ha&W>)S^El!wYv68lh=SLT^^B}y&goWkLjCB+YXfxQG4ogbh zqjJl8ojG#{&8Y}y&Ai!_?IlRxfbhnIpad+q59Q4Wq>KS>A>~P>;ugc}Xd4UT9vW!} zf##4w0+iO9^eFP?k~cwG96)SuY~G6}ZS3rJ*0B#YR!svPh%k9M6kBmDNGM-R!su4y zdu??A)fQd`DE&-uuqIHkC%DZ-8hSHpu1z~`=JFmYsg+~X6IbInkmARWeqyNSw@h$8~HkN zGgw1VS5dP4+2=PvBT-3XN8%s%!Ykz%uZ^&d32eh{=KQ*jpRaE&=|wkMI!)tz1Nh?Q z%a`9$4fB35Ml3*G_KuE@3;QtjK}lhCL&n#yzg^$(c?PQO1A$QuTfx{0mnZNv@zN zUG}`%B%1Hy>2>wC zwMdixdD_F{hYA8RLgFz#ABoM(&VHkcMvvvXdL{fdU%#KX(dT(X%Gt%mrMI{Dg2$Og zZe!We-i*&PGc)AgGS{Tu)@xJz(Y?;D8KSArwzjrrfTkb7Lx}X!)Ye{g2nq_iRZNrP zH2zBXI-y@qD!)P`BK@K+$jN|$NA~BowY6!p`y!^MrqFaOU?+8~*R!=U*H&({)9+C?VdMIMm`4{L{ OgRD;4;a-^H$^Qd{UB>JH literal 0 HcmV?d00001 diff --git a/docs/content/index.md b/docs/content/index.md new file mode 100644 index 0000000..cc6ee34 --- /dev/null +++ b/docs/content/index.md @@ -0,0 +1,37 @@ +# PowerShellGallery + +PowerShellGallery is a PowerShell module for interacting with the [PowerShell Gallery](https://www.powershellgallery.com). + +Version 1 focuses on two publisher-oriented workflows: + +- **Discovery** — read package and API metadata from the public OData v2 endpoint. +- **Listing management** — list and unlist package versions you own, using gallery API credentials. + +## Installation + +Install the module from the PowerShell Gallery when a published release is available: + +```powershell +Install-PSResource -Name PowerShellGallery -TrustRepository +``` + +## Quick start + +```powershell +# Read gallery API metadata +Get-PowerShellGalleryAPI + +# Search for packages +Find-PowerShellGalleryPackage -Name 'Pester' -First 5 + +# Get a specific package +Get-PowerShellGalleryPackage -Name 'Pester' -Version '5.5.0' +``` + +## Documentation + +- [v1 Specification](specs/v1.md) — functional specification for the initial release. + +## Contributing + +See `CONTRIBUTING.md` and `AGENTS.md` in the repository root. diff --git a/docs/specs/v1.md b/docs/content/specs/v1.md similarity index 100% rename from docs/specs/v1.md rename to docs/content/specs/v1.md diff --git a/docs/zensical.toml b/docs/zensical.toml new file mode 100644 index 0000000..933befe --- /dev/null +++ b/docs/zensical.toml @@ -0,0 +1,64 @@ +[project] +site_name = "-{{ REPO_NAME }}-" +docs_dir = "content" +repo_name = "-{{ REPO_OWNER }}-/-{{ REPO_NAME }}-" +repo_url = "https://github.com/-{{ REPO_OWNER }}-/-{{ REPO_NAME }}-" + +[project.theme] +variant = "classic" +language = "en" +logo = "Assets/icon.png" +favicon = "Assets/icon.png" +features = [ + "navigation.instant", + "navigation.instant.progress", + "navigation.top", + "navigation.tracking", + "navigation.expand", + "search.suggest", + "search.highlight", + "content.code.copy" +] + +[[project.theme.palette]] +media = "(prefers-color-scheme)" +toggle.icon = "lucide/sun-moon" +toggle.name = "Switch to dark mode" + +[[project.theme.palette]] +media = "(prefers-color-scheme: dark)" +scheme = "slate" +primary = "black" +accent = "light-blue" +toggle.icon = "lucide/moon" +toggle.name = "Switch to light mode" + +[[project.theme.palette]] +media = "(prefers-color-scheme: light)" +scheme = "default" +primary = "black" +accent = "light-blue" +toggle.icon = "lucide/sun" +toggle.name = "Switch to system preference" + +[project.theme.icon] +repo = "fontawesome/brands/github" + +[project.markdown_extensions.toc] +permalink = true + +[project.markdown_extensions.attr_list] +[project.markdown_extensions.admonition] +[project.markdown_extensions.md_in_html] +[project.markdown_extensions.pymdownx.details] +[project.markdown_extensions.pymdownx.superfences] + +[[project.extra.social]] +icon = "fontawesome/brands/discord" +link = "https://discord.psmodule.io" +name = "-{{ REPO_OWNER }}- on Discord" + +[[project.extra.social]] +icon = "fontawesome/brands/github" +link = "https://github.com/-{{ REPO_OWNER }}-/" +name = "-{{ REPO_OWNER }}- on GitHub" diff --git a/tests/PowerShellGallery.Tests.ps1 b/tests/PowerShellGallery.Tests.ps1 index 0d9b261..eeb8634 100644 --- a/tests/PowerShellGallery.Tests.ps1 +++ b/tests/PowerShellGallery.Tests.ps1 @@ -1,16 +1,29 @@ -Describe 'PowerShellGallery' { +#Requires -Modules @{ ModuleName = 'Pester'; ModuleVersion = '6.0.0'; MaximumVersion = '6.*' } + +[Diagnostics.CodeAnalysis.SuppressMessageAttribute( + 'PSReviewUnusedParameter', '', + Justification = 'Required for Pester tests' +)] +[Diagnostics.CodeAnalysis.SuppressMessageAttribute( + 'PSUseDeclaredVarsMoreThanAssignments', '', + Justification = 'Required for Pester tests' +)] +[CmdletBinding()] +param() + +Describe 'PowerShellGallery' { Context 'Function: Get-PSGalleryAPI' { - It 'Should not throw' { + It 'Get-PSGalleryAPI - does not throw' { { Get-PSGalleryAPI } | Should -Not -Throw } } Context 'Function: Hide-PowerShellGalleryItem' { - It 'Should not throw' { + It 'Hide-PowerShellGalleryItem - does not throw' { { Hide-PowerShellGalleryItem } | Should -Not -Throw } } Context 'Function: Show-PowerShellGalleryItem' { - It 'Should not throw' { + It 'Show-PowerShellGalleryItem - does not throw' { { Show-PowerShellGalleryItem } | Should -Not -Throw } }