[release/v7.4] Optimize/split windows package signing (#26413)

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
Travis Plunk
2025-11-10 12:05:43 -08:00
committed by GitHub
co-authored by Copilot
parent 7a63d92aa1
commit ac01f2de00
24 changed files with 971 additions and 242 deletions
@@ -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 <target-branch>..<source-branch> --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 <source-branch> --oneline -10`
- `git log <target-branch> --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 <sha1>` for single commits
- Or: `git cherry-pick <sha1> <sha2> <sha3>` 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 <target-branch> -<number-of-commits> --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 <target>..<source> --oneline --reverse
# Compare recent commits on each branch (more reliable for rebased branches)
git log <source-branch> --oneline -10
git log <target-branch> --oneline -10
# Cherry-pick specific commits (when target is checked out)
git cherry-pick <sha1>
git cherry-pick <sha1> <sha2> <sha3>
# Skip empty commits
git cherry-pick --skip
# Verify result
git log <target-branch> -<count> --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
@@ -4,6 +4,7 @@ applyTo:
- "tools/ci.psm1"
- ".github/**/*.yml"
- ".github/**/*.yaml"
- ".pipelines/**/*.yml"
---
# Build Configuration Guide
@@ -121,7 +122,7 @@ The `Switch-PSNugetConfig` function in `build.psm1` manages NuGet package source
- **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
@@ -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.
@@ -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:`)
@@ -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`
@@ -165,7 +165,6 @@ extends:
parameters:
ReleaseTagVar: $(ReleaseTagVar)
CreateJson: yes
UseJson: no
- stage: macos
displayName: macOS - build and sign
+48 -14
View File
@@ -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,19 @@ 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
- 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
-1
View File
@@ -159,7 +159,6 @@ extends:
parameters:
ReleaseTagVar: $(ReleaseTagVar)
CreateJson: yes
UseJson: no
- pwsh: |
$version = '$(Version)'
+16 -47
View File
@@ -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 detect 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")
@@ -51,7 +20,7 @@ steps:
$REPOROOT = $env:REPOROOT
if (-not (Test-Path $REPOROOT/tools/releaseBuild/setReleaseTag.ps1)) {
if ((Test-Path "$REPOROOT/PowerShell/tools/releaseBuild/setReleaseTag.ps1")) {
if (Test-Path "$REPOROOT/PowerShell/tools/releaseBuild/setReleaseTag.ps1") {
$REPOROOT = "$REPOROOT/PowerShell"
} else {
throw "Could not find setReleaseTag.ps1 in $REPOROOT/tools/releaseBuild or $REPOROOT/PowerShell/tools/releaseBuild"
@@ -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 9999 -Stream | write-Verbose -Verbose
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 }}
+2 -1
View File
@@ -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
+15 -3
View File
@@ -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 }}
+1 -2
View File
@@ -51,8 +51,7 @@ jobs:
- template: ../SetVersionVariables.yml
parameters:
ReleaseTagVar: $(ReleaseTagVar)
CreateJson: yes
UseJson: no
CreateJson: no
- template: ../insert-nuget-config-azfeed.yml
parameters:
+6 -1
View File
@@ -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 }}
+1 -2
View File
@@ -54,8 +54,7 @@ jobs:
- template: SetVersionVariables.yml@self
parameters:
ReleaseTagVar: $(ReleaseTagVar)
CreateJson: yes
UseJson: no
CreateJson: no
- template: shouldSign.yml
+1 -2
View File
@@ -52,8 +52,7 @@ jobs:
- template: SetVersionVariables.yml@self
parameters:
ReleaseTagVar: $(ReleaseTagVar)
CreateJson: yes
UseJson: no
CreateJson: no
- template: shouldSign.yml
+1 -2
View File
@@ -41,8 +41,7 @@ jobs:
- template: SetVersionVariables.yml@self
parameters:
ReleaseTagVar: $(ReleaseTagVar)
CreateJson: yes
UseJson: no
CreateJson: no
- template: shouldSign.yml
+3 -3
View File
@@ -22,7 +22,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'
@@ -31,7 +31,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'
@@ -40,7 +40,7 @@ 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'
@@ -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,35 @@ 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
- 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 +76,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)'
@@ -178,94 +171,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' }
@@ -278,35 +196,25 @@ 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"
Write-Verbose -Verbose "unsigned 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 "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 "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
displayName: 'List artifacts'
env:
ob_restore_phase: true # This ensures this done in restore phase to workaround signing issue
displayName: 'List unsigned artifacts'
@@ -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
@@ -44,8 +44,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
@@ -131,8 +130,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
@@ -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
+35
View File
@@ -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 }}
+6 -1
View File
@@ -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 }}
+1 -2
View File
@@ -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