From a8a9cc28b194fac79f545eb226098e97f7fb7186 Mon Sep 17 00:00:00 2001 From: Clint Branham Date: Fri, 20 Mar 2026 12:22:13 -0500 Subject: [PATCH] chore: add community files and PSGallery publish workflow - Add CONTRIBUTING.md, SECURITY.md, CODE_OF_CONDUCT.md - Add .gitattributes for line ending normalization - Add GitHub issue templates (bug report, feature request) - Add pull request template - Add publish.yml workflow for PSGallery publication on tag push Co-Authored-By: Claude Opus 4.6 (1M context) --- .gitattributes | 29 +++++++ .github/ISSUE_TEMPLATE/bug_report.yml | 74 +++++++++++++++++ .github/ISSUE_TEMPLATE/feature_request.yml | 37 +++++++++ .github/pull_request_template.md | 30 +++++++ .github/workflows/publish.yml | 72 ++++++++++++++++ CODE_OF_CONDUCT.md | 30 +++++++ CONTRIBUTING.md | 96 ++++++++++++++++++++++ SECURITY.md | 45 ++++++++++ 8 files changed, 413 insertions(+) create mode 100644 .gitattributes create mode 100644 .github/ISSUE_TEMPLATE/bug_report.yml create mode 100644 .github/ISSUE_TEMPLATE/feature_request.yml create mode 100644 .github/pull_request_template.md create mode 100644 .github/workflows/publish.yml create mode 100644 CODE_OF_CONDUCT.md create mode 100644 CONTRIBUTING.md create mode 100644 SECURITY.md diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..7101fc9 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,29 @@ +# Auto-detect text files and normalize line endings +* text=auto + +# Source code +*.cs text diff=csharp +*.csproj text +*.sln text eol=crlf +*.ps1 text +*.psm1 text +*.psd1 text + +# Documentation +*.md text diff=markdown +*.yml text +*.yaml text +*.json text + +# Binary +*.dll binary +*.exe binary +*.pdb binary +*.iso binary +*.img binary + +# Ensure shell scripts use LF +*.sh text eol=lf + +# Ensure PowerShell format files use platform default +*.ps1xml text diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000..713eadb --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,74 @@ +name: Bug Report +description: Report a bug in PSProxmoxVE +labels: [bug] +body: + - type: markdown + attributes: + value: | + Thanks for reporting a bug! Please fill out the sections below. + + - type: input + id: module-version + attributes: + label: Module Version + description: Output of `(Get-Module PSProxmoxVE).Version` + placeholder: "0.1.0" + validations: + required: true + + - type: input + id: pve-version + attributes: + label: Proxmox VE Version + description: PVE server version (e.g. 9.1-1, 8.4-1) + placeholder: "9.1-1" + validations: + required: true + + - type: dropdown + id: ps-version + attributes: + label: PowerShell Version + options: + - "5.1 (Windows PowerShell)" + - "7.2" + - "7.4" + - "7.5" + - "Other" + validations: + required: true + + - type: dropdown + id: os + attributes: + label: Operating System + options: + - Windows + - Linux + - macOS + validations: + required: true + + - type: textarea + id: description + attributes: + label: Description + description: What happened? What did you expect? + validations: + required: true + + - type: textarea + id: repro + attributes: + label: Steps to Reproduce + description: Minimal PowerShell commands to reproduce the issue + render: powershell + validations: + required: true + + - type: textarea + id: error + attributes: + label: Error Output + description: Paste any error messages or verbose output + render: text diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000..c645929 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,37 @@ +name: Feature Request +description: Suggest a new feature or enhancement +labels: [enhancement] +body: + - type: markdown + attributes: + value: | + Thanks for suggesting an improvement! Please describe what you'd like. + + - type: textarea + id: description + attributes: + label: Description + description: What feature or improvement would you like? + validations: + required: true + + - type: textarea + id: use-case + attributes: + label: Use Case + description: How would you use this feature? What problem does it solve? + validations: + required: true + + - type: textarea + id: api-endpoints + attributes: + label: PVE API Endpoints + description: If this involves specific PVE API endpoints, list them here + placeholder: "GET /nodes/{node}/qemu/{vmid}/firewall/rules" + + - type: textarea + id: alternatives + attributes: + label: Alternatives Considered + description: Have you considered any workarounds or alternative approaches? diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..024fc75 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,30 @@ +## Summary + + + +## Type of Change + +- [ ] Bug fix +- [ ] New feature (new cmdlet, new parameter, etc.) +- [ ] Enhancement (improvement to existing functionality) +- [ ] Documentation +- [ ] CI/CD +- [ ] Refactoring (no functional change) + +## Checklist + +- [ ] `dotnet build` succeeds with zero warnings +- [ ] xUnit tests pass (`dotnet test`) +- [ ] Pester tests pass (`Invoke-Pester -ExcludeTag Integration`) +- [ ] New cmdlets added to `CmdletsToExport` in `PSProxmoxVE.psd1` +- [ ] New cmdlets have Pester unit tests +- [ ] `CHANGELOG.md` updated under `[Unreleased]` +- [ ] README cmdlet reference updated (if adding new cmdlets) + +## PVE API Endpoints + + + +## Testing + + diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..b64f532 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,72 @@ +name: Publish to PSGallery + +on: + push: + tags: + - 'v*' + +permissions: + contents: write + +jobs: + publish: + runs-on: ubuntu-latest + timeout-minutes: 15 + + steps: + - uses: actions/checkout@v5 + + - name: Setup .NET + uses: actions/setup-dotnet@v5 + with: + dotnet-version: '9.0.x' + + - name: Extract version from tag + id: version + run: echo "version=${GITHUB_REF_NAME#v}" >> "$GITHUB_OUTPUT" + + - name: Build module + run: dotnet publish src/PSProxmoxVE/PSProxmoxVE.csproj --configuration Release --framework netstandard2.0 --output ./publish/netstandard2.0 + + - name: Clean publish output + run: rm -f ./publish/netstandard2.0/*.deps.json ./publish/netstandard2.0/*.runtimeconfig.json + + - name: Update module version in manifest + shell: pwsh + run: | + $manifestPath = './publish/netstandard2.0/PSProxmoxVE.psd1' + $version = '${{ steps.version.outputs.version }}' + # Strip prerelease suffix for ModuleVersion (must be X.Y.Z) + $moduleVersion = ($version -split '-')[0] + $content = Get-Content $manifestPath -Raw + $content = $content -replace "ModuleVersion\s*=\s*'[^']*'", "ModuleVersion = '$moduleVersion'" + Set-Content $manifestPath $content + + - name: Install PowerShell and Pester + shell: pwsh + run: Install-Module -Name Pester -MinimumVersion 5.0 -Force -Scope CurrentUser + + - name: Test module loads + shell: pwsh + run: | + $modulePath = "$HOME/.local/share/powershell/Modules/PSProxmoxVE" + New-Item -ItemType Directory -Path $modulePath -Force | Out-Null + Copy-Item -Path ./publish/netstandard2.0/* -Destination $modulePath -Recurse -Force + Import-Module PSProxmoxVE -Force -ErrorAction Stop + $commands = Get-Command -Module PSProxmoxVE + Write-Host "Module loaded with $($commands.Count) commands" + if ($commands.Count -lt 60) { + throw "Expected at least 60 commands, got $($commands.Count)" + } + + - name: Publish to PSGallery + shell: pwsh + env: + NUGET_API_KEY: ${{ secrets.PSGALLERY_API_KEY }} + run: | + Publish-Module -Path ./publish/netstandard2.0 -NuGetApiKey $env:NUGET_API_KEY -Verbose + + - name: Create GitHub Release + uses: softprops/action-gh-release@v2 + with: + generate_release_notes: true diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..ee6c47c --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,30 @@ +# Code of Conduct + +## Our Standards + +This project is committed to providing a welcoming and inclusive experience for everyone. We expect all participants to: + +- Be respectful and considerate in all interactions +- Welcome newcomers and help them get started +- Accept constructive feedback gracefully +- Focus on what is best for the community and the project + +## Unacceptable Behavior + +- Personal attacks, insults, or derogatory comments +- Publishing others' private information without permission +- Any conduct that would be considered inappropriate in a professional setting + +## Scope + +This code of conduct applies to all project spaces including issues, pull requests, discussions, and any other communication channels associated with this project. + +## Enforcement + +Project maintainers are responsible for clarifying and enforcing standards of acceptable behavior. Instances of unacceptable behavior may be reported by contacting the project maintainer via GitHub. + +Maintainers may remove, edit, or reject contributions that do not align with this Code of Conduct, and may temporarily or permanently ban contributors for inappropriate behavior. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org/), version 2.1. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..ca92c65 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,96 @@ +# Contributing to PSProxmoxVE + +Thank you for your interest in contributing! This document provides guidelines and instructions for contributing to PSProxmoxVE. + +## Development Setup + +### Prerequisites + +- [.NET SDK 9.0+](https://dotnet.microsoft.com/download) +- [PowerShell 7.2+](https://github.com/PowerShell/PowerShell) (for running Pester tests) +- [Pester 5](https://pester.dev/) (`Install-Module Pester -MinimumVersion 5.0 -Force`) +- An IDE with C# support (Visual Studio, VS Code with C# Dev Kit, Rider) + +### Building + +```bash +# Clone the repository +git clone https://github.com/goodolclint/PSProxmoxVE.git +cd PSProxmoxVE + +# Restore and build +dotnet build + +# Publish for local testing +dotnet publish src/PSProxmoxVE/PSProxmoxVE.csproj --framework netstandard2.0 --output ./publish/netstandard2.0 +``` + +### Running Tests + +```bash +# xUnit unit tests (C# core library) +dotnet test tests/PSProxmoxVE.Core.Tests + +# Pester cmdlet tests (requires built module) +pwsh -Command "Invoke-Pester -Path tests/PSProxmoxVE.Tests -ExcludeTag Integration" + +# Integration tests (requires live PVE node -- see tests/infrastructure/README.md) +pwsh -Command "Invoke-Pester -Path tests/PSProxmoxVE.Tests/Integration -Tag Integration" +``` + +## Coding Standards + +### C# Style + +- Use C# 10.0 language features. +- Enable nullable reference types (`#nullable enable`). +- Follow standard .NET naming conventions (PascalCase for public members, camelCase for locals). +- Use 4-space indentation (see `.editorconfig`). + +### Cmdlet Design + +- **Verb-Noun naming**: Use approved PowerShell verbs (`Get-Verb` to see the list). Noun prefix is always `Pve`. +- **ShouldProcess**: All mutating cmdlets must implement `SupportsShouldProcess = true` and call `ShouldProcess()`. +- **ConfirmImpact**: Set `ConfirmImpact.High` on destructive operations (Remove, Stop, Reset). +- **OutputType**: Every cmdlet must have an `[OutputType]` attribute. +- **Pipeline support**: Use `ValueFromPipelineByPropertyName = true` on `Node`, `VmId`, and similar parameters. +- **WriteVerbose**: Add a `WriteVerbose` call describing the API operation before making API calls. +- **HelpMessage**: All `[Parameter]` attributes should include a `HelpMessage`. +- **ValidateRange**: VmId parameters should have `[ValidateRange(100, 999999999)]`. + +### Commit Convention + +This project uses [Conventional Commits](https://www.conventionalcommits.org/): + +- `feat:` -- new feature +- `fix:` -- bug fix +- `test:` -- test additions or changes +- `ci:` -- CI/CD changes +- `docs:` -- documentation changes +- `refactor:` -- code refactoring +- `chore:` -- maintenance tasks + +## Pull Request Process + +1. Fork the repository and create a feature branch from `main`. +2. Make your changes following the coding standards above. +3. Add or update tests for your changes. +4. Ensure `dotnet build` succeeds with zero warnings. +5. Ensure all existing tests pass. +6. Update `CHANGELOG.md` under `[Unreleased]` with a description of your change. +7. Submit a pull request with a clear description of the change and its motivation. + +## Adding a New Cmdlet + +1. Create the cmdlet class in the appropriate `Cmdlets/` subdirectory. +2. Create or extend a service class in `PSProxmoxVE.Core/Services/`. +3. Add model classes in `PSProxmoxVE.Core/Models/` if needed. +4. Add the cmdlet name to `CmdletsToExport` in `PSProxmoxVE.psd1`. +5. Add Pester unit tests in `tests/PSProxmoxVE.Tests/`. +6. Add integration test coverage in `Integration.Tests.ps1` if applicable. +7. Update `README.md` cmdlet reference table. + +## Reporting Issues + +- Use [GitHub Issues](https://github.com/goodolclint/PSProxmoxVE/issues) for bug reports and feature requests. +- For security vulnerabilities, see [SECURITY.md](SECURITY.md). diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..80e8eab --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,45 @@ +# Security Policy + +## Supported Versions + +| Version | Supported | +|---|---| +| 0.1.x (current) | Yes | + +## Reporting a Vulnerability + +If you discover a security vulnerability in PSProxmoxVE, please report it responsibly. + +**Do not open a public issue for security vulnerabilities.** + +Instead, please email the maintainer directly or use [GitHub's private vulnerability reporting](https://github.com/goodolclint/PSProxmoxVE/security/advisories/new). + +### What to include + +- A description of the vulnerability +- Steps to reproduce the issue +- The potential impact +- Any suggested fixes (optional) + +### Response timeline + +- **Acknowledgment**: Within 48 hours of receipt +- **Initial assessment**: Within 1 week +- **Fix release**: As soon as practical, depending on severity + +## Security Considerations + +### Credential Handling + +- PSProxmoxVE accepts credentials via `PSCredential` objects and API tokens. +- Credentials are not written to disk or included in verbose/debug output. +- Ticket-based sessions expire after 2 hours. The module detects and reports expiry. + +### TLS/HTTPS + +- All API communication uses HTTPS. +- The `-SkipCertificateCheck` parameter disables TLS certificate validation. Use only in trusted networks or test environments. + +### Dependencies + +All NuGet dependencies are pinned to specific versions. We monitor for known vulnerabilities and update promptly.