Skip to content
Closed
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
182 changes: 131 additions & 51 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,14 @@ jobs:
shell: pwsh
run: ./scripts/test-ci-workflow-contract.ps1

- name: Validate MSIX CI artifacts
shell: pwsh
run: ./scripts/test-msix-ci-artifacts.ps1

- name: Validate Store MSIX alpha release assets
shell: pwsh
run: ./scripts/test-msix-alpha-release.ps1

- name: Validate stable correction release ordering regressions
shell: pwsh
run: ./scripts/test-stable-correction-release-validator.ps1
Expand Down Expand Up @@ -154,6 +162,7 @@ jobs:
majorMinorPatch: ${{ steps.release_version.outputs.majorMinorPatch }}
isPrerelease: ${{ steps.release_version.outputs.isPrerelease }}
isStableCorrection: ${{ steps.release_version.outputs.isStableCorrection }}
isMsixAlpha: ${{ steps.release_version.outputs.isMsixAlpha }}
steps:
- uses: actions/checkout@v7
with:
Expand Down Expand Up @@ -212,6 +221,8 @@ jobs:
"majorMinorPatch=$majorMinorPatch" >> $env:GITHUB_OUTPUT
"isPrerelease=$($isPrerelease.ToString().ToLowerInvariant())" >> $env:GITHUB_OUTPUT
"isStableCorrection=$($isStableCorrection.ToString().ToLowerInvariant())" >> $env:GITHUB_OUTPUT
$isMsixAlpha = $isPrerelease -and ($env:GITHUB_REF -cmatch '^refs/tags/v(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)-alpha\.(?:0|[1-9]\d*)$')
"isMsixAlpha=$($isMsixAlpha.ToString().ToLowerInvariant())" >> $env:GITHUB_OUTPUT

core-tests:
name: Core and CLI tests
Expand Down Expand Up @@ -808,37 +819,28 @@ jobs:
path: publish/

build-msix:
needs: [metadata]
if: false # MSIX distribution is paused; ship Inno setup and portable ZIP artifacts only.
runs-on: ${{ matrix.rid == 'win-arm64' && 'windows-11-arm' || 'windows-latest' }}
continue-on-error: true
name: MSIX artifacts (${{ matrix.architecture }})
needs: [change-classification, metadata]
if: ${{ !cancelled() && needs.change-classification.result == 'success' && needs.metadata.result == 'success' && (needs.change-classification.outputs.x64_release == 'true' || needs.change-classification.outputs.arm64_release == 'true') }}
# Unsigned Store packages may publish to alpha releases only. Dev packages stay workflow-only.
runs-on: ${{ matrix.architecture == 'arm64' && 'windows-11-arm' || 'windows-latest' }}
env:
OPENCLAW_BUILD_VERSION: ${{ needs.metadata.outputs.semVer }}
DEV_MSIX_REVISION: ${{ github.run_number }}
strategy:
fail-fast: false
matrix:
rid: [win-x64, win-arm64]
include:
- rid: win-x64
platform: x64
- rid: win-arm64
platform: ARM64
architecture: [x64, arm64]

steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0

- name: Setup .NET 10 for VS MSBuild
- name: Setup .NET from global.json
uses: actions/setup-dotnet@v6
with:
dotnet-version: 10.0.100

- name: Pin .NET SDK for MSIX packaging
shell: pwsh
run: |
$globalJson = Get-Content global.json -Raw | ConvertFrom-Json
$globalJson.sdk.rollForward = "disable"
$globalJson | ConvertTo-Json -Depth 5 | Set-Content global.json
dotnet --version
global-json-file: global.json

- name: Cache NuGet packages
continue-on-error: true
Expand All @@ -848,48 +850,98 @@ jobs:
key: nuget-${{ runner.os }}-${{ hashFiles('**/*.csproj', '**/Directory.Packages.props') }}
restore-keys: nuget-${{ runner.os }}-

- name: Setup MSBuild
uses: microsoft/setup-msbuild@v3
- name: Select MSIX artifact version
id: msix_version
shell: pwsh
env:
BUILD_EVENT: ${{ github.event_name }}
PR_HEAD_REPOSITORY: ${{ github.event.pull_request.head.repo.full_name }}
PR_HEAD_BRANCH: ${{ github.head_ref }}
run: |
$baseVersionOverride = ''
# Temporary first-Store-submission exception for this PR branch. Remove before merge.
if ($env:BUILD_EVENT -eq 'pull_request' -and
$env:PR_HEAD_REPOSITORY -eq 'natalie-aguinaldo/openclaw-windows-node' -and
$env:PR_HEAD_BRANCH -eq 'user/natalie-aguinaldo/msix-ci-artifacts-versioning') {
$baseVersionOverride = '2026.9.4'
}
$expectedDevVersion = if ($baseVersionOverride) { $baseVersionOverride } else { $env:OPENCLAW_BUILD_VERSION }
"baseVersionOverride=$baseVersionOverride" >> $env:GITHUB_OUTPUT
"expectedDevVersion=$expectedDevVersion" >> $env:GITHUB_OUTPUT

