diff --git a/.github/agents/Documentation.md b/.github/agents/Documentation.md new file mode 100644 index 000000000..c41ba3f8d --- /dev/null +++ b/.github/agents/Documentation.md @@ -0,0 +1,8 @@ +# Documentation Rules + +## Important (Should Flag) + +1. **Missing RELEASENOTES update**: User-facing changes without a release note entry +1. **Missing documentation for new settings**: New or changed AL-Go settings must be documented in `Scenarios/settings.md` (including purpose, type, default/required status, and which templates/workflows honor them) and represented in the settings schema (`Actions/.Modules/settings.schema.json`) with matching descriptions and correct metadata (`type`, `enum`, `default`, `required`). +1. **Missing documentation for new functions**: New public functions (exported from modules or used as entry points) should include comment-based help (e.g., `.SYNOPSIS`, `.DESCRIPTION`, parameter help) and be described in relevant markdown documentation when they are part of the public surface. +1. **Missing documentation for new workflows or user-facing behaviors**: New or significantly changed workflows/templates in `Templates/` must have corresponding scenario documentation (or updates) in `Scenarios/`, and new user-facing commands or actions must be documented in scenarios or `README.md`. diff --git a/.github/agents/Security.md b/.github/agents/Security.md new file mode 100644 index 000000000..445743d0c --- /dev/null +++ b/.github/agents/Security.md @@ -0,0 +1,9 @@ +# Security Rules + +## Critical (Must Flag) + +1. **Missing error handling**: Scripts must start with `$errorActionPreference = "Stop"; $ProgressPreference = "SilentlyContinue"; Set-StrictMode -Version 2.0` +1. **Secret leakage**: Any path where a secret value could appear in logs, error messages, or output without being masked via `::add-mask::` +1. **Path traversal**: File operations that don't validate paths stay within the workspace +1. **Missing `-recurse` on ConvertTo-HashTable**: After `ConvertFrom-Json`, always chain `| ConvertTo-HashTable -recurse` for case-insensitive access +1. **Deprecated settings**: Flag usage of settings listed in `DEPRECATIONS.md` diff --git a/.github/agents/Style.md b/.github/agents/Style.md new file mode 100644 index 000000000..2b51743f2 --- /dev/null +++ b/.github/agents/Style.md @@ -0,0 +1,13 @@ +# Style Rules + +## Important (Should Flag) + +1. **Missing tests**: New or modified functions should have corresponding Pester tests in `Tests/` +1. **Cross-platform issues**: Hardcoded path separators, PS5-only or PS7-only constructs +1. **Encoding omissions**: File read/write without explicit `-Encoding UTF8` +1. **YAML permissions**: Workflows without minimal permission declarations + +## Informational (May Flag) + +1. Opportunities to use existing helper functions from `AL-Go-Helper.ps1` or shared modules +1. Inconsistent naming (should be PascalCase functions, camelCase variables) diff --git a/.github/agents/code-review.agent.md b/.github/agents/code-review.agent.md new file mode 100644 index 000000000..31921a9e1 --- /dev/null +++ b/.github/agents/code-review.agent.md @@ -0,0 +1,42 @@ +# AL-Go Code Review Agent + +You are a code review agent specialized in the AL-Go for GitHub repository. Your role is to review pull requests for correctness, security, and adherence to AL-Go conventions. + +## Your Expertise + +You are an expert in: + +- PowerShell scripting (PS5 and PS7 compatibility) +- GitHub Actions workflows (YAML) +- Business Central extension development patterns +- AL-Go's architecture: actions in `Actions/`, reusable workflows in `Templates/`, tests in `Tests/` + +## Review Focus Areas + +Detailed rules are organized in separate files: + +- **[Security.md](./Security.md)** — Critical rules: error handling, secret leakage, path traversal, JSON handling, deprecated settings +- **[Style.md](./Style.md)** — Style/quality rules: tests, cross-platform, encoding, YAML permissions, naming conventions +- **[Documentation.md](./Documentation.md)** — Documentation rules: RELEASENOTES, settings docs, function docs, workflow/scenario docs + +## How to Review + +When reviewing changes: + +1. Read the PR description to understand intent +1. Check each changed file against the critical and important rules in [Security.md](./Security.md) and [Style.md](./Style.md) +1. Verify that test coverage exists for logic changes +1. Check for deprecated setting usage against `DEPRECATIONS.md`, and ensure any deprecations are documented there with clear replacement guidance and reflected in settings documentation/schema descriptions. +1. Validate that workflows follow the existing patterns in `Templates/` +1. Confirm that any new or modified settings are both documented and added to the schema, with aligned descriptions and correct metadata (type/default/enum/required). See [Documentation.md](./Documentation.md). +1. Confirm that new public functions have appropriate documentation, including accurate comment-based help (parameter names and descriptions kept in sync with the implementation). +1. Confirm that new or significantly changed workflows/templates and other user-facing behaviors are documented in the appropriate scenario files and/or `README.md`, and that any breaking changes are called out in `RELEASENOTES.md`. + +## Key Repository Knowledge + +- **Settings reference**: `Scenarios/settings.md` describes all AL-Go settings +- **Settings schema**: `Actions/.Modules/settings.schema.json` defines the JSON schema for AL-Go settings +- **Action pattern**: Each action lives in `Actions//` with an `action.yaml` and PowerShell scripts +- **Template workflows**: `Templates/Per Tenant Extension/` and `Templates/AppSource App/` contain the workflow templates shipped to users +- **Shared modules**: `Actions/.Modules/` contains reusable PowerShell modules +- **Security checks**: `Actions/VerifyPRChanges/` validates that fork PRs don't modify protected files (.ps1, .psm1, .yml, .yaml, CODEOWNERS) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 000000000..dccaddf65 --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,111 @@ +# Copilot Instructions for AL-Go + +## Project Overview + +AL-Go for GitHub is a set of GitHub Actions and Templates for building, testing, and deploying Business Central extensions using GitHub workflows. It consists of PowerShell actions, reusable YAML workflows, and Pester-based unit tests. + +## PowerShell Conventions + +### Error Handling + +- Every action script must start with the standard header: + ```powershell + $errorActionPreference = "Stop"; $ProgressPreference = "SilentlyContinue"; Set-StrictMode -Version 2.0 + ``` +- Use `try/catch/finally` with structured error propagation. +- Check `$LASTEXITCODE` after running external commands. +- Use `Write-Host "::Error::"` for GitHub Actions error annotations. +- Use `Write-Host "::Warning::"` for non-blocking warnings. + +### JSON Processing + +- Always use `ConvertTo-HashTable -recurse` after `ConvertFrom-Json` to ensure nested objects and arrays are converted to hashtables for consistent access. +- Always specify `-Encoding UTF8` when reading or writing JSON files. + +### Function Declarations + +- Use PascalCase for function names and camelCase for variables. + +### Module Loading + +- Import modules with explicit paths: `Join-Path $PSScriptRoot` pattern. +- Use `-Force -DisableNameChecking` for re-imports. + +## Security Patterns + +### Secret Handling + +- Mask secrets with `Write-Host "::add-mask::$secret"` before any output. +- Never log raw secrets; use clean/placeholder URLs in error messages. +- Be aware that secrets in URLs use `${{ secretName }}` syntax — replacement is done before use. +- URL-encode secret values when injecting into URLs. + +### Input Sanitization + +- Sanitize filenames using `[System.IO.Path]::GetInvalidFileNameChars()`. +- Check for path traversal using `Test-PathWithinWorkspace` or equivalent. +- Sanitize container names with `-replace "[^a-z0-9\-]"`. + +### Authentication + +- Never hardcode credentials or tokens in source code. +- Use GitHub secrets or Azure KeyVault for credential storage. + +## YAML Workflow Conventions + +- Declare minimal required permissions (e.g., `contents: read`, `actions: read`). +- Use `defaults.run.shell: pwsh` for cross-platform compatibility. +- Prefix internal environment variables with `_` to distinguish from GitHub context. +- Use `${{ needs.JobName.outputs.key }}` for cross-job communication. +- Add `::Notice::` steps when conditionally skipping workflow steps. + +## Testing Requirements + +- All new functions must have Pester unit tests in the `Tests/` folder. +- Test files follow the naming convention `*.Test.ps1`. +- Use `Describe`/`It` blocks with descriptive names. +- Mock external dependencies to isolate units under test. +- Tests must pass on both Windows (PowerShell 5) and Linux (PowerShell 7). +- Use `InModuleScope` for testing private module functions. + +## Documentation Requirements + +- All new or modified AL-Go settings must be: + - Documented in `Scenarios/settings.md` with a clear description, type, default/required status, valid values (e.g., enum), and which templates/workflows honor the setting. + - Added or updated in the settings schema (`Actions/.Modules/settings.schema.json`) with aligned `description`, `type`, `enum`, `default`, and `required` metadata. + - Marked as deprecated in both `Scenarios/settings.md` and the schema description when applicable, with guidance on the replacement setting, and listed in `DEPRECATIONS.md`. +- New public functions (in `.ps1` / `.psm1` files, or used as entry points from workflows) should include comment-based help with at least `.SYNOPSIS` and, when appropriate, `.DESCRIPTION`, `.PARAMETER`, and `.EXAMPLE` blocks. Parameter names and descriptions in the help should stay in sync with the function signature. +- When adding new user-facing behaviors, workflows, or commands: + - Update the relevant scenario(s) under `Scenarios/` or the appropriate `README.md` so users can discover and understand the change. + - Call out breaking changes and notable new capabilities in `RELEASENOTES.md`. + +## Deprecated Features + +Before using or accepting settings, check `DEPRECATIONS.md` for deprecated settings: + +- `unusedALGoSystemFiles` → use `customALGoFiles.filesToExclude` +- `alwaysBuildAllProjects` → use `incrementalBuilds.onPull_Request` +- `Schedule` → use `workflowSchedule` with conditional settings +- `cleanModePreprocessorSymbols` → use `preprocessorSymbols` with conditional settings + +## Cross-Platform Considerations + +- Use `[System.IO.Path]::DirectorySeparatorChar` instead of hardcoded separators. +- Account for PowerShell 5 vs 7 differences (e.g., encoding parameters, `$IsWindows`). +- Use `Replace('\', '/')` for path normalization in URLs and artifact names. + +## Pull Request Checklist + +When reviewing PRs, verify: + +- [ ] Standard error handling header is present in new scripts +- [ ] Secrets are masked before any output +- [ ] JSON is converted with `ConvertTo-HashTable -recurse` +- [ ] File encoding is explicitly specified +- [ ] Unit tests are added or updated +- [ ] RELEASENOTES.md is updated for user-facing changes +- [ ] No deprecated settings are introduced +- [ ] YAML workflows declare minimal permissions +- [ ] Cross-platform compatibility is maintained +- [ ] New or changed settings are documented in `Scenarios/settings.md` and reflected in `Actions/.Modules/settings.schema.json` with consistent metadata +- [ ] New public functions have appropriate comment-based help and any new workflows/user-facing behaviors are documented in scenarios/READMEs