Skip to content

Build and Package MSI & Portable Installer #240

Build and Package MSI & Portable Installer

Build and Package MSI & Portable Installer #240

name: Build and Package MSI
on:
workflow_dispatch:
inputs:
uploadAsLatest:
type: string
default: "False"
required: false
description: 'Also upload the msi installer to storage account as latest'
version:
type: string
default: ""
required: false
description: 'Version of promptflow to install (optional). Will build locally if not specified.'
set_msi_private_version:
type: string
default: ""
required: false
description: 'Set the version of the private msi installer'
env:
packageSetupType: promptflow_with_extra
testWorkingDirectory: src/promptflow
jobs:
build_msi_installer:
runs-on: windows-latest
name: Build Windows MSI
steps:
- name: Check input parameters
run: |
echo "uploadAsLatest: ${{ inputs.uploadAsLatest }}"
echo "version: ${{ inputs.version }}"
echo "set_msi_private_version: ${{ inputs.set_msi_private_version }}"
- name: Checkout Repo
uses: actions/checkout@v3
with:
submodules: true
- name: Add msbuild to PATH
uses: microsoft/[email protected]
- name: Install WIX Toolset
shell: pwsh
working-directory: ${{ github.workspace }}/scripts/installer/windows
run: |
Invoke-WebRequest -Uri 'https://azurecliprod.blob.core.windows.net/msi/wix310-binaries-mirror.zip' -OutFile 'wix-archive.zip'
Expand-Archive -Path 'wix-archive.zip' -DestinationPath 'wix'
Remove-Item -Path 'wix-archive.zip'
- name: Python Setup
uses: "./.github/actions/step_create_python_environment"
- name: Setup and Install dev promptflow
if: ${{ github.event.inputs.version == null || github.event.inputs.version == '' }}
uses: "./.github/actions/step_sdk_setup"
with:
setupType: promptflow_with_extra
scriptPath: ${{ env.testWorkingDirectory }}
- name: Install stable promptflow
if: ${{ github.event.inputs.version != null && github.event.inputs.version != '' }}
run: |
pip install "promptflow[azure,executable]==$env:INPUT_VERSION" promptflow-tools
env:
INPUT_VERSION: ${{ github.event.inputs.version }}
shell: pwsh
- name: Get promptflow version
id: get-version
# Convert string to int since the version tuple used in "version_info" can't start with 0.
run: |
if ($env:INPUT_VERSION) {
$version=$env:INPUT_VERSION
$run_version=$(python -c "import promptflow; print(promptflow.__version__)")
if ($version -ne $run_version) {
throw "Version input does not match the version in promptflow package. Version input: $version, version in promptflow package: $run_version"
}
}
elseif ($env:MSI_PRIVATE_VERSION) {
$version=$env:MSI_PRIVATE_VERSION
}
else {
$prefix = 0
$year = [int](Get-Date -Format "yy")
$monthday = [int](Get-Date -Format "MMdd")
$hourminutesecond = [int](Get-Date -Format "HHmmss")
$version="$prefix.$year.$monthday.$hourminutesecond"
}
echo "::set-output name=version::$version"
env:
INPUT_VERSION: ${{ github.event.inputs.version }}
MSI_PRIVATE_VERSION: ${{ github.event.inputs.set_msi_private_version }}
shell: pwsh
- name: Build Pyinstaller project
working-directory: ${{ github.workspace }}/scripts/installer/windows/scripts
run: |
echo 'Version from promptflow: ${{ steps.get-version.outputs.version }}'
$text = Get-Content "version_info.txt" -Raw
$versionString = '${{ steps.get-version.outputs.version }}'
$versionArray = $versionString.Split('.')
if ($versionArray.Count -ge 4) {
$versionArray = $versionArray[0..3]
} else {
$remainingLength = 4 - $versionArray.Count
$zerosToAppend = @(0) * $remainingLength
$versionArray += $zerosToAppend
}
$versionTuple = [string]::Join(', ', $versionArray)
$text = $text -replace '\$\((env\.FILE_VERSION)\)', $versionTuple
$text = $text -replace '\$\((env\.CLI_VERSION)\)', '${{ steps.get-version.outputs.version }}'
$text | Out-File -FilePath "version_info.txt" -Encoding utf8
pyinstaller promptflow.spec
shell: pwsh
- name: Build WIX project
working-directory: ${{ github.workspace }}/scripts/installer/windows
run: |
$text = Get-Content "promptflow.wixproj" -Raw
$text = $text -replace '\$\((env\.CLI_VERSION)\)', '${{ steps.get-version.outputs.version }}'
$text | Out-File -FilePath "promptflow.wixproj" -Encoding utf8
$text = Get-Content "product.wxs" -Raw
$text = $text -replace '\$\((env\.CLI_VERSION)\)', '${{ steps.get-version.outputs.version }}'
$text | Out-File -FilePath "product.wxs" -Encoding utf8
msbuild /t:rebuild /p:Configuration=Release /p:Platform=x64 promptflow.wixproj
shell: pwsh
- name: Azure Login
uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- name: Download JSON file from Azure Blob Storage
id: download-json
run: |
az storage blob download --account-name promptflowartifact --container-name msi-installer --name latest_version.json --file downloaded_version.json
$downloaded_version = (Get-Content downloaded_version.json | ConvertFrom-Json).promptflow
echo "::set-output name=downloaded_version::$downloaded_version"
- name: Check if version input is valid and upload JSON file
run: |
$version = "${{ steps.get-version.outputs.version }}"
$downloaded_version = "${{ steps.download-json.outputs.downloaded_version }}"
if ($version -like '1.*' -and [Version]$version -gt [Version]$downloaded_version){
$jsonContent = @{
"promptflow" = $version
} | ConvertTo-Json -Depth 100
$jsonContent | Out-File -FilePath latest_version.json -Encoding UTF8
Write-Output "Created latest_version.json with version: $version"
az storage blob upload --account-name promptflowartifact --container-name msi-installer --file "latest_version.json" --name "latest_version.json" --overwrite
} else {
Write-Output "skip uploading since version input isn't greater than latest version or does not start with '1.'"
}
- name: Upload to Azure Storage
run: |
$msi_files = Get-ChildItem -Path 'scripts/installer/windows/out/' -Filter *.msi
foreach ($msi_file in $msi_files) {
if ($env:INPUT_UPLOADASLATEST -ieq 'True') {
az storage blob upload --account-name promptflowartifact --container-name msi-installer --file "scripts/installer/windows/out/$($msi_file.Name)" --name "promptflow.msi" --overwrite
az storage blob copy start --account-name promptflowartifact --destination-container msi-installer --destination-blob "$($msi_file.Name)" --source-container msi-installer --source-blob "promptflow.msi"
} else {
az storage blob upload --account-name promptflowartifact --container-name msi-installer --file "scripts/installer/windows/out/$($msi_file.Name)" --name "$($msi_file.Name)" --overwrite
}
}
env:
INPUT_UPLOADASLATEST: ${{ github.event.inputs.uploadAsLatest }}
shell: pwsh