- name: Restore
run: dotnet restore src/OpenClaw.Tray.WinUI -r ${{ matrix.rid }}
- name: Build and validate unsigned Store MSIX
shell: pwsh
env:
BUILD_ARCHITECTURE: ${{ matrix.architecture }}
MSIX_BASE_VERSION_OVERRIDE: ${{ steps.msix_version.outputs.baseVersionOverride }}
run: |
$buildArguments = @{ Architecture = $env:BUILD_ARCHITECTURE }
if ($env:MSIX_BASE_VERSION_OVERRIDE) {
$buildArguments.StorePackageVersion = "$($env:MSIX_BASE_VERSION_OVERRIDE).0"
}
.\scripts\Build-StoreMsix.ps1 @buildArguments

- name: Build MSIX Package
run: >
msbuild src/OpenClaw.Tray.WinUI/OpenClaw.Tray.WinUI.csproj
/p:Configuration=Release
/p:RuntimeIdentifier=${{ matrix.rid }}
/p:Platform=${{ matrix.platform }}
/p:PackageMsix=true
/p:GenerateAppxPackageOnBuild=true
/p:AppxPackageSigningEnabled=false
/p:AppxBundle=Never
/p:UapAppxPackageBuildMode=SideloadOnly
/p:AppxPackageDir=AppPackages\

- name: Find MSIX Package
id: find-msix
- name: Upload unsigned Store submission artifact
uses: actions/upload-artifact@v7
with:
name: openclaw-msix-store-unsigned-${{ matrix.architecture }}
path: |
artifacts/msix/${{ matrix.architecture }}/OpenClaw-${{ matrix.architecture }}.msix
artifacts/msix/${{ matrix.architecture }}/msix-metadata.json
if-no-files-found: error

- name: Provision disposable Dev MSIX certificate
shell: pwsh
run: .\scripts\setup-dev-msix-cert.ps1

