Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions .github/actions/infrastructure/path-filters/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,12 +88,14 @@ runs:

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 packagingChanged = files.some(file =>
const packagingChanged = files.some(file =>
file.filename === '.github/workflows/windows-ci.yml' ||
file.filename === '.github/workflows/linux-ci.yml' ||
file.filename.startsWith('assets/wix/') ||
file.filename === 'PowerShell.Common.props' ||
file.filename.match(/^src\/.*\.csproj$/) ||
file.filename.startsWith('test/packaging/windows/') ||
file.filename.startsWith('test/packaging/linux/') ||
file.filename.startsWith('tools/packaging/') ||
file.filename.startsWith('tools/wix/')
) ||
Expand All @@ -112,7 +114,7 @@ runs:
core.setOutput('globalConfigChanged', globalConfigChanged);
core.setOutput('packagingChanged', packagingChanged);
core.setOutput('source', source);


- name: Capture outputs
run: |
Expand Down
59 changes: 5 additions & 54 deletions .github/actions/test/linux-packaging/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,68 +13,19 @@ runs:
with:
global-json-file: ./global.json

- name: Download Build Artifacts
uses: actions/download-artifact@v4
with:
name: build
path: "${{ runner.workspace }}/build"

- name: Capture Artifacts Directory
continue-on-error: true
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: 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: Fix permissions
continue-on-error: true
run: |-
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 "${{ runner.workspace }}/bins/*" -Recurse -ErrorAction SilentlyContinue
Import-Module ./tools/ci.psm1
Invoke-CIInstall -SkipUser
shell: pwsh

- name: Create Packages
env:
BUILD_ARTIFACTSTAGINGDIRECTORY: ${{ runner.workspace }}/packages
- name: Build and Package
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 '${{ runner.workspace }}/build/psoptions.json'
$options = (Get-PSOptions)
$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'
chmod a+x $pwshPath
$options.Output = $pwshPath
Set-PSOptions $options
$releaseTag = Get-ReleaseTag
Start-PSBuild -Configuration 'Release' -ReleaseTag $releaseTag
Invoke-CIFinish
shell: pwsh

Expand Down
127 changes: 127 additions & 0 deletions .github/instructions/build-and-packaging-steps.instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
---
applyTo:
- ".github/actions/**/*.yml"
- ".github/workflows/**/*.yml"
---

# Build and Packaging Steps Pattern

## Important Rule

**Build and packaging must run in the same step OR you must save and restore PSOptions between steps.**

## Why This Matters

When `Start-PSBuild` runs, it creates PSOptions that contain build configuration details (runtime, configuration, output path, etc.). The packaging functions like `Start-PSPackage` and `Invoke-CIFinish` rely on these PSOptions to know where the build output is located and how it was built.

GitHub Actions steps run in separate PowerShell sessions. This means PSOptions from one step are not available in the next step.

## Pattern 1: Combined Build and Package (Recommended)

Run build and packaging in the same step to keep PSOptions in memory:

```yaml
- name: Build and Package
run: |-
Import-Module ./tools/ci.psm1
$releaseTag = Get-ReleaseTag
Start-PSBuild -Configuration 'Release' -ReleaseTag $releaseTag
Invoke-CIFinish
shell: pwsh
```

**Benefits:**
- Simpler code
- No need for intermediate files
- PSOptions automatically available to packaging

## Pattern 2: Separate Steps with Save/Restore

If you must separate build and packaging into different steps:

```yaml
- name: Build PowerShell
run: |-
Import-Module ./tools/ci.psm1
$releaseTag = Get-ReleaseTag
Start-PSBuild -Configuration 'Release' -ReleaseTag $releaseTag
Save-PSOptions -PSOptionsPath "${{ runner.workspace }}/psoptions.json"
shell: pwsh

- name: Create Packages
run: |-
Import-Module ./tools/ci.psm1
Restore-PSOptions -PSOptionsPath "${{ runner.workspace }}/psoptions.json"
Invoke-CIFinish
shell: pwsh
```

**When to use:**
- When you need to run other steps between build and packaging
- When build and packaging require different permissions or environments

## Common Mistakes

### ❌ Incorrect: Separate steps without save/restore

```yaml
- name: Build PowerShell
run: |-
Start-PSBuild -Configuration 'Release'
shell: pwsh

- name: Create Packages
run: |-
Invoke-CIFinish # ❌ FAILS: PSOptions not available
shell: pwsh
```

### ❌ Incorrect: Using artifacts without PSOptions

```yaml
- name: Download Build Artifacts
uses: actions/download-artifact@v4
with:
name: build

- name: Create Packages
run: |-
Invoke-CIFinish # ❌ FAILS: PSOptions not restored
shell: pwsh
```

## Related Functions

- `Start-PSBuild` - Builds PowerShell and sets PSOptions
- `Save-PSOptions` - Saves PSOptions to a JSON file
- `Restore-PSOptions` - Loads PSOptions from a JSON file
- `Get-PSOptions` - Gets current PSOptions
- `Set-PSOptions` - Sets PSOptions
- `Start-PSPackage` - Creates packages (requires PSOptions)
- `Invoke-CIFinish` - Calls packaging (requires PSOptions on Linux/macOS)

## Examples

### Linux Packaging Action

```yaml
- name: Build and Package
run: |-
Import-Module ./tools/ci.psm1
$releaseTag = Get-ReleaseTag
Start-PSBuild -Configuration 'Release' -ReleaseTag $releaseTag
Invoke-CIFinish
shell: pwsh
```

### Windows Packaging Workflow

```yaml
- name: Build and Package
run: |
Import-Module .\tools\ci.psm1
Invoke-CIFinish -Runtime ${{ matrix.runtimePrefix }}-${{ matrix.architecture }} -channel ${{ matrix.channel }}
shell: pwsh
```

Note: `Invoke-CIFinish` for Windows includes both build and packaging in its logic when `Stage` contains 'Build'.
1 change: 0 additions & 1 deletion .github/workflows/linux-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,6 @@ jobs:
linux_packaging:
name: Linux Packaging
needs:
- ci_build
- changes
if: ${{ needs.changes.outputs.packagingChanged == 'true' }}
runs-on: ubuntu-latest
Expand Down
Loading