Add GitHub Copilot instruction files for PowerShell CI build system (#26253)

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: TravisEz13 <10873629+TravisEz13@users.noreply.github.com>
Co-authored-by: Travis Plunk <travis.plunk@microsoft.com>
This commit is contained in:
Copilot
2025-10-21 15:45:23 -04:00
committed by GitHub
co-authored by TravisEz13 Travis Plunk
parent dbc09a1aab
commit eeefcd7bd6
7 changed files with 392 additions and 162 deletions
@@ -0,0 +1,148 @@
---
applyTo:
- ".github/**/*.yml"
- ".github/**/*.yaml"
---
# Build and Checkout Prerequisites for PowerShell CI
This document describes the checkout and build prerequisites used in PowerShell's CI workflows. It is intended for GitHub Copilot sessions working with the build system.
## Overview
The PowerShell repository uses a standardized build process across Linux, Windows, and macOS CI workflows. Understanding the checkout configuration and the `Sync-PSTags` operation is crucial for working with the build system.
## Checkout Configuration
### Fetch Depth
All CI workflows that build or test PowerShell use `fetch-depth: 1000` in the checkout step:
```yaml
- name: checkout
uses: actions/checkout@v5
with:
fetch-depth: 1000
```
**Why 1000 commits?**
- The build system needs access to Git history to determine version information
- `Sync-PSTags` requires sufficient history to fetch and work with tags
- 1000 commits provides a reasonable balance between clone speed and having enough history for version calculation
- Shallow clones (fetch-depth: 1) would break versioning logic
**Exceptions:**
- The `changes` job uses default fetch depth (no explicit `fetch-depth`) since it only needs to detect file changes
- The `analyze` job (CodeQL) uses `fetch-depth: '0'` (full history) for comprehensive security analysis
- Linux packaging uses `fetch-depth: 0` to ensure all tags are available for package version metadata
### Workflows Using fetch-depth: 1000
- **Linux CI** (`.github/workflows/linux-ci.yml`): All build and test jobs
- **Windows CI** (`.github/workflows/windows-ci.yml`): All build and test jobs
- **macOS CI** (`.github/workflows/macos-ci.yml`): All build and test jobs
## Sync-PSTags Operation
### What is Sync-PSTags?
`Sync-PSTags` is a PowerShell function defined in `build.psm1` that ensures Git tags from the upstream PowerShell repository are synchronized to the local clone.
### Location
- **Function Definition**: `build.psm1` (line 36-76)
- **Called From**:
- `.github/actions/build/ci/action.yml` (Bootstrap step, line 24)
- `tools/ci.psm1` (Invoke-CIInstall function, line 146)
### How It Works
```powershell
Sync-PSTags -AddRemoteIfMissing
```
The function:
1. Searches for a Git remote pointing to the official PowerShell repository:
- `https://github.com/PowerShell/PowerShell`
- `git@github.com:PowerShell/PowerShell`
2. If no upstream remote exists and `-AddRemoteIfMissing` is specified:
- Adds a remote named `upstream` pointing to `https://github.com/PowerShell/PowerShell.git`
3. Fetches all tags from the upstream remote:
```bash
git fetch --tags --quiet upstream
```
4. Sets `$script:tagsUpToDate = $true` to indicate tags are synchronized
### Why Sync-PSTags is Required
Tags are critical for:
- **Version Calculation**: `Get-PSVersion` uses `git describe --abbrev=0` to find the latest tag
- **Build Numbering**: CI builds use tag-based versioning for artifacts
- **Changelog Generation**: Release notes are generated based on tags
- **Package Metadata**: Package versions are derived from Git tags
Without synchronized tags:
- Version detection would fail or return incorrect versions
- Builds might have inconsistent version numbers
- The build process would error when trying to determine the version
### Bootstrap Step in CI Action
The `.github/actions/build/ci/action.yml` includes this in the Bootstrap step:
```yaml
- name: Bootstrap
if: success()
run: |-
Write-Verbose -Verbose "Running Bootstrap..."
Import-Module .\tools\ci.psm1
Invoke-CIInstall -SkipUser
Write-Verbose -Verbose "Start Sync-PSTags"
Sync-PSTags -AddRemoteIfMissing
Write-Verbose -Verbose "End Sync-PSTags"
shell: pwsh
```
**Note**: `Sync-PSTags` is called twice:
1. Once by `Invoke-CIInstall` (in `tools/ci.psm1`)
2. Explicitly again in the Bootstrap step
This redundancy ensures tags are available even if the first call encounters issues.
## Best Practices for Copilot Sessions
When working with the PowerShell CI system:
1. **Always use `fetch-depth: 1000` or greater** when checking out code for build or test operations
2. **Understand that `Sync-PSTags` requires network access** to fetch tags from the upstream repository
3. **Don't modify the fetch-depth without understanding the impact** on version calculation
4. **If adding new CI workflows**, follow the existing pattern:
- Use `fetch-depth: 1000` for build/test jobs
- Call `Sync-PSTags -AddRemoteIfMissing` during bootstrap
- Ensure the upstream remote is properly configured
5. **For local development**, developers should:
- Have the upstream remote configured
- Run `Sync-PSTags -AddRemoteIfMissing` before building
- Or use `Start-PSBuild` which handles this automatically
## Related Files
- `.github/actions/build/ci/action.yml` - Main CI build action
- `.github/workflows/linux-ci.yml` - Linux CI workflow
- `.github/workflows/windows-ci.yml` - Windows CI workflow
- `.github/workflows/macos-ci.yml` - macOS CI workflow
- `build.psm1` - Contains Sync-PSTags function definition
- `tools/ci.psm1` - CI-specific build functions that call Sync-PSTags
## Summary
The PowerShell CI system depends on:
1. **Adequate Git history** (fetch-depth: 1000) for version calculation
2. **Synchronized Git tags** via `Sync-PSTags` for accurate versioning
3. **Upstream remote access** to fetch official repository tags
These prerequisites ensure consistent, accurate build versioning across all CI platforms.
@@ -1,3 +1,11 @@
---
applyTo:
- "build.psm1"
- "tools/ci.psm1"
- ".github/**/*.yml"
- ".github/**/*.yaml"
---
# Build Configuration Guide
## Choosing the Right Configuration
@@ -1,71 +0,0 @@
# Git Requirements for Building PowerShell
## Fetch Depth
**Required:** `fetch-depth: 1000`
The PowerShell build process uses `git describe --abbrev=60 --long` to generate version information. This requires access to git history and tags.
### Problem
Without sufficient fetch depth, builds fail with:
```
error MSB3073: The command "git describe --abbrev=60 --long" exited with code 128.
```
### Solution
Always use `fetch-depth: 1000` in the checkout step:
```yaml
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 1000
```
## Tag Synchronization
**Required:** `Sync-PSTags -AddRemoteIfMissing`
The build process needs git tags to properly version the build.
### Problem
Without tag synchronization:
- Version information is incorrect
- Build versioning fails
### Solution
Include tag synchronization in the bootstrap step:
```yaml
- name: Bootstrap
shell: pwsh
run: |
Import-Module ./tools/ci.psm1
Sync-PSTags -AddRemoteIfMissing
```
## Complete Example
```yaml
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 1000
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
global-json-file: ./global.json
- name: Bootstrap
shell: pwsh
run: |
Import-Module ./tools/ci.psm1
Invoke-CIInstall -SkipUser
Sync-PSTags -AddRemoteIfMissing
```
@@ -0,0 +1,220 @@
---
applyTo:
- ".github/instructions/**/*.instructions.md"
---
# Instruction File Format Guide
This document describes the format and guidelines for creating custom instruction files for GitHub Copilot in the PowerShell repository.
## File Naming Convention
All instruction files must use the `.instructions.md` suffix:
- ✅ Correct: `build-checkout-prerequisites.instructions.md`
- ✅ Correct: `start-psbuild-basics.instructions.md`
- ❌ Incorrect: `build-guide.md`
- ❌ Incorrect: `instructions.md`
## Required Frontmatter
Every instruction file must start with YAML frontmatter containing an `applyTo` section:
```yaml
---
applyTo:
- "path/to/files/**/*.ext"
- "specific-file.ext"
---
```
### applyTo Patterns
Specify which files or directories these instructions apply to:
**For workflow files:**
```yaml
applyTo:
- ".github/**/*.yml"
- ".github/**/*.yaml"
```
**For build scripts:**
```yaml
applyTo:
- "build.psm1"
- "tools/ci.psm1"
```
**For multiple contexts:**
```yaml
applyTo:
- "build.psm1"
- "tools/**/*.psm1"
- ".github/**/*.yml"
```
## Content Structure
### 1. Clear Title
Use a descriptive H1 heading after the frontmatter:
```markdown
# Build Configuration Guide
```
### 2. Purpose or Overview
Start with a brief explanation of what the instructions cover:
```markdown
## Purpose
This guide explains how to configure PowerShell builds for different scenarios.
```
### 3. Actionable Content
Provide clear, actionable guidance:
**✅ Good - Specific and actionable:**
```markdown
## Default Usage
Use `Start-PSBuild` with no parameters for testing:
```powershell
Import-Module ./tools/ci.psm1
Start-PSBuild
```
```
**❌ Bad - Vague and unclear:**
```markdown
## Usage
You can use Start-PSBuild to build stuff.
```
### 4. Code Examples
Include working code examples with proper syntax highlighting:
```markdown
```yaml
- name: Build PowerShell
shell: pwsh
run: |
Import-Module ./tools/ci.psm1
Start-PSBuild
```
```
### 5. Context and Rationale
Explain why things are done a certain way:
```markdown
**Why fetch-depth: 1000?**
- The build system needs Git history for version calculation
- Shallow clones would break versioning logic
```
## Best Practices
### Be Concise
- Focus on essential information
- Remove redundant explanations
- Use bullet points for lists
### Be Specific
- Provide exact commands and parameters
- Include file paths and line numbers when relevant
- Show concrete examples, not abstract concepts
### Avoid Duplication
- Don't repeat information from other instruction files
- Reference other files when appropriate
- Keep each file focused on one topic
### Use Proper Formatting
**Headers:**
- Use H1 (`#`) for the main title
- Use H2 (`##`) for major sections
- Use H3 (`###`) for subsections
**Code blocks:**
- Always specify the language: ` ```yaml `, ` ```powershell `, ` ```bash `
- Keep examples short and focused
- Test examples before including them
**Lists:**
- Use `-` for unordered lists
- Use `1.` for ordered lists
- Keep list items concise
## Example Structure
```markdown
---
applyTo:
- "relevant/files/**/*.ext"
---
# Title of Instructions
Brief description of what these instructions cover.
## Section 1
Content with examples.
```language
code example
```
## Section 2
More specific guidance.
### Subsection
Detailed information when needed.
## Best Practices
- Actionable tip 1
- Actionable tip 2
```
## Maintaining Instructions
### When to Create a New File
Create a new instruction file when:
- Covering a distinct topic not addressed elsewhere
- The content is substantial enough to warrant its own file
- The `applyTo` scope is different from existing files
### When to Update an Existing File
Update an existing file when:
- Information is outdated
- New best practices emerge
- Examples need correction
### When to Merge or Delete
Merge or delete files when:
- Content is duplicated across multiple files
- A file is too small to be useful standalone
- Information is no longer relevant
## Reference
For more details, see:
- [GitHub Copilot Custom Instructions Documentation](https://docs.github.com/en/copilot/how-tos/configure-custom-instructions/add-repository-instructions)
@@ -1,3 +1,11 @@
---
applyTo:
- "build.psm1"
- "tools/ci.psm1"
- ".github/**/*.yml"
- ".github/**/*.yaml"
---
# Start-PSBuild Basics
## Purpose
@@ -1,3 +1,11 @@
---
applyTo:
- "build.psm1"
- "tools/ci.psm1"
- ".github/**/*.yml"
- ".github/**/*.yaml"
---
# Troubleshooting Build Issues
## Git Describe Error
@@ -1,91 +0,0 @@
# Workflow Prerequisites for Building PowerShell
## Required Steps Before Start-PSBuild
These steps must run before calling `Start-PSBuild`:
### 1. Checkout
```yaml
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 1000 # Required for version generation
```
### 2. Setup .NET
```yaml
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
global-json-file: ./global.json
```
### 3. Bootstrap
```yaml
- name: Bootstrap
shell: pwsh
run: |
Import-Module ./tools/ci.psm1
Invoke-CIInstall -SkipUser
Sync-PSTags -AddRemoteIfMissing
```
## Complete Prerequisites Example
```yaml
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 1000
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
global-json-file: ./global.json
- name: Bootstrap
shell: pwsh
run: |
Import-Module ./tools/ci.psm1
Invoke-CIInstall -SkipUser
Sync-PSTags -AddRemoteIfMissing
- name: Build PowerShell
shell: pwsh
run: |
Import-Module ./tools/ci.psm1
Start-PSBuild
```
## Why Each Step Matters
**Checkout with fetch-depth:**
- Build needs git history for versioning
- Without it: `git describe` fails
**Setup .NET:**
- Provides SDK for building
- Uses version from global.json
**Bootstrap:**
- Installs dependencies
- Syncs git tags
- Prepares build environment
## Optional Steps
### Environment Capture (Debugging)
```yaml
- name: Capture Environment
run: |
Get-ChildItem -Path env: | Out-String -width 9999 -Stream | Write-Verbose -Verbose
shell: pwsh
```