diff --git a/.github/actions/build/ci/action.yml b/.github/actions/build/ci/action.yml
index 93adaf6b17a..be9c0ecd20b 100644
--- a/.github/actions/build/ci/action.yml
+++ b/.github/actions/build/ci/action.yml
@@ -5,7 +5,9 @@ runs:
steps:
- name: Capture Environment
if: success() || failure()
- run: 'Get-ChildItem -Path env: | Out-String -width 9999 -Stream | write-Verbose -Verbose'
+ run: |-
+ Import-Module .\tools\ci.psm1
+ Show-Environment
shell: pwsh
- name: Set Build Name for Non-PR
if: github.event_name != 'PullRequest'
@@ -31,22 +33,8 @@ runs:
Import-Module .\tools\ci.psm1
Invoke-CIBuild
shell: pwsh
- - name: xUnit Tests
- if: success()
- continue-on-error: true
- run: |-
- Write-Verbose -Verbose "Running xUnit tests..."
- Import-Module .\tools\ci.psm1
- Restore-PSOptions
- Invoke-CIxUnit -SkipFailing
- shell: pwsh
- name: Upload build artifact
uses: actions/upload-artifact@v4
with:
name: build
path: ${{ runner.workspace }}/build
- - name: Upload xunit artifact
- uses: actions/upload-artifact@v4
- with:
- name: testResults-xunit
- path: ${{ runner.workspace }}/xunit
diff --git a/.github/actions/infrastructure/get-changed-files/README.md b/.github/actions/infrastructure/get-changed-files/README.md
new file mode 100644
index 00000000000..277b28c0674
--- /dev/null
+++ b/.github/actions/infrastructure/get-changed-files/README.md
@@ -0,0 +1,122 @@
+# Get Changed Files Action
+
+A reusable composite action that retrieves the list of files changed in a pull request or push event.
+
+## Features
+
+- Supports both `pull_request` and `push` events
+- Optional filtering by file pattern
+- Returns files as JSON array for easy consumption
+- Filters out deleted files (only returns added, modified, or renamed files)
+- Handles up to 100 changed files per request
+
+## Usage
+
+### Basic Usage (Pull Requests Only)
+
+```yaml
+- name: Get changed files
+ id: changed-files
+ uses: "./.github/actions/infrastructure/get-changed-files"
+
+- name: Process files
+ run: |
+ echo "Changed files: ${{ steps.changed-files.outputs.files }}"
+ echo "Count: ${{ steps.changed-files.outputs.count }}"
+```
+
+### With Filtering
+
+```yaml
+# Get only markdown files
+- name: Get changed markdown files
+ id: changed-md
+ uses: "./.github/actions/infrastructure/get-changed-files"
+ with:
+ filter: '*.md'
+
+# Get only GitHub workflow/action files
+- name: Get changed GitHub files
+ id: changed-github
+ uses: "./.github/actions/infrastructure/get-changed-files"
+ with:
+ filter: '.github/'
+```
+
+### Support Both PR and Push Events
+
+```yaml
+- name: Get changed files
+ id: changed-files
+ uses: "./.github/actions/infrastructure/get-changed-files"
+ with:
+ event-types: 'pull_request,push'
+```
+
+## Inputs
+
+| Name | Description | Required | Default |
+|------|-------------|----------|---------|
+| `filter` | Optional filter pattern (e.g., `*.md` for markdown files, `.github/` for GitHub files) | No | `''` |
+| `event-types` | Comma-separated list of event types to support (`pull_request`, `push`) | No | `pull_request` |
+
+## Outputs
+
+| Name | Description |
+|------|-------------|
+| `files` | JSON array of changed file paths |
+| `count` | Number of changed files |
+
+## Filter Patterns
+
+The action supports simple filter patterns:
+
+- **Extension matching**: Use `*.ext` to match files with a specific extension
+ - Example: `*.md` matches all markdown files
+ - Example: `*.yml` matches all YAML files
+
+- **Path prefix matching**: Use a path prefix to match files in a directory
+ - Example: `.github/` matches all files in the `.github` directory
+ - Example: `tools/` matches all files in the `tools` directory
+
+## Example: Processing Changed Files
+
+```yaml
+- name: Get changed files
+ id: changed-files
+ uses: "./.github/actions/infrastructure/get-changed-files"
+
+- name: Process each file
+ shell: pwsh
+ env:
+ CHANGED_FILES: ${{ steps.changed-files.outputs.files }}
+ run: |
+ $changedFilesJson = $env:CHANGED_FILES
+ $changedFiles = $changedFilesJson | ConvertFrom-Json
+
+ foreach ($file in $changedFiles) {
+ Write-Host "Processing: $file"
+ # Your processing logic here
+ }
+```
+
+## Limitations
+
+- Simple filter patterns only (no complex glob or regex patterns)
+
+## Pagination
+
+The action automatically handles pagination to fetch **all** changed files in a PR, regardless of how many files were changed:
+
+- Fetches files in batches of 100 per page
+- Continues fetching until all files are retrieved
+- Logs a note when pagination occurs, showing the total file count
+- **No file limit** - all changed files will be processed, even in very large PRs
+
+This ensures that critical workflows (such as merge conflict checking, link validation, etc.) don't miss files due to pagination limits.
+
+## Related Actions
+
+- **markdownlinks**: Uses this pattern to get changed markdown files
+- **merge-conflict-checker**: Uses this pattern to get changed files for conflict detection
+- **path-filters**: Similar functionality but with more complex filtering logic
diff --git a/.github/actions/infrastructure/get-changed-files/action.yml b/.github/actions/infrastructure/get-changed-files/action.yml
new file mode 100644
index 00000000000..c897d4f388d
--- /dev/null
+++ b/.github/actions/infrastructure/get-changed-files/action.yml
@@ -0,0 +1,117 @@
+name: 'Get Changed Files'
+description: 'Gets the list of files changed in a pull request or push event'
+inputs:
+ filter:
+ description: 'Optional filter pattern (e.g., "*.md" for markdown files, ".github/" for GitHub files)'
+ required: false
+ default: ''
+ event-types:
+ description: 'Comma-separated list of event types to support (pull_request, push)'
+ required: false
+ default: 'pull_request'
+outputs:
+ files:
+ description: 'JSON array of changed file paths'
+ value: ${{ steps.get-files.outputs.files }}
+ count:
+ description: 'Number of changed files'
+ value: ${{ steps.get-files.outputs.count }}
+runs:
+ using: 'composite'
+ steps:
+ - name: Get changed files
+ id: get-files
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const eventTypes = '${{ inputs.event-types }}'.split(',').map(t => t.trim());
+ const filter = '${{ inputs.filter }}';
+ let changedFiles = [];
+
+ if (eventTypes.includes('pull_request') && context.eventName === 'pull_request') {
+ console.log(`Getting files changed in PR #${context.payload.pull_request.number}`);
+
+ // Fetch all files changed in the PR with pagination
+ let allFiles = [];
+ let page = 1;
+ let fetchedCount;
+
+ do {
+ const { data: files } = await github.rest.pulls.listFiles({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ pull_number: context.payload.pull_request.number,
+ per_page: 100,
+ page: page
+ });
+
+ allFiles = allFiles.concat(files);
+ fetchedCount = files.length;
+ page++;
+ } while (fetchedCount === 100);
+
+ if (allFiles.length >= 100) {
+ console.log(`Note: This PR has ${allFiles.length} changed files. All files fetched using pagination.`);
+ }
+
+ changedFiles = allFiles
+ .filter(file => file.status === 'added' || file.status === 'modified' || file.status === 'renamed')
+ .map(file => file.filename);
+
+ } else if (eventTypes.includes('push') && context.eventName === 'push') {
+ console.log(`Getting files changed in push to ${context.ref}`);
+
+ const { data: comparison } = await github.rest.repos.compareCommits({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ base: context.payload.before,
+ head: context.payload.after,
+ });
+
+ changedFiles = comparison.files
+ .filter(file => file.status === 'added' || file.status === 'modified' || file.status === 'renamed')
+ .map(file => file.filename);
+
+ } else {
+ core.setFailed(`Unsupported event type: ${context.eventName}. Supported types: ${eventTypes.join(', ')}`);
+ return;
+ }
+
+ // Apply filter if provided
+ if (filter) {
+ const filterLower = filter.toLowerCase();
+ const beforeFilter = changedFiles.length;
+ changedFiles = changedFiles.filter(file => {
+ const fileLower = file.toLowerCase();
+ // Support simple patterns like "*.md" or ".github/"
+ if (filterLower.startsWith('*.')) {
+ const ext = filterLower.substring(1);
+ return fileLower.endsWith(ext);
+ } else {
+ return fileLower.startsWith(filterLower);
+ }
+ });
+ console.log(`Filter '${filter}' applied: ${beforeFilter} → ${changedFiles.length} files`);
+ }
+
+ // Calculate simple hash for verification
+ const crypto = require('crypto');
+ const filesJson = JSON.stringify(changedFiles.sort());
+ const hash = crypto.createHash('sha256').update(filesJson).digest('hex').substring(0, 8);
+
+ // Log changed files in a collapsible group
+ core.startGroup(`Changed Files (${changedFiles.length} total, hash: ${hash})`);
+ if (changedFiles.length > 0) {
+ changedFiles.forEach(file => console.log(` - ${file}`));
+ } else {
+ console.log(' (no files changed)');
+ }
+ core.endGroup();
+
+ console.log(`Found ${changedFiles.length} changed files`);
+ core.setOutput('files', JSON.stringify(changedFiles));
+ core.setOutput('count', changedFiles.length);
+
+branding:
+ icon: 'file-text'
+ color: 'blue'
diff --git a/.github/actions/infrastructure/markdownlinks/Parse-MarkdownLink.ps1 b/.github/actions/infrastructure/markdownlinks/Parse-MarkdownLink.ps1
new file mode 100644
index 00000000000..a56d696eb6e
--- /dev/null
+++ b/.github/actions/infrastructure/markdownlinks/Parse-MarkdownLink.ps1
@@ -0,0 +1,182 @@
+# Copyright (c) Microsoft Corporation.
+# Licensed under the MIT License.
+
+#requires -version 7
+# Markdig is always available in PowerShell 7
+<#
+.SYNOPSIS
+ Parse CHANGELOG files using Markdig to extract links.
+
+.DESCRIPTION
+ This script uses Markdig.Markdown.Parse to parse all markdown files in the CHANGELOG directory
+ and extract different types of links (inline links, reference links, etc.).
+
+.PARAMETER ChangelogPath
+ Path to the CHANGELOG directory. Defaults to ./CHANGELOG
+
+.PARAMETER LinkType
+ Filter by link type: All, Inline, Reference, AutoLink. Defaults to All.
+
+.EXAMPLE
+ .\Parse-MarkdownLink.ps1
+
+.EXAMPLE
+ .\Parse-MarkdownLink.ps1 -LinkType Reference
+#>
+
+param(
+ [string]$ChangelogPath = "./CHANGELOG",
+ [ValidateSet("All", "Inline", "Reference", "AutoLink")]
+ [string]$LinkType = "All"
+)
+
+Write-Verbose "Using built-in Markdig functionality to parse markdown files"
+
+function Get-LinksFromMarkdownAst {
+ param(
+ [Parameter(Mandatory)]
+ [object]$Node,
+ [Parameter(Mandatory)]
+ [string]$FileName,
+ [System.Collections.ArrayList]$Links
+ )
+
+ if ($null -eq $Links) {
+ return
+ }
+
+ # Check if current node is a link
+ if ($Node -is [Markdig.Syntax.Inlines.LinkInline]) {
+ $linkInfo = [PSCustomObject]@{
+ Path = $FileName
+ Line = $Node.Line + 1 # Convert to 1-based line numbering
+ Column = $Node.Column + 1 # Convert to 1-based column numbering
+ Url = $Node.Url ?? ""
+ Text = $Node.FirstChild?.ToString() ?? ""
+ Type = "Inline"
+ IsImage = $Node.IsImage
+ }
+ [void]$Links.Add($linkInfo)
+ }
+ elseif ($Node -is [Markdig.Syntax.Inlines.AutolinkInline]) {
+ $linkInfo = [PSCustomObject]@{
+ Path = $FileName
+ Line = $Node.Line + 1
+ Column = $Node.Column + 1
+ Url = $Node.Url ?? ""
+ Text = $Node.Url ?? ""
+ Type = "AutoLink"
+ IsImage = $false
+ }
+ [void]$Links.Add($linkInfo)
+ }
+ elseif ($Node -is [Markdig.Syntax.LinkReferenceDefinitionGroup]) {
+ foreach ($refDef in $Node) {
+ $linkInfo = [PSCustomObject]@{
+ Path = $FileName
+ Line = $refDef.Line + 1
+ Column = $refDef.Column + 1
+ Url = $refDef.Url ?? ""
+ Text = $refDef.Label ?? ""
+ Type = "Reference"
+ IsImage = $false
+ }
+ [void]$Links.Add($linkInfo)
+ }
+ }
+ elseif ($Node -is [Markdig.Syntax.LinkReferenceDefinition]) {
+ $linkInfo = [PSCustomObject]@{
+ Path = $FileName
+ Line = $Node.Line + 1
+ Column = $Node.Column + 1
+ Url = $Node.Url ?? ""
+ Text = $Node.Label ?? ""
+ Type = "Reference"
+ IsImage = $false
+ }
+ [void]$Links.Add($linkInfo)
+ }
+
+ # For MarkdownDocument (root), iterate through all blocks
+ if ($Node -is [Markdig.Syntax.MarkdownDocument]) {
+ foreach ($block in $Node) {
+ Get-LinksFromMarkdownAst -Node $block -FileName $FileName -Links $Links
+ }
+ }
+ # For block containers, iterate through children
+ elseif ($Node -is [Markdig.Syntax.ContainerBlock]) {
+ foreach ($child in $Node) {
+ Get-LinksFromMarkdownAst -Node $child -FileName $FileName -Links $Links
+ }
+ }
+ # For leaf blocks with inlines, process the inline content
+ elseif ($Node -is [Markdig.Syntax.LeafBlock] -and $Node.Inline) {
+ Get-LinksFromMarkdownAst -Node $Node.Inline -FileName $FileName -Links $Links
+ }
+ # For inline containers, process all child inlines
+ elseif ($Node -is [Markdig.Syntax.Inlines.ContainerInline]) {
+ $child = $Node.FirstChild
+ while ($child) {
+ Get-LinksFromMarkdownAst -Node $child -FileName $FileName -Links $Links
+ $child = $child.NextSibling
+ }
+ }
+ # For other inline elements that might have children
+ elseif ($Node.PSObject.Properties.Name -contains "FirstChild" -and $Node.FirstChild) {
+ $child = $Node.FirstChild
+ while ($child) {
+ Get-LinksFromMarkdownAst -Node $child -FileName $FileName -Links $Links
+ $child = $child.NextSibling
+ }
+ }
+}
+
+function Parse-ChangelogFiles {
+ param(
+ [string]$Path
+ )
+
+ if (-not (Test-Path $Path)) {
+ Write-Error "CHANGELOG directory not found: $Path"
+ return
+ }
+
+ $markdownFiles = Get-ChildItem -Path $Path -Filter "*.md" -File
+
+ if ($markdownFiles.Count -eq 0) {
+ Write-Warning "No markdown files found in $Path"
+ return
+ }
+
+ $allLinks = [System.Collections.ArrayList]::new()
+
+ foreach ($file in $markdownFiles) {
+ Write-Verbose "Processing file: $($file.Name)"
+
+ try {
+ $content = Get-Content -Path $file.FullName -Raw -Encoding UTF8
+
+ # Parse the markdown content using Markdig
+ $document = [Markdig.Markdown]::Parse($content, [Markdig.MarkdownPipelineBuilder]::new())
+
+ # Extract links from the AST
+ Get-LinksFromMarkdownAst -Node $document -FileName $file.FullName -Links $allLinks
+
+ } catch {
+ Write-Warning "Error processing file $($file.Name): $($_.Exception.Message)"
+ }
+ }
+
+ # Filter by link type if specified
+ if ($LinkType -ne "All") {
+ $allLinks = $allLinks | Where-Object { $_.Type -eq $LinkType }
+ }
+
+ return $allLinks
+}
+
+# Main execution
+$links = Parse-ChangelogFiles -Path $ChangelogPath
+
+# Output PowerShell objects
+$links
diff --git a/.github/actions/infrastructure/markdownlinks/README.md b/.github/actions/infrastructure/markdownlinks/README.md
new file mode 100644
index 00000000000..e566ec2bcc3
--- /dev/null
+++ b/.github/actions/infrastructure/markdownlinks/README.md
@@ -0,0 +1,177 @@
+# Verify Markdown Links Action
+
+A GitHub composite action that verifies all links in markdown files using PowerShell and Markdig.
+
+## Features
+
+- ✅ Parses markdown files using Markdig (built into PowerShell 7)
+- ✅ Extracts all link types: inline links, reference links, and autolinks
+- ✅ Verifies HTTP/HTTPS links with configurable timeouts and retries
+- ✅ Validates local file references
+- ✅ Supports excluding specific URL patterns
+- ✅ Provides detailed error reporting with file locations
+- ✅ Outputs metrics for CI/CD integration
+
+## Usage
+
+### Basic Usage
+
+```yaml
+- name: Verify Markdown Links
+ uses: ./.github/actions/infrastructure/markdownlinks
+ with:
+ path: './CHANGELOG'
+```
+
+### Advanced Usage
+
+```yaml
+- name: Verify Markdown Links
+ uses: ./.github/actions/infrastructure/markdownlinks
+ with:
+ path: './docs'
+ fail-on-error: 'true'
+ timeout: 30
+ max-retries: 2
+ exclude-patterns: '*.example.com/*,*://localhost/*'
+```
+
+### With Outputs
+
+```yaml
+- name: Verify Markdown Links
+ id: verify-links
+ uses: ./.github/actions/infrastructure/markdownlinks
+ with:
+ path: './CHANGELOG'
+ fail-on-error: 'false'
+
+- name: Display Results
+ run: |
+ echo "Total links: ${{ steps.verify-links.outputs.total-links }}"
+ echo "Passed: ${{ steps.verify-links.outputs.passed-links }}"
+ echo "Failed: ${{ steps.verify-links.outputs.failed-links }}"
+ echo "Skipped: ${{ steps.verify-links.outputs.skipped-links }}"
+```
+
+## Inputs
+
+| Input | Description | Required | Default |
+|-------|-------------|----------|---------|
+| `path` | Path to the directory containing markdown files to verify | No | `./CHANGELOG` |
+| `exclude-patterns` | Comma-separated list of URL patterns to exclude from verification | No | `''` |
+| `fail-on-error` | Whether to fail the action if any links are broken | No | `true` |
+| `timeout` | Timeout in seconds for HTTP requests | No | `30` |
+| `max-retries` | Maximum number of retries for failed requests | No | `2` |
+
+## Outputs
+
+| Output | Description |
+|--------|-------------|
+| `total-links` | Total number of unique links checked |
+| `passed-links` | Number of links that passed verification |
+| `failed-links` | Number of links that failed verification |
+| `skipped-links` | Number of links that were skipped |
+
+## Excluded Link Types
+
+The action automatically skips the following link types:
+
+- **Anchor links** (`#section-name`) - Would require full markdown parsing
+- **Email links** (`mailto:user@example.com`) - Cannot be verified without sending email
+
+## GitHub Workflow Test
+
+This section provides a workflow example and instructions for testing the link verification action.
+
+### Testing the Workflow
+
+To test that the workflow properly detects broken links:
+
+1. Make change to this file (e.g., this README.md file already contains one in the [Broken Link Test](#broken-link-test) section)
+1. The workflow will run and should fail, reporting the broken link(s)
+1. Revert your change to this file
+1. Push again to verify the workflow passes
+
+### Example Workflow Configuration
+
+```yaml
+name: Verify Links
+
+on:
+ push:
+ branches: [ main ]
+ paths:
+ - '**/*.md'
+ pull_request:
+ branches: [ main ]
+ paths:
+ - '**/*.md'
+ schedule:
+ # Run weekly to catch external link rot
+ - cron: '0 0 * * 0'
+
+jobs:
+ verify-links:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Verify CHANGELOG Links
+ uses: ./.github/actions/infrastructure/markdownlinks
+ with:
+ path: './CHANGELOG'
+ fail-on-error: 'true'
+
+ - name: Verify Documentation Links
+ uses: ./.github/actions/infrastructure/markdownlinks
+ with:
+ path: './docs'
+ fail-on-error: 'false'
+ exclude-patterns: '*.internal.example.com/*'
+```
+
+## How It Works
+
+1. **Parse Markdown**: Uses `Parse-MarkdownLink.ps1` to extract all links from markdown files using Markdig
+2. **Deduplicate**: Groups links by URL to avoid checking the same link multiple times
+3. **Verify Links**:
+ - HTTP/HTTPS links: Makes HEAD/GET requests with configurable timeout and retries
+ - Local file references: Checks if the file exists relative to the markdown file
+ - Excluded patterns: Skips links matching the exclude patterns
+4. **Report Results**: Displays detailed results with file locations for failed links
+5. **Set Outputs**: Provides metrics for downstream steps
+
+## Error Output Example
+
+```
+✗ FAILED: https://example.com/broken-link - HTTP 404
+ Found in: /path/to/file.md:42:15
+ Found in: /path/to/other.md:100:20
+
+Link Verification Summary
+============================================================
+Total URLs checked: 150
+Passed: 145
+Failed: 2
+Skipped: 3
+
+Failed Links:
+ • https://example.com/broken-link
+ Error: HTTP 404
+ Occurrences: 2
+```
+
+## Requirements
+
+- PowerShell 7+ (includes Markdig)
+- Runs on: `ubuntu-latest`, `windows-latest`, `macos-latest`
+
+## Broken Link Test
+
+- [Broken Link](https://github.com/PowerShell/PowerShell/wiki/NonExistentPage404)
+
+## License
+
+Same as the PowerShell repository.
diff --git a/.github/actions/infrastructure/markdownlinks/Verify-MarkdownLinks.ps1 b/.github/actions/infrastructure/markdownlinks/Verify-MarkdownLinks.ps1
new file mode 100644
index 00000000000..f50ab1590b9
--- /dev/null
+++ b/.github/actions/infrastructure/markdownlinks/Verify-MarkdownLinks.ps1
@@ -0,0 +1,317 @@
+# Copyright (c) Microsoft Corporation.
+# Licensed under the MIT License.
+
+#Requires -Version 7.0
+
+<#
+.SYNOPSIS
+ Verify all links in markdown files.
+
+.DESCRIPTION
+ This script parses markdown files to extract links and verifies their accessibility.
+ It supports HTTP/HTTPS links and local file references.
+
+.PARAMETER Path
+ Path to the directory containing markdown files. Defaults to current directory.
+
+.PARAMETER File
+ Array of specific markdown files to verify. If provided, Path parameter is ignored.
+
+.PARAMETER TimeoutSec
+ Timeout in seconds for HTTP requests. Defaults to 30.
+
+.PARAMETER MaximumRetryCount
+ Maximum number of retries for failed requests. Defaults to 2.
+
+.PARAMETER RetryIntervalSec
+ Interval in seconds between retry attempts. Defaults to 2.
+
+.EXAMPLE
+ .\Verify-MarkdownLinks.ps1 -Path ./CHANGELOG
+
+.EXAMPLE
+ .\Verify-MarkdownLinks.ps1 -Path ./docs -FailOnError
+
+.EXAMPLE
+ .\Verify-MarkdownLinks.ps1 -File @('CHANGELOG/7.5.md', 'README.md')
+#>
+
+param(
+ [Parameter(ParameterSetName = 'ByPath', Mandatory)]
+ [string]$Path = "Q:\src\git\powershell\docs\git",
+ [Parameter(ParameterSetName = 'ByFile', Mandatory)]
+ [string[]]$File = @(),
+ [int]$TimeoutSec = 30,
+ [int]$MaximumRetryCount = 2,
+ [int]$RetryIntervalSec = 2
+)
+
+$ErrorActionPreference = 'Stop'
+
+# Get the script directory
+$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
+
+# Determine what to process: specific files or directory
+if ($File.Count -gt 0) {
+ Write-Host "Extracting links from $($File.Count) specified markdown file(s)" -ForegroundColor Cyan
+
+ # Process each file individually
+ $allLinks = @()
+ $parseScriptPath = Join-Path $scriptDir "Parse-MarkdownLink.ps1"
+
+ foreach ($filePath in $File) {
+ if (Test-Path $filePath) {
+ Write-Verbose "Processing: $filePath"
+ $fileLinks = & $parseScriptPath -ChangelogPath $filePath
+ $allLinks += $fileLinks
+ }
+ else {
+ Write-Warning "File not found: $filePath"
+ }
+ }
+}
+else {
+ Write-Host "Extracting links from markdown files in: $Path" -ForegroundColor Cyan
+
+ # Get all links from markdown files using the Parse-ChangelogLinks script
+ $parseScriptPath = Join-Path $scriptDir "Parse-MarkdownLink.ps1"
+ $allLinks = & $parseScriptPath -ChangelogPath $Path
+}
+
+if ($allLinks.Count -eq 0) {
+ Write-Host "No links found in markdown files." -ForegroundColor Yellow
+ exit 0
+}
+
+Write-Host "Found $($allLinks.Count) links to verify" -ForegroundColor Green
+
+# Group links by URL to avoid duplicate checks
+$uniqueLinks = $allLinks | Group-Object -Property Url
+
+Write-Host "Unique URLs to verify: $($uniqueLinks.Count)" -ForegroundColor Cyan
+
+$results = @{
+ Total = $uniqueLinks.Count
+ Passed = 0
+ Failed = 0
+ Skipped = 0
+ Errors = [System.Collections.ArrayList]::new()
+}
+
+function Test-HttpLink {
+ param(
+ [string]$Url
+ )
+
+ try {
+ # Try HEAD request first (faster, doesn't download content)
+ $response = Invoke-WebRequest -Uri $Url `
+ -Method Head `
+ -TimeoutSec $TimeoutSec `
+ -MaximumRetryCount $MaximumRetryCount `
+ -RetryIntervalSec $RetryIntervalSec `
+ -UserAgent "Mozilla/5.0 (compatible; GitHubActions/1.0; +https://github.com/PowerShell/PowerShell)" `
+ -SkipHttpErrorCheck
+
+ # If HEAD fails with 404 or 405, retry with GET (some servers don't support HEAD)
+ if ($response.StatusCode -eq 404 -or $response.StatusCode -eq 405) {
+ Write-Verbose "HEAD request failed with $($response.StatusCode), retrying with GET for: $Url"
+ $response = Invoke-WebRequest -Uri $Url `
+ -Method Get `
+ -TimeoutSec $TimeoutSec `
+ -MaximumRetryCount $MaximumRetryCount `
+ -RetryIntervalSec $RetryIntervalSec `
+ -UserAgent "Mozilla/5.0 (compatible; GitHubActions/1.0; +https://github.com)" `
+ -SkipHttpErrorCheck
+ }
+
+ if ($response.StatusCode -ge 200 -and $response.StatusCode -lt 400) {
+ return @{ Success = $true; StatusCode = $response.StatusCode }
+ }
+ else {
+ return @{ Success = $false; StatusCode = $response.StatusCode; Error = "HTTP $($response.StatusCode)" }
+ }
+ }
+ catch {
+ return @{ Success = $false; StatusCode = 0; Error = $_.Exception.Message }
+ }
+}
+
+function Test-LocalLink {
+ param(
+ [string]$Url,
+ [string]$BasePath
+ )
+
+ # Strip query parameters (e.g., ?sanitize=true) and anchors (e.g., #section)
+ $cleanUrl = $Url -replace '\?.*$', '' -replace '#.*$', ''
+
+ # Handle relative paths
+ $targetPath = Join-Path $BasePath $cleanUrl
+
+ if (Test-Path $targetPath) {
+ return @{ Success = $true }
+ }
+ else {
+ return @{ Success = $false; Error = "File not found: $targetPath" }
+ }
+}
+
+# Verify each unique link
+$progressCount = 0
+foreach ($linkGroup in $uniqueLinks) {
+ $progressCount++
+ $url = $linkGroup.Name
+ $occurrences = $linkGroup.Group
+ Write-Verbose -Verbose "[$progressCount/$($uniqueLinks.Count)] Checking: $url"
+
+ # Determine link type and verify
+ $verifyResult = $null
+ if ($url -match '^https?://') {
+ $verifyResult = Test-HttpLink -Url $url
+ }
+ elseif ($url -match '^#') {
+ Write-Verbose -Verbose "Skipping anchor link: $url"
+ $results.Skipped++
+ continue
+ }
+ elseif ($url -match '^mailto:') {
+ Write-Verbose -Verbose "Skipping mailto link: $url"
+ $results.Skipped++
+ continue
+ }
+ else {
+ $basePath = Split-Path -Parent $occurrences[0].Path
+ $verifyResult = Test-LocalLink -Url $url -BasePath $basePath
+ }
+ if ($verifyResult.Success) {
+ Write-Host "✓ OK: $url" -ForegroundColor Green
+ $results.Passed++
+ }
+ else {
+ $errorMsg = if ($verifyResult.StatusCode) {
+ "HTTP $($verifyResult.StatusCode)"
+ }
+ else {
+ $verifyResult.Error
+ }
+
+ # Determine if this status code should be ignored or treated as failure
+ # Ignore: 401 (Unauthorized), 403 (Forbidden), 429 (Too Many Requests - already retried)
+ # Fail: 404 (Not Found), 410 (Gone), 406 (Not Acceptable) - these indicate broken links
+ $shouldIgnore = $false
+ $ignoreReason = ""
+
+ switch ($verifyResult.StatusCode) {
+ 401 {
+ $shouldIgnore = $true
+ $ignoreReason = "authentication required"
+ }
+ 403 {
+ $shouldIgnore = $true
+ $ignoreReason = "access forbidden"
+ }
+ 429 {
+ $shouldIgnore = $true
+ $ignoreReason = "rate limited (already retried)"
+ }
+ }
+
+ if ($shouldIgnore) {
+ Write-Host "⊘ IGNORED: $url - $errorMsg ($ignoreReason)" -ForegroundColor Yellow
+ Write-Verbose -Verbose "Ignored error details for $url - Status: $($verifyResult.StatusCode) - $ignoreReason"
+ foreach ($occurrence in $occurrences) {
+ Write-Verbose -Verbose " Found in: $($occurrence.Path):$($occurrence.Line):$($occurrence.Column)"
+ }
+ $results.Skipped++
+ }
+ else {
+ Write-Host "✗ FAILED: $url - $errorMsg" -ForegroundColor Red
+ foreach ($occurrence in $occurrences) {
+ Write-Host " Found in: $($occurrence.Path):$($occurrence.Line):$($occurrence.Column)" -ForegroundColor DarkGray
+ }
+ $results.Failed++
+ [void]$results.Errors.Add(@{
+ Url = $url
+ Error = $errorMsg
+ Occurrences = $occurrences
+ })
+ }
+ }
+ }
+
+# Print summary
+Write-Host "`n" + ("=" * 60) -ForegroundColor Cyan
+Write-Host "Link Verification Summary" -ForegroundColor Cyan
+Write-Host ("=" * 60) -ForegroundColor Cyan
+Write-Host "Total URLs checked: $($results.Total)" -ForegroundColor White
+Write-Host "Passed: $($results.Passed)" -ForegroundColor Green
+Write-Host "Failed: $($results.Failed)" -ForegroundColor $(if ($results.Failed -gt 0) { "Red" } else { "Green" })
+Write-Host "Skipped: $($results.Skipped)" -ForegroundColor Gray
+
+if ($results.Failed -gt 0) {
+ Write-Host "`nFailed Links:" -ForegroundColor Red
+ foreach ($failedLink in $results.Errors) {
+ Write-Host " • $($failedLink.Url)" -ForegroundColor Red
+ Write-Host " Error: $($failedLink.Error)" -ForegroundColor DarkGray
+ Write-Host " Occurrences: $($failedLink.Occurrences.Count)" -ForegroundColor DarkGray
+ }
+
+ Write-Host "`n❌ Link verification failed!" -ForegroundColor Red
+ exit 1
+}
+else {
+ Write-Host "`n✅ All links verified successfully!" -ForegroundColor Green
+}
+
+# Write to GitHub Actions step summary if running in a workflow
+if ($env:GITHUB_STEP_SUMMARY) {
+ $summaryContent = @"
+
+# Markdown Link Verification Results
+
+## Summary
+- **Total URLs checked:** $($results.Total)
+- **Passed:** ✅ $($results.Passed)
+- **Failed:** $(if ($results.Failed -gt 0) { "❌" } else { "✅" }) $($results.Failed)
+- **Skipped:** $($results.Skipped)
+
+"@
+
+ if ($results.Failed -gt 0) {
+ $summaryContent += @"
+
+## Failed Links
+
+| URL | Error | Occurrences |
+|-----|-------|-------------|
+
+"@
+ foreach ($failedLink in $results.Errors) {
+ $summaryContent += "| $($failedLink.Url) | $($failedLink.Error) | $($failedLink.Occurrences.Count) |`n"
+ }
+
+ $summaryContent += @"
+
+
+Click to see all failed link locations
+
+"@
+ foreach ($failedLink in $results.Errors) {
+ $summaryContent += "`n### $($failedLink.Url)`n"
+ $summaryContent += "**Error:** $($failedLink.Error)`n`n"
+ foreach ($occurrence in $failedLink.Occurrences) {
+ $summaryContent += "- `$($occurrence.Path):$($occurrence.Line):$($occurrence.Column)`n"
+ }
+ }
+ $summaryContent += "`n`n"
+ }
+ else {
+ $summaryContent += "`n## ✅ All links verified successfully!`n"
+ }
+
+ Write-Verbose -Verbose "Writing `n $summaryContent `n to ${env:GITHUB_STEP_SUMMARY}"
+ $summaryContent | Out-File -FilePath $env:GITHUB_STEP_SUMMARY -Append
+ Write-Verbose -Verbose "Summary written to GitHub Actions step summary"
+}
+
diff --git a/.github/actions/infrastructure/markdownlinks/action.yml b/.github/actions/infrastructure/markdownlinks/action.yml
new file mode 100644
index 00000000000..de2952252d4
--- /dev/null
+++ b/.github/actions/infrastructure/markdownlinks/action.yml
@@ -0,0 +1,110 @@
+name: 'Verify Markdown Links'
+description: 'Verify all links in markdown files using PowerShell and Markdig'
+author: 'PowerShell Team'
+
+inputs:
+ timeout-sec:
+ description: 'Timeout in seconds for HTTP requests'
+ required: false
+ default: '30'
+ maximum-retry-count:
+ description: 'Maximum number of retries for failed requests'
+ required: false
+ default: '2'
+
+outputs:
+ total-links:
+ description: 'Total number of unique links checked'
+ value: ${{ steps.verify.outputs.total }}
+ passed-links:
+ description: 'Number of links that passed verification'
+ value: ${{ steps.verify.outputs.passed }}
+ failed-links:
+ description: 'Number of links that failed verification'
+ value: ${{ steps.verify.outputs.failed }}
+ skipped-links:
+ description: 'Number of links that were skipped'
+ value: ${{ steps.verify.outputs.skipped }}
+
+runs:
+ using: 'composite'
+ steps:
+ - name: Get changed markdown files
+ id: changed-files
+ uses: "./.github/actions/infrastructure/get-changed-files"
+ with:
+ filter: '*.md'
+ event-types: 'pull_request,push'
+
+ - name: Verify markdown links
+ id: verify
+ shell: pwsh
+ env:
+ CHANGED_FILES_JSON: ${{ steps.changed-files.outputs.files }}
+ run: |
+ Write-Host "Starting markdown link verification..." -ForegroundColor Cyan
+
+ # Get changed markdown files from environment variable (secure against injection)
+ $changedFilesJson = $env:CHANGED_FILES_JSON
+ $changedFiles = $changedFilesJson | ConvertFrom-Json
+
+ if ($changedFiles.Count -eq 0) {
+ Write-Host "No markdown files changed, skipping verification" -ForegroundColor Yellow
+ "total=0" >> $env:GITHUB_OUTPUT
+ "passed=0" >> $env:GITHUB_OUTPUT
+ "failed=0" >> $env:GITHUB_OUTPUT
+ "skipped=0" >> $env:GITHUB_OUTPUT
+ exit 0
+ }
+
+ Write-Host "Changed markdown files: $($changedFiles.Count)" -ForegroundColor Cyan
+ $changedFiles | ForEach-Object { Write-Host " - $_" -ForegroundColor Gray }
+
+ # Build parameters for each file
+ $params = @{
+ File = $changedFiles
+ TimeoutSec = [int]'${{ inputs.timeout-sec }}'
+ MaximumRetryCount = [int]'${{ inputs.maximum-retry-count }}'
+ }
+
+ # Run the verification script
+ $scriptPath = Join-Path '${{ github.action_path }}' 'Verify-MarkdownLinks.ps1'
+
+ # Capture output and parse results
+ $output = & $scriptPath @params 2>&1 | Tee-Object -Variable capturedOutput
+
+ # Try to extract metrics from output
+ $totalLinks = 0
+ $passedLinks = 0
+ $failedLinks = 0
+ $skippedLinks = 0
+
+ foreach ($line in $capturedOutput) {
+ if ($line -match 'Total URLs checked: (\d+)') {
+ $totalLinks = $Matches[1]
+ }
+ elseif ($line -match 'Passed: (\d+)') {
+ $passedLinks = $Matches[1]
+ }
+ elseif ($line -match 'Failed: (\d+)') {
+ $failedLinks = $Matches[1]
+ }
+ elseif ($line -match 'Skipped: (\d+)') {
+ $skippedLinks = $Matches[1]
+ }
+ }
+
+ # Set outputs
+ "total=$totalLinks" >> $env:GITHUB_OUTPUT
+ "passed=$passedLinks" >> $env:GITHUB_OUTPUT
+ "failed=$failedLinks" >> $env:GITHUB_OUTPUT
+ "skipped=$skippedLinks" >> $env:GITHUB_OUTPUT
+
+ Write-Host "Action completed" -ForegroundColor Cyan
+
+ # Exit with the same code as the verification script
+ exit $LASTEXITCODE
+
+branding:
+ icon: 'link'
+ color: 'blue'
diff --git a/.github/actions/infrastructure/merge-conflict-checker/README.md b/.github/actions/infrastructure/merge-conflict-checker/README.md
new file mode 100644
index 00000000000..b53d6f99964
--- /dev/null
+++ b/.github/actions/infrastructure/merge-conflict-checker/README.md
@@ -0,0 +1,86 @@
+# Merge Conflict Checker
+
+This composite GitHub Action checks for Git merge conflict markers in files changed in pull requests.
+
+## Purpose
+
+Automatically detects leftover merge conflict markers (`<<<<<<<`, `=======`, `>>>>>>>`) in pull request files to prevent them from being merged into the codebase.
+
+## Usage
+
+### In a Workflow
+
+```yaml
+- name: Check for merge conflict markers
+ uses: "./.github/actions/infrastructure/merge-conflict-checker"
+```
+
+### Complete Example
+
+```yaml
+jobs:
+ merge_conflict_check:
+ name: Check for Merge Conflict Markers
+ runs-on: ubuntu-latest
+ if: github.event_name == 'pull_request'
+ permissions:
+ pull-requests: read
+ contents: read
+ steps:
+ - name: checkout
+ uses: actions/checkout@v5
+
+ - name: Check for merge conflict markers
+ uses: "./.github/actions/infrastructure/merge-conflict-checker"
+```
+
+## How It Works
+
+1. **File Detection**: Uses GitHub's API to get the list of files changed in the pull request
+2. **Marker Scanning**: Reads each changed file and searches for the following markers:
+ - `<<<<<<<` (conflict start marker)
+ - `=======` (conflict separator)
+ - `>>>>>>>` (conflict end marker)
+3. **Result Reporting**:
+ - If markers are found, the action fails and lists all affected files
+ - If no markers are found, the action succeeds
+
+## Outputs
+
+- `files-checked`: Number of files that were checked
+- `conflicts-found`: Number of files containing merge conflict markers
+
+## Behavior
+
+- **Event Support**: Only works with `pull_request` events
+- **File Handling**:
+ - Checks only files that were added, modified, or renamed
+ - Skips deleted files
+ - **Filters out `*.cs` files** (C# files are excluded from merge conflict checking)
+ - Skips binary/unreadable files
+ - Skips directories
+- **Empty File List**: Gracefully handles cases where no files need checking (e.g., PRs that only delete files)
+
+## Example Output
+
+When conflict markers are detected:
+
+```
+❌ Merge conflict markers detected in the following files:
+ - src/example.cs
+ Markers found: <<<<<<<, =======, >>>>>>>
+ - README.md
+ Markers found: <<<<<<<, =======, >>>>>>>
+
+Please resolve these conflicts before merging.
+```
+
+When no markers are found:
+
+```
+✅ No merge conflict markers found
+```
+
+## Integration
+
+This action is integrated into the `linux-ci.yml` workflow and runs automatically on all pull requests to ensure code quality before merging.
diff --git a/.github/actions/infrastructure/merge-conflict-checker/action.yml b/.github/actions/infrastructure/merge-conflict-checker/action.yml
new file mode 100644
index 00000000000..41c7d2ad941
--- /dev/null
+++ b/.github/actions/infrastructure/merge-conflict-checker/action.yml
@@ -0,0 +1,37 @@
+name: 'Check for Merge Conflict Markers'
+description: 'Checks for Git merge conflict markers in changed files for pull requests'
+author: 'PowerShell Team'
+
+outputs:
+ files-checked:
+ description: 'Number of files checked for merge conflict markers'
+ value: ${{ steps.check.outputs.files-checked }}
+ conflicts-found:
+ description: 'Number of files with merge conflict markers'
+ value: ${{ steps.check.outputs.conflicts-found }}
+
+runs:
+ using: 'composite'
+ steps:
+ - name: Get changed files
+ id: changed-files
+ uses: "./.github/actions/infrastructure/get-changed-files"
+
+ - name: Check for merge conflict markers
+ id: check
+ shell: pwsh
+ env:
+ CHANGED_FILES_JSON: ${{ steps.changed-files.outputs.files }}
+ run: |
+ # Get changed files from environment variable (secure against injection)
+ $changedFilesJson = $env:CHANGED_FILES_JSON
+ # Ensure we always have an array (ConvertFrom-Json returns null for empty JSON arrays)
+ $changedFiles = @($changedFilesJson | ConvertFrom-Json)
+
+ # Import ci.psm1 and run the check
+ Import-Module "$env:GITHUB_WORKSPACE/tools/ci.psm1" -Force
+ Test-MergeConflictMarker -File $changedFiles -WorkspacePath $env:GITHUB_WORKSPACE
+
+branding:
+ icon: 'alert-triangle'
+ color: 'red'
diff --git a/.github/actions/infrastructure/path-filters/action.yml b/.github/actions/infrastructure/path-filters/action.yml
index e150b1a9d09..656719262b2 100644
--- a/.github/actions/infrastructure/path-filters/action.yml
+++ b/.github/actions/infrastructure/path-filters/action.yml
@@ -26,12 +26,22 @@ outputs:
buildModuleChanged:
description: 'Build module changes'
value: ${{ steps.filter.outputs.buildModuleChanged }}
+ packagingChanged:
+ description: 'Packaging related changes'
+ value: ${{ steps.filter.outputs.packagingChanged }}
runs:
using: composite
steps:
+ - name: Get changed files
+ id: get-files
+ if: github.event_name == 'pull_request'
+ uses: "./.github/actions/infrastructure/get-changed-files"
+
- name: Check if GitHubWorkflowChanges is present
id: filter
uses: actions/github-script@v7.0.1
+ env:
+ FILES_JSON: ${{ steps.get-files.outputs.files }}
with:
github-token: ${{ inputs.GITHUB_TOKEN }}
script: |
@@ -50,42 +60,71 @@ runs:
return;
}
- console.log(`Getting files changed in PR #${context.issue.number}`);
-
- // Fetch the list of files changed in the PR
- let files = [];
- let page = 1;
- let fetchedFiles;
- do {
- fetchedFiles = await github.rest.pulls.listFiles({
- owner: context.repo.owner,
- repo: context.repo.repo,
- pull_number: context.issue.number,
- per_page: 100,
- page: page++
- });
- files = files.concat(fetchedFiles.data);
- } while (fetchedFiles.data.length > 0);
-
- const actionsChanged = files.some(file => file.filename.startsWith('.github/actions'));
- const workflowsChanged = files.some(file => file.filename.startsWith('.github/workflows'));
+ // Get files from environment variable (secure against injection)
+ const files = JSON.parse(process.env.FILES_JSON || '[]');
+
+ // Calculate hash for verification (matches get-changed-files action)
+ const crypto = require('crypto');
+ const filesJson = JSON.stringify(files.sort());
+ const hash = crypto.createHash('sha256').update(filesJson).digest('hex').substring(0, 8);
+ console.log(`Received ${files.length} files (hash: ${hash})`);
+
+ // Analyze changes with detailed logging
+ core.startGroup('Path Filter Analysis');
+
+ const actionsChanged = files.some(file => file.startsWith('.github/actions'));
+ console.log(`✓ Actions changed: ${actionsChanged}`);
+
+ const workflowsChanged = files.some(file => file.startsWith('.github/workflows'));
+ console.log(`✓ Workflows changed: ${workflowsChanged}`);
+
const githubChanged = actionsChanged || workflowsChanged;
+ console.log(`→ GitHub changed (actions OR workflows): ${githubChanged}`);
+
+ const toolsCiPsm1Changed = files.some(file => file === 'tools/ci.psm1');
+ console.log(`✓ tools/ci.psm1 changed: ${toolsCiPsm1Changed}`);
+
+ const toolsBuildCommonChanged = files.some(file => file.startsWith('tools/buildCommon/'));
+ console.log(`✓ tools/buildCommon/ changed: ${toolsBuildCommonChanged}`);
- const toolsCiPsm1Changed = files.some(file => file.filename.startsWith('tools/ci.psm1'));
- const toolsBuildCommonChanged = files.some(file => file.filename.startsWith('tools/buildCommon/'));
const toolsChanged = toolsCiPsm1Changed || toolsBuildCommonChanged;
+ console.log(`→ Tools changed: ${toolsChanged}`);
- const propsChanged = files.some(file => file.filename.endsWith('.props'));
+ const propsChanged = files.some(file => file.endsWith('.props'));
+ console.log(`✓ Props files changed: ${propsChanged}`);
- const testsChanged = files.some(file => file.filename.startsWith('test/powershell/') || file.filename.startsWith('test/tools/') || file.filename.startsWith('test/xUnit/'));
+ const testsChanged = files.some(file => file.startsWith('test/powershell/') || file.startsWith('test/tools/') || file.startsWith('test/xUnit/'));
+ console.log(`✓ Tests changed: ${testsChanged}`);
- const mainSourceChanged = files.some(file => file.filename.startsWith('src/'));
+ const mainSourceChanged = files.some(file => file.startsWith('src/'));
+ console.log(`✓ Main source (src/) changed: ${mainSourceChanged}`);
- const buildModuleChanged = files.some(file => file.filename.startsWith('build.psm1'));
+ const buildModuleChanged = files.some(file => file === 'build.psm1');
+ console.log(`✓ build.psm1 changed: ${buildModuleChanged}`);
- const globalConfigChanged = files.some(file => file.filename.startsWith('.globalconfig')) || files.some(file => file.filename.startsWith('nuget.config')) || files.some(file => file.filename.startsWith('global.json'));
+ const globalConfigChanged = files.some(file => file === '.globalconfig' || file === 'nuget.config' || file === 'global.json');
+ console.log(`✓ Global config changed: ${globalConfigChanged}`);
+
+ const packagingChanged = files.some(file =>
+ file === '.github/workflows/windows-ci.yml' ||
+ file === '.github/workflows/linux-ci.yml' ||
+ file.startsWith('assets/wix/') ||
+ file === 'PowerShell.Common.props' ||
+ file.match(/^src\/.*\.csproj$/) ||
+ file.startsWith('test/packaging/windows/') ||
+ file.startsWith('test/packaging/linux/') ||
+ file.startsWith('tools/packaging/') ||
+ file.startsWith('tools/wix/')
+ ) ||
+ buildModuleChanged ||
+ globalConfigChanged ||
+ toolsCiPsm1Changed;
+ console.log(`→ Packaging changed: ${packagingChanged}`);
const source = mainSourceChanged || toolsChanged || githubChanged || propsChanged || testsChanged || globalConfigChanged;
+ console.log(`→ Source (composite): ${source}`);
+
+ core.endGroup();
core.setOutput('toolsChanged', toolsChanged);
core.setOutput('githubChanged', githubChanged);
@@ -94,16 +133,5 @@ runs:
core.setOutput('mainSourceChanged', mainSourceChanged);
core.setOutput('buildModuleChanged', buildModuleChanged);
core.setOutput('globalConfigChanged', globalConfigChanged);
+ core.setOutput('packagingChanged', packagingChanged);
core.setOutput('source', source);
-
-
- - name: Capture outputs
- run: |
- Write-Verbose -Verbose "source: ${{ steps.filter.outputs.source }}"
- Write-Verbose -Verbose "github: ${{ steps.filter.outputs.githubChanged }}"
- Write-Verbose -Verbose "tools: ${{ steps.filter.outputs.toolsChanged }}"
- Write-Verbose -Verbose "props: ${{ steps.filter.outputs.propsChanged }}"
- Write-Verbose -Verbose "tests: ${{ steps.filter.outputs.testsChanged }}"
- Write-Verbose -Verbose "mainSource: ${{ steps.filter.outputs.mainSourceChanged }}"
- Write-Verbose -Verbose "buildModule: ${{ steps.filter.outputs.buildModuleChanged }}"
- shell: pwsh
diff --git a/.github/actions/test/linux-packaging/action.yml b/.github/actions/test/linux-packaging/action.yml
index b4a9c3b55c0..ef9ba23e799 100644
--- a/.github/actions/test/linux-packaging/action.yml
+++ b/.github/actions/test/linux-packaging/action.yml
@@ -1,72 +1,76 @@
name: linux_packaging
-description: 'Test very basic Linux packaging'
-
-# This isn't working yet
-# It fails with
-
-# ERROR: While executing gem ... (Gem::FilePermissionError)
-# You don't have write permissions for the /var/lib/gems/2.7.0 directory.
-# WARNING: Installation of gem dotenv 2.8.1 failed! Must resolve manually.
+description: 'Linux packaging for PowerShell'
runs:
using: composite
steps:
- name: Capture Environment
if: success() || failure()
- run: 'Get-ChildItem -Path env: | Out-String -width 9999 -Stream | write-Verbose -Verbose'
+ run: |-
+ Import-Module ./tools/ci.psm1
+ Show-Environment
shell: pwsh
+
+ - uses: actions/setup-dotnet@v5
+ with:
+ global-json-file: ./global.json
+
- name: Download Build Artifacts
uses: actions/download-artifact@v4
with:
- path: "${{ github.workspace }}"
+ name: build
+ path: "${{ runner.workspace }}/build"
+
- name: Capture Artifacts Directory
continue-on-error: true
- run: Get-ChildItem "${{ github.workspace }}/build/*" -Recurse
+ run: Get-ChildItem "${{ runner.workspace }}/build/*" -Recurse
shell: pwsh
- name: Bootstrap
run: |-
Import-Module ./build.psm1
Start-PSBootstrap -Scenario Package
+ Write-Verbose -Verbose "Start Sync-PSTags"
+ Sync-PSTags -AddRemoteIfMissing
+ Write-Verbose -Verbose "End Sync-PSTags"
shell: pwsh
- - name: Capture Artifacts Directory
- continue-on-error: true
- run: Import-Module ./build.psm1
+
+ - name: Extract Build ZIP
+ run: |-
+ $destinationFolder = "${{ runner.workspace }}/bins"
+ $archiveFile = "${{ runner.workspace }}/build/build.zip"
+
+ Write-Verbose "Extracting $archiveFile to $destinationFolder" -Verbose
+ New-Item -ItemType Directory -Path $destinationFolder -Force | Out-Null
+ Expand-Archive -Path $archiveFile -DestinationPath $destinationFolder -Force
shell: pwsh
- - name: Extract Files
- uses: actions/github-script@v7.0.0
- env:
- DESTINATION_FOLDER: "${{ github.workspace }}/bins"
- ARCHIVE_FILE_PATTERNS: "${{ github.workspace }}/build/build.zip"
- with:
- script: |-
- const fs = require('fs').promises
- const path = require('path')
- const target = path.resolve(process.env.DESTINATION_FOLDER)
- const patterns = process.env.ARCHIVE_FILE_PATTERNS
- const globber = await glob.create(patterns)
- await io.mkdirP(path.dirname(target))
- for await (const file of globber.globGenerator()) {
- if ((await fs.lstat(file)).isDirectory()) continue
- await exec.exec(`7z x ${file} -o${target} -aoa`)
- }
+
- name: Fix permissions
continue-on-error: true
run: |-
- find "${{ github.workspace }}/bins" -type d -exec chmod +rwx {} \;
- find "${{ github.workspace }}/bins" -type f -exec chmod +rw {} \;
+ find "${{ runner.workspace }}/bins" -type d -exec chmod +rwx {} \;
+ find "${{ runner.workspace }}/bins" -type f -exec chmod +rw {} \;
shell: bash
+
- name: Capture Extracted Build ZIP
continue-on-error: true
- run: Get-ChildItem "${{ github.workspace }}/bins/*" -Recurse -ErrorAction SilentlyContinue
+ run: Get-ChildItem "${{ runner.workspace }}/bins/*" -Recurse -ErrorAction SilentlyContinue
shell: pwsh
- - name: Packaging Tests
- if: success()
+
+ - name: Create Packages
+ env:
+ BUILD_ARTIFACTSTAGINGDIRECTORY: ${{ runner.workspace }}/packages
run: |-
+ # Create the artifacts staging directory
+ New-Item -ItemType Directory -Path "$env:BUILD_ARTIFACTSTAGINGDIRECTORY" -Force | Out-Null
+
+ # Import packaging module to ensure RPM packaging changes are loaded
+ Import-Module ./build.psm1 -Force
+ Import-Module ./tools/packaging/packaging.psm1 -Force
Import-Module ./tools/ci.psm1
- Restore-PSOptions -PSOptionsPath '${{ github.workspace }}/build/psoptions.json'
+ Restore-PSOptions -PSOptionsPath '${{ runner.workspace }}/build/psoptions.json'
$options = (Get-PSOptions)
- $rootPath = '${{ github.workspace }}/bins'
+ $rootPath = '${{ runner.workspace }}/bins'
$originalRootPath = Split-Path -path $options.Output
$path = Join-Path -path $rootPath -ChildPath (split-path -leaf -path $originalRootPath)
$pwshPath = Join-Path -path $path -ChildPath 'pwsh'
@@ -75,21 +79,40 @@ runs:
Set-PSOptions $options
Invoke-CIFinish
shell: pwsh
- - name: Upload packages
+
+ - name: Install Pester
run: |-
- Get-ChildItem "${env:BUILD_ARTIFACTSTAGINGDIRECTORY}/*.deb" -Recurse | ForEach-Object {
- $packagePath = $_.FullName
- Write-Host "Uploading $packagePath"
- Write-Host "##vso[artifact.upload containerfolder=deb;artifactname=deb]$packagePath"
- }
- Get-ChildItem "${env:BUILD_ARTIFACTSTAGINGDIRECTORY}/*.rpm" -Recurse | ForEach-Object {
- $packagePath = $_.FullName
- Write-Host "Uploading $packagePath"
- Write-Host "##vso[artifact.upload containerfolder=rpm;artifactname=rpm]$packagePath"
- }
- Get-ChildItem "${env:BUILD_ARTIFACTSTAGINGDIRECTORY}/*.tar.gz" -Recurse | ForEach-Object {
- $packagePath = $_.FullName
- Write-Host "Uploading $packagePath"
- Write-Host "##vso[artifact.upload containerfolder=rpm;artifactname=rpm]$packagePath"
+ Import-Module ./tools/ci.psm1
+ Install-CIPester
+ shell: pwsh
+
+ - name: Validate Package Names
+ run: |-
+ # Run Pester tests to validate package names
+ Import-Module Pester -Force
+ $testResults = Invoke-Pester -Path ./test/packaging/linux/package-validation.tests.ps1 -PassThru
+ if ($testResults.FailedCount -gt 0) {
+ throw "Package validation tests failed"
}
shell: pwsh
+
+ - name: Upload deb packages
+ uses: actions/upload-artifact@v4
+ with:
+ name: packages-deb
+ path: ${{ runner.workspace }}/packages/*.deb
+ if-no-files-found: ignore
+
+ - name: Upload rpm packages
+ uses: actions/upload-artifact@v4
+ with:
+ name: packages-rpm
+ path: ${{ runner.workspace }}/packages/*.rpm
+ if-no-files-found: ignore
+
+ - name: Upload tar.gz packages
+ uses: actions/upload-artifact@v4
+ with:
+ name: packages-tar
+ path: ${{ runner.workspace }}/packages/*.tar.gz
+ if-no-files-found: ignore
diff --git a/.github/actions/test/nix/action.yml b/.github/actions/test/nix/action.yml
index b338c398340..7f68e71c1f5 100644
--- a/.github/actions/test/nix/action.yml
+++ b/.github/actions/test/nix/action.yml
@@ -14,6 +14,9 @@ inputs:
required: false
default: ctrf
type: string
+ GITHUB_TOKEN:
+ description: 'GitHub token for API authentication'
+ required: true
runs:
using: composite
@@ -21,10 +24,8 @@ runs:
- name: Capture Environment
if: success() || failure()
run: |-
- Import-Module ./build.psm1
- Write-LogGroupStart -Title 'Environment'
- Get-ChildItem -Path env: | Out-String -width 9999 -Stream | write-Verbose -Verbose
- Write-LogGroupEnd -Title 'Environment'
+ Import-Module ./tools/ci.psm1
+ Show-Environment
shell: pwsh
- name: Download Build Artifacts
@@ -45,6 +46,51 @@ runs:
with:
global-json-file: ./global.json
+ - name: Set Package Name by Platform
+ id: set_package_name
+ shell: pwsh
+ run: |-
+ Import-Module ./.github/workflows/GHWorkflowHelper/GHWorkflowHelper.psm1
+ $platform = $env:RUNNER_OS
+ Write-Host "Runner platform: $platform"
+ if ($platform -eq 'Linux') {
+ $packageName = 'DSC-*-x86_64-linux.tar.gz'
+ } elseif ($platform -eq 'macOS') {
+ $packageName = 'DSC-*-x86_64-apple-darwin.tar.gz'
+ } else {
+ throw "Unsupported platform: $platform"
+ }
+
+ Set-GWVariable -Name "DSC_PACKAGE_NAME" -Value $packageName
+
+ - name: Get Latest DSC Package Version
+ shell: pwsh
+ run: |-
+ Import-Module ./.github/workflows/GHWorkflowHelper/GHWorkflowHelper.psm1
+ $headers = @{
+ Authorization = "Bearer ${{ inputs.GITHUB_TOKEN }}"
+ }
+ $releases = Invoke-RestMethod -Uri "https://api.github.com/repos/PowerShell/Dsc/releases" -Headers $headers
+ $latestRelease = $releases | Where-Object { $v = $_.name.trim("v"); $semVer = [System.Management.Automation.SemanticVersion]::new($v); if ($semVer.Major -eq 3 -and $semVer.Minor -ge 2) { $_ } } | Select-Object -First 1
+ $latestVersion = $latestRelease.tag_name.TrimStart("v")
+ Write-Host "Latest DSC Version: $latestVersion"
+
+ $packageName = "$env:DSC_PACKAGE_NAME"
+
+ Write-Host "Package Name: $packageName"
+
+ $downloadUrl = $latestRelease.assets | Where-Object { $_.name -like "*$packageName*" } | Select-Object -First 1 | Select-Object -ExpandProperty browser_download_url
+ Write-Host "Download URL: $downloadUrl"
+
+ $tempPath = Get-GWTempPath
+
+ Invoke-RestMethod -Uri $downloadUrl -OutFile "$tempPath/DSC.tar.gz" -Verbose -Headers $headers
+ New-Item -ItemType Directory -Path "$tempPath/DSC" -Force -Verbose
+ tar xvf "$tempPath/DSC.tar.gz" -C "$tempPath/DSC"
+ $dscRoot = "$tempPath/DSC"
+ Write-Host "DSC Root: $dscRoot"
+ Set-GWVariable -Name "DSC_ROOT" -Value $dscRoot
+
- name: Bootstrap
shell: pwsh
run: |-
diff --git a/.github/actions/test/verify_xunit/action.yml b/.github/actions/test/verify_xunit/action.yml
deleted file mode 100644
index fccca27182f..00000000000
--- a/.github/actions/test/verify_xunit/action.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-name: verify_xunit
-description: 'Verify xUnit Results'
-
-runs:
- using: composite
- steps:
- - name: Download build artifacts
- uses: actions/download-artifact@v4
- with:
- path: "${{ github.workspace }}"
- - name: Capture artifacts directory
- continue-on-error: true
- run: dir "${{ github.workspace }}\testResults-xunit\*" -Recurse
- shell: pwsh
- - name: Test
- if: success()
- run: |-
- Import-Module .\tools\ci.psm1
- $xUnitTestResultsFile = "${{ github.workspace }}\testResults-xunit\xUnitTestResults.xml"
- Test-XUnitTestResults -TestResultsFile $xUnitTestResultsFile
- shell: pwsh
diff --git a/.github/actions/test/windows/action.yml b/.github/actions/test/windows/action.yml
index 734e30208f0..2c41f6aac5c 100644
--- a/.github/actions/test/windows/action.yml
+++ b/.github/actions/test/windows/action.yml
@@ -14,6 +14,9 @@ inputs:
required: false
default: ctrf
type: string
+ GITHUB_TOKEN:
+ description: 'GitHub token for API authentication'
+ required: true
runs:
using: composite
@@ -21,10 +24,8 @@ runs:
- name: Capture Environment
if: success() || failure()
run: |-
- Import-Module ./build.psm1
- Write-LogGroupStart -Title 'Environment'
- Get-ChildItem -Path env: | Out-String -width 9999 -Stream | write-Verbose -Verbose
- Write-LogGroupEnd -Title 'Environment'
+ Import-Module ./tools/ci.psm1
+ Show-Environment
shell: pwsh
- name: Download Build Artifacts
@@ -45,6 +46,29 @@ runs:
with:
global-json-file: .\global.json
+ - name: Get Latest DSC Package Version
+ shell: pwsh
+ run: |-
+ Import-Module .\.github\workflows\GHWorkflowHelper\GHWorkflowHelper.psm1
+ $headers = @{
+ Authorization = "Bearer ${{ inputs.GITHUB_TOKEN }}"
+ }
+ $releases = Invoke-RestMethod -Uri "https://api.github.com/repos/PowerShell/Dsc/releases" -Headers $headers
+ $latestRelease = $releases | Where-Object { $v = $_.name.trim("v"); $semVer = [System.Management.Automation.SemanticVersion]::new($v); if ($semVer.Major -eq 3 -and $semVer.Minor -ge 2) { $_ } } | Select-Object -First 1
+ $latestVersion = $latestRelease.tag_name.TrimStart("v")
+ Write-Host "Latest DSC Version: $latestVersion"
+
+ $downloadUrl = $latestRelease.assets | Where-Object { $_.name -like "DSC-*-x86_64-pc-windows-msvc.zip" } | Select-Object -First 1 | Select-Object -ExpandProperty browser_download_url
+ Write-Host "Download URL: $downloadUrl"
+ $tempPath = Get-GWTempPath
+ Invoke-RestMethod -Uri $downloadUrl -OutFile "$tempPath\DSC.zip" -Headers $headers
+
+ $null = New-Item -ItemType Directory -Path "$tempPath\DSC" -Force
+ Expand-Archive -Path "$tempPath\DSC.zip" -DestinationPath "$tempPath\DSC" -Force
+ $dscRoot = "$tempPath\DSC"
+ Write-Host "DSC Root: $dscRoot"
+ Set-GWVariable -Name "DSC_ROOT" -Value $dscRoot
+
- name: Bootstrap
shell: powershell
run: |-
diff --git a/.github/chatmodes/cherry-pick-commits.chatmode.md b/.github/chatmodes/cherry-pick-commits.chatmode.md
new file mode 100644
index 00000000000..826ab11d56c
--- /dev/null
+++ b/.github/chatmodes/cherry-pick-commits.chatmode.md
@@ -0,0 +1,78 @@
+# Cherry-Pick Commits Between Branches
+
+Cherry-pick recent commits from a source branch to a target branch without switching branches.
+
+## Instructions for Copilot
+
+1. **Confirm branches with the user**
+ - Ask the user to confirm the source and target branches
+ - If different branches are needed, update the configuration
+
+2. **Identify unique commits**
+ - Run: `git log .. --oneline --reverse`
+ - **IMPORTANT**: The commit count may be misleading if branches diverged from different base commits
+ - Compare the LAST few commits from each branch to identify actual missing commits:
+ - `git log --oneline -10`
+ - `git log --oneline -10`
+ - Look for commits with the same message but different SHAs (rebased commits)
+ - Show the user ONLY the truly missing commits (usually just the most recent ones)
+
+3. **Confirm with user before proceeding**
+ - If the commit count seems unusually high (e.g., 400+), STOP and verify semantically
+ - Ask: "I found X commits to cherry-pick. Shall I proceed?"
+ - If there are many commits, warn that this may take time
+
+4. **Execute the cherry-pick**
+ - Ensure the target branch is checked out first
+ - Run: `git cherry-pick ` for single commits
+ - Or: `git cherry-pick ` for multiple commits
+ - Apply commits in chronological order (oldest first)
+
+5. **Handle any issues**
+ - If conflicts occur, pause and ask user for guidance
+ - If empty commits occur, automatically skip with `git cherry-pick --skip`
+
+6. **Verify and report results**
+ - Run: `git log - --oneline`
+ - Show the user the newly applied commits
+ - Confirm the branch is now ahead by X commits
+
+## Key Git Commands
+
+```bash
+# Find unique commits (may show full divergence if branches were rebased)
+git log .. --oneline --reverse
+
+# Compare recent commits on each branch (more reliable for rebased branches)
+git log --oneline -10
+git log --oneline -10
+
+# Cherry-pick specific commits (when target is checked out)
+git cherry-pick
+git cherry-pick
+
+# Skip empty commits
+git cherry-pick --skip
+
+# Verify result
+git log - --oneline
+```
+
+## Common Scenarios
+
+- **Empty commits**: Automatically skip with `git cherry-pick --skip`
+- **Conflicts**: Stop, show files with conflicts, ask user to resolve
+- **Many commits**: Warn user and confirm before proceeding
+- **Already applied**: These will result in empty commits that should be skipped
+- **Diverged branches**: If branches diverged (rebased), `git log` may show the entire history difference
+ - The actual missing commits are usually only the most recent ones
+ - Compare commit messages from recent history on both branches
+ - Cherry-pick only commits that are semantically missing
+
+## Workflow Style
+
+Use an interactive, step-by-step approach:
+- Show output from each command
+- Ask for confirmation before major actions
+- Provide clear status updates
+- Handle errors gracefully with user guidance
diff --git a/.github/instructions/build-configuration-guide.md b/.github/instructions/build-configuration-guide.md
new file mode 100644
index 00000000000..408a004e0c7
--- /dev/null
+++ b/.github/instructions/build-configuration-guide.md
@@ -0,0 +1,150 @@
+---
+applyTo:
+ - "build.psm1"
+ - "tools/ci.psm1"
+ - ".github/**/*.yml"
+ - ".github/**/*.yaml"
+ - ".pipelines/**/*.yml"
+---
+
+# Build Configuration Guide
+
+## Choosing the Right Configuration
+
+### For Testing
+
+**Use: Default (Debug)**
+
+```yaml
+- name: Build for Testing
+ shell: pwsh
+ run: |
+ Import-Module ./tools/ci.psm1
+ Start-PSBuild
+```
+
+**Why Debug:**
+- Includes debugging symbols
+- Better error messages
+- Faster build times
+- Suitable for xUnit and Pester tests
+
+**Do NOT use:**
+- `-Configuration 'Release'` (unnecessary for tests)
+- `-ReleaseTag` (not needed for tests)
+- `-CI` (unless you specifically need Pester module)
+
+### For Release/Packaging
+
+**Use: Release with version tag and public NuGet feeds**
+
+```yaml
+- name: Build for Release
+ shell: pwsh
+ run: |
+ Import-Module ./build.psm1
+ Import-Module ./tools/ci.psm1
+ Switch-PSNugetConfig -Source Public
+ $releaseTag = Get-ReleaseTag
+ Start-PSBuild -Configuration 'Release' -ReleaseTag $releaseTag
+```
+
+**Why Release:**
+- Optimized binaries
+- No debug symbols (smaller size)
+- Production-ready
+
+**Why Switch-PSNugetConfig -Source Public:**
+- Switches NuGet package sources to public feeds (nuget.org and public Azure DevOps feeds)
+- Required for CI/CD environments that don't have access to private feeds
+- Uses publicly available packages instead of Microsoft internal feeds
+
+### For Code Coverage
+
+**Use: CodeCoverage configuration**
+
+```yaml
+- name: Build with Coverage
+ shell: pwsh
+ run: |
+ Import-Module ./tools/ci.psm1
+ Start-PSBuild -Configuration 'CodeCoverage'
+```
+
+## Platform Considerations
+
+### All Platforms
+
+Same commands work across Linux, Windows, and macOS:
+
+```yaml
+strategy:
+ matrix:
+ os: [ubuntu-latest, windows-latest, macos-latest]
+runs-on: ${{ matrix.os }}
+steps:
+ - name: Build PowerShell
+ shell: pwsh
+ run: |
+ Import-Module ./tools/ci.psm1
+ Start-PSBuild
+```
+
+### Output Locations
+
+**Linux/macOS:**
+```
+src/powershell-unix/bin/Debug///publish/
+```
+
+**Windows:**
+```
+src/powershell-win-core/bin/Debug///publish/
+```
+
+## Best Practices
+
+1. Use default configuration for testing
+2. Avoid redundant parameters
+3. Match configuration to purpose
+4. Use `-CI` only when needed
+5. Always specify `-ReleaseTag` for release or packaging builds
+6. Use `Switch-PSNugetConfig -Source Public` in CI/CD for release builds
+
+## NuGet Feed Configuration
+
+### Switch-PSNugetConfig
+
+The `Switch-PSNugetConfig` function in `build.psm1` manages NuGet package source configuration.
+
+**Available Sources:**
+
+- **Public**: Uses public feeds (nuget.org and public Azure DevOps feeds)
+ - Required for: CI/CD environments, public builds, packaging
+ - Does not require authentication
+
+- **Private**: Uses internal PowerShell team feeds
+ - Required for: Internal development with preview packages
+ - Requires authentication credentials
+
+- **NuGetOnly**: Uses only nuget.org
+ - Required for: Minimal dependency scenarios
+
+**Usage:**
+
+```powershell
+# Switch to public feeds (most common for CI/CD)
+Switch-PSNugetConfig -Source Public
+
+# Switch to private feeds with authentication
+Switch-PSNugetConfig -Source Private -UserName $userName -ClearTextPAT $pat
+
+# Switch to nuget.org only
+Switch-PSNugetConfig -Source NuGetOnly
+```
+
+**When to Use:**
+
+- **Always use `-Source Public`** before building in CI/CD workflows
+- Use before any build that will create packages for distribution
+- Use in forks or environments without access to Microsoft internal feeds
\ No newline at end of file
diff --git a/.github/instructions/code-review-branch-strategy.instructions.md b/.github/instructions/code-review-branch-strategy.instructions.md
new file mode 100644
index 00000000000..191a677b912
--- /dev/null
+++ b/.github/instructions/code-review-branch-strategy.instructions.md
@@ -0,0 +1,230 @@
+---
+applyTo: "**/*"
+---
+
+# Code Review Branch Strategy Guide
+
+This guide helps GitHub Copilot provide appropriate feedback when reviewing code changes, particularly distinguishing between issues that should be fixed in the current branch versus the default branch.
+
+## Purpose
+
+When reviewing pull requests, especially those targeting release branches, it's important to identify whether an issue should be fixed in:
+- **The current PR/branch** - Release-specific fixes or backports
+- **The default branch first** - General bugs that exist in the main codebase
+
+## Branch Types and Fix Strategy
+
+### Release Branches (e.g., `release/v7.5`, `release/v7.4`)
+
+**Purpose:** Contain release-specific changes and critical backports
+
+**Should contain:**
+- Release-specific configuration changes
+- Critical bug fixes that are backported from the default branch
+- Release packaging/versioning adjustments
+
+**Should NOT contain:**
+- New general bug fixes that haven't been fixed in the default branch
+- Refactoring or improvements that apply to the main codebase
+- Workarounds for issues that exist in the default branch
+
+### Default/Main Branch (e.g., `master`, `main`)
+
+**Purpose:** Primary development branch for all ongoing work
+
+**Should contain:**
+- All general bug fixes
+- New features and improvements
+- Refactoring and code quality improvements
+- Fixes that will later be backported to release branches
+
+## Identifying Issues That Belong in the Default Branch
+
+When reviewing a PR targeting a release branch, look for these indicators that suggest the fix should be in the default branch first:
+
+### 1. The Root Cause Exists in Default Branch
+
+If the underlying issue exists in the default branch's code, it should be fixed there first.
+
+**Example:**
+```yaml
+# PR changes this in release/v7.5:
+- $metadata = Get-Content "$repoRoot/tools/metadata.json" -Raw | ConvertFrom-Json
++ $metadata = Get-Content "$(Build.SourcesDirectory)/PowerShell/tools/metadata.json" -Raw | ConvertFrom-Json
+```
+
+**Analysis:** If `$repoRoot` is undefined because the template doesn't include its dependencies in BOTH the release branch AND the default branch, the fix should address the root cause in the default branch first.
+
+### 2. The Fix is a Workaround Rather Than a Proper Solution
+
+If the change introduces a workaround (hardcoded paths, special cases) rather than fixing the underlying design issue, it likely belongs in the default branch as a proper fix.
+
+**Example:**
+- Using hardcoded paths instead of fixing variable initialization
+- Adding special cases instead of fixing the logic
+- Duplicating code instead of fixing shared dependencies
+
+### 3. The Issue Affects General Functionality
+
+If the issue affects general functionality not specific to a release, it should be fixed in the default branch.
+
+**Example:**
+- Template dependencies that affect all pipelines
+- Shared utility functions
+- Common configuration issues
+
+## Providing Code Review Feedback
+
+### For Issues in the Current Branch
+
+When an issue is specific to the current branch or is a legitimate fix for the branch being targeted, **use the default code review feedback format** without any special branch-strategy commentary.
+
+### For Issues That Belong in the Default Branch
+
+1. **Provide the code review feedback**
+2. **Explain why it should be fixed in the default branch**
+3. **Provide an issue template** in markdown format
+
+**Example:**
+
+```markdown
+The `channelSelection.yml` template relies on `$repoRoot` being set by `SetVersionVariables.yml`, but doesn't declare this dependency. This issue exists in both the release branch and the default branch.
+
+**This should be fixed in the default branch first**, then backported if needed. The proper fix is to ensure template dependencies are correctly declared, rather than using hardcoded paths as a workaround.
+
+---
+
+**Suggested Issue for Default Branch:**
+
+### Issue Title
+`channelSelection.yml` template missing dependency on `SetVersionVariables.yml`
+
+### Description
+The `channelSelection.yml` template uses the `$repoRoot` variable but doesn't ensure it's set beforehand by including `SetVersionVariables.yml`.
+
+**Current State:**
+- `channelSelection.yml` expects `$repoRoot` to be available
+- Not all pipelines that use `channelSelection.yml` include `SetVersionVariables.yml` first
+- This creates an implicit dependency that's not enforced
+
+**Expected State:**
+Either:
+1. `channelSelection.yml` should include `SetVersionVariables.yml` as a dependency, OR
+2. `channelSelection.yml` should be refactored to not depend on `$repoRoot`, OR
+3. Pipelines using `channelSelection.yml` should explicitly include `SetVersionVariables.yml` first
+
+**Files Affected:**
+- `.pipelines/templates/channelSelection.yml`
+- `.pipelines/templates/package-create-msix.yml`
+- `.pipelines/templates/release-SetTagAndChangelog.yml`
+
+**Priority:** Medium
+**Labels:** `Issue-Bug`, `Area-Build`, `Area-Pipeline`
+```
+
+## Issue Template Format
+
+When creating an issue template for the default branch, use this structure:
+
+```markdown
+### Issue Title
+[Clear, concise description of the problem]
+
+### Description
+[Detailed explanation of the issue]
+
+**Current State:**
+- [What's happening now]
+- [Why it's problematic]
+
+**Expected State:**
+- [What should happen]
+- [Proposed solution(s)]
+
+**Files Affected:**
+- [List of files]
+
+**Priority:** [Low/Medium/High/Critical]
+**Labels:** [Suggested labels like `Issue-Bug`, `Area-*`]
+
+**Additional Context:**
+[Any additional information, links to related issues, etc.]
+```
+
+## Common Scenarios
+
+### Scenario 1: Template Dependency Issues
+
+**Indicators:**
+- Missing template includes
+- Undefined variables from other templates
+- Assumptions about pipeline execution order
+
+**Action:** Suggest fixing template dependencies in the default branch.
+
+### Scenario 2: Hardcoded Values
+
+**Indicators:**
+- Hardcoded paths replacing variables
+- Environment-specific values in shared code
+- Magic strings or numbers
+
+**Action:** Suggest proper variable/parameter usage in the default branch.
+
+### Scenario 3: Logic Errors
+
+**Indicators:**
+- Incorrect conditional logic
+- Missing error handling
+- Race conditions
+
+**Action:** Suggest fixing the logic in the default branch unless it's release-specific.
+
+### Scenario 4: Legitimate Release Branch Fixes
+
+**Indicators:**
+- Version-specific configuration
+- Release packaging changes
+- Backport of already-fixed default branch issue
+
+**Action:** Provide normal code review feedback for the current PR.
+
+## Best Practices
+
+1. **Always check if the issue exists in the default branch** before suggesting a release-branch-only fix
+2. **Prefer fixing root causes over workarounds**
+3. **Provide clear rationale** for why a fix belongs in the default branch
+4. **Include actionable issue templates** so users can easily create issues
+5. **Be helpful, not blocking** - provide the feedback even if you can't enforce where it's fixed
+
+## Examples of Good vs. Bad Approaches
+
+### ❌ Bad: Workaround in Release Branch Only
+
+```yaml
+# In release/v7.5 only
+- pwsh: |
+ $metadata = Get-Content "$(Build.SourcesDirectory)/PowerShell/tools/metadata.json" -Raw
+```
+
+**Why bad:** Hardcodes path to work around missing `$repoRoot`, doesn't fix the default branch.
+
+### ✅ Good: Fix in Default Branch, Then Backport
+
+```yaml
+# In default branch first
+- template: SetVersionVariables.yml@self # Ensures $repoRoot is set
+- template: channelSelection.yml@self # Now can use $repoRoot
+```
+
+**Why good:** Fixes the root cause by ensuring dependencies are declared, then backport to release if needed.
+
+## When in Doubt
+
+If you're unsure whether an issue should be fixed in the current branch or the default branch, ask yourself:
+
+1. Does this issue exist in the default branch?
+2. Is this a workaround or a proper fix?
+3. Will other branches/releases benefit from this fix?
+
+If the answer to any of these is "yes," suggest fixing it in the default branch first.
diff --git a/.github/instructions/git-requirements-for-builds.md b/.github/instructions/git-requirements-for-builds.md
new file mode 100644
index 00000000000..3c8cd91e7c7
--- /dev/null
+++ b/.github/instructions/git-requirements-for-builds.md
@@ -0,0 +1,71 @@
+# 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
+```
diff --git a/.github/instructions/log-grouping-guidelines.instructions.md b/.github/instructions/log-grouping-guidelines.instructions.md
new file mode 100644
index 00000000000..ff845db4e4b
--- /dev/null
+++ b/.github/instructions/log-grouping-guidelines.instructions.md
@@ -0,0 +1,181 @@
+---
+applyTo:
+ - "build.psm1"
+ - "tools/ci.psm1"
+ - ".github/**/*.yml"
+ - ".github/**/*.yaml"
+---
+
+# Log Grouping Guidelines for GitHub Actions
+
+## Purpose
+
+Guidelines for using `Write-LogGroupStart` and `Write-LogGroupEnd` to create collapsible log sections in GitHub Actions CI/CD runs.
+
+## Key Principles
+
+### 1. Groups Cannot Be Nested
+
+GitHub Actions does not support nested groups. Only use one level of grouping.
+
+**❌ Don't:**
+```powershell
+Write-LogGroupStart -Title "Outer Group"
+Write-LogGroupStart -Title "Inner Group"
+# ... operations ...
+Write-LogGroupEnd -Title "Inner Group"
+Write-LogGroupEnd -Title "Outer Group"
+```
+
+**✅ Do:**
+```powershell
+Write-LogGroupStart -Title "Operation A"
+# ... operations ...
+Write-LogGroupEnd -Title "Operation A"
+
+Write-LogGroupStart -Title "Operation B"
+# ... operations ...
+Write-LogGroupEnd -Title "Operation B"
+```
+
+### 2. Groups Should Be Substantial
+
+Only create groups for operations that generate substantial output (5+ lines). Small groups add clutter without benefit.
+
+**❌ Don't:**
+```powershell
+Write-LogGroupStart -Title "Generate Resource Files"
+Write-Log -message "Run ResGen"
+Start-ResGen
+Write-LogGroupEnd -Title "Generate Resource Files"
+```
+
+**✅ Do:**
+```powershell
+Write-Log -message "Run ResGen (generating C# bindings for resx files)"
+Start-ResGen
+```
+
+### 3. Groups Should Represent Independent Operations
+
+Each group should be a logically independent operation that users might want to expand/collapse separately.
+
+**✅ Good examples:**
+- Install Native Dependencies
+- Install .NET SDK
+- Build PowerShell
+- Restore NuGet Packages
+
+**❌ Bad examples:**
+- Individual project restores (too granular)
+- Small code generation steps (too small)
+- Sub-steps of a larger operation (would require nesting)
+
+### 4. One Group Per Iteration Is Excessive
+
+Avoid putting log groups inside loops where each iteration creates a separate group. This would probably cause nesting.
+
+**❌ Don't:**
+```powershell
+$projects | ForEach-Object {
+ Write-LogGroupStart -Title "Restore Project: $_"
+ dotnet restore $_
+ Write-LogGroupEnd -Title "Restore Project: $_"
+}
+```
+
+**✅ Do:**
+```powershell
+Write-LogGroupStart -Title "Restore All Projects"
+$projects | ForEach-Object {
+ Write-Log -message "Restoring $_"
+ dotnet restore $_
+}
+Write-LogGroupEnd -Title "Restore All Projects"
+```
+
+## Usage Pattern
+
+```powershell
+Write-LogGroupStart -Title "Descriptive Operation Name"
+try {
+ # ... operation code ...
+ Write-Log -message "Status updates"
+}
+finally {
+ # Ensure group is always closed
+}
+Write-LogGroupEnd -Title "Descriptive Operation Name"
+```
+
+## When to Use Log Groups
+
+Use log groups for:
+- Major build phases (bootstrap, restore, build, test, package)
+- Installation operations (dependencies, SDKs, tools)
+- Operations that produce 5+ lines of output
+- Operations where users might want to collapse verbose output
+
+Don't use log groups for:
+- Single-line operations
+- Code that's already inside another group
+- Loop iterations with minimal output per iteration
+- Diagnostic or debug output that should always be visible
+
+## Examples from build.psm1
+
+### Good Usage
+
+```powershell
+function Start-PSBootstrap {
+ # Multiple independent operations, each with substantial output
+ Write-LogGroupStart -Title "Install Native Dependencies"
+ # ... apt-get/yum/brew install commands ...
+ Write-LogGroupEnd -Title "Install Native Dependencies"
+
+ Write-LogGroupStart -Title "Install .NET SDK"
+ # ... dotnet installation ...
+ Write-LogGroupEnd -Title "Install .NET SDK"
+}
+```
+
+### Avoid
+
+```powershell
+# Too small - just 2-3 lines
+Write-LogGroupStart -Title "Generate Resource Files (ResGen)"
+Write-Log -message "Run ResGen"
+Start-ResGen
+Write-LogGroupEnd -Title "Generate Resource Files (ResGen)"
+```
+
+## GitHub Actions Syntax
+
+These functions emit GitHub Actions workflow commands:
+- `Write-LogGroupStart` → `::group::Title`
+- `Write-LogGroupEnd` → `::endgroup::`
+
+In the GitHub Actions UI, this renders as collapsible sections with the specified title.
+
+## Testing
+
+Test log grouping locally:
+```powershell
+$env:GITHUB_ACTIONS = 'true'
+Import-Module ./build.psm1
+Write-LogGroupStart -Title "Test"
+Write-Log -Message "Content"
+Write-LogGroupEnd -Title "Test"
+```
+
+Output should show:
+```
+::group::Test
+Content
+::endgroup::
+```
+
+## References
+
+- [GitHub Actions: Grouping log lines](https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#grouping-log-lines)
+- `build.psm1`: `Write-LogGroupStart` and `Write-LogGroupEnd` function definitions
diff --git a/.github/instructions/onebranch-condition-syntax.instructions.md b/.github/instructions/onebranch-condition-syntax.instructions.md
new file mode 100644
index 00000000000..19bf331d9c3
--- /dev/null
+++ b/.github/instructions/onebranch-condition-syntax.instructions.md
@@ -0,0 +1,223 @@
+---
+applyTo: ".pipelines/**/*.{yml,yaml}"
+---
+
+# OneBranch Pipeline Condition Syntax
+
+## Overview
+Azure Pipelines (OneBranch) uses specific syntax for referencing variables and parameters in condition expressions. Using the wrong syntax will cause conditions to fail silently or behave unexpectedly.
+
+## Variable Reference Patterns
+
+### In Condition Expressions
+
+**✅ Correct Pattern:**
+```yaml
+condition: eq(variables['VariableName'], 'value')
+condition: or(eq(variables['VAR1'], 'true'), eq(variables['VAR2'], 'true'))
+condition: and(succeeded(), eq(variables['Architecture'], 'fxdependent'))
+```
+
+**❌ Incorrect Patterns:**
+```yaml
+# Don't use $(VAR) string expansion in conditions
+condition: eq('$(VariableName)', 'value')
+
+# Don't use direct variable references
+condition: eq($VariableName, 'value')
+```
+
+### In Script Content (pwsh, bash, etc.)
+
+**✅ Correct Pattern:**
+```yaml
+- pwsh: |
+ $value = '$(VariableName)'
+ Write-Host "Value: $(VariableName)"
+```
+
+### In Input Fields
+
+**✅ Correct Pattern:**
+```yaml
+inputs:
+ serviceEndpoint: '$(ServiceEndpoint)'
+ sbConfigPath: '$(SBConfigPath)'
+```
+
+## Parameter References
+
+### Template Parameters (Compile-Time)
+
+**✅ Correct Pattern:**
+```yaml
+parameters:
+ - name: OfficialBuild
+ type: boolean
+ default: false
+
+steps:
+ - task: SomeTask@1
+ condition: eq('${{ parameters.OfficialBuild }}', 'true')
+```
+
+Note: Parameters use `${{ parameters.Name }}` because they're evaluated at template compile-time.
+
+### Runtime Variables (Execution-Time)
+
+**✅ Correct Pattern:**
+```yaml
+steps:
+ - pwsh: |
+ Write-Host "##vso[task.setvariable variable=MyVar]somevalue"
+ displayName: Set Variable
+
+ - task: SomeTask@1
+ condition: eq(variables['MyVar'], 'somevalue')
+```
+
+## Common Scenarios
+
+### Scenario 1: Check if Variable Equals Value
+
+```yaml
+- task: DoSomething@1
+ condition: eq(variables['PREVIEW'], 'true')
+```
+
+### Scenario 2: Multiple Variable Conditions (OR)
+
+```yaml
+- task: DoSomething@1
+ condition: or(eq(variables['STABLE'], 'true'), eq(variables['LTS'], 'true'))
+```
+
+### Scenario 3: Multiple Variable Conditions (AND)
+
+```yaml
+- task: DoSomething@1
+ condition: and(succeeded(), eq(variables['Architecture'], 'fxdependent'))
+```
+
+### Scenario 4: Complex Conditions
+
+```yaml
+- task: DoSomething@1
+ condition: and(
+ succeededOrFailed(),
+ ne(variables['UseAzDevOpsFeed'], ''),
+ eq(variables['Build.SourceBranch'], 'refs/heads/master')
+ )
+```
+
+### Scenario 5: Built-in Variables
+
+```yaml
+- task: CodeQL3000Init@0
+ condition: eq(variables['Build.SourceBranch'], 'refs/heads/master')
+
+- step: finalize
+ condition: eq(variables['Agent.JobStatus'], 'SucceededWithIssues')
+```
+
+### Scenario 6: Parameter vs Variable
+
+```yaml
+parameters:
+ - name: OfficialBuild
+ type: boolean
+
+steps:
+ # Parameter condition (compile-time)
+ - task: SignFiles@1
+ condition: eq('${{ parameters.OfficialBuild }}', 'true')
+
+ # Variable condition (runtime)
+ - task: PublishArtifact@1
+ condition: eq(variables['PUBLISH_ENABLED'], 'true')
+```
+
+## Why This Matters
+
+**String Expansion `$(VAR)` in Conditions:**
+- When you use `'$(VAR)'` in a condition, Azure Pipelines attempts to expand it as a string
+- If the variable is undefined or empty, it becomes an empty string `''`
+- The condition `eq('', 'true')` will always be false
+- This makes debugging difficult because there's no error message
+
+**Variables Array Syntax `variables['VAR']`:**
+- This is the proper way to reference runtime variables in conditions
+- Azure Pipelines correctly evaluates the variable's value
+- Undefined variables are handled properly by the condition evaluator
+- This is the standard pattern used throughout Azure Pipelines
+
+## Reference Examples
+
+Working examples can be found in:
+- `.pipelines/templates/linux.yml` - Build.SourceBranch conditions
+- `.pipelines/templates/windows-hosted-build.yml` - Architecture conditions
+- `.pipelines/templates/compliance/apiscan.yml` - CODEQL_ENABLED conditions
+- `.pipelines/templates/insert-nuget-config-azfeed.yml` - Complex AND/OR conditions
+
+## Quick Reference Table
+
+| Context | Syntax | Example |
+|---------|--------|---------|
+| Condition expression | `variables['Name']` | `condition: eq(variables['PREVIEW'], 'true')` |
+| Script content | `$(Name)` | `pwsh: Write-Host "$(PREVIEW)"` |
+| Task input | `$(Name)` | `inputs: path: '$(Build.SourcesDirectory)'` |
+| Template parameter | `${{ parameters.Name }}` | `condition: eq('${{ parameters.Official }}', 'true')` |
+
+## Troubleshooting
+
+### Condition Always False
+If your condition is always evaluating to false:
+1. Check if you're using `'$(VAR)'` instead of `variables['VAR']`
+2. Verify the variable is actually set (add a debug step to print the variable)
+3. Check the variable value is exactly what you expect (case-sensitive)
+
+### Variable Not Found
+If you get errors about variables not being found:
+1. Ensure the variable is set before the condition is evaluated
+2. Check that the variable name is spelled correctly
+3. Verify the variable is in scope (job vs. stage vs. pipeline level)
+
+## Best Practices
+
+1. **Always use `variables['Name']` in conditions** - This is the correct Azure Pipelines pattern
+2. **Use `$(Name)` for string expansion** in scripts and inputs
+3. **Use `${{ parameters.Name }}` for template parameters** (compile-time)
+4. **Add debug steps** to verify variable values when troubleshooting conditions
+5. **Follow existing patterns** in the repository - grep for `condition:` to see examples
+
+## Common Mistakes
+
+❌ **Mistake 1: String expansion in condition**
+```yaml
+condition: eq('$(PREVIEW)', 'true') # WRONG
+```
+
+✅ **Fix:**
+```yaml
+condition: eq(variables['PREVIEW'], 'true') # CORRECT
+```
+
+❌ **Mistake 2: Missing quotes around parameter**
+```yaml
+condition: eq(${{ parameters.Official }}, true) # WRONG
+```
+
+✅ **Fix:**
+```yaml
+condition: eq('${{ parameters.Official }}', 'true') # CORRECT
+```
+
+❌ **Mistake 3: Mixing syntax**
+```yaml
+condition: or(eq('$(STABLE)', 'true'), eq(variables['LTS'], 'true')) # INCONSISTENT
+```
+
+✅ **Fix:**
+```yaml
+condition: or(eq(variables['STABLE'], 'true'), eq(variables['LTS'], 'true')) # CORRECT
+```
diff --git a/.github/instructions/onebranch-restore-phase-pattern.instructions.md b/.github/instructions/onebranch-restore-phase-pattern.instructions.md
new file mode 100644
index 00000000000..0945bb47c0b
--- /dev/null
+++ b/.github/instructions/onebranch-restore-phase-pattern.instructions.md
@@ -0,0 +1,83 @@
+---
+applyTo: ".pipelines/**/*.{yml,yaml}"
+---
+
+# OneBranch Restore Phase Pattern
+
+## Overview
+When steps need to run in the OneBranch restore phase (before the main build phase), the `ob_restore_phase` environment variable must be set in the `env:` block of **each individual step**.
+
+## Pattern
+
+### ✅ Correct (Working Pattern)
+```yaml
+parameters:
+- name: "ob_restore_phase"
+ type: boolean
+ default: true # or false if you don't want restore phase
+
+steps:
+- powershell: |
+ # script content
+ displayName: 'Step Name'
+ env:
+ ob_restore_phase: ${{ parameters.ob_restore_phase }}
+```
+
+The key is to:
+1. Define `ob_restore_phase` as a **boolean** parameter
+2. Set `ob_restore_phase: ${{ parameters.ob_restore_phase }}` directly in each step's `env:` block
+3. Pass `true` to run in restore phase, `false` to run in normal build phase
+
+### ❌ Incorrect (Does Not Work)
+```yaml
+steps:
+- powershell: |
+ # script content
+ displayName: 'Step Name'
+ ${{ if eq(parameters.useRestorePhase, 'yes') }}:
+ env:
+ ob_restore_phase: true
+```
+
+Using conditionals at the same indentation level as `env:` causes only the first step to execute in restore phase.
+
+## Parameters
+
+Templates using this pattern should accept an `ob_restore_phase` boolean parameter:
+
+```yaml
+parameters:
+- name: "ob_restore_phase"
+ type: boolean
+ default: true # Set to true to run in restore phase by default
+```
+
+## Reference Examples
+
+Working examples of this pattern can be found in:
+- `.pipelines/templates/insert-nuget-config-azfeed.yml` - Demonstrates the correct pattern
+- `.pipelines/templates/SetVersionVariables.yml` - Updated to use this pattern
+
+## Why This Matters
+
+The restore phase in OneBranch pipelines runs before signing and other build operations. Steps that need to:
+- Set environment variables for the entire build
+- Configure authentication
+- Prepare the repository structure
+
+Must run in the restore phase to be available when subsequent stages execute.
+
+## Common Use Cases
+
+- Setting `REPOROOT` variable
+- Configuring NuGet feeds with authentication
+- Setting version variables
+- Repository preparation and validation
+
+## Troubleshooting
+
+If only the first step in your template is running in restore phase:
+1. Check that `env:` block exists for **each step**
+2. Verify the conditional `${{ if ... }}:` is **inside** the `env:` block
+3. Confirm indentation is correct (conditional is indented under `env:`)
diff --git a/.github/instructions/onebranch-signing-configuration.instructions.md b/.github/instructions/onebranch-signing-configuration.instructions.md
new file mode 100644
index 00000000000..747fcaffdd6
--- /dev/null
+++ b/.github/instructions/onebranch-signing-configuration.instructions.md
@@ -0,0 +1,195 @@
+---
+applyTo:
+ - ".pipelines/**/*.yml"
+ - ".pipelines/**/*.yaml"
+---
+
+# OneBranch Signing Configuration
+
+This guide explains how to configure OneBranch signing variables in Azure Pipeline jobs, particularly when signing is not required.
+
+## Purpose
+
+OneBranch pipelines include signing infrastructure by default. For build-only jobs where signing happens in a separate stage, you should disable signing setup to improve performance and avoid unnecessary overhead.
+
+## Disable Signing for Build-Only Jobs
+
+When a job does not perform signing (e.g., it only builds artifacts that will be signed in a later stage), disable both signing setup and code sign validation:
+
+```yaml
+variables:
+ - name: ob_signing_setup_enabled
+ value: false # Disable signing setup - this is a build-only stage
+ - name: ob_sdl_codeSignValidation_enabled
+ value: false # Skip signing validation in build-only stage
+```
+
+### Why Disable These Variables?
+
+**`ob_signing_setup_enabled: false`**
+- Prevents OneBranch from setting up the signing infrastructure
+- Reduces job startup time
+- Avoids unnecessary credential validation
+- Only disable when the job will NOT sign any artifacts
+
+**`ob_sdl_codeSignValidation_enabled: false`**
+- Skips validation that checks if files are properly signed
+- Appropriate for build stages where artifacts are unsigned
+- Must be enabled in signing/release stages to validate signatures
+
+## Common Patterns
+
+### Build-Only Job (No Signing)
+
+```yaml
+jobs:
+- job: build_artifacts
+ variables:
+ - name: ob_signing_setup_enabled
+ value: false
+ - name: ob_sdl_codeSignValidation_enabled
+ value: false
+ steps:
+ - checkout: self
+ - pwsh: |
+ # Build unsigned artifacts
+ Start-PSBuild
+```
+
+### Signing Job
+
+```yaml
+jobs:
+- job: sign_artifacts
+ variables:
+ - name: ob_signing_setup_enabled
+ value: true
+ - name: ob_sdl_codeSignValidation_enabled
+ value: true
+ steps:
+ - checkout: self
+ env:
+ ob_restore_phase: true # Steps before first signing operation
+ - pwsh: |
+ # Prepare artifacts for signing
+ env:
+ ob_restore_phase: true # Steps before first signing operation
+ - task: onebranch.pipeline.signing@1
+ displayName: 'Sign artifacts'
+ # Signing step runs in build phase (no ob_restore_phase)
+ - pwsh: |
+ # Post-signing validation
+ # Post-signing steps run in build phase (no ob_restore_phase)
+```
+
+## Restore Phase Usage with Signing
+
+**The restore phase (`ob_restore_phase: true`) should only be used in jobs that perform signing operations.** It separates preparation steps from the actual signing and build steps.
+
+### When to Use Restore Phase
+
+Use `ob_restore_phase: true` **only** in jobs where `ob_signing_setup_enabled: true`:
+
+```yaml
+jobs:
+- job: sign_artifacts
+ variables:
+ - name: ob_signing_setup_enabled
+ value: true # Signing enabled
+ steps:
+ # Steps BEFORE first signing operation: use restore phase
+ - checkout: self
+ env:
+ ob_restore_phase: true
+ - template: prepare-for-signing.yml
+ parameters:
+ ob_restore_phase: true
+
+ # SIGNING STEP: runs in build phase (no ob_restore_phase)
+ - task: onebranch.pipeline.signing@1
+ displayName: 'Sign artifacts'
+
+ # Steps AFTER signing: run in build phase (no ob_restore_phase)
+ - pwsh: |
+ # Validation or packaging
+```
+
+### When NOT to Use Restore Phase
+
+**Do not use restore phase in build-only jobs** where `ob_signing_setup_enabled: false`:
+
+```yaml
+jobs:
+- job: build_artifacts
+ variables:
+ - name: ob_signing_setup_enabled
+ value: false # No signing
+ - name: ob_sdl_codeSignValidation_enabled
+ value: false
+ steps:
+ - checkout: self
+ # NO ob_restore_phase - not needed without signing
+ - pwsh: |
+ Start-PSBuild
+```
+
+**Why?** The restore phase is part of OneBranch's signing infrastructure. Using it without signing enabled adds unnecessary overhead without benefit.
+
+## Related Variables
+
+Other OneBranch signing-related variables:
+
+- `ob_sdl_binskim_enabled`: Controls BinSkim security analysis (can be false in build-only, true in signing stages)
+
+## Best Practices
+
+1. **Separate build and signing stages**: Build artifacts in one job, sign in another
+2. **Disable signing in build stages**: Improves performance and clarifies intent
+3. **Only use restore phase with signing**: The restore phase should only be used in jobs where signing is enabled (`ob_signing_setup_enabled: true`)
+4. **Restore phase before first signing step**: All steps before the first signing operation should use `ob_restore_phase: true`
+5. **Always validate after signing**: Enable validation in signing stages to catch issues
+6. **Document the reason**: Add comments explaining why signing is disabled or why restore phase is used
+
+## Example: Split Build and Sign Pipeline
+
+```yaml
+stages:
+ - stage: Build
+ jobs:
+ - job: build_windows
+ variables:
+ - name: ob_signing_setup_enabled
+ value: false # Build-only, no signing
+ - name: ob_sdl_codeSignValidation_enabled
+ value: false # Artifacts are unsigned
+ steps:
+ - template: templates/build-unsigned.yml
+
+ - stage: Sign
+ dependsOn: Build
+ jobs:
+ - job: sign_windows
+ variables:
+ - name: ob_signing_setup_enabled
+ value: true # Enable signing infrastructure
+ - name: ob_sdl_codeSignValidation_enabled
+ value: true # Validate signatures
+ steps:
+ - template: templates/sign-artifacts.yml
+```
+
+## Troubleshooting
+
+**Job fails with signing-related errors but signing is disabled:**
+- Verify `ob_signing_setup_enabled: false` is set in variables
+- Check that no template is overriding the setting
+- Ensure `ob_sdl_codeSignValidation_enabled: false` is also set
+
+**Signed artifacts fail validation:**
+- Confirm `ob_sdl_codeSignValidation_enabled: true` in signing job
+- Verify signing actually occurred
+- Check certificate configuration
+
+## Reference
+
+- PowerShell signing templates: `.pipelines/templates/packaging/windows/sign.yml`
diff --git a/.github/instructions/powershell-automatic-variables.instructions.md b/.github/instructions/powershell-automatic-variables.instructions.md
new file mode 100644
index 00000000000..5015847f41f
--- /dev/null
+++ b/.github/instructions/powershell-automatic-variables.instructions.md
@@ -0,0 +1,159 @@
+---
+applyTo:
+ - "**/*.ps1"
+ - "**/*.psm1"
+---
+
+# PowerShell Automatic Variables - Naming Guidelines
+
+## Purpose
+
+This instruction provides guidelines for avoiding conflicts with PowerShell's automatic variables when writing PowerShell scripts and modules.
+
+## What Are Automatic Variables?
+
+PowerShell has built-in automatic variables that are created and maintained by PowerShell itself. Assigning values to these variables can cause unexpected behavior and side effects.
+
+## Common Automatic Variables to Avoid
+
+### Critical Variables (Never Use)
+
+- **`$matches`** - Contains the results of regular expression matches. Overwriting this can break regex operations.
+- **`$_`** - Represents the current object in the pipeline. Only use within pipeline blocks.
+- **`$PSItem`** - Alias for `$_`. Same rules apply.
+- **`$args`** - Contains an array of undeclared parameters. Don't use as a regular variable.
+- **`$input`** - Contains an enumerator of all input passed to a function. Don't reassign.
+- **`$LastExitCode`** - Exit code of the last native command. Don't overwrite unless intentional.
+- **`$?`** - Success status of the last command. Don't use as a variable name.
+- **`$$`** - Last token in the last line received by the session. Don't use.
+- **`$^`** - First token in the last line received by the session. Don't use.
+
+### Context Variables (Use with Caution)
+
+- **`$Error`** - Array of error objects. Don't replace, but can modify (e.g., `$Error.Clear()`).
+- **`$PSBoundParameters`** - Parameters passed to the current function. Read-only.
+- **`$MyInvocation`** - Information about the current command. Read-only.
+- **`$PSCmdlet`** - Cmdlet object for advanced functions. Read-only.
+
+### Other Common Automatic Variables
+
+- `$true`, `$false`, `$null` - Boolean and null constants
+- `$HOME`, `$PSHome`, `$PWD` - Path-related variables
+- `$PID` - Process ID of the current PowerShell session
+- `$Host` - Host application object
+- `$PSVersionTable` - PowerShell version information
+
+For a complete list, see: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_automatic_variables
+
+## Best Practices
+
+### ❌ Bad - Using Automatic Variable Names
+
+```powershell
+# Bad: $matches is an automatic variable used for regex capture groups
+$matches = Select-String -Path $file -Pattern $pattern
+
+# Bad: $args is an automatic variable for undeclared parameters
+$args = Get-ChildItem
+
+# Bad: $input is an automatic variable for pipeline input
+$input = Read-Host "Enter value"
+```
+
+### ✅ Good - Using Descriptive Alternative Names
+
+```powershell
+# Good: Use descriptive names that avoid conflicts
+$matchedLines = Select-String -Path $file -Pattern $pattern
+
+# Good: Use specific names for arguments
+$arguments = Get-ChildItem
+
+# Good: Use specific names for user input
+$userInput = Read-Host "Enter value"
+```
+
+## Naming Alternatives
+
+When you encounter a situation where you might use an automatic variable name, use these alternatives:
+
+| Avoid | Use Instead |
+|-------|-------------|
+| `$matches` | `$matchedLines`, `$matchResults`, `$regexMatches` |
+| `$args` | `$arguments`, `$parameters`, `$commandArgs` |
+| `$input` | `$userInput`, `$inputValue`, `$inputData` |
+| `$_` (outside pipeline) | Use a named parameter or explicit variable |
+| `$Error` (reassignment) | Don't reassign; use `$Error.Clear()` if needed |
+
+## How to Check
+
+### PSScriptAnalyzer Rule
+
+PSScriptAnalyzer has a built-in rule that detects assignments to automatic variables:
+
+```powershell
+# This will trigger PSAvoidAssignmentToAutomaticVariable
+$matches = Get-Something
+```
+
+**Rule ID**: PSAvoidAssignmentToAutomaticVariable
+
+### Manual Review
+
+When writing PowerShell code, always:
+1. Avoid variable names that match PowerShell keywords or automatic variables
+2. Use descriptive, specific names that clearly indicate the variable's purpose
+3. Run PSScriptAnalyzer on your code before committing
+4. Review code for variable naming during PR reviews
+
+## Examples from the Codebase
+
+### Example 1: Regex Matching
+
+```powershell
+# ❌ Bad - Overwrites automatic $matches variable
+$matches = [regex]::Matches($content, $pattern)
+
+# ✅ Good - Uses descriptive name
+$regexMatches = [regex]::Matches($content, $pattern)
+```
+
+### Example 2: Select-String Results
+
+```powershell
+# ❌ Bad - Conflicts with automatic $matches
+$matches = Select-String -Path $file -Pattern $pattern
+
+# ✅ Good - Clear and specific
+$matchedLines = Select-String -Path $file -Pattern $pattern
+```
+
+### Example 3: Collecting Arguments
+
+```powershell
+# ❌ Bad - Conflicts with automatic $args
+function Process-Items {
+ $args = $MyItems
+ # ... process items
+}
+
+# ✅ Good - Descriptive parameter name
+function Process-Items {
+ [CmdletBinding()]
+ param(
+ [Parameter(ValueFromRemainingArguments)]
+ [string[]]$Items
+ )
+ # ... process items
+}
+```
+
+## References
+
+- [PowerShell Automatic Variables Documentation](https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_automatic_variables)
+- [PSScriptAnalyzer Rules](https://github.com/PowerShell/PSScriptAnalyzer/blob/master/docs/Rules/README.md)
+- [PowerShell Best Practices](https://learn.microsoft.com/powershell/scripting/developer/cmdlet/strongly-encouraged-development-guidelines)
+
+## Summary
+
+**Key Takeaway**: Always use descriptive, specific variable names that clearly indicate their purpose and avoid conflicts with PowerShell's automatic variables. When in doubt, choose a longer, more descriptive name over a short one that might conflict.
diff --git a/.github/instructions/powershell-module-organization.instructions.md b/.github/instructions/powershell-module-organization.instructions.md
new file mode 100644
index 00000000000..461d19fb5df
--- /dev/null
+++ b/.github/instructions/powershell-module-organization.instructions.md
@@ -0,0 +1,201 @@
+---
+applyTo:
+ - "tools/ci.psm1"
+ - "build.psm1"
+ - "tools/packaging/**/*.psm1"
+ - ".github/**/*.yml"
+ - ".github/**/*.yaml"
+---
+
+# Guidelines for PowerShell Code Organization
+
+## When to Move Code from YAML to PowerShell Modules
+
+PowerShell code in GitHub Actions YAML files should be kept minimal. Move code to a module when:
+
+### Size Threshold
+- **More than ~30 lines** of PowerShell in a YAML file step
+- **Any use of .NET types** like `[regex]`, `[System.IO.Path]`, etc.
+- **Complex logic** requiring multiple nested loops or conditionals
+- **Reusable functionality** that might be needed elsewhere
+
+### Indicators to Move Code
+1. Using .NET type accelerators (`[regex]`, `[PSCustomObject]`, etc.)
+2. Complex string manipulation or parsing
+3. File system operations beyond basic reads/writes
+4. Logic that would benefit from unit testing
+5. Code that's difficult to read/maintain in YAML format
+
+## Which Module to Use
+
+### ci.psm1 (`tools/ci.psm1`)
+**Purpose**: CI/CD-specific operations and workflows
+
+**Use for**:
+- Build orchestration (invoking builds, tests, packaging)
+- CI environment setup and configuration
+- Test execution and result processing
+- Artifact handling and publishing
+- CI-specific validations and checks
+- Environment variable management for CI
+
+**Examples**:
+- `Invoke-CIBuild` - Orchestrates build process
+- `Invoke-CITest` - Runs Pester tests
+- `Test-MergeConflictMarker` - Validates files for conflicts
+- `Set-BuildVariable` - Manages CI variables
+
+**When NOT to use**:
+- Core build operations (use build.psm1)
+- Package creation logic (use packaging.psm1)
+- Platform-specific build steps
+
+### build.psm1 (`build.psm1`)
+**Purpose**: Core build operations and utilities
+
+**Use for**:
+- Compiling source code
+- Resource generation
+- Build configuration management
+- Core build utilities (New-PSOptions, Get-PSOutput, etc.)
+- Bootstrap operations
+- Cross-platform build helpers
+
+**Examples**:
+- `Start-PSBuild` - Main build function
+- `Start-PSBootstrap` - Bootstrap dependencies
+- `New-PSOptions` - Create build configuration
+- `Start-ResGen` - Generate resources
+
+**When NOT to use**:
+- CI workflow orchestration (use ci.psm1)
+- Package creation (use packaging.psm1)
+- Test execution
+
+### packaging.psm1 (`tools/packaging/packaging.psm1`)
+**Purpose**: Package creation and distribution
+
+**Use for**:
+- Creating distribution packages (MSI, RPM, DEB, etc.)
+- Package-specific metadata generation
+- Package signing operations
+- Platform-specific packaging logic
+
+**Examples**:
+- `Start-PSPackage` - Create packages
+- `New-MSIPackage` - Create Windows MSI
+- `New-DotnetSdkContainerFxdPackage` - Create container packages
+
+**When NOT to use**:
+- Building binaries (use build.psm1)
+- Running tests (use ci.psm1)
+- General utilities
+
+## Best Practices
+
+### Keep YAML Minimal
+```yaml
+# ❌ Bad - too much logic in YAML
+- name: Check files
+ shell: pwsh
+ run: |
+ $files = Get-ChildItem -Recurse
+ foreach ($file in $files) {
+ $content = Get-Content $file -Raw
+ if ($content -match $pattern) {
+ # ... complex processing ...
+ }
+ }
+
+# ✅ Good - call function from module
+- name: Check files
+ shell: pwsh
+ run: |
+ Import-Module ./tools/ci.psm1
+ Test-SomeCondition -Path ${{ github.workspace }}
+```
+
+### Document Functions
+Always include comment-based help for functions:
+```powershell
+function Test-MyFunction
+{
+ <#
+ .SYNOPSIS
+ Brief description
+ .DESCRIPTION
+ Detailed description
+ .PARAMETER ParameterName
+ Parameter description
+ .EXAMPLE
+ Test-MyFunction -ParameterName Value
+ #>
+ [CmdletBinding()]
+ param(
+ [Parameter(Mandatory)]
+ [string] $ParameterName
+ )
+ # Implementation
+}
+```
+
+### Error Handling
+Use proper error handling in modules:
+```powershell
+try {
+ # Operation
+}
+catch {
+ Write-Error "Detailed error message: $_"
+ throw
+}
+```
+
+### Verbose Output
+Use `Write-Verbose` for debugging information:
+```powershell
+Write-Verbose "Processing file: $filePath"
+```
+
+## Module Dependencies
+
+- **ci.psm1** imports both `build.psm1` and `packaging.psm1`
+- **build.psm1** is standalone (minimal dependencies)
+- **packaging.psm1** imports `build.psm1`
+
+When adding new functions, consider these import relationships to avoid circular dependencies.
+
+## Testing Modules
+
+Functions in modules should be testable:
+```powershell
+# Test locally
+Import-Module ./tools/ci.psm1 -Force
+Test-MyFunction -Parameter Value
+
+# Can be unit tested with Pester
+Describe "Test-MyFunction" {
+ It "Should return expected result" {
+ # Test implementation
+ }
+}
+```
+
+## Migration Checklist
+
+When moving code from YAML to a module:
+
+1. ✅ Determine which module is appropriate (ci, build, or packaging)
+2. ✅ Create function with proper parameter validation
+3. ✅ Add comment-based help documentation
+4. ✅ Use `[CmdletBinding()]` for advanced function features
+5. ✅ Include error handling
+6. ✅ Add verbose output for debugging
+7. ✅ Test the function independently
+8. ✅ Update YAML to call the new function
+9. ✅ Verify the workflow still works end-to-end
+
+## References
+
+- PowerShell Advanced Functions: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_functions_advanced
+- Comment-Based Help: https://learn.microsoft.com/powershell/scripting/developer/help/writing-help-for-windows-powershell-scripts-and-functions
diff --git a/.github/instructions/powershell-parameter-naming.instructions.md b/.github/instructions/powershell-parameter-naming.instructions.md
new file mode 100644
index 00000000000..155fd1a85c3
--- /dev/null
+++ b/.github/instructions/powershell-parameter-naming.instructions.md
@@ -0,0 +1,69 @@
+---
+applyTo: '**/*.ps1, **/*.psm1'
+description: Naming conventions for PowerShell parameters
+---
+
+# PowerShell Parameter Naming Conventions
+
+## Purpose
+
+This instruction defines the naming conventions for parameters in PowerShell scripts and modules. Consistent parameter naming improves code readability, maintainability, and usability for users of PowerShell cmdlets and functions.
+
+## Parameter Naming Rules
+
+### General Conventions
+- **Singular Nouns**: Use singular nouns for parameter names even if the parameter is expected to handle multiple values (e.g., `File` instead of `Files`).
+- **Use PascalCase**: Parameter names must use PascalCase (e.g., `ParameterName`).
+- **Descriptive Names**: Parameter names should be descriptive and convey their purpose clearly (e.g., `FilePath`, `UserName`).
+- **Avoid Abbreviations**: Avoid using abbreviations unless they are widely recognized (e.g., `ID` for Identifier).
+- **Avoid Reserved Words**: Do not use PowerShell reserved words as parameter names (e.g., `if`, `else`, `function`).
+
+### Units and Precision
+- **Include Units in Parameter Names**: When a parameter represents a value with units, include the unit in the parameter name for clarity:
+ - `TimeoutSec` instead of `Timeout`
+ - `RetryIntervalSec` instead of `RetryInterval`
+ - `MaxSizeBytes` instead of `MaxSize`
+- **Use Full Words for Clarity**: Spell out common terms to match PowerShell conventions:
+ - `MaximumRetryCount` instead of `MaxRetries`
+ - `MinimumLength` instead of `MinLength`
+
+### Alignment with Built-in Cmdlets
+- **Follow Existing PowerShell Conventions**: When your parameter serves a similar purpose to a built-in cmdlet parameter, use the same or similar naming:
+ - Match `Invoke-WebRequest` parameters when making HTTP requests: `TimeoutSec`, `MaximumRetryCount`, `RetryIntervalSec`
+ - Follow common parameter patterns like `Path`, `Force`, `Recurse`, `WhatIf`, `Confirm`
+- **Consistency Within Scripts**: If multiple parameters relate to the same concept, use consistent naming patterns (e.g., `TimeoutSec`, `RetryIntervalSec` both use `Sec` suffix).
+
+## Examples
+
+### Good Parameter Names
+```powershell
+param(
+ [string[]]$File, # Singular, even though it accepts arrays
+ [int]$TimeoutSec = 30, # Unit included
+ [int]$MaximumRetryCount = 2, # Full word "Maximum"
+ [int]$RetryIntervalSec = 2, # Consistent with TimeoutSec
+ [string]$Path, # Standard PowerShell convention
+ [switch]$Force # Common PowerShell parameter
+)
+```
+
+### Names to Avoid
+```powershell
+param(
+ [string[]]$Files, # Should be singular: File
+ [int]$Timeout = 30, # Missing unit: TimeoutSec
+ [int]$MaxRetries = 2, # Should be: MaximumRetryCount
+ [int]$RetryInterval = 2, # Missing unit: RetryIntervalSec
+ [string]$FileLoc, # Avoid abbreviations: FilePath
+ [int]$Max # Ambiguous: MaximumWhat?
+)
+```
+
+## Exceptions
+- **Common Terms**: Some common terms may be used in plural form if they are widely accepted in the context (e.g., `Credentials`, `Permissions`).
+- **Legacy Code**: Existing code that does not follow these conventions may be exempted to avoid breaking changes, but new code should adhere to these guidelines.
+- **Well Established Naming Patterns**: If a naming pattern is well established in the PowerShell community, it may be used even if it does not strictly adhere to these guidelines.
+
+## References
+- [PowerShell Cmdlet Design Guidelines](https://learn.microsoft.com/powershell/scripting/developer/cmdlet/strongly-encouraged-development-guidelines)
+- [About Parameters - PowerShell Documentation](https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_parameters)
diff --git a/.github/instructions/start-native-execution.instructions.md b/.github/instructions/start-native-execution.instructions.md
new file mode 100644
index 00000000000..347e496b3bf
--- /dev/null
+++ b/.github/instructions/start-native-execution.instructions.md
@@ -0,0 +1,149 @@
+---
+applyTo:
+ - "**/*.ps1"
+ - "**/*.psm1"
+---
+
+# Using Start-NativeExecution for Native Command Execution
+
+## Purpose
+
+`Start-NativeExecution` is the standard function for executing native commands (external executables) in PowerShell scripts within this repository. It provides consistent error handling and better diagnostics when native commands fail.
+
+## When to Use
+
+Use `Start-NativeExecution` whenever you need to:
+- Execute external commands (e.g., `git`, `dotnet`, `pkgbuild`, `productbuild`, `fpm`, `rpmbuild`)
+- Ensure proper exit code checking
+- Get better error messages with caller information
+- Handle verbose output on error
+
+## Basic Usage
+
+```powershell
+Start-NativeExecution {
+ git clone https://github.com/PowerShell/PowerShell.git
+}
+```
+
+## With Parameters
+
+Use backticks for line continuation within the script block:
+
+```powershell
+Start-NativeExecution {
+ pkgbuild --root $pkgRoot `
+ --identifier $pkgIdentifier `
+ --version $Version `
+ --scripts $scriptsDir `
+ $outputPath
+}
+```
+
+## Common Parameters
+
+### -VerboseOutputOnError
+
+Captures command output and displays it only if the command fails:
+
+```powershell
+Start-NativeExecution -VerboseOutputOnError {
+ dotnet build --configuration Release
+}
+```
+
+### -IgnoreExitcode
+
+Allows the command to fail without throwing an exception:
+
+```powershell
+Start-NativeExecution -IgnoreExitcode {
+ git diff --exit-code # Returns 1 if differences exist
+}
+```
+
+## Availability
+
+The function is defined in `tools/buildCommon/startNativeExecution.ps1` and is available in:
+- `build.psm1` (dot-sourced automatically)
+- `tools/packaging/packaging.psm1` (dot-sourced automatically)
+- Test modules that include `HelpersCommon.psm1`
+
+To use in other scripts, dot-source the function:
+
+```powershell
+. "$PSScriptRoot/../buildCommon/startNativeExecution.ps1"
+```
+
+## Error Handling
+
+When a native command fails (non-zero exit code), `Start-NativeExecution`:
+1. Captures the exit code
+2. Identifies the calling location (file and line number)
+3. Throws a descriptive error with full context
+
+Example error message:
+```
+Execution of {git clone ...} by /path/to/script.ps1: line 42 failed with exit code 1
+```
+
+## Examples from the Codebase
+
+### Git Operations
+```powershell
+Start-NativeExecution {
+ git fetch --tags --quiet upstream
+}
+```
+
+### Build Operations
+```powershell
+Start-NativeExecution -VerboseOutputOnError {
+ dotnet publish --configuration Release
+}
+```
+
+### Packaging Operations
+```powershell
+Start-NativeExecution -VerboseOutputOnError {
+ pkgbuild --root $pkgRoot --identifier $pkgId --version $version $outputPath
+}
+```
+
+### Permission Changes
+```powershell
+Start-NativeExecution {
+ find $staging -type d | xargs chmod 755
+ find $staging -type f | xargs chmod 644
+}
+```
+
+## Anti-Patterns
+
+**Don't do this:**
+```powershell
+& somecommand $args
+if ($LASTEXITCODE -ne 0) {
+ throw "Command failed"
+}
+```
+
+**Do this instead:**
+```powershell
+Start-NativeExecution {
+ somecommand $args
+}
+```
+
+## Best Practices
+
+1. **Always use Start-NativeExecution** for native commands to ensure consistent error handling
+2. **Use -VerboseOutputOnError** for commands with useful diagnostic output
+3. **Use backticks for readability** when commands have multiple arguments
+4. **Don't capture output unnecessarily** - let the function handle it
+5. **Use -IgnoreExitcode sparingly** - only when non-zero exit codes are expected and acceptable
+
+## Related Documentation
+
+- Source: `tools/buildCommon/startNativeExecution.ps1`
+- Blog post: https://mnaoumov.wordpress.com/2015/01/11/execution-of-external-commands-in-powershell-done-right/
diff --git a/.github/instructions/start-psbuild-basics.md b/.github/instructions/start-psbuild-basics.md
new file mode 100644
index 00000000000..ae216a1584d
--- /dev/null
+++ b/.github/instructions/start-psbuild-basics.md
@@ -0,0 +1,92 @@
+# Start-PSBuild Basics
+
+## Purpose
+
+`Start-PSBuild` builds PowerShell from source. It's defined in `build.psm1` and used in CI/CD workflows.
+
+## Default Usage
+
+For most scenarios, use with no parameters:
+
+```powershell
+Import-Module ./tools/ci.psm1
+Start-PSBuild
+```
+
+**Default behavior:**
+- Configuration: `Debug`
+- PSModuleRestore: Enabled
+- Runtime: Auto-detected for platform
+
+## Common Configurations
+
+### Debug Build (Default)
+
+```powershell
+Start-PSBuild
+```
+
+Use for:
+- Testing (xUnit, Pester)
+- Development
+- Debugging
+
+### Release Build
+
+```powershell
+Start-PSBuild -Configuration 'Release'
+```
+
+Use for:
+- Production packages
+- Distribution
+- Performance testing
+
+### Code Coverage Build
+
+```powershell
+Start-PSBuild -Configuration 'CodeCoverage'
+```
+
+Use for:
+- Code coverage analysis
+- Test coverage reports
+
+## Common Parameters
+
+### -Configuration
+
+Values: `Debug`, `Release`, `CodeCoverage`, `StaticAnalysis`
+
+Default: `Debug`
+
+### -CI
+
+Restores Pester module for CI environments.
+
+```powershell
+Start-PSBuild -CI
+```
+
+### -PSModuleRestore
+
+Now enabled by default. Use `-NoPSModuleRestore` to skip.
+
+### -ReleaseTag
+
+Specifies version tag for release builds:
+
+```powershell
+$releaseTag = Get-ReleaseTag
+Start-PSBuild -Configuration 'Release' -ReleaseTag $releaseTag
+```
+
+## Workflow Example
+
+```yaml
+- name: Build PowerShell
+ shell: pwsh
+ run: |
+ Import-Module ./tools/ci.psm1
+ Start-PSBuild
+```
diff --git a/.github/instructions/troubleshooting-builds.md b/.github/instructions/troubleshooting-builds.md
new file mode 100644
index 00000000000..37f5df00912
--- /dev/null
+++ b/.github/instructions/troubleshooting-builds.md
@@ -0,0 +1,92 @@
+# Troubleshooting Build Issues
+
+## Git Describe Error
+
+**Error:**
+```
+error MSB3073: The command "git describe --abbrev=60 --long" exited with code 128.
+```
+
+**Cause:** Insufficient git history (shallow clone)
+
+**Solution:** Add `fetch-depth: 1000` to checkout step
+
+```yaml
+- name: Checkout
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 1000
+```
+
+## Version Information Incorrect
+
+**Symptom:** Build produces wrong version numbers
+
+**Cause:** Git tags not synchronized
+
+**Solution:** Run `Sync-PSTags -AddRemoteIfMissing`:
+
+```yaml
+- name: Bootstrap
+ shell: pwsh
+ run: |
+ Import-Module ./tools/ci.psm1
+ Invoke-CIInstall -SkipUser
+ Sync-PSTags -AddRemoteIfMissing
+```
+
+## PowerShell Binary Not Built
+
+**Error:**
+```
+Exception: CoreCLR pwsh.exe was not built
+```
+
+**Causes:**
+1. Build failed (check logs)
+2. Wrong configuration used
+3. Build output location incorrect
+
+**Solutions:**
+1. Check build logs for errors
+2. Verify correct configuration for use case
+3. Use default parameters: `Start-PSBuild`
+
+## Module Restore Issues
+
+**Symptom:** Slow build or module restore failures
+
+**Causes:**
+- Network issues
+- Module cache problems
+- Package source unavailable
+
+**Solutions:**
+1. Retry the build
+2. Check network connectivity
+3. Use `-NoPSModuleRestore` if modules not needed
+4. Clear package cache if persistent
+
+## .NET SDK Not Found
+
+**Symptom:** Build can't find .NET SDK
+
+**Solution:** Ensure .NET setup step runs first:
+
+```yaml
+- name: Setup .NET
+ uses: actions/setup-dotnet@v4
+ with:
+ global-json-file: ./global.json
+```
+
+## Bootstrap Failures
+
+**Symptom:** Invoke-CIInstall fails
+
+**Causes:**
+- Missing dependencies
+- Network issues
+- Platform-specific requirements not met
+
+**Solution:** Check prerequisites for your platform in build system docs
diff --git a/.github/instructions/workflow-prerequisites.md b/.github/instructions/workflow-prerequisites.md
new file mode 100644
index 00000000000..fe88abb384f
--- /dev/null
+++ b/.github/instructions/workflow-prerequisites.md
@@ -0,0 +1,91 @@
+# 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
+```
diff --git a/.github/workflows/AssignPrs.yml b/.github/workflows/AssignPrs.yml
deleted file mode 100644
index a01c0bb0950..00000000000
--- a/.github/workflows/AssignPrs.yml
+++ /dev/null
@@ -1,30 +0,0 @@
-name: Auto Assign PR Maintainer
-on:
- issues:
- types: [opened, edited]
-permissions:
- contents: read
-
-jobs:
- run:
- if: github.repository_owner == 'PowerShell'
- runs-on: ubuntu-latest
- permissions:
- issues: write
- pull-requests: write
- steps:
- - uses: wow-actions/auto-assign@67fafa03df61d7e5f201734a2fa60d1ab111880d # v3.0.2
- if: github.event.issue.pull_request
- with:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- # using the `org/team_slug` or `/team_slug` syntax to add git team as reviewers
- assignees: |
- TravisEz13
- daxian-dbw
- adityapatwardhan
- iSazonov
- SeeminglyScience
- skipDraft: true
- skipKeywords: wip, draft
- addReviewers: false
- numberOfAssignees: 1
diff --git a/.github/workflows/analyze-reusable.yml b/.github/workflows/analyze-reusable.yml
new file mode 100644
index 00000000000..10b2f0893a3
--- /dev/null
+++ b/.github/workflows/analyze-reusable.yml
@@ -0,0 +1,77 @@
+name: CodeQL Analysis (Reusable)
+
+on:
+ workflow_call:
+ inputs:
+ runner_os:
+ description: 'Runner OS for CodeQL analysis'
+ type: string
+ required: false
+ default: ubuntu-latest
+
+permissions:
+ actions: read # for github/codeql-action/init to get workflow details
+ contents: read # for actions/checkout to fetch code
+ security-events: write # for github/codeql-action/analyze to upload SARIF results
+
+env:
+ DOTNET_CLI_TELEMETRY_OPTOUT: 1
+ DOTNET_NOLOGO: 1
+ POWERSHELL_TELEMETRY_OPTOUT: 1
+ __SuppressAnsiEscapeSequences: 1
+ nugetMultiFeedWarnLevel: none
+
+jobs:
+ analyze:
+ name: Analyze
+ runs-on: ${{ inputs.runner_os }}
+
+ strategy:
+ fail-fast: false
+ matrix:
+ # Override automatic language detection by changing the below list
+ # Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python']
+ language: ['csharp']
+ # Learn more...
+ # https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
+ with:
+ fetch-depth: '0'
+
+ - uses: actions/setup-dotnet@v5
+ with:
+ global-json-file: ./global.json
+
+ # Initializes the CodeQL tools for scanning.
+ - name: Initialize CodeQL
+ uses: github/codeql-action/init@4e94bd11f71e507f7f87df81788dff88d1dacbfb # v3.29.5
+ with:
+ languages: ${{ matrix.language }}
+ # If you wish to specify custom queries, you can do so here or in a config file.
+ # By default, queries listed here will override any specified in a config file.
+ # Prefix the list here with "+" to use these queries and those in the config file.
+ # queries: ./path/to/local/query, your-org/your-repo/queries@main
+
+ - run: |
+ Import-Module .\tools\ci.psm1
+ Show-Environment
+ name: Capture Environment
+ shell: pwsh
+
+ - run: |
+ Import-Module .\tools\ci.psm1
+ Invoke-CIInstall -SkipUser
+ name: Bootstrap
+ shell: pwsh
+
+ - run: |
+ Import-Module .\tools\ci.psm1
+ Invoke-CIBuild -Configuration 'StaticAnalysis'
+ name: Build
+ shell: pwsh
+
+ - name: Perform CodeQL Analysis
+ uses: github/codeql-action/analyze@4e94bd11f71e507f7f87df81788dff88d1dacbfb # v3.29.5
diff --git a/.github/workflows/createReminders.yml b/.github/workflows/createReminders.yml
deleted file mode 100644
index bab5342fe0b..00000000000
--- a/.github/workflows/createReminders.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-name: 'Create reminder'
-
-on:
- issue_comment:
- types: [created, edited]
-
-permissions:
- contents: read
-
-jobs:
- reminder:
- if: github.repository_owner == 'PowerShell'
-
- permissions:
- issues: write # for agrc/create-reminder-action to set reminders on issues
- pull-requests: write # for agrc/create-reminder-action to set reminders on PRs
- runs-on: ubuntu-latest
-
- steps:
- - name: check for reminder
- uses: agrc/create-reminder-action@30624e347adbc7ff2dd287ad0632499552e048e8 # v1.1.22
diff --git a/.github/workflows/linux-ci.yml b/.github/workflows/linux-ci.yml
index 30f5acd5619..4146725fbb1 100644
--- a/.github/workflows/linux-ci.yml
+++ b/.github/workflows/linux-ci.yml
@@ -53,6 +53,8 @@ jobs:
# Set job outputs to values from filter step
outputs:
source: ${{ steps.filter.outputs.source }}
+ buildModuleChanged: ${{ steps.filter.outputs.buildModuleChanged }}
+ packagingChanged: ${{ steps.filter.outputs.packagingChanged }}
steps:
- name: checkout
uses: actions/checkout@v5
@@ -65,11 +67,25 @@ jobs:
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ merge_conflict_check:
+ name: Check for Merge Conflict Markers
+ runs-on: ubuntu-latest
+ if: github.event_name == 'pull_request' && (startsWith(github.repository_owner, 'azure') || github.repository_owner == 'PowerShell')
+ permissions:
+ pull-requests: read
+ contents: read
+ steps:
+ - name: checkout
+ uses: actions/checkout@v5
+
+ - name: Check for merge conflict markers
+ uses: "./.github/actions/infrastructure/merge-conflict-checker"
+
ci_build:
name: Build PowerShell
runs-on: ubuntu-latest
needs: changes
- if: ${{ needs.changes.outputs.source == 'true' }}
+ if: ${{ needs.changes.outputs.source == 'true' || needs.changes.outputs.buildModuleChanged == 'true' }}
steps:
- name: checkout
uses: actions/checkout@v5
@@ -83,7 +99,7 @@ jobs:
needs:
- ci_build
- changes
- if: ${{ needs.changes.outputs.source == 'true' }}
+ if: ${{ needs.changes.outputs.source == 'true' || needs.changes.outputs.buildModuleChanged == 'true' }}
runs-on: ubuntu-latest
steps:
- name: checkout
@@ -95,12 +111,13 @@ jobs:
with:
purpose: UnelevatedPesterTests
tagSet: CI
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
linux_test_elevated_ci:
name: Linux Elevated CI
needs:
- ci_build
- changes
- if: ${{ needs.changes.outputs.source == 'true' }}
+ if: ${{ needs.changes.outputs.source == 'true' || needs.changes.outputs.buildModuleChanged == 'true' }}
runs-on: ubuntu-latest
steps:
- name: checkout
@@ -112,12 +129,13 @@ jobs:
with:
purpose: ElevatedPesterTests
tagSet: CI
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
linux_test_unelevated_others:
name: Linux Unelevated Others
needs:
- ci_build
- changes
- if: ${{ needs.changes.outputs.source == 'true' }}
+ if: ${{ needs.changes.outputs.source == 'true' || needs.changes.outputs.buildModuleChanged == 'true' }}
runs-on: ubuntu-latest
steps:
- name: checkout
@@ -129,12 +147,13 @@ jobs:
with:
purpose: UnelevatedPesterTests
tagSet: Others
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
linux_test_elevated_others:
name: Linux Elevated Others
needs:
- ci_build
- changes
- if: ${{ needs.changes.outputs.source == 'true' }}
+ if: ${{ needs.changes.outputs.source == 'true' || needs.changes.outputs.buildModuleChanged == 'true' }}
runs-on: ubuntu-latest
steps:
- name: checkout
@@ -146,107 +165,98 @@ jobs:
with:
purpose: ElevatedPesterTests
tagSet: Others
- verify_xunit:
- name: Verify xUnit test results
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ xunit_tests:
+ name: xUnit Tests
needs:
- - ci_build
- changes
- if: ${{ needs.changes.outputs.source == 'true' }}
+ if: ${{ needs.changes.outputs.source == 'true' || needs.changes.outputs.buildModuleChanged == 'true' }}
+ uses: ./.github/workflows/xunit-tests.yml
+ with:
+ runner_os: ubuntu-latest
+ test_results_artifact_name: testResults-xunit
+
+ infrastructure_tests:
+ name: Infrastructure Tests
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@v5
with:
- fetch-depth: 1000
- - name: Verify xUnit test results
- uses: "./.github/actions/test/verify_xunit"
+ fetch-depth: 1
- analyze:
- permissions:
- actions: read # for github/codeql-action/init to get workflow details
- contents: read # for actions/checkout to fetch code
- security-events: write # for github/codeql-action/analyze to upload SARIF results
- name: Analyze
- runs-on: ubuntu-latest
- needs: changes
- if: ${{ needs.changes.outputs.source == 'true' }}
+ - name: Install Pester
+ shell: pwsh
+ run: |
+ Import-Module ./tools/ci.psm1
+ Install-CIPester
+
+ - name: Run Infrastructure Tests
+ shell: pwsh
+ run: |
+ $testResultsFolder = Join-Path $PWD "testResults"
+ New-Item -ItemType Directory -Path $testResultsFolder -Force | Out-Null
+
+ $config = New-PesterConfiguration
+ $config.Run.Path = './test/infrastructure/'
+ $config.Run.PassThru = $true
+ $config.TestResult.Enabled = $true
+ $config.TestResult.OutputFormat = 'NUnitXml'
+ $config.TestResult.OutputPath = "$testResultsFolder/InfrastructureTests.xml"
+ $config.Output.Verbosity = 'Detailed'
+
+ $result = Invoke-Pester -Configuration $config
+
+ if ($result.FailedCount -gt 0 -or $result.Result -eq 'Failed') {
+ throw "Infrastructure tests failed"
+ }
- strategy:
- fail-fast: false
- matrix:
- # Override automatic language detection by changing the below list
- # Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python']
- language: ['csharp']
- # Learn more...
- # https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection
+ - name: Publish Test Results
+ uses: "./.github/actions/test/process-pester-results"
+ if: always()
+ with:
+ name: "InfrastructureTests"
+ testResultsFolder: "${{ github.workspace }}/testResults"
+ ## Temporarily disable the CodeQL analysis on Linux as it doesn't work for .NET SDK 10-rc.2.
+ # analyze:
+ # name: CodeQL Analysis
+ # needs: changes
+ # if: ${{ needs.changes.outputs.source == 'true' }}
+ # uses: ./.github/workflows/analyze-reusable.yml
+ # permissions:
+ # actions: read
+ # contents: read
+ # security-events: write
+ # with:
+ linux_packaging:
+ name: Linux Packaging
+ needs:
+ - ci_build
+ - changes
+ if: ${{ needs.changes.outputs.packagingChanged == 'true' }}
+ runs-on: ubuntu-latest
steps:
- - name: Checkout repository
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- with:
- fetch-depth: '0'
-
- - uses: actions/setup-dotnet@v5
- with:
- global-json-file: ./global.json
-
- # Initializes the CodeQL tools for scanning.
- - name: Initialize CodeQL
- uses: github/codeql-action/init@192325c86100d080feab897ff886c34abd4c83a3 # v3.29.5
- with:
- languages: ${{ matrix.language }}
- # If you wish to specify custom queries, you can do so here or in a config file.
- # By default, queries listed here will override any specified in a config file.
- # Prefix the list here with "+" to use these queries and those in the config file.
- # queries: ./path/to/local/query, your-org/your-repo/queries@main
-
- - run: |
- Get-ChildItem -Path env: | Out-String -width 9999 -Stream | write-Verbose -Verbose
- name: Capture Environment
- shell: pwsh
-
- - run: |
- Import-Module .\tools\ci.psm1
- Invoke-CIInstall -SkipUser
- name: Bootstrap
- shell: pwsh
-
- - run: |
- Import-Module .\tools\ci.psm1
- Invoke-CIBuild
- name: Build
- shell: pwsh
-
- - name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@192325c86100d080feab897ff886c34abd4c83a3 # v3.29.5
+ - name: checkout
+ uses: actions/checkout@v5
+ with:
+ fetch-depth: 0
+ - name: Linux Packaging
+ uses: "./.github/actions/test/linux-packaging"
ready_to_merge:
name: Linux ready to merge
needs:
- - verify_xunit
+ - xunit_tests
- linux_test_elevated_ci
- linux_test_elevated_others
- linux_test_unelevated_ci
- linux_test_unelevated_others
- - analyze
+ - linux_packaging
+ - merge_conflict_check
+ - infrastructure_tests
+ # - analyze
if: always()
uses: PowerShell/compliance/.github/workflows/ready-to-merge.yml@v1.0.0
with:
needs_context: ${{ toJson(needs) }}
- # TODO: Enable this when we have a Linux packaging workflow
-
- # ERROR: While executing gem ... (Gem::FilePermissionError)
- # You don't have write permissions for the /var/lib/gems/2.7.0 directory.
- # WARNING: Installation of gem dotenv 2.8.1 failed! Must resolve manually.
-
- # linux_packaging:
- # name: Attempt Linux Packaging
- # needs: ci_build
- # runs-on: ubuntu-20.04
- # steps:
- # - name: checkout
- # uses: actions/checkout@v5
- # with:
- # fetch-depth: 1000
- # - name: Verify xUnit test results
- # uses: "./.github/actions/test/linux-packaging"
diff --git a/.github/workflows/macos-ci.yml b/.github/workflows/macos-ci.yml
index 0007d550f06..85549d04229 100644
--- a/.github/workflows/macos-ci.yml
+++ b/.github/workflows/macos-ci.yml
@@ -53,6 +53,7 @@ jobs:
# Set job outputs to values from filter step
outputs:
source: ${{ steps.filter.outputs.source }}
+ buildModuleChanged: ${{ steps.filter.outputs.buildModuleChanged }}
steps:
- name: checkout
uses: actions/checkout@v5
@@ -67,7 +68,7 @@ jobs:
name: Build PowerShell
runs-on: macos-15-large
needs: changes
- if: ${{ needs.changes.outputs.source == 'true' }}
+ if: ${{ needs.changes.outputs.source == 'true' || needs.changes.outputs.buildModuleChanged == 'true' }}
steps:
- name: checkout
uses: actions/checkout@v5
@@ -80,7 +81,7 @@ jobs:
needs:
- ci_build
- changes
- if: ${{ needs.changes.outputs.source == 'true' }}
+ if: ${{ needs.changes.outputs.source == 'true' || needs.changes.outputs.buildModuleChanged == 'true' }}
runs-on: macos-15-large
steps:
- name: checkout
@@ -92,12 +93,13 @@ jobs:
with:
purpose: UnelevatedPesterTests
tagSet: CI
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
macos_test_elevated_ci:
name: macOS Elevated CI
needs:
- ci_build
- changes
- if: ${{ needs.changes.outputs.source == 'true' }}
+ if: ${{ needs.changes.outputs.source == 'true' || needs.changes.outputs.buildModuleChanged == 'true' }}
runs-on: macos-15-large
steps:
- name: checkout
@@ -109,12 +111,13 @@ jobs:
with:
purpose: ElevatedPesterTests
tagSet: CI
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
macos_test_unelevated_others:
name: macOS Unelevated Others
needs:
- ci_build
- changes
- if: ${{ needs.changes.outputs.source == 'true' }}
+ if: ${{ needs.changes.outputs.source == 'true' || needs.changes.outputs.buildModuleChanged == 'true' }}
runs-on: macos-15-large
steps:
- name: checkout
@@ -126,12 +129,13 @@ jobs:
with:
purpose: UnelevatedPesterTests
tagSet: Others
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
macos_test_elevated_others:
name: macOS Elevated Others
needs:
- ci_build
- changes
- if: ${{ needs.changes.outputs.source == 'true' }}
+ if: ${{ needs.changes.outputs.source == 'true' || needs.changes.outputs.buildModuleChanged == 'true' }}
runs-on: macos-15-large
steps:
- name: checkout
@@ -143,40 +147,95 @@ jobs:
with:
purpose: ElevatedPesterTests
tagSet: Others
- verify_xunit:
- name: Verify xUnit test results
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ xunit_tests:
+ name: xUnit Tests
needs:
- - ci_build
- changes
- if: ${{ needs.changes.outputs.source == 'true' }}
- runs-on: ubuntu-latest
- steps:
- - name: checkout
- uses: actions/checkout@v5
- with:
- fetch-depth: 1000
- - name: Verify xUnit test results
- uses: "./.github/actions/test/verify_xunit"
+ if: ${{ needs.changes.outputs.source == 'true' || needs.changes.outputs.buildModuleChanged == 'true' }}
+ uses: ./.github/workflows/xunit-tests.yml
+ with:
+ runner_os: macos-15-large
+ test_results_artifact_name: testResults-xunit
PackageMac-macos_packaging:
- name: macOS packaging (bootstrap only)
+ name: macOS packaging and testing
needs:
- changes
- if: ${{ needs.changes.outputs.source == 'true' }}
+ if: ${{ needs.changes.outputs.source == 'true' || needs.changes.outputs.buildModuleChanged == 'true' }}
runs-on:
- macos-15-large
steps:
- name: checkout
uses: actions/checkout@v5
+ with:
+ fetch-depth: 1000
+ - uses: actions/setup-dotnet@v4
+ with:
+ global-json-file: ./global.json
- name: Bootstrap packaging
- if: success() || failure()
+ if: success()
run: |-
import-module ./build.psm1
start-psbootstrap -Scenario package
shell: pwsh
+ - name: Build PowerShell and Create macOS package
+ if: success()
+ run: |-
+ import-module ./build.psm1
+ import-module ./tools/ci.psm1
+ import-module ./tools/packaging/packaging.psm1
+ Switch-PSNugetConfig -Source Public
+ Sync-PSTags -AddRemoteIfMissing
+ $releaseTag = Get-ReleaseTag
+ Start-PSBuild -Configuration Release -PSModuleRestore -ReleaseTag $releaseTag
+ $macOSRuntime = if ([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture -eq 'Arm64') { 'osx-arm64' } else { 'osx-x64' }
+ Start-PSPackage -Type osxpkg -ReleaseTag $releaseTag -MacOSRuntime $macOSRuntime -SkipReleaseChecks
+ shell: pwsh
+
+ - name: Install Pester
+ if: success()
+ run: |-
+ Import-Module ./tools/ci.psm1
+ Install-CIPester
+ shell: pwsh
+
+ - name: Test package contents
+ if: success()
+ run: |-
+ $env:PACKAGE_FOLDER = Get-Location
+ $testResultsPath = Join-Path $env:RUNNER_WORKSPACE "testResults"
+ if (-not (Test-Path $testResultsPath)) {
+ New-Item -ItemType Directory -Path $testResultsPath -Force | Out-Null
+ }
+ Import-Module Pester
+ $pesterConfig = New-PesterConfiguration
+ $pesterConfig.Run.Path = './test/packaging/macos/package-validation.tests.ps1'
+ $pesterConfig.Run.PassThru = $true
+ $pesterConfig.Output.Verbosity = 'Detailed'
+ $pesterConfig.TestResult.Enabled = $true
+ $pesterConfig.TestResult.OutputFormat = 'NUnitXml'
+ $pesterConfig.TestResult.OutputPath = Join-Path $testResultsPath "macOSPackage.xml"
+ $result = Invoke-Pester -Configuration $pesterConfig
+ if ($result.FailedCount -gt 0) {
+ throw "Package validation failed with $($result.FailedCount) failed test(s)"
+ }
+ shell: pwsh
+ - name: Publish and Upload Pester Test Results
+ if: always()
+ uses: "./.github/actions/test/process-pester-results"
+ with:
+ name: "macOSPackage"
+ testResultsFolder: "${{ runner.workspace }}/testResults"
+ - name: Upload package artifact
+ if: always()
+ uses: actions/upload-artifact@v4
+ with:
+ name: macos-package
+ path: "*.pkg"
ready_to_merge:
name: macos ready to merge
needs:
- - verify_xunit
+ - xunit_tests
- PackageMac-macos_packaging
- macos_test_elevated_ci
- macos_test_elevated_others
diff --git a/.github/workflows/markdownLink.yml b/.github/workflows/markdownLink.yml
deleted file mode 100644
index 5ad78cf84d4..00000000000
--- a/.github/workflows/markdownLink.yml
+++ /dev/null
@@ -1,51 +0,0 @@
-on:
- pull_request:
- branches:
- - master
-
-name: Check modified markdown files
-permissions:
- contents: read
-
-jobs:
- markdown-link-check:
- runs-on: ubuntu-latest
- if: github.repository_owner == 'PowerShell'
-
- steps:
- - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- - uses: gaurav-nelson/github-action-markdown-link-check@5c5dfc0ac2e225883c0e5f03a85311ec2830d368 # v1
- with:
- use-quiet-mode: 'yes'
- use-verbose-mode: 'yes'
- check-modified-files-only: 'yes'
- config-file: .github/workflows/markdown-link/config.json
- markdown-lint:
- permissions:
- contents: read
- packages: read
- statuses: write
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- with:
- # Full git history is needed to get a proper
- # list of changed files within `super-linter`
- fetch-depth: 0
- - name: Load super-linter configuration
- # Use grep inverse matching to exclude eventual comments in the .env file
- # because the GitHub Actions command to set environment variables doesn't
- # support comments.
- # Ref: https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions#setting-an-environment-variable
- run: grep -v '^#' tools/super-linter/config/super-linter.env >> "$GITHUB_ENV"
- - name: Lint Markdown
- uses: super-linter/super-linter@5119dcd8011e92182ce8219d9e9efc82f16fddb6 # v8.0.0
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- - name: Super-Linter correction instructions
- if: failure()
- uses: actions/github-script@v8
- with:
- script: |
- const message = "Super-Linter found issues in the changed files. Please check the logs for details. You can run the linter locally using the command: `./tools/super-lister/super-lister.ps1`.";
- core.setFailed(message);
diff --git a/.github/workflows/markdownLinkDaily.yml b/.github/workflows/markdownLinkDaily.yml
deleted file mode 100644
index 7f5789ed96d..00000000000
--- a/.github/workflows/markdownLinkDaily.yml
+++ /dev/null
@@ -1,33 +0,0 @@
-# Copyright (c) Microsoft Corporation.
-# Licensed under the MIT license.
-
-name: PowerShell Daily Markdown Link Verification
-
-on:
- workflow_dispatch:
- schedule:
- # At 13:00 UTC every day.
- - cron: '0 13 * * *'
-
-permissions:
- contents: read
-
-jobs:
- markdown-link-check:
- runs-on: ubuntu-latest
- if: github.repository == 'PowerShell/PowerShell'
- steps:
- - name: Checkout
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- - name: Check Links
- uses: gaurav-nelson/github-action-markdown-link-check@5c5dfc0ac2e225883c0e5f03a85311ec2830d368 # v1
- with:
- use-quiet-mode: 'yes'
- use-verbose-mode: 'yes'
- config-file: .github/workflows/markdown-link/config.json
- - name: Microsoft Teams Notifier
- uses: skitionek/notify-microsoft-teams@e7a2493ac87dad8aa7a62f079f295e54ff511d88 # master
- if: failure()
- with:
- webhook_url: ${{ secrets.PS_BUILD_TEAMS_CHANNEL }}
- overwrite: "{title: `Failure in .github/markdownLinkDaily.yml validating links. Look at ${workflow_link}`}"
diff --git a/.github/workflows/processReminders.yml b/.github/workflows/processReminders.yml
deleted file mode 100644
index 18de16159ac..00000000000
--- a/.github/workflows/processReminders.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-name: 'Process reminders'
-
-on:
- schedule:
- - cron: '*/15 * * * *'
- workflow_dispatch:
-
-permissions:
- contents: read
-
-jobs:
- reminder:
- if: github.repository_owner == 'PowerShell'
- permissions:
- issues: write # for agrc/reminder-action to set reminders on issues
- pull-requests: write # for agrc/reminder-action to set reminders on PRs
- runs-on: ubuntu-latest
-
- steps:
- - name: check reminders and notify
- uses: agrc/reminder-action@3095f64f8f0c26c751bee802cb1008ece5953078 # v1.0.18
diff --git a/.github/workflows/verify-markdown-links.yml b/.github/workflows/verify-markdown-links.yml
new file mode 100644
index 00000000000..713160dea21
--- /dev/null
+++ b/.github/workflows/verify-markdown-links.yml
@@ -0,0 +1,32 @@
+name: Verify Markdown Links
+
+on:
+ push:
+ branches: [ main, master, release/v7.6 ]
+ paths:
+ - '**/*.md'
+ - '.github/workflows/verify-markdown-links.yml'
+ - '.github/actions/infrastructure/markdownlinks/**'
+ pull_request:
+ branches: [ main, master, release/v7.6 ]
+ paths:
+ - '**/*.md'
+ schedule:
+ # Run weekly on Sundays at midnight UTC to catch external link rot
+ - cron: '0 0 * * 0'
+ workflow_dispatch:
+
+jobs:
+ verify-markdown-links:
+ name: Verify Markdown Links
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+
+ - name: Verify markdown links
+ id: verify
+ uses: ./.github/actions/infrastructure/markdownlinks
+ with:
+ timeout-sec: 30
+ maximum-retry-count: 2
diff --git a/.github/workflows/windows-ci.yml b/.github/workflows/windows-ci.yml
index 63e6c5ab7a3..df23d5b3c48 100644
--- a/.github/workflows/windows-ci.yml
+++ b/.github/workflows/windows-ci.yml
@@ -41,6 +41,8 @@ env:
POWERSHELL_TELEMETRY_OPTOUT: 1
__SuppressAnsiEscapeSequences: 1
nugetMultiFeedWarnLevel: none
+ SYSTEM_ARTIFACTSDIRECTORY: ${{ github.workspace }}/artifacts
+ BUILD_ARTIFACTSTAGINGDIRECTORY: ${{ github.workspace }}/artifacts
jobs:
changes:
name: Change Detection
@@ -54,6 +56,8 @@ jobs:
# Set job outputs to values from filter step
outputs:
source: ${{ steps.filter.outputs.source }}
+ buildModuleChanged: ${{ steps.filter.outputs.buildModuleChanged }}
+ packagingChanged: ${{ steps.filter.outputs.packagingChanged }}
steps:
- name: checkout
uses: actions/checkout@v5
@@ -67,7 +71,7 @@ jobs:
ci_build:
name: Build PowerShell
needs: changes
- if: ${{ needs.changes.outputs.source == 'true' }}
+ if: ${{ needs.changes.outputs.source == 'true' || needs.changes.outputs.buildModuleChanged == 'true' }}
runs-on: windows-latest
steps:
- name: checkout
@@ -81,7 +85,7 @@ jobs:
needs:
- ci_build
- changes
- if: ${{ needs.changes.outputs.source == 'true' }}
+ if: ${{ needs.changes.outputs.source == 'true' || needs.changes.outputs.buildModuleChanged == 'true' }}
runs-on: windows-latest
steps:
- name: checkout
@@ -93,12 +97,13 @@ jobs:
with:
purpose: UnelevatedPesterTests
tagSet: CI
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
windows_test_elevated_ci:
name: Windows Elevated CI
needs:
- ci_build
- changes
- if: ${{ needs.changes.outputs.source == 'true' }}
+ if: ${{ needs.changes.outputs.source == 'true' || needs.changes.outputs.buildModuleChanged == 'true' }}
runs-on: windows-latest
steps:
- name: checkout
@@ -110,12 +115,13 @@ jobs:
with:
purpose: ElevatedPesterTests
tagSet: CI
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
windows_test_unelevated_others:
name: Windows Unelevated Others
needs:
- ci_build
- changes
- if: ${{ needs.changes.outputs.source == 'true' }}
+ if: ${{ needs.changes.outputs.source == 'true' || needs.changes.outputs.buildModuleChanged == 'true' }}
runs-on: windows-latest
steps:
- name: checkout
@@ -127,12 +133,13 @@ jobs:
with:
purpose: UnelevatedPesterTests
tagSet: Others
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
windows_test_elevated_others:
name: Windows Elevated Others
needs:
- ci_build
- changes
- if: ${{ needs.changes.outputs.source == 'true' }}
+ if: ${{ needs.changes.outputs.source == 'true' || needs.changes.outputs.buildModuleChanged == 'true' }}
runs-on: windows-latest
steps:
- name: checkout
@@ -144,28 +151,43 @@ jobs:
with:
purpose: ElevatedPesterTests
tagSet: Others
- verify_xunit:
- name: Verify xUnit test results
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ xunit_tests:
+ name: xUnit Tests
needs:
- - ci_build
- changes
- if: ${{ needs.changes.outputs.source == 'true' }}
- runs-on: windows-latest
- steps:
- - name: checkout
- uses: actions/checkout@v5
- with:
- fetch-depth: 1000
- - name: Verify xUnit test results
- uses: "./.github/actions/test/verify_xunit"
+ if: ${{ needs.changes.outputs.source == 'true' || needs.changes.outputs.buildModuleChanged == 'true' }}
+ uses: ./.github/workflows/xunit-tests.yml
+ with:
+ runner_os: windows-latest
+ test_results_artifact_name: testResults-xunit
+ analyze:
+ name: CodeQL Analysis
+ needs: changes
+ if: ${{ needs.changes.outputs.source == 'true' || needs.changes.outputs.buildModuleChanged == 'true' }}
+ uses: ./.github/workflows/analyze-reusable.yml
+ permissions:
+ actions: read
+ contents: read
+ security-events: write
+ with:
+ runner_os: windows-latest
+ windows_packaging:
+ name: Windows Packaging
+ needs:
+ - changes
+ if: ${{ needs.changes.outputs.packagingChanged == 'true' }}
+ uses: ./.github/workflows/windows-packaging-reusable.yml
ready_to_merge:
name: windows ready to merge
needs:
- - verify_xunit
+ - xunit_tests
- windows_test_elevated_ci
- windows_test_elevated_others
- windows_test_unelevated_ci
- windows_test_unelevated_others
+ - analyze
+ - windows_packaging
if: always()
uses: PowerShell/compliance/.github/workflows/ready-to-merge.yml@v1.0.0
with:
diff --git a/.github/workflows/windows-packaging-reusable.yml b/.github/workflows/windows-packaging-reusable.yml
new file mode 100644
index 00000000000..6b42a8899ec
--- /dev/null
+++ b/.github/workflows/windows-packaging-reusable.yml
@@ -0,0 +1,89 @@
+name: Windows Packaging (Reusable)
+
+on:
+ workflow_call:
+
+env:
+ GIT_CONFIG_PARAMETERS: "'core.autocrlf=false'"
+ DOTNET_CLI_TELEMETRY_OPTOUT: 1
+ POWERSHELL_TELEMETRY_OPTOUT: 1
+ DOTNET_NOLOGO: 1
+ __SuppressAnsiEscapeSequences: 1
+ nugetMultiFeedWarnLevel: none
+ SYSTEM_ARTIFACTSDIRECTORY: ${{ github.workspace }}/artifacts
+ BUILD_ARTIFACTSTAGINGDIRECTORY: ${{ github.workspace }}/artifacts
+
+jobs:
+ package:
+ name: ${{ matrix.architecture }} - ${{ matrix.channel }}
+ runs-on: windows-latest
+ strategy:
+ fail-fast: false
+ matrix:
+ include:
+ - architecture: x64
+ channel: preview
+ runtimePrefix: win7
+ - architecture: x86
+ channel: stable
+ runtimePrefix: win7
+ - architecture: x86
+ channel: preview
+ runtimePrefix: win7
+ - architecture: arm64
+ channel: preview
+ runtimePrefix: win
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v5
+ with:
+ fetch-depth: 1000
+
+ - name: Capture Environment
+ if: success() || failure()
+ run: |
+ Import-Module .\tools\ci.psm1
+ Show-Environment
+ shell: pwsh
+
+ - name: Capture PowerShell Version Table
+ if: success() || failure()
+ run: |
+ $PSVersionTable
+ shell: pwsh
+
+ - name: Switch to Public Feeds
+ if: success()
+ run: |
+ Import-Module .\tools\ci.psm1
+ Switch-PSNugetConfig -Source Public
+ shell: pwsh
+
+ - name: Setup .NET
+ uses: actions/setup-dotnet@v4
+ with:
+ global-json-file: ./global.json
+
+ - name: Bootstrap
+ if: success()
+ run: |
+ Import-Module .\tools\ci.psm1
+ Invoke-CIInstall -SkipUser
+ shell: pwsh
+
+ - name: Build and Package
+ run: |
+ Import-Module .\tools\ci.psm1
+ New-CodeCoverageAndTestPackage
+ Invoke-CIFinish -Runtime ${{ matrix.runtimePrefix }}-${{ matrix.architecture }} -channel ${{ matrix.channel }}
+ shell: pwsh
+
+ - name: Upload Build Artifacts
+ if: always()
+ uses: actions/upload-artifact@v4
+ with:
+ name: windows-packaging-${{ matrix.architecture }}-${{ matrix.channel }}
+ path: |
+ ${{ github.workspace }}/artifacts/**/*
+ !${{ github.workspace }}/artifacts/**/*.pdb
diff --git a/.github/workflows/xunit-tests.yml b/.github/workflows/xunit-tests.yml
new file mode 100644
index 00000000000..8bf5fd699d0
--- /dev/null
+++ b/.github/workflows/xunit-tests.yml
@@ -0,0 +1,53 @@
+name: xUnit Tests (Reusable)
+
+on:
+ workflow_call:
+ inputs:
+ runner_os:
+ description: 'Runner OS for xUnit tests'
+ type: string
+ required: false
+ default: ubuntu-latest
+ test_results_artifact_name:
+ description: 'Artifact name for xUnit test results directory'
+ type: string
+ required: false
+ default: testResults-xunit
+
+jobs:
+ xunit:
+ name: Run xUnit Tests
+ runs-on: ${{ inputs.runner_os }}
+ 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 and run xUnit tests
+ shell: pwsh
+ run: |
+ Import-Module ./tools/ci.psm1
+ Start-PSBuild
+ Write-Host "Running full xUnit test suite (no skipping)..."
+ Invoke-CIxUnit
+ Write-Host "Completed xUnit test run."
+
+ - name: Upload xUnit results
+ uses: actions/upload-artifact@v4
+ if: always()
+ with:
+ name: ${{ inputs.test_results_artifact_name }}
+ path: ${{ github.workspace }}/xUnitTestResults.xml
diff --git a/.pipelines/EV2Specs/ServiceGroupRoot/Shell/Run/Run.ps1 b/.pipelines/EV2Specs/ServiceGroupRoot/Shell/Run/Run.ps1
index 25a5686b33e..23f91c1bff2 100644
--- a/.pipelines/EV2Specs/ServiceGroupRoot/Shell/Run/Run.ps1
+++ b/.pipelines/EV2Specs/ServiceGroupRoot/Shell/Run/Run.ps1
@@ -354,6 +354,9 @@ try {
$skipPublish = $metadataContent.SkipPublish
$lts = $metadataContent.LTS
+ # Check if this is a rebuild version (e.g., 7.4.13-rebuild.5)
+ $isRebuild = $releaseVersion -match '-rebuild\.'
+
if ($releaseVersion.Contains('-')) {
$channel = 'preview'
$packageNames = @('powershell-preview')
@@ -363,7 +366,8 @@ try {
$packageNames = @('powershell')
}
- if ($lts) {
+ # Only add LTS package if not a rebuild branch
+ if ($lts -and -not $isRebuild) {
$packageNames += @('powershell-lts')
}
diff --git a/.pipelines/MSIXBundle-vPack-Official.yml b/.pipelines/MSIXBundle-vPack-Official.yml
index 8e175c5a6bb..997b7c458be 100644
--- a/.pipelines/MSIXBundle-vPack-Official.yml
+++ b/.pipelines/MSIXBundle-vPack-Official.yml
@@ -99,7 +99,6 @@ extends:
- template: .pipelines/templates/SetVersionVariables.yml@self
parameters:
ReleaseTagVar: $(ReleaseTagVar)
- UseJson: no
- pwsh: |
Write-Verbose -Verbose 'PowerShell Version: $(version)'
diff --git a/.pipelines/PowerShell-Coordinated_Packages-Official.yml b/.pipelines/PowerShell-Coordinated_Packages-Official.yml
index e70b65a9a64..e4de1fe5c21 100644
--- a/.pipelines/PowerShell-Coordinated_Packages-Official.yml
+++ b/.pipelines/PowerShell-Coordinated_Packages-Official.yml
@@ -178,7 +178,6 @@ extends:
parameters:
ReleaseTagVar: $(ReleaseTagVar)
CreateJson: yes
- UseJson: no
- stage: macos
displayName: macOS - build and sign
@@ -297,9 +296,20 @@ extends:
- template: /.pipelines/templates/SetVersionVariables.yml@self
parameters:
ReleaseTagVar: $(ReleaseTagVar)
+ - template: /.pipelines/templates/rebuild-branch-check.yml@self
- powershell: |
$metadata = Get-Content '$(Build.SourcesDirectory)/PowerShell/tools/metadata.json' -Raw | ConvertFrom-Json
- $LTS = $metadata.LTSRelease.Package
+
+ # Use the rebuild branch check from the template
+ $isRebuildBranch = '$(RebuildBranchCheck.IsRebuildBranch)' -eq 'true'
+
+ # Don't mark as LTS release for rebuild branches
+ $LTS = $metadata.LTSRelease.Package -and -not $isRebuildBranch
+
+ if ($isRebuildBranch) {
+ Write-Verbose -Message "Rebuild branch detected, not marking as LTS release" -Verbose
+ }
+
@{ ReleaseVersion = "$(Version)"; LTSRelease = $LTS } | ConvertTo-Json | Out-File "$(Build.StagingDirectory)\release.json"
Get-Content "$(Build.StagingDirectory)\release.json"
diff --git a/.pipelines/PowerShell-Packages-Official.yml b/.pipelines/PowerShell-Packages-Official.yml
index 9c2dee1c571..18ef7b2d14c 100644
--- a/.pipelines/PowerShell-Packages-Official.yml
+++ b/.pipelines/PowerShell-Packages-Official.yml
@@ -127,11 +127,13 @@ extends:
tsaOptionsFile: .config\tsaoptions.json
stages:
- stage: prep
+ displayName: 'Prep BuildInfo+Az'
jobs:
- template: /.pipelines/templates/checkAzureContainer.yml@self
- stage: mac_package
- dependsOn: [prep]
+ displayName: 'macOS Pkg+Sign'
+ dependsOn: []
jobs:
- template: /.pipelines/templates/mac-package-build.yml@self
parameters:
@@ -141,35 +143,65 @@ extends:
parameters:
buildArchitecture: arm64
- - stage: windows_package
- dependsOn: [prep]
+ - stage: windows_package_build
+ displayName: 'Win Pkg (unsigned)'
+ dependsOn: []
jobs:
- - template: /.pipelines/templates/windows-package-build.yml@self
+ - template: /.pipelines/templates/packaging/windows/package.yml@self
parameters:
runtime: x64
- - template: /.pipelines/templates/windows-package-build.yml@self
+ - template: /.pipelines/templates/packaging/windows/package.yml@self
parameters:
runtime: arm64
- - template: /.pipelines/templates/windows-package-build.yml@self
+ - template: /.pipelines/templates/packaging/windows/package.yml@self
parameters:
runtime: x86
- - template: /.pipelines/templates/windows-package-build.yml@self
+ - template: /.pipelines/templates/packaging/windows/package.yml@self
parameters:
runtime: fxdependent
- - template: /.pipelines/templates/windows-package-build.yml@self
+ - template: /.pipelines/templates/packaging/windows/package.yml@self
parameters:
runtime: fxdependentWinDesktop
- - template: /.pipelines/templates/windows-package-build.yml@self
+ - template: /.pipelines/templates/packaging/windows/package.yml@self
+ parameters:
+ runtime: minsize
+
+ - stage: windows_package_sign
+ displayName: 'Win Pkg Sign'
+ dependsOn: [windows_package_build]
+ jobs:
+ - template: /.pipelines/templates/packaging/windows/sign.yml@self
+ parameters:
+ runtime: x64
+
+ - template: /.pipelines/templates/packaging/windows/sign.yml@self
+ parameters:
+ runtime: arm64
+
+ - template: /.pipelines/templates/packaging/windows/sign.yml@self
+ parameters:
+ runtime: x86
+
+ - template: /.pipelines/templates/packaging/windows/sign.yml@self
+ parameters:
+ runtime: fxdependent
+
+ - template: /.pipelines/templates/packaging/windows/sign.yml@self
+ parameters:
+ runtime: fxdependentWinDesktop
+
+ - template: /.pipelines/templates/packaging/windows/sign.yml@self
parameters:
runtime: minsize
- stage: linux_package
- dependsOn: [prep]
+ displayName: 'Linux Pkg+Sign'
+ dependsOn: []
jobs:
- template: /.pipelines/templates/linux-package-build.yml@self
parameters:
@@ -251,17 +283,27 @@ extends:
jobName: minSize
- stage: nupkg
- dependsOn: [prep]
+ displayName: 'NuGet Pkg+Sign'
+ dependsOn: []
jobs:
- template: /.pipelines/templates/nupkg.yml@self
- stage: msixbundle
- displayName: 'Create MSIX Bundle'
- dependsOn: [windows_package]
+ displayName: 'MSIX Bundle+Sign'
+ dependsOn: [windows_package_build] # Only depends on unsigned packages
jobs:
- template: /.pipelines/templates/package-create-msix.yml@self
+ parameters:
+ OfficialBuild: ${{ parameters.OfficialBuild }}
- stage: upload
- dependsOn: [mac_package, windows_package, linux_package, nupkg, msixbundle]
+ displayName: 'Upload'
+ dependsOn: [prep, mac_package, windows_package_sign, linux_package, nupkg, msixbundle] # prep needed for BuildInfo JSON
jobs:
- template: /.pipelines/templates/uploadToAzure.yml@self
+
+ - stage: validatePackages
+ displayName: 'Validate Packages'
+ dependsOn: [upload]
+ jobs:
+ - template: /.pipelines/templates/release-validate-packagenames.yml@self
diff --git a/.pipelines/PowerShell-Release-Official.yml b/.pipelines/PowerShell-Release-Official.yml
index ca6b79335dd..868d61ebfd0 100644
--- a/.pipelines/PowerShell-Release-Official.yml
+++ b/.pipelines/PowerShell-Release-Official.yml
@@ -216,12 +216,6 @@ extends:
arm64: 'yes'
enableCredScan: false
- - stage: validatePackages
- displayName: 'Validate Packages'
- dependsOn: []
- jobs:
- - template: /.pipelines/templates/release-validate-packagenames.yml@self
-
- stage: ManualValidation
dependsOn: []
displayName: Manual Validation
@@ -272,7 +266,6 @@ extends:
dependsOn:
- ManualValidation
- ReleaseAutomation
- - validatePackages
- fxdpackages
- gbltool
- validateSdk
@@ -365,7 +358,7 @@ extends:
This is typically done by the community 1-2 days after the release.
- stage: PublishMsix
- dependsOn:
+ dependsOn:
- setReleaseTagAndChangelog
- PushGitTagAndMakeDraftPublic
displayName: Publish MSIX to store
diff --git a/.pipelines/PowerShell-vPack-Official.yml b/.pipelines/PowerShell-vPack-Official.yml
index f110ff0366a..ba70ddb59df 100644
--- a/.pipelines/PowerShell-vPack-Official.yml
+++ b/.pipelines/PowerShell-vPack-Official.yml
@@ -23,6 +23,14 @@ parameters: # parameters are shown up in ADO UI in a build queue time
displayName: 'Enable debug output'
type: boolean
default: false
+- name: netiso
+ displayName: "Network Isolation Policy"
+ type: string
+ values:
+ - KS4
+ - R1
+ - Netlock
+ default: "R1"
name: vPack_$(Build.SourceBranchName)_Prod.${{ parameters.OfficialBuild }}_Create.${{ parameters.createVPack }}_Name.${{ parameters.vPackName}}_$(date:yyyyMMdd).$(rev:rr)
@@ -53,6 +61,8 @@ variables:
value: ${{ iif ( parameters.OfficialBuild, 'v2/Microsoft.Official.yml@onebranchTemplates', 'v2/Microsoft.NonOfficial.yml@onebranchTemplates' ) }}
- group: DotNetPrivateBuildAccess
- group: certificate_logical_to_actual
+ - name: netiso
+ value: ${{ parameters.netiso }}
# We shouldn't be using PATs anymore
# - group: mscodehub-feed-read-general
@@ -69,6 +79,11 @@ extends:
platform:
name: 'windows_undocked' # windows undocked
+ featureFlags:
+ WindowsHostVersion:
+ Version: 2022
+ Network: ${{ variables.netiso }}
+
cloudvault:
enabled: false
@@ -143,7 +158,6 @@ extends:
parameters:
ReleaseTagVar: $(ReleaseTagVar)
CreateJson: yes
- UseJson: no
- pwsh: |
$version = '$(Version)'
diff --git a/.pipelines/templates/SetVersionVariables.yml b/.pipelines/templates/SetVersionVariables.yml
index 9f692373f6c..30ed1704022 100644
--- a/.pipelines/templates/SetVersionVariables.yml
+++ b/.pipelines/templates/SetVersionVariables.yml
@@ -1,49 +1,18 @@
parameters:
- ReleaseTagVar: v6.2.0
- ReleaseTagVarName: ReleaseTagVar
- CreateJson: 'no'
- UseJson: 'yes'
+- name: ReleaseTagVar
+ default: v6.2.0
+- name: ReleaseTagVarName
+ default: ReleaseTagVar
+- name: CreateJson
+ default: 'no'
+- name: ob_restore_phase
+ type: boolean
+ default: true
steps:
-- ${{ if eq(parameters['UseJson'],'yes') }}:
- - task: DownloadBuildArtifacts@0
- inputs:
- artifactName: 'drop_prep_SetVars'
- itemPattern: '*.json'
- downloadPath: '$(System.ArtifactsDirectory)'
- displayName: Download Build Info Json
- env:
- ob_restore_phase: true # This ensures this done in restore phase to workaround signing issue
-
-- powershell: |
- $path = "./build.psm1"
- if($env:REPOROOT){
- Write-Verbose "reporoot already set to ${env:REPOROOT}" -Verbose
- exit 0
- }
- if(Test-Path -Path $path)
- {
- Write-Verbose "reporoot detected at: ." -Verbose
- $repoRoot = '.'
- }
- else{
- $path = "./PowerShell/build.psm1"
- if(Test-Path -Path $path)
- {
- Write-Verbose "reporoot detect at: ./PowerShell" -Verbose
- $repoRoot = './PowerShell'
- }
- }
- if($repoRoot) {
- $vstsCommandString = "vso[task.setvariable variable=repoRoot]$repoRoot"
- Write-Host ("sending " + $vstsCommandString)
- Write-Host "##$vstsCommandString"
- } else {
- Write-Verbose -Verbose "repo not found"
- }
- displayName: 'Set repo Root'
- env:
- ob_restore_phase: true # This ensures this done in restore phase to workaround signing issue
+- template: set-reporoot.yml@self
+ parameters:
+ ob_restore_phase: ${{ parameters.ob_restore_phase }}
- powershell: |
$createJson = ("${{ parameters.CreateJson }}" -ne "no")
@@ -69,11 +38,11 @@ steps:
Write-Host "##$vstsCommandString"
displayName: 'Set ${{ parameters.ReleaseTagVarName }} and other version Variables'
env:
- ob_restore_phase: true # This ensures this done in restore phase to workaround signing issue
+ ob_restore_phase: ${{ parameters.ob_restore_phase }}
- powershell: |
Get-ChildItem -Path Env: | Out-String -Width 150
displayName: Capture environment
condition: succeededOrFailed()
env:
- ob_restore_phase: true # This ensures this done in restore phase to workaround signing issue
+ ob_restore_phase: ${{ parameters.ob_restore_phase }}
diff --git a/.pipelines/templates/channelSelection.yml b/.pipelines/templates/channelSelection.yml
index 3d1f445c559..9dd0f3fb216 100644
--- a/.pipelines/templates/channelSelection.yml
+++ b/.pipelines/templates/channelSelection.yml
@@ -2,13 +2,31 @@ steps:
- pwsh: |
# Determine LTS, Preview, or Stable
$metadata = Get-Content "$(Build.SourcesDirectory)/PowerShell/tools/metadata.json" -Raw | ConvertFrom-Json
+ $releaseTag = '$(OutputReleaseTag.releaseTag)'
+
+ # Rebuild branches should be treated as preview builds
+ # NOTE: The following regex is duplicated from rebuild-branch-check.yml.
+ # This duplication is necessary because channelSelection.yml does not call rebuild-branch-check.yml,
+ # and is used in contexts where that check may not have run.
+ # If you update this regex, also update it in rebuild-branch-check.yml to keep them in sync.
+ $isRebuildBranch = '$(Build.SourceBranch)' -match 'refs/heads/rebuild/.*-rebuild\.'
+
$LTS = $metadata.LTSRelease.Latest
$Stable = $metadata.StableRelease.Latest
- $isPreview = '$(OutputReleaseTag.releaseTag)' -match '-'
+ $isPreview = $releaseTag -match '-'
- $IsLTS = [bool]$LTS
- $IsStable = [bool]$Stable
- $IsPreview = [bool]$isPreview
+ # If this is a rebuild branch, force preview mode and ignore LTS metadata
+ if ($isRebuildBranch) {
+ $IsLTS = $false
+ $IsStable = $false
+ $IsPreview = $true
+ Write-Verbose -Message "Rebuild branch detected, forcing Preview channel" -Verbose
+ }
+ else {
+ $IsLTS = [bool]$LTS
+ $IsStable = [bool]$Stable
+ $IsPreview = [bool]$isPreview
+ }
$channelVars = @{
IsLTS = $IsLTS
diff --git a/.pipelines/templates/checkAzureContainer.yml b/.pipelines/templates/checkAzureContainer.yml
index a6a86214d07..3e383d2c572 100644
--- a/.pipelines/templates/checkAzureContainer.yml
+++ b/.pipelines/templates/checkAzureContainer.yml
@@ -3,6 +3,8 @@ jobs:
variables:
- group: Azure Blob variable group
- group: AzureBlobServiceConnection
+ - name: ob_artifactBaseName
+ value: BuildInfoJson
- name: ob_outputDirectory
value: '$(Build.ArtifactStagingDirectory)/ONEBRANCH_ARTIFACT/BuildJson'
- name: ob_sdl_sbom_enabled
@@ -29,7 +31,6 @@ jobs:
parameters:
ReleaseTagVar: $(ReleaseTagVar)
CreateJson: yes
- UseJson: no
- template: /.pipelines/templates/cloneToOfficialPath.yml@self
diff --git a/.pipelines/templates/cloneToOfficialPath.yml b/.pipelines/templates/cloneToOfficialPath.yml
index 844d8b8028d..b060c713683 100644
--- a/.pipelines/templates/cloneToOfficialPath.yml
+++ b/.pipelines/templates/cloneToOfficialPath.yml
@@ -1,5 +1,9 @@
parameters:
- nativePathRoot: ''
+- name: nativePathRoot
+ default: ''
+- name: ob_restore_phase
+ type: boolean
+ default: true
steps:
- powershell: |
@@ -12,8 +16,16 @@ steps:
else {
Write-Verbose -Verbose -Message "No cleanup required."
}
- git clone --quiet $env:REPOROOT $nativePath
+ # REPOROOT must be set by the pipeline - this is where the repository was checked out
+ $sourceDir = $env:REPOROOT
+ if (-not $sourceDir) { throw "REPOROOT environment variable is not set. This step depends on REPOROOT being configured in the pipeline." }
+
+ $buildModulePath = Join-Path $sourceDir "build.psm1"
+ if (-not (Test-Path $buildModulePath)) { throw "build.psm1 not found at: $buildModulePath. REPOROOT must point to the PowerShell repository root." }
+
+ Write-Verbose -Verbose -Message "Cloning from: $sourceDir to $nativePath"
+ git clone --quiet $sourceDir $nativePath
displayName: Clone PowerShell Repo to /PowerShell
errorActionPreference: silentlycontinue
env:
- ob_restore_phase: true # This ensures checkout is done at the beginning of the restore phase
+ ob_restore_phase: ${{ parameters.ob_restore_phase }}
diff --git a/.pipelines/templates/compliance/apiscan.yml b/.pipelines/templates/compliance/apiscan.yml
index 817d5ab777f..5809af8e28c 100644
--- a/.pipelines/templates/compliance/apiscan.yml
+++ b/.pipelines/templates/compliance/apiscan.yml
@@ -50,8 +50,7 @@ jobs:
- template: ../SetVersionVariables.yml
parameters:
ReleaseTagVar: $(ReleaseTagVar)
- CreateJson: yes
- UseJson: no
+ CreateJson: no
- template: ../insert-nuget-config-azfeed.yml
parameters:
diff --git a/.pipelines/templates/install-dotnet.yml b/.pipelines/templates/install-dotnet.yml
index c2a2cfebeca..464e13d1047 100644
--- a/.pipelines/templates/install-dotnet.yml
+++ b/.pipelines/templates/install-dotnet.yml
@@ -1,3 +1,8 @@
+parameters:
+- name: ob_restore_phase
+ type: boolean
+ default: true
+
steps:
- pwsh: |
if (-not (Test-Path '$(RepoRoot)')) {
@@ -15,5 +20,5 @@ steps:
displayName: 'Install dotnet SDK'
workingDirectory: $(RepoRoot)
env:
- ob_restore_phase: true
+ ob_restore_phase: ${{ parameters.ob_restore_phase }}
diff --git a/.pipelines/templates/linux-package-build.yml b/.pipelines/templates/linux-package-build.yml
index 68fa46690c2..bcf332b3778 100644
--- a/.pipelines/templates/linux-package-build.yml
+++ b/.pipelines/templates/linux-package-build.yml
@@ -54,8 +54,7 @@ jobs:
- template: SetVersionVariables.yml@self
parameters:
ReleaseTagVar: $(ReleaseTagVar)
- CreateJson: yes
- UseJson: no
+ CreateJson: no
- template: shouldSign.yml
@@ -63,6 +62,8 @@ jobs:
parameters:
nativePathRoot: '$(Agent.TempDirectory)'
+ - template: rebuild-branch-check.yml@self
+
- download: CoOrdinatedBuildPipeline
artifact: ${{ parameters.unsignedDrop }}
displayName: 'Download unsigned artifacts'
@@ -140,7 +141,21 @@ jobs:
}
$metadata = Get-Content "$repoRoot/tools/metadata.json" -Raw | ConvertFrom-Json
- $LTS = $metadata.LTSRelease.Package
+
+ Write-Verbose -Verbose "metadata:"
+ $metadata | Out-String | Write-Verbose -Verbose
+
+ # Use the rebuild branch check from the template
+ $isRebuildBranch = '$(RebuildBranchCheck.IsRebuildBranch)' -eq 'true'
+
+ # Don't build LTS packages for rebuild branches
+ $LTS = $metadata.LTSRelease.Package -and -not $isRebuildBranch
+
+ if ($isRebuildBranch) {
+ Write-Verbose -Message "Rebuild branch detected, skipping LTS package build" -Verbose
+ }
+
+ Write-Verbose -Verbose "LTS: $LTS"
if ($LTS) {
Write-Verbose -Message "LTS Release: $LTS"
diff --git a/.pipelines/templates/mac-package-build.yml b/.pipelines/templates/mac-package-build.yml
index 669ab3c8437..4e7040d4acc 100644
--- a/.pipelines/templates/mac-package-build.yml
+++ b/.pipelines/templates/mac-package-build.yml
@@ -52,8 +52,7 @@ jobs:
- template: SetVersionVariables.yml@self
parameters:
ReleaseTagVar: $(ReleaseTagVar)
- CreateJson: yes
- UseJson: no
+ CreateJson: no
- template: shouldSign.yml
@@ -61,6 +60,8 @@ jobs:
parameters:
nativePathRoot: '$(Agent.TempDirectory)'
+ - template: rebuild-branch-check.yml@self
+
- download: CoOrdinatedBuildPipeline
artifact: macosBinResults-${{ parameters.buildArchitecture }}
@@ -104,7 +105,21 @@ jobs:
Get-PSOptions | Write-Verbose -Verbose
$metadata = Get-Content "$repoRoot/tools/metadata.json" -Raw | ConvertFrom-Json
- $LTS = $metadata.LTSRelease.Package
+
+ Write-Verbose -Verbose "metadata:"
+ $metadata | Out-String | Write-Verbose -Verbose
+
+ # Use the rebuild branch check from the template
+ $isRebuildBranch = '$(RebuildBranchCheck.IsRebuildBranch)' -eq 'true'
+
+ # Don't build LTS packages for rebuild branches
+ $LTS = $metadata.LTSRelease.Package -and -not $isRebuildBranch
+
+ if ($isRebuildBranch) {
+ Write-Verbose -Message "Rebuild branch detected, skipping LTS package build" -Verbose
+ }
+
+ Write-Verbose -Verbose "LTS: $LTS"
if ($LTS) {
Write-Verbose -Message "LTS Release: $LTS"
@@ -116,13 +131,25 @@ jobs:
Start-PSPackage -Type osxpkg -SkipReleaseChecks -MacOSRuntime $macosRuntime -ReleaseTag $(ReleaseTagVar) -PackageBinPath $signedFilesPath -LTS:$LTS
$pkgNameFilter = "powershell-*$macosRuntime.pkg"
- $pkgPath = Get-ChildItem -Path $(Pipeline.Workspace) -Filter $pkgNameFilter -Recurse -File | Select-Object -ExpandProperty FullName
- Write-Host "##vso[artifact.upload containerfolder=macos-pkgs;artifactname=macos-pkgs]$pkgPath"
+ Write-Verbose -Verbose "Looking for pkg packages with filter: $pkgNameFilter in '$(Pipeline.Workspace)' to upload..."
+ $pkgPath = Get-ChildItem -Path $(Pipeline.Workspace) -Filter $pkgNameFilter -Recurse -File
+
+ foreach($p in $pkgPath) {
+ $file = $p.FullName
+ Write-Verbose -verbose "Uploading $file to macos-pkgs"
+ Write-Host "##vso[artifact.upload containerfolder=macos-pkgs;artifactname=macos-pkgs]$file"
+ }
Start-PSPackage -Type tar -SkipReleaseChecks -MacOSRuntime $macosRuntime -ReleaseTag $(ReleaseTagVar) -PackageBinPath $signedFilesPath -LTS:$LTS
$tarPkgNameFilter = "powershell-*$macosRuntime.tar.gz"
- $tarPkgPath = Get-ChildItem -Path $(Pipeline.Workspace) -Filter $tarPkgNameFilter -Recurse -File | Select-Object -ExpandProperty FullName
- Write-Host "##vso[artifact.upload containerfolder=macos-pkgs;artifactname=macos-pkgs]$tarPkgPath"
+ Write-Verbose -Verbose "Looking for tar packages with filter: $tarPkgNameFilter in '$(Pipeline.Workspace)' to upload..."
+ $tarPkgPath = Get-ChildItem -Path $(Pipeline.Workspace) -Filter $tarPkgNameFilter -Recurse -File
+
+ foreach($t in $tarPkgPath) {
+ $file = $t.FullName
+ Write-Verbose -verbose "Uploading $file to macos-pkgs"
+ Write-Host "##vso[artifact.upload containerfolder=macos-pkgs;artifactname=macos-pkgs]$file"
+ }
displayName: 'Package ${{ parameters.buildArchitecture}}'
env:
@@ -195,14 +222,14 @@ jobs:
- pwsh: |
$signedPkg = Get-ChildItem -Path $(Pipeline.Workspace) -Filter "*osx*.zip" -File
-
+
$signedPkg | ForEach-Object {
Write-Verbose -Verbose "Signed package zip: $_"
-
+
if (-not (Test-Path $_)) {
throw "Package not found: $_"
}
-
+
if (-not (Test-Path $(ob_outputDirectory))) {
$null = New-Item -Path $(ob_outputDirectory) -ItemType Directory
}
diff --git a/.pipelines/templates/nupkg.yml b/.pipelines/templates/nupkg.yml
index 4756c99a9d3..3a2aa4f3172 100644
--- a/.pipelines/templates/nupkg.yml
+++ b/.pipelines/templates/nupkg.yml
@@ -41,8 +41,7 @@ jobs:
- template: SetVersionVariables.yml@self
parameters:
ReleaseTagVar: $(ReleaseTagVar)
- CreateJson: yes
- UseJson: no
+ CreateJson: no
- template: shouldSign.yml
diff --git a/.pipelines/templates/package-create-msix.yml b/.pipelines/templates/package-create-msix.yml
index e464b612234..22815c98e11 100644
--- a/.pipelines/templates/package-create-msix.yml
+++ b/.pipelines/templates/package-create-msix.yml
@@ -1,3 +1,8 @@
+parameters:
+ - name: OfficialBuild
+ type: boolean
+ default: false
+
jobs:
- job: CreateMSIXBundle
displayName: Create .msixbundle file
@@ -26,7 +31,7 @@ jobs:
- task: DownloadPipelineArtifact@2
inputs:
buildType: 'current'
- artifact: drop_windows_package_package_win_arm64
+ artifact: drop_windows_package_arm64
itemPattern: |
**/*.msix
targetPath: '$(Build.ArtifactStagingDirectory)/downloads'
@@ -35,7 +40,7 @@ jobs:
- task: DownloadPipelineArtifact@2
inputs:
buildType: 'current'
- artifact: drop_windows_package_package_win_x64
+ artifact: drop_windows_package_x64
itemPattern: |
**/*.msix
targetPath: '$(Build.ArtifactStagingDirectory)/downloads'
@@ -44,12 +49,12 @@ jobs:
- task: DownloadPipelineArtifact@2
inputs:
buildType: 'current'
- artifact: drop_windows_package_package_win_x86
+ artifact: drop_windows_package_x86
itemPattern: |
**/*.msix
targetPath: '$(Build.ArtifactStagingDirectory)/downloads'
displayName: Download windows x86 packages
-
+
# Finds the makeappx tool on the machine with image: 'onebranch.azurecr.io/windows/ltsc2022/vse2022:latest'
- pwsh: |
$cmd = Get-Command makeappx.exe -ErrorAction Ignore
@@ -99,12 +104,13 @@ jobs:
- task: onebranch.pipeline.signing@1
displayName: Sign MsixBundle
+ condition: eq('${{ parameters.OfficialBuild }}', 'true')
inputs:
command: 'sign'
signing_profile: $(MSIXProfile)
files_to_sign: '**/*.msixbundle'
search_root: '$(BundleDir)'
-
+
- pwsh: |
$signedBundle = Get-ChildItem -Path $(BundleDir) -Filter "*.msixbundle" -File
Write-Verbose -Verbose "Signed bundle: $signedBundle"
@@ -126,12 +132,12 @@ jobs:
Get-ChildItem -Path $(System.DefaultWorkingDirectory) -Recurse | Select-Object -ExpandProperty FullName
Test-Path -Path '$(System.DefaultWorkingDirectory)/PowerShell/.pipelines/store/PDP-Private.xml' | Write-Verbose -Verbose
displayName: Output Pipeline.Workspace and System.DefaultWorkingDirectory
-
+
- template: channelSelection.yml@self
- pwsh: |
$IsLTS = '$(ChannelSelection.IsLTS)' -eq 'true'
- $IsStable = '$(ChannelSelection.IsStable)' -eq 'true'
+ $IsStable = '$(ChannelSelection.IsStable)' -eq 'true'
$IsPreview = '$(ChannelSelection.IsPreview)' -eq 'true'
Write-Verbose -Verbose "Channel Selection - LTS: $IsLTS, Stable: $IsStable, Preview: $IsPreview"
@@ -161,11 +167,11 @@ jobs:
$currentChannel = if ($IsLTS) { 'LTS' }
elseif ($IsStable) { 'Stable' }
elseif ($IsPreview) { 'Preview' }
- else {
+ else {
Write-Error "No valid channel detected"
exit 1
}
-
+
$config = $channelConfigs[$currentChannel]
Write-Verbose -Verbose "Selected channel: $currentChannel"
Write-Verbose -Verbose "App Store Name: $($config.AppStoreName)"
@@ -181,7 +187,7 @@ jobs:
# Create namespace manager for XML with default namespace
$nsManager = New-Object System.Xml.XmlNamespaceManager($pdpXml.NameTable)
$nsManager.AddNamespace("pd", "http://schemas.microsoft.com/appx/2012/ProductDescription")
-
+
$appStoreNameElement = $pdpXml.SelectSingleNode("//pd:AppStoreName", $nsManager)
if ($appStoreNameElement) {
$appStoreNameElement.SetAttribute("_locID", $config.AppStoreName)
@@ -215,16 +221,28 @@ jobs:
Write-Error "SBConfig file not found: $sbConfigPath"
exit 1
}
-
Write-Host "##vso[task.setvariable variable=ServiceConnection]$($config.ServiceEndpoint)"
Write-Host "##vso[task.setvariable variable=SBConfigPath]$($sbConfigPath)"
+
+ # These variables are used in the next tasks to determine which ServiceEndpoint to use
+ Write-Host "##vso[task.setvariable variable=LTS]$($IsLTS.ToString().ToLower())"
+ Write-Host "##vso[task.setvariable variable=STABLE]$($IsStable.ToString().ToLower())"
+ Write-Host "##vso[task.setvariable variable=PREVIEW]$($IsPreview.ToString().ToLower())"
name: UpdateConfigs
displayName: Update PDPs and SBConfig.json
+ - pwsh: |
+ Write-Verbose -Verbose "Checking variables after UpdateConfigs:"
+ Write-Verbose -Verbose "LTS=$(LTS)"
+ Write-Verbose -Verbose "STABLE=$(STABLE)"
+ Write-Verbose -Verbose "PREVIEW=$(PREVIEW)"
+ displayName: Debug - Check Variables
+
- task: MS-RDX-MRO.windows-store-publish.package-task.store-package@3
- displayName: 'Create StoreBroker Package'
+ displayName: 'Create StoreBroker Package (Preview)'
+ condition: eq(variables['PREVIEW'], 'true')
inputs:
- serviceEndpoint: 'StoreAppPublish-Private'
+ serviceEndpoint: 'StoreAppPublish-Preview'
sbConfigPath: '$(SBConfigPath)'
sourceFolder: '$(BundleDir)'
contents: '*.msixBundle'
@@ -232,24 +250,30 @@ jobs:
pdpPath: '$(System.DefaultWorkingDirectory)/PowerShell/.pipelines/store/PDP/PDP'
pdpMediaPath: '$(System.DefaultWorkingDirectory)/PowerShell/.pipelines/store/PDP/PDP-Media'
- - pwsh: |
- Get-Item -Path "$(System.DefaultWorkingDirectory)/SBLog.txt" -ErrorAction SilentlyContinue |
- Copy-Item -Destination "$(ob_outputDirectory)" -Verbose
- displayName: Upload Store Failure Log
- condition: failed()
+ - task: MS-RDX-MRO.windows-store-publish.package-task.store-package@3
+ displayName: 'Create StoreBroker Package (Stable/LTS)'
+ condition: or(eq(variables['STABLE'], 'true'), eq(variables['LTS'], 'true'))
+ inputs:
+ serviceEndpoint: 'StoreAppPublish-Stable'
+ sbConfigPath: '$(SBConfigPath)'
+ sourceFolder: '$(BundleDir)'
+ contents: '*.msixBundle'
+ outSBName: 'PowerShellStorePackage'
+ pdpPath: '$(System.DefaultWorkingDirectory)/PowerShell/.pipelines/store/PDP/PDP'
+ pdpMediaPath: '$(System.DefaultWorkingDirectory)/PowerShell/.pipelines/store/PDP/PDP-Media'
- pwsh: |
$submissionPackageDir = "$(System.DefaultWorkingDirectory)/SBOutDir"
$jsonFile = "$submissionPackageDir/PowerShellStorePackage.json"
$zipFile = "$submissionPackageDir/PowerShellStorePackage.zip"
-
+
if ((Test-Path $jsonFile) -and (Test-Path $zipFile)) {
Write-Verbose -Verbose "Uploading StoreBroker Package files:"
Write-Verbose -Verbose "JSON File: $jsonFile"
Write-Verbose -Verbose "ZIP File: $zipFile"
Copy-Item -Path $submissionPackageDir -Destination "$(ob_outputDirectory)" -Verbose -Recurse
- }
+ }
else {
Write-Error "Required files not found in $submissionPackageDir"
diff --git a/.pipelines/templates/windows-package-build.yml b/.pipelines/templates/packaging/windows/package.yml
similarity index 57%
rename from .pipelines/templates/windows-package-build.yml
rename to .pipelines/templates/packaging/windows/package.yml
index bc23bfc659e..3a4ecacbfce 100644
--- a/.pipelines/templates/windows-package-build.yml
+++ b/.pipelines/templates/packaging/windows/package.yml
@@ -2,8 +2,8 @@ parameters:
runtime: x64
jobs:
-- job: package_win_${{ parameters.runtime }}
- displayName: Package Windows ${{ parameters.runtime }}
+- job: build_win_${{ parameters.runtime }}
+ displayName: Build Windows Packages ${{ parameters.runtime }}
condition: succeeded()
pool:
type: windows
@@ -11,6 +11,12 @@ jobs:
variables:
- name: runCodesignValidationInjection
value: false
+ - name: ob_sdl_codeSignValidation_enabled
+ value: false # Skip signing validation in build-only stage
+ - name: ob_signing_setup_enabled
+ value: false # Disable signing setup - this is a build-only stage, signing happens in separate stage
+ - name: ob_artifactBaseName
+ value: drop_windows_package_${{ parameters.runtime }}
- name: nugetMultiFeedWarnLevel
value: none
- name: NugetSecurityAnalysisWarningLevel
@@ -22,7 +28,7 @@ jobs:
- name: ob_outputDirectory
value: '$(Build.ArtifactStagingDirectory)\ONEBRANCH_ARTIFACT'
- name: ob_sdl_binskim_enabled
- value: true
+ value: false # Disable for build-only, enable in signing stage
- name: ob_sdl_tsa_configFile
value: $(Build.SourcesDirectory)\PowerShell\.config\tsaoptions.json
- name: ob_sdl_credscan_suppressionsFile
@@ -34,40 +40,37 @@ jobs:
steps:
- checkout: self
clean: true
- env:
- ob_restore_phase: true # This ensures checkout is done at the beginning of the restore phase
- pwsh: |
Get-ChildItem -Path env: | Out-String -width 9999 -Stream | write-Verbose -Verbose
displayName: Capture environment
- env:
- ob_restore_phase: true # This ensures this done in restore phase to workaround signing issue
- - template: SetVersionVariables.yml@self
+ - template: /.pipelines/templates/SetVersionVariables.yml@self
parameters:
ReleaseTagVar: $(ReleaseTagVar)
- CreateJson: yes
- UseJson: no
+ CreateJson: no
+ ob_restore_phase: false
- - template: shouldSign.yml
+ - template: /.pipelines/templates/shouldSign.yml@self
+ parameters:
+ ob_restore_phase: false
- - template: cloneToOfficialPath.yml
+ - template: /.pipelines/templates/cloneToOfficialPath.yml@self
parameters:
nativePathRoot: '$(Agent.TempDirectory)'
+ ob_restore_phase: false
+
+ - template: /.pipelines/templates/rebuild-branch-check.yml@self
- download: CoOrdinatedBuildPipeline
artifact: drop_windows_build_windows_${{ parameters.runtime }}_release
displayName: Download signed artifacts
condition: ${{ ne(parameters.runtime, 'minSize') }}
- env:
- ob_restore_phase: true # This ensures this done in restore phase to workaround signing issue
- download: CoOrdinatedBuildPipeline
artifact: drop_windows_build_windows_x64_${{ parameters.runtime }}
displayName: Download minsize signed artifacts
condition: ${{ eq(parameters.runtime, 'minSize') }}
- env:
- ob_restore_phase: true # This ensures this done in restore phase to workaround signing issue
- pwsh: |
Write-Verbose -Verbose "signed artifacts"
@@ -75,18 +78,10 @@ jobs:
displayName: 'Capture Downloaded Artifacts'
# Diagnostics is not critical it passes every time it runs
continueOnError: true
- env:
- ob_restore_phase: true # This ensures this done in restore phase to workaround signing issue
- template: /.pipelines/templates/install-dotnet.yml@self
-
- - pwsh: |
- $msixUrl = '$(makeappUrl)'
- Invoke-RestMethod -Uri $msixUrl -OutFile '$(Pipeline.Workspace)\makeappx.zip'
- Expand-Archive '$(Pipeline.Workspace)\makeappx.zip' -destination '\' -Force
- displayName: Install packaging tools
- env:
- ob_restore_phase: true # This ensures this done in restore phase to workaround signing issue
+ parameters:
+ ob_restore_phase: false
- pwsh: |
$runtime = '$(Runtime)'
@@ -134,7 +129,21 @@ jobs:
Get-PSOptions | Write-Verbose -Verbose
$metadata = Get-Content "$repoRoot/tools/metadata.json" -Raw | ConvertFrom-Json
- $LTS = $metadata.LTSRelease.Package
+
+ Write-Verbose -Verbose "metadata:"
+ $metadata | Out-String | Write-Verbose -Verbose
+
+ # Use the rebuild branch check from the template
+ $isRebuildBranch = '$(RebuildBranchCheck.IsRebuildBranch)' -eq 'true'
+
+ # Don't build LTS packages for rebuild branches
+ $LTS = $metadata.LTSRelease.Package -and -not $isRebuildBranch
+
+ if ($isRebuildBranch) {
+ Write-Verbose -Message "Rebuild branch detected, skipping LTS package build" -Verbose
+ }
+
+ Write-Verbose -Verbose "LTS: $LTS"
if ($LTS) {
Write-Verbose -Message "LTS Release: $LTS"
@@ -168,94 +177,19 @@ jobs:
Start-PSPackage -Type $packageTypes -SkipReleaseChecks -WindowsRuntime $WindowsRuntime -ReleaseTag $(ReleaseTagVar) -PackageBinPath $signedFilesPath -LTS:$LTS
- displayName: 'Package ${{ parameters.buildArchitecture}}'
+ displayName: 'Build Packages (Unsigned)'
env:
__DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY)
- ob_restore_phase: true # This ensures this done in restore phase to workaround signing issue
-
- - task: onebranch.pipeline.signing@1
- displayName: Sign MSI packages
- inputs:
- command: 'sign'
- signing_profile: external_distribution
- files_to_sign: '**\*.msi'
- search_root: '$(Pipeline.Workspace)'
-
- - pwsh: |
- $runtime = '$(Runtime)'
- Write-Verbose -Verbose "runtime = '$(Runtime)'"
-
- $repoRoot = "$env:REPOROOT"
- Import-Module "$repoRoot\build.psm1"
- Import-Module "$repoRoot\tools\packaging"
-
- $noExeRuntimes = @('fxdependent', 'fxdependentWinDesktop', 'minsize')
-
- if ($runtime -in $noExeRuntimes) {
- Write-Verbose -Verbose "No EXE generated for $runtime"
- return
- }
-
- $version = '$(Version)'
-
- $msiLocation = Get-ChildItem -Path $(Pipeline.Workspace) -Recurse -Filter "powershell-*$runtime.msi" | Select-Object -ExpandProperty FullName
- Write-Verbose -Verbose "msiLocation: $msiLocation"
-
- Set-Location $repoRoot
-
- $exePath = New-ExePackage -ProductVersion $version -ProductTargetArchitecture $runtime -MsiLocationPath $msiLocation
- Write-Verbose -Verbose "setting vso[task.setvariable variable=exePath]$exePath"
- Write-Host "##vso[task.setvariable variable=exePath]$exePath"
- Write-Verbose -Verbose "exePath: $exePath"
-
- $enginePath = Join-Path -Path '$(System.ArtifactsDirectory)\unsignedEngine' -ChildPath engine.exe
- Expand-ExePackageEngine -ExePath $exePath -EnginePath $enginePath -ProductTargetArchitecture $runtime
- displayName: 'Make exe and expand package'
-
- - task: onebranch.pipeline.signing@1
- displayName: Sign exe engine
- inputs:
- command: 'sign'
- signing_profile: $(msft_3rd_party_cert_id)
- files_to_sign: '$(System.ArtifactsDirectory)\unsignedEngine\*.exe'
- search_root: '$(Pipeline.Workspace)'
-
- - pwsh: |
- $runtime = '$(Runtime)'
- Write-Verbose -Verbose "runtime = '$(Runtime)'"
- $repoRoot = "$env:REPOROOT"
- Import-Module "$repoRoot\build.psm1"
- Import-Module "$repoRoot\tools\packaging"
-
- $noExeRuntimes = @('fxdependent', 'fxdependentWinDesktop', 'minsize')
-
- if ($runtime -in $noExeRuntimes) {
- Write-Verbose -Verbose "No EXE generated for $runtime"
- return
- }
-
- $exePath = '$(exePath)'
- $enginePath = Join-Path -Path '$(System.ArtifactsDirectory)\unsignedEngine' -ChildPath engine.exe
- $enginePath | Get-AuthenticodeSignature | out-string | Write-Verbose -verbose
- Compress-ExePackageEngine -ExePath $exePath -EnginePath $enginePath -ProductTargetArchitecture $runtime
- displayName: Compress signed exe package
-
- - task: onebranch.pipeline.signing@1
- displayName: Sign exe packages
- inputs:
- command: 'sign'
- signing_profile: external_distribution
- files_to_sign: '**\*.exe'
- search_root: '$(Pipeline.Workspace)'
+ # Copy unsigned packages to output directory
- pwsh: |
$runtime = '$(Runtime)'
Write-Verbose -Verbose "runtime = '$(Runtime)'"
$packageTypes = switch ($runtime) {
- 'x64' { @('msi', 'zip', 'msix', 'exe') }
- 'x86' { @('msi', 'zip', 'msix', 'exe') }
- 'arm64' { @('msi', 'zip', 'msix', 'exe') }
+ 'x64' { @('msi', 'zip', 'msix') }
+ 'x86' { @('msi', 'zip', 'msix') }
+ 'arm64' { @('msi', 'zip', 'msix') }
'fxdependent' { 'fxdependent' }
'fxdependentWinDesktop' { 'fxdependent-win-desktop' }
'minsize' { 'min-size' }
@@ -268,31 +202,24 @@ jobs:
if ($packageTypes -contains 'msi') {
$msiPkgNameFilter = "powershell-*.msi"
$msiPkgPath = Get-ChildItem -Path $(Pipeline.Workspace) -Filter $msiPkgNameFilter -Recurse -File | Select-Object -ExpandProperty FullName
- Write-Verbose -Verbose "msiPkgPath: $msiPkgPath"
- Copy-Item -Path $msiPkgPath -Destination '$(ob_outputDirectory)' -Force -Verbose
- }
-
- if ($packageTypes -contains 'exe') {
- $msiPkgNameFilter = "powershell-*.exe"
- $msiPkgPath = Get-ChildItem -Path $(Pipeline.Workspace) -Filter $msiPkgNameFilter -Recurse -File | Select-Object -ExpandProperty FullName
- Write-Verbose -Verbose "msiPkgPath: $msiPkgPath"
+ Write-Verbose -Verbose "unsigned msiPkgPath: $msiPkgPath"
Copy-Item -Path $msiPkgPath -Destination '$(ob_outputDirectory)' -Force -Verbose
}
if ($packageTypes -contains 'zip' -or $packageTypes -contains 'fxdependent' -or $packageTypes -contains 'min-size' -or $packageTypes -contains 'fxdependent-win-desktop') {
$zipPkgNameFilter = "powershell-*.zip"
$zipPkgPath = Get-ChildItem -Path $(Pipeline.Workspace) -Filter $zipPkgNameFilter -Recurse -File | Select-Object -ExpandProperty FullName
- Write-Verbose -Verbose "zipPkgPath: $zipPkgPath"
+ Write-Verbose -Verbose "unsigned zipPkgPath: $zipPkgPath"
Copy-Item -Path $zipPkgPath -Destination '$(ob_outputDirectory)' -Force -Verbose
}
if ($packageTypes -contains 'msix') {
$msixPkgNameFilter = "powershell-*.msix"
$msixPkgPath = Get-ChildItem -Path $(Pipeline.Workspace) -Filter $msixPkgNameFilter -Recurse -File | Select-Object -ExpandProperty FullName
- Write-Verbose -Verbose "msixPkgPath: $msixPkgPath"
+ Write-Verbose -Verbose "unsigned msixPkgPath: $msixPkgPath"
Copy-Item -Path $msixPkgPath -Destination '$(ob_outputDirectory)' -Force -Verbose
}
- displayName: Copy to output directory
+ displayName: Copy unsigned packages to output directory
- pwsh: |
Get-ChildItem -Path $(ob_outputDirectory) -Recurse
diff --git a/.pipelines/templates/packaging/windows/sign.yml b/.pipelines/templates/packaging/windows/sign.yml
new file mode 100644
index 00000000000..4a095ba7694
--- /dev/null
+++ b/.pipelines/templates/packaging/windows/sign.yml
@@ -0,0 +1,216 @@
+parameters:
+ runtime: x64
+
+jobs:
+- job: sign_win_${{ parameters.runtime }}
+ displayName: Sign Windows Packages ${{ parameters.runtime }}
+ condition: succeeded()
+ pool:
+ type: windows
+
+ variables:
+ - name: runCodesignValidationInjection
+ value: false
+ - name: ob_artifactBaseName
+ value: drop_windows_package_package_win_${{ parameters.runtime }}
+ - name: nugetMultiFeedWarnLevel
+ value: none
+ - name: NugetSecurityAnalysisWarningLevel
+ value: none
+ - name: skipNugetSecurityAnalysis
+ value: true
+ - group: DotNetPrivateBuildAccess
+ - group: certificate_logical_to_actual
+ - name: ob_outputDirectory
+ value: '$(Build.ArtifactStagingDirectory)\ONEBRANCH_ARTIFACT'
+ - name: ob_sdl_binskim_enabled
+ value: true
+ - name: ob_sdl_tsa_configFile
+ value: $(Build.SourcesDirectory)\PowerShell\.config\tsaoptions.json
+ - name: ob_sdl_credscan_suppressionsFile
+ value: $(Build.SourcesDirectory)\PowerShell\.config\suppress.json
+ - name: Runtime
+ value: ${{ parameters.runtime }}
+ - group: msixTools
+
+ steps:
+ - checkout: self
+ clean: true
+ env:
+ ob_restore_phase: true
+
+ - template: /.pipelines/templates/SetVersionVariables.yml@self
+ parameters:
+ ReleaseTagVar: $(ReleaseTagVar)
+ CreateJson: no
+
+ - template: /.pipelines/templates/shouldSign.yml@self
+
+ - template: /.pipelines/templates/cloneToOfficialPath.yml@self
+ parameters:
+ nativePathRoot: '$(Agent.TempDirectory)'
+
+ # Download unsigned packages from the build stage
+ - download: current
+ artifact: drop_windows_package_${{ parameters.runtime }}
+ displayName: Download unsigned packages
+ env:
+ ob_restore_phase: true
+
+ - pwsh: |
+ Write-Verbose -Verbose "Downloaded unsigned artifacts:"
+ Get-ChildItem "$(Pipeline.Workspace)\drop_windows_package_${{ parameters.runtime }}" -Recurse
+ displayName: 'Capture Downloaded Unsigned Artifacts'
+ continueOnError: true
+ env:
+ ob_restore_phase: true
+
+ - template: /.pipelines/templates/install-dotnet.yml@self
+
+ # Import build.psm1 and bootstrap packaging dependencies (WiX Toolset)
+ - pwsh: |
+ $repoRoot = "$env:REPOROOT"
+ Import-Module "$repoRoot\build.psm1"
+ Import-Module "$repoRoot\tools\packaging"
+ Write-Verbose -Verbose "Modules imported successfully"
+
+ # Install WiX Toolset for EXE package creation
+ $isArm64 = '$(Runtime)' -eq 'arm64'
+ $env:RUNTIME = '$(Runtime)'
+ Start-PSBootstrap -Scenario Package
+ displayName: 'Import modules and install WiX Toolset'
+ env:
+ ob_restore_phase: true
+
+ # Sign MSI packages
+ - task: onebranch.pipeline.signing@1
+ displayName: Sign MSI packages
+ inputs:
+ command: 'sign'
+ signing_profile: external_distribution
+ files_to_sign: '**\*.msi'
+ search_root: '$(Pipeline.Workspace)'
+
+ # Create EXE package from signed MSI (for x64, x86, arm64 only)
+ - pwsh: |
+ $runtime = '$(Runtime)'
+ Write-Verbose -Verbose "runtime = '$(Runtime)'"
+
+ $repoRoot = "$env:REPOROOT"
+ Import-Module "$repoRoot\build.psm1"
+ Import-Module "$repoRoot\tools\packaging"
+
+ $noExeRuntimes = @('fxdependent', 'fxdependentWinDesktop', 'minsize')
+
+ if ($runtime -in $noExeRuntimes) {
+ Write-Verbose -Verbose "No EXE generated for $runtime"
+ return
+ }
+
+ $version = '$(Version)'
+
+ $msiLocation = Get-ChildItem -Path $(Pipeline.Workspace) -Recurse -Filter "powershell-*$runtime.msi" | Select-Object -ExpandProperty FullName
+ Write-Verbose -Verbose "msiLocation: $msiLocation"
+
+ Set-Location $repoRoot
+
+ $exePath = New-ExePackage -ProductVersion $version -ProductTargetArchitecture $runtime -MsiLocationPath $msiLocation
+ Write-Verbose -Verbose "setting vso[task.setvariable variable=exePath]$exePath"
+ Write-Host "##vso[task.setvariable variable=exePath]$exePath"
+ Write-Verbose -Verbose "exePath: $exePath"
+
+ $enginePath = Join-Path -Path '$(System.ArtifactsDirectory)\unsignedEngine' -ChildPath engine.exe
+ Expand-ExePackageEngine -ExePath $exePath -EnginePath $enginePath -ProductTargetArchitecture $runtime
+ displayName: 'Make exe and expand package'
+
+ # Sign EXE engine
+ - task: onebranch.pipeline.signing@1
+ displayName: Sign exe engine
+ inputs:
+ command: 'sign'
+ signing_profile: $(msft_3rd_party_cert_id)
+ files_to_sign: '$(System.ArtifactsDirectory)\unsignedEngine\*.exe'
+ search_root: '$(Pipeline.Workspace)'
+
+ # Compress signed EXE engine back into package
+ - pwsh: |
+ $runtime = '$(Runtime)'
+ Write-Verbose -Verbose "runtime = '$(Runtime)'"
+ $repoRoot = "$env:REPOROOT"
+ Import-Module "$repoRoot\build.psm1"
+ Import-Module "$repoRoot\tools\packaging"
+
+ $noExeRuntimes = @('fxdependent', 'fxdependentWinDesktop', 'minsize')
+
+ if ($runtime -in $noExeRuntimes) {
+ Write-Verbose -Verbose "No EXE generated for $runtime"
+ return
+ }
+
+ $exePath = '$(exePath)'
+ $enginePath = Join-Path -Path '$(System.ArtifactsDirectory)\unsignedEngine' -ChildPath engine.exe
+ $enginePath | Get-AuthenticodeSignature | out-string | Write-Verbose -verbose
+ Compress-ExePackageEngine -ExePath $exePath -EnginePath $enginePath -ProductTargetArchitecture $runtime
+ displayName: Compress signed exe package
+
+ # Sign final EXE packages
+ - task: onebranch.pipeline.signing@1
+ displayName: Sign exe packages
+ inputs:
+ command: 'sign'
+ signing_profile: external_distribution
+ files_to_sign: '**\*.exe'
+ search_root: '$(Pipeline.Workspace)'
+
+ # Copy all signed packages to output directory
+ - pwsh: |
+ $runtime = '$(Runtime)'
+ Write-Verbose -Verbose "runtime = '$(Runtime)'"
+
+ $packageTypes = switch ($runtime) {
+ 'x64' { @('msi', 'zip', 'msix', 'exe') }
+ 'x86' { @('msi', 'zip', 'msix', 'exe') }
+ 'arm64' { @('msi', 'zip', 'msix', 'exe') }
+ 'fxdependent' { 'fxdependent' }
+ 'fxdependentWinDesktop' { 'fxdependent-win-desktop' }
+ 'minsize' { 'min-size' }
+ }
+
+ if (-not (Test-Path $(ob_outputDirectory))) {
+ New-Item -ItemType Directory -Path $(ob_outputDirectory) -Force
+ }
+
+ if ($packageTypes -contains 'msi') {
+ $msiPkgNameFilter = "powershell-*.msi"
+ $msiPkgPath = Get-ChildItem -Path $(Pipeline.Workspace) -Filter $msiPkgNameFilter -Recurse -File | Select-Object -ExpandProperty FullName
+ Write-Verbose -Verbose "signed msiPkgPath: $msiPkgPath"
+ Copy-Item -Path $msiPkgPath -Destination '$(ob_outputDirectory)' -Force -Verbose
+ }
+
+ if ($packageTypes -contains 'exe') {
+ $exePkgNameFilter = "powershell-*.exe"
+ $exePkgPath = Get-ChildItem -Path $(Pipeline.Workspace) -Filter $exePkgNameFilter -Recurse -File | Select-Object -ExpandProperty FullName
+ Write-Verbose -Verbose "signed exePkgPath: $exePkgPath"
+ Copy-Item -Path $exePkgPath -Destination '$(ob_outputDirectory)' -Force -Verbose
+ }
+
+ if ($packageTypes -contains 'zip' -or $packageTypes -contains 'fxdependent' -or $packageTypes -contains 'min-size' -or $packageTypes -contains 'fxdependent-win-desktop') {
+ $zipPkgNameFilter = "powershell-*.zip"
+ $zipPkgPath = Get-ChildItem -Path $(Pipeline.Workspace) -Filter $zipPkgNameFilter -Recurse -File | Select-Object -ExpandProperty FullName
+ Write-Verbose -Verbose "signed zipPkgPath: $zipPkgPath"
+ Copy-Item -Path $zipPkgPath -Destination '$(ob_outputDirectory)' -Force -Verbose
+ }
+
+ if ($packageTypes -contains 'msix') {
+ $msixPkgNameFilter = "powershell-*.msix"
+ $msixPkgPath = Get-ChildItem -Path $(Pipeline.Workspace) -Filter $msixPkgNameFilter -Recurse -File | Select-Object -ExpandProperty FullName
+ Write-Verbose -Verbose "signed msixPkgPath: $msixPkgPath"
+ Copy-Item -Path $msixPkgPath -Destination '$(ob_outputDirectory)' -Force -Verbose
+ }
+ displayName: Copy signed packages to output directory
+
+ - pwsh: |
+ Get-ChildItem -Path $(ob_outputDirectory) -Recurse
+ displayName: 'List signed artifacts'
+ env:
+ ob_restore_phase: true
diff --git a/.pipelines/templates/rebuild-branch-check.yml b/.pipelines/templates/rebuild-branch-check.yml
new file mode 100644
index 00000000000..a4b546a0dc6
--- /dev/null
+++ b/.pipelines/templates/rebuild-branch-check.yml
@@ -0,0 +1,17 @@
+# This template checks if the current branch is a rebuild branch
+# and sets an output variable IsRebuildBranch that can be used by other templates
+steps:
+- pwsh: |
+ # Check if this is a rebuild branch (e.g., rebuild/v7.4.13-rebuild.5)
+ $isRebuildBranch = '$(Build.SourceBranch)' -match 'refs/heads/rebuild/.*-rebuild\.'
+
+ $value = if ($isRebuildBranch) { 'true' } else { 'false' }
+ Write-Verbose -Message "IsRebuildBranch: $value" -Verbose
+
+ if ($isRebuildBranch) {
+ Write-Verbose -Message "Rebuild branch detected: $(Build.SourceBranch)" -Verbose
+ }
+
+ Write-Host "##vso[task.setvariable variable=IsRebuildBranch;isOutput=true]$value"
+ name: RebuildBranchCheck
+ displayName: Check if Rebuild Branch
diff --git a/.pipelines/templates/release-MSIX-Publish.yml b/.pipelines/templates/release-MSIX-Publish.yml
index 4d3e0cb41c8..2bf1e130103 100644
--- a/.pipelines/templates/release-MSIX-Publish.yml
+++ b/.pipelines/templates/release-MSIX-Publish.yml
@@ -50,7 +50,7 @@ jobs:
$middleURL = $matches[1]
}
- $endURL = $tagString -replace '^v|\.', ''
+ $endURL = $tagString -replace '^v','' -replace '\.',''
$message = "Changelog: https://github.com/PowerShell/PowerShell/blob/master/CHANGELOG/$middleURL.md#$endURL"
Write-Verbose -Verbose "Release Notes for the Store:"
Write-Verbose -Verbose "$message"
@@ -73,7 +73,6 @@ jobs:
Write-Verbose -Verbose "Channel Selection - LTS: $(LTS), Stable: $(STABLE), Preview: $(PREVIEW)"
- # Determine the current channel for logging purposes
$currentChannel = if ($IsLTS) { 'LTS' }
elseif ($IsStable) { 'Stable' }
elseif ($IsPreview) { 'Preview' }
@@ -81,17 +80,30 @@ jobs:
Write-Error "No valid channel detected"
exit 1
}
-
+
+ # Assign AppID for Store-Publish Task
+ $appID = $null
+ if ($IsLTS) {
+ $appID = '$(AppID-LTS)'
+ }
+ elseif ($IsStable) {
+ $appID = '$(AppID-Stable)'
+ }
+ else {
+ $appID = '$(AppID-Preview)'
+ }
+
+ Write-Host "##vso[task.setvariable variable=AppID]$appID"
Write-Verbose -Verbose "Selected channel: $currentChannel"
Write-Verbose -Verbose "Conditional tasks will handle the publishing based on channel variables"
displayName: 'Validate Channel Selection'
- task: MS-RDX-MRO.windows-store-publish.publish-task.store-publish@3
- displayName: 'Publish LTS StoreBroker Package'
- condition: and(ne('${{ parameters.skipMSIXPublish }}', 'true'), eq(variables['LTS'], 'true'))
+ displayName: 'Publish StoreBroker Package (Stable/LTS)'
+ condition: and(ne('${{ parameters.skipMSIXPublish }}', 'true'), or(eq(variables['STABLE'], 'true'), eq(variables['LTS'], 'true')))
inputs:
- serviceEndpoint: 'StoreAppPublish-Private'
- appId: '$(AppID-LTS)'
+ serviceEndpoint: 'StoreAppPublish-Stable'
+ appId: '$(AppID)'
inputMethod: JsonAndZip
jsonPath: '$(Pipeline.Workspace)\SBOutDir\PowerShellStorePackage.json'
zipPath: '$(Pipeline.Workspace)\SBOutDir\PowerShellStorePackage.zip'
@@ -100,32 +112,14 @@ jobs:
targetPublishMode: 'Immediate'
- task: MS-RDX-MRO.windows-store-publish.publish-task.store-publish@3
- displayName: 'Publish Stable StoreBroker Package'
- condition: and(ne('${{ parameters.skipMSIXPublish }}', 'true'), eq(variables['STABLE'], 'true'))
- inputs:
- serviceEndpoint: 'StoreAppPublish-Private'
- appId: '$(AppID-Stable)'
- inputMethod: JsonAndZip
- jsonPath: '$(Pipeline.Workspace)\SBOutDir\PowerShellStorePackage.json'
- zipPath: '$(Pipeline.Workspace)\SBOutDir\PowerShellStorePackage.zip'
- numberOfPackagesToKeep: 2
- jsonZipUpdateMetadata: true
- targetPublishMode: 'Immediate'
-
- - task: MS-RDX-MRO.windows-store-publish.publish-task.store-publish@3
- displayName: 'Publish Preview StoreBroker Package'
+ displayName: 'Publish StoreBroker Package (Preview)'
condition: and(ne('${{ parameters.skipMSIXPublish }}', 'true'), eq(variables['PREVIEW'], 'true'))
inputs:
- serviceEndpoint: 'StoreAppPublish-Private'
- appId: '$(AppID-Preview)'
+ serviceEndpoint: 'StoreAppPublish-Preview'
+ appId: '$(AppID)'
inputMethod: JsonAndZip
jsonPath: '$(Pipeline.Workspace)\SBOutDir\PowerShellStorePackage.json'
zipPath: '$(Pipeline.Workspace)\SBOutDir\PowerShellStorePackage.zip'
numberOfPackagesToKeep: 2
jsonZipUpdateMetadata: true
targetPublishMode: 'Immediate'
-
- - pwsh: |
- Get-Content -Path "$(System.DefaultWorkingDirectory)/SBLog.txt" -ErrorAction SilentlyContinue
- displayName: Upload Store Failure Log
- condition: failed()
diff --git a/.pipelines/templates/release-MakeBlobPublic.yml b/.pipelines/templates/release-MakeBlobPublic.yml
index c8f12938d25..758298202a1 100644
--- a/.pipelines/templates/release-MakeBlobPublic.yml
+++ b/.pipelines/templates/release-MakeBlobPublic.yml
@@ -45,8 +45,7 @@ jobs:
- template: /.pipelines/templates/SetVersionVariables.yml@self
parameters:
ReleaseTagVar: $(ReleaseTagVar)
- CreateJson: yes
- UseJson: no
+ CreateJson: no
- pwsh: |
Get-ChildItem Env:
@@ -132,8 +131,7 @@ jobs:
- template: /.pipelines/templates/SetVersionVariables.yml@self
parameters:
ReleaseTagVar: $(ReleaseTagVar)
- CreateJson: yes
- UseJson: no
+ CreateJson: no
- pwsh: |
Get-ChildItem Env: | Out-String -width 9999 -Stream | write-Verbose -Verbose
diff --git a/.pipelines/templates/release-checkout-pwsh-repo.yml b/.pipelines/templates/release-checkout-pwsh-repo.yml
deleted file mode 100644
index 9a7486887a6..00000000000
--- a/.pipelines/templates/release-checkout-pwsh-repo.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-steps:
- - pwsh: |
- Write-Verbose -Verbose "Deploy Box Product Pathway Does Not Support the `"checkout`" task"
- if ($ENV:BUILD_REASON -eq 'PullRequest') {
- throw 'We dont support PRs'
- }
-
- Write-Verbose -Verbose $ENV:BUILD_SOURCEBRANCH
- $branchName = $ENV:BUILD_SOURCEBRANCH -replace '^refs/heads/'
- Write-Verbose -Verbose "Branch Name: $branchName"
- git clone --depth 1 --branch $branchName https://$(mscodehubCodeReadPat)@mscodehub.visualstudio.com/PowerShellCore/_git/PowerShell '$(Pipeline.Workspace)/PowerShell'
- cd $(Pipeline.Workspace)/PowerShell
- displayName: Checkout Powershell Repository
diff --git a/.pipelines/templates/release-download-packages.yml b/.pipelines/templates/release-download-packages.yml
deleted file mode 100644
index 27a3098d1e1..00000000000
--- a/.pipelines/templates/release-download-packages.yml
+++ /dev/null
@@ -1,122 +0,0 @@
-jobs:
-- job: upload_packages
- displayName: Upload packages
- condition: succeeded()
- pool:
- type: windows
- variables:
- - template: ./variable/release-shared.yml@self
- parameters:
- REPOROOT: $(Build.SourcesDirectory)
- SBOM: true
-
- steps:
- - pwsh: |
- Get-ChildItem -Path env: | Out-String -width 9999 -Stream | write-Verbose -Verbose
- displayName: Capture environment variables
-
- - download: PSPackagesOfficial
- artifact: drop_linux_package_deb
- displayName: Download linux deb packages
-
- - download: PSPackagesOfficial
- artifact: drop_linux_package_fxdependent
- displayName: Download linux fx packages
-
- - download: PSPackagesOfficial
- artifact: drop_linux_package_mariner_arm64
- displayName: Download linux mariner packages
-
- - download: PSPackagesOfficial
- artifact: drop_linux_package_mariner_x64
- displayName: Download linux mariner x64 packages
-
- - download: PSPackagesOfficial
- artifact: drop_linux_package_minSize
- displayName: Download linux min packages
-
- - download: PSPackagesOfficial
- artifact: drop_linux_package_rpm
- displayName: Download linux rpm packages
-
- - download: PSPackagesOfficial
- artifact: drop_linux_package_tar
- displayName: Download linux tar packages
-
- - download: PSPackagesOfficial
- artifact: drop_linux_package_tar_alpine
- displayName: Download linux tar alpine packages
-
- - download: PSPackagesOfficial
- artifact: drop_linux_package_tar_alpine_fxd
- displayName: Download linux tar alpine fxd packages
-
- - download: PSPackagesOfficial
- artifact: drop_linux_package_tar_arm
- displayName: Download linux tar arm packages
-
- - download: PSPackagesOfficial
- artifact: drop_linux_package_tar_arm64
- displayName: Download linux tar arm 64 packages
-
- - download: PSPackagesOfficial
- artifact: drop_nupkg_build_nupkg
- displayName: Download nupkg packages
-
- - download: PSPackagesOfficial
- artifact: drop_windows_package_package_win_arm64
- displayName: Download windows arm64 packages
-
- - download: PSPackagesOfficial
- artifact: drop_windows_package_package_win_fxdependent
- displayName: Download windows fxdependent packages
-
- - download: PSPackagesOfficial
- artifact: drop_windows_package_package_win_fxdependentWinDesktop
- displayName: Download windows fxdependentWinDesktop packages
-
- - download: PSPackagesOfficial
- artifact: drop_windows_package_package_win_minsize
- displayName: Download windows minsize packages
-
- - download: PSPackagesOfficial
- artifact: drop_windows_package_package_win_x64
- displayName: Download windows x64 packages
-
- - download: PSPackagesOfficial
- artifact: drop_windows_package_package_win_x86
- displayName: Download windows x86 packages
-
- - download: PSPackagesOfficial
- artifact: macos-pkgs
- displayName: Download macos tar packages
-
- - download: PSPackagesOfficial
- artifact: drop_mac_package_sign_package_macos_arm64
- displayName: Download macos arm packages
-
- - download: PSPackagesOfficial
- artifact: drop_mac_package_sign_package_macos_x64
- displayName: Download macos x64 packages
-
- - pwsh: |
- Get-ChildItem '$(Pipeline.Workspace)/PSPackagesOfficial' -Recurse | Select-Object -ExpandProperty FullName
- displayName: 'Capture downloads'
-
- - pwsh: |
- $PackagesPath = '$(Pipeline.Workspace)/PSPackagesOfficial'
- Write-Verbose -Verbose "Copying Github Release files in $PackagesPath to use in Release Pipeline"
-
- Write-Verbose -Verbose "Creating output directory for GitHub Release files: $(ob_outputDirectory)/GitHubPackages"
- New-Item -Path $(ob_outputDirectory)/GitHubPackages -ItemType Directory -Force
- Get-ChildItem -Path "$PackagesPath/*" -Recurse |
- Where-Object { $_.Extension -notin '.msix', '.nupkg' } |
- Where-Object { $_.Extension -in '.gz', '.pkg', '.msi', '.zip', '.deb', '.rpm', '.zip' } |
- Copy-Item -Destination $(ob_outputDirectory)/GitHubPackages -Recurse -Verbose
-
- Write-Verbose -Verbose "Creating output directory for NuGet packages: $(ob_outputDirectory)/NuGetPackages"
- New-Item -Path $(ob_outputDirectory)/NuGetPackages -ItemType Directory -Force
- Get-ChildItem -Path "$PackagesPath/*" -Recurse |
- Where-Object { $_.Extension -eq '.nupkg' } |
- Copy-Item -Destination $(ob_outputDirectory)/NuGetPackages -Recurse -Verbose
- displayName: Copy downloads to Artifacts
diff --git a/.pipelines/templates/release-install-pwsh.yml b/.pipelines/templates/release-install-pwsh.yml
deleted file mode 100644
index 9d7080a7e78..00000000000
--- a/.pipelines/templates/release-install-pwsh.yml
+++ /dev/null
@@ -1,34 +0,0 @@
-steps:
- - task: PowerShell@2
- inputs:
- targetType: inline
- script: |
- $localInstallerPath = Get-ChildItem -Path "$(Pipeline.Workspace)/GitHubPackages" -Filter '*win-x64.msi' | Select-Object -First 1 -ExpandProperty FullName
- if (Test-Path -Path $localInstallerPath) {
- Write-Verbose -Verbose "Installer found at $localInstallerPath"
- } else {
- throw "Installer not found"
- }
- Write-Verbose -Verbose "Installing PowerShell via msiexec"
- Start-Process -FilePath msiexec -ArgumentList "/package $localInstallerPath /quiet REGISTER_MANIFEST=1" -Wait -NoNewWindow
- $pwshPath = Get-ChildItem -Directory -Path 'C:\Program Files\PowerShell\7*' | Select-Object -First 1 -ExpandProperty FullName
- if (Test-Path -Path $pwshPath) {
- Write-Verbose -Verbose "PowerShell installed at $pwshPath"
- Write-Verbose -Verbose "Adding pwsh to env:PATH"
- Write-Host "##vso[task.prependpath]$pwshPath"
- } else {
- throw "PowerShell not installed"
- }
- displayName: Install pwsh 7
-
- - task: PowerShell@2
- inputs:
- targetType: inline
- pwsh: true
- script: |
- Write-Verbose -Verbose "Pwsh 7 Installed"
- Write-Verbose -Verbose "env:Path: "
- $env:PATH -split ';' | ForEach-Object {
- Write-Verbose -Verbose $_
- }
- displayName: Check pwsh 7 installation
diff --git a/.pipelines/templates/release-validate-packagenames.yml b/.pipelines/templates/release-validate-packagenames.yml
index c717b50f289..6344418cd8f 100644
--- a/.pipelines/templates/release-validate-packagenames.yml
+++ b/.pipelines/templates/release-validate-packagenames.yml
@@ -82,7 +82,7 @@ jobs:
- pwsh: |
$message = @()
Get-ChildItem $(System.ArtifactsDirectory)\* -recurse -filter *.pkg | ForEach-Object {
- if($_.Name -notmatch 'powershell-(lts-)?\d+\.\d+\.\d+\-([a-z]*.\d+\-)?osx(\.10\.12)?\-(x64|arm64)\.pkg')
+ if($_.Name -notmatch 'powershell-(lts-)?\d+\.\d+\.\d+\-([a-z]*.\d+\-)?osx\-(x64|arm64)\.pkg')
{
$messageInstance = "$($_.Name) is not a valid package name"
$message += $messageInstance
diff --git a/.pipelines/templates/set-reporoot.yml b/.pipelines/templates/set-reporoot.yml
new file mode 100644
index 00000000000..af7983afaa1
--- /dev/null
+++ b/.pipelines/templates/set-reporoot.yml
@@ -0,0 +1,35 @@
+parameters:
+- name: ob_restore_phase
+ type: boolean
+ default: true
+
+steps:
+- pwsh: |
+ $path = "./build.psm1"
+ if($env:REPOROOT){
+ Write-Verbose "reporoot already set to ${env:REPOROOT}" -Verbose
+ exit 0
+ }
+ if(Test-Path -Path $path)
+ {
+ Write-Verbose "reporoot detected at: ." -Verbose
+ $repoRoot = '.'
+ }
+ else{
+ $path = "./PowerShell/build.psm1"
+ if(Test-Path -Path $path)
+ {
+ Write-Verbose "reporoot detected at: ./PowerShell" -Verbose
+ $repoRoot = './PowerShell'
+ }
+ }
+ if($repoRoot) {
+ $vstsCommandString = "vso[task.setvariable variable=repoRoot]$repoRoot"
+ Write-Host ("sending " + $vstsCommandString)
+ Write-Host "##$vstsCommandString"
+ } else {
+ Write-Verbose -Verbose "repo not found"
+ }
+ displayName: 'Set repo Root'
+ env:
+ ob_restore_phase: ${{ parameters.ob_restore_phase }}
diff --git a/.pipelines/templates/shouldSign.yml b/.pipelines/templates/shouldSign.yml
index 4bac9e1a3ae..551297f3aaa 100644
--- a/.pipelines/templates/shouldSign.yml
+++ b/.pipelines/templates/shouldSign.yml
@@ -1,3 +1,8 @@
+parameters:
+- name: ob_restore_phase
+ type: boolean
+ default: true
+
steps:
- powershell: |
$shouldSign = $true
@@ -22,4 +27,4 @@ steps:
Write-Host "##$vstsCommandString"
displayName: 'Set SHOULD_SIGN Variable'
env:
- ob_restore_phase: true # This ensures this done in restore phase to workaround signing issue
+ ob_restore_phase: ${{ parameters.ob_restore_phase }}
diff --git a/.pipelines/templates/uploadToAzure.yml b/.pipelines/templates/uploadToAzure.yml
index b330a2eef10..20842de81cc 100644
--- a/.pipelines/templates/uploadToAzure.yml
+++ b/.pipelines/templates/uploadToAzure.yml
@@ -36,8 +36,7 @@ jobs:
- template: /.pipelines/templates/SetVersionVariables.yml@self
parameters:
ReleaseTagVar: $(ReleaseTagVar)
- CreateJson: yes
- UseJson: no
+ CreateJson: no
- template: /.pipelines/templates/release-SetReleaseTagandContainerName.yml@self
diff --git a/.vsts-ci/templates/nanoserver.yml b/.vsts-ci/templates/nanoserver.yml
deleted file mode 100644
index ae9f639b3b2..00000000000
--- a/.vsts-ci/templates/nanoserver.yml
+++ /dev/null
@@ -1,61 +0,0 @@
-parameters:
- vmImage: 'windows-latest'
- jobName: 'Nanoserver_Tests'
- continueOnError: false
-
-jobs:
-
-- job: ${{ parameters.jobName }}
- variables:
- scriptName: ${{ parameters.scriptName }}
-
- pool:
- vmImage: ${{ parameters.vmImage }}
-
- displayName: ${{ parameters.jobName }}
-
- steps:
- - script: |
- set
- displayName: Capture Environment
- condition: succeededOrFailed()
-
- - task: DownloadBuildArtifacts@0
- displayName: 'Download Build Artifacts'
- inputs:
- downloadType: specific
- itemPattern: |
- build/**/*
- downloadPath: '$(System.ArtifactsDirectory)'
-
- - pwsh: |
- Get-ChildItem "$(System.ArtifactsDirectory)\*" -Recurse
- displayName: 'Capture Artifacts Directory'
- continueOnError: true
-
- - pwsh: |
- Install-module Pester -Scope CurrentUser -Force -MaximumVersion 4.99
- displayName: 'Install Pester'
- continueOnError: true
-
- - pwsh: |
- Import-Module .\tools\ci.psm1
- Restore-PSOptions -PSOptionsPath '$(System.ArtifactsDirectory)\build\psoptions.json'
- $options = (Get-PSOptions)
- $path = split-path -path $options.Output
- Write-Verbose "Path: '$path'" -Verbose
- $rootPath = split-Path -path $path
- Expand-Archive -Path '$(System.ArtifactsDirectory)\build\build.zip' -DestinationPath $rootPath -Force
- Invoke-Pester -Path ./test/nanoserver -OutputFormat NUnitXml -OutputFile ./test-nanoserver.xml
- displayName: Test
- condition: succeeded()
-
- - task: PublishTestResults@2
- condition: succeededOrFailed()
- displayName: Publish Nanoserver Test Results **\test*.xml
- inputs:
- testRunner: NUnit
- testResultsFiles: '**\test*.xml'
- testRunTitle: nanoserver
- mergeTestResults: true
- failTaskOnFailedTests: true
diff --git a/CHANGELOG/preview.md b/CHANGELOG/preview.md
index 3648f4cc121..f1c5f566289 100644
--- a/CHANGELOG/preview.md
+++ b/CHANGELOG/preview.md
@@ -1,5 +1,76 @@
# Preview Changelog
+## [7.6.0-preview.6] - 2025-12-11
+
+### Engine Updates and Fixes
+
+- Properly Expand Aliases to their actual ResolvedCommand (#26571) (Thanks @kilasuit!)
+
+### General Cmdlet Updates and Fixes
+
+- Update `Microsoft.PowerShell.PSResourceGet` to `v1.2.0-preview5` (#26590)
+- Make the experimental feature `PSFeedbackProvider` stable (#26502)
+- Fix a regression in the API `CompletionCompleters.CompleteFilename()` that causes null reference exception (#26487)
+- Add Delimiter parameter to `Get-Clipboard` (#26572) (Thanks @MartinGC94!)
+- Close pipe client handles after creating the child ssh process (#26564)
+- Make some experimental features stable (#26490)
+- DSC v3 resource for PowerShell Profile (#26447)
+
+### Tools
+
+- Add merge conflict marker detection to linux-ci workflow and refactor existing actions to use reusable get-changed-files action (#26530)
+- Add reusable get-changed-files action and refactor existing actions (#26529)
+- Refactor analyze job to reusable workflow and enable on Windows CI (#26494)
+
+### Tests
+
+- Fix merge conflict checker for empty file lists and filter *.cs files (#26556)
+- Add markdown link verification for PRs (#26445)
+
+### Build and Packaging Improvements
+
+
+
+
+
+
Expand to see details.
+
+
+
+
+
Fix template path for rebuild branch check in package.yml (#26560)
+
Update the macos package name for preview releases to match the previous pattern (#26576)
+
Add rebuild branch support with conditional MSIX signing (#26573)
+
Update the WCF packages to the latest version that is compatible with v4.10.3 (#26503)
+
Improve ADO package build and validation across platforms (#26532)
+
Mirror .NET/runtime ICU version range in PowerShell (#26563) (Thanks @kasperk81!)
+
Update the macos package name for preview releases to match the previous pattern (#26562)
+
Fix condition syntax for StoreBroker package tasks in MSIX pipeline (#26561)
+
Move package validation to package pipeline (#26558)
+
Optimize/split windows package signing (#26557)
+
Remove usage of fpm for DEB package generation (#26504)
+
Add log grouping to build.psm1 for collapsible GitHub Actions logs (#26524)
+
Replace fpm with native macOS packaging tools (pkgbuild/productbuild) (#26501)
+
Replace fpm with native rpmbuild for RPM package generation (#26441)
+
Fix GitHub API rate limit errors in test actions (#26492)
+
Convert Azure DevOps Linux Packaging pipeline to GitHub Actions workflow (#26493)
+
Refactor: Centralize xUnit tests into reusable workflow and remove legacy verification (#26488)
+
Fix build to only enable ready-to-run for the Release configuration (#26481)
+
Integrate Windows packaging into windows-ci workflow using reusable workflow (#26468)
+
Update outdated package references (#26471)
+
GitHub Workflow cleanup (#26439)
+
Update PSResourceGet package version to preview4 (#26438)
+
Update PSReadLine to v2.4.5 (#26446)
+
Add network isolation policy parameter to vPack pipeline (#26444)
+
Fix a couple more lint errors
+
Fix lint errors in preview.md
+
Make MSIX publish stage dependent on SetReleaseTagandContainerName stage
+
+
+
+
+[7.6.0-preview.6]: https://github.com/PowerShell/PowerShell/compare/v7.6.0-preview.5...v7.6.0-preview.6
+
## [7.6.0-preview.5] - 2025-09-30
### Engine Updates and Fixes
diff --git a/DotnetRuntimeMetadata.json b/DotnetRuntimeMetadata.json
index 8541f8ba795..267f0bda7d6 100644
--- a/DotnetRuntimeMetadata.json
+++ b/DotnetRuntimeMetadata.json
@@ -4,7 +4,7 @@
"quality": "daily",
"qualityFallback": "preview",
"packageVersionPattern": "9.0.0-preview.6",
- "sdkImageVersion": "10.0.100-rc.1.25451.107",
+ "sdkImageVersion": "10.0.100",
"nextChannel": "9.0.0-preview.7",
"azureFeed": "",
"sdkImageOverride": ""
diff --git a/PowerShell.Common.props b/PowerShell.Common.props
index 91d44c21f03..dfc16f830d7 100644
--- a/PowerShell.Common.props
+++ b/PowerShell.Common.props
@@ -193,12 +193,20 @@
Global
+
+
+
+ truetrueAppLocal
+
+
+
+ truetrue
diff --git a/ThirdPartyNotices.txt b/ThirdPartyNotices.txt
index 8abff24592f..0397684ed7a 100644
--- a/ThirdPartyNotices.txt
+++ b/ThirdPartyNotices.txt
@@ -17,7 +17,7 @@ required to debug changes to any libraries licensed under the GNU Lesser General
---------------------------------------------------------
-Markdig.Signed 0.42.0 - BSD-2-Clause
+Markdig.Signed 0.43.0 - BSD-2-Clause
@@ -170,7 +170,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
---------------------------------------------------------
-Microsoft.Bcl.AsyncInterfaces 9.0.9 - MIT
+Microsoft.Bcl.AsyncInterfaces 10.0.0 - MIT
Copyright (c) 2021
@@ -193,7 +193,7 @@ Copyright (c) 2005-2020 Rich Felker
Copyright (c) 2012-2021 Yann Collet
Copyright (c) Microsoft Corporation
Copyright (c) 2007 James Newton-King
-Copyright (c) 1991-2022 Unicode, Inc.
+Copyright (c) 1991-2024 Unicode, Inc.
Copyright (c) 2013-2017, Alfred Klomp
Copyright (c) 2018 Nemanja Mijailovic
Copyright 2012 the V8 project authors
@@ -214,7 +214,6 @@ Copyright (c) The Internet Society (2003)
Copyright (c) .NET Foundation Contributors
(c) 1995-2024 Jean-loup Gailly and Mark Adler
Copyright (c) 2020 Mara Bos
-Copyright (c) .NET Foundation and Contributors
Copyright (c) 2012 - present, Victor Zverovich
Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
@@ -231,30 +230,15 @@ Copyright (c) 1980, 1986, 1993 The Regents of the University of California
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
+MIT License
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
+Copyright (c)
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
@@ -305,7 +289,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
---------------------------------------------------------
-Microsoft.Extensions.ObjectPool 9.0.9 - MIT
+Microsoft.Extensions.ObjectPool 10.0.0 - MIT
Copyright Jorn Zaefferer
@@ -395,7 +379,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
---------------------------------------------------------
-Microsoft.Win32.Registry.AccessControl 9.0.9 - MIT
+Microsoft.Win32.Registry.AccessControl 10.0.0 - MIT
Copyright (c) 2021
@@ -418,7 +402,7 @@ Copyright (c) 2005-2020 Rich Felker
Copyright (c) 2012-2021 Yann Collet
Copyright (c) Microsoft Corporation
Copyright (c) 2007 James Newton-King
-Copyright (c) 1991-2022 Unicode, Inc.
+Copyright (c) 1991-2024 Unicode, Inc.
Copyright (c) 2013-2017, Alfred Klomp
Copyright (c) 2018 Nemanja Mijailovic
Copyright 2012 the V8 project authors
@@ -439,7 +423,6 @@ Copyright (c) The Internet Society (2003)
Copyright (c) .NET Foundation Contributors
(c) 1995-2024 Jean-loup Gailly and Mark Adler
Copyright (c) 2020 Mara Bos
-Copyright (c) .NET Foundation and Contributors
Copyright (c) 2012 - present, Victor Zverovich
Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
@@ -456,36 +439,21 @@ Copyright (c) 1980, 1986, 1993 The Regents of the University of California
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
+MIT License
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
+Copyright (c)
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
---------------------------------------------------------
-Microsoft.Win32.SystemEvents 9.0.9 - MIT
+Microsoft.Win32.SystemEvents 10.0.0 - MIT
Copyright (c) 2021
@@ -508,7 +476,7 @@ Copyright (c) 2005-2020 Rich Felker
Copyright (c) 2012-2021 Yann Collet
Copyright (c) Microsoft Corporation
Copyright (c) 2007 James Newton-King
-Copyright (c) 1991-2022 Unicode, Inc.
+Copyright (c) 1991-2024 Unicode, Inc.
Copyright (c) 2013-2017, Alfred Klomp
Copyright (c) 2018 Nemanja Mijailovic
Copyright 2012 the V8 project authors
@@ -529,7 +497,6 @@ Copyright (c) The Internet Society (2003)
Copyright (c) .NET Foundation Contributors
(c) 1995-2024 Jean-loup Gailly and Mark Adler
Copyright (c) 2020 Mara Bos
-Copyright (c) .NET Foundation and Contributors
Copyright (c) 2012 - present, Victor Zverovich
Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
@@ -546,36 +513,21 @@ Copyright (c) 1980, 1986, 1993 The Regents of the University of California
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
+MIT License
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
+Copyright (c)
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
---------------------------------------------------------
-Microsoft.Windows.Compatibility 9.0.9 - MIT
+Microsoft.Windows.Compatibility 10.0.0 - MIT
(c) Microsoft Corporation
@@ -628,7 +580,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
-runtime.android-arm.runtime.native.System.IO.Ports 9.0.9 - MIT
+runtime.android-arm.runtime.native.System.IO.Ports 10.0.0 - MIT
Copyright (c) 2021
@@ -651,7 +603,7 @@ Copyright (c) 2005-2020 Rich Felker
Copyright (c) 2012-2021 Yann Collet
Copyright (c) Microsoft Corporation
Copyright (c) 2007 James Newton-King
-Copyright (c) 1991-2022 Unicode, Inc.
+Copyright (c) 1991-2024 Unicode, Inc.
Copyright (c) 2013-2017, Alfred Klomp
Copyright (c) 2018 Nemanja Mijailovic
Copyright 2012 the V8 project authors
@@ -672,7 +624,6 @@ Copyright (c) The Internet Society (2003)
Copyright (c) .NET Foundation Contributors
(c) 1995-2024 Jean-loup Gailly and Mark Adler
Copyright (c) 2020 Mara Bos
-Copyright (c) .NET Foundation and Contributors
Copyright (c) 2012 - present, Victor Zverovich
Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
@@ -689,36 +640,21 @@ Copyright (c) 1980, 1986, 1993 The Regents of the University of California
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
+MIT License
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
+Copyright (c)
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
---------------------------------------------------------
-runtime.android-arm64.runtime.native.System.IO.Ports 9.0.9 - MIT
+runtime.android-arm64.runtime.native.System.IO.Ports 10.0.0 - MIT
Copyright (c) 2021
@@ -741,7 +677,7 @@ Copyright (c) 2005-2020 Rich Felker
Copyright (c) 2012-2021 Yann Collet
Copyright (c) Microsoft Corporation
Copyright (c) 2007 James Newton-King
-Copyright (c) 1991-2022 Unicode, Inc.
+Copyright (c) 1991-2024 Unicode, Inc.
Copyright (c) 2013-2017, Alfred Klomp
Copyright (c) 2018 Nemanja Mijailovic
Copyright 2012 the V8 project authors
@@ -762,7 +698,6 @@ Copyright (c) The Internet Society (2003)
Copyright (c) .NET Foundation Contributors
(c) 1995-2024 Jean-loup Gailly and Mark Adler
Copyright (c) 2020 Mara Bos
-Copyright (c) .NET Foundation and Contributors
Copyright (c) 2012 - present, Victor Zverovich
Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
@@ -779,36 +714,21 @@ Copyright (c) 1980, 1986, 1993 The Regents of the University of California
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
+MIT License
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
+Copyright (c)
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
---------------------------------------------------------
-runtime.android-x64.runtime.native.System.IO.Ports 9.0.9 - MIT
+runtime.android-x64.runtime.native.System.IO.Ports 10.0.0 - MIT
Copyright (c) 2021
@@ -831,7 +751,7 @@ Copyright (c) 2005-2020 Rich Felker
Copyright (c) 2012-2021 Yann Collet
Copyright (c) Microsoft Corporation
Copyright (c) 2007 James Newton-King
-Copyright (c) 1991-2022 Unicode, Inc.
+Copyright (c) 1991-2024 Unicode, Inc.
Copyright (c) 2013-2017, Alfred Klomp
Copyright (c) 2018 Nemanja Mijailovic
Copyright 2012 the V8 project authors
@@ -852,7 +772,6 @@ Copyright (c) The Internet Society (2003)
Copyright (c) .NET Foundation Contributors
(c) 1995-2024 Jean-loup Gailly and Mark Adler
Copyright (c) 2020 Mara Bos
-Copyright (c) .NET Foundation and Contributors
Copyright (c) 2012 - present, Victor Zverovich
Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
@@ -869,36 +788,21 @@ Copyright (c) 1980, 1986, 1993 The Regents of the University of California
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
+MIT License
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
+Copyright (c)
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
---------------------------------------------------------
-runtime.android-x86.runtime.native.System.IO.Ports 9.0.9 - MIT
+runtime.android-x86.runtime.native.System.IO.Ports 10.0.0 - MIT
Copyright (c) 2021
@@ -921,7 +825,7 @@ Copyright (c) 2005-2020 Rich Felker
Copyright (c) 2012-2021 Yann Collet
Copyright (c) Microsoft Corporation
Copyright (c) 2007 James Newton-King
-Copyright (c) 1991-2022 Unicode, Inc.
+Copyright (c) 1991-2024 Unicode, Inc.
Copyright (c) 2013-2017, Alfred Klomp
Copyright (c) 2018 Nemanja Mijailovic
Copyright 2012 the V8 project authors
@@ -942,7 +846,6 @@ Copyright (c) The Internet Society (2003)
Copyright (c) .NET Foundation Contributors
(c) 1995-2024 Jean-loup Gailly and Mark Adler
Copyright (c) 2020 Mara Bos
-Copyright (c) .NET Foundation and Contributors
Copyright (c) 2012 - present, Victor Zverovich
Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
@@ -959,36 +862,21 @@ Copyright (c) 1980, 1986, 1993 The Regents of the University of California
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
+MIT License
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
+Copyright (c)
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
---------------------------------------------------------
-runtime.linux-arm.runtime.native.System.IO.Ports 9.0.9 - MIT
+runtime.linux-arm.runtime.native.System.IO.Ports 10.0.0 - MIT
Copyright (c) 2021
@@ -1011,7 +899,7 @@ Copyright (c) 2005-2020 Rich Felker
Copyright (c) 2012-2021 Yann Collet
Copyright (c) Microsoft Corporation
Copyright (c) 2007 James Newton-King
-Copyright (c) 1991-2022 Unicode, Inc.
+Copyright (c) 1991-2024 Unicode, Inc.
Copyright (c) 2013-2017, Alfred Klomp
Copyright (c) 2018 Nemanja Mijailovic
Copyright 2012 the V8 project authors
@@ -1032,7 +920,6 @@ Copyright (c) The Internet Society (2003)
Copyright (c) .NET Foundation Contributors
(c) 1995-2024 Jean-loup Gailly and Mark Adler
Copyright (c) 2020 Mara Bos
-Copyright (c) .NET Foundation and Contributors
Copyright (c) 2012 - present, Victor Zverovich
Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
@@ -1049,36 +936,21 @@ Copyright (c) 1980, 1986, 1993 The Regents of the University of California
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
+MIT License
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
+Copyright (c)
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
---------------------------------------------------------
-runtime.linux-arm64.runtime.native.System.IO.Ports 9.0.9 - MIT
+runtime.linux-arm64.runtime.native.System.IO.Ports 10.0.0 - MIT
Copyright (c) 2021
@@ -1101,7 +973,7 @@ Copyright (c) 2005-2020 Rich Felker
Copyright (c) 2012-2021 Yann Collet
Copyright (c) Microsoft Corporation
Copyright (c) 2007 James Newton-King
-Copyright (c) 1991-2022 Unicode, Inc.
+Copyright (c) 1991-2024 Unicode, Inc.
Copyright (c) 2013-2017, Alfred Klomp
Copyright (c) 2018 Nemanja Mijailovic
Copyright 2012 the V8 project authors
@@ -1122,7 +994,6 @@ Copyright (c) The Internet Society (2003)
Copyright (c) .NET Foundation Contributors
(c) 1995-2024 Jean-loup Gailly and Mark Adler
Copyright (c) 2020 Mara Bos
-Copyright (c) .NET Foundation and Contributors
Copyright (c) 2012 - present, Victor Zverovich
Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
@@ -1139,36 +1010,21 @@ Copyright (c) 1980, 1986, 1993 The Regents of the University of California
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
+MIT License
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
+Copyright (c)
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
---------------------------------------------------------
-runtime.linux-bionic-arm64.runtime.native.System.IO.Ports 9.0.9 - MIT
+runtime.linux-bionic-arm64.runtime.native.System.IO.Ports 10.0.0 - MIT
Copyright (c) 2021
@@ -1191,7 +1047,7 @@ Copyright (c) 2005-2020 Rich Felker
Copyright (c) 2012-2021 Yann Collet
Copyright (c) Microsoft Corporation
Copyright (c) 2007 James Newton-King
-Copyright (c) 1991-2022 Unicode, Inc.
+Copyright (c) 1991-2024 Unicode, Inc.
Copyright (c) 2013-2017, Alfred Klomp
Copyright (c) 2018 Nemanja Mijailovic
Copyright 2012 the V8 project authors
@@ -1212,7 +1068,6 @@ Copyright (c) The Internet Society (2003)
Copyright (c) .NET Foundation Contributors
(c) 1995-2024 Jean-loup Gailly and Mark Adler
Copyright (c) 2020 Mara Bos
-Copyright (c) .NET Foundation and Contributors
Copyright (c) 2012 - present, Victor Zverovich
Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
@@ -1229,36 +1084,21 @@ Copyright (c) 1980, 1986, 1993 The Regents of the University of California
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
-The MIT License (MIT)
+MIT License
-Copyright (c) .NET Foundation and Contributors
+Copyright (c)
-All rights reserved.
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
---------------------------------------------------------
-runtime.linux-bionic-x64.runtime.native.System.IO.Ports 9.0.9 - MIT
+runtime.linux-bionic-x64.runtime.native.System.IO.Ports 10.0.0 - MIT
Copyright (c) 2021
@@ -1281,7 +1121,7 @@ Copyright (c) 2005-2020 Rich Felker
Copyright (c) 2012-2021 Yann Collet
Copyright (c) Microsoft Corporation
Copyright (c) 2007 James Newton-King
-Copyright (c) 1991-2022 Unicode, Inc.
+Copyright (c) 1991-2024 Unicode, Inc.
Copyright (c) 2013-2017, Alfred Klomp
Copyright (c) 2018 Nemanja Mijailovic
Copyright 2012 the V8 project authors
@@ -1302,7 +1142,6 @@ Copyright (c) The Internet Society (2003)
Copyright (c) .NET Foundation Contributors
(c) 1995-2024 Jean-loup Gailly and Mark Adler
Copyright (c) 2020 Mara Bos
-Copyright (c) .NET Foundation and Contributors
Copyright (c) 2012 - present, Victor Zverovich
Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
@@ -1319,36 +1158,21 @@ Copyright (c) 1980, 1986, 1993 The Regents of the University of California
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
+MIT License
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
+Copyright (c)
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
---------------------------------------------------------
-runtime.linux-musl-arm.runtime.native.System.IO.Ports 9.0.9 - MIT
+runtime.linux-musl-arm.runtime.native.System.IO.Ports 10.0.0 - MIT
Copyright (c) 2021
@@ -1371,7 +1195,7 @@ Copyright (c) 2005-2020 Rich Felker
Copyright (c) 2012-2021 Yann Collet
Copyright (c) Microsoft Corporation
Copyright (c) 2007 James Newton-King
-Copyright (c) 1991-2022 Unicode, Inc.
+Copyright (c) 1991-2024 Unicode, Inc.
Copyright (c) 2013-2017, Alfred Klomp
Copyright (c) 2018 Nemanja Mijailovic
Copyright 2012 the V8 project authors
@@ -1392,7 +1216,6 @@ Copyright (c) The Internet Society (2003)
Copyright (c) .NET Foundation Contributors
(c) 1995-2024 Jean-loup Gailly and Mark Adler
Copyright (c) 2020 Mara Bos
-Copyright (c) .NET Foundation and Contributors
Copyright (c) 2012 - present, Victor Zverovich
Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
@@ -1409,36 +1232,21 @@ Copyright (c) 1980, 1986, 1993 The Regents of the University of California
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
+MIT License
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
+Copyright (c)
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
---------------------------------------------------------
-runtime.linux-musl-arm64.runtime.native.System.IO.Ports 9.0.9 - MIT
+runtime.linux-musl-arm64.runtime.native.System.IO.Ports 10.0.0 - MIT
Copyright (c) 2021
@@ -1461,7 +1269,7 @@ Copyright (c) 2005-2020 Rich Felker
Copyright (c) 2012-2021 Yann Collet
Copyright (c) Microsoft Corporation
Copyright (c) 2007 James Newton-King
-Copyright (c) 1991-2022 Unicode, Inc.
+Copyright (c) 1991-2024 Unicode, Inc.
Copyright (c) 2013-2017, Alfred Klomp
Copyright (c) 2018 Nemanja Mijailovic
Copyright 2012 the V8 project authors
@@ -1482,7 +1290,6 @@ Copyright (c) The Internet Society (2003)
Copyright (c) .NET Foundation Contributors
(c) 1995-2024 Jean-loup Gailly and Mark Adler
Copyright (c) 2020 Mara Bos
-Copyright (c) .NET Foundation and Contributors
Copyright (c) 2012 - present, Victor Zverovich
Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
@@ -1499,36 +1306,21 @@ Copyright (c) 1980, 1986, 1993 The Regents of the University of California
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
+MIT License
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
+Copyright (c)
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
---------------------------------------------------------
-runtime.linux-musl-x64.runtime.native.System.IO.Ports 9.0.9 - MIT
+runtime.linux-musl-x64.runtime.native.System.IO.Ports 10.0.0 - MIT
Copyright (c) 2021
@@ -1551,7 +1343,7 @@ Copyright (c) 2005-2020 Rich Felker
Copyright (c) 2012-2021 Yann Collet
Copyright (c) Microsoft Corporation
Copyright (c) 2007 James Newton-King
-Copyright (c) 1991-2022 Unicode, Inc.
+Copyright (c) 1991-2024 Unicode, Inc.
Copyright (c) 2013-2017, Alfred Klomp
Copyright (c) 2018 Nemanja Mijailovic
Copyright 2012 the V8 project authors
@@ -1572,7 +1364,6 @@ Copyright (c) The Internet Society (2003)
Copyright (c) .NET Foundation Contributors
(c) 1995-2024 Jean-loup Gailly and Mark Adler
Copyright (c) 2020 Mara Bos
-Copyright (c) .NET Foundation and Contributors
Copyright (c) 2012 - present, Victor Zverovich
Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
@@ -1589,36 +1380,21 @@ Copyright (c) 1980, 1986, 1993 The Regents of the University of California
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
+MIT License
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
+Copyright (c)
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
---------------------------------------------------------
-runtime.linux-x64.runtime.native.System.IO.Ports 9.0.9 - MIT
+runtime.linux-x64.runtime.native.System.IO.Ports 10.0.0 - MIT
Copyright (c) 2021
@@ -1641,7 +1417,7 @@ Copyright (c) 2005-2020 Rich Felker
Copyright (c) 2012-2021 Yann Collet
Copyright (c) Microsoft Corporation
Copyright (c) 2007 James Newton-King
-Copyright (c) 1991-2022 Unicode, Inc.
+Copyright (c) 1991-2024 Unicode, Inc.
Copyright (c) 2013-2017, Alfred Klomp
Copyright (c) 2018 Nemanja Mijailovic
Copyright 2012 the V8 project authors
@@ -1662,7 +1438,6 @@ Copyright (c) The Internet Society (2003)
Copyright (c) .NET Foundation Contributors
(c) 1995-2024 Jean-loup Gailly and Mark Adler
Copyright (c) 2020 Mara Bos
-Copyright (c) .NET Foundation and Contributors
Copyright (c) 2012 - present, Victor Zverovich
Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
@@ -1679,36 +1454,21 @@ Copyright (c) 1980, 1986, 1993 The Regents of the University of California
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
+MIT License
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
+Copyright (c)
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
---------------------------------------------------------
-runtime.maccatalyst-arm64.runtime.native.System.IO.Ports 9.0.9 - MIT
+runtime.maccatalyst-arm64.runtime.native.System.IO.Ports 10.0.0 - MIT
Copyright (c) 2021
@@ -1731,7 +1491,7 @@ Copyright (c) 2005-2020 Rich Felker
Copyright (c) 2012-2021 Yann Collet
Copyright (c) Microsoft Corporation
Copyright (c) 2007 James Newton-King
-Copyright (c) 1991-2022 Unicode, Inc.
+Copyright (c) 1991-2024 Unicode, Inc.
Copyright (c) 2013-2017, Alfred Klomp
Copyright (c) 2018 Nemanja Mijailovic
Copyright 2012 the V8 project authors
@@ -1752,7 +1512,6 @@ Copyright (c) The Internet Society (2003)
Copyright (c) .NET Foundation Contributors
(c) 1995-2024 Jean-loup Gailly and Mark Adler
Copyright (c) 2020 Mara Bos
-Copyright (c) .NET Foundation and Contributors
Copyright (c) 2012 - present, Victor Zverovich
Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
@@ -1769,36 +1528,21 @@ Copyright (c) 1980, 1986, 1993 The Regents of the University of California
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
+MIT License
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
+Copyright (c)
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
---------------------------------------------------------
-runtime.maccatalyst-x64.runtime.native.System.IO.Ports 9.0.9 - MIT
+runtime.maccatalyst-x64.runtime.native.System.IO.Ports 10.0.0 - MIT
Copyright (c) 2021
@@ -1821,7 +1565,7 @@ Copyright (c) 2005-2020 Rich Felker
Copyright (c) 2012-2021 Yann Collet
Copyright (c) Microsoft Corporation
Copyright (c) 2007 James Newton-King
-Copyright (c) 1991-2022 Unicode, Inc.
+Copyright (c) 1991-2024 Unicode, Inc.
Copyright (c) 2013-2017, Alfred Klomp
Copyright (c) 2018 Nemanja Mijailovic
Copyright 2012 the V8 project authors
@@ -1842,7 +1586,6 @@ Copyright (c) The Internet Society (2003)
Copyright (c) .NET Foundation Contributors
(c) 1995-2024 Jean-loup Gailly and Mark Adler
Copyright (c) 2020 Mara Bos
-Copyright (c) .NET Foundation and Contributors
Copyright (c) 2012 - present, Victor Zverovich
Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
@@ -1859,30 +1602,15 @@ Copyright (c) 1980, 1986, 1993 The Regents of the University of California
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
+MIT License
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
+Copyright (c)
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
@@ -1933,7 +1661,7 @@ SOFTWARE.
---------------------------------------------------------
-runtime.native.System.IO.Ports 9.0.9 - MIT
+runtime.native.System.IO.Ports 10.0.0 - MIT
Copyright (c) 2021
@@ -1956,7 +1684,7 @@ Copyright (c) 2005-2020 Rich Felker
Copyright (c) 2012-2021 Yann Collet
Copyright (c) Microsoft Corporation
Copyright (c) 2007 James Newton-King
-Copyright (c) 1991-2022 Unicode, Inc.
+Copyright (c) 1991-2024 Unicode, Inc.
Copyright (c) 2013-2017, Alfred Klomp
Copyright (c) 2018 Nemanja Mijailovic
Copyright 2012 the V8 project authors
@@ -1977,7 +1705,6 @@ Copyright (c) The Internet Society (2003)
Copyright (c) .NET Foundation Contributors
(c) 1995-2024 Jean-loup Gailly and Mark Adler
Copyright (c) 2020 Mara Bos
-Copyright (c) .NET Foundation and Contributors
Copyright (c) 2012 - present, Victor Zverovich
Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
@@ -1994,36 +1721,21 @@ Copyright (c) 1980, 1986, 1993 The Regents of the University of California
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
+MIT License
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
+Copyright (c)
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
---------------------------------------------------------
-runtime.osx-arm64.runtime.native.System.IO.Ports 9.0.9 - MIT
+runtime.osx-arm64.runtime.native.System.IO.Ports 10.0.0 - MIT
Copyright (c) 2021
@@ -2046,7 +1758,7 @@ Copyright (c) 2005-2020 Rich Felker
Copyright (c) 2012-2021 Yann Collet
Copyright (c) Microsoft Corporation
Copyright (c) 2007 James Newton-King
-Copyright (c) 1991-2022 Unicode, Inc.
+Copyright (c) 1991-2024 Unicode, Inc.
Copyright (c) 2013-2017, Alfred Klomp
Copyright (c) 2018 Nemanja Mijailovic
Copyright 2012 the V8 project authors
@@ -2067,7 +1779,6 @@ Copyright (c) The Internet Society (2003)
Copyright (c) .NET Foundation Contributors
(c) 1995-2024 Jean-loup Gailly and Mark Adler
Copyright (c) 2020 Mara Bos
-Copyright (c) .NET Foundation and Contributors
Copyright (c) 2012 - present, Victor Zverovich
Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
@@ -2084,36 +1795,21 @@ Copyright (c) 1980, 1986, 1993 The Regents of the University of California
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
+MIT License
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
+Copyright (c)
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
---------------------------------------------------------
-runtime.osx-x64.runtime.native.System.IO.Ports 9.0.9 - MIT
+runtime.osx-x64.runtime.native.System.IO.Ports 10.0.0 - MIT
Copyright (c) 2021
@@ -2136,7 +1832,7 @@ Copyright (c) 2005-2020 Rich Felker
Copyright (c) 2012-2021 Yann Collet
Copyright (c) Microsoft Corporation
Copyright (c) 2007 James Newton-King
-Copyright (c) 1991-2022 Unicode, Inc.
+Copyright (c) 1991-2024 Unicode, Inc.
Copyright (c) 2013-2017, Alfred Klomp
Copyright (c) 2018 Nemanja Mijailovic
Copyright 2012 the V8 project authors
@@ -2157,7 +1853,6 @@ Copyright (c) The Internet Society (2003)
Copyright (c) .NET Foundation Contributors
(c) 1995-2024 Jean-loup Gailly and Mark Adler
Copyright (c) 2020 Mara Bos
-Copyright (c) .NET Foundation and Contributors
Copyright (c) 2012 - present, Victor Zverovich
Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
@@ -2174,36 +1869,21 @@ Copyright (c) 1980, 1986, 1993 The Regents of the University of California
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
-The MIT License (MIT)
+MIT License
-Copyright (c) .NET Foundation and Contributors
+Copyright (c)
-All rights reserved.
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
---------------------------------------------------------
-System.CodeDom 9.0.9 - MIT
+System.CodeDom 10.0.0 - MIT
Copyright (c) 2021
@@ -2226,7 +1906,7 @@ Copyright (c) 2005-2020 Rich Felker
Copyright (c) 2012-2021 Yann Collet
Copyright (c) Microsoft Corporation
Copyright (c) 2007 James Newton-King
-Copyright (c) 1991-2022 Unicode, Inc.
+Copyright (c) 1991-2024 Unicode, Inc.
Copyright (c) 2013-2017, Alfred Klomp
Copyright (c) 2018 Nemanja Mijailovic
Copyright 2012 the V8 project authors
@@ -2247,7 +1927,6 @@ Copyright (c) The Internet Society (2003)
Copyright (c) .NET Foundation Contributors
(c) 1995-2024 Jean-loup Gailly and Mark Adler
Copyright (c) 2020 Mara Bos
-Copyright (c) .NET Foundation and Contributors
Copyright (c) 2012 - present, Victor Zverovich
Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
@@ -2264,36 +1943,21 @@ Copyright (c) 1980, 1986, 1993 The Regents of the University of California
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
+MIT License
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
+Copyright (c)
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
---------------------------------------------------------
-System.ComponentModel.Composition 9.0.9 - MIT
+System.ComponentModel.Composition 10.0.0 - MIT
Copyright (c) 2021
@@ -2316,7 +1980,7 @@ Copyright (c) 2005-2020 Rich Felker
Copyright (c) 2012-2021 Yann Collet
Copyright (c) Microsoft Corporation
Copyright (c) 2007 James Newton-King
-Copyright (c) 1991-2022 Unicode, Inc.
+Copyright (c) 1991-2024 Unicode, Inc.
Copyright (c) 2013-2017, Alfred Klomp
Copyright (c) 2018 Nemanja Mijailovic
Copyright 2012 the V8 project authors
@@ -2337,7 +2001,6 @@ Copyright (c) The Internet Society (2003)
Copyright (c) .NET Foundation Contributors
(c) 1995-2024 Jean-loup Gailly and Mark Adler
Copyright (c) 2020 Mara Bos
-Copyright (c) .NET Foundation and Contributors
Copyright (c) 2012 - present, Victor Zverovich
Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
@@ -2354,36 +2017,21 @@ Copyright (c) 1980, 1986, 1993 The Regents of the University of California
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
+MIT License
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
+Copyright (c)
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
---------------------------------------------------------
-System.ComponentModel.Composition.Registration 9.0.9 - MIT
+System.ComponentModel.Composition.Registration 10.0.0 - MIT
Copyright (c) 2021
@@ -2406,7 +2054,7 @@ Copyright (c) 2005-2020 Rich Felker
Copyright (c) 2012-2021 Yann Collet
Copyright (c) Microsoft Corporation
Copyright (c) 2007 James Newton-King
-Copyright (c) 1991-2022 Unicode, Inc.
+Copyright (c) 1991-2024 Unicode, Inc.
Copyright (c) 2013-2017, Alfred Klomp
Copyright (c) 2018 Nemanja Mijailovic
Copyright 2012 the V8 project authors
@@ -2427,7 +2075,6 @@ Copyright (c) The Internet Society (2003)
Copyright (c) .NET Foundation Contributors
(c) 1995-2024 Jean-loup Gailly and Mark Adler
Copyright (c) 2020 Mara Bos
-Copyright (c) .NET Foundation and Contributors
Copyright (c) 2012 - present, Victor Zverovich
Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
@@ -2444,36 +2091,21 @@ Copyright (c) 1980, 1986, 1993 The Regents of the University of California
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
+MIT License
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
+Copyright (c)
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
---------------------------------------------------------
-System.Configuration.ConfigurationManager 9.0.9 - MIT
+System.Configuration.ConfigurationManager 10.0.0 - MIT
Copyright (c) 2021
@@ -2496,7 +2128,7 @@ Copyright (c) 2005-2020 Rich Felker
Copyright (c) 2012-2021 Yann Collet
Copyright (c) Microsoft Corporation
Copyright (c) 2007 James Newton-King
-Copyright (c) 1991-2022 Unicode, Inc.
+Copyright (c) 1991-2024 Unicode, Inc.
Copyright (c) 2013-2017, Alfred Klomp
Copyright (c) 2018 Nemanja Mijailovic
Copyright 2012 the V8 project authors
@@ -2517,7 +2149,6 @@ Copyright (c) The Internet Society (2003)
Copyright (c) .NET Foundation Contributors
(c) 1995-2024 Jean-loup Gailly and Mark Adler
Copyright (c) 2020 Mara Bos
-Copyright (c) .NET Foundation and Contributors
Copyright (c) 2012 - present, Victor Zverovich
Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
@@ -2534,36 +2165,21 @@ Copyright (c) 1980, 1986, 1993 The Regents of the University of California
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
+MIT License
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
+Copyright (c)
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
---------------------------------------------------------
-System.Data.Odbc 9.0.9 - MIT
+System.Data.Odbc 10.0.0 - MIT
Copyright (c) 2021
@@ -2586,7 +2202,7 @@ Copyright (c) 2005-2020 Rich Felker
Copyright (c) 2012-2021 Yann Collet
Copyright (c) Microsoft Corporation
Copyright (c) 2007 James Newton-King
-Copyright (c) 1991-2022 Unicode, Inc.
+Copyright (c) 1991-2024 Unicode, Inc.
Copyright (c) 2013-2017, Alfred Klomp
Copyright (c) 2018 Nemanja Mijailovic
Copyright 2012 the V8 project authors
@@ -2607,7 +2223,6 @@ Copyright (c) The Internet Society (2003)
Copyright (c) .NET Foundation Contributors
(c) 1995-2024 Jean-loup Gailly and Mark Adler
Copyright (c) 2020 Mara Bos
-Copyright (c) .NET Foundation and Contributors
Copyright (c) 2012 - present, Victor Zverovich
Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
@@ -2624,36 +2239,21 @@ Copyright (c) 1980, 1986, 1993 The Regents of the University of California
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
+MIT License
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
+Copyright (c)
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
---------------------------------------------------------
-System.Data.OleDb 9.0.9 - MIT
+System.Data.OleDb 10.0.0 - MIT
Copyright (c) 2021
@@ -2676,7 +2276,7 @@ Copyright (c) 2005-2020 Rich Felker
Copyright (c) 2012-2021 Yann Collet
Copyright (c) Microsoft Corporation
Copyright (c) 2007 James Newton-King
-Copyright (c) 1991-2022 Unicode, Inc.
+Copyright (c) 1991-2024 Unicode, Inc.
Copyright (c) 2013-2017, Alfred Klomp
Copyright (c) 2018 Nemanja Mijailovic
Copyright 2012 the V8 project authors
@@ -2697,7 +2297,6 @@ Copyright (c) The Internet Society (2003)
Copyright (c) .NET Foundation Contributors
(c) 1995-2024 Jean-loup Gailly and Mark Adler
Copyright (c) 2020 Mara Bos
-Copyright (c) .NET Foundation and Contributors
Copyright (c) 2012 - present, Victor Zverovich
Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
@@ -2714,30 +2313,15 @@ Copyright (c) 1980, 1986, 1993 The Regents of the University of California
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
+MIT License
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
+Copyright (c)
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
@@ -2762,7 +2346,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
---------------------------------------------------------
-System.Diagnostics.EventLog 9.0.9 - MIT
+System.Diagnostics.EventLog 10.0.0 - MIT
Copyright (c) 2021
@@ -2785,7 +2369,7 @@ Copyright (c) 2005-2020 Rich Felker
Copyright (c) 2012-2021 Yann Collet
Copyright (c) Microsoft Corporation
Copyright (c) 2007 James Newton-King
-Copyright (c) 1991-2022 Unicode, Inc.
+Copyright (c) 1991-2024 Unicode, Inc.
Copyright (c) 2013-2017, Alfred Klomp
Copyright (c) 2018 Nemanja Mijailovic
Copyright 2012 the V8 project authors
@@ -2806,7 +2390,6 @@ Copyright (c) The Internet Society (2003)
Copyright (c) .NET Foundation Contributors
(c) 1995-2024 Jean-loup Gailly and Mark Adler
Copyright (c) 2020 Mara Bos
-Copyright (c) .NET Foundation and Contributors
Copyright (c) 2012 - present, Victor Zverovich
Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
@@ -2823,36 +2406,21 @@ Copyright (c) 1980, 1986, 1993 The Regents of the University of California
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
+MIT License
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
+Copyright (c)
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
---------------------------------------------------------
-System.Diagnostics.PerformanceCounter 9.0.9 - MIT
+System.Diagnostics.PerformanceCounter 10.0.0 - MIT
Copyright (c) 2021
@@ -2875,7 +2443,7 @@ Copyright (c) 2005-2020 Rich Felker
Copyright (c) 2012-2021 Yann Collet
Copyright (c) Microsoft Corporation
Copyright (c) 2007 James Newton-King
-Copyright (c) 1991-2022 Unicode, Inc.
+Copyright (c) 1991-2024 Unicode, Inc.
Copyright (c) 2013-2017, Alfred Klomp
Copyright (c) 2018 Nemanja Mijailovic
Copyright 2012 the V8 project authors
@@ -2896,7 +2464,6 @@ Copyright (c) The Internet Society (2003)
Copyright (c) .NET Foundation Contributors
(c) 1995-2024 Jean-loup Gailly and Mark Adler
Copyright (c) 2020 Mara Bos
-Copyright (c) .NET Foundation and Contributors
Copyright (c) 2012 - present, Victor Zverovich
Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
@@ -2913,36 +2480,21 @@ Copyright (c) 1980, 1986, 1993 The Regents of the University of California
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
+MIT License
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
+Copyright (c)
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
---------------------------------------------------------
-System.DirectoryServices 9.0.9 - MIT
+System.DirectoryServices 10.0.0 - MIT
Copyright (c) 2021
@@ -2965,7 +2517,7 @@ Copyright (c) 2005-2020 Rich Felker
Copyright (c) 2012-2021 Yann Collet
Copyright (c) Microsoft Corporation
Copyright (c) 2007 James Newton-King
-Copyright (c) 1991-2022 Unicode, Inc.
+Copyright (c) 1991-2024 Unicode, Inc.
Copyright (c) 2013-2017, Alfred Klomp
Copyright (c) 2018 Nemanja Mijailovic
Copyright 2012 the V8 project authors
@@ -2986,7 +2538,6 @@ Copyright (c) The Internet Society (2003)
Copyright (c) .NET Foundation Contributors
(c) 1995-2024 Jean-loup Gailly and Mark Adler
Copyright (c) 2020 Mara Bos
-Copyright (c) .NET Foundation and Contributors
Copyright (c) 2012 - present, Victor Zverovich
Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
@@ -3003,36 +2554,21 @@ Copyright (c) 1980, 1986, 1993 The Regents of the University of California
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
+MIT License
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
+Copyright (c)
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
---------------------------------------------------------
-System.DirectoryServices.AccountManagement 9.0.9 - MIT
+System.DirectoryServices.AccountManagement 10.0.0 - MIT
Copyright (c) 2021
@@ -3055,7 +2591,7 @@ Copyright (c) 2005-2020 Rich Felker
Copyright (c) 2012-2021 Yann Collet
Copyright (c) Microsoft Corporation
Copyright (c) 2007 James Newton-King
-Copyright (c) 1991-2022 Unicode, Inc.
+Copyright (c) 1991-2024 Unicode, Inc.
Copyright (c) 2013-2017, Alfred Klomp
Copyright (c) 2018 Nemanja Mijailovic
Copyright 2012 the V8 project authors
@@ -3076,7 +2612,6 @@ Copyright (c) The Internet Society (2003)
Copyright (c) .NET Foundation Contributors
(c) 1995-2024 Jean-loup Gailly and Mark Adler
Copyright (c) 2020 Mara Bos
-Copyright (c) .NET Foundation and Contributors
Copyright (c) 2012 - present, Victor Zverovich
Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
@@ -3093,36 +2628,21 @@ Copyright (c) 1980, 1986, 1993 The Regents of the University of California
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
-The MIT License (MIT)
+MIT License
-Copyright (c) .NET Foundation and Contributors
+Copyright (c)
-All rights reserved.
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
---------------------------------------------------------
-System.DirectoryServices.Protocols 9.0.9 - MIT
+System.DirectoryServices.Protocols 10.0.0 - MIT
Copyright (c) 2021
@@ -3145,7 +2665,7 @@ Copyright (c) 2005-2020 Rich Felker
Copyright (c) 2012-2021 Yann Collet
Copyright (c) Microsoft Corporation
Copyright (c) 2007 James Newton-King
-Copyright (c) 1991-2022 Unicode, Inc.
+Copyright (c) 1991-2024 Unicode, Inc.
Copyright (c) 2013-2017, Alfred Klomp
Copyright (c) 2018 Nemanja Mijailovic
Copyright 2012 the V8 project authors
@@ -3166,7 +2686,6 @@ Copyright (c) The Internet Society (2003)
Copyright (c) .NET Foundation Contributors
(c) 1995-2024 Jean-loup Gailly and Mark Adler
Copyright (c) 2020 Mara Bos
-Copyright (c) .NET Foundation and Contributors
Copyright (c) 2012 - present, Victor Zverovich
Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
@@ -3183,36 +2702,21 @@ Copyright (c) 1980, 1986, 1993 The Regents of the University of California
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
+MIT License
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
+Copyright (c)
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
---------------------------------------------------------
-System.Drawing.Common 9.0.9 - MIT
+System.Drawing.Common 10.0.0 - MIT
(c) Microsoft Corporation
@@ -3247,7 +2751,7 @@ SOFTWARE.
---------------------------------------------------------
-System.IO.Packaging 9.0.9 - MIT
+System.IO.Packaging 10.0.0 - MIT
Copyright (c) 2021
@@ -3270,7 +2774,7 @@ Copyright (c) 2005-2020 Rich Felker
Copyright (c) 2012-2021 Yann Collet
Copyright (c) Microsoft Corporation
Copyright (c) 2007 James Newton-King
-Copyright (c) 1991-2022 Unicode, Inc.
+Copyright (c) 1991-2024 Unicode, Inc.
Copyright (c) 2013-2017, Alfred Klomp
Copyright (c) 2018 Nemanja Mijailovic
Copyright 2012 the V8 project authors
@@ -3291,7 +2795,6 @@ Copyright (c) The Internet Society (2003)
Copyright (c) .NET Foundation Contributors
(c) 1995-2024 Jean-loup Gailly and Mark Adler
Copyright (c) 2020 Mara Bos
-Copyright (c) .NET Foundation and Contributors
Copyright (c) 2012 - present, Victor Zverovich
Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
@@ -3308,36 +2811,21 @@ Copyright (c) 1980, 1986, 1993 The Regents of the University of California
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
+MIT License
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
+Copyright (c)
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
---------------------------------------------------------
-System.IO.Ports 9.0.9 - MIT
+System.IO.Ports 10.0.0 - MIT
Copyright (c) 2021
@@ -3360,7 +2848,7 @@ Copyright (c) 2005-2020 Rich Felker
Copyright (c) 2012-2021 Yann Collet
Copyright (c) Microsoft Corporation
Copyright (c) 2007 James Newton-King
-Copyright (c) 1991-2022 Unicode, Inc.
+Copyright (c) 1991-2024 Unicode, Inc.
Copyright (c) 2013-2017, Alfred Klomp
Copyright (c) 2018 Nemanja Mijailovic
Copyright 2012 the V8 project authors
@@ -3381,7 +2869,6 @@ Copyright (c) The Internet Society (2003)
Copyright (c) .NET Foundation Contributors
(c) 1995-2024 Jean-loup Gailly and Mark Adler
Copyright (c) 2020 Mara Bos
-Copyright (c) .NET Foundation and Contributors
Copyright (c) 2012 - present, Victor Zverovich
Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
@@ -3398,36 +2885,21 @@ Copyright (c) 1980, 1986, 1993 The Regents of the University of California
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
+MIT License
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
+Copyright (c)
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
---------------------------------------------------------
-System.Management 9.0.9 - MIT
+System.Management 10.0.0 - MIT
Copyright (c) 2021
@@ -3450,7 +2922,7 @@ Copyright (c) 2005-2020 Rich Felker
Copyright (c) 2012-2021 Yann Collet
Copyright (c) Microsoft Corporation
Copyright (c) 2007 James Newton-King
-Copyright (c) 1991-2022 Unicode, Inc.
+Copyright (c) 1991-2024 Unicode, Inc.
Copyright (c) 2013-2017, Alfred Klomp
Copyright (c) 2018 Nemanja Mijailovic
Copyright 2012 the V8 project authors
@@ -3471,7 +2943,6 @@ Copyright (c) The Internet Society (2003)
Copyright (c) .NET Foundation Contributors
(c) 1995-2024 Jean-loup Gailly and Mark Adler
Copyright (c) 2020 Mara Bos
-Copyright (c) .NET Foundation and Contributors
Copyright (c) 2012 - present, Victor Zverovich
Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
@@ -3488,36 +2959,21 @@ Copyright (c) 1980, 1986, 1993 The Regents of the University of California
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
+MIT License
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
+Copyright (c)
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
---------------------------------------------------------
-System.Net.Http.WinHttpHandler 9.0.9 - MIT
+System.Net.Http.WinHttpHandler 10.0.0 - MIT
Copyright (c) 2021
@@ -3540,7 +2996,7 @@ Copyright (c) 2005-2020 Rich Felker
Copyright (c) 2012-2021 Yann Collet
Copyright (c) Microsoft Corporation
Copyright (c) 2007 James Newton-King
-Copyright (c) 1991-2022 Unicode, Inc.
+Copyright (c) 1991-2024 Unicode, Inc.
Copyright (c) 2013-2017, Alfred Klomp
Copyright (c) 2018 Nemanja Mijailovic
Copyright 2012 the V8 project authors
@@ -3561,7 +3017,6 @@ Copyright (c) The Internet Society (2003)
Copyright (c) .NET Foundation Contributors
(c) 1995-2024 Jean-loup Gailly and Mark Adler
Copyright (c) 2020 Mara Bos
-Copyright (c) .NET Foundation and Contributors
Copyright (c) 2012 - present, Victor Zverovich
Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
@@ -3578,72 +3033,21 @@ Copyright (c) 1980, 1986, 1993 The Regents of the University of California
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-
-
----------------------------------------------------------
-
----------------------------------------------------------
-
-System.Private.ServiceModel 4.10.3 - MIT
-
-
-(c) Microsoft Corporation
-Copyright (c) .NET Foundation and Contributors
-Copyright (c) 2000-2014 The Legion of the Bouncy Castle Inc. (http://www.bouncycastle.org)
-
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
+MIT License
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
+Copyright (c)
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
---------------------------------------------------------
-System.Reflection.Context 9.0.9 - MIT
+System.Reflection.Context 10.0.0 - MIT
Copyright (c) 2021
@@ -3666,7 +3070,7 @@ Copyright (c) 2005-2020 Rich Felker
Copyright (c) 2012-2021 Yann Collet
Copyright (c) Microsoft Corporation
Copyright (c) 2007 James Newton-King
-Copyright (c) 1991-2022 Unicode, Inc.
+Copyright (c) 1991-2024 Unicode, Inc.
Copyright (c) 2013-2017, Alfred Klomp
Copyright (c) 2018 Nemanja Mijailovic
Copyright 2012 the V8 project authors
@@ -3687,7 +3091,6 @@ Copyright (c) The Internet Society (2003)
Copyright (c) .NET Foundation Contributors
(c) 1995-2024 Jean-loup Gailly and Mark Adler
Copyright (c) 2020 Mara Bos
-Copyright (c) .NET Foundation and Contributors
Copyright (c) 2012 - present, Victor Zverovich
Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
@@ -3704,36 +3107,21 @@ Copyright (c) 1980, 1986, 1993 The Regents of the University of California
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
+MIT License
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
+Copyright (c)
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
---------------------------------------------------------
-System.Runtime.Caching 9.0.9 - MIT
+System.Runtime.Caching 10.0.0 - MIT
Copyright (c) 2021
@@ -3756,7 +3144,7 @@ Copyright (c) 2005-2020 Rich Felker
Copyright (c) 2012-2021 Yann Collet
Copyright (c) Microsoft Corporation
Copyright (c) 2007 James Newton-King
-Copyright (c) 1991-2022 Unicode, Inc.
+Copyright (c) 1991-2024 Unicode, Inc.
Copyright (c) 2013-2017, Alfred Klomp
Copyright (c) 2018 Nemanja Mijailovic
Copyright 2012 the V8 project authors
@@ -3777,7 +3165,6 @@ Copyright (c) The Internet Society (2003)
Copyright (c) .NET Foundation Contributors
(c) 1995-2024 Jean-loup Gailly and Mark Adler
Copyright (c) 2020 Mara Bos
-Copyright (c) .NET Foundation and Contributors
Copyright (c) 2012 - present, Victor Zverovich
Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
@@ -3794,36 +3181,21 @@ Copyright (c) 1980, 1986, 1993 The Regents of the University of California
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
+MIT License
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
+Copyright (c)
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
---------------------------------------------------------
-System.Security.Cryptography.Pkcs 9.0.9 - MIT
+System.Security.Cryptography.Pkcs 10.0.0 - MIT
Copyright (c) 2021
@@ -3846,7 +3218,7 @@ Copyright (c) 2005-2020 Rich Felker
Copyright (c) 2012-2021 Yann Collet
Copyright (c) Microsoft Corporation
Copyright (c) 2007 James Newton-King
-Copyright (c) 1991-2022 Unicode, Inc.
+Copyright (c) 1991-2024 Unicode, Inc.
Copyright (c) 2013-2017, Alfred Klomp
Copyright (c) 2018 Nemanja Mijailovic
Copyright 2012 the V8 project authors
@@ -3867,7 +3239,6 @@ Copyright (c) The Internet Society (2003)
Copyright (c) .NET Foundation Contributors
(c) 1995-2024 Jean-loup Gailly and Mark Adler
Copyright (c) 2020 Mara Bos
-Copyright (c) .NET Foundation and Contributors
Copyright (c) 2012 - present, Victor Zverovich
Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
@@ -3884,36 +3255,21 @@ Copyright (c) 1980, 1986, 1993 The Regents of the University of California
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
+MIT License
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
+Copyright (c)
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
---------------------------------------------------------
-System.Security.Cryptography.ProtectedData 9.0.9 - MIT
+System.Security.Cryptography.ProtectedData 10.0.0 - MIT
Copyright (c) 2021
@@ -3936,7 +3292,7 @@ Copyright (c) 2005-2020 Rich Felker
Copyright (c) 2012-2021 Yann Collet
Copyright (c) Microsoft Corporation
Copyright (c) 2007 James Newton-King
-Copyright (c) 1991-2022 Unicode, Inc.
+Copyright (c) 1991-2024 Unicode, Inc.
Copyright (c) 2013-2017, Alfred Klomp
Copyright (c) 2018 Nemanja Mijailovic
Copyright 2012 the V8 project authors
@@ -3957,7 +3313,6 @@ Copyright (c) The Internet Society (2003)
Copyright (c) .NET Foundation Contributors
(c) 1995-2024 Jean-loup Gailly and Mark Adler
Copyright (c) 2020 Mara Bos
-Copyright (c) .NET Foundation and Contributors
Copyright (c) 2012 - present, Victor Zverovich
Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
@@ -3974,36 +3329,21 @@ Copyright (c) 1980, 1986, 1993 The Regents of the University of California
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
+MIT License
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
+Copyright (c)
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
---------------------------------------------------------
-System.Security.Cryptography.Xml 9.0.9 - MIT
+System.Security.Cryptography.Xml 10.0.0 - MIT
Copyright (c) 2021
@@ -4026,7 +3366,7 @@ Copyright (c) 2005-2020 Rich Felker
Copyright (c) 2012-2021 Yann Collet
Copyright (c) Microsoft Corporation
Copyright (c) 2007 James Newton-King
-Copyright (c) 1991-2022 Unicode, Inc.
+Copyright (c) 1991-2024 Unicode, Inc.
Copyright (c) 2013-2017, Alfred Klomp
Copyright (c) 2018 Nemanja Mijailovic
Copyright 2012 the V8 project authors
@@ -4047,7 +3387,6 @@ Copyright (c) The Internet Society (2003)
Copyright (c) .NET Foundation Contributors
(c) 1995-2024 Jean-loup Gailly and Mark Adler
Copyright (c) 2020 Mara Bos
-Copyright (c) .NET Foundation and Contributors
Copyright (c) 2012 - present, Victor Zverovich
Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
@@ -4064,36 +3403,21 @@ Copyright (c) 1980, 1986, 1993 The Regents of the University of California
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
+MIT License
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
+Copyright (c)
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
---------------------------------------------------------
-System.Security.Permissions 9.0.9 - MIT
+System.Security.Permissions 10.0.0 - MIT
Copyright (c) 2021
@@ -4116,7 +3440,7 @@ Copyright (c) 2005-2020 Rich Felker
Copyright (c) 2012-2021 Yann Collet
Copyright (c) Microsoft Corporation
Copyright (c) 2007 James Newton-King
-Copyright (c) 1991-2022 Unicode, Inc.
+Copyright (c) 1991-2024 Unicode, Inc.
Copyright (c) 2013-2017, Alfred Klomp
Copyright (c) 2018 Nemanja Mijailovic
Copyright 2012 the V8 project authors
@@ -4137,7 +3461,6 @@ Copyright (c) The Internet Society (2003)
Copyright (c) .NET Foundation Contributors
(c) 1995-2024 Jean-loup Gailly and Mark Adler
Copyright (c) 2020 Mara Bos
-Copyright (c) .NET Foundation and Contributors
Copyright (c) 2012 - present, Victor Zverovich
Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
@@ -4154,113 +3477,26 @@ Copyright (c) 1980, 1986, 1993 The Regents of the University of California
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-
-
----------------------------------------------------------
-
----------------------------------------------------------
-
-System.ServiceModel.Duplex 4.10.3 - MIT
-
-
-(c) Microsoft Corporation
-Copyright (c) .NET Foundation and Contributors
-Copyright (c) 2000-2014 The Legion of the Bouncy Castle Inc. (http://www.bouncycastle.org)
-
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-
-
----------------------------------------------------------
-
----------------------------------------------------------
-
-System.ServiceModel.Http 4.10.3 - MIT
-
-
-(c) Microsoft Corporation
-Copyright (c) .NET Foundation and Contributors
-Copyright (c) 2000-2014 The Legion of the Bouncy Castle Inc. (http://www.bouncycastle.org)
-
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
+MIT License
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
+Copyright (c)
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
---------------------------------------------------------
-System.ServiceModel.NetTcp 4.10.3 - MIT
+System.ServiceModel.Http 8.1.2 - MIT
(c) Microsoft Corporation
Copyright (c) .NET Foundation and Contributors
-Copyright (c) 2000-2014 The Legion of the Bouncy Castle Inc. (http://www.bouncycastle.org)
+Copyright (c) 2000-2014 The Legion of the Bouncy Castle Inc. (http://www.bouncycastle.org) Provided
The MIT License (MIT)
@@ -4291,12 +3527,12 @@ SOFTWARE.
---------------------------------------------------------
-System.ServiceModel.Primitives 4.10.3 - MIT
+System.ServiceModel.NetFramingBase 8.1.2 - MIT
(c) Microsoft Corporation
Copyright (c) .NET Foundation and Contributors
-Copyright (c) 2000-2014 The Legion of the Bouncy Castle Inc. (http://www.bouncycastle.org)
+Copyright (c) 2000-2014 The Legion of the Bouncy Castle Inc. (http://www.bouncycastle.org) Provided
The MIT License (MIT)
@@ -4327,12 +3563,12 @@ SOFTWARE.
---------------------------------------------------------
-System.ServiceModel.Security 4.10.3 - MIT
+System.ServiceModel.NetTcp 8.1.2 - MIT
(c) Microsoft Corporation
Copyright (c) .NET Foundation and Contributors
-Copyright (c) 2000-2014 The Legion of the Bouncy Castle Inc. (http://www.bouncycastle.org)
+Copyright (c) 2000-2014 The Legion of the Bouncy Castle Inc. (http://www.bouncycastle.org) Provided
The MIT License (MIT)
@@ -4363,66 +3599,12 @@ SOFTWARE.
---------------------------------------------------------
-System.ServiceModel.Syndication 9.0.9 - MIT
+System.ServiceModel.Primitives 8.1.2 - MIT
-Copyright (c) 2021
-Copyright (c) Six Labors
(c) Microsoft Corporation
-Copyright (c) 2022 FormatJS
-Copyright (c) Andrew Arnott
-Copyright 2019 LLVM Project
-Copyright (c) 1998 Microsoft
-Copyright 2018 Daniel Lemire
-Copyright (c) .NET Foundation
-Copyright (c) 2011, Google Inc.
-Copyright (c) 2020 Dan Shechter
-(c) 1997-2005 Sean Eron Anderson
-Copyright (c) 2015 Andrew Gallant
-Copyright (c) 2022, Wojciech Mula
-Copyright (c) 2017 Yoshifumi Kawai
-Copyright (c) 2022, Geoff Langdale
-Copyright (c) 2005-2020 Rich Felker
-Copyright (c) 2012-2021 Yann Collet
-Copyright (c) Microsoft Corporation
-Copyright (c) 2007 James Newton-King
-Copyright (c) 1991-2022 Unicode, Inc.
-Copyright (c) 2013-2017, Alfred Klomp
-Copyright (c) 2018 Nemanja Mijailovic
-Copyright 2012 the V8 project authors
-Copyright (c) 1999 Lucent Technologies
-Copyright (c) 2008-2016, Wojciech Mula
-Copyright (c) 2011-2020 Microsoft Corp
-Copyright (c) 2015-2017, Wojciech Mula
-Copyright (c) 2015-2018, Wojciech Mula
-Copyright (c) 2005-2007, Nick Galbreath
-Copyright (c) 2015 The Chromium Authors
-Copyright (c) 2018 Alexander Chermyanin
-Copyright (c) The Internet Society 1997
-Copyright (c) 2004-2006 Intel Corporation
-Copyright (c) 2011-2015 Intel Corporation
-Copyright (c) 2013-2017, Milosz Krajewski
-Copyright (c) 2016-2017, Matthieu Darbois
-Copyright (c) The Internet Society (2003)
-Copyright (c) .NET Foundation Contributors
-(c) 1995-2024 Jean-loup Gailly and Mark Adler
-Copyright (c) 2020 Mara Bos
Copyright (c) .NET Foundation and Contributors
-Copyright (c) 2012 - present, Victor Zverovich
-Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
-Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
-Copyright (c) 2019 Microsoft Corporation, Daan Leijen
-Copyright (c) 2011 Novell, Inc (http://www.novell.com)
-Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)
-Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors
-Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com
-Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.
-Portions (c) International Organization for Standardization 1986
-Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers
-Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip
-Copyright (c) 1980, 1986, 1993 The Regents of the University of California
-Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
-Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
+Copyright (c) 2000-2014 The Legion of the Bouncy Castle Inc. (http://www.bouncycastle.org) Provided
The MIT License (MIT)
@@ -4453,7 +3635,7 @@ SOFTWARE.
---------------------------------------------------------
-System.ServiceProcess.ServiceController 9.0.9 - MIT
+System.ServiceModel.Syndication 10.0.0 - MIT
Copyright (c) 2021
@@ -4476,7 +3658,7 @@ Copyright (c) 2005-2020 Rich Felker
Copyright (c) 2012-2021 Yann Collet
Copyright (c) Microsoft Corporation
Copyright (c) 2007 James Newton-King
-Copyright (c) 1991-2022 Unicode, Inc.
+Copyright (c) 1991-2024 Unicode, Inc.
Copyright (c) 2013-2017, Alfred Klomp
Copyright (c) 2018 Nemanja Mijailovic
Copyright 2012 the V8 project authors
@@ -4497,7 +3679,6 @@ Copyright (c) The Internet Society (2003)
Copyright (c) .NET Foundation Contributors
(c) 1995-2024 Jean-loup Gailly and Mark Adler
Copyright (c) 2020 Mara Bos
-Copyright (c) .NET Foundation and Contributors
Copyright (c) 2012 - present, Victor Zverovich
Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
@@ -4514,36 +3695,21 @@ Copyright (c) 1980, 1986, 1993 The Regents of the University of California
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
+MIT License
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
+Copyright (c)
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
---------------------------------------------------------
-System.Speech 9.0.9 - MIT
+System.ServiceProcess.ServiceController 10.0.0 - MIT
Copyright (c) 2021
@@ -4566,7 +3732,7 @@ Copyright (c) 2005-2020 Rich Felker
Copyright (c) 2012-2021 Yann Collet
Copyright (c) Microsoft Corporation
Copyright (c) 2007 James Newton-King
-Copyright (c) 1991-2022 Unicode, Inc.
+Copyright (c) 1991-2024 Unicode, Inc.
Copyright (c) 2013-2017, Alfred Klomp
Copyright (c) 2018 Nemanja Mijailovic
Copyright 2012 the V8 project authors
@@ -4587,7 +3753,6 @@ Copyright (c) The Internet Society (2003)
Copyright (c) .NET Foundation Contributors
(c) 1995-2024 Jean-loup Gailly and Mark Adler
Copyright (c) 2020 Mara Bos
-Copyright (c) .NET Foundation and Contributors
Copyright (c) 2012 - present, Victor Zverovich
Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
@@ -4604,36 +3769,21 @@ Copyright (c) 1980, 1986, 1993 The Regents of the University of California
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
+MIT License
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
+Copyright (c)
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
---------------------------------------------------------
-System.Threading.AccessControl 9.0.9 - MIT
+System.Speech 10.0.0 - MIT
Copyright (c) 2021
@@ -4656,7 +3806,7 @@ Copyright (c) 2005-2020 Rich Felker
Copyright (c) 2012-2021 Yann Collet
Copyright (c) Microsoft Corporation
Copyright (c) 2007 James Newton-King
-Copyright (c) 1991-2022 Unicode, Inc.
+Copyright (c) 1991-2024 Unicode, Inc.
Copyright (c) 2013-2017, Alfred Klomp
Copyright (c) 2018 Nemanja Mijailovic
Copyright 2012 the V8 project authors
@@ -4677,7 +3827,6 @@ Copyright (c) The Internet Society (2003)
Copyright (c) .NET Foundation Contributors
(c) 1995-2024 Jean-loup Gailly and Mark Adler
Copyright (c) 2020 Mara Bos
-Copyright (c) .NET Foundation and Contributors
Copyright (c) 2012 - present, Victor Zverovich
Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
@@ -4694,30 +3843,15 @@ Copyright (c) 1980, 1986, 1993 The Regents of the University of California
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
+MIT License
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
+Copyright (c)
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
@@ -4759,7 +3893,7 @@ SOFTWARE.
---------------------------------------------------------
-System.Windows.Extensions 9.0.9 - MIT
+System.Windows.Extensions 10.0.0 - MIT
Copyright (c) 2021
@@ -4782,7 +3916,7 @@ Copyright (c) 2005-2020 Rich Felker
Copyright (c) 2012-2021 Yann Collet
Copyright (c) Microsoft Corporation
Copyright (c) 2007 James Newton-King
-Copyright (c) 1991-2022 Unicode, Inc.
+Copyright (c) 1991-2024 Unicode, Inc.
Copyright (c) 2013-2017, Alfred Klomp
Copyright (c) 2018 Nemanja Mijailovic
Copyright 2012 the V8 project authors
@@ -4803,7 +3937,6 @@ Copyright (c) The Internet Society (2003)
Copyright (c) .NET Foundation Contributors
(c) 1995-2024 Jean-loup Gailly and Mark Adler
Copyright (c) 2020 Mara Bos
-Copyright (c) .NET Foundation and Contributors
Copyright (c) 2012 - present, Victor Zverovich
Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
@@ -4820,30 +3953,15 @@ Copyright (c) 1980, 1986, 1993 The Regents of the University of California
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
-The MIT License (MIT)
-
-Copyright (c) .NET Foundation and Contributors
-
-All rights reserved.
+MIT License
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
+Copyright (c)
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
diff --git a/build.psm1 b/build.psm1
index a610c684e2c..7640bf5ccf5 100644
--- a/build.psm1
+++ b/build.psm1
@@ -385,7 +385,7 @@ function Start-PSBuild {
}
if ($Clean) {
- Write-Log -message "Cleaning your working directory. You can also do it with 'git clean -fdX --exclude .vs/PowerShell/v16/Server/sqlite3'"
+ Write-LogGroupStart -Title "Cleaning your working directory"
Push-Location $PSScriptRoot
try {
# Excluded sqlite3 folder is due to this Roslyn issue: https://github.com/dotnet/roslyn/issues/23060
@@ -393,6 +393,7 @@ function Start-PSBuild {
# Excluded nuget.config as this is required for release build.
git clean -fdX --exclude .vs/PowerShell/v16/Server/sqlite3 --exclude src/Modules/nuget.config --exclude nuget.config
} finally {
+ Write-LogGroupEnd -Title "Cleaning your working directory"
Pop-Location
}
}
@@ -536,7 +537,9 @@ Fix steps:
}
# handle Restore
+ Write-LogGroupStart -Title "Restore NuGet Packages"
Restore-PSPackage -Options $Options -Force:$Restore -InteractiveAuth:$InteractiveAuth
+ Write-LogGroupEnd -Title "Restore NuGet Packages"
# handle ResGen
# Heuristic to run ResGen on the fresh machine
@@ -566,6 +569,7 @@ Fix steps:
$publishPath = $Options.Output
}
+ Write-LogGroupStart -Title "Build PowerShell"
try {
# Relative paths do not work well if cwd is not changed to project
Push-Location $Options.Top
@@ -620,6 +624,7 @@ Fix steps:
} finally {
Pop-Location
}
+ Write-LogGroupEnd -Title "Build PowerShell"
# No extra post-building task will run if '-SMAOnly' is specified, because its purpose is for a quick update of S.M.A.dll after full build.
if ($SMAOnly) {
@@ -627,6 +632,7 @@ Fix steps:
}
# publish reference assemblies
+ Write-LogGroupStart -Title "Publish Reference Assemblies"
try {
Push-Location "$PSScriptRoot/src/TypeCatalogGen"
$refAssemblies = Get-Content -Path $incFileName | Where-Object { $_ -like "*microsoft.netcore.app*" } | ForEach-Object { $_.TrimEnd(';') }
@@ -640,6 +646,7 @@ Fix steps:
} finally {
Pop-Location
}
+ Write-LogGroupEnd -Title "Publish Reference Assemblies"
if ($ReleaseTag) {
$psVersion = $ReleaseTag
@@ -682,10 +689,13 @@ Fix steps:
# download modules from powershell gallery.
# - PowerShellGet, PackageManagement, Microsoft.PowerShell.Archive
if ($PSModuleRestore) {
+ Write-LogGroupStart -Title "Restore PowerShell Modules"
Restore-PSModuleToBuild -PublishPath $publishPath
+ Write-LogGroupEnd -Title "Restore PowerShell Modules"
}
# publish powershell.config.json
+ Write-LogGroupStart -Title "Generate PowerShell Configuration"
$config = [ordered]@{}
if ($Options.Runtime -like "*win*") {
@@ -731,10 +741,13 @@ Fix steps:
} else {
Write-Warning "No powershell.config.json generated for $publishPath"
}
+ Write-LogGroupEnd -Title "Generate PowerShell Configuration"
# Restore the Pester module
if ($CI) {
+ Write-LogGroupStart -Title "Restore Pester Module"
Restore-PSPester -Destination (Join-Path $publishPath "Modules")
+ Write-LogGroupEnd -Title "Restore Pester Module"
}
Clear-NativeDependencies -PublishFolder $publishPath
@@ -2086,6 +2099,7 @@ function Install-Dotnet {
[string]$FeedCredential
)
+ Write-LogGroupStart -Title "Install .NET SDK $Version"
Write-Verbose -Verbose "In install-dotnet"
# This allows sudo install to be optional; needed when running in containers / as root
@@ -2220,6 +2234,7 @@ function Install-Dotnet {
}
}
}
+ Write-LogGroupEnd -Title "Install .NET SDK $Version"
}
function Get-RedHatPackageManager {
@@ -2234,43 +2249,6 @@ function Get-RedHatPackageManager {
}
}
-function Install-GlobalGem {
- param(
- [Parameter()]
- [string]
- $Sudo = "",
-
- [Parameter(Mandatory)]
- [string]
- $GemName,
-
- [Parameter(Mandatory)]
- [string]
- $GemVersion
- )
- try {
- # We cannot guess if the user wants to run gem install as root on linux and windows,
- # but macOs usually requires sudo
- $gemsudo = ''
- if($environment.IsMacOS -or $env:TF_BUILD) {
- $gemsudo = $sudo
- }
-
- Start-NativeExecution ([ScriptBlock]::Create("$gemsudo gem install $GemName -v $GemVersion --no-document"))
-
- } catch {
- Write-Warning "Installation of gem $GemName $GemVersion failed! Must resolve manually."
- $logs = Get-ChildItem "/var/lib/gems/*/extensions/x86_64-linux/*/$GemName-*/gem_make.out" | Select-Object -ExpandProperty FullName
- foreach ($log in $logs) {
- Write-Verbose "Contents of: $log" -Verbose
- Get-Content -Raw -Path $log -ErrorAction Ignore | ForEach-Object { Write-Verbose $_ -Verbose }
- Write-Verbose "END Contents of: $log" -Verbose
- }
-
- throw
- }
-}
-
function Start-PSBootstrap {
[CmdletBinding()]
param(
@@ -2282,7 +2260,12 @@ function Start-PSBootstrap {
[switch]$BuildLinuxArm,
[switch]$Force,
[Parameter(Mandatory = $true)]
- [ValidateSet("Package", "DotNet", "Both")]
+ # Package: Install dependencies for packaging tools (rpmbuild, dpkg-deb, pkgbuild, WiX)
+ # DotNet: Install the .NET SDK
+ # Both: Package and DotNet scenarios
+ # Tools: Install .NET global tools (e.g., dotnet-format)
+ # All: Install all dependencies (packaging, .NET SDK, and tools)
+ [ValidateSet("Package", "DotNet", "Both", "Tools", "All")]
[string]$Scenario = "Package"
)
@@ -2296,12 +2279,14 @@ function Start-PSBootstrap {
try {
if ($environment.IsLinux -or $environment.IsMacOS) {
+ Write-LogGroupStart -Title "Install Native Dependencies"
# This allows sudo install to be optional; needed when running in containers / as root
# Note that when it is null, Invoke-Expression (but not &) must be used to interpolate properly
$sudo = if (!$NoSudo) { "sudo" }
if ($BuildLinuxArm -and $environment.IsLinux -and -not $environment.IsUbuntu -and -not $environment.IsMariner) {
Write-Error "Cross compiling for linux-arm is only supported on AzureLinux/Ubuntu environment"
+ Write-LogGroupEnd -Title "Install Native Dependencies"
return
}
@@ -2316,7 +2301,9 @@ function Start-PSBootstrap {
elseif ($environment.IsUbuntu18) { $Deps += "libicu60"}
# Packaging tools
- if ($Scenario -eq 'Both' -or $Scenario -eq 'Package') { $Deps += "ruby-dev", "groff", "libffi-dev", "rpm", "g++", "make" }
+ # Note: ruby-dev, libffi-dev, g++, and make are no longer needed for DEB packaging
+ # DEB packages now use native dpkg-deb (pre-installed)
+ if ($Scenario -eq 'Both' -or $Scenario -eq 'Package') { $Deps += "groff", "rpm" }
# Install dependencies
# change the fontend from apt-get to noninteractive
@@ -2340,7 +2327,9 @@ function Start-PSBootstrap {
$Deps += "libicu", "openssl-libs"
# Packaging tools
- if ($Scenario -eq 'Both' -or $Scenario -eq 'Package') { $Deps += "ruby-devel", "rpm-build", "groff", 'libffi-devel', "gcc-c++" }
+ # Note: ruby-devel and libffi-devel are no longer needed
+ # RPM packages use rpmbuild, DEB packages use dpkg-deb
+ if ($Scenario -eq 'Both' -or $Scenario -eq 'Package') { $Deps += "rpm-build", "groff" }
$PackageManager = Get-RedHatPackageManager
@@ -2361,7 +2350,8 @@ function Start-PSBootstrap {
$Deps += "wget"
# Packaging tools
- if ($Scenario -eq 'Both' -or $Scenario -eq 'Package') { $Deps += "ruby-devel", "rpmbuild", "groff", 'libffi-devel', "gcc" }
+ # Note: ruby-devel and libffi-devel are no longer needed for packaging
+ if ($Scenario -eq 'Both' -or $Scenario -eq 'Package') { $Deps += "rpmbuild", "groff" }
$PackageManager = "zypper --non-interactive install"
$baseCommand = "$sudo $PackageManager"
@@ -2400,16 +2390,42 @@ function Start-PSBootstrap {
}
}
- # Install [fpm](https://github.com/jordansissel/fpm)
- if ($Scenario -eq 'Both' -or $Scenario -eq 'Package') {
- Install-GlobalGem -Sudo $sudo -GemName "dotenv" -GemVersion "2.8.1"
- Install-GlobalGem -Sudo $sudo -GemName "ffi" -GemVersion "1.16.3"
- Install-GlobalGem -Sudo $sudo -GemName "fpm" -GemVersion "1.15.1"
- Install-GlobalGem -Sudo $sudo -GemName "rexml" -GemVersion "3.2.5"
+ if ($Scenario -in 'All', 'Both', 'Package') {
+ # For RPM-based systems, ensure rpmbuild is available
+ if ($environment.IsLinux -and ($environment.IsRedHatFamily -or $environment.IsSUSEFamily -or $environment.IsMariner)) {
+ Write-Verbose -Verbose "Checking for rpmbuild..."
+ if (!(Get-Command rpmbuild -ErrorAction SilentlyContinue)) {
+ Write-Warning "rpmbuild not found. Installing rpm-build package..."
+ Start-NativeExecution -sb ([ScriptBlock]::Create("$sudo $PackageManager install -y rpm-build")) -IgnoreExitcode
+ }
+ }
+
+ # For Debian-based systems and Mariner, ensure dpkg-deb is available
+ if ($environment.IsLinux -and ($environment.IsDebianFamily -or $environment.IsMariner)) {
+ Write-Verbose -Verbose "Checking for dpkg-deb..."
+ if (!(Get-Command dpkg-deb -ErrorAction SilentlyContinue)) {
+ Write-Warning "dpkg-deb not found. Installing dpkg package..."
+ if ($environment.IsMariner) {
+ # For Mariner (Azure Linux), install the extended repo first to access dpkg.
+ Write-Verbose -verbose "BEGIN: /etc/os-release content:"
+ Get-Content /etc/os-release | Write-Verbose -verbose
+ Write-Verbose -verbose "END: /etc/os-release content"
+
+ Write-Verbose -Verbose "Installing azurelinux-repos-extended for Mariner..."
+
+ Start-NativeExecution -sb ([ScriptBlock]::Create("$sudo $PackageManager azurelinux-repos-extended")) -IgnoreExitcode -Verbose
+ Start-NativeExecution -sb ([ScriptBlock]::Create("$sudo $PackageManager dpkg")) -IgnoreExitcode -Verbose
+ } else {
+ Start-NativeExecution -sb ([ScriptBlock]::Create("$sudo apt-get install -y dpkg")) -IgnoreExitcode
+ }
+ }
+ }
}
+ Write-LogGroupEnd -Title "Install Native Dependencies"
}
if ($Scenario -eq 'DotNet' -or $Scenario -eq 'Both') {
+ Write-LogGroupStart -Title "Install .NET SDK"
Write-Verbose -Verbose "Calling Find-Dotnet from Start-PSBootstrap"
@@ -2448,10 +2464,12 @@ function Start-PSBootstrap {
else {
Write-Log -message "dotnet is already installed. Skipping installation."
}
+ Write-LogGroupEnd -Title "Install .NET SDK"
}
# Install Windows dependencies if `-Package` or `-BuildWindowsNative` is specified
if ($environment.IsWindows) {
+ Write-LogGroupStart -Title "Install Windows Dependencies"
## The VSCode build task requires 'pwsh.exe' to be found in Path
if (-not (Get-Command -Name pwsh.exe -CommandType Application -ErrorAction Ignore))
{
@@ -2464,12 +2482,32 @@ function Start-PSBootstrap {
$isArm64 = "$env:RUNTIME" -eq 'arm64'
Install-Wix -arm64:$isArm64
}
+ Write-LogGroupEnd -Title "Install Windows Dependencies"
+ }
+
+ # Ensure dotnet is available
+ Find-Dotnet
+
+ if (-not $env:TF_BUILD) {
+ if ($Scenario -eq 'DotNet' -or $Scenario -eq 'Both') {
+ Write-LogGroupStart -Title "Install .NET SDK"
+ Write-Log -message "Installing .NET global tools"
+
+ # Install dotnet-format
+ Write-Verbose -Verbose "Installing dotnet-format global tool"
+ Start-NativeExecution {
+ dotnet tool install --global dotnet-format
+ }
+ Write-LogGroupEnd -Title "Install .NET Global Tools"
+ }
}
if ($env:TF_BUILD) {
+ Write-LogGroupStart -Title "Capture NuGet Sources"
Write-Verbose -Verbose "--- Start - Capturing nuget sources"
dotnet nuget list source --format detailed
Write-Verbose -Verbose "--- End - Capturing nuget sources"
+ Write-LogGroupEnd -Title "Capture NuGet Sources"
}
} finally {
Pop-Location
diff --git a/docs/maintainers/releasing.md b/docs/maintainers/releasing.md
index 5aae87582c9..3562962e68f 100644
--- a/docs/maintainers/releasing.md
+++ b/docs/maintainers/releasing.md
@@ -72,11 +72,18 @@ The output of `Start-PSBuild` includes a `powershell.exe` executable which can s
#### Linux / macOS
The `Start-PSPackage` function delegates to `New-UnixPackage`.
-It relies on the [Effing Package Management][fpm] project,
-which makes building packages for any (non-Windows) platform a breeze.
-Similarly, the PowerShell man-page is generated from the Markdown-like file
+
+For **Linux** (Debian-based distributions), it relies on the [Effing Package Management][fpm] project,
+which makes building packages a breeze.
+
+For **macOS**, it uses native packaging tools (`pkgbuild` and `productbuild`) from Xcode Command Line Tools,
+eliminating the need for Ruby or fpm.
+
+For **Linux** (Red Hat-based distributions), it uses `rpmbuild` directly.
+
+The PowerShell man-page is generated from the Markdown-like file
[`assets/pwsh.1.ronn`][man] using [Ronn][].
-The function `Start-PSBootstrap -Package` will install both these tools.
+The function `Start-PSBootstrap -Package` will install these tools.
To modify any property of the packages, edit the `New-UnixPackage` function.
Please also refer to the function for details on the package properties
@@ -131,7 +138,7 @@ Without `-Name` specified, the primary `powershell`
package will instead be created.
[fpm]: https://github.com/jordansissel/fpm
-[man]: ../../assets/pwsh.1.ronn
+[man]: ../../assets/manpage/pwsh.1.ronn
[ronn]: https://github.com/rtomayko/ronn
### Build and Packaging Examples
diff --git a/dsc/pwsh.profile.dsc.resource.json b/dsc/pwsh.profile.dsc.resource.json
new file mode 100644
index 00000000000..cd18e94eec6
--- /dev/null
+++ b/dsc/pwsh.profile.dsc.resource.json
@@ -0,0 +1,126 @@
+{
+ "$schema": "https://aka.ms/dsc/schemas/v3/bundled/resource/manifest.json",
+ "description": "Manage PowerShell profiles.",
+ "tags": [
+ "Linux",
+ "Windows",
+ "macOS",
+ "PowerShell"
+ ],
+ "type": "Microsoft.PowerShell/Profile",
+ "version": "0.1.0",
+ "get": {
+ "executable": "pwsh",
+ "args": [
+ "-NoLogo",
+ "-NonInteractive",
+ "-NoProfile",
+ "-ExecutionPolicy",
+ "Bypass",
+ "-File",
+ "./pwsh.profile.resource.ps1",
+ "-operation",
+ "get"
+ ],
+ "input": "stdin"
+ },
+ "set": {
+ "executable": "pwsh",
+ "args": [
+ "-NoLogo",
+ "-NonInteractive",
+ "-NoProfile",
+ "-ExecutionPolicy",
+ "Bypass",
+ "-File",
+ "./pwsh.profile.resource.ps1",
+ "-operation",
+ "set"
+ ],
+ "input": "stdin"
+ },
+ "export": {
+ "executable": "pwsh",
+ "args": [
+ "-NoLogo",
+ "-NonInteractive",
+ "-NoProfile",
+ "-ExecutionPolicy",
+ "Bypass",
+ "-File",
+ "./pwsh.profile.resource.ps1",
+ "-operation",
+ "export"
+ ],
+ "input": "stdin"
+ },
+ "exitCodes": {
+ "0": "Success",
+ "1": "Error",
+ "2": "Input not supported for export operation"
+ },
+ "schema": {
+ "embedded": {
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "title": "Profile",
+ "description": "Manage PowerShell profiles.",
+ "type": "object",
+ "unevaluatedProperties": false,
+ "required": [
+ "profileType"
+ ],
+ "properties": {
+ "profileType": {
+ "type": "string",
+ "title": "Profile Type",
+ "description": "Defines which profile to manage. Valid values are: 'AllUsersCurrentHost', 'AllUsersAllHosts', 'CurrentUserAllHosts', and 'CurrentUserCurrentHost'.",
+ "enum": [
+ "AllUsersCurrentHost",
+ "AllUsersAllHosts",
+ "CurrentUserAllHosts",
+ "CurrentUserCurrentHost"
+ ]
+ },
+ "profilePath": {
+ "title": "Profile Path",
+ "description": "The full path to the profile file.",
+ "type": "string",
+ "readOnly": true
+ },
+ "content": {
+ "title": "Content",
+ "description": "Defines the content of the profile. If you don't specify this property, the resource doesn't manage the file contents. If you specify this property as an empty string, the resource removes all content from the file. If you specify this property as a non-empty string, the resource sets the file contents to the specified string. The resources retains newlines from this property without any modification.",
+ "type": "string"
+ },
+ "_exist": {
+ "$ref": "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/v3/resource/properties/exist.json"
+ },
+ "_name": {
+ "$ref": "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/v3/resource/properties/name.json"
+ }
+ },
+ "$defs": {
+ "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/v3/resource/properties/exist.json": {
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/v3/resource/properties/exist.json",
+ "title": "Instance should exist",
+ "description": "Indicates whether the DSC resource instance should exist.",
+ "type": "boolean",
+ "default": true,
+ "enum": [
+ false,
+ true
+ ]
+ },
+ "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/v3/resource/properties/name.json": {
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/v3/resource/properties/name.json",
+ "title": "Exported instance name",
+ "description": "Returns a generated name for the resource instance from an export operation.",
+ "readOnly": true,
+ "type": "string"
+ }
+ }
+ }
+ }
+}
diff --git a/dsc/pwsh.profile.resource.ps1 b/dsc/pwsh.profile.resource.ps1
new file mode 100644
index 00000000000..ad9cfa4a63a
--- /dev/null
+++ b/dsc/pwsh.profile.resource.ps1
@@ -0,0 +1,179 @@
+## Copyright (c) Microsoft Corporation. All rights reserved.
+## Licensed under the MIT License.
+
+[CmdletBinding()]
+param(
+ [Parameter(Mandatory = $true)]
+ [ValidateSet('get', 'set', 'export')]
+ [string]$Operation,
+ [Parameter(ValueFromPipeline)]
+ [string[]]$UserInput
+)
+
+Begin {
+ enum ProfileType {
+ AllUsersCurrentHost
+ AllUsersAllHosts
+ CurrentUserAllHosts
+ CurrentUserCurrentHost
+ }
+
+ function New-PwshResource {
+ param(
+ [Parameter(Mandatory = $true)]
+ [ProfileType] $ProfileType,
+
+ [Parameter(ParameterSetName = 'WithContent')]
+ [string] $Content,
+
+ [Parameter(ParameterSetName = 'WithContent')]
+ [bool] $Exist
+ )
+
+ # Create the PSCustomObject with properties
+ $resource = [PSCustomObject]@{
+ profileType = $ProfileType
+ content = $null
+ profilePath = GetProfilePath -profileType $ProfileType
+ _exist = $false
+ }
+
+ # Add ToJson method
+ $resource | Add-Member -MemberType ScriptMethod -Name 'ToJson' -Value {
+ return ([ordered] @{
+ profileType = $this.profileType
+ content = $this.content
+ profilePath = $this.profilePath
+ _exist = $this._exist
+ }) | ConvertTo-Json -Compress -EnumsAsStrings
+ }
+
+ # Constructor logic - if Content and Exist parameters are provided (WithContent parameter set)
+ if ($PSCmdlet.ParameterSetName -eq 'WithContent') {
+ $resource.content = $Content
+ $resource._exist = $Exist
+ } else {
+ # Default constructor logic - read from file system
+ $fileExists = Test-Path $resource.profilePath
+ if ($fileExists) {
+ $resource.content = Get-Content -Path $resource.profilePath
+ } else {
+ $resource.content = $null
+ }
+ $resource._exist = $fileExists
+ }
+
+ return $resource
+ }
+
+ function GetProfilePath {
+ param (
+ [ProfileType] $profileType
+ )
+
+ $path = switch ($profileType) {
+ 'AllUsersCurrentHost' { $PROFILE.AllUsersCurrentHost }
+ 'AllUsersAllHosts' { $PROFILE.AllUsersAllHosts }
+ 'CurrentUserAllHosts' { $PROFILE.CurrentUserAllHosts }
+ 'CurrentUserCurrentHost' { $PROFILE.CurrentUserCurrentHost }
+ }
+
+ return $path
+ }
+
+ function ExportOperation {
+ $allUserCurrentHost = New-PwshResource -ProfileType 'AllUsersCurrentHost'
+ $allUsersAllHost = New-PwshResource -ProfileType 'AllUsersAllHosts'
+ $currentUserAllHost = New-PwshResource -ProfileType 'CurrentUserAllHosts'
+ $currentUserCurrentHost = New-PwshResource -ProfileType 'CurrentUserCurrentHost'
+
+ # Cannot use the ToJson() method here as we are adding a note property
+ $allUserCurrentHost | Add-Member -NotePropertyName '_name' -NotePropertyValue 'AllUsersCurrentHost' -PassThru | ConvertTo-Json -Compress -EnumsAsStrings
+ $allUsersAllHost | Add-Member -NotePropertyName '_name' -NotePropertyValue 'AllUsersAllHosts' -PassThru | ConvertTo-Json -Compress -EnumsAsStrings
+ $currentUserAllHost | Add-Member -NotePropertyName '_name' -NotePropertyValue 'CurrentUserAllHosts' -PassThru | ConvertTo-Json -Compress -EnumsAsStrings
+ $currentUserCurrentHost | Add-Member -NotePropertyName '_name' -NotePropertyValue 'CurrentUserCurrentHost' -PassThru | ConvertTo-Json -Compress -EnumsAsStrings
+ }
+
+ function GetOperation {
+ param (
+ [Parameter(Mandatory = $true)]
+ $InputResource,
+ [Parameter()]
+ [switch] $AsJson
+ )
+
+ $profilePath = GetProfilePath -profileType $InputResource.profileType.ToString()
+
+ $actualState = New-PwshResource -ProfileType $InputResource.profileType
+
+ $actualState.profilePath = $profilePath
+
+ $exists = Test-Path $profilePath
+
+ if ($InputResource._exist -and $exists) {
+ $content = Get-Content -Path $profilePath
+ $actualState.Content = $content
+ } elseif ($InputResource._exist -and -not $exists) {
+ $actualState.Content = $null
+ $actualState._exist = $false
+ } elseif (-not $InputResource._exist -and $exists) {
+ $actualState.Content = Get-Content -Path $profilePath
+ $actualState._exist = $true
+ } else {
+ $actualState.Content = $null
+ $actualState._exist = $false
+ }
+
+ if ($AsJson) {
+ return $actualState.ToJson()
+ } else {
+ return $actualState
+ }
+ }
+
+ function SetOperation {
+ param (
+ $InputResource
+ )
+
+ $actualState = GetOperation -InputResource $InputResource
+
+ if ($InputResource._exist) {
+ if (-not $actualState._exist) {
+ $null = New-Item -Path $actualState.profilePath -ItemType File -Force
+ }
+
+ if ($null -ne $InputResource.content) {
+ Set-Content -Path $actualState.profilePath -Value $InputResource.content
+ }
+ } elseif ($actualState._exist) {
+ Remove-Item -Path $actualState.profilePath -Force
+ }
+ }
+}
+End {
+ $inputJson = $input | ConvertFrom-Json
+
+ if ($inputJson) {
+ $InputResource = New-PwshResource -ProfileType $inputJson.profileType -Content $inputJson.content -Exist $inputJson._exist
+ }
+
+ switch ($Operation) {
+ 'get' {
+ GetOperation -InputResource $InputResource -AsJson
+ }
+ 'set' {
+ SetOperation -InputResource $InputResource
+ }
+ 'export' {
+ if ($inputJson) {
+ Write-Error "Input not supported for export operation"
+ exit 2
+ }
+
+ ExportOperation
+ }
+ }
+
+ exit 0
+}
diff --git a/experimental-feature-linux.json b/experimental-feature-linux.json
index ca5b49878a4..31f7b965a5b 100644
--- a/experimental-feature-linux.json
+++ b/experimental-feature-linux.json
@@ -2,6 +2,7 @@
"PSFeedbackProvider",
"PSLoadAssemblyFromNativeCode",
"PSNativeWindowsTildeExpansion",
+ "PSProfileDSCResource",
"PSSerializeJSONLongEnumAsNumber",
"PSRedirectToVariable",
"PSSubsystemPluginModel"
diff --git a/experimental-feature-windows.json b/experimental-feature-windows.json
index ca5b49878a4..31f7b965a5b 100644
--- a/experimental-feature-windows.json
+++ b/experimental-feature-windows.json
@@ -2,6 +2,7 @@
"PSFeedbackProvider",
"PSLoadAssemblyFromNativeCode",
"PSNativeWindowsTildeExpansion",
+ "PSProfileDSCResource",
"PSSerializeJSONLongEnumAsNumber",
"PSRedirectToVariable",
"PSSubsystemPluginModel"
diff --git a/global.json b/global.json
index e7cce33e5d9..376af49c07f 100644
--- a/global.json
+++ b/global.json
@@ -1,5 +1,5 @@
{
"sdk": {
- "version": "10.0.100-rc.1.25451.107"
+ "version": "10.0.100"
}
}
diff --git a/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj b/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj
index 547911668e9..a338c175f14 100644
--- a/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj
+++ b/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj
@@ -8,7 +8,7 @@
-
+
diff --git a/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj b/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj
index 029571c4145..ef949508346 100644
--- a/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj
+++ b/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj
@@ -47,7 +47,7 @@
-
+
diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/GetClipboardCommand.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/GetClipboardCommand.cs
index dd878bd72ce..a2b7f03ce70 100644
--- a/src/Microsoft.PowerShell.Commands.Management/commands/management/GetClipboardCommand.cs
+++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/GetClipboardCommand.cs
@@ -2,8 +2,10 @@
// Licensed under the MIT License.
using System;
+using System.Collections;
using System.Collections.Generic;
using System.Management.Automation;
+using System.Management.Automation.Language;
using Microsoft.PowerShell.Commands.Internal;
namespace Microsoft.PowerShell.Commands
@@ -34,6 +36,13 @@ public SwitchParameter Raw
}
}
+ ///
+ /// Gets or sets the delimiters to use when splitting the clipboard content.
+ ///
+ [Parameter]
+ [ArgumentCompleter(typeof(DelimiterCompleter))]
+ public string[] Delimiter { get; set; } = [Environment.NewLine];
+
private bool _raw;
///
@@ -68,11 +77,40 @@ private List GetClipboardContentAsText()
}
else
{
- string[] splitSymbol = { Environment.NewLine };
- result.AddRange(textContent.Split(splitSymbol, StringSplitOptions.None));
+ result.AddRange(textContent.Split(Delimiter, StringSplitOptions.None));
}
return result;
}
}
+
+ ///
+ /// Provides argument completion for the Delimiter parameter.
+ ///
+ public sealed class DelimiterCompleter : IArgumentCompleter
+ {
+ ///
+ /// Provides argument completion for the Delimiter parameter.
+ ///
+ /// The name of the command that is being completed.
+ /// The name of the parameter that is being completed.
+ /// The input text to filter the results by.
+ /// The ast of the command that triggered the completion.
+ /// The parameters bound to the command.
+ /// Completion results.
+ public IEnumerable CompleteArgument(string commandName, string parameterName, string wordToComplete, CommandAst commandAst, IDictionary fakeBoundParameters)
+ {
+ wordToComplete ??= string.Empty;
+ var pattern = new WildcardPattern(wordToComplete + '*', WildcardOptions.IgnoreCase);
+ if (pattern.IsMatch("CRLF") || pattern.IsMatch("Windows"))
+ {
+ yield return new CompletionResult("\"`r`n\"", "CRLF", CompletionResultType.ParameterValue, "Windows (CRLF)");
+ }
+
+ if (pattern.IsMatch("LF") || pattern.IsMatch("Unix") || pattern.IsMatch("Linux"))
+ {
+ yield return new CompletionResult("\"`n\"", "LF", CompletionResultType.ParameterValue, "UNIX (LF)");
+ }
+ }
+ }
}
diff --git a/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj b/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj
index a35f4258e56..1f9f342b259 100644
--- a/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj
+++ b/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj
@@ -8,7 +8,7 @@
-
+
@@ -33,8 +33,7 @@
-
-
+
diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Var.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Var.cs
index 12cfb784c72..a41b284f568 100644
--- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Var.cs
+++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Var.cs
@@ -697,7 +697,6 @@ public SwitchParameter PassThru
/// Gets whether we will append to the variable if it exists.
///
[Parameter]
- [Experimental(ExperimentalFeature.PSRedirectToVariable, ExperimentAction.Show)]
public SwitchParameter Append { get; set; }
private bool _nameIsFormalParameter;
diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHost.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHost.cs
index b866815a25c..bcc1d45da49 100644
--- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHost.cs
+++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHost.cs
@@ -2565,14 +2565,7 @@ internal void Run(bool inputLoopIsNested)
// Evaluate any suggestions
if (previousResponseWasEmpty == false)
{
- if (ExperimentalFeature.IsEnabled(ExperimentalFeature.PSFeedbackProvider))
- {
- EvaluateFeedbacks(ui);
- }
- else
- {
- EvaluateSuggestions(ui);
- }
+ EvaluateFeedbacks(ui);
}
// Then output the prompt
@@ -2896,44 +2889,6 @@ private void EvaluateFeedbacks(ConsoleHostUserInterface ui)
}
}
- private void EvaluateSuggestions(ConsoleHostUserInterface ui)
- {
- // Output any training suggestions
- try
- {
- List suggestions = HostUtilities.GetSuggestion(_parent.Runspace);
-
- if (suggestions.Count > 0)
- {
- ui.WriteLine();
- }
-
- bool first = true;
- foreach (string suggestion in suggestions)
- {
- if (!first)
- ui.WriteLine();
-
- ui.WriteLine(suggestion);
-
- first = false;
- }
- }
- catch (TerminateException)
- {
- // A variable breakpoint may be hit by HostUtilities.GetSuggestion. The debugger throws TerminateExceptions to stop the execution
- // of the current statement; we do not want to treat these exceptions as errors.
- }
- catch (Exception e)
- {
- // Catch-all OK. This is a third-party call-out.
- ui.WriteErrorLine(e.Message);
-
- LocalRunspace localRunspace = (LocalRunspace)_parent.Runspace;
- localRunspace.GetExecutionContext.AppendDollarError(e);
- }
- }
-
private string EvaluatePrompt()
{
string promptString = _promptExec.ExecuteCommandAndGetResultAsString("prompt", out _);
diff --git a/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj b/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj
index d60337d5d90..45b4d8c0a0a 100644
--- a/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj
+++ b/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj
@@ -8,7 +8,7 @@
-
+
diff --git a/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj b/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj
index 2c796312a1a..87f71daada9 100644
--- a/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj
+++ b/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj
@@ -16,28 +16,19 @@
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
-
+
diff --git a/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj b/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj
index 710102ca2fa..48b4d8ff29c 100644
--- a/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj
+++ b/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj
@@ -10,7 +10,7 @@
-
+
diff --git a/src/Modules/PSGalleryModules.csproj b/src/Modules/PSGalleryModules.csproj
index 327c293e72c..b6e5506e0b0 100644
--- a/src/Modules/PSGalleryModules.csproj
+++ b/src/Modules/PSGalleryModules.csproj
@@ -13,9 +13,9 @@
-
+
-
+
diff --git a/src/System.Management.Automation/System.Management.Automation.csproj b/src/System.Management.Automation/System.Management.Automation.csproj
index 033c39034ac..e929166b20d 100644
--- a/src/System.Management.Automation/System.Management.Automation.csproj
+++ b/src/System.Management.Automation/System.Management.Automation.csproj
@@ -32,22 +32,15 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
-
+
diff --git a/src/System.Management.Automation/engine/CommandCompletion/CompletionCompleters.cs b/src/System.Management.Automation/engine/CommandCompletion/CompletionCompleters.cs
index 8ca133cf1c2..e0104805d0c 100644
--- a/src/System.Management.Automation/engine/CommandCompletion/CompletionCompleters.cs
+++ b/src/System.Management.Automation/engine/CommandCompletion/CompletionCompleters.cs
@@ -4580,8 +4580,8 @@ internal static IEnumerable CompleteFilename(CompletionContext
return CommandCompletion.EmptyCompletionResult;
}
- var lastAst = context.RelatedAsts[^1];
- if (lastAst.Parent is UsingStatementAst usingStatement
+ var lastAst = context.RelatedAsts?[^1];
+ if (lastAst?.Parent is UsingStatementAst usingStatement
&& usingStatement.UsingStatementKind is UsingStatementKind.Module or UsingStatementKind.Assembly
&& lastAst.Extent.File is not null)
{
diff --git a/src/System.Management.Automation/engine/ExperimentalFeature/ExperimentalFeature.cs b/src/System.Management.Automation/engine/ExperimentalFeature/ExperimentalFeature.cs
index dd26e609641..7e17ec43137 100644
--- a/src/System.Management.Automation/engine/ExperimentalFeature/ExperimentalFeature.cs
+++ b/src/System.Management.Automation/engine/ExperimentalFeature/ExperimentalFeature.cs
@@ -1,7 +1,6 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
@@ -21,10 +20,8 @@ public class ExperimentalFeature
#region Const Members
internal const string EngineSource = "PSEngine";
- internal const string PSFeedbackProvider = "PSFeedbackProvider";
- internal const string PSNativeWindowsTildeExpansion = nameof(PSNativeWindowsTildeExpansion);
- internal const string PSRedirectToVariable = "PSRedirectToVariable";
internal const string PSSerializeJSONLongEnumAsNumber = nameof(PSSerializeJSONLongEnumAsNumber);
+ internal const string PSProfileDSCResource = "PSProfileDSCResource";
#endregion
@@ -107,24 +104,16 @@ static ExperimentalFeature()
name: "PSFileSystemProviderV2",
description: "Replace the old FileSystemProvider with cleaner design and faster code"),
*/
- new ExperimentalFeature(
- name: "PSSubsystemPluginModel",
- description: "A plugin model for registering and un-registering PowerShell subsystems"),
new ExperimentalFeature(
name: "PSLoadAssemblyFromNativeCode",
description: "Expose an API to allow assembly loading from native code"),
- new ExperimentalFeature(
- name: PSFeedbackProvider,
- description: "Replace the hard-coded suggestion framework with the extensible feedback provider"),
- new ExperimentalFeature(
- name: PSNativeWindowsTildeExpansion,
- description: "On windows, expand unquoted tilde (`~`) with the user's current home folder."),
- new ExperimentalFeature(
- name: PSRedirectToVariable,
- description: "Add support for redirecting to the variable drive"),
new ExperimentalFeature(
name: PSSerializeJSONLongEnumAsNumber,
description: "Serialize enums based on long or ulong as an numeric value rather than the string representation when using ConvertTo-Json."
+ ),
+ new ExperimentalFeature(
+ name: PSProfileDSCResource,
+ description: "DSC v3 resources for managing PowerShell profile."
)
};
diff --git a/src/System.Management.Automation/engine/InitialSessionState.cs b/src/System.Management.Automation/engine/InitialSessionState.cs
index 84f513d8450..86e6240fdad 100644
--- a/src/System.Management.Automation/engine/InitialSessionState.cs
+++ b/src/System.Management.Automation/engine/InitialSessionState.cs
@@ -5470,6 +5470,7 @@ private static void InitializeCoreCmdletsAndProviders(
{ "Get-Module", new SessionStateCmdletEntry("Get-Module", typeof(GetModuleCommand), helpFile) },
{ "Get-PSHostProcessInfo", new SessionStateCmdletEntry("Get-PSHostProcessInfo", typeof(GetPSHostProcessInfoCommand), helpFile) },
{ "Get-PSSession", new SessionStateCmdletEntry("Get-PSSession", typeof(GetPSSessionCommand), helpFile) },
+ { "Get-PSSubsystem", new SessionStateCmdletEntry("Get-PSSubsystem", typeof(Subsystem.GetPSSubsystemCommand), helpFile) },
{ "Import-Module", new SessionStateCmdletEntry("Import-Module", typeof(ImportModuleCommand), helpFile) },
{ "Invoke-Command", new SessionStateCmdletEntry("Invoke-Command", typeof(InvokeCommandCommand), helpFile) },
{ "Invoke-History", new SessionStateCmdletEntry("Invoke-History", typeof(InvokeHistoryCommand), helpFile) },
@@ -5510,11 +5511,6 @@ private static void InitializeCoreCmdletsAndProviders(
{ "Format-Default", new SessionStateCmdletEntry("Format-Default", typeof(FormatDefaultCommand), helpFile) },
};
- if (ExperimentalFeature.IsEnabled("PSSubsystemPluginModel"))
- {
- cmdlets.Add("Get-PSSubsystem", new SessionStateCmdletEntry("Get-PSSubsystem", typeof(Subsystem.GetPSSubsystemCommand), helpFile));
- }
-
#if UNIX
cmdlets.Add("Switch-Process", new SessionStateCmdletEntry("Switch-Process", typeof(SwitchProcessCommand), helpFile));
#endif
diff --git a/src/System.Management.Automation/engine/NativeCommandParameterBinder.cs b/src/System.Management.Automation/engine/NativeCommandParameterBinder.cs
index 0124b01332c..19e17b71cca 100644
--- a/src/System.Management.Automation/engine/NativeCommandParameterBinder.cs
+++ b/src/System.Management.Automation/engine/NativeCommandParameterBinder.cs
@@ -406,12 +406,9 @@ private void PossiblyGlobArg(string arg, CommandParameterInternal parameter, boo
}
}
#else
- if (!usedQuotes && ExperimentalFeature.IsEnabled(ExperimentalFeature.PSNativeWindowsTildeExpansion))
+ if (!usedQuotes && ExpandTilde(arg, parameter))
{
- if (ExpandTilde(arg, parameter))
- {
- argExpanded = true;
- }
+ argExpanded = true;
}
#endif
diff --git a/src/System.Management.Automation/engine/Subsystem/Commands/GetPSSubsystemCommand.cs b/src/System.Management.Automation/engine/Subsystem/Commands/GetPSSubsystemCommand.cs
index 1ad79404f51..df828c724a2 100644
--- a/src/System.Management.Automation/engine/Subsystem/Commands/GetPSSubsystemCommand.cs
+++ b/src/System.Management.Automation/engine/Subsystem/Commands/GetPSSubsystemCommand.cs
@@ -8,7 +8,6 @@ namespace System.Management.Automation.Subsystem
///
/// Implementation of 'Get-PSSubsystem' cmdlet.
///
- [Experimental("PSSubsystemPluginModel", ExperimentAction.Show)]
[Cmdlet(VerbsCommon.Get, "PSSubsystem", DefaultParameterSetName = AllSet)]
[OutputType(typeof(SubsystemInfo))]
public sealed class GetPSSubsystemCommand : PSCmdlet
diff --git a/src/System.Management.Automation/engine/TypeTable_Types_Ps1Xml.cs b/src/System.Management.Automation/engine/TypeTable_Types_Ps1Xml.cs
index c1a134cdfbf..26e3621c240 100644
--- a/src/System.Management.Automation/engine/TypeTable_Types_Ps1Xml.cs
+++ b/src/System.Management.Automation/engine/TypeTable_Types_Ps1Xml.cs
@@ -565,9 +565,7 @@ private void Process_Types_Ps1Xml(string filePath, ConcurrentBag errors)
typeName,
new PSScriptProperty(
@"DisplayName",
- GetScriptBlock(@"if ($this.Name.IndexOf('-') -lt 0)
- {
- if ($null -ne $this.ResolvedCommand)
+ GetScriptBlock(@"if ($null -ne $this.ResolvedCommand)
{
$this.Name + "" -> "" + $this.ResolvedCommand.Name
}
@@ -575,11 +573,7 @@ private void Process_Types_Ps1Xml(string filePath, ConcurrentBag errors)
{
$this.Name + "" -> "" + $this.Definition
}
- }
- else
- {
- $this.Name
- }"),
+ "),
setterScript: null,
shouldCloneOnAccess: true),
typeMembers,
diff --git a/src/System.Management.Automation/engine/hostifaces/HostUtilities.cs b/src/System.Management.Automation/engine/hostifaces/HostUtilities.cs
index 003625791b1..f06399e09d2 100644
--- a/src/System.Management.Automation/engine/hostifaces/HostUtilities.cs
+++ b/src/System.Management.Automation/engine/hostifaces/HostUtilities.cs
@@ -1,10 +1,8 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
-using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Management.Automation.Host;
using System.Management.Automation.Internal;
@@ -12,26 +10,10 @@
using System.Management.Automation.Subsystem.Feedback;
using System.Runtime.InteropServices;
using System.Text;
-using System.Text.RegularExpressions;
-
-using Microsoft.PowerShell.Commands;
using Microsoft.PowerShell.Commands.Internal.Format;
namespace System.Management.Automation
{
- internal enum SuggestionMatchType
- {
- /// Match on a command.
- Command = 0,
- /// Match based on exception message.
- Error = 1,
- /// Match by running a script block.
- Dynamic = 2,
-
- /// Match by fully qualified ErrorId.
- ErrorId = 3
- }
-
#region Public HostUtilities Class
///
@@ -43,31 +25,6 @@ public static class HostUtilities
private static readonly char s_actionIndicator = HostSupportUnicode() ? '\u27a4' : '>';
- private static readonly string s_checkForCommandInCurrentDirectoryScript = @"
- [System.Diagnostics.DebuggerHidden()]
- param()
-
- $foundSuggestion = $false
-
- if($lastError -and
- ($lastError.Exception -is ""System.Management.Automation.CommandNotFoundException""))
- {
- $escapedCommand = [System.Management.Automation.WildcardPattern]::Escape($lastError.TargetObject)
- $foundSuggestion = @(Get-Command ($ExecutionContext.SessionState.Path.Combine(""."", $escapedCommand)) -ErrorAction Ignore).Count -gt 0
- }
-
- $foundSuggestion
- ";
-
- private static readonly string s_createCommandExistsInCurrentDirectoryScript = @"
- [System.Diagnostics.DebuggerHidden()]
- param([string] $formatString)
-
- $formatString -f $lastError.TargetObject,"".\$($lastError.TargetObject)""
- ";
-
- private static readonly List s_suggestions = InitializeSuggestions();
-
private static bool HostSupportUnicode()
{
// Reference: https://github.com/zkat/supports-unicode/blob/main/src/lib.rs
@@ -87,23 +44,6 @@ private static bool HostSupportUnicode()
return ctype.EndsWith("UTF8") || ctype.EndsWith("UTF-8");
}
- private static List InitializeSuggestions()
- {
- var suggestions = new List()
- {
- NewSuggestion(
- id: 3,
- category: "General",
- matchType: SuggestionMatchType.Dynamic,
- rule: ScriptBlock.CreateDelayParsedScriptBlock(s_checkForCommandInCurrentDirectoryScript, isProductCode: true),
- suggestion: ScriptBlock.CreateDelayParsedScriptBlock(s_createCommandExistsInCurrentDirectoryScript, isProductCode: true),
- suggestionArgs: new object[] { SuggestionStrings.Suggestion_CommandExistsInCurrentDirectory_Legacy },
- enabled: true)
- };
-
- return suggestions;
- }
-
#region GetProfileCommands
///
/// Gets a PSObject whose base object is currentUserCurrentHost and with notes for the other 4 parameters.
@@ -282,303 +222,6 @@ internal static string GetMaxLines(string source, int maxLines)
return returnValue.ToString();
}
- internal static List GetSuggestion(Runspace runspace)
- {
- if (!(runspace is LocalRunspace localRunspace))
- {
- return new List();
- }
-
- // Get the last value of $?
- bool questionMarkVariableValue = localRunspace.ExecutionContext.QuestionMarkVariableValue;
-
- // Get the last history item
- History history = localRunspace.History;
- HistoryInfo[] entries = history.GetEntries(-1, 1, true);
-
- if (entries.Length == 0)
- return new List();
-
- HistoryInfo lastHistory = entries[0];
-
- // Get the last error
- ArrayList errorList = (ArrayList)localRunspace.GetExecutionContext.DollarErrorVariable;
- object lastError = null;
-
- if (errorList.Count > 0)
- {
- lastError = errorList[0] as Exception;
- ErrorRecord lastErrorRecord = null;
-
- // The error was an actual ErrorRecord
- if (lastError == null)
- {
- lastErrorRecord = errorList[0] as ErrorRecord;
- }
- else if (lastError is RuntimeException)
- {
- lastErrorRecord = ((RuntimeException)lastError).ErrorRecord;
- }
-
- // If we got information about the error invocation,
- // we can be more careful with the errors we pass along
- if ((lastErrorRecord != null) && (lastErrorRecord.InvocationInfo != null))
- {
- if (lastErrorRecord.InvocationInfo.HistoryId == lastHistory.Id)
- lastError = lastErrorRecord;
- else
- lastError = null;
- }
- }
-
- Runspace oldDefault = null;
- bool changedDefault = false;
- if (Runspace.DefaultRunspace != runspace)
- {
- oldDefault = Runspace.DefaultRunspace;
- changedDefault = true;
- Runspace.DefaultRunspace = runspace;
- }
-
- List suggestions = null;
-
- try
- {
- suggestions = GetSuggestion(lastHistory, lastError, errorList);
- }
- finally
- {
- if (changedDefault)
- {
- Runspace.DefaultRunspace = oldDefault;
- }
- }
-
- // Restore $?
- localRunspace.ExecutionContext.QuestionMarkVariableValue = questionMarkVariableValue;
- return suggestions;
- }
-
- [SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly")]
- internal static List GetSuggestion(HistoryInfo lastHistory, object lastError, ArrayList errorList)
- {
- var returnSuggestions = new List();
-
- PSModuleInfo invocationModule = new PSModuleInfo(true);
- invocationModule.SessionState.PSVariable.Set("lastHistory", lastHistory);
- invocationModule.SessionState.PSVariable.Set("lastError", lastError);
-
- int initialErrorCount = 0;
-
- // Go through all of the suggestions
- foreach (Hashtable suggestion in s_suggestions)
- {
- initialErrorCount = errorList.Count;
-
- // Make sure the rule is enabled
- if (!LanguagePrimitives.IsTrue(suggestion["Enabled"]))
- continue;
-
- SuggestionMatchType matchType = (SuggestionMatchType)LanguagePrimitives.ConvertTo(
- suggestion["MatchType"],
- typeof(SuggestionMatchType),
- CultureInfo.InvariantCulture);
-
- // If this is a dynamic match, evaluate the ScriptBlock
- if (matchType == SuggestionMatchType.Dynamic)
- {
- object result = null;
-
- ScriptBlock evaluator = suggestion["Rule"] as ScriptBlock;
- if (evaluator == null)
- {
- suggestion["Enabled"] = false;
-
- throw new ArgumentException(
- SuggestionStrings.RuleMustBeScriptBlock, "Rule");
- }
-
- try
- {
- result = invocationModule.Invoke(evaluator, null);
- }
- catch (Exception)
- {
- // Catch-all OK. This is a third-party call-out.
- suggestion["Enabled"] = false;
- continue;
- }
-
- // If it returned results, evaluate its suggestion
- if (LanguagePrimitives.IsTrue(result))
- {
- string suggestionText = GetSuggestionText(suggestion["Suggestion"], (object[])suggestion["SuggestionArgs"], invocationModule);
-
- if (!string.IsNullOrEmpty(suggestionText))
- {
- string returnString = string.Format(
- CultureInfo.CurrentCulture,
- "Suggestion [{0},{1}]: {2}",
- (int)suggestion["Id"],
- (string)suggestion["Category"],
- suggestionText);
-
- returnSuggestions.Add(returnString);
- }
- }
- }
- else
- {
- string matchText = string.Empty;
-
- // Otherwise, this is a Regex match against the
- // command or error
- if (matchType == SuggestionMatchType.Command)
- {
- matchText = lastHistory.CommandLine;
- }
- else if (matchType == SuggestionMatchType.Error)
- {
- if (lastError != null)
- {
- Exception lastException = lastError as Exception;
- if (lastException != null)
- {
- matchText = lastException.Message;
- }
- else
- {
- matchText = lastError.ToString();
- }
- }
- }
- else if (matchType == SuggestionMatchType.ErrorId)
- {
- if (lastError != null && lastError is ErrorRecord errorRecord)
- {
- matchText = errorRecord.FullyQualifiedErrorId;
- }
- }
- else
- {
- suggestion["Enabled"] = false;
-
- throw new ArgumentException(
- SuggestionStrings.InvalidMatchType,
- "MatchType");
- }
-
- // If the text matches, evaluate the suggestion
- if (Regex.IsMatch(matchText, (string)suggestion["Rule"], RegexOptions.IgnoreCase))
- {
- string suggestionText = GetSuggestionText(suggestion["Suggestion"], (object[])suggestion["SuggestionArgs"], invocationModule);
-
- if (!string.IsNullOrEmpty(suggestionText))
- {
- string returnString = string.Format(
- CultureInfo.CurrentCulture,
- "Suggestion [{0},{1}]: {2}",
- (int)suggestion["Id"],
- (string)suggestion["Category"],
- suggestionText);
-
- returnSuggestions.Add(returnString);
- }
- }
- }
-
- // If the rule generated an error, disable it
- if (errorList.Count != initialErrorCount)
- {
- suggestion["Enabled"] = false;
- }
- }
-
- return returnSuggestions;
- }
-
- ///
- /// Create suggestion with string rule and scriptblock suggestion.
- ///
- /// Identifier for the suggestion.
- /// Category for the suggestion.
- /// Suggestion match type.
- /// Rule to match.
- /// Scriptblock to run that returns the suggestion.
- /// Arguments to pass to suggestion scriptblock.
- /// True if the suggestion is enabled.
- /// Hashtable representing the suggestion.
- private static Hashtable NewSuggestion(int id, string category, SuggestionMatchType matchType, string rule, ScriptBlock suggestion, object[] suggestionArgs, bool enabled)
- {
- Hashtable result = new Hashtable(StringComparer.CurrentCultureIgnoreCase);
-
- result["Id"] = id;
- result["Category"] = category;
- result["MatchType"] = matchType;
- result["Rule"] = rule;
- result["Suggestion"] = suggestion;
- result["SuggestionArgs"] = suggestionArgs;
- result["Enabled"] = enabled;
-
- return result;
- }
-
- ///
- /// Create suggestion with scriptblock rule and suggestion.
- ///
- private static Hashtable NewSuggestion(int id, string category, SuggestionMatchType matchType, ScriptBlock rule, ScriptBlock suggestion, bool enabled)
- {
- Hashtable result = new Hashtable(StringComparer.CurrentCultureIgnoreCase);
-
- result["Id"] = id;
- result["Category"] = category;
- result["MatchType"] = matchType;
- result["Rule"] = rule;
- result["Suggestion"] = suggestion;
- result["Enabled"] = enabled;
-
- return result;
- }
-
- ///
- /// Create suggestion with scriptblock rule and scriptblock suggestion with arguments.
- ///
- private static Hashtable NewSuggestion(int id, string category, SuggestionMatchType matchType, ScriptBlock rule, ScriptBlock suggestion, object[] suggestionArgs, bool enabled)
- {
- Hashtable result = NewSuggestion(id, category, matchType, rule, suggestion, enabled);
- result.Add("SuggestionArgs", suggestionArgs);
-
- return result;
- }
-
- ///
- /// Get suggestion text from suggestion scriptblock with arguments.
- ///
- private static string GetSuggestionText(object suggestion, object[] suggestionArgs, PSModuleInfo invocationModule)
- {
- if (suggestion is ScriptBlock)
- {
- ScriptBlock suggestionScript = (ScriptBlock)suggestion;
-
- object result = null;
- try
- {
- result = invocationModule.Invoke(suggestionScript, suggestionArgs);
- }
- catch (Exception)
- {
- // Catch-all OK. This is a third-party call-out.
- return string.Empty;
- }
-
- return (string)LanguagePrimitives.ConvertTo(result, typeof(string), CultureInfo.CurrentCulture);
- }
- else
- {
- return (string)LanguagePrimitives.ConvertTo(suggestion, typeof(string), CultureInfo.CurrentCulture);
- }
- }
-
///
/// Returns the prompt used in remote sessions: "[machine]: basePrompt"
///
diff --git a/src/System.Management.Automation/engine/remoting/common/RunspaceConnectionInfo.cs b/src/System.Management.Automation/engine/remoting/common/RunspaceConnectionInfo.cs
index d9a6d0b317b..0c99f90fa7e 100644
--- a/src/System.Management.Automation/engine/remoting/common/RunspaceConnectionInfo.cs
+++ b/src/System.Management.Automation/engine/remoting/common/RunspaceConnectionInfo.cs
@@ -2211,11 +2211,11 @@ internal int StartSSHProcess(
CommandTypes.Application,
SearchResolutionOptions.None,
CommandOrigin.Internal,
- context) as ApplicationInfo;
+ context);
- if (cmdInfo != null)
+ if (cmdInfo is ApplicationInfo appInfo)
{
- filePath = cmdInfo.Path;
+ filePath = appInfo.Path;
}
}
else
@@ -2273,13 +2273,13 @@ internal int StartSSHProcess(
// Subsystem powershell /usr/local/bin/pwsh -SSHServerMode -NoLogo -NoProfile
// codeql[cs/microsoft/command-line-injection-shell-execution] - This is expected Poweshell behavior where user inputted paths are supported for the context of this method. The user assumes trust for the file path specified, so any file executed in the runspace would be in the user's local system/process or a system they have access to in which case restricted remoting security guidelines should be used.
- System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo(filePath);
+ ProcessStartInfo startInfo = new(filePath);
// pass "-i identity_file" command line argument to ssh if KeyFilePath is set
// if KeyFilePath is not set, then ssh will use IdentityFile / IdentityAgent from ssh_config if defined else none by default
if (!string.IsNullOrEmpty(this.KeyFilePath))
{
- if (!System.IO.File.Exists(this.KeyFilePath))
+ if (!File.Exists(this.KeyFilePath))
{
throw new FileNotFoundException(
StringUtil.Format(RemotingErrorIdStrings.KeyFileNotFound, this.KeyFilePath));
@@ -2326,7 +2326,7 @@ internal int StartSSHProcess(
// note that ssh expects IPv6 addresses to not be enclosed in square brackets so trim them if present
startInfo.ArgumentList.Add(string.Create(CultureInfo.InvariantCulture, $@"-s {this.ComputerName.TrimStart('[').TrimEnd(']')} {this.Subsystem}"));
- startInfo.WorkingDirectory = System.IO.Path.GetDirectoryName(filePath);
+ startInfo.WorkingDirectory = Path.GetDirectoryName(filePath);
startInfo.CreateNoWindow = true;
startInfo.UseShellExecute = false;
@@ -2580,7 +2580,7 @@ private static unsafe void AllocNullTerminatedArray(string[] arr, ref byte** arr
// Allocate the unmanaged array to hold each string pointer.
// It needs to have an extra element to null terminate the array.
arrPtr = (byte**)Marshal.AllocHGlobal(sizeof(IntPtr) * arrLength);
- System.Diagnostics.Debug.Assert(arrPtr != null, "Invalid array ptr");
+ Debug.Assert(arrPtr != null, "Invalid array ptr");
// Zero the memory so that if any of the individual string allocations fails,
// we can loop through the array to free any that succeeded.
@@ -2597,7 +2597,7 @@ private static unsafe void AllocNullTerminatedArray(string[] arr, ref byte** arr
byte[] byteArr = System.Text.Encoding.UTF8.GetBytes(arr[i]);
arrPtr[i] = (byte*)Marshal.AllocHGlobal(byteArr.Length + 1); // +1 for null termination
- System.Diagnostics.Debug.Assert(arrPtr[i] != null, "Invalid array ptr");
+ Debug.Assert(arrPtr[i] != null, "Invalid array ptr");
Marshal.Copy(byteArr, 0, (IntPtr)arrPtr[i], byteArr.Length); // copy over the data from the managed byte array
arrPtr[i][byteArr.Length] = (byte)'\0'; // null terminate
@@ -2641,13 +2641,13 @@ internal static extern unsafe int ForkAndExecProcess(
/// P-Invoking native APIs.
///
private static int StartSSHProcessImpl(
- System.Diagnostics.ProcessStartInfo startInfo,
+ ProcessStartInfo startInfo,
out StreamWriter stdInWriterVar,
out StreamReader stdOutReaderVar,
out StreamReader stdErrReaderVar)
{
Exception ex = null;
- System.Diagnostics.Process sshProcess = null;
+ Process sshProcess = null;
//
// These std pipe handles are bound to managed Reader/Writer objects and returned to the transport
// manager object, which uses them for PSRP communication. The lifetime of these handles are then
@@ -2668,7 +2668,7 @@ private static int StartSSHProcessImpl(
catch (InvalidOperationException e) { ex = e; }
catch (ArgumentException e) { ex = e; }
catch (FileNotFoundException e) { ex = e; }
- catch (System.ComponentModel.Win32Exception e) { ex = e; }
+ catch (Win32Exception e) { ex = e; }
if ((ex != null) ||
(sshProcess == null) ||
@@ -2693,9 +2693,9 @@ private static int StartSSHProcessImpl(
{
if (stdInWriterVar != null) { stdInWriterVar.Dispose(); } else { stdInPipeServer.Dispose(); }
- if (stdOutReaderVar != null) { stdInWriterVar.Dispose(); } else { stdOutPipeServer.Dispose(); }
+ if (stdOutReaderVar != null) { stdOutReaderVar.Dispose(); } else { stdOutPipeServer.Dispose(); }
- if (stdErrReaderVar != null) { stdInWriterVar.Dispose(); } else { stdErrPipeServer.Dispose(); }
+ if (stdErrReaderVar != null) { stdErrReaderVar.Dispose(); } else { stdErrPipeServer.Dispose(); }
throw;
}
@@ -2705,7 +2705,7 @@ private static int StartSSHProcessImpl(
private static void KillSSHProcessImpl(int pid)
{
- using (var sshProcess = System.Diagnostics.Process.GetProcessById(pid))
+ using (var sshProcess = Process.GetProcessById(pid))
{
if ((sshProcess != null) && (sshProcess.Handle != IntPtr.Zero) && !sshProcess.HasExited)
{
@@ -2736,7 +2736,7 @@ private static Process CreateProcessWithRedirectedStd(
SafeFileHandle stdInPipeClient = null;
SafeFileHandle stdOutPipeClient = null;
SafeFileHandle stdErrPipeClient = null;
- string randomName = System.IO.Path.GetFileNameWithoutExtension(System.IO.Path.GetRandomFileName());
+ string randomName = Path.GetFileNameWithoutExtension(Path.GetRandomFileName());
try
{
@@ -2829,16 +2829,14 @@ private static Process CreateProcessWithRedirectedStd(
catch (Exception)
{
stdInPipeServer?.Dispose();
- stdInPipeClient?.Dispose();
stdOutPipeServer?.Dispose();
- stdOutPipeClient?.Dispose();
stdErrPipeServer?.Dispose();
- stdErrPipeClient?.Dispose();
throw;
}
finally
{
+ lpStartupInfo.Dispose();
lpProcessInformation.Dispose();
}
}
diff --git a/src/System.Management.Automation/engine/remoting/fanin/OutOfProcTransportManager.cs b/src/System.Management.Automation/engine/remoting/fanin/OutOfProcTransportManager.cs
index d9532c8691a..47ff6270dba 100644
--- a/src/System.Management.Automation/engine/remoting/fanin/OutOfProcTransportManager.cs
+++ b/src/System.Management.Automation/engine/remoting/fanin/OutOfProcTransportManager.cs
@@ -1733,7 +1733,7 @@ public override void CreateAsync()
bool sshTerminated = false;
try
{
- using (var sshProcess = System.Diagnostics.Process.GetProcessById(_sshProcessId))
+ using (var sshProcess = Process.GetProcessById(_sshProcessId))
{
sshTerminated = sshProcess == null || sshProcess.Handle == IntPtr.Zero || sshProcess.HasExited;
}
@@ -1847,7 +1847,7 @@ private void ProcessErrorThread(object state)
// Messages in error stream from ssh are unreliable, and may just be warnings or
// banner text.
// So just report the messages but don't act on them.
- System.Console.WriteLine(error);
+ Console.WriteLine(error);
}
catch (IOException)
{ }
@@ -1907,10 +1907,10 @@ private void ProcessReaderThread(object state)
break;
}
- if (data.StartsWith(System.Management.Automation.Remoting.Server.FormattedErrorTextWriter.ErrorPrefix, StringComparison.OrdinalIgnoreCase))
+ if (data.StartsWith(OutOfProcessTextWriter.ErrorPrefix, StringComparison.OrdinalIgnoreCase))
{
// Error message from the server.
- string errorData = data.Substring(System.Management.Automation.Remoting.Server.FormattedErrorTextWriter.ErrorPrefix.Length);
+ string errorData = data.Substring(OutOfProcessTextWriter.ErrorPrefix.Length);
HandleErrorDataReceived(errorData);
}
else
diff --git a/src/System.Management.Automation/engine/runtime/Operations/MiscOps.cs b/src/System.Management.Automation/engine/runtime/Operations/MiscOps.cs
index ddc70fabd50..50054f6501d 100644
--- a/src/System.Management.Automation/engine/runtime/Operations/MiscOps.cs
+++ b/src/System.Management.Automation/engine/runtime/Operations/MiscOps.cs
@@ -1092,14 +1092,11 @@ internal override void Bind(PipelineProcessor pipelineProcessor, CommandProcesso
{
// Check first to see if File is a variable path. If so, we'll not create the FileBytePipe
bool redirectToVariable = false;
- if (ExperimentalFeature.IsEnabled(ExperimentalFeature.PSRedirectToVariable))
+
+ context.SessionState.Path.GetUnresolvedProviderPathFromPSPath(File, out ProviderInfo p, out _);
+ if (p != null && p.NameEquals(context.ProviderNames.Variable))
{
- ProviderInfo p;
- context.SessionState.Path.GetUnresolvedProviderPathFromPSPath(File, out p, out _);
- if (p != null && p.NameEquals(context.ProviderNames.Variable))
- {
- redirectToVariable = true;
- }
+ redirectToVariable = true;
}
if (commandProcessor is NativeCommandProcessor nativeCommand
@@ -1223,12 +1220,10 @@ internal Pipe GetRedirectionPipe(ExecutionContext context, PipelineProcessor par
// determine whether we're trying to set a variable by inspecting the file path
// if we can determine that it's a variable, we'll use Set-Variable rather than Out-File
- ProviderInfo p;
- PSDriveInfo d;
CommandProcessorBase commandProcessor;
- var name = context.SessionState.Path.GetUnresolvedProviderPathFromPSPath(File, out p, out d);
+ var name = context.SessionState.Path.GetUnresolvedProviderPathFromPSPath(File, out ProviderInfo p, out _);
- if (ExperimentalFeature.IsEnabled(ExperimentalFeature.PSRedirectToVariable) && p != null && p.NameEquals(context.ProviderNames.Variable))
+ if (p != null && p.NameEquals(context.ProviderNames.Variable))
{
commandProcessor = context.CreateCommand("Set-Variable", false);
Diagnostics.Assert(commandProcessor != null, "CreateCommand returned null");
diff --git a/src/System.Management.Automation/resources/SuggestionStrings.resx b/src/System.Management.Automation/resources/SuggestionStrings.resx
index 9e325b2616c..39fbc3469f2 100644
--- a/src/System.Management.Automation/resources/SuggestionStrings.resx
+++ b/src/System.Management.Automation/resources/SuggestionStrings.resx
@@ -123,16 +123,7 @@ PowerShell does not load commands from the current location by default (see 'Get
If you trust this command, run the following command instead:
-
- The command "{0}" was not found, but does exist in the current location. PowerShell does not load commands from the current location by default. If you trust this command, instead type: "{1}". See "get-help about_Command_Precedence" for more details.
-
The most similar commands are:
-
- Rule must be a ScriptBlock for dynamic match types.
-
-
- MatchType must be 'Command', 'Error', or 'Dynamic'.
-
diff --git a/src/powershell-unix/powershell-unix.csproj b/src/powershell-unix/powershell-unix.csproj
index 802acf05e3a..20c61247d24 100644
--- a/src/powershell-unix/powershell-unix.csproj
+++ b/src/powershell-unix/powershell-unix.csproj
@@ -37,6 +37,10 @@
PreserveNewestPreserveNewest
+
+ PreserveNewest
+ PreserveNewest
+
diff --git a/src/powershell-win-core/powershell-win-core.csproj b/src/powershell-win-core/powershell-win-core.csproj
index 5368518dd3c..e6efeac10f0 100644
--- a/src/powershell-win-core/powershell-win-core.csproj
+++ b/src/powershell-win-core/powershell-win-core.csproj
@@ -29,6 +29,10 @@
PreserveNewestPreserveNewest
+
+ PreserveNewest
+ PreserveNewest
+ PreserveNewestPreserveNewest
diff --git a/test/infrastructure/ciModule.Tests.ps1 b/test/infrastructure/ciModule.Tests.ps1
new file mode 100644
index 00000000000..b7320ff49b7
--- /dev/null
+++ b/test/infrastructure/ciModule.Tests.ps1
@@ -0,0 +1,246 @@
+# Copyright (c) Microsoft Corporation.
+# Licensed under the MIT License.
+
+# NOTE: This test file tests the Test-MergeConflictMarker function which detects Git merge conflict markers.
+# IMPORTANT: Do NOT use here-strings or literal conflict markers (e.g., "<<<<<<<", "=======", ">>>>>>>")
+# in this file, as they will trigger conflict marker detection in CI pipelines.
+# Instead, use string multiplication (e.g., '<' * 7) to dynamically generate these markers at runtime.
+
+Describe "Test-MergeConflictMarker" {
+ BeforeAll {
+ # Import the module
+ Import-Module "$PSScriptRoot/../../tools/ci.psm1" -Force
+
+ # Create a temporary test workspace
+ $script:testWorkspace = Join-Path $TestDrive "workspace"
+ New-Item -ItemType Directory -Path $script:testWorkspace -Force | Out-Null
+
+ # Create temporary output files
+ $script:testOutputPath = Join-Path $TestDrive "outputs.txt"
+ $script:testSummaryPath = Join-Path $TestDrive "summary.md"
+ }
+
+ AfterEach {
+ # Clean up test files after each test
+ if (Test-Path $script:testWorkspace) {
+ Get-ChildItem $script:testWorkspace -File -ErrorAction SilentlyContinue | Remove-Item -Force -ErrorAction SilentlyContinue
+ }
+ Remove-Item $script:testOutputPath -Force -ErrorAction SilentlyContinue
+ Remove-Item $script:testSummaryPath -Force -ErrorAction SilentlyContinue
+ }
+
+ Context "When no files are provided" {
+ It "Should handle empty file array gracefully" {
+ # The function now accepts empty arrays to handle cases like delete-only PRs
+ $emptyArray = @()
+ Test-MergeConflictMarker -File $emptyArray -WorkspacePath $script:testWorkspace -OutputPath $script:testOutputPath -SummaryPath $script:testSummaryPath
+
+ $outputs = Get-Content $script:testOutputPath
+ $outputs | Should -Contain "files-checked=0"
+ $outputs | Should -Contain "conflicts-found=0"
+
+ $summary = Get-Content $script:testSummaryPath -Raw
+ $summary | Should -Match "No Files to Check"
+ }
+ }
+
+ Context "When files have no conflicts" {
+ It "Should pass for clean files" {
+ $testFile = Join-Path $script:testWorkspace "clean.txt"
+ "This is a clean file" | Out-File $testFile -Encoding utf8
+
+ Test-MergeConflictMarker -File @("clean.txt") -WorkspacePath $script:testWorkspace -OutputPath $script:testOutputPath -SummaryPath $script:testSummaryPath
+
+ $outputs = Get-Content $script:testOutputPath
+ $outputs | Should -Contain "files-checked=1"
+ $outputs | Should -Contain "conflicts-found=0"
+
+ $summary = Get-Content $script:testSummaryPath -Raw
+ $summary | Should -Match "No Conflicts Found"
+ }
+ }
+
+ Context "When files have conflict markers" {
+ It "Should detect <<<<<<< marker" {
+ $testFile = Join-Path $script:testWorkspace "conflict1.txt"
+ "Some content`n" + ('<' * 7) + " HEAD`nConflicting content" | Out-File $testFile -Encoding utf8
+
+ { Test-MergeConflictMarker -File @("conflict1.txt") -WorkspacePath $script:testWorkspace -OutputPath $script:testOutputPath -SummaryPath $script:testSummaryPath } | Should -Throw
+
+ $outputs = Get-Content $script:testOutputPath
+ $outputs | Should -Contain "files-checked=1"
+ $outputs | Should -Contain "conflicts-found=1"
+ }
+
+ It "Should detect ======= marker" {
+ $testFile = Join-Path $script:testWorkspace "conflict2.txt"
+ "Some content`n" + ('=' * 7) + "`nMore content" | Out-File $testFile -Encoding utf8
+
+ { Test-MergeConflictMarker -File @("conflict2.txt") -WorkspacePath $script:testWorkspace -OutputPath $script:testOutputPath -SummaryPath $script:testSummaryPath } | Should -Throw
+ }
+
+ It "Should detect >>>>>>> marker" {
+ $testFile = Join-Path $script:testWorkspace "conflict3.txt"
+ "Some content`n" + ('>' * 7) + " branch-name`nMore content" | Out-File $testFile -Encoding utf8
+
+ { Test-MergeConflictMarker -File @("conflict3.txt") -WorkspacePath $script:testWorkspace -OutputPath $script:testOutputPath -SummaryPath $script:testSummaryPath } | Should -Throw
+ }
+
+ It "Should detect multiple markers in one file" {
+ $testFile = Join-Path $script:testWorkspace "conflict4.txt"
+ $content = "Some content`n" + ('<' * 7) + " HEAD`nContent A`n" + ('=' * 7) + "`nContent B`n" + ('>' * 7) + " branch`nMore content"
+ $content | Out-File $testFile -Encoding utf8
+
+ { Test-MergeConflictMarker -File @("conflict4.txt") -WorkspacePath $script:testWorkspace -OutputPath $script:testOutputPath -SummaryPath $script:testSummaryPath } | Should -Throw
+
+ $summary = Get-Content $script:testSummaryPath -Raw
+ $summary | Should -Match "Conflicts Detected"
+ $summary | Should -Match "conflict4.txt"
+ }
+
+ It "Should detect conflicts in multiple files" {
+ $testFile1 = Join-Path $script:testWorkspace "conflict5.txt"
+ ('<' * 7) + " HEAD" | Out-File $testFile1 -Encoding utf8
+
+ $testFile2 = Join-Path $script:testWorkspace "conflict6.txt"
+ ('=' * 7) | Out-File $testFile2 -Encoding utf8
+
+ { Test-MergeConflictMarker -File @("conflict5.txt", "conflict6.txt") -WorkspacePath $script:testWorkspace -OutputPath $script:testOutputPath -SummaryPath $script:testSummaryPath } | Should -Throw
+
+ $outputs = Get-Content $script:testOutputPath
+ $outputs | Should -Contain "files-checked=2"
+ $outputs | Should -Contain "conflicts-found=2"
+ }
+ }
+
+ Context "When markers are not at line start" {
+ It "Should not detect markers in middle of line" {
+ $testFile = Join-Path $script:testWorkspace "notconflict.txt"
+ "This line has <<<<<<< in the middle" | Out-File $testFile -Encoding utf8
+
+ Test-MergeConflictMarker -File @("notconflict.txt") -WorkspacePath $script:testWorkspace -OutputPath $script:testOutputPath -SummaryPath $script:testSummaryPath
+
+ $outputs = Get-Content $script:testOutputPath
+ $outputs | Should -Contain "conflicts-found=0"
+ }
+
+ It "Should not detect markers with wrong number of characters" {
+ $testFile = Join-Path $script:testWorkspace "wrongcount.txt"
+ ('<' * 6) + " Only 6`n" + ('<' * 8) + " 8 characters" | Out-File $testFile -Encoding utf8
+
+ Test-MergeConflictMarker -File @("wrongcount.txt") -WorkspacePath $script:testWorkspace -OutputPath $script:testOutputPath -SummaryPath $script:testSummaryPath
+
+ $outputs = Get-Content $script:testOutputPath
+ $outputs | Should -Contain "conflicts-found=0"
+ }
+ }
+
+ Context "When handling special file scenarios" {
+ It "Should skip non-existent files" {
+ Test-MergeConflictMarker -File @("nonexistent.txt") -WorkspacePath $script:testWorkspace -OutputPath $script:testOutputPath -SummaryPath $script:testSummaryPath
+
+ $outputs = Get-Content $script:testOutputPath
+ $outputs | Should -Contain "files-checked=0"
+ }
+
+ It "Should handle absolute paths" {
+ $testFile = Join-Path $script:testWorkspace "absolute.txt"
+ "Clean content" | Out-File $testFile -Encoding utf8
+
+ Test-MergeConflictMarker -File @($testFile) -WorkspacePath $script:testWorkspace -OutputPath $script:testOutputPath -SummaryPath $script:testSummaryPath
+
+ $outputs = Get-Content $script:testOutputPath
+ $outputs | Should -Contain "conflicts-found=0"
+ }
+
+ It "Should handle mixed relative and absolute paths" {
+ $testFile1 = Join-Path $script:testWorkspace "relative.txt"
+ "Clean" | Out-File $testFile1 -Encoding utf8
+
+ $testFile2 = Join-Path $script:testWorkspace "absolute.txt"
+ "Clean" | Out-File $testFile2 -Encoding utf8
+
+ Test-MergeConflictMarker -File @("relative.txt", $testFile2) -WorkspacePath $script:testWorkspace -OutputPath $script:testOutputPath -SummaryPath $script:testSummaryPath
+
+ $outputs = Get-Content $script:testOutputPath
+ $outputs | Should -Contain "files-checked=2"
+ $outputs | Should -Contain "conflicts-found=0"
+ }
+ }
+
+ Context "When summary and output generation" {
+ It "Should generate proper GitHub Actions outputs format" {
+ $testFile = Join-Path $script:testWorkspace "test.txt"
+ "Clean file" | Out-File $testFile -Encoding utf8
+
+ Test-MergeConflictMarker -File @("test.txt") -WorkspacePath $script:testWorkspace -OutputPath $script:testOutputPath -SummaryPath $script:testSummaryPath
+
+ $outputs = Get-Content $script:testOutputPath
+ $outputs | Where-Object {$_ -match "^files-checked=\d+$"} | Should -Not -BeNullOrEmpty
+ $outputs | Where-Object {$_ -match "^conflicts-found=\d+$"} | Should -Not -BeNullOrEmpty
+ }
+
+ It "Should generate markdown summary with conflict details" {
+ $testFile = Join-Path $script:testWorkspace "marked.txt"
+ $content = "Line 1`n" + ('<' * 7) + " HEAD`nLine 3`n" + ('=' * 7) + "`nLine 5"
+ $content | Out-File $testFile -Encoding utf8
+
+ { Test-MergeConflictMarker -File @("marked.txt") -WorkspacePath $script:testWorkspace -OutputPath $script:testOutputPath -SummaryPath $script:testSummaryPath } | Should -Throw
+
+ $summary = Get-Content $script:testSummaryPath -Raw
+ $summary | Should -Match "# Merge Conflict Marker Check Results"
+ $summary | Should -Match "marked.txt"
+ $summary | Should -Match "\| Line \| Marker \|"
+ }
+ }
+}
+
+Describe "Install-CIPester" {
+ BeforeAll {
+ # Import the module
+ Import-Module "$PSScriptRoot/../../tools/ci.psm1" -Force
+ }
+
+ Context "When checking function exists" {
+ It "Should export Install-CIPester function" {
+ $function = Get-Command Install-CIPester -ErrorAction SilentlyContinue
+ $function | Should -Not -BeNullOrEmpty
+ $function.ModuleName | Should -Be 'ci'
+ }
+
+ It "Should have expected parameters" {
+ $function = Get-Command Install-CIPester
+ $function.Parameters.Keys | Should -Contain 'MinimumVersion'
+ $function.Parameters.Keys | Should -Contain 'MaximumVersion'
+ $function.Parameters.Keys | Should -Contain 'Force'
+ }
+
+ It "Should accept version parameters" {
+ $function = Get-Command Install-CIPester
+ $function.Parameters['MinimumVersion'].ParameterType.Name | Should -Be 'String'
+ $function.Parameters['MaximumVersion'].ParameterType.Name | Should -Be 'String'
+ $function.Parameters['Force'].ParameterType.Name | Should -Be 'SwitchParameter'
+ }
+ }
+
+ Context "When validating real execution" {
+ # These tests only run in CI where we can safely install/test Pester
+
+ It "Should successfully run without errors when Pester exists" {
+ if (!$env:CI) {
+ Set-ItResult -Skipped -Because "Test requires CI environment to safely install Pester"
+ }
+
+ { Install-CIPester -ErrorAction Stop } | Should -Not -Throw
+ }
+
+ It "Should accept custom version parameters" {
+ if (!$env:CI) {
+ Set-ItResult -Skipped -Because "Test requires CI environment to safely install Pester"
+ }
+
+ { Install-CIPester -MinimumVersion '4.0.0' -MaximumVersion '5.99.99' -ErrorAction Stop } | Should -Not -Throw
+ }
+ }
+}
+
diff --git a/test/packaging/linux/package-validation.tests.ps1 b/test/packaging/linux/package-validation.tests.ps1
new file mode 100644
index 00000000000..594a729fa77
--- /dev/null
+++ b/test/packaging/linux/package-validation.tests.ps1
@@ -0,0 +1,117 @@
+# Copyright (c) Microsoft Corporation.
+# Licensed under the MIT License.
+
+Describe "Linux Package Name Validation" {
+ BeforeAll {
+ # Determine artifacts directory (GitHub Actions or Azure DevOps)
+ $artifactsDir = if ($env:GITHUB_ACTIONS -eq 'true') {
+ "$env:GITHUB_WORKSPACE/../packages"
+ } else {
+ $env:SYSTEM_ARTIFACTSDIRECTORY
+ }
+
+ if (-not $artifactsDir) {
+ throw "Artifacts directory not found. GITHUB_WORKSPACE or SYSTEM_ARTIFACTSDIRECTORY must be set."
+ }
+
+ Write-Verbose "Artifacts directory: $artifactsDir" -Verbose
+ }
+
+ Context "RPM Package Names" {
+ It "Should have valid RPM package names" {
+ $rpmPackages = Get-ChildItem -Path $artifactsDir -Recurse -Filter *.rpm -ErrorAction SilentlyContinue
+
+ $rpmPackages.Count | Should -BeGreaterThan 0 -Because "At least one RPM package should exist in the artifacts directory"
+
+ $invalidPackages = @()
+ # Regex pattern for valid RPM package names.
+ # Breakdown:
+ # ^powershell\- : Starts with 'powershell-'
+ # (preview-|lts-)? : Optionally 'preview-' or 'lts-'
+ # \d+\.\d+\.\d+ : Version number (e.g., 7.6.0)
+ # (_[a-z]*\.\d+)? : Optional underscore, letters, dot, and digits (e.g., _alpha.1)
+ # -1\. : Literal '-1.'
+ # (preview\.\d+\.)? : Optional 'preview.' and digits, followed by a dot
+ # (rh|cm)\. : Either 'rh.' or 'cm.'
+ # (x86_64|aarch64)\.rpm$ : Architecture and file extension
+ $rpmPackageNamePattern = 'powershell\-(preview-|lts-)?\d+\.\d+\.\d+(_[a-z]*\.\d+)?-1\.(preview\.\d+\.)?(rh|cm)\.(x86_64|aarch64)\.rpm'
+
+ foreach ($package in $rpmPackages) {
+ if ($package.Name -notmatch $rpmPackageNamePattern) {
+ $invalidPackages += "$($package.Name) is not a valid RPM package name"
+ Write-Warning "$($package.Name) is not a valid RPM package name"
+ }
+ }
+
+ if ($invalidPackages.Count -gt 0) {
+ throw ($invalidPackages | Out-String)
+ }
+ }
+ }
+
+ Context "DEB Package Names" {
+ It "Should have valid DEB package names" {
+ $debPackages = Get-ChildItem -Path $artifactsDir -Recurse -Filter *.deb -ErrorAction SilentlyContinue
+
+ $debPackages.Count | Should -BeGreaterThan 0 -Because "At least one DEB package should exist in the artifacts directory"
+
+ $invalidPackages = @()
+ # Regex pattern for valid DEB package names.
+ # Valid examples:
+ # - powershell-preview_7.6.0-preview.6-1.deb_amd64.deb
+ # - powershell-lts_7.4.13-1.deb_amd64.deb
+ # - powershell_7.4.13-1.deb_amd64.deb
+ # Breakdown:
+ # ^powershell : Starts with 'powershell'
+ # (-preview|-lts)? : Optionally '-preview' or '-lts'
+ # _\d+\.\d+\.\d+ : Underscore followed by version number (e.g., _7.6.0)
+ # (-[a-z]+\.\d+)? : Optional dash, letters, dot, and digits (e.g., -preview.6)
+ # -1 : Literal '-1'
+ # \.deb_ : Literal '.deb_'
+ # (amd64|arm64) : Architecture
+ # \.deb$ : File extension
+ $debPackageNamePattern = '^powershell(-preview|-lts)?_\d+\.\d+\.\d+(-[a-z]+\.\d+)?-1\.deb_(amd64|arm64)\.deb$'
+
+ foreach ($package in $debPackages) {
+ if ($package.Name -notmatch $debPackageNamePattern) {
+ $invalidPackages += "$($package.Name) is not a valid DEB package name"
+ Write-Warning "$($package.Name) is not a valid DEB package name"
+ }
+ }
+
+ if ($invalidPackages.Count -gt 0) {
+ throw ($invalidPackages | Out-String)
+ }
+ }
+ }
+
+ Context "Tar.Gz Package Names" {
+ It "Should have valid tar.gz package names" {
+ $tarPackages = Get-ChildItem -Path $artifactsDir -Recurse -Filter *.tar.gz -ErrorAction SilentlyContinue
+
+ $tarPackages.Count | Should -BeGreaterThan 0 -Because "At least one tar.gz package should exist in the artifacts directory"
+
+ $invalidPackages = @()
+ foreach ($package in $tarPackages) {
+ # Pattern matches: powershell-7.6.0-preview.6-linux-x64.tar.gz or powershell-7.6.0-linux-x64.tar.gz
+ # Also matches various runtime configurations
+ if ($package.Name -notmatch 'powershell-(lts-)?\d+\.\d+\.\d+\-([a-z]*.\d+\-)?(linux|osx|linux-musl)+\-(x64\-fxdependent|x64|arm32|arm64|x64\-musl-noopt\-fxdependent)\.(tar\.gz)') {
+ $invalidPackages += "$($package.Name) is not a valid tar.gz package name"
+ Write-Warning "$($package.Name) is not a valid tar.gz package name"
+ }
+ }
+
+ if ($invalidPackages.Count -gt 0) {
+ throw ($invalidPackages | Out-String)
+ }
+ }
+ }
+
+ Context "Package Existence" {
+ It "Should find at least one package in artifacts directory" {
+ $allPackages = Get-ChildItem -Path $artifactsDir -Recurse -Include *.rpm, *.tar.gz, *.deb -ErrorAction SilentlyContinue
+
+ $allPackages.Count | Should -BeGreaterThan 0 -Because "At least one package should exist in the artifacts directory"
+ }
+ }
+}
diff --git a/test/packaging/macos/package-validation.tests.ps1 b/test/packaging/macos/package-validation.tests.ps1
new file mode 100644
index 00000000000..92179c31624
--- /dev/null
+++ b/test/packaging/macos/package-validation.tests.ps1
@@ -0,0 +1,186 @@
+# Copyright (c) Microsoft Corporation.
+# Licensed under the MIT License.
+
+Describe "Verify macOS Package" {
+ BeforeAll {
+ Write-Verbose "In Describe BeforeAll" -Verbose
+ Import-Module $PSScriptRoot/../../../build.psm1
+
+ # Find the macOS package
+ $packagePath = $env:PACKAGE_FOLDER
+ if (-not $packagePath) {
+ $packagePath = Get-Location
+ }
+
+ Write-Verbose "Looking for package in: $packagePath" -Verbose
+ $package = Get-ChildItem -Path $packagePath -Filter "*.pkg" -ErrorAction SilentlyContinue | Select-Object -First 1
+
+ if (-not $package) {
+ Write-Warning "No .pkg file found in $packagePath"
+ } else {
+ Write-Verbose "Found package: $($package.FullName)" -Verbose
+ }
+
+ # Set up test directories
+ $script:package = $package
+ $script:expandDir = $null
+ $script:payloadDir = $null
+ $script:extractedFiles = @()
+
+ if ($package) {
+ # Use TestDrive for temporary directories - pkgutil will create the expand directory
+ $script:expandDir = Join-Path "TestDrive:" -ChildPath "package-contents-test"
+ $expandDirResolved = (Resolve-Path "TestDrive:").ProviderPath
+ $script:expandDir = Join-Path $expandDirResolved -ChildPath "package-contents-test"
+
+ Write-Verbose "Expanding package to: $($script:expandDir)" -Verbose
+ # pkgutil will create the directory itself, so don't pre-create it
+ Start-NativeExecution {
+ pkgutil --expand $package.FullName $script:expandDir
+ }
+
+ # Extract the payload to verify files
+ $script:payloadDir = Join-Path "TestDrive:" -ChildPath "package-payload-test"
+ $payloadDirResolved = (Resolve-Path "TestDrive:").ProviderPath
+ $script:payloadDir = Join-Path $payloadDirResolved -ChildPath "package-payload-test"
+
+ # Create payload directory since cpio needs it
+ if (-not (Test-Path $script:payloadDir)) {
+ $null = New-Item -ItemType Directory -Path $script:payloadDir -Force
+ }
+
+ $componentPkg = Get-ChildItem -Path $script:expandDir -Filter "*.pkg" -Recurse | Select-Object -First 1
+ if ($componentPkg) {
+ Write-Verbose "Extracting payload from: $($componentPkg.FullName)" -Verbose
+ Push-Location $script:payloadDir
+ try {
+ $payloadFile = Join-Path $componentPkg.FullName "Payload"
+ Get-Content -Path $payloadFile -Raw -AsByteStream | & cpio -i 2>&1 | Out-Null
+ } finally {
+ Pop-Location
+ }
+ }
+
+ # Get all extracted files for verification
+ $script:extractedFiles = Get-ChildItem -Path $script:payloadDir -Recurse -ErrorAction SilentlyContinue
+ Write-Verbose "Extracted $($script:extractedFiles.Count) files" -Verbose
+ }
+ }
+
+ AfterAll {
+ # TestDrive automatically cleans up, but we can ensure cleanup happens
+ # No manual cleanup needed as TestDrive handles it
+ }
+
+ Context "Package existence and structure" {
+ It "Package file should exist" {
+ $script:package | Should -Not -BeNullOrEmpty -Because "A .pkg file should be created"
+ $script:package.Extension | Should -Be ".pkg"
+ }
+
+ It "Package name should follow correct naming convention" {
+ $script:package | Should -Not -BeNullOrEmpty
+
+ # Regex pattern for valid macOS PKG package names.
+ # This pattern matches the validation used in release-validate-packagenames.yml
+ # Valid examples:
+ # - powershell-7.4.13-osx-x64.pkg (Stable release)
+ # - powershell-7.6.0-preview.6-osx-x64.pkg (Preview version string)
+ # - powershell-7.4.13-rebuild.5-osx-arm64.pkg (Rebuild version)
+ # - powershell-lts-7.4.13-osx-arm64.pkg (LTS package)
+ $pkgPackageNamePattern = '^powershell-(lts-)?\d+\.\d+\.\d+\-([a-z]*.\d+\-)?osx\-(x64|arm64)\.pkg$'
+
+ $script:package.Name | Should -Match $pkgPackageNamePattern -Because "Package name should follow the standard naming convention"
+ }
+
+ It "Package name should NOT use x86_64 with underscores" {
+ $script:package | Should -Not -BeNullOrEmpty
+
+ $script:package.Name | Should -Not -Match 'x86_64' -Because "Package should use 'x64' not 'x86_64' (with underscores) for compatibility"
+ }
+
+ It "Package should expand successfully" {
+ $script:expandDir | Should -Exist
+ Get-ChildItem -Path $script:expandDir | Should -Not -BeNullOrEmpty
+ }
+
+ It "Package should have a component package" {
+ $componentPkg = Get-ChildItem -Path $script:expandDir -Filter "*.pkg" -Recurse -ErrorAction SilentlyContinue
+ $componentPkg | Should -Not -BeNullOrEmpty -Because "Package should contain a component.pkg"
+ }
+
+ It "Payload should extract successfully" {
+ $script:payloadDir | Should -Exist
+ $script:extractedFiles | Should -Not -BeNullOrEmpty -Because "Package payload should contain files"
+ }
+ }
+
+ Context "Required files in package" {
+ BeforeAll {
+ $expectedFilePatterns = @{
+ "PowerShell executable" = "usr/local/microsoft/powershell/*/pwsh"
+ "PowerShell symlink in /usr/local/bin" = "usr/local/bin/pwsh*"
+ "Man page" = "usr/local/share/man/man1/pwsh*.gz"
+ "Launcher application plist" = "Applications/PowerShell*.app/Contents/Info.plist"
+ }
+
+ $testCases = @()
+ foreach ($key in $expectedFilePatterns.Keys) {
+ $testCases += @{
+ Description = $key
+ Pattern = $expectedFilePatterns[$key]
+ }
+ }
+
+ $script:testCases = $testCases
+ }
+
+ It "Should contain " -TestCases $script:testCases {
+ param($Description, $Pattern)
+
+ $found = $script:extractedFiles | Where-Object { $_.FullName -like "*$Pattern*" }
+ $found | Should -Not -BeNullOrEmpty -Because "$Description should exist in the package at path matching '$Pattern'"
+ }
+ }
+
+ Context "PowerShell binary verification" {
+ It "PowerShell executable should be executable" {
+ $pwshBinary = $script:extractedFiles | Where-Object { $_.FullName -like "*/pwsh" -and $_.FullName -like "*/microsoft/powershell/*" }
+ $pwshBinary | Should -Not -BeNullOrEmpty
+
+ # Check if file has executable permissions (on Unix-like systems)
+ if ($IsLinux -or $IsMacOS) {
+ $permissions = (Get-Item $pwshBinary[0].FullName).UnixFileMode
+ # Executable bit should be set
+ $permissions.ToString() | Should -Match 'x' -Because "pwsh binary should have execute permissions"
+ }
+ }
+ }
+
+ Context "Launcher application" {
+ It "Launcher app should have proper bundle structure" {
+ $plistFile = $script:extractedFiles | Where-Object { $_.FullName -like "*PowerShell*.app/Contents/Info.plist" }
+ $plistFile | Should -Not -BeNullOrEmpty
+
+ # Verify the bundle has required components
+ $appPath = Split-Path (Split-Path $plistFile[0].FullName -Parent) -Parent
+ $macOSDir = Join-Path $appPath "Contents/MacOS"
+ $resourcesDir = Join-Path $appPath "Contents/Resources"
+
+ Test-Path $macOSDir | Should -Be $true -Because "App bundle should have Contents/MacOS directory"
+ Test-Path $resourcesDir | Should -Be $true -Because "App bundle should have Contents/Resources directory"
+ }
+
+ It "Launcher script should exist and be executable" {
+ $launcherScript = $script:extractedFiles | Where-Object {
+ $_.FullName -like "*PowerShell*.app/Contents/MacOS/PowerShell.sh"
+ }
+ $launcherScript | Should -Not -BeNullOrEmpty -Because "Launcher script should exist"
+
+ if ($IsLinux -or $IsMacOS) {
+ $permissions = (Get-Item $launcherScript[0].FullName).UnixFileMode
+ $permissions.ToString() | Should -Match 'x' -Because "Launcher script should have execute permissions"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/perf/dotnet-tools/BenchmarkDotNet.Extensions/BenchmarkDotNet.Extensions.csproj b/test/perf/dotnet-tools/BenchmarkDotNet.Extensions/BenchmarkDotNet.Extensions.csproj
index 74a4cf9e089..2416d128bf5 100644
--- a/test/perf/dotnet-tools/BenchmarkDotNet.Extensions/BenchmarkDotNet.Extensions.csproj
+++ b/test/perf/dotnet-tools/BenchmarkDotNet.Extensions/BenchmarkDotNet.Extensions.csproj
@@ -6,12 +6,12 @@
-
-
+
+
-
+
\ No newline at end of file
diff --git a/test/perf/dotnet-tools/ResultsComparer/ResultsComparer.csproj b/test/perf/dotnet-tools/ResultsComparer/ResultsComparer.csproj
index 9883c8b2d63..3bcb86355be 100644
--- a/test/perf/dotnet-tools/ResultsComparer/ResultsComparer.csproj
+++ b/test/perf/dotnet-tools/ResultsComparer/ResultsComparer.csproj
@@ -9,7 +9,7 @@
-
-
+
+
-
+
\ No newline at end of file
diff --git a/test/powershell/Host/TabCompletion/BugFix.Tests.ps1 b/test/powershell/Host/TabCompletion/BugFix.Tests.ps1
index 32fd73f8c09..a7191d06e9b 100644
--- a/test/powershell/Host/TabCompletion/BugFix.Tests.ps1
+++ b/test/powershell/Host/TabCompletion/BugFix.Tests.ps1
@@ -126,4 +126,27 @@ Describe "Tab completion bug fix" -Tags "CI" {
$Runspace.Dispose()
}
}
+
+ It "Issue#26277 - [CompletionCompleters]::CompleteFilename('') should work" {
+ $testDir = Join-Path $TestDrive "TempTestDir"
+ $file1 = Join-Path $testDir "abc.ps1"
+ $file2 = Join-Path $testDir "def.py"
+
+ New-Item -ItemType Directory -Path $testDir > $null
+ New-Item -ItemType File -Path $file1 > $null
+ New-Item -ItemType File -Path $file2 > $null
+
+ try {
+ Push-Location -Path $testDir
+ $result = [System.Management.Automation.CompletionCompleters]::CompleteFilename("")
+ $result | Should -Not -Be $null
+ $result | Measure-Object | ForEach-Object -MemberName Count | Should -Be 2
+
+ $item1, $item2 = @($result)
+ $item1.ListItemText | Should -BeExactly 'abc.ps1'
+ $item2.ListItemText | Should -BeExactly 'def.py'
+ } finally {
+ Pop-Location
+ }
+ }
}
diff --git a/test/powershell/Language/Parser/RedirectionOperator.Tests.ps1 b/test/powershell/Language/Parser/RedirectionOperator.Tests.ps1
index d948881f1de..140d92fae88 100644
--- a/test/powershell/Language/Parser/RedirectionOperator.Tests.ps1
+++ b/test/powershell/Language/Parser/RedirectionOperator.Tests.ps1
@@ -127,12 +127,6 @@ Describe "File redirection should have 'DoComplete' called on the underlying pip
Describe "Redirection and Set-Variable -append tests" -tags CI {
Context "variable redirection should work" {
BeforeAll {
- if ( $EnabledExperimentalFeatures -contains "PSRedirectToVariable" ) {
- $skipTest = $false
- }
- else {
- $skipTest = $true
- }
$testCases = @{ Name = "Variable should be created"; scriptBlock = { 1..3>variable:a }; Validation = { ($a -join "") | Should -Be ((1..3) -join "") } },
@{ Name = "variable should be appended"; scriptBlock = {1..3>variable:a; 4..6>>variable:a}; Validation = { ($a -join "") | Should -Be ((1..6) -join "")}},
@{ Name = "variable should maintain type"; scriptBlock = {@{one=1}>variable:a};Validation = {$a | Should -BeOfType [hashtable]}},
@@ -220,7 +214,7 @@ Describe "Redirection and Set-Variable -append tests" -tags CI {
}
- It "" -TestCases $testCases -skip:$skipTest {
+ It "" -TestCases $testCases {
param ( $scriptBlock, $validation )
. $scriptBlock
. $validation
diff --git a/test/powershell/Language/Scripting/NativeExecution/NativeWindowsTildeExpansion.Tests.ps1 b/test/powershell/Language/Scripting/NativeExecution/NativeWindowsTildeExpansion.Tests.ps1
index 04156099fa4..3a478607c08 100644
--- a/test/powershell/Language/Scripting/NativeExecution/NativeWindowsTildeExpansion.Tests.ps1
+++ b/test/powershell/Language/Scripting/NativeExecution/NativeWindowsTildeExpansion.Tests.ps1
@@ -5,7 +5,6 @@ Describe 'Native Windows tilde expansion tests' -tags "CI" {
BeforeAll {
$originalDefaultParams = $PSDefaultParameterValues.Clone()
$PSDefaultParameterValues["it:skip"] = -Not $IsWindows
- $EnabledExperimentalFeatures.Contains('PSNativeWindowsTildeExpansion') | Should -BeTrue
}
AfterAll {
@@ -21,12 +20,13 @@ Describe 'Native Windows tilde expansion tests' -tags "CI" {
cmd /c echo ~/foo | Should -BeExactly "$($ExecutionContext.SessionState.Provider.Get("FileSystem").Home)/foo"
cmd /c echo ~\foo | Should -BeExactly "$($ExecutionContext.SessionState.Provider.Get("FileSystem").Home)\foo"
}
- It '~ should not be replaced when quoted' {
- cmd /c echo '~' | Should -BeExactly '~'
- cmd /c echo "~" | Should -BeExactly '~'
- cmd /c echo '~/foo' | Should -BeExactly '~/foo'
- cmd /c echo "~/foo" | Should -BeExactly '~/foo'
+
+ It '~ should not be replaced when quoted' {
+ cmd /c echo '~' | Should -BeExactly '~'
+ cmd /c echo "~" | Should -BeExactly '~'
+ cmd /c echo '~/foo' | Should -BeExactly '~/foo'
+ cmd /c echo "~/foo" | Should -BeExactly '~/foo'
cmd /c echo '~\foo' | Should -BeExactly '~\foo'
- cmd /c echo "~\foo" | Should -BeExactly '~\foo'
- }
+ cmd /c echo "~\foo" | Should -BeExactly '~\foo'
+ }
}
diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/Clipboard.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/Clipboard.Tests.ps1
index 7cd4f492bfa..62f8d77a44c 100644
--- a/test/powershell/Modules/Microsoft.PowerShell.Management/Clipboard.Tests.ps1
+++ b/test/powershell/Modules/Microsoft.PowerShell.Management/Clipboard.Tests.ps1
@@ -36,6 +36,13 @@ Describe 'Clipboard cmdlet tests' -Tag CI {
Get-Clipboard -Raw | Should -BeExactly "1$([Environment]::NewLine)2"
}
+ It 'Get-Clipboard -Delimiter should return items based on the delimiter' {
+ Set-Clipboard -Value "Line1`r`nLine2`nLine3"
+ $result = Get-Clipboard -Delimiter "`r`n", "`n"
+ $result.Count | Should -Be 3
+ $result | ForEach-Object -Process {$_.Length | Should -Be "LineX".Length}
+ }
+
It 'Set-Clipboard -Append will add text' {
'hello' | Set-Clipboard
'world' | Set-Clipboard -Append
diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/Get-Alias.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/Get-Alias.Tests.ps1
index edccb912ca7..a5b0b039d00 100644
--- a/test/powershell/Modules/Microsoft.PowerShell.Utility/Get-Alias.Tests.ps1
+++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/Get-Alias.Tests.ps1
@@ -155,6 +155,16 @@ Describe "Get-Alias DRT Unit Tests" -Tags "CI" {
$returnObject[$i].Definition | Should -Be 'Get-Command'
}
}
+
+ It "Get-Alias DisplayName should always show AliasName -> ResolvedCommand for all aliases" {
+ Set-Alias -Name Test-MyAlias -Value Get-Command -Force
+ Set-Alias -Name tma -Value Test-MyAlias -force
+ $aliases = Get-Alias Test-MyAlias, tma
+ $aliases | ForEach-Object {
+ $_.DisplayName | Should -Be "$($_.Name) -> Get-Command"
+ }
+ $aliases.Name.foreach{Remove-Item Alias:$_ -ErrorAction SilentlyContinue}
+ }
}
Describe "Get-Alias" -Tags "CI" {
diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/Set-Variable.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/Set-Variable.Tests.ps1
index d11fd5cfbb3..6e6fc1a2e1d 100644
--- a/test/powershell/Modules/Microsoft.PowerShell.Utility/Set-Variable.Tests.ps1
+++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/Set-Variable.Tests.ps1
@@ -244,44 +244,30 @@ Describe "Set-Variable" -Tags "CI" {
Context "Set-Variable -Append tests" {
BeforeAll {
- if (! (Get-ExperimentalFeature PSRedirectToVariable).Enabled) {
- $skipTest = $true
- }
-
- $testCases = @{ value = 2; Count = 2 },
- @{ value = @(2,3,4); Count = 2},
- @{ value = "abc",(Get-Process -Id $PID) ; count = 2}
+ $testCases = @{ value = 2; Count = 2 },
+ @{ value = @(2,3,4); Count = 2},
+ @{ value = "abc",(Get-Process -Id $PID) ; count = 2}
}
- It "Can append values to a variable" -testCases $testCases {
- param ($value, $count)
-
- if ($skipTest) {
- Set-ItResult -skip -because "Experimental Feature PSRedirectToVariable not enabled"
- return
- }
-
- $variableName = "testVar"
- Set-Variable -Name $variableName -Value 1
- Set-Variable -Name $variableName -Value $value -Append
+ It "Can append values to a variable" -testCases $testCases {
+ param ($value, $count)
- $observedValues = Get-Variable $variableName -Value
+ $variableName = "testVar"
+ Set-Variable -Name $variableName -Value 1
+ Set-Variable -Name $variableName -Value $value -Append
- $observedValues.Count | Should -Be $count
- $observedValues[0] | Should -Be 1
+ $observedValues = Get-Variable $variableName -Value
- $observedValues[1] | Should -Be $value
- }
+ $observedValues.Count | Should -Be $count
+ $observedValues[0] | Should -Be 1
- It "Can use set-variable via streaming and append values" {
- if ($skipTest) {
- Set-ItResult -skip -because "Experimental Feature PSRedirectToVariable not enabled"
- return
- }
+ $observedValues[1] | Should -Be $value
+ }
- $testVar = 1
- 4..6 | Set-Variable -Name testVar -Append
- $testVar | Should -Be @(1,4,5,6)
- }
+ It "Can use set-variable via streaming and append values" {
+ $testVar = 1
+ 4..6 | Set-Variable -Name testVar -Append
+ $testVar | Should -Be @(1,4,5,6)
+ }
}
}
diff --git a/test/powershell/dsc/dsc.profileresource.Tests.ps1 b/test/powershell/dsc/dsc.profileresource.Tests.ps1
new file mode 100644
index 00000000000..cb357c7350b
--- /dev/null
+++ b/test/powershell/dsc/dsc.profileresource.Tests.ps1
@@ -0,0 +1,214 @@
+# Copyright (c) Microsoft Corporation.
+# Licensed under the MIT License.
+
+Describe "DSC PowerShell Profile Resource Tests" -Tag "CI" {
+ BeforeAll {
+ $DSC_ROOT = $env:DSC_ROOT
+ $skipCleanup = $false
+
+ if (-not (Test-Path -Path $DSC_ROOT)) {
+ $skipCleanup = $true
+ throw "DSC_ROOT environment variable is not set or path does not exist."
+ }
+
+ Write-Verbose "DSC_ROOT is set to $DSC_ROOT" -Verbose
+
+ $originalPath = $env:PATH
+
+ $pathSeparator = [System.IO.Path]::PathSeparator
+ $env:PATH += "$pathSeparator$DSC_ROOT"
+ $env:PATH += "$pathSeparator$PSHome"
+
+ Write-Verbose "Updated PATH to include DSC_ROOT: $env:PATH" -Verbose
+
+ # Ensure DSC v3 is available
+ if (-not (Get-Command -name dsc -CommandType Application -ErrorAction SilentlyContinue)) {
+ Get-ChildItem $DSC_ROOT -Recurse 'dsc' | ForEach-Object {
+ Write-Verbose "Found DSC executable at $($_.FullName)" -Verbose
+ }
+ throw "DSC v3 is not installed"
+ }
+
+ $dscExe = Get-Command -name dsc -CommandType Application | Select-Object -First 1
+
+ $testProfileContent = "# Test profile content currentuser currenthost"
+ $testProfilePathCurrentUserCurrentHost = $PROFILE.CurrentUserCurrentHost
+ Copy-Item -Path $testProfilePathCurrentUserCurrentHost -Destination "$TestDrive/currentuser-currenthost-profile.bak" -Force -ErrorAction SilentlyContinue
+ New-Item -Path $testProfilePathCurrentUserCurrentHost -Value $testProfileContent -Force -ItemType File
+
+ $testProfileContent = "# Test profile content currentuser allhosts"
+ $testProfilePathCurrentUserAllHosts = $PROFILE.CurrentUserAllHosts
+ Copy-Item -Path $testProfilePathCurrentUserAllHosts -Destination "$TestDrive/currentuser-allhosts-profile.bak" -Force -ErrorAction SilentlyContinue
+ New-Item -Path $testProfilePathCurrentUserAllHosts -Value $testProfileContent -Force -ItemType File
+ }
+ AfterAll {
+ if ($skipCleanup) {
+ return
+ }
+
+ # Restore original profile
+ $testProfilePathCurrentUserCurrentHost = $PROFILE.CurrentUserCurrentHost
+ if (Test-Path "$TestDrive/currentuser-currenthost-profile.bak") {
+ Copy-Item -Path "$TestDrive/currentuser-currenthost-profile.bak" -Destination $testProfilePathCurrentUserCurrentHost -Force -ErrorAction SilentlyContinue
+ }
+ else {
+ Remove-Item $testProfilePathCurrentUserCurrentHost -Force -ErrorAction SilentlyContinue
+ }
+
+ $testProfilePathCurrentUserAllHosts = $PROFILE.CurrentUserAllHosts
+ if (Test-Path "$TestDrive/currentuser-allhosts-profile.bak") {
+ Copy-Item -Path "$TestDrive/currentuser-allhosts-profile.bak" -Destination $testProfilePathCurrentUserAllHosts -Force -ErrorAction SilentlyContinue
+ }
+ else {
+ Remove-Item $testProfilePathCurrentUserAllHosts -Force -ErrorAction SilentlyContinue
+ }
+
+ $env:PATH = $originalPath
+ Remove-Item -Path "$TestDrive/currentuser-currenthost-profile.bak" -Force -ErrorAction SilentlyContinue
+ Remove-Item -Path "$TestDrive/currentuser-allhosts-profile.bak" -Force -ErrorAction SilentlyContinue
+ }
+
+ It 'DSC resource is located at $PSHome' {
+ $resourceFile = Join-Path -Path $PSHome -ChildPath 'pwsh.profile.resource.ps1'
+ $resourceFile | Should -Exist
+
+ $resourceManifest = Join-Path -Path $PSHome -ChildPath 'pwsh.profile.dsc.resource.json'
+ $resourceManifest | Should -Exist
+ }
+
+ It 'DSC resource can be found' {
+ (& $dscExe resource list -o json | ConvertFrom-Json | Select-Object -Property type).type | Should -Contain 'Microsoft.PowerShell/Profile'
+ }
+
+ It 'DSC resource can set current user current host profile' {
+ $setOutput = (& $dscExe config set --file $PSScriptRoot/psprofile_currentuser_currenthost.dsc.yaml -o json) | ConvertFrom-Json
+ $expectedContent = "Write-Host 'Welcome to your PowerShell profile - CurrentUserCurrentHost!'"
+ $setOutput.results.result.afterState.content | Should -BeExactly $expectedContent
+ }
+
+ It 'DSC resource can get current user current host profile' {
+ $getOutput = (& $dscExe config get --file $PSScriptRoot/psprofile_currentuser_currenthost.dsc.yaml -o json) | ConvertFrom-Json
+ $expectedContent = "Write-Host 'Welcome to your PowerShell profile - CurrentUserCurrentHost!'"
+ $getOutput.results.result.actualState.content | Should -BeExactly $expectedContent
+ }
+
+ It 'DSC resource can set content as empty for current user current host profile' -Pending {
+ $setOutput = (& $dscExe config set --file $PSScriptRoot/psprofile_currentuser_currenthost_emptycontent.dsc.yaml -o json) | ConvertFrom-Json
+ $setOutput.results.result.afterState.content | Should -BeExactly ''
+ }
+
+ It 'DSC resource can set current user all hosts profile' {
+ $setOutput = (& $dscExe config set --file $PSScriptRoot/psprofile_currentuser_allhosts.dsc.yaml -o json) | ConvertFrom-Json
+ $expectedContent = "Write-Host 'Welcome to your PowerShell profile - CurrentUserAllHosts!'"
+ $setOutput.results.result.afterState.content | Should -BeExactly $expectedContent
+ }
+
+ It 'DSC resource can get current user all hosts profile' {
+ $getOutput = (& $dscExe config get --file $PSScriptRoot/psprofile_currentuser_allhosts.dsc.yaml -o json) | ConvertFrom-Json
+ $expectedContent = "Write-Host 'Welcome to your PowerShell profile - CurrentUserAllHosts!'"
+ $getOutput.results.result.actualState.content | Should -BeExactly $expectedContent
+ }
+
+ It 'DSC resource can export all profiles' {
+ $exportOutput = (& $dscExe config export --file $PSScriptRoot/psprofile_export.dsc.yaml -o json) | ConvertFrom-Json
+
+ $exportOutput.resources | Should -HaveCount 4
+
+ $exportOutput.resources | ForEach-Object {
+ $_.type | Should -Be 'Microsoft.PowerShell/Profile'
+ $_.name | Should -BeIn @('AllUsersCurrentHost', 'AllUsersAllHosts', 'CurrentUserCurrentHost', 'CurrentUserAllHosts')
+ }
+ }
+}
+
+Describe "DSC PowerShell Profile resource elevated tests" -Tag "CI", 'RequireAdminOnWindows', 'RequireSudoOnUnix' {
+ BeforeAll {
+ $DSC_ROOT = $env:DSC_ROOT
+ $skipCleanup = $false
+
+ if (-not (Test-Path -Path $DSC_ROOT)) {
+ $skipCleanup = $true
+ throw "DSC_ROOT environment variable is not set or path does not exist."
+ }
+
+ Write-Verbose "DSC_ROOT is set to $DSC_ROOT" -Verbose
+
+ $originalPath = $env:PATH
+
+ $pathSeparator = [System.IO.Path]::PathSeparator
+ $env:PATH += "$pathSeparator$DSC_ROOT"
+ $env:PATH += "$pathSeparator$PSHome"
+
+ Write-Verbose "Updated PATH to include DSC_ROOT: $env:PATH" -Verbose
+
+ # Ensure DSC v3 is available
+ if (-not (Get-Command -name dsc -CommandType Application -ErrorAction SilentlyContinue)) {
+ Get-ChildItem $DSC_ROOT -Recurse 'dsc' | ForEach-Object {
+ Write-Verbose "Found DSC executable at $($_.FullName)" -Verbose
+ }
+ throw "DSC v3 is not installed"
+ }
+
+ $dscExe = Get-Command -name dsc -CommandType Application | Select-Object -First 1
+
+ $testProfileContent = "# Test profile content allusers currenthost"
+ $testProfilePathAllUsersCurrentHost = $PROFILE.AllUsersCurrentHost
+ Copy-Item -Path $testProfilePathAllUsersCurrentHost -Destination "$TestDrive/allusers-currenthost-profile.bak" -Force -ErrorAction SilentlyContinue
+ New-Item -Path $testProfilePathAllUsersCurrentHost -Value $testProfileContent -Force -ItemType File
+
+ $testProfileContent = "# Test profile content allusers allhosts"
+ $testProfilePathAllUsersAllHosts = $PROFILE.AllUsersAllHosts
+ Copy-Item -Path $testProfilePathAllUsersAllHosts -Destination "$TestDrive/allusers-allhosts-profile.bak" -Force -ErrorAction SilentlyContinue
+ New-Item -Path $testProfilePathAllUsersAllHosts -Value $testProfileContent -Force -ItemType File
+ }
+ AfterAll {
+ if ($skipCleanup) {
+ return
+ }
+
+ $env:PATH = $originalPath
+
+ $testProfilePathAllUsersCurrentHost = $PROFILE.AllUsersCurrentHost
+ if (Test-Path "$TestDrive/allusers-currenthost-profile.bak") {
+ Copy-Item -Path "$TestDrive/allusers-currenthost-profile.bak" -Destination $testProfilePathAllUsersCurrentHost -Force -ErrorAction SilentlyContinue
+ }
+ else {
+ Remove-Item $testProfilePathAllUsersCurrentHost -Force -ErrorAction SilentlyContinue
+ }
+
+ $testProfilePathAllUsersAllHosts = $PROFILE.AllUsersAllHosts
+ if (Test-Path "$TestDrive/allusers-allhosts-profile.bak") {
+ Copy-Item -Path "$TestDrive/allusers-allhosts-profile.bak" -Destination $testProfilePathAllUsersAllHosts -Force -ErrorAction SilentlyContinue
+ }
+ else {
+ Remove-Item $testProfilePathAllUsersAllHosts -Force -ErrorAction SilentlyContinue
+ }
+
+ Remove-Item -Path "$TestDrive/currentuser-allhosts-profile.bak" -Force -ErrorAction SilentlyContinue
+ Remove-Item -Path "$TestDrive/allusers-allhosts-profile.bak" -Force -ErrorAction SilentlyContinue
+ }
+
+ It 'DSC resource can set all users all hosts profile' {
+ $setOutput = (& $dscExe config set --file $PSScriptRoot/psprofile_alluser_allhost.dsc.yaml -o json) | ConvertFrom-Json
+ $expectedContent = "Write-Host 'Welcome to your PowerShell profile - AllUsersAllHosts!'"
+ $setOutput.results.result.afterState.content | Should -BeExactly $expectedContent
+ }
+
+ It 'DSC resource can get all users all hosts profile' {
+ $getOutput = (& $dscExe config get --file $PSScriptRoot/psprofile_alluser_allhost.dsc.yaml -o json) | ConvertFrom-Json
+ $expectedContent = "Write-Host 'Welcome to your PowerShell profile - AllUsersAllHosts!'"
+ $getOutput.results.result.actualState.content | Should -BeExactly $expectedContent
+ }
+
+ It 'DSC resource can set all users current hosts profile' {
+ $setOutput = (& $dscExe config set --file $PSScriptRoot/psprofile_allusers_currenthost.dsc.yaml -o json) | ConvertFrom-Json
+ $expectedContent = "Write-Host 'Welcome to your PowerShell profile - AllUsersCurrentHost!'"
+ $setOutput.results.result.afterState.content | Should -BeExactly $expectedContent
+ }
+
+ It 'DSC resource can get all users current hosts profile' {
+ $getOutput = (& $dscExe config get --file $PSScriptRoot/psprofile_allusers_currenthost.dsc.yaml -o json) | ConvertFrom-Json
+ $expectedContent = "Write-Host 'Welcome to your PowerShell profile - AllUsersCurrentHost!'"
+ $getOutput.results.result.actualState.content | Should -BeExactly $expectedContent
+ }
+}
diff --git a/test/powershell/dsc/psprofile_alluser_allhost.dsc.yaml b/test/powershell/dsc/psprofile_alluser_allhost.dsc.yaml
new file mode 100644
index 00000000000..356119826c3
--- /dev/null
+++ b/test/powershell/dsc/psprofile_alluser_allhost.dsc.yaml
@@ -0,0 +1,9 @@
+# Set PowerShell profile content
+$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
+resources:
+- name: PSProfile
+ type: Microsoft.PowerShell/Profile
+ properties:
+ profileType: AllUsersAllHosts
+ content: "Write-Host 'Welcome to your PowerShell profile - AllUsersAllHosts!'"
+ _exist: true
diff --git a/test/powershell/dsc/psprofile_allusers_currenthost.dsc.yaml b/test/powershell/dsc/psprofile_allusers_currenthost.dsc.yaml
new file mode 100644
index 00000000000..bc51f0a4392
--- /dev/null
+++ b/test/powershell/dsc/psprofile_allusers_currenthost.dsc.yaml
@@ -0,0 +1,9 @@
+# Set PowerShell profile content
+$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
+resources:
+- name: PSProfile
+ type: Microsoft.PowerShell/Profile
+ properties:
+ profileType: AllUsersCurrentHost
+ content: "Write-Host 'Welcome to your PowerShell profile - AllUsersCurrentHost!'"
+ _exist: true
diff --git a/test/powershell/dsc/psprofile_currentuser_allhosts.dsc.yaml b/test/powershell/dsc/psprofile_currentuser_allhosts.dsc.yaml
new file mode 100644
index 00000000000..8ed8d98c3ab
--- /dev/null
+++ b/test/powershell/dsc/psprofile_currentuser_allhosts.dsc.yaml
@@ -0,0 +1,9 @@
+# Set PowerShell profile content
+$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
+resources:
+- name: PSProfile
+ type: Microsoft.PowerShell/Profile
+ properties:
+ profileType: CurrentUserAllHosts
+ content: "Write-Host 'Welcome to your PowerShell profile - CurrentUserAllHosts!'"
+ _exist: true
diff --git a/test/powershell/dsc/psprofile_currentuser_currenthost.dsc.yaml b/test/powershell/dsc/psprofile_currentuser_currenthost.dsc.yaml
new file mode 100644
index 00000000000..5a42c28eb96
--- /dev/null
+++ b/test/powershell/dsc/psprofile_currentuser_currenthost.dsc.yaml
@@ -0,0 +1,9 @@
+# Set PowerShell profile content
+$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
+resources:
+- name: PSProfile
+ type: Microsoft.PowerShell/Profile
+ properties:
+ profileType: CurrentUserCurrentHost
+ content: "Write-Host 'Welcome to your PowerShell profile - CurrentUserCurrentHost!'"
+ _exist: true
diff --git a/test/powershell/dsc/psprofile_currentuser_currenthost_emptycontent.yaml b/test/powershell/dsc/psprofile_currentuser_currenthost_emptycontent.yaml
new file mode 100644
index 00000000000..76439387d2e
--- /dev/null
+++ b/test/powershell/dsc/psprofile_currentuser_currenthost_emptycontent.yaml
@@ -0,0 +1,9 @@
+# Set PowerShell profile content
+$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
+resources:
+- name: PSProfile
+ type: Microsoft.PowerShell/Profile
+ properties:
+ profileType: CurrentUserCurrentHost
+ content: ''
+ _exist: true
diff --git a/test/powershell/dsc/psprofile_export.dsc.yaml b/test/powershell/dsc/psprofile_export.dsc.yaml
new file mode 100644
index 00000000000..cf7881b5df8
--- /dev/null
+++ b/test/powershell/dsc/psprofile_export.dsc.yaml
@@ -0,0 +1,5 @@
+# Set PowerShell profile content
+$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
+resources:
+- name: PSProfile
+ type: Microsoft.PowerShell/Profile
diff --git a/test/powershell/engine/Basic/DefaultCommands.Tests.ps1 b/test/powershell/engine/Basic/DefaultCommands.Tests.ps1
index 312c34b6706..7a757e6eac4 100644
--- a/test/powershell/engine/Basic/DefaultCommands.Tests.ps1
+++ b/test/powershell/engine/Basic/DefaultCommands.Tests.ps1
@@ -337,6 +337,7 @@ Describe "Verify aliases and cmdlets" -Tags "CI" {
"Cmdlet", "Get-PSSessionCapability", "", $($FullCLR -or $CoreWindows ), "", "", "None"
"Cmdlet", "Get-PSSessionConfiguration", "", $($FullCLR -or $CoreWindows ), "", "", "None"
"Cmdlet", "Get-PSSnapin", "", $($FullCLR ), "", "", ""
+"Cmdlet", "Get-PSSubsystem", "", $( $CoreWindows -or $CoreUnix), "", "", "None"
"Cmdlet", "Get-Random", "", $($FullCLR -or $CoreWindows -or $CoreUnix), "", "", "None"
"Cmdlet", "Get-Runspace", "", $($FullCLR -or $CoreWindows -or $CoreUnix), "", "", "None"
"Cmdlet", "Get-RunspaceDebug", "", $($FullCLR -or $CoreWindows -or $CoreUnix), "", "", "None"
diff --git a/test/powershell/engine/Remoting/SSHRemotingCmdlets.Tests.ps1 b/test/powershell/engine/Remoting/SSHRemotingCmdlets.Tests.ps1
index 1568d284d0f..c1090bdc186 100644
--- a/test/powershell/engine/Remoting/SSHRemotingCmdlets.Tests.ps1
+++ b/test/powershell/engine/Remoting/SSHRemotingCmdlets.Tests.ps1
@@ -70,3 +70,24 @@ Describe "SSHConnection parameter hashtable type conversions" -Tags 'Feature', '
$err.FullyQualifiedErrorId | Should -Match 'PSSessionOpenFailed'
}
}
+
+Describe "No hangs when host doesn't exist" -Tags "CI" {
+ $testCases = @(
+ @{
+ Name = 'Verifies no hang for New-PSSession with non-existing host name'
+ ScriptBlock = { New-PSSession -HostName "test-notexist" -UserName "test" -ErrorAction Stop }
+ FullyQualifiedErrorId = 'PSSessionOpenFailed'
+ },
+ @{
+ Name = 'Verifies no hang for Invoke-Command with non-existing host name'
+ ScriptBlock = { Invoke-Command -HostName "test-notexist" -UserName "test" -ScriptBlock { 1 } -ErrorAction Stop }
+ FullyQualifiedErrorId = 'PSSessionStateBroken'
+ }
+ )
+
+ It "" -TestCases $testCases {
+ param ($ScriptBlock, $FullyQualifiedErrorId)
+
+ $ScriptBlock | Should -Throw -ErrorId $FullyQualifiedErrorId -ExceptionType 'System.Management.Automation.Remoting.PSRemotingTransportException'
+ }
+}
diff --git a/test/tools/TestAlc/nested/Test.Isolated.Nested.csproj b/test/tools/TestAlc/nested/Test.Isolated.Nested.csproj
index 10c707c176a..886b5f11826 100644
--- a/test/tools/TestAlc/nested/Test.Isolated.Nested.csproj
+++ b/test/tools/TestAlc/nested/Test.Isolated.Nested.csproj
@@ -19,7 +19,7 @@
-
+
diff --git a/test/tools/TestMetadata.json b/test/tools/TestMetadata.json
index bd716ccec7b..19ffb93ce92 100644
--- a/test/tools/TestMetadata.json
+++ b/test/tools/TestMetadata.json
@@ -1,9 +1,6 @@
{
"ExperimentalFeatures": {
"ExpTest.FeatureOne": [ "test/powershell/engine/ExperimentalFeature/ExperimentalFeature.Basic.Tests.ps1" ],
- "PSCultureInvariantReplaceOperator": [ "test/powershell/Language/Operators/ReplaceOperator.Tests.ps1" ],
- "Microsoft.PowerShell.Utility.PSManageBreakpointsInRunspace": [ "test/powershell/Modules/Microsoft.PowerShell.Utility/RunspaceBreakpointManagement.Tests.ps1" ],
- "PSNativeWindowsTildeExpansion": [ "test/powershell/Language/Scripting/NativeExecution/NativeWindowsTildeExpansion.Tests.ps1" ],
"PSSerializeJSONLongEnumAsNumber": [ "test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertTo-Json.PSSerializeJSONLongEnumAsNumber.Tests.ps1" ]
}
}
diff --git a/test/tools/TestService/TestService.csproj b/test/tools/TestService/TestService.csproj
index f50e3bccf60..15a6e49864c 100644
--- a/test/tools/TestService/TestService.csproj
+++ b/test/tools/TestService/TestService.csproj
@@ -15,7 +15,7 @@
-
+
diff --git a/test/tools/WebListener/WebListener.csproj b/test/tools/WebListener/WebListener.csproj
index 46638197255..1dddf99ba5e 100644
--- a/test/tools/WebListener/WebListener.csproj
+++ b/test/tools/WebListener/WebListener.csproj
@@ -7,6 +7,6 @@
-
+
diff --git a/test/xUnit/xUnit.tests.csproj b/test/xUnit/xUnit.tests.csproj
index 33f0a2dde00..0863a23d441 100644
--- a/test/xUnit/xUnit.tests.csproj
+++ b/test/xUnit/xUnit.tests.csproj
@@ -29,8 +29,8 @@
runtime; build; native; contentfiles; analyzers; buildtransitiveall
-
-
+
+
diff --git a/tools/cgmanifest.json b/tools/cgmanifest.json
index 11c7447ff7d..d8165298b22 100644
--- a/tools/cgmanifest.json
+++ b/tools/cgmanifest.json
@@ -1,4 +1,5 @@
{
+ "$schema": "https://json.schemastore.org/component-detection-manifest.json",
"Registrations": [
{
"Component": {
@@ -65,7 +66,7 @@
"Type": "nuget",
"Nuget": {
"Name": "Markdig.Signed",
- "Version": "0.42.0"
+ "Version": "0.43.0"
}
},
"DevelopmentDependency": false
@@ -85,7 +86,7 @@
"Type": "nuget",
"Nuget": {
"Name": "Microsoft.Bcl.AsyncInterfaces",
- "Version": "9.0.9"
+ "Version": "10.0.0"
}
},
"DevelopmentDependency": false
@@ -125,7 +126,7 @@
"Type": "nuget",
"Nuget": {
"Name": "Microsoft.Extensions.ObjectPool",
- "Version": "9.0.9"
+ "Version": "10.0.0"
}
},
"DevelopmentDependency": false
@@ -165,7 +166,7 @@
"Type": "nuget",
"Nuget": {
"Name": "Microsoft.Win32.Registry.AccessControl",
- "Version": "9.0.9"
+ "Version": "10.0.0"
}
},
"DevelopmentDependency": false
@@ -175,7 +176,7 @@
"Type": "nuget",
"Nuget": {
"Name": "Microsoft.Win32.SystemEvents",
- "Version": "9.0.9"
+ "Version": "10.0.0"
}
},
"DevelopmentDependency": false
@@ -185,7 +186,7 @@
"Type": "nuget",
"Nuget": {
"Name": "Microsoft.Windows.Compatibility",
- "Version": "9.0.9"
+ "Version": "10.0.0"
}
},
"DevelopmentDependency": false
@@ -205,7 +206,7 @@
"Type": "nuget",
"Nuget": {
"Name": "runtime.android-arm.runtime.native.System.IO.Ports",
- "Version": "9.0.9"
+ "Version": "10.0.0"
}
},
"DevelopmentDependency": false
@@ -215,7 +216,7 @@
"Type": "nuget",
"Nuget": {
"Name": "runtime.android-arm64.runtime.native.System.IO.Ports",
- "Version": "9.0.9"
+ "Version": "10.0.0"
}
},
"DevelopmentDependency": false
@@ -225,7 +226,7 @@
"Type": "nuget",
"Nuget": {
"Name": "runtime.android-x64.runtime.native.System.IO.Ports",
- "Version": "9.0.9"
+ "Version": "10.0.0"
}
},
"DevelopmentDependency": false
@@ -235,7 +236,7 @@
"Type": "nuget",
"Nuget": {
"Name": "runtime.android-x86.runtime.native.System.IO.Ports",
- "Version": "9.0.9"
+ "Version": "10.0.0"
}
},
"DevelopmentDependency": false
@@ -245,7 +246,7 @@
"Type": "nuget",
"Nuget": {
"Name": "runtime.linux-arm.runtime.native.System.IO.Ports",
- "Version": "9.0.9"
+ "Version": "10.0.0"
}
},
"DevelopmentDependency": false
@@ -255,7 +256,7 @@
"Type": "nuget",
"Nuget": {
"Name": "runtime.linux-arm64.runtime.native.System.IO.Ports",
- "Version": "9.0.9"
+ "Version": "10.0.0"
}
},
"DevelopmentDependency": false
@@ -265,7 +266,7 @@
"Type": "nuget",
"Nuget": {
"Name": "runtime.linux-bionic-arm64.runtime.native.System.IO.Ports",
- "Version": "9.0.9"
+ "Version": "10.0.0"
}
},
"DevelopmentDependency": false
@@ -275,7 +276,7 @@
"Type": "nuget",
"Nuget": {
"Name": "runtime.linux-bionic-x64.runtime.native.System.IO.Ports",
- "Version": "9.0.9"
+ "Version": "10.0.0"
}
},
"DevelopmentDependency": false
@@ -285,7 +286,7 @@
"Type": "nuget",
"Nuget": {
"Name": "runtime.linux-musl-arm.runtime.native.System.IO.Ports",
- "Version": "9.0.9"
+ "Version": "10.0.0"
}
},
"DevelopmentDependency": false
@@ -295,7 +296,7 @@
"Type": "nuget",
"Nuget": {
"Name": "runtime.linux-musl-arm64.runtime.native.System.IO.Ports",
- "Version": "9.0.9"
+ "Version": "10.0.0"
}
},
"DevelopmentDependency": false
@@ -305,7 +306,7 @@
"Type": "nuget",
"Nuget": {
"Name": "runtime.linux-musl-x64.runtime.native.System.IO.Ports",
- "Version": "9.0.9"
+ "Version": "10.0.0"
}
},
"DevelopmentDependency": false
@@ -315,7 +316,7 @@
"Type": "nuget",
"Nuget": {
"Name": "runtime.linux-x64.runtime.native.System.IO.Ports",
- "Version": "9.0.9"
+ "Version": "10.0.0"
}
},
"DevelopmentDependency": false
@@ -325,7 +326,7 @@
"Type": "nuget",
"Nuget": {
"Name": "runtime.maccatalyst-arm64.runtime.native.System.IO.Ports",
- "Version": "9.0.9"
+ "Version": "10.0.0"
}
},
"DevelopmentDependency": false
@@ -335,7 +336,7 @@
"Type": "nuget",
"Nuget": {
"Name": "runtime.maccatalyst-x64.runtime.native.System.IO.Ports",
- "Version": "9.0.9"
+ "Version": "10.0.0"
}
},
"DevelopmentDependency": false
@@ -355,7 +356,7 @@
"Type": "nuget",
"Nuget": {
"Name": "runtime.native.System.IO.Ports",
- "Version": "9.0.9"
+ "Version": "10.0.0"
}
},
"DevelopmentDependency": false
@@ -365,7 +366,7 @@
"Type": "nuget",
"Nuget": {
"Name": "runtime.osx-arm64.runtime.native.System.IO.Ports",
- "Version": "9.0.9"
+ "Version": "10.0.0"
}
},
"DevelopmentDependency": false
@@ -375,7 +376,7 @@
"Type": "nuget",
"Nuget": {
"Name": "runtime.osx-x64.runtime.native.System.IO.Ports",
- "Version": "9.0.9"
+ "Version": "10.0.0"
}
},
"DevelopmentDependency": false
@@ -435,7 +436,7 @@
"Type": "nuget",
"Nuget": {
"Name": "System.CodeDom",
- "Version": "9.0.9"
+ "Version": "10.0.0"
}
},
"DevelopmentDependency": false
@@ -445,7 +446,7 @@
"Type": "nuget",
"Nuget": {
"Name": "System.ComponentModel.Composition.Registration",
- "Version": "9.0.9"
+ "Version": "10.0.0"
}
},
"DevelopmentDependency": false
@@ -455,7 +456,7 @@
"Type": "nuget",
"Nuget": {
"Name": "System.ComponentModel.Composition",
- "Version": "9.0.9"
+ "Version": "10.0.0"
}
},
"DevelopmentDependency": false
@@ -465,7 +466,7 @@
"Type": "nuget",
"Nuget": {
"Name": "System.Configuration.ConfigurationManager",
- "Version": "9.0.9"
+ "Version": "10.0.0"
}
},
"DevelopmentDependency": false
@@ -475,7 +476,7 @@
"Type": "nuget",
"Nuget": {
"Name": "System.Data.Odbc",
- "Version": "9.0.9"
+ "Version": "10.0.0"
}
},
"DevelopmentDependency": false
@@ -485,7 +486,7 @@
"Type": "nuget",
"Nuget": {
"Name": "System.Data.OleDb",
- "Version": "9.0.9"
+ "Version": "10.0.0"
}
},
"DevelopmentDependency": false
@@ -505,7 +506,7 @@
"Type": "nuget",
"Nuget": {
"Name": "System.Diagnostics.EventLog",
- "Version": "9.0.9"
+ "Version": "10.0.0"
}
},
"DevelopmentDependency": false
@@ -515,7 +516,7 @@
"Type": "nuget",
"Nuget": {
"Name": "System.Diagnostics.PerformanceCounter",
- "Version": "9.0.9"
+ "Version": "10.0.0"
}
},
"DevelopmentDependency": false
@@ -525,7 +526,7 @@
"Type": "nuget",
"Nuget": {
"Name": "System.DirectoryServices.AccountManagement",
- "Version": "9.0.9"
+ "Version": "10.0.0"
}
},
"DevelopmentDependency": false
@@ -535,7 +536,7 @@
"Type": "nuget",
"Nuget": {
"Name": "System.DirectoryServices.Protocols",
- "Version": "9.0.9"
+ "Version": "10.0.0"
}
},
"DevelopmentDependency": false
@@ -545,7 +546,7 @@
"Type": "nuget",
"Nuget": {
"Name": "System.DirectoryServices",
- "Version": "9.0.9"
+ "Version": "10.0.0"
}
},
"DevelopmentDependency": false
@@ -555,7 +556,7 @@
"Type": "nuget",
"Nuget": {
"Name": "System.Drawing.Common",
- "Version": "9.0.9"
+ "Version": "10.0.0"
}
},
"DevelopmentDependency": false
@@ -565,7 +566,7 @@
"Type": "nuget",
"Nuget": {
"Name": "System.IO.Packaging",
- "Version": "9.0.9"
+ "Version": "10.0.0"
}
},
"DevelopmentDependency": false
@@ -575,7 +576,7 @@
"Type": "nuget",
"Nuget": {
"Name": "System.IO.Ports",
- "Version": "9.0.9"
+ "Version": "10.0.0"
}
},
"DevelopmentDependency": false
@@ -585,7 +586,7 @@
"Type": "nuget",
"Nuget": {
"Name": "System.Management",
- "Version": "9.0.9"
+ "Version": "10.0.0"
}
},
"DevelopmentDependency": false
@@ -595,17 +596,7 @@
"Type": "nuget",
"Nuget": {
"Name": "System.Net.Http.WinHttpHandler",
- "Version": "9.0.9"
- }
- },
- "DevelopmentDependency": false
- },
- {
- "Component": {
- "Type": "nuget",
- "Nuget": {
- "Name": "System.Private.ServiceModel",
- "Version": "4.10.3"
+ "Version": "10.0.0"
}
},
"DevelopmentDependency": false
@@ -615,7 +606,7 @@
"Type": "nuget",
"Nuget": {
"Name": "System.Reflection.Context",
- "Version": "9.0.9"
+ "Version": "10.0.0"
}
},
"DevelopmentDependency": false
@@ -625,7 +616,7 @@
"Type": "nuget",
"Nuget": {
"Name": "System.Runtime.Caching",
- "Version": "9.0.9"
+ "Version": "10.0.0"
}
},
"DevelopmentDependency": false
@@ -635,7 +626,7 @@
"Type": "nuget",
"Nuget": {
"Name": "System.Security.Cryptography.Pkcs",
- "Version": "9.0.9"
+ "Version": "10.0.0"
}
},
"DevelopmentDependency": false
@@ -645,7 +636,7 @@
"Type": "nuget",
"Nuget": {
"Name": "System.Security.Cryptography.ProtectedData",
- "Version": "9.0.9"
+ "Version": "10.0.0"
}
},
"DevelopmentDependency": false
@@ -655,7 +646,7 @@
"Type": "nuget",
"Nuget": {
"Name": "System.Security.Cryptography.Xml",
- "Version": "9.0.9"
+ "Version": "10.0.0"
}
},
"DevelopmentDependency": false
@@ -665,7 +656,7 @@
"Type": "nuget",
"Nuget": {
"Name": "System.Security.Permissions",
- "Version": "9.0.9"
+ "Version": "10.0.0"
}
},
"DevelopmentDependency": false
@@ -674,8 +665,8 @@
"Component": {
"Type": "nuget",
"Nuget": {
- "Name": "System.ServiceModel.Duplex",
- "Version": "4.10.3"
+ "Name": "System.ServiceModel.Http",
+ "Version": "8.1.2"
}
},
"DevelopmentDependency": false
@@ -684,8 +675,8 @@
"Component": {
"Type": "nuget",
"Nuget": {
- "Name": "System.ServiceModel.Http",
- "Version": "4.10.3"
+ "Name": "System.ServiceModel.NetFramingBase",
+ "Version": "8.1.2"
}
},
"DevelopmentDependency": false
@@ -695,7 +686,7 @@
"Type": "nuget",
"Nuget": {
"Name": "System.ServiceModel.NetTcp",
- "Version": "4.10.3"
+ "Version": "8.1.2"
}
},
"DevelopmentDependency": false
@@ -705,17 +696,7 @@
"Type": "nuget",
"Nuget": {
"Name": "System.ServiceModel.Primitives",
- "Version": "4.10.3"
- }
- },
- "DevelopmentDependency": false
- },
- {
- "Component": {
- "Type": "nuget",
- "Nuget": {
- "Name": "System.ServiceModel.Security",
- "Version": "4.10.3"
+ "Version": "8.1.2"
}
},
"DevelopmentDependency": false
@@ -725,7 +706,7 @@
"Type": "nuget",
"Nuget": {
"Name": "System.ServiceModel.Syndication",
- "Version": "9.0.9"
+ "Version": "10.0.0"
}
},
"DevelopmentDependency": false
@@ -735,7 +716,7 @@
"Type": "nuget",
"Nuget": {
"Name": "System.ServiceProcess.ServiceController",
- "Version": "9.0.9"
+ "Version": "10.0.0"
}
},
"DevelopmentDependency": false
@@ -745,17 +726,7 @@
"Type": "nuget",
"Nuget": {
"Name": "System.Speech",
- "Version": "9.0.9"
- }
- },
- "DevelopmentDependency": false
- },
- {
- "Component": {
- "Type": "nuget",
- "Nuget": {
- "Name": "System.Threading.AccessControl",
- "Version": "9.0.9"
+ "Version": "10.0.0"
}
},
"DevelopmentDependency": false
@@ -775,11 +746,10 @@
"Type": "nuget",
"Nuget": {
"Name": "System.Windows.Extensions",
- "Version": "9.0.9"
+ "Version": "10.0.0"
}
},
"DevelopmentDependency": false
}
- ],
- "$schema": "https://json.schemastore.org/component-detection-manifest.json"
+ ]
}
diff --git a/tools/ci.psm1 b/tools/ci.psm1
index 7b13ded1811..9090e11a19a 100644
--- a/tools/ci.psm1
+++ b/tools/ci.psm1
@@ -101,6 +101,11 @@ function Invoke-CIFull
# Implements the CI 'build_script' step
function Invoke-CIBuild
{
+ param(
+ [ValidateSet('Debug', 'Release', 'CodeCoverage', 'StaticAnalysis')]
+ [string]$Configuration = 'Release'
+ )
+
$releaseTag = Get-ReleaseTag
# check to be sure our test tags are correct
$result = Get-PesterTag
@@ -115,7 +120,7 @@ function Invoke-CIBuild
Start-PSBuild -Configuration 'CodeCoverage' -PSModuleRestore -CI -ReleaseTag $releaseTag
}
- Start-PSBuild -PSModuleRestore -Configuration 'Release' -CI -ReleaseTag $releaseTag -UseNuGetOrg
+ Start-PSBuild -PSModuleRestore -Configuration $Configuration -CI -ReleaseTag $releaseTag -UseNuGetOrg
Save-PSOptions
$options = (Get-PSOptions)
@@ -223,6 +228,45 @@ function Invoke-CIxUnit
}
}
+# Install Pester module if not already installed with a compatible version
+function Install-CIPester
+{
+ [CmdletBinding()]
+ param(
+ [string]$MinimumVersion = '5.0.0',
+ [string]$MaximumVersion = '5.99.99',
+ [switch]$Force
+ )
+
+ Write-Verbose "Checking for Pester module (required: $MinimumVersion - $MaximumVersion)" -Verbose
+
+ # Check if a compatible version of Pester is already installed
+ $installedPester = Get-Module -Name Pester -ListAvailable |
+ Where-Object { $_.Version -ge $MinimumVersion -and $_.Version -le $MaximumVersion } |
+ Sort-Object -Property Version -Descending |
+ Select-Object -First 1
+
+ if ($installedPester -and -not $Force) {
+ Write-Host "Pester version $($installedPester.Version) is already installed and meets requirements" -ForegroundColor Green
+ return
+ }
+
+ if ($Force) {
+ Write-Host "Installing Pester module (forced)" -ForegroundColor Yellow
+ } else {
+ Write-Host "Installing Pester module" -ForegroundColor Yellow
+ }
+
+ try {
+ Install-Module -Name Pester -Force -SkipPublisherCheck -MaximumVersion $MaximumVersion -ErrorAction Stop
+ Write-Host "Successfully installed Pester module" -ForegroundColor Green
+ }
+ catch {
+ Write-Error "Failed to install Pester module: $_"
+ throw
+ }
+}
+
# Implement CI 'Test_script'
function Invoke-CITest
{
@@ -616,7 +660,7 @@ function Invoke-CIFinish
# Install the latest Pester and import it
$maximumPesterVersion = '4.99'
- Install-Module Pester -Force -SkipPublisherCheck -MaximumVersion $maximumPesterVersion
+ Install-CIPester -MinimumVersion '4.0.0' -MaximumVersion $maximumPesterVersion -Force
Import-Module Pester -Force -MaximumVersion $maximumPesterVersion
$testResultPath = Join-Path -Path $env:TEMP -ChildPath "win-package-$channel-$runtime.xml"
@@ -683,6 +727,14 @@ function Set-Path
}
}
+# Display environment variables in a log group for GitHub Actions
+function Show-Environment
+{
+ Write-LogGroupStart -Title 'Environment'
+ Get-ChildItem -Path env: | Out-String -width 9999 -Stream | Write-Verbose -Verbose
+ Write-LogGroupEnd -Title 'Environment'
+}
+
# Bootstrap script for Linux and macOS
function Invoke-BootstrapStage
{
@@ -874,16 +926,36 @@ function New-LinuxPackage
$packageObj = $package
}
- Write-Log -message "Artifacts directory: ${env:BUILD_ARTIFACTSTAGINGDIRECTORY}"
- Copy-Item $packageObj.FullName -Destination "${env:BUILD_ARTIFACTSTAGINGDIRECTORY}" -Force
+ # Determine artifacts directory (GitHub Actions or Azure DevOps)
+ $artifactsDir = if ($env:GITHUB_ACTIONS -eq 'true') {
+ "${env:GITHUB_WORKSPACE}/../packages"
+ } else {
+ "${env:BUILD_ARTIFACTSTAGINGDIRECTORY}"
+ }
+
+ # Ensure artifacts directory exists
+ if (-not (Test-Path $artifactsDir)) {
+ New-Item -ItemType Directory -Path $artifactsDir -Force | Out-Null
+ }
+
+ Write-Log -message "Artifacts directory: $artifactsDir"
+ Copy-Item $packageObj.FullName -Destination $artifactsDir -Force
}
if ($IsLinux)
{
+ # Determine artifacts directory (GitHub Actions or Azure DevOps)
+ $artifactsDir = if ($env:GITHUB_ACTIONS -eq 'true') {
+ "${env:GITHUB_WORKSPACE}/../packages"
+ } else {
+ "${env:BUILD_ARTIFACTSTAGINGDIRECTORY}"
+ }
+
# Create and package Raspbian .tgz
+ # Build must be clean for Raspbian
Start-PSBuild -PSModuleRestore -Clean -Runtime linux-arm -Configuration 'Release'
$armPackage = Start-PSPackage @packageParams -Type tar-arm -SkipReleaseChecks
- Copy-Item $armPackage -Destination "${env:BUILD_ARTIFACTSTAGINGDIRECTORY}" -Force
+ Copy-Item $armPackage -Destination $artifactsDir -Force
}
}
@@ -939,8 +1011,230 @@ function Invoke-InitializeContainerStage {
Write-Host "##vso[build.updatebuildnumber]PR-${env:SYSTEM_PULLREQUEST_PULLREQUESTNUMBER}-$($selectedImage.JobName)-$((get-date).ToString("yyyyMMddhhmmss"))"
} else {
Write-Host "##vso[build.updatebuildnumber]${env:BUILD_SOURCEBRANCHNAME}-$($selectedImage.JobName)-${env:BUILD_SOURCEVERSION}-$((get-date).ToString("yyyyMMddhhmmss"))"
-
# Cannot do this for a PR
Write-Host "##vso[build.addbuildtag]$($selectedImage.JobName)"
}
}
+
+Function Test-MergeConflictMarker
+{
+ <#
+ .SYNOPSIS
+ Checks files for Git merge conflict markers and outputs results for GitHub Actions.
+ .DESCRIPTION
+ Scans the specified files for Git merge conflict markers (<<<<<<<, =======, >>>>>>>)
+ and generates console output, GitHub Actions outputs, and job summary.
+ Designed for use in GitHub Actions workflows.
+ .PARAMETER File
+ Array of file paths (relative or absolute) to check for merge conflict markers.
+ .PARAMETER WorkspacePath
+ Base workspace path for resolving relative paths. Defaults to current directory.
+ .PARAMETER OutputPath
+ Path to write GitHub Actions outputs. Defaults to $env:GITHUB_OUTPUT.
+ .PARAMETER SummaryPath
+ Path to write GitHub Actions job summary. Defaults to $env:GITHUB_STEP_SUMMARY.
+ .EXAMPLE
+ Test-MergeConflictMarker -File @('file1.txt', 'file2.cs') -WorkspacePath $env:GITHUB_WORKSPACE
+ #>
+ [CmdletBinding()]
+ param(
+ [Parameter()]
+ [AllowEmptyCollection()]
+ [string[]] $File = @(),
+
+ [Parameter()]
+ [string] $WorkspacePath = $PWD,
+
+ [Parameter()]
+ [string] $OutputPath = $env:GITHUB_OUTPUT,
+
+ [Parameter()]
+ [string] $SummaryPath = $env:GITHUB_STEP_SUMMARY
+ )
+
+ Write-Host "Starting merge conflict marker check..." -ForegroundColor Cyan
+
+ # Helper function to write outputs when no files to check
+ function Write-NoFilesOutput {
+ param(
+ [string]$Message,
+ [string]$OutputPath,
+ [string]$SummaryPath
+ )
+
+ # Output results to GitHub Actions
+ if ($OutputPath) {
+ "files-checked=0" | Out-File -FilePath $OutputPath -Append -Encoding utf8
+ "conflicts-found=0" | Out-File -FilePath $OutputPath -Append -Encoding utf8
+ }
+
+ # Create GitHub Actions job summary
+ if ($SummaryPath) {
+ $summaryContent = @"
+# Merge Conflict Marker Check Results
+
+## Summary
+- **Files Checked:** 0
+- **Files with Conflicts:** 0
+
+## ℹ️ No Files to Check
+
+$Message
+
+"@
+ $summaryContent | Out-File -FilePath $SummaryPath -Encoding utf8
+ }
+ }
+
+ # Handle empty file list (e.g., when PR only deletes files)
+ if ($File.Count -eq 0) {
+ Write-Host "No files to check (empty file list)" -ForegroundColor Yellow
+ Write-NoFilesOutput -Message "No files were provided for checking (this can happen when a PR only deletes files)." -OutputPath $OutputPath -SummaryPath $SummaryPath
+ return
+ }
+
+ # Filter out *.cs files from merge conflict checking
+ $filesToCheck = @($File | Where-Object { $_ -notlike "*.cs" })
+ $filteredCount = $File.Count - $filesToCheck.Count
+
+ if ($filteredCount -gt 0) {
+ Write-Host "Filtered out $filteredCount *.cs file(s) from merge conflict checking" -ForegroundColor Yellow
+ }
+
+ if ($filesToCheck.Count -eq 0) {
+ Write-Host "No files to check after filtering (all files were *.cs)" -ForegroundColor Yellow
+ Write-NoFilesOutput -Message "All $filteredCount file(s) were filtered out (*.cs files are excluded from merge conflict checking)." -OutputPath $OutputPath -SummaryPath $SummaryPath
+ return
+ }
+
+ Write-Host "Checking $($filesToCheck.Count) changed files for merge conflict markers" -ForegroundColor Cyan
+
+ # Convert relative paths to absolute paths for processing
+ $absolutePaths = $filesToCheck | ForEach-Object {
+ if ([System.IO.Path]::IsPathRooted($_)) {
+ $_
+ } else {
+ Join-Path $WorkspacePath $_
+ }
+ }
+
+ $filesWithConflicts = @()
+ $filesChecked = 0
+
+ foreach ($filePath in $absolutePaths) {
+ # Check if file exists (might be deleted)
+ if (-not (Test-Path $filePath)) {
+ Write-Verbose " Skipping deleted file: $filePath"
+ continue
+ }
+
+ # Skip binary files and directories
+ if ((Get-Item $filePath) -is [System.IO.DirectoryInfo]) {
+ continue
+ }
+
+ $filesChecked++
+
+ # Get relative path for display
+ $relativePath = if ($WorkspacePath -and $filePath.StartsWith($WorkspacePath)) {
+ $filePath.Substring($WorkspacePath.Length).TrimStart([System.IO.Path]::DirectorySeparatorChar, [System.IO.Path]::AltDirectorySeparatorChar)
+ } else {
+ $filePath
+ }
+
+ Write-Host " Checking: $relativePath" -ForegroundColor Gray
+
+ # Search for conflict markers using Select-String
+ try {
+ # Git conflict markers are 7 characters followed by a space or end of line
+ # Regex pattern breakdown:
+ # ^ - Matches the start of a line
+ # (<{7}|={7}|>{7}) - Matches exactly 7 consecutive '<', '=', or '>' characters (Git conflict markers)
+ # (\s|$) - Ensures the marker is followed by whitespace or end of line
+ $pattern = '^(<{7}|={7}|>{7})(\s|$)'
+ $matchedLines = Select-String -Path $filePath -Pattern $pattern -AllMatches -ErrorAction Stop
+
+ if ($matchedLines) {
+ # Collect marker details with line numbers (Select-String provides LineNumber automatically)
+ $markerDetails = @()
+
+ foreach ($match in $matchedLines) {
+ $markerDetails += [PSCustomObject]@{
+ Marker = $match.Matches[0].Groups[1].Value
+ Line = $match.LineNumber
+ }
+ }
+
+ $filesWithConflicts += [PSCustomObject]@{
+ File = $relativePath
+ MarkerDetails = $markerDetails
+ }
+
+ Write-Host " ❌ CONFLICT MARKERS FOUND in $relativePath" -ForegroundColor Red
+ foreach ($detail in $markerDetails) {
+ Write-Host " Line $($detail.Line): $($detail.Marker)" -ForegroundColor Red
+ }
+ }
+ }
+ catch {
+ # Skip files that can't be read (likely binary)
+ Write-Verbose " Skipping unreadable file: $relativePath"
+ }
+ }
+
+ # Output results to GitHub Actions
+ if ($OutputPath) {
+ "files-checked=$filesChecked" | Out-File -FilePath $OutputPath -Append -Encoding utf8
+ "conflicts-found=$($filesWithConflicts.Count)" | Out-File -FilePath $OutputPath -Append -Encoding utf8
+ }
+
+ Write-Host "`nSummary:" -ForegroundColor Cyan
+ Write-Host " Files checked: $filesChecked" -ForegroundColor Cyan
+ Write-Host " Files with conflicts: $($filesWithConflicts.Count)" -ForegroundColor Cyan
+
+ # Create GitHub Actions job summary
+ if ($SummaryPath) {
+ $summaryContent = @"
+# Merge Conflict Marker Check Results
+
+## Summary
+- **Files Checked:** $filesChecked
+- **Files with Conflicts:** $($filesWithConflicts.Count)
+
+"@
+
+ if ($filesWithConflicts.Count -gt 0) {
+ Write-Host "`n❌ Merge conflict markers detected in the following files:" -ForegroundColor Red
+
+ $summaryContent += "`n## ❌ Conflicts Detected`n`n"
+ $summaryContent += "The following files contain merge conflict markers:`n`n"
+
+ foreach ($fileInfo in $filesWithConflicts) {
+ Write-Host " - $($fileInfo.File)" -ForegroundColor Red
+
+ $summaryContent += "### 📄 ``$($fileInfo.File)```n`n"
+ $summaryContent += "| Line | Marker |`n"
+ $summaryContent += "|------|--------|`n"
+
+ foreach ($detail in $fileInfo.MarkerDetails) {
+ Write-Host " Line $($detail.Line): $($detail.Marker)" -ForegroundColor Red
+ $summaryContent += "| $($detail.Line) | ``$($detail.Marker)`` |`n"
+ }
+ $summaryContent += "`n"
+ }
+
+ $summaryContent += "`n**Action Required:** Please resolve these conflicts before merging.`n"
+ Write-Host "`nPlease resolve these conflicts before merging." -ForegroundColor Red
+ } else {
+ Write-Host "`n✅ No merge conflict markers found" -ForegroundColor Green
+ $summaryContent += "`n## ✅ No Conflicts Found`n`nAll checked files are free of merge conflict markers.`n"
+ }
+
+ $summaryContent | Out-File -FilePath $SummaryPath -Encoding utf8
+ }
+
+ # Exit with error if conflicts found
+ if ($filesWithConflicts.Count -gt 0) {
+ throw "Merge conflict markers detected in $($filesWithConflicts.Count) file(s)"
+ }
+}
diff --git a/tools/download.sh b/tools/download.sh
index 6a6c6436b4b..f1e8c42cdc3 100644
--- a/tools/download.sh
+++ b/tools/download.sh
@@ -1 +1,3 @@
-bash <(curl -s https://raw.githubusercontent.com/PowerShell/PowerShell/master/tools/install-powershell.sh)
+# Pin to specific commit for security (OpenSSF Scorecard requirement)
+# Pinned commit: 26bb188c8 - "Improve ValidateLength error message consistency and refactor validation tests" (2025-10-12)
+bash <(curl -s https://raw.githubusercontent.com/PowerShell/PowerShell/26bb188c8be0cda6cb548ce1a12840ebf67e1331/tools/install-powershell.sh)
diff --git a/tools/install-powershell.sh b/tools/install-powershell.sh
index 128f5664483..91425c183a8 100755
--- a/tools/install-powershell.sh
+++ b/tools/install-powershell.sh
@@ -26,7 +26,9 @@ install(){
#gitrepo paths are overrideable to run from your own fork or branch for testing or private distribution
local VERSION="1.2.0"
- local gitreposubpath="PowerShell/PowerShell/master"
+ # Pin to specific commit for security (OpenSSF Scorecard requirement)
+ # Pinned commit: 26bb188c8 - "Improve ValidateLength error message consistency and refactor validation tests" (2025-10-12)
+ local gitreposubpath="PowerShell/PowerShell/26bb188c8be0cda6cb548ce1a12840ebf67e1331"
local gitreposcriptroot="https://raw.githubusercontent.com/$gitreposubpath/tools"
local gitscriptname="install-powershell.psh"
@@ -125,7 +127,7 @@ install(){
if [[ $osname = *SUSE* ]]; then
DistroBasedOn='suse'
REV=$(source /etc/os-release; echo $VERSION_ID)
- fi
+ fi
OS=$(lowercase $OS)
DistroBasedOn=$(lowercase $DistroBasedOn)
fi
diff --git a/tools/packaging/boms/linux.json b/tools/packaging/boms/linux.json
index 9f5f886a4ca..db29e47a290 100644
--- a/tools/packaging/boms/linux.json
+++ b/tools/packaging/boms/linux.json
@@ -2442,5 +2442,15 @@
{
"Pattern": "System.Management.Automation.dll",
"FileType": "Product"
+ },
+ {
+ "Pattern": "pwsh.profile.dsc.resource.json",
+ "FileType": "Product",
+ "Architecture": null
+ },
+ {
+ "Pattern": "pwsh.profile.resource.ps1",
+ "FileType": "Product",
+ "Architecture": null
}
]
diff --git a/tools/packaging/boms/mac.json b/tools/packaging/boms/mac.json
index a4b5bc2bffb..af4fcb0c967 100644
--- a/tools/packaging/boms/mac.json
+++ b/tools/packaging/boms/mac.json
@@ -2218,5 +2218,15 @@
{
"Pattern": "System.Management.Automation.dll",
"FileType": "Product"
+ },
+ {
+ "Pattern": "pwsh.profile.dsc.resource.json",
+ "FileType": "Product",
+ "Architecture": null
+ },
+ {
+ "Pattern": "pwsh.profile.resource.ps1",
+ "FileType": "Product",
+ "Architecture": null
}
]
diff --git a/tools/packaging/boms/windows.json b/tools/packaging/boms/windows.json
index d8857c71786..f811109f818 100644
--- a/tools/packaging/boms/windows.json
+++ b/tools/packaging/boms/windows.json
@@ -89,11 +89,6 @@
"FileType": "NonProduct",
"Architecture": null
},
- {
- "Pattern": "cs/System.Private.ServiceModel.resources.dll",
- "FileType": "NonProduct",
- "Architecture": null
- },
{
"Pattern": "cs/System.Web.Services.Description.resources.dll",
"FileType": "NonProduct",
@@ -159,6 +154,26 @@
"FileType": "NonProduct",
"Architecture": null
},
+ {
+ "Pattern": "cs\\System.ServiceModel.Http.resources.dll",
+ "FileType": "NonProduct",
+ "Architecture": null
+ },
+ {
+ "Pattern": "cs\\System.ServiceModel.NetFramingBase.resources.dll",
+ "FileType": "NonProduct",
+ "Architecture": null
+ },
+ {
+ "Pattern": "cs\\System.ServiceModel.NetTcp.resources.dll",
+ "FileType": "NonProduct",
+ "Architecture": null
+ },
+ {
+ "Pattern": "cs\\System.ServiceModel.Primitives.resources.dll",
+ "FileType": "NonProduct",
+ "Architecture": null
+ },
{
"Pattern": "D3DCompiler_47_cor3.dll",
"FileType": "NonProduct",
@@ -201,11 +216,6 @@
"FileType": "NonProduct",
"Architecture": null
},
- {
- "Pattern": "de/System.Private.ServiceModel.resources.dll",
- "FileType": "NonProduct",
- "Architecture": null
- },
{
"Pattern": "de/System.Web.Services.Description.resources.dll",
"FileType": "NonProduct",
@@ -271,6 +281,26 @@
"FileType": "NonProduct",
"Architecture": null
},
+ {
+ "Pattern": "de\\System.ServiceModel.Http.resources.dll",
+ "FileType": "NonProduct",
+ "Architecture": null
+ },
+ {
+ "Pattern": "de\\System.ServiceModel.NetFramingBase.resources.dll",
+ "FileType": "NonProduct",
+ "Architecture": null
+ },
+ {
+ "Pattern": "de\\System.ServiceModel.NetTcp.resources.dll",
+ "FileType": "NonProduct",
+ "Architecture": null
+ },
+ {
+ "Pattern": "de\\System.ServiceModel.Primitives.resources.dll",
+ "FileType": "NonProduct",
+ "Architecture": null
+ },
{
"Pattern": "DirectWriteForwarder.dll",
"FileType": "NonProduct",
@@ -316,11 +346,6 @@
"FileType": "NonProduct",
"Architecture": null
},
- {
- "Pattern": "es/System.Private.ServiceModel.resources.dll",
- "FileType": "NonProduct",
- "Architecture": null
- },
{
"Pattern": "es/System.Web.Services.Description.resources.dll",
"FileType": "NonProduct",
@@ -386,6 +411,26 @@
"FileType": "NonProduct",
"Architecture": null
},
+ {
+ "Pattern": "es\\System.ServiceModel.Http.resources.dll",
+ "FileType": "NonProduct",
+ "Architecture": null
+ },
+ {
+ "Pattern": "es\\System.ServiceModel.NetFramingBase.resources.dll",
+ "FileType": "NonProduct",
+ "Architecture": null
+ },
+ {
+ "Pattern": "es\\System.ServiceModel.NetTcp.resources.dll",
+ "FileType": "NonProduct",
+ "Architecture": null
+ },
+ {
+ "Pattern": "es\\System.ServiceModel.Primitives.resources.dll",
+ "FileType": "NonProduct",
+ "Architecture": null
+ },
{
"Pattern": "fr/Microsoft.CodeAnalysis.CSharp.resources.dll",
"FileType": "NonProduct",
@@ -421,11 +466,6 @@
"FileType": "NonProduct",
"Architecture": null
},
- {
- "Pattern": "fr/System.Private.ServiceModel.resources.dll",
- "FileType": "NonProduct",
- "Architecture": null
- },
{
"Pattern": "fr/System.Web.Services.Description.resources.dll",
"FileType": "NonProduct",
@@ -491,6 +531,26 @@
"FileType": "NonProduct",
"Architecture": null
},
+ {
+ "Pattern": "fr\\System.ServiceModel.Http.resources.dll",
+ "FileType": "NonProduct",
+ "Architecture": null
+ },
+ {
+ "Pattern": "fr\\System.ServiceModel.NetFramingBase.resources.dll",
+ "FileType": "NonProduct",
+ "Architecture": null
+ },
+ {
+ "Pattern": "fr\\System.ServiceModel.NetTcp.resources.dll",
+ "FileType": "NonProduct",
+ "Architecture": null
+ },
+ {
+ "Pattern": "fr\\System.ServiceModel.Primitives.resources.dll",
+ "FileType": "NonProduct",
+ "Architecture": null
+ },
{
"Pattern": "getfilesiginforedist.dll",
"FileType": "NonProduct",
@@ -551,11 +611,6 @@
"FileType": "NonProduct",
"Architecture": null
},
- {
- "Pattern": "it/System.Private.ServiceModel.resources.dll",
- "FileType": "NonProduct",
- "Architecture": null
- },
{
"Pattern": "it/System.Web.Services.Description.resources.dll",
"FileType": "NonProduct",
@@ -621,6 +676,26 @@
"FileType": "NonProduct",
"Architecture": null
},
+ {
+ "Pattern": "it\\System.ServiceModel.Http.resources.dll",
+ "FileType": "NonProduct",
+ "Architecture": null
+ },
+ {
+ "Pattern": "it\\System.ServiceModel.NetFramingBase.resources.dll",
+ "FileType": "NonProduct",
+ "Architecture": null
+ },
+ {
+ "Pattern": "it\\System.ServiceModel.NetTcp.resources.dll",
+ "FileType": "NonProduct",
+ "Architecture": null
+ },
+ {
+ "Pattern": "it\\System.ServiceModel.Primitives.resources.dll",
+ "FileType": "NonProduct",
+ "Architecture": null
+ },
{
"Pattern": "ja/Microsoft.CodeAnalysis.CSharp.resources.dll",
"FileType": "NonProduct",
@@ -656,11 +731,6 @@
"FileType": "NonProduct",
"Architecture": null
},
- {
- "Pattern": "ja/System.Private.ServiceModel.resources.dll",
- "FileType": "NonProduct",
- "Architecture": null
- },
{
"Pattern": "ja/System.Web.Services.Description.resources.dll",
"FileType": "NonProduct",
@@ -726,6 +796,26 @@
"FileType": "NonProduct",
"Architecture": null
},
+ {
+ "Pattern": "ja\\System.ServiceModel.Http.resources.dll",
+ "FileType": "NonProduct",
+ "Architecture": null
+ },
+ {
+ "Pattern": "ja\\System.ServiceModel.NetFramingBase.resources.dll",
+ "FileType": "NonProduct",
+ "Architecture": null
+ },
+ {
+ "Pattern": "ja\\System.ServiceModel.NetTcp.resources.dll",
+ "FileType": "NonProduct",
+ "Architecture": null
+ },
+ {
+ "Pattern": "ja\\System.ServiceModel.Primitives.resources.dll",
+ "FileType": "NonProduct",
+ "Architecture": null
+ },
{
"Pattern": "Json.More.dll",
"FileType": "NonProduct",
@@ -776,11 +866,6 @@
"FileType": "NonProduct",
"Architecture": null
},
- {
- "Pattern": "ko/System.Private.ServiceModel.resources.dll",
- "FileType": "NonProduct",
- "Architecture": null
- },
{
"Pattern": "ko/System.Web.Services.Description.resources.dll",
"FileType": "NonProduct",
@@ -846,6 +931,26 @@
"FileType": "NonProduct",
"Architecture": null
},
+ {
+ "Pattern": "ko\\System.ServiceModel.Http.resources.dll",
+ "FileType": "NonProduct",
+ "Architecture": null
+ },
+ {
+ "Pattern": "ko\\System.ServiceModel.NetFramingBase.resources.dll",
+ "FileType": "NonProduct",
+ "Architecture": null
+ },
+ {
+ "Pattern": "ko\\System.ServiceModel.NetTcp.resources.dll",
+ "FileType": "NonProduct",
+ "Architecture": null
+ },
+ {
+ "Pattern": "ko\\System.ServiceModel.Primitives.resources.dll",
+ "FileType": "NonProduct",
+ "Architecture": null
+ },
{
"Pattern": "Markdig.Signed.dll",
"FileType": "NonProduct",
@@ -1111,11 +1216,6 @@
"FileType": "NonProduct",
"Architecture": null
},
- {
- "Pattern": "Modules/ThreadJob/*.psd1",
- "FileType": "NonProduct",
- "Architecture": null
- },
{
"Pattern": "Modules\\Microsoft.PowerShell.PSResourceGet\\Microsoft.PowerShell.PSResourceGet.pdb",
"FileType": "NonProduct",
@@ -1156,16 +1256,6 @@
"FileType": "NonProduct",
"Architecture": null
},
- {
- "Pattern": "Modules\\ThreadJob\\.signature.p7s",
- "FileType": "NonProduct",
- "Architecture": null
- },
- {
- "Pattern": "Modules\\ThreadJob\\ThreadJob.psm1",
- "FileType": "NonProduct",
- "Architecture": null
- },
{
"Pattern": "mscordaccore_*.dll",
"FileType": "NonProduct",
@@ -1246,11 +1336,6 @@
"FileType": "NonProduct",
"Architecture": null
},
- {
- "Pattern": "pl/System.Private.ServiceModel.resources.dll",
- "FileType": "NonProduct",
- "Architecture": null
- },
{
"Pattern": "pl/System.Web.Services.Description.resources.dll",
"FileType": "NonProduct",
@@ -1316,6 +1401,26 @@
"FileType": "NonProduct",
"Architecture": null
},
+ {
+ "Pattern": "pl\\System.ServiceModel.Http.resources.dll",
+ "FileType": "NonProduct",
+ "Architecture": null
+ },
+ {
+ "Pattern": "pl\\System.ServiceModel.NetFramingBase.resources.dll",
+ "FileType": "NonProduct",
+ "Architecture": null
+ },
+ {
+ "Pattern": "pl\\System.ServiceModel.NetTcp.resources.dll",
+ "FileType": "NonProduct",
+ "Architecture": null
+ },
+ {
+ "Pattern": "pl\\System.ServiceModel.Primitives.resources.dll",
+ "FileType": "NonProduct",
+ "Architecture": null
+ },
{
"Pattern": "powershell.config.json",
"FileType": "NonProduct",
@@ -1466,11 +1571,6 @@
"FileType": "NonProduct",
"Architecture": null
},
- {
- "Pattern": "pt-BR/System.Private.ServiceModel.resources.dll",
- "FileType": "NonProduct",
- "Architecture": null
- },
{
"Pattern": "pt-BR/System.Web.Services.Description.resources.dll",
"FileType": "NonProduct",
@@ -1536,6 +1636,26 @@
"FileType": "NonProduct",
"Architecture": null
},
+ {
+ "Pattern": "pt-BR\\System.ServiceModel.Http.resources.dll",
+ "FileType": "NonProduct",
+ "Architecture": null
+ },
+ {
+ "Pattern": "pt-BR\\System.ServiceModel.NetFramingBase.resources.dll",
+ "FileType": "NonProduct",
+ "Architecture": null
+ },
+ {
+ "Pattern": "pt-BR\\System.ServiceModel.NetTcp.resources.dll",
+ "FileType": "NonProduct",
+ "Architecture": null
+ },
+ {
+ "Pattern": "pt-BR\\System.ServiceModel.Primitives.resources.dll",
+ "FileType": "NonProduct",
+ "Architecture": null
+ },
{
"Pattern": "pwrshplugin.dll",
"FileType": "NonProduct",
@@ -2431,11 +2551,6 @@
"FileType": "NonProduct",
"Architecture": null
},
- {
- "Pattern": "ru/System.Private.ServiceModel.resources.dll",
- "FileType": "NonProduct",
- "Architecture": null
- },
{
"Pattern": "ru/System.Web.Services.Description.resources.dll",
"FileType": "NonProduct",
@@ -2501,6 +2616,26 @@
"FileType": "NonProduct",
"Architecture": null
},
+ {
+ "Pattern": "ru\\System.ServiceModel.Http.resources.dll",
+ "FileType": "NonProduct",
+ "Architecture": null
+ },
+ {
+ "Pattern": "ru\\System.ServiceModel.NetFramingBase.resources.dll",
+ "FileType": "NonProduct",
+ "Architecture": null
+ },
+ {
+ "Pattern": "ru\\System.ServiceModel.NetTcp.resources.dll",
+ "FileType": "NonProduct",
+ "Architecture": null
+ },
+ {
+ "Pattern": "ru\\System.ServiceModel.Primitives.resources.dll",
+ "FileType": "NonProduct",
+ "Architecture": null
+ },
{
"Pattern": "Schemas/PSMaml/base.xsd",
"FileType": "NonProduct",
@@ -3316,11 +3451,6 @@
"FileType": "NonProduct",
"Architecture": null
},
- {
- "Pattern": "System.Private.ServiceModel.dll",
- "FileType": "NonProduct",
- "Architecture": null
- },
{
"Pattern": "System.Private.Uri.dll",
"FileType": "NonProduct",
@@ -3606,6 +3736,11 @@
"FileType": "NonProduct",
"Architecture": null
},
+ {
+ "Pattern": "System.ServiceModel.NetFramingBase.dll",
+ "FileType": "NonProduct",
+ "Architecture": null
+ },
{
"Pattern": "System.ServiceModel.NetTcp.dll",
"FileType": "NonProduct",
@@ -3901,11 +4036,6 @@
"FileType": "NonProduct",
"Architecture": null
},
- {
- "Pattern": "tr/System.Private.ServiceModel.resources.dll",
- "FileType": "NonProduct",
- "Architecture": null
- },
{
"Pattern": "tr/System.Web.Services.Description.resources.dll",
"FileType": "NonProduct",
@@ -3971,6 +4101,26 @@
"FileType": "NonProduct",
"Architecture": null
},
+ {
+ "Pattern": "tr\\System.ServiceModel.Http.resources.dll",
+ "FileType": "NonProduct",
+ "Architecture": null
+ },
+ {
+ "Pattern": "tr\\System.ServiceModel.NetFramingBase.resources.dll",
+ "FileType": "NonProduct",
+ "Architecture": null
+ },
+ {
+ "Pattern": "tr\\System.ServiceModel.NetTcp.resources.dll",
+ "FileType": "NonProduct",
+ "Architecture": null
+ },
+ {
+ "Pattern": "tr\\System.ServiceModel.Primitives.resources.dll",
+ "FileType": "NonProduct",
+ "Architecture": null
+ },
{
"Pattern": "UIAutomationClient.dll",
"FileType": "NonProduct",
@@ -4046,11 +4196,6 @@
"FileType": "NonProduct",
"Architecture": null
},
- {
- "Pattern": "zh-Hans/System.Private.ServiceModel.resources.dll",
- "FileType": "NonProduct",
- "Architecture": null
- },
{
"Pattern": "zh-Hans/System.Web.Services.Description.resources.dll",
"FileType": "NonProduct",
@@ -4116,6 +4261,26 @@
"FileType": "NonProduct",
"Architecture": null
},
+ {
+ "Pattern": "zh-Hans\\System.ServiceModel.Http.resources.dll",
+ "FileType": "NonProduct",
+ "Architecture": null
+ },
+ {
+ "Pattern": "zh-Hans\\System.ServiceModel.NetFramingBase.resources.dll",
+ "FileType": "NonProduct",
+ "Architecture": null
+ },
+ {
+ "Pattern": "zh-Hans\\System.ServiceModel.NetTcp.resources.dll",
+ "FileType": "NonProduct",
+ "Architecture": null
+ },
+ {
+ "Pattern": "zh-Hans\\System.ServiceModel.Primitives.resources.dll",
+ "FileType": "NonProduct",
+ "Architecture": null
+ },
{
"Pattern": "zh-Hant/Microsoft.CodeAnalysis.CSharp.resources.dll",
"FileType": "NonProduct",
@@ -4151,11 +4316,6 @@
"FileType": "NonProduct",
"Architecture": null
},
- {
- "Pattern": "zh-Hant/System.Private.ServiceModel.resources.dll",
- "FileType": "NonProduct",
- "Architecture": null
- },
{
"Pattern": "zh-Hant/System.Web.Services.Description.resources.dll",
"FileType": "NonProduct",
@@ -4221,6 +4381,26 @@
"FileType": "NonProduct",
"Architecture": null
},
+ {
+ "Pattern": "zh-Hant\\System.ServiceModel.Http.resources.dll",
+ "FileType": "NonProduct",
+ "Architecture": null
+ },
+ {
+ "Pattern": "zh-Hant\\System.ServiceModel.NetFramingBase.resources.dll",
+ "FileType": "NonProduct",
+ "Architecture": null
+ },
+ {
+ "Pattern": "zh-Hant\\System.ServiceModel.NetTcp.resources.dll",
+ "FileType": "NonProduct",
+ "Architecture": null
+ },
+ {
+ "Pattern": "zh-Hant\\System.ServiceModel.Primitives.resources.dll",
+ "FileType": "NonProduct",
+ "Architecture": null
+ },
{
"Pattern": "_manifest/spdx_2.2/manifest.spdx.json",
"FileType": "Product",
@@ -4425,5 +4605,15 @@
"Pattern": "System.Management.Automation.dll",
"FileType": "Product",
"Architecture": null
+ },
+ {
+ "Pattern": "pwsh.profile.dsc.resource.json",
+ "FileType": "Product",
+ "Architecture": null
+ },
+ {
+ "Pattern": "pwsh.profile.resource.ps1",
+ "FileType": "Product",
+ "Architecture": null
}
]
diff --git a/tools/packaging/packaging.psm1 b/tools/packaging/packaging.psm1
index 8e7fb3c4e08..8e4dc9aa1dc 100644
--- a/tools/packaging/packaging.psm1
+++ b/tools/packaging/packaging.psm1
@@ -1,6 +1,8 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
+. "$PSScriptRoot\..\buildCommon\startNativeExecution.ps1"
+
$Environment = Get-EnvironmentInformation
$RepoRoot = (Resolve-Path -Path "$PSScriptRoot/../..").Path
@@ -282,6 +284,18 @@ function Start-PSPackage {
$createdSpdxPathSha = New-Item -Path $manifestSpdxPathSha -Force
Write-Verbose -Verbose "Created manifest.spdx.json.sha256 file: $createdSpdxPathSha"
}
+
+ $bsiJsonPath = (Join-Path -Path $Source "_manifest\spdx_2.2\bsi.json")
+ if (-not (Test-Path -Path $bsiJsonPath)) {
+ $createdBsiJsonPath = New-Item -Path $bsiJsonPath -Force
+ Write-Verbose -Verbose "Created bsi.json file: $createdBsiJsonPath"
+ }
+
+ $manifestCatPath = (Join-Path -Path $Source "_manifest\spdx_2.2\manifest.cat")
+ if (-not (Test-Path -Path $manifestCatPath)) {
+ $createdCatPath = New-Item -Path $manifestCatPath -Force
+ Write-Verbose -Verbose "Created manifest.cat file: $createdCatPath"
+ }
}
# If building a symbols package, we add a zip of the parent to publish
@@ -1145,15 +1159,12 @@ function New-UnixPackage {
}
# Determine if the version is a preview version
- $IsPreview = Test-IsPreview -Version $Version -IsLTS:$LTS
-
- # Preview versions have preview in the name
+ # Only LTS packages get a prefix in the name
+ # Preview versions are identified by the version string itself (e.g., 7.6.0-preview.6)
+ # Rebuild versions are also identified by the version string (e.g., 7.4.13-rebuild.5)
$Name = if($LTS) {
"powershell-lts"
}
- elseif ($IsPreview) {
- "powershell-preview"
- }
else {
"powershell"
}
@@ -1197,20 +1208,6 @@ function New-UnixPackage {
# Generate After Install and After Remove scripts
$AfterScriptInfo = New-AfterScripts -Link $Link -Distribution $DebDistro -Destination $Destination
- # there is a weird bug in fpm
- # if the target of the powershell symlink exists, `fpm` aborts
- # with a `utime` error on macOS.
- # so we move it to make symlink broken
- # refers to executable, does not vary by channel
- $symlink_dest = "$Destination/pwsh"
- $hack_dest = "./_fpm_symlink_hack_powershell"
- if ($Environment.IsMacOS) {
- if (Test-Path $symlink_dest) {
- Write-Warning "Move $symlink_dest to $hack_dest (fpm utime bug)"
- Start-NativeExecution ([ScriptBlock]::Create("$sudo mv $symlink_dest $hack_dest"))
- }
- }
-
# Generate gzip of man file
$ManGzipInfo = New-ManGzip -IsPreview:$IsPreview -IsLTS:$LTS
@@ -1245,41 +1242,150 @@ function New-UnixPackage {
# Setup package dependencies
$Dependencies = @(Get-PackageDependencies @packageDependenciesParams)
- $Arguments = @()
-
-
- $Arguments += Get-FpmArguments `
- -Name $Name `
- -Version $packageVersion `
- -Iteration $Iteration `
- -Description $Description `
- -Type $Type `
- -Dependencies $Dependencies `
- -AfterInstallScript $AfterScriptInfo.AfterInstallScript `
- -AfterRemoveScript $AfterScriptInfo.AfterRemoveScript `
- -Staging $Staging `
- -Destination $Destination `
- -ManGzipFile $ManGzipInfo.GzipFile `
- -ManDestination $ManGzipInfo.ManFile `
- -LinkInfo $Links `
- -AppsFolder $AppsFolder `
- -Distribution $DebDistro `
- -HostArchitecture $HostArchitecture `
- -ErrorAction Stop
-
# Build package
try {
- if ($PSCmdlet.ShouldProcess("Create $type package")) {
- Write-Log "Creating package with fpm $Arguments..."
- try {
- $Output = Start-NativeExecution { fpm $Arguments }
+ if ($Type -eq 'rpm') {
+ # Use rpmbuild directly for RPM packages
+ if ($PSCmdlet.ShouldProcess("Create RPM package with rpmbuild")) {
+ Write-Log "Creating RPM package with rpmbuild..."
+
+ # Create rpmbuild directory structure
+ $rpmBuildRoot = Join-Path $env:HOME "rpmbuild"
+ $specsDir = Join-Path $rpmBuildRoot "SPECS"
+ $rpmsDir = Join-Path $rpmBuildRoot "RPMS"
+
+ New-Item -ItemType Directory -Path $specsDir -Force | Out-Null
+ New-Item -ItemType Directory -Path $rpmsDir -Force | Out-Null
+
+ # Generate RPM spec file
+ $specContent = New-RpmSpec `
+ -Name $Name `
+ -Version $packageVersion `
+ -Iteration $Iteration `
+ -Description $Description `
+ -Dependencies $Dependencies `
+ -AfterInstallScript $AfterScriptInfo.AfterInstallScript `
+ -AfterRemoveScript $AfterScriptInfo.AfterRemoveScript `
+ -Staging $Staging `
+ -Destination $Destination `
+ -ManGzipFile $ManGzipInfo.GzipFile `
+ -ManDestination $ManGzipInfo.ManFile `
+ -LinkInfo $Links `
+ -Distribution $DebDistro `
+ -HostArchitecture $HostArchitecture
+
+ $specFile = Join-Path $specsDir "$Name.spec"
+ $specContent | Out-File -FilePath $specFile -Encoding ascii
+ Write-Verbose "Generated spec file: $specFile" -Verbose
+
+ # Log the spec file content
+ if ($env:GITHUB_ACTIONS -eq 'true') {
+ Write-Host "::group::RPM Spec File Content"
+ Write-Host $specContent
+ Write-Host "::endgroup::"
+ } else {
+ Write-Verbose "RPM Spec File Content:`n$specContent" -Verbose
+ }
+
+ # Build RPM package
+ try {
+ # Use bash to properly handle rpmbuild arguments
+ # Add --target for cross-architecture builds
+ $targetArch = ""
+ if ($HostArchitecture -ne "x86_64" -and $HostArchitecture -ne "noarch") {
+ $targetArch = "--target $HostArchitecture"
+ }
+ $buildCmd = "rpmbuild -bb --quiet $targetArch --define '_topdir $rpmBuildRoot' --buildroot '$rpmBuildRoot/BUILDROOT' '$specFile'"
+ Write-Verbose "Running: $buildCmd" -Verbose
+ $Output = bash -c $buildCmd 2>&1
+ $exitCode = $LASTEXITCODE
+
+ if ($exitCode -ne 0) {
+ throw "rpmbuild failed with exit code $exitCode"
+ }
+
+ # Find the generated RPM
+ $rpmFile = Get-ChildItem -Path (Join-Path $rpmsDir $HostArchitecture) -Filter "*.rpm" -ErrorAction Stop |
+ Sort-Object -Property LastWriteTime -Descending |
+ Select-Object -First 1
+
+ if ($rpmFile) {
+ # Copy RPM to current location
+ Copy-Item -Path $rpmFile.FullName -Destination $CurrentLocation -Force
+ $Output = @("Created package {:path=>""$($rpmFile.Name)""}")
+ } else {
+ throw "RPM file not found after build"
+ }
+ }
+ catch {
+ Write-Verbose -Message "!!!Handling error in rpmbuild!!!" -Verbose -ErrorAction SilentlyContinue
+ if ($Output) {
+ Write-Verbose -Message "$Output" -Verbose -ErrorAction SilentlyContinue
+ }
+ Get-Error -InputObject $_
+ throw
+ }
}
- catch {
- Write-Verbose -Message "!!!Handling error in FPM!!!" -Verbose -ErrorAction SilentlyContinue
- Write-Verbose -Message "$Output" -Verbose -ErrorAction SilentlyContinue
- Get-Error -InputObject $_
- throw
+ } elseif ($Type -eq 'deb') {
+ # Use native DEB package builder
+ if ($PSCmdlet.ShouldProcess("Create DEB package natively")) {
+ Write-Log "Creating DEB package natively..."
+ try {
+ $result = New-NativeDeb `
+ -Name $Name `
+ -Version $packageVersion `
+ -Iteration $Iteration `
+ -Description $Description `
+ -Staging $Staging `
+ -Destination $Destination `
+ -ManGzipFile $ManGzipInfo.GzipFile `
+ -ManDestination $ManGzipInfo.ManFile `
+ -LinkInfo $Links `
+ -Dependencies $Dependencies `
+ -AfterInstallScript $AfterScriptInfo.AfterInstallScript `
+ -AfterRemoveScript $AfterScriptInfo.AfterRemoveScript `
+ -HostArchitecture $HostArchitecture `
+ -CurrentLocation $CurrentLocation
+
+ $Output = @("Created package {:path=>""$($result.PackageName)""}")
+ }
+ catch {
+ Write-Verbose -Message "!!!Handling error in native DEB creation!!!" -Verbose -ErrorAction SilentlyContinue
+ }
+ }
+ } elseif ($Type -eq 'osxpkg') {
+ # Use native macOS packaging tools
+ if ($PSCmdlet.ShouldProcess("Create macOS package with pkgbuild/productbuild")) {
+ Write-Log "Creating macOS package with native tools..."
+
+ $macPkgArgs = @{
+ Name = $Name
+ Version = $packageVersion
+ Iteration = $Iteration
+ Staging = $Staging
+ Destination = $Destination
+ ManGzipFile = $ManGzipInfo.GzipFile
+ ManDestination = $ManGzipInfo.ManFile
+ LinkInfo = $Links
+ AfterInstallScript = $AfterScriptInfo.AfterInstallScript
+ AppsFolder = $AppsFolder
+ HostArchitecture = $HostArchitecture
+ CurrentLocation = $CurrentLocation
+ }
+
+ try {
+ $packageFile = New-MacOSPackage @macPkgArgs
+ $Output = @("Created package {:path=>""$($packageFile.Name)""}")
+ }
+ catch {
+ Write-Verbose -Message "!!!Handling error in macOS packaging!!!" -Verbose -ErrorAction SilentlyContinue
+ Get-Error -InputObject $_
+ throw
+ }
}
+ } else {
+ # Nothing should reach here
+ throw "Unknown package type: $Type"
}
} finally {
if ($Environment.IsMacOS) {
@@ -1288,13 +1394,17 @@ function New-UnixPackage {
{
Clear-MacOSLauncher
}
+ }
- # this is continuation of a fpm hack for a weird bug
- if (Test-Path $hack_dest) {
- Write-Warning "Move $hack_dest to $symlink_dest (fpm utime bug)"
- Start-NativeExecution -sb ([ScriptBlock]::Create("$sudo mv $hack_dest $symlink_dest")) -VerboseOutputOnError
+ # Clean up rpmbuild directory if it was created
+ if ($Type -eq 'rpm') {
+ $rpmBuildRoot = Join-Path $env:HOME "rpmbuild"
+ if (Test-Path $rpmBuildRoot) {
+ Write-Verbose "Cleaning up rpmbuild directory: $rpmBuildRoot" -Verbose
+ Remove-Item -Path $rpmBuildRoot -Recurse -Force -ErrorAction SilentlyContinue
}
}
+
if ($AfterScriptInfo.AfterInstallScript) {
Remove-Item -ErrorAction 'silentlycontinue' $AfterScriptInfo.AfterInstallScript -Force
}
@@ -1307,12 +1417,8 @@ function New-UnixPackage {
# Magic to get path output
$createdPackage = Get-Item (Join-Path $CurrentLocation (($Output[-1] -split ":path=>")[-1] -replace '["{}]'))
- if ($Environment.IsMacOS) {
- if ($PSCmdlet.ShouldProcess("Add distribution information and Fix PackageName"))
- {
- $createdPackage = New-MacOsDistributionPackage -FpmPackage $createdPackage -HostArchitecture $HostArchitecture -IsPreview:$IsPreview
- }
- }
+ # For macOS with native tools, the package is already in the correct format
+ # For other platforms, the package name from dpkg-deb/rpmbuild is sufficient
if (Test-Path $createdPackage)
{
@@ -1357,14 +1463,27 @@ Function New-LinkInfo
function New-MacOsDistributionPackage
{
+ [CmdletBinding(SupportsShouldProcess=$true)]
param(
- [Parameter(Mandatory,HelpMessage='The FileInfo of the file created by FPM')]
- [System.IO.FileInfo]$FpmPackage,
+ [Parameter(Mandatory,HelpMessage='The FileInfo of the component package')]
+ [System.IO.FileInfo]$ComponentPackage,
+
+ [Parameter(Mandatory,HelpMessage='Package name for the output file')]
+ [string]$PackageName,
+
+ [Parameter(Mandatory,HelpMessage='Package version')]
+ [string]$Version,
+
+ [Parameter(Mandatory,HelpMessage='Output directory for the final package')]
+ [string]$OutputDirectory,
[Parameter(HelpMessage='x86_64 for Intel or arm64 for Apple Silicon')]
[ValidateSet("x86_64", "arm64")]
[string] $HostArchitecture = "x86_64",
+ [Parameter(HelpMessage='Package identifier')]
+ [string]$PackageIdentifier,
+
[Switch] $IsPreview
)
@@ -1373,64 +1492,83 @@ function New-MacOsDistributionPackage
throw 'New-MacOsDistributionPackage is only supported on macOS!'
}
- $packageName = Split-Path -Leaf -Path $FpmPackage
-
# Create a temp directory to store the needed files
$tempDir = Join-Path ([System.IO.Path]::GetTempPath()) ([System.IO.Path]::GetRandomFileName())
New-Item -ItemType Directory -Path $tempDir -Force > $null
$resourcesDir = Join-Path -Path $tempDir -ChildPath 'resources'
New-Item -ItemType Directory -Path $resourcesDir -Force > $null
- #Copy background file to temp directory
- $backgroundFile = "$RepoRoot/assets/macDialog.png"
- Copy-Item -Path $backgroundFile -Destination $resourcesDir
- # Move the current package to the temp directory
- $tempPackagePath = Join-Path -Path $tempDir -ChildPath $packageName
- Move-Item -Path $FpmPackage -Destination $tempPackagePath -Force
-
- # Add the OS information to the macOS package file name.
- $packageExt = [System.IO.Path]::GetExtension($FpmPackage.Name)
- # get the package name from fpm without the extension, but replace powershell-preview at the beginning of the name with powershell.
- $packageNameWithoutExt = [System.IO.Path]::GetFileNameWithoutExtension($FpmPackage.Name) -replace '^powershell\-preview' , 'powershell'
-
- $newPackageName = "{0}-{1}{2}" -f $packageNameWithoutExt, $script:Options.Runtime, $packageExt
- $newPackagePath = Join-Path $FpmPackage.DirectoryName $newPackageName
-
- # -Force is not deleting the NewName if it exists, so delete it if it does
- if ($Force -and (Test-Path -Path $newPackagePath))
- {
- Remove-Item -Force $newPackagePath
+ # Copy background file to temp directory
+ $backgroundFile = "$RepoRoot/assets/macDialog.png"
+ if (Test-Path $backgroundFile) {
+ Copy-Item -Path $backgroundFile -Destination $resourcesDir -Force
}
+ # Copy the component package to temp directory
+ $componentFileName = Split-Path -Leaf -Path $ComponentPackage
+ $tempComponentPath = Join-Path -Path $tempDir -ChildPath $componentFileName
+ Copy-Item -Path $ComponentPackage -Destination $tempComponentPath -Force
+
# Create the distribution xml
$distributionXmlPath = Join-Path -Path $tempDir -ChildPath 'powershellDistribution.xml'
- $packageId = Get-MacOSPackageId -IsPreview:$IsPreview.IsPresent
+ # Get package ID if not provided
+ if (-not $PackageIdentifier) {
+ $PackageIdentifier = Get-MacOSPackageId -IsPreview:$IsPreview.IsPresent
+ }
+
+ # Minimum OS version
+ $minOSVersion = "11.0" # macOS Big Sur minimum
# format distribution template with:
# 0 - title
# 1 - version
- # 2 - package path
+ # 2 - package path (component package filename)
# 3 - minimum os version
# 4 - Package Identifier
# 5 - host architecture (x86_64 for Intel or arm64 for Apple Silicon)
- $PackagingStrings.OsxDistributionTemplate -f "PowerShell - $packageVersion", $packageVersion, $packageName, '10.14', $packageId, $HostArchitecture | Out-File -Encoding ascii -FilePath $distributionXmlPath -Force
+ $PackagingStrings.OsxDistributionTemplate -f $PackageName, $Version, $componentFileName, $minOSVersion, $PackageIdentifier, $HostArchitecture | Out-File -Encoding utf8 -FilePath $distributionXmlPath -Force
- Write-Log "Applying distribution.xml to package..."
- Push-Location $tempDir
- try
- {
- # productbuild is an xcode command line tool, and those tools are installed when you install brew
- Start-NativeExecution -sb {productbuild --distribution $distributionXmlPath --resources $resourcesDir $newPackagePath} -VerboseOutputOnError
+ # Build final package path
+ # Rename x86_64 to x64 for compatibility
+ $packageArchName = if ($HostArchitecture -eq "x86_64") { "x64" } else { $HostArchitecture }
+ $finalPackagePath = Join-Path $OutputDirectory "$PackageName-$Version-osx-$packageArchName.pkg"
+
+ # Remove existing package if it exists
+ if (Test-Path $finalPackagePath) {
+ Write-Warning "Removing existing package: $finalPackagePath"
+ Remove-Item $finalPackagePath -Force
}
- finally
- {
- Pop-Location
- Remove-Item -Path $tempDir -Recurse -Force
+
+ if ($PSCmdlet.ShouldProcess("Build product package with productbuild")) {
+ Write-Log "Applying distribution.xml to package..."
+ Push-Location $tempDir
+ try
+ {
+ # productbuild is an xcode command line tool
+ Start-NativeExecution -VerboseOutputOnError {
+ productbuild --distribution $distributionXmlPath `
+ --package-path $tempDir `
+ --resources $resourcesDir `
+ $finalPackagePath
+ }
+
+ if (Test-Path $finalPackagePath) {
+ Write-Log "Successfully created macOS package: $finalPackagePath"
+ }
+ else {
+ throw "Package was not created at expected location: $finalPackagePath"
+ }
+ }
+ finally
+ {
+ Pop-Location
+ Remove-Item -Path $tempDir -Recurse -Force -ErrorAction SilentlyContinue
+ }
}
- return (Get-Item $newPackagePath)
+ return (Get-Item $finalPackagePath)
}
Class LinkInfo
@@ -1439,7 +1577,7 @@ Class LinkInfo
[string] $Destination
}
-function Get-FpmArguments
+function New-RpmSpec
{
param(
[Parameter(Mandatory,HelpMessage='Package Name')]
@@ -1454,11 +1592,6 @@ function Get-FpmArguments
[Parameter(Mandatory,HelpMessage='Package description')]
[String]$Description,
- # From start-PSPackage without modification, already validated
- # Values: deb, rpm, osxpkg
- [Parameter(Mandatory,HelpMessage='Installer Type')]
- [String]$Type,
-
[Parameter(Mandatory,HelpMessage='Staging folder for installation files')]
[String]$Staging,
@@ -1474,109 +1607,495 @@ function Get-FpmArguments
[Parameter(Mandatory,HelpMessage='Symlink to powershell executable')]
[LinkInfo[]]$LinkInfo,
- [Parameter(HelpMessage='Packages required to install this package. Not applicable for MacOS.')]
- [ValidateScript({
- if (!$Environment.IsMacOS -and $_.Count -eq 0)
- {
- throw "Must not be null or empty on this environment."
- }
- return $true
- })]
+ [Parameter(Mandatory,HelpMessage='Packages required to install this package')]
[String[]]$Dependencies,
- [Parameter(HelpMessage='Script to run after the package installation.')]
- [AllowNull()]
- [ValidateScript({
- if (!$Environment.IsMacOS -and !$_)
- {
- throw "Must not be null on this environment."
- }
- return $true
- })]
+ [Parameter(Mandatory,HelpMessage='Script to run after the package installation.')]
[String]$AfterInstallScript,
- [Parameter(HelpMessage='Script to run after the package removal.')]
- [AllowNull()]
- [ValidateScript({
- if (!$Environment.IsMacOS -and !$_)
- {
- throw "Must not be null on this environment."
- }
- return $true
- })]
+ [Parameter(Mandatory,HelpMessage='Script to run after the package removal.')]
[String]$AfterRemoveScript,
- [Parameter(HelpMessage='AppsFolder used to add macOS launcher')]
- [AllowNull()]
- [ValidateScript({
- if ($Environment.IsMacOS -and !$_)
- {
- throw "Must not be null on this environment."
- }
- return $true
- })]
- [String]$AppsFolder,
[String]$Distribution = 'rhel.7',
[string]$HostArchitecture
)
- $Arguments = @(
- "--force", "--verbose",
- "--name", $Name,
- "--version", $Version,
- "--iteration", $Iteration,
- "--maintainer", "PowerShell Team ",
- "--vendor", "Microsoft Corporation",
- "--url", "https://microsoft.com/powershell",
- "--description", $Description,
- "--architecture", $HostArchitecture,
- "--category", "shells",
- "-t", $Type,
- "-s", "dir"
- )
- if ($Distribution -in $script:RedHatDistributions) {
- $Arguments += @("--rpm-digest", "sha256")
- $Arguments += @("--rpm-dist", $Distribution)
- $Arguments += @("--rpm-os", "linux")
- $Arguments += @("--license", "MIT")
- $Arguments += @("--rpm-rpmbuild-define", "_build_id_links none")
+ # RPM doesn't allow hyphens in version, so convert them to underscores
+ # e.g., "7.6.0-preview.6" becomes Version: 7.6.0_preview.6
+ $rpmVersion = $Version -replace '-', '_'
+
+ # Build Release field with distribution suffix (e.g., "1.cm" or "1.rh")
+ # Don't use RPM macros - build the full release string in PowerShell
+ $rpmRelease = "$Iteration.$Distribution"
+
+ $specContent = @"
+# RPM spec file for PowerShell
+# Generated by PowerShell build system
+
+Name: $Name
+Version: $rpmVersion
+Release: $rpmRelease
+Summary: PowerShell - Cross-platform automation and configuration tool/framework
+License: MIT
+URL: https://microsoft.com/powershell
+AutoReq: no
+
+"@
+
+ # Only add BuildArch if not doing cross-architecture build
+ # For cross-arch builds, we'll rely on --target option
+ if ($HostArchitecture -eq "x86_64" -or $HostArchitecture -eq "noarch") {
+ $specContent += "BuildArch: $HostArchitecture`n`n"
} else {
- $Arguments += @("--license", "MIT License")
- }
+ # For cross-architecture builds, don't specify BuildArch in spec
+ # The --target option will handle the architecture
- if ($Environment.IsMacOS) {
- $Arguments += @("--osxpkg-identifier-prefix", "com.microsoft")
+ # Disable automatic binary stripping for cross-arch builds
+ # The native /bin/strip on x86_64 cannot process ARM64 binaries and would fail with:
+ # "Unable to recognise the format of the input file"
+ # See: https://rpm-software-management.github.io/rpm/manual/macros.html
+ # __strip: This macro controls the command used for stripping binaries during the build process.
+ # /bin/true: A command that does nothing and always exits successfully, effectively bypassing the stripping process.
+ $specContent += "%define __strip /bin/true`n"
+
+ # Disable debug package generation to prevent strip-related errors
+ # Debug packages require binary stripping which fails for cross-arch builds
+ # See: https://rpm-packaging-guide.github.io/#debugging
+ # See: https://docs.fedoraproject.org/en-US/packaging-guidelines/Debuginfo/#_useless_or_incomplete_debuginfo_packages_due_to_other_reasons
+ $specContent += "%global debug_package %{nil}`n`n"
}
- foreach ($Dependency in $Dependencies) {
- $Arguments += @("--depends", $Dependency)
+ # Add dependencies
+ foreach ($dep in $Dependencies) {
+ $specContent += "Requires: $dep`n"
}
- if ($AfterInstallScript) {
- $Arguments += @("--after-install", $AfterInstallScript)
+ $specContent += @"
+
+%description
+$Description
+
+%prep
+# No prep needed - files are already staged
+
+%build
+# No build needed - binaries are pre-built
+
+%install
+rm -rf `$RPM_BUILD_ROOT
+mkdir -p `$RPM_BUILD_ROOT$Destination
+mkdir -p `$RPM_BUILD_ROOT$(Split-Path -Parent $ManDestination)
+
+# Copy all files from staging to destination
+cp -r $Staging/* `$RPM_BUILD_ROOT$Destination/
+
+# Copy man page
+cp $ManGzipFile `$RPM_BUILD_ROOT$ManDestination
+
+"@
+
+ # Add symlinks - we need to get the target of the temp symlink
+ foreach ($link in $LinkInfo) {
+ $linkDir = Split-Path -Parent $link.Destination
+ $specContent += "mkdir -p `$RPM_BUILD_ROOT$linkDir`n"
+ # For RPM, we copy the symlink itself.
+ # The symlink at $link.Source points to the actual target, so we'll copy it.
+ # The -P flag preserves symlinks rather than copying their targets, which is critical for this operation.
+ $specContent += "cp -P $($link.Source) `$RPM_BUILD_ROOT$($link.Destination)`n"
}
- if ($AfterRemoveScript) {
- $Arguments += @("--after-remove", $AfterRemoveScript)
+ # Post-install script
+ $postInstallContent = Get-Content -Path $AfterInstallScript -Raw
+ $specContent += "`n%post`n"
+ $specContent += $postInstallContent
+ $specContent += "`n"
+
+ # Post-uninstall script
+ $postUninstallContent = Get-Content -Path $AfterRemoveScript -Raw
+ $specContent += "%postun`n"
+ $specContent += $postUninstallContent
+ $specContent += "`n"
+
+ # Files section
+ $specContent += "%files`n"
+ $specContent += "%defattr(-,root,root,-)`n"
+ $specContent += "$Destination/*`n"
+ $specContent += "$ManDestination`n"
+
+ # Add symlinks to files
+ foreach ($link in $LinkInfo) {
+ $specContent += "$($link.Destination)`n"
}
- $Arguments += @(
- "$Staging/=$Destination/",
- "$ManGzipFile=$ManDestination"
+ # Changelog with correct date format for RPM
+ $changelogDate = Get-Date -Format "ddd MMM dd yyyy"
+ $specContent += "`n%changelog`n"
+ $specContent += "* $changelogDate PowerShell Team - $rpmVersion-$rpmRelease`n"
+ $specContent += "- Automated build`n"
+
+ return $specContent
+}
+
+function New-NativeDeb
+{
+ param(
+ [Parameter(Mandatory, HelpMessage='Package Name')]
+ [String]$Name,
+
+ [Parameter(Mandatory, HelpMessage='Package Version')]
+ [String]$Version,
+
+ [Parameter(Mandatory)]
+ [String]$Iteration,
+
+ [Parameter(Mandatory, HelpMessage='Package description')]
+ [String]$Description,
+
+ [Parameter(Mandatory, HelpMessage='Staging folder for installation files')]
+ [String]$Staging,
+
+ [Parameter(Mandatory, HelpMessage='Install path on target machine')]
+ [String]$Destination,
+
+ [Parameter(Mandatory, HelpMessage='The built and gzipped man file.')]
+ [String]$ManGzipFile,
+
+ [Parameter(Mandatory, HelpMessage='The destination of the man file')]
+ [String]$ManDestination,
+
+ [Parameter(Mandatory, HelpMessage='Symlink to powershell executable')]
+ [LinkInfo[]]$LinkInfo,
+
+ [Parameter(HelpMessage='Packages required to install this package.')]
+ [String[]]$Dependencies,
+
+ [Parameter(HelpMessage='Script to run after the package installation.')]
+ [String]$AfterInstallScript,
+
+ [Parameter(HelpMessage='Script to run after the package removal.')]
+ [String]$AfterRemoveScript,
+
+ [string]$HostArchitecture,
+
+ [string]$CurrentLocation
)
- foreach($link in $LinkInfo)
- {
- $linkArgument = "$($link.Source)=$($link.Destination)"
- $Arguments += $linkArgument
- }
+ Write-Log "Creating native DEB package..."
- if ($AppsFolder)
- {
- $Arguments += "$AppsFolder=/"
+ # Create temporary build directory
+ $debBuildRoot = Join-Path $env:HOME "debbuild-$(Get-Random)"
+ $debianDir = Join-Path $debBuildRoot "DEBIAN"
+ $dataDir = Join-Path $debBuildRoot "data"
+
+ try {
+ New-Item -ItemType Directory -Path $debianDir -Force | Out-Null
+ New-Item -ItemType Directory -Path $dataDir -Force | Out-Null
+
+ # Calculate installed size (in KB)
+ $installedSize = 0
+ Get-ChildItem -Path $Staging -Recurse -File | ForEach-Object { $installedSize += $_.Length }
+ $installedSize += (Get-Item $ManGzipFile).Length
+ $installedSizeKB = [Math]::Ceiling($installedSize / 1024)
+
+ # Create control file with all fields in proper order
+ # Description must be single line (first line) followed by extended description with leading space
+ $descriptionLines = $Description -split "`n"
+ $shortDescription = $descriptionLines[0]
+ $extendedDescription = if ($descriptionLines.Count -gt 1) {
+ ($descriptionLines[1..($descriptionLines.Count-1)] | ForEach-Object { " $_" }) -join "`n"
+ }
+
+ $controlContent = @"
+Package: $Name
+Version: $Version-$Iteration
+Architecture: $HostArchitecture
+Maintainer: PowerShell Team
+Installed-Size: $installedSizeKB
+Priority: optional
+Section: shells
+Homepage: https://microsoft.com/powershell
+Depends: $(if ($Dependencies) { $Dependencies -join ', ' })
+Description: $shortDescription
+$(if ($extendedDescription) { $extendedDescription + "`n" })
+"@
+
+ $controlFile = Join-Path $debianDir "control"
+ $controlContent | Out-File -FilePath $controlFile -Encoding ascii -NoNewline
+
+ Write-Verbose "Control file created: $controlFile" -Verbose
+ Write-LogGroup -Title "DEB Control File Content" -Message $controlContent
+
+ # Copy postinst script if provided
+ if ($AfterInstallScript -and (Test-Path $AfterInstallScript)) {
+ $postinstFile = Join-Path $debianDir "postinst"
+ Copy-Item -Path $AfterInstallScript -Destination $postinstFile -Force
+ Start-NativeExecution { chmod 755 $postinstFile }
+ Write-Verbose "Postinst script copied to: $postinstFile" -Verbose
+ }
+
+ # Copy postrm script if provided
+ if ($AfterRemoveScript -and (Test-Path $AfterRemoveScript)) {
+ $postrmFile = Join-Path $debianDir "postrm"
+ Copy-Item -Path $AfterRemoveScript -Destination $postrmFile -Force
+ Start-NativeExecution { chmod 755 $postrmFile }
+ Write-Verbose "Postrm script copied to: $postrmFile" -Verbose
+ }
+
+ # Copy staging files to data directory
+ $targetPath = Join-Path $dataDir $Destination.TrimStart('/')
+ New-Item -ItemType Directory -Path $targetPath -Force | Out-Null
+ Copy-Item -Path "$Staging/*" -Destination $targetPath -Recurse -Force
+ Write-Verbose "Copied staging files to: $targetPath" -Verbose
+
+ # Copy man page
+ $manDestPath = Join-Path $dataDir $ManDestination.TrimStart('/')
+ $manDestDir = Split-Path $manDestPath -Parent
+ New-Item -ItemType Directory -Path $manDestDir -Force | Out-Null
+ Copy-Item -Path $ManGzipFile -Destination $manDestPath -Force
+ Write-Verbose "Copied man page to: $manDestPath" -Verbose
+
+ # Copy symlinks from temporary locations
+ foreach ($link in $LinkInfo) {
+ $linkPath = Join-Path $dataDir $link.Destination.TrimStart('/')
+ $linkDir = Split-Path $linkPath -Parent
+ New-Item -ItemType Directory -Path $linkDir -Force | Out-Null
+
+ # Copy the temporary symlink file that was created by New-LinkInfo
+ # The Source contains a temporary symlink that points to the correct target
+ if (Test-Path $link.Source) {
+ # Use cp to preserve the symlink
+ Start-NativeExecution { cp -P $link.Source $linkPath }
+ Write-Verbose "Copied symlink: $linkPath (from $($link.Source))" -Verbose
+ } else {
+ Write-Warning "Symlink source not found: $($link.Source)"
+ }
+ }
+
+ # Set proper permissions
+ Write-Verbose "Setting file permissions..." -Verbose
+ # 755 = rwxr-xr-x (owner can read/write/execute, group and others can read/execute)
+ Get-ChildItem $dataDir -Directory -Recurse | ForEach-Object {
+ Start-NativeExecution { chmod 755 $_.FullName }
+ }
+ # 644 = rw-r--r-- (owner can read/write, group and others can read only)
+ # Exclude symlinks to avoid "cannot operate on dangling symlink" error
+ Get-ChildItem $dataDir -File -Recurse |
+ Where-Object { -not $_.Target } |
+ ForEach-Object {
+ Start-NativeExecution { chmod 644 $_.FullName }
+ }
+
+ # Set executable permission for pwsh if it exists
+ # 755 = rwxr-xr-x (executable permission)
+ $pwshPath = "$targetPath/pwsh"
+ if (Test-Path $pwshPath) {
+ Start-NativeExecution { chmod 755 $pwshPath }
+ }
+
+ # Calculate md5sums for all files in data directory (excluding symlinks)
+ $md5sumsFile = Join-Path $debianDir "md5sums"
+ $md5Content = ""
+ Get-ChildItem -Path $dataDir -Recurse -File |
+ Where-Object { -not $_.Target } |
+ ForEach-Object {
+ $relativePath = $_.FullName.Substring($dataDir.Length + 1)
+ $md5Hash = (Get-FileHash -Path $_.FullName -Algorithm MD5).Hash.ToLower()
+ $md5Content += "$md5Hash $relativePath`n"
+ }
+ $md5Content | Out-File -FilePath $md5sumsFile -Encoding ascii -NoNewline
+ Write-Verbose "MD5 sums file created: $md5sumsFile" -Verbose
+
+ # Build the package using dpkg-deb
+ $debFileName = "${Name}_${Version}-${Iteration}_${HostArchitecture}.deb"
+ $debFilePath = Join-Path $CurrentLocation $debFileName
+
+ Write-Verbose "Building DEB package: $debFileName" -Verbose
+
+ # Copy DEBIAN directory and data files to build root
+ $buildDir = Join-Path $debBuildRoot "build"
+ New-Item -ItemType Directory -Path $buildDir -Force | Out-Null
+
+ Write-Verbose "debianDir: $debianDir" -Verbose
+ Write-Verbose "dataDir: $dataDir" -Verbose
+ Write-Verbose "buildDir: $buildDir" -Verbose
+
+ # Use cp to preserve symlinks
+ Start-NativeExecution { cp -a $debianDir "$buildDir/DEBIAN" }
+ Start-NativeExecution { cp -a $dataDir/* $buildDir }
+
+ # Build package with dpkg-deb
+ Start-NativeExecution -VerboseOutputOnError {
+ dpkg-deb --build $buildDir $debFilePath
+ }
+
+ if (Test-Path $debFilePath) {
+ Write-Log "Successfully created DEB package: $debFileName"
+ return @{
+ PackagePath = $debFilePath
+ PackageName = $debFileName
+ }
+ } else {
+ throw "DEB package file not found after build: $debFilePath"
+ }
+ }
+ finally {
+ # Cleanup temporary directory
+ if (Test-Path $debBuildRoot) {
+ Write-Verbose "Cleaning up temporary build directory: $debBuildRoot" -Verbose
+ Remove-Item -Path $debBuildRoot -Recurse -Force -ErrorAction SilentlyContinue
+ }
}
+}
- return $Arguments
+function New-MacOSPackage
+{
+ [CmdletBinding(SupportsShouldProcess=$true)]
+ param(
+ [Parameter(Mandatory)]
+ [string]$Name,
+
+ [Parameter(Mandatory)]
+ [string]$Version,
+
+ [Parameter(Mandatory)]
+ [string]$Iteration,
+
+ [Parameter(Mandatory)]
+ [string]$Staging,
+
+ [Parameter(Mandatory)]
+ [string]$Destination,
+
+ [Parameter(Mandatory)]
+ [string]$ManGzipFile,
+
+ [Parameter(Mandatory)]
+ [string]$ManDestination,
+
+ [Parameter(Mandatory)]
+ [LinkInfo[]]$LinkInfo,
+
+ [Parameter(Mandatory)]
+ [string]$AfterInstallScript,
+
+ [Parameter(Mandatory)]
+ [string]$AppsFolder,
+
+ [Parameter(Mandatory)]
+ [string]$HostArchitecture,
+
+ [string]$CurrentLocation = (Get-Location)
+ )
+
+ Write-Log "Creating macOS package using pkgbuild and productbuild..."
+
+ # Create a temporary directory for package building
+ $tempRoot = New-TempFolder
+ $componentPkgPath = Join-Path $tempRoot "component.pkg"
+ $scriptsDir = Join-Path $tempRoot "scripts"
+ $resourcesDir = Join-Path $tempRoot "resources"
+ $distributionFile = Join-Path $tempRoot "distribution.xml"
+
+ try {
+ # Create scripts directory
+ New-Item -ItemType Directory -Path $scriptsDir -Force | Out-Null
+
+ # Copy and prepare the postinstall script
+ $postInstallPath = Join-Path $scriptsDir "postinstall"
+ Copy-Item -Path $AfterInstallScript -Destination $postInstallPath -Force
+ Start-NativeExecution {
+ chmod 755 $postInstallPath
+ }
+
+ # Create a temporary directory for the package root
+ $pkgRoot = Join-Path $tempRoot "pkgroot"
+ New-Item -ItemType Directory -Path $pkgRoot -Force | Out-Null
+
+ # Copy staging files to destination path in package root
+ $destInPkg = Join-Path $pkgRoot $Destination
+ New-Item -ItemType Directory -Path $destInPkg -Force | Out-Null
+ Write-Verbose "Copying staging files from $Staging to $destInPkg" -Verbose
+ Copy-Item -Path "$Staging/*" -Destination $destInPkg -Recurse -Force
+
+ # Create man page directory structure
+ $manDir = Join-Path $pkgRoot (Split-Path $ManDestination -Parent)
+ New-Item -ItemType Directory -Path $manDir -Force | Out-Null
+ Copy-Item -Path $ManGzipFile -Destination (Join-Path $pkgRoot $ManDestination) -Force
+
+ # Create symlinks in package root
+ # The LinkInfo contains Source (a temp file that IS a symlink) and Destination (where to install it)
+ foreach ($link in $LinkInfo) {
+ $linkDestDir = Join-Path $pkgRoot (Split-Path $link.Destination -Parent)
+ New-Item -ItemType Directory -Path $linkDestDir -Force | Out-Null
+ $finalLinkPath = Join-Path $pkgRoot $link.Destination
+
+ Write-Verbose "Creating symlink at $finalLinkPath" -Verbose
+
+ # Remove if exists
+ if (Test-Path $finalLinkPath) {
+ Remove-Item $finalLinkPath -Force
+ }
+
+ # Get the target of the original symlink and recreate it in the package root
+ if (Test-Path $link.Source) {
+ $linkTarget = (Get-Item $link.Source).Target
+ if ($linkTarget) {
+ Write-Verbose "Creating symlink to target: $linkTarget" -Verbose
+ New-Item -ItemType SymbolicLink -Path $finalLinkPath -Target $linkTarget -Force | Out-Null
+ } else {
+ Write-Warning "Could not determine target for symlink at $($link.Source), copying file instead"
+ Copy-Item -Path $link.Source -Destination $finalLinkPath -Force
+ }
+ } else {
+ Write-Warning "Source symlink $($link.Source) does not exist"
+ }
+ }
+
+ # Copy launcher app folder if provided
+ if ($AppsFolder) {
+ $appsInPkg = Join-Path $pkgRoot "Applications"
+ New-Item -ItemType Directory -Path $appsInPkg -Force | Out-Null
+ Write-Verbose "Copying launcher app from $AppsFolder to $appsInPkg" -Verbose
+ Copy-Item -Path "$AppsFolder/*" -Destination $appsInPkg -Recurse -Force
+ }
+
+ # Build the component package using pkgbuild
+ $pkgIdentifier = Get-MacOSPackageId -IsPreview:($Name -like '*-preview')
+
+ if ($PSCmdlet.ShouldProcess("Build component package with pkgbuild")) {
+ Write-Log "Running pkgbuild to create component package..."
+
+ Start-NativeExecution -VerboseOutputOnError {
+ pkgbuild --root $pkgRoot `
+ --identifier $pkgIdentifier `
+ --version $Version `
+ --scripts $scriptsDir `
+ --install-location "/" `
+ $componentPkgPath
+ }
+
+ Write-Verbose "Component package created: $componentPkgPath" -Verbose
+ }
+
+ # Create the final distribution package using the refactored function
+ $distributionPackage = New-MacOsDistributionPackage `
+ -ComponentPackage (Get-Item $componentPkgPath) `
+ -PackageName $Name `
+ -Version $Version `
+ -OutputDirectory $CurrentLocation `
+ -HostArchitecture $HostArchitecture `
+ -PackageIdentifier $pkgIdentifier `
+ -IsPreview:($Name -like '*-preview')
+
+ return $distributionPackage
+ }
+ finally {
+ # Clean up temporary directory
+ if (Test-Path $tempRoot) {
+ Write-Verbose "Cleaning up temporary directory: $tempRoot" -Verbose
+ Remove-Item -Path $tempRoot -Recurse -Force -ErrorAction SilentlyContinue
+ }
+ }
}
function Get-PackageDependencies
@@ -1606,6 +2125,22 @@ function Get-PackageDependencies
# These should match those in the Dockerfiles, but exclude tools like Git, which, and curl
$Dependencies = @()
+
+ # ICU version range follows .NET runtime policy.
+ # See: https://github.com/dotnet/runtime/blob/3fe8518d51bbcaa179bbe275b2597fbe1b88bc5a/src/native/libs/System.Globalization.Native/pal_icushim.c#L235-L243
+ #
+ # Version range rationale:
+ # - The runtime supports ICU versions >= the version it was built against
+ # and <= that version + 30, to allow sufficient headroom for future releases.
+ # - ICU typically releases about twice per year, so +30 provides roughly
+ # 15 years of forward compatibility.
+ # - On some platforms, the minimum supported version may be lower
+ # than the build version and we know that older versions just works.
+ #
+ $MinICUVersion = 60 # runtime minimum supported
+ $BuildICUVersion = 76 # current build version
+ $MaxICUVersion = $BuildICUVersion + 30 # headroom
+
if ($Distribution -eq 'deb') {
$Dependencies = @(
"libc6",
@@ -1613,10 +2148,9 @@ function Get-PackageDependencies
"libgssapi-krb5-2",
"libstdc++6",
"zlib1g",
- "libicu76|libicu74|libicu72|libicu71|libicu70|libicu69|libicu68|libicu67|libicu66|libicu65|libicu63|libicu60|libicu57|libicu55|libicu52",
+ (($MaxICUVersion..$MinICUVersion).ForEach{ "libicu$_" } -join '|'),
"libssl3|libssl1.1|libssl1.0.2|libssl1.0.0"
)
-
} elseif ($Distribution -eq 'rh') {
$Dependencies = @(
"openssl-libs",
@@ -1651,25 +2185,25 @@ function Get-PackageDependencies
function Test-Dependencies
{
- foreach ($Dependency in "fpm") {
- if (!(precheck $Dependency "Package dependency '$Dependency' not found. Run Start-PSBootstrap -Scenario Package")) {
- # These tools are not added to the path automatically on OpenSUSE 13.2
- # try adding them to the path and re-tesing first
- [string] $gemsPath = $null
- [string] $depenencyPath = $null
- $gemsPath = Get-ChildItem -Path /usr/lib64/ruby/gems | Sort-Object -Property LastWriteTime -Descending | Select-Object -First 1 -ExpandProperty FullName
- if ($gemsPath) {
- $depenencyPath = Get-ChildItem -Path (Join-Path -Path $gemsPath -ChildPath "gems" -AdditionalChildPath $Dependency) -Recurse | Sort-Object -Property LastWriteTime -Descending | Select-Object -First 1 -ExpandProperty DirectoryName
- $originalPath = $env:PATH
- $env:PATH = $ENV:PATH +":" + $depenencyPath
- if ((precheck $Dependency "Package dependency '$Dependency' not found. Run Start-PSBootstrap -Scenario Package")) {
- continue
- }
- else {
- $env:PATH = $originalPath
- }
- }
+ # RPM packages use rpmbuild directly.
+ # DEB packages use dpkg-deb directly.
+ # macOS packages use pkgbuild and productbuild from Xcode Command Line Tools.
+ $Dependencies = @()
+
+ # Check for 'rpmbuild' and 'dpkg-deb' on Azure Linux.
+ if ($Environment.IsMariner) {
+ $Dependencies += "dpkg-deb"
+ $Dependencies += "rpmbuild"
+ }
+
+ # Check for macOS packaging tools
+ if ($Environment.IsMacOS) {
+ $Dependencies += "pkgbuild"
+ $Dependencies += "productbuild"
+ }
+ foreach ($Dependency in $Dependencies) {
+ if (!(precheck $Dependency "Package dependency '$Dependency' not found. Run Start-PSBootstrap -Scenario Package")) {
throw "Dependency precheck failed!"
}
}
@@ -1824,10 +2358,12 @@ function New-MacOSLauncher
# Set permissions for plist and shell script.
Start-NativeExecution {
chmod 644 $plist
+ }
+ Start-NativeExecution {
chmod 755 $shellscript
}
- # Add app folder to fpm paths.
+ # Return the app folder path for packaging
$appsfolder = (Resolve-Path -Path "$macosapp/..").Path
return $appsfolder
@@ -5009,8 +5545,24 @@ function Send-AzdoFile {
Copy-Item -Path $Path -Destination $logFile
}
- Write-Host "##vso[artifact.upload containerfolder=$newName;artifactname=$newName]$logFile"
- Write-Verbose "Log file captured as $newName" -Verbose
+ Write-Verbose "Capture the log file as '$newName'" -Verbose
+ if($env:TF_BUILD) {
+ ## In Azure DevOps
+ Write-Host "##vso[artifact.upload containerfolder=$newName;artifactname=$newName]$logFile"
+ } elseif ($env:GITHUB_WORKFLOW -and $env:SYSTEM_ARTIFACTSDIRECTORY) {
+ ## In GitHub Actions
+ $destinationPath = $env:SYSTEM_ARTIFACTSDIRECTORY
+ Write-Verbose "Upload '$logFile' to '$destinationPath' in GitHub Action" -Verbose
+
+ # Create the folder if it does not exist
+ if (!(Test-Path -Path $destinationPath)) {
+ $null = New-Item -ItemType Directory -Path $destinationPath -Force
+ }
+
+ Copy-Item -Path $logFile -Destination $destinationPath -Force -Verbose
+ } else {
+ Write-Warning "This environment is neither Azure Devops nor GitHub Actions. Cannot capture the log file in this environment."
+ }
}
# Class used for serializing and deserialing a BOM into Json