- name: Build signed Dev MSIX
shell: pwsh
env:
MSIX_BASE_VERSION_OVERRIDE: ${{ steps.msix_version.outputs.baseVersionOverride }}
run: |
$msix = Get-ChildItem -Path src/OpenClaw.Tray.WinUI/AppPackages -Recurse -Filter "*.msix" -ErrorAction SilentlyContinue | Select-Object -First 1
if (-not $msix) {
Write-Error "No MSIX package found in AppPackages directory"
exit 1
$versionArguments = @{}
if ($env:MSIX_BASE_VERSION_OVERRIDE) {
$versionArguments.MsixBaseVersion = $env:MSIX_BASE_VERSION_OVERRIDE
}
Write-Host "Found: $($msix.FullName)"
echo "msix_path=$($msix.FullName)" >> $env:GITHUB_OUTPUT
echo "msix_name=$($msix.Name)" >> $env:GITHUB_OUTPUT
.\build.ps1 -Project WinUI -Configuration Release -Msix Dev `
-MsixRevision $env:DEV_MSIX_REVISION `
-MsixOutputDirectory "$env:RUNNER_TEMP\openclaw-dev-appx" `
@versionArguments

- name: Upload MSIX Artifact
- name: Validate and stage Dev tester artifact
shell: pwsh
env:
EXPECTED_DEV_VERSION: ${{ steps.msix_version.outputs.expectedDevVersion }}
run: |
$thumbprint = (Get-Content "$env:LOCALAPPDATA\OpenClawDevelopment\MSIX\dev-msix-thumbprint.txt" -Raw).Trim()
.\scripts\Export-DevMsixArtifact.ps1 `
-Architecture ${{ matrix.architecture }} `
-PackageDirectory "$env:RUNNER_TEMP\openclaw-dev-appx" `
-ExpectedRevision $env:DEV_MSIX_REVISION `
-ExpectedVersion $env:EXPECTED_DEV_VERSION `
-CertificateThumbprint $thumbprint `
-OutputDirectory "artifacts\msix-dev\${{ matrix.architecture }}"

- name: Upload Dev tester artifact
uses: actions/upload-artifact@v7
with:
name: openclaw-msix-${{ matrix.rid }}
path: ${{ steps.find-msix.outputs.msix_path }}
name: openclaw-msix-dev-${{ matrix.architecture }}
path: |
artifacts/msix-dev/${{ matrix.architecture }}/OpenClaw-Dev-${{ matrix.architecture }}.msix
artifacts/msix-dev/${{ matrix.architecture }}/OpenClaw-Dev.cer
artifacts/msix-dev/${{ matrix.architecture }}/msix-metadata.json
artifacts/msix-dev/${{ matrix.architecture }}/INSTALL.txt
if-no-files-found: error

- name: Remove disposable Dev MSIX certificate
if: ${{ always() }}
shell: pwsh
run: .\scripts\setup-dev-msix-cert.ps1 -Remove

ci-gate:
name: CI Gate
if: ${{ always() }}
needs: [change-classification, fast-validation, proof-pool-contracts, metadata, core-tests, tray-tests, ui-tests, setup-e2e, revocation-e2e, network-e2e, build-x64, build-arm64]
needs: [change-classification, fast-validation, proof-pool-contracts, metadata, core-tests, tray-tests, ui-tests, setup-e2e, revocation-e2e, network-e2e, build-x64, build-arm64, build-msix]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
Expand Down Expand Up @@ -919,6 +971,7 @@ jobs:
ARM64_RELEASE_REQUIRED: ${{ needs.change-classification.outputs.arm64_release }}
ARM64_RELEASE_RESULT: ${{ needs.build-arm64.result }}
METADATA_RESULT: ${{ needs.metadata.result }}
MSIX_RESULT: ${{ needs.build-msix.result }}
run: |
$validatedMode = ./scripts/Assert-CiGateResults.ps1 `
-ClassificationResult $env:CLASSIFICATION_RESULT `
Expand All @@ -942,7 +995,8 @@ jobs:
-X64ReleaseResult $env:X64_RELEASE_RESULT `
-Arm64ReleaseRequired $env:ARM64_RELEASE_REQUIRED `
-Arm64ReleaseResult $env:ARM64_RELEASE_RESULT `
-MetadataResult $env:METADATA_RESULT
-MetadataResult $env:METADATA_RESULT `
-MsixResult $env:MSIX_RESULT
"CI Gate passed $validatedMode validation." >> $env:GITHUB_STEP_SUMMARY

release:
Expand Down Expand Up @@ -1150,6 +1204,28 @@ jobs:
-Tag $env:RELEASE_TAG
-GitHubToken $env:GH_TOKEN

- name: Download alpha Store MSIX artifacts
if: needs.metadata.outputs.isMsixAlpha == 'true'
uses: actions/download-artifact@v8
with:
pattern: openclaw-msix-store-unsigned-*
path: artifacts/msix-alpha

- name: Stage alpha Store MSIX release assets
if: needs.metadata.outputs.isMsixAlpha == 'true'
id: msix_alpha
shell: pwsh
env:
RELEASE_VERSION: ${{ needs.metadata.outputs.semVer }}
run: |
$assets = .\scripts\Stage-StoreMsixReleaseAssets.ps1 `
-ArtifactDirectory 'artifacts\msix-alpha' `
-OutputDirectory 'msix-alpha-release' `
-Version $env:RELEASE_VERSION `
-ExpectedSourceCommit $env:GITHUB_SHA
@('files<<MSIX_ALPHA_FILES'; $assets.Files; 'MSIX_ALPHA_FILES') >> $env:GITHUB_OUTPUT
@('notes<<MSIX_ALPHA_NOTES'; $assets.Notes; 'MSIX_ALPHA_NOTES') >> $env:GITHUB_OUTPUT

- name: Create Release
uses: softprops/action-gh-release@v3
with:
Expand All @@ -1159,6 +1235,8 @@ jobs:
Output/OpenClawCompanion-Setup-arm64.exe
OpenClawTray-${{ needs.metadata.outputs.semVer }}-win-x64.zip
OpenClawTray-${{ needs.metadata.outputs.semVer }}-win-arm64.zip
${{ steps.msix_alpha.outputs.files }}
fail_on_unmatched_files: true
prerelease: ${{ needs.metadata.outputs.isPrerelease }}
make_latest: ${{ needs.metadata.outputs.isPrerelease == 'true' && 'false' || 'true' }}
body: |
Expand All @@ -1170,6 +1248,8 @@ jobs:
- **Portable x64**: `OpenClawTray-${{ needs.metadata.outputs.semVer }}-win-x64.zip`
- **Portable ARM64**: `OpenClawTray-${{ needs.metadata.outputs.semVer }}-win-arm64.zip`

${{ steps.msix_alpha.outputs.notes }}

### Features
- 🦞 System tray integration with gateway status
- 🔄 Auto-updates from GitHub Releases
Expand Down
11 changes: 11 additions & 0 deletions .github/workflows/daily-alpha-release.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
name: Daily Alpha Release

on:
workflow_dispatch:
schedule:
- cron: '0 21 * * *'
- cron: '0 22 * * *'
Expand All @@ -21,10 +22,17 @@ jobs:
id: pacific_schedule
shell: bash
env:
EVENT_NAME: ${{ github.event_name }}
SCHEDULE: ${{ github.event.schedule }}
run: |
set -euo pipefail

if [[ "$EVENT_NAME" == "workflow_dispatch" ]]; then
echo "run=true" >> "$GITHUB_OUTPUT"
echo "Manually checking the default branch for a new alpha release."
exit 0
fi

pacific_offset="$(TZ=America/Los_Angeles date +%z)"
case "$pacific_offset" in
-0700) expected_schedule='0 21 * * *' ;;
Expand Down Expand Up @@ -117,6 +125,9 @@ jobs:
if: steps.pacific_schedule.outputs.run == 'true' && steps.previous_release.outputs.changed == 'true'
id: gitversion
uses: gittools/actions/gitversion/execute@7417b1089e2c7de93510f1901d656ddf60bb024f # v4.7.0
with:
# Checkout already selected the full default branch. Ignore a manual dispatch's source ref.
disableNormalization: true

- name: Create or reuse alpha tag
if: steps.pacific_schedule.outputs.run == 'true' && steps.previous_release.outputs.changed == 'true'
Expand Down
Loading
Loading