chore: import upstream snapshot with attribution
tools_continuous_delivery / Private PyPI non-main branch release (push) Has been skipped
tools_continuous_delivery / Private PyPI main branch release (push) Failing after 2m42s
Publish Promptflow Doc / Build (push) Has been cancelled
Publish Promptflow Doc / Deploy (push) Has been cancelled
Flake8 Lint / flake8 (push) Has been cancelled
Spell check CI / Spell_Check (push) Has been cancelled
tools_continuous_delivery / Private PyPI non-main branch release (push) Has been skipped
tools_continuous_delivery / Private PyPI main branch release (push) Failing after 2m42s
Publish Promptflow Doc / Build (push) Has been cancelled
Publish Promptflow Doc / Deploy (push) Has been cancelled
Flake8 Lint / flake8 (push) Has been cancelled
Spell check CI / Spell_Check (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
# Curl Install Script Information
|
||||
|
||||
The scripts in this directory are used for installing through curl and they point to the packages on PyPI.
|
||||
|
||||
## Install or update promptflow
|
||||
|
||||
curl https://promptflowartifact.blob.core.windows.net/linux-install-scripts/install | bash
|
||||
|
||||
The script can also be downloaded and run locally. You may have to restart your shell in order for the changes to take effect.
|
||||
|
||||
## Uninstall promptflow
|
||||
|
||||
Uninstall the promptflow by directly deleting the files from the location chosen at the time of installation.
|
||||
|
||||
1. Remove the installed CLI files.
|
||||
|
||||
```bash
|
||||
# The default install/executable location is the user's home directory ($HOME).
|
||||
rm -r $HOME/lib/promptflow
|
||||
```
|
||||
|
||||
2. Modify your `$HOME/.bash_profile` or `$HOME/.bashrc` file to remove the following line:
|
||||
|
||||
```text
|
||||
export PATH=$PATH:$HOME/lib/promptflow/bin
|
||||
```
|
||||
|
||||
3. If using `bash` or `zsh`, reload your shell's command cache.
|
||||
|
||||
```bash
|
||||
hash -r
|
||||
```
|
||||
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
#---------------------------------------------------------------------------------------------
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
#---------------------------------------------------------------------------------------------
|
||||
|
||||
#
|
||||
# Bash script to install the prompt flow
|
||||
#
|
||||
INSTALL_SCRIPT_URL="https://promptflowartifact.blob.core.windows.net/linux-install-scripts/install.py"
|
||||
_TTY=/dev/tty
|
||||
|
||||
install_script=$(mktemp -t promptflow_install_tmp_XXXXXX) || exit
|
||||
echo "Downloading prompt flow install script from $INSTALL_SCRIPT_URL to $install_script."
|
||||
curl -# $INSTALL_SCRIPT_URL > $install_script || exit
|
||||
|
||||
python_cmd=python3
|
||||
if ! command -v python3 >/dev/null 2>&1
|
||||
then
|
||||
echo "ERROR: python3 not found."
|
||||
echo "If python3 is available on the system, add it to PATH."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
chmod 775 $install_script
|
||||
echo "Running install script."
|
||||
$python_cmd $install_script < $_TTY
|
||||
@@ -0,0 +1,262 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# --------------------------------------------------------------------------------------------
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
# --------------------------------------------------------------------------------------------
|
||||
|
||||
#
|
||||
# This script will install the promptflow into a directory and create an executable
|
||||
# at a specified file path that is the entry point into the promptflow.
|
||||
#
|
||||
# The latest versions of all promptflow command packages will be installed.
|
||||
#
|
||||
|
||||
import os
|
||||
import sys
|
||||
import platform
|
||||
import tempfile
|
||||
import shutil
|
||||
import subprocess
|
||||
|
||||
|
||||
DEFAULT_INSTALL_DIR = os.path.expanduser(os.path.join('~', 'lib', 'promptflow'))
|
||||
DEFAULT_EXEC_DIR = os.path.expanduser(os.path.join('~', 'bin'))
|
||||
PF_EXECUTABLE_NAME = 'pf'
|
||||
PFAZURE_EXECUTABLE_NAME = 'pfazure'
|
||||
|
||||
|
||||
USER_BASH_RC = os.path.expanduser(os.path.join('~', '.bashrc'))
|
||||
USER_BASH_PROFILE = os.path.expanduser(os.path.join('~', '.bash_profile'))
|
||||
|
||||
|
||||
class CLIInstallError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def print_status(msg=''):
|
||||
print('-- '+msg)
|
||||
|
||||
|
||||
def prompt_input(msg):
|
||||
return input('\n===> '+msg)
|
||||
|
||||
|
||||
def prompt_input_with_default(msg, default):
|
||||
if default:
|
||||
return prompt_input("{} (leave blank to use '{}'): ".format(msg, default)) or default
|
||||
else:
|
||||
return prompt_input('{}: '.format(msg))
|
||||
|
||||
|
||||
def prompt_y_n(msg, default=None):
|
||||
if default not in [None, 'y', 'n']:
|
||||
raise ValueError("Valid values for default are 'y', 'n' or None")
|
||||
y = 'Y' if default == 'y' else 'y'
|
||||
n = 'N' if default == 'n' else 'n'
|
||||
while True:
|
||||
ans = prompt_input('{} ({}/{}): '.format(msg, y, n))
|
||||
if ans.lower() == n.lower():
|
||||
return False
|
||||
if ans.lower() == y.lower():
|
||||
return True
|
||||
if default and not ans:
|
||||
return default == y.lower()
|
||||
|
||||
|
||||
def exec_command(command_list, cwd=None, env=None):
|
||||
print_status('Executing: '+str(command_list))
|
||||
subprocess.check_call(command_list, cwd=cwd, env=env)
|
||||
|
||||
|
||||
def create_tmp_dir():
|
||||
tmp_dir = tempfile.mkdtemp()
|
||||
return tmp_dir
|
||||
|
||||
|
||||
def create_dir(dir):
|
||||
if not os.path.isdir(dir):
|
||||
print_status("Creating directory '{}'.".format(dir))
|
||||
os.makedirs(dir)
|
||||
|
||||
|
||||
def create_virtualenv(install_dir):
|
||||
cmd = [sys.executable, '-m', 'venv', install_dir]
|
||||
exec_command(cmd)
|
||||
|
||||
|
||||
def install_cli(install_dir, tmp_dir):
|
||||
path_to_pip = os.path.join(install_dir, 'bin', 'pip')
|
||||
cmd = [path_to_pip, 'install', '--cache-dir', tmp_dir,
|
||||
'promptflow[azure,executable,azureml-serving,executor-service]', '--upgrade']
|
||||
exec_command(cmd)
|
||||
cmd = [path_to_pip, 'install', '--cache-dir', tmp_dir, 'promptflow-tools', '--upgrade']
|
||||
exec_command(cmd)
|
||||
cmd = [path_to_pip, 'install', '--cache-dir', tmp_dir, 'keyrings.alt', '--upgrade']
|
||||
exec_command(cmd)
|
||||
|
||||
|
||||
def get_install_dir():
|
||||
install_dir = None
|
||||
while not install_dir:
|
||||
prompt_message = 'In what directory would you like to place the install?'
|
||||
install_dir = prompt_input_with_default(prompt_message, DEFAULT_INSTALL_DIR)
|
||||
install_dir = os.path.realpath(os.path.expanduser(install_dir))
|
||||
if ' ' in install_dir:
|
||||
print_status("The install directory '{}' cannot contain spaces.".format(install_dir))
|
||||
install_dir = None
|
||||
else:
|
||||
create_dir(install_dir)
|
||||
if os.listdir(install_dir):
|
||||
print_status("'{}' is not empty and may contain a previous installation.".format(install_dir))
|
||||
ans_yes = prompt_y_n('Remove this directory?', 'n')
|
||||
if ans_yes:
|
||||
shutil.rmtree(install_dir)
|
||||
print_status("Deleted '{}'.".format(install_dir))
|
||||
create_dir(install_dir)
|
||||
else:
|
||||
# User opted to not delete the directory so ask for install directory again
|
||||
install_dir = None
|
||||
print_status("We will install at '{}'.".format(install_dir))
|
||||
return install_dir
|
||||
|
||||
|
||||
def _backup_rc(rc_file):
|
||||
try:
|
||||
shutil.copyfile(rc_file, rc_file+'.backup')
|
||||
print_status("Backed up '{}' to '{}'".format(rc_file, rc_file+'.backup'))
|
||||
except (OSError, IOError):
|
||||
pass
|
||||
|
||||
|
||||
def _get_default_rc_file():
|
||||
bashrc_exists = os.path.isfile(USER_BASH_RC)
|
||||
bash_profile_exists = os.path.isfile(USER_BASH_PROFILE)
|
||||
if not bashrc_exists and bash_profile_exists:
|
||||
return USER_BASH_PROFILE
|
||||
if bashrc_exists and bash_profile_exists and platform.system().lower() == 'darwin':
|
||||
return USER_BASH_PROFILE
|
||||
return USER_BASH_RC if bashrc_exists else None
|
||||
|
||||
|
||||
def _default_rc_file_creation_step():
|
||||
rcfile = USER_BASH_PROFILE if platform.system().lower() == 'darwin' else USER_BASH_RC
|
||||
ans_yes = prompt_y_n('Could not automatically find a suitable file to use. Create {} now?'.format(rcfile),
|
||||
default='y')
|
||||
if ans_yes:
|
||||
open(rcfile, 'a').close()
|
||||
return rcfile
|
||||
return None
|
||||
|
||||
|
||||
def _find_line_in_file(file_path, search_pattern):
|
||||
try:
|
||||
with open(file_path, 'r', encoding="utf-8") as search_file:
|
||||
for line in search_file:
|
||||
if search_pattern in line:
|
||||
return True
|
||||
except (OSError, IOError):
|
||||
pass
|
||||
return False
|
||||
|
||||
|
||||
def _modify_rc(rc_file_path, line_to_add):
|
||||
if not _find_line_in_file(rc_file_path, line_to_add):
|
||||
with open(rc_file_path, 'a', encoding="utf-8") as rc_file:
|
||||
rc_file.write('\n'+line_to_add+'\n')
|
||||
|
||||
|
||||
def get_rc_file_path():
|
||||
rc_file = None
|
||||
default_rc_file = _get_default_rc_file()
|
||||
if not default_rc_file:
|
||||
rc_file = _default_rc_file_creation_step()
|
||||
rc_file = rc_file or prompt_input_with_default('Enter a path to an rc file to update', default_rc_file)
|
||||
if rc_file:
|
||||
rc_file_path = os.path.realpath(os.path.expanduser(rc_file))
|
||||
if os.path.isfile(rc_file_path):
|
||||
return rc_file_path
|
||||
print_status("The file '{}' could not be found.".format(rc_file_path))
|
||||
return None
|
||||
|
||||
|
||||
def warn_other_azs_on_path(exec_dir, exec_filepath):
|
||||
env_path = os.environ.get('PATH')
|
||||
conflicting_paths = []
|
||||
if env_path:
|
||||
for p in env_path.split(':'):
|
||||
for file in [PF_EXECUTABLE_NAME, PFAZURE_EXECUTABLE_NAME]:
|
||||
p_to_pf = os.path.join(p, file)
|
||||
if p != exec_dir and os.path.isfile(p_to_pf):
|
||||
conflicting_paths.append(p_to_pf)
|
||||
if conflicting_paths:
|
||||
print_status()
|
||||
print_status(f"** WARNING: Other '{PF_EXECUTABLE_NAME}/{PFAZURE_EXECUTABLE_NAME}' "
|
||||
f"executables are on your $PATH. **")
|
||||
print_status("Conflicting paths: {}".format(', '.join(conflicting_paths)))
|
||||
print_status("You can run this installation of the promptflow with '{}'.".format(exec_filepath))
|
||||
|
||||
|
||||
def handle_path_and_tab_completion(exec_filepath, install_dir):
|
||||
ans_yes = prompt_y_n('Modify profile to update your $PATH now?', 'y')
|
||||
if ans_yes:
|
||||
rc_file_path = get_rc_file_path()
|
||||
if not rc_file_path:
|
||||
raise CLIInstallError('No suitable profile file found.')
|
||||
_backup_rc(rc_file_path)
|
||||
line_to_add = "export PATH=$PATH:{}".format(os.path.join(install_dir, "bin"))
|
||||
_modify_rc(rc_file_path, line_to_add)
|
||||
warn_other_azs_on_path(install_dir, exec_filepath)
|
||||
print_status()
|
||||
print_status('** Run `exec -l $SHELL` to restart your shell. **')
|
||||
print_status()
|
||||
else:
|
||||
print_status("You can run the promptflow with '{}'.".format(exec_filepath))
|
||||
|
||||
|
||||
def verify_python_version():
|
||||
print_status('Verifying Python version.')
|
||||
v = sys.version_info
|
||||
if v < (3, 8):
|
||||
raise CLIInstallError('The promptflow does not support Python versions less than 3.9.')
|
||||
if 'conda' in sys.version:
|
||||
raise CLIInstallError("This script does not support the Python Anaconda environment. "
|
||||
"Create an Anaconda virtual environment and install with 'pip'")
|
||||
print_status('Python version {}.{}.{} okay.'.format(v.major, v.minor, v.micro))
|
||||
|
||||
|
||||
def main():
|
||||
verify_python_version()
|
||||
tmp_dir = create_tmp_dir()
|
||||
install_dir = get_install_dir()
|
||||
create_virtualenv(install_dir)
|
||||
install_cli(install_dir, tmp_dir)
|
||||
exec_filepath = [os.path.join(install_dir, "bin", PF_EXECUTABLE_NAME),
|
||||
os.path.join(install_dir, "bin", PFAZURE_EXECUTABLE_NAME)]
|
||||
try:
|
||||
handle_path_and_tab_completion(exec_filepath, install_dir)
|
||||
except Exception as e:
|
||||
print_status("Unable to set up PATH. ERROR: {}".format(str(e)))
|
||||
shutil.rmtree(tmp_dir)
|
||||
print_status("Installation successful.")
|
||||
print_status("Run the CLI with {} --help".format(exec_filepath))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
main()
|
||||
except CLIInstallError as cie:
|
||||
print('ERROR: '+str(cie), file=sys.stderr)
|
||||
sys.exit(1)
|
||||
except KeyboardInterrupt:
|
||||
print('\n\nExiting...')
|
||||
sys.exit(1)
|
||||
|
||||
# SIG # Begin signature block
|
||||
# Op0/tmmNDX4QgQefj28K91e/ClVKWeYaA1w1kb5Hi8ALJZtmvyhwvxYlCRZ9eWT+
|
||||
# wFBfSvpUIzAWYxEMfVqqWy7g9AzqHGa5vE37zQ7uGkIyR0OsmO0bkauOv5FxuCWX
|
||||
# U0u9d9sir6sRTb2nrEj2O1EXAcP2xNaW77w1fcOtMX9W6ytHXx/+v5p387+/HBnQ
|
||||
# y00GvJrrcIJeRj4MboBdDdv0VgGJAAlTJp0hxO0lt5ZQUMJvi/sM4e1cPUTcx7uB
|
||||
# djCmvSZzZrJO2ZIIWiyiP2XNYWJv4A9klJWMbWKukeZOSjxYPS0pO2mTftkKoL5U
|
||||
# sOJu9RtRWIIx/kLG/Axliw==
|
||||
# SIG # End signature block
|
||||
@@ -0,0 +1,4 @@
|
||||
**/windows/scripts/build
|
||||
**/windows/scripts/dist
|
||||
**/windows/wix
|
||||
**/windows/out
|
||||
@@ -0,0 +1,35 @@
|
||||
# Building the Windows MSI Installer
|
||||
|
||||
This document provides instructions on creating the MSI installer.
|
||||
|
||||
## Option1: Building with Github Actions
|
||||
Trigger the [workflow](https://github.com/microsoft/promptflow/actions/workflows/build_msi_installer.yml) manually.
|
||||
|
||||
|
||||
## Option2: Local Building
|
||||
### Prerequisites
|
||||
|
||||
1. Turn on the '.NET Framework 3.5' Windows Feature (required for WIX Toolset).
|
||||
2. Install 'Microsoft Build Tools 2015'.
|
||||
https://www.microsoft.com/download/details.aspx?id=48159
|
||||
3. You need to have curl.exe, unzip.exe and msbuild.exe available under PATH.
|
||||
4. Install 'WIX Toolset build tools' following the instructions below.
|
||||
- Enter the directory where the README is located (`cd scripts/installer/windows`), `mkdir wix` and `cd wix`.
|
||||
- `curl --output wix-archive.zip https://azurecliprod.blob.core.windows.net/msi/wix310-binaries-mirror.zip`
|
||||
- `unzip wix-archive.zip` and `del wix-archive.zip`
|
||||
5. We recommend creating a clean virtual Python environment and installing all dependencies using src/promptflow/setup.py.
|
||||
- `python -m venv venv`
|
||||
- `venv\Scripts\activate`
|
||||
- `pip install promptflow[azure,executable,azureml-serving,executor-service] promptflow-tools`
|
||||
|
||||
|
||||
### Building
|
||||
1. Update the version number `$(env.CLI_VERSION)` and `$(env.FILE_VERSION)` in `product.wxs`, `promptflow.wixproj` and `version_info.txt`.
|
||||
2. `cd scripts/installer/windows/scripts` and run `python generate_dependency.py`.
|
||||
3. run `pyinstaller promptflow.spec`.
|
||||
4. `cd scripts/installer/windows` and Run `msbuild /t:rebuild /p:Configuration=Release /p:Platform=x64 promptflow.wixproj`.
|
||||
5. The unsigned MSI will be in the `scripts/installer/windows/out` folder.
|
||||
|
||||
## Notes
|
||||
- If you encounter "Access is denied" error when running promptflow. Please follow the [link](https://learn.microsoft.com/en-us/microsoft-365/security/defender-endpoint/attack-surface-reduction-rules-deployment-implement?view=o365-worldwide#customize-attack-surface-reduction-rules) to add the executable to the Windows Defender Attack Surface Reduction (ASR) rule.
|
||||
Or you can add promptflow installation folder to the Windows Defender exclusion list.
|
||||
@@ -0,0 +1,101 @@
|
||||
# Install prompt flow MSI installer on Windows
|
||||
Prompt flow is a suite of development tools designed to streamline the end-to-end development
|
||||
cycle of LLM-based AI applications, that can be installed locally on Windows computers.
|
||||
|
||||
For Windows, the prompt flow is installed via an MSI, which gives you access to the CLI
|
||||
through the Windows Command Prompt (CMD) or PowerShell.
|
||||
|
||||
## Install or update
|
||||
|
||||
The MSI distributable is used for installing or updating the prompt flow on Windows.
|
||||
You don't need to uninstall current versions before using the MSI installer because
|
||||
the MSI updates any existing version.
|
||||
|
||||
::::{tab-set}
|
||||
:::{tab-item} Microsoft Installer (MSI)
|
||||
:sync: Microsoft Installer (MSI)
|
||||
### Latest version
|
||||
|
||||
Download and install the latest release of the prompt flow.
|
||||
When the installer asks if it can make changes to your computer, select the "Yes" box.
|
||||
|
||||
> [Latest release of the promptflow (64-bit)](https://aka.ms/installpromptflowwindowsx64)
|
||||
)
|
||||
|
||||
|
||||
### Specific version
|
||||
|
||||
If you prefer, you can download a specific version of the promptflow by using a URL.
|
||||
To download the MSI installer for a specific version, change the version segment in URL
|
||||
https://promptflowartifact.blob.core.windows.net/msi-installer/promptflow-<version>.msi
|
||||
:::
|
||||
|
||||
:::{tab-item} Microsoft Installer (MSI) with PowerShell
|
||||
:sync: Microsoft Installer (MSI) with PowerShell
|
||||
|
||||
### PowerShell
|
||||
|
||||
To install the prompt flow using PowerShell, start PowerShell and
|
||||
run the following command:
|
||||
|
||||
```PowerShell
|
||||
$ProgressPreference = 'SilentlyContinue'; Invoke-WebRequest -Uri https://aka.ms/installpromptflowwindowsx64 -OutFile .\promptflow.msi; Start-Process msiexec.exe -Wait -ArgumentList '/I promptflow.msi /quiet'; Remove-Item .\promptflow.msi
|
||||
```
|
||||
|
||||
This will download and install the latest 64-bit installer of the prompt flow for Windows.
|
||||
|
||||
To install a specific version, replace the `-Uri` argument with the URL like below.
|
||||
Here is an example of using the 64-bit installer of the promptflow version 1.0.0 in PowerShell:
|
||||
|
||||
```PowerShell
|
||||
$ProgressPreference = 'SilentlyContinue'; Invoke-WebRequest -Uri https://promptflowartifact.blob.core.windows.net/msi-installer/promptflow-1.0.0.msi -OutFile .\promptflow.msi; Start-Process msiexec.exe -Wait -ArgumentList '/I promptflow.msi /quiet'; Remove-Item .\promptflow.msi
|
||||
```
|
||||
:::
|
||||
|
||||
::::
|
||||
|
||||
|
||||
|
||||
## Run the prompt flow
|
||||
|
||||
You can now run the prompt flow with the `pf` or `pfazure` command from either Windows Command Prompt or PowerShell.
|
||||
|
||||
|
||||
## Upgrade the prompt flow
|
||||
Beginning with version 1.4.0, the prompt flow provides an in-tool command to upgrade to the latest version.
|
||||
|
||||
```commandline
|
||||
pf upgrade
|
||||
```
|
||||
For prompt flow versions prior to 1.4.0, upgrade by reinstalling as described in Install the prompt flow.
|
||||
|
||||
## Uninstall
|
||||
You uninstall the prompt flow from the Windows "Apps and Features" list. To uninstall:
|
||||
|
||||
| Platform | Instructions |
|
||||
|---|---|
|
||||
| Windows 11 | Start > Settings > Apps > Installed apps |
|
||||
| Windows 10 | Start > Settings > System > Apps & Features |
|
||||
| Windows 8 and Windows 7 | Start > Control Panel > Programs > Uninstall a program |
|
||||
|
||||
Once on this screen type __promptflow_ into the program search bar.
|
||||
The program to uninstall is listed as __promptflow (64-bit)__.
|
||||
Select this application, then select the `Uninstall` button.
|
||||
|
||||
## FAQ
|
||||
|
||||
### Where is the prompt flow installed?
|
||||
In Windows, the 64-bit prompt flow installs in `C:\Users\**\AppData\Local\Apps\promptflow` by default.
|
||||
|
||||
|
||||
### What version of the prompt flow is installed?
|
||||
|
||||
Type `pf --version` in a terminal window to know what version of the prompt flow is installed.
|
||||
Your output looks like this:
|
||||
|
||||
```output
|
||||
promptflow x.x.x
|
||||
|
||||
Executable '***\python.exe'
|
||||
Python (Windows) 3.*.* | packaged by conda-forge | *
|
||||
```
|
||||
@@ -0,0 +1,161 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
|
||||
|
||||
<?define ProductVersion="$(env.CLI_VERSION)" ?>
|
||||
|
||||
<?define ProductName = "promptflow" ?>
|
||||
<?define ProductDescription = "Command-line tools for prompt flow." ?>
|
||||
<?define ProductAuthor = "Microsoft Corporation" ?>
|
||||
<?define ProductResources = ".\resources\" ?>
|
||||
<?define UpgradeCode32 = "8b748161-e07a-48f2-8cdf-401480df4694" ?>
|
||||
|
||||
<?if $(var.Platform) = "x64" ?>
|
||||
<?define PromptflowCliRegistryGuid = "0efd984f-9eec-425b-b230-a3994b69649a" ?>
|
||||
<?define PromptflowServiceGuid = "d4e99207-77be-4bdf-a430-b08632c5aa2b" ?>
|
||||
<?define PromptflowSystemPathGuid = "4c321045-d4e0-4446-bda4-8c19eaa42af1" ?>
|
||||
<?define ProgramFilesFolder = "ProgramFiles64Folder" ?>
|
||||
<?define RemovePromptflowFolderGuid = "ee843aa5-2b72-4958-be84-53dbac17efc7" ?>
|
||||
<?define UpgradeCode = "772aa21f-f8d4-4771-b910-1dbce3f1920c" ?>
|
||||
<?define Architecture = "64-bit" ?>
|
||||
|
||||
<?elseif $(var.Platform) = "x86" ?>
|
||||
<?define PromptflowCliRegistryGuid = "7c2c792d-c395-44a1-8222-8e4ea006abb9" ?>
|
||||
<?define PromptflowServiceGuid = "f706b208-a15d-4ae7-9185-cfcc43656570" ?>
|
||||
<?define PromptflowSystemPathGuid = "9661fe6a-ff48-4e7c-a60d-fc34c2d06ef3" ?>
|
||||
<?define ProgramFilesFolder = "ProgramFilesFolder" ?>
|
||||
<?define RemovePromptflowFolderGuid = "588ca5e1-38c6-4659-8b38-762df7ed5b28" ?>
|
||||
<?define UpgradeCode = $(var.UpgradeCode32) ?>
|
||||
<?define Architecture = "32-bit" ?>
|
||||
|
||||
<?else ?>
|
||||
<?error Unsupported platform "$(var.Platform)" ?>
|
||||
<?endif ?>
|
||||
|
||||
<Product Id="*" Name="$(var.ProductName) ($(var.Architecture))" Language="1033" Version="$(var.ProductVersion)" Manufacturer="$(var.ProductAuthor)" UpgradeCode="$(var.UpgradeCode)">
|
||||
<Package InstallerVersion="200" Compressed="yes" InstallScope="perUser" />
|
||||
|
||||
<Upgrade Id="$(var.UpgradeCode)">
|
||||
<UpgradeVersion Property="WIX_UPGRADE_DETECTED" Maximum="$(var.ProductVersion)" IncludeMaximum="no" MigrateFeatures="yes" />
|
||||
<UpgradeVersion Property="WIX_DOWNGRADE_DETECTED" Minimum="$(var.ProductVersion)" IncludeMinimum="no" OnlyDetect="yes" />
|
||||
</Upgrade>
|
||||
<InstallExecuteSequence>
|
||||
<RemoveExistingProducts After="InstallExecute" />
|
||||
</InstallExecuteSequence>
|
||||
|
||||
|
||||
<!-- New product architectures should upgrade the original x86 product - even of the same version. -->
|
||||
<?if $(var.UpgradeCode) != $(var.UpgradeCode32) ?>
|
||||
<Upgrade Id="$(var.UpgradeCode32)">
|
||||
<UpgradeVersion Property="WIX_X86_UPGRADE_DETECTED" Maximum="$(var.ProductVersion)" IncludeMaximum="yes" MigrateFeatures="yes" />
|
||||
<UpgradeVersion Property="WIX_X86_DOWNGRADE_DETECTED" Minimum="$(var.ProductVersion)" IncludeMinimum="no" OnlyDetect="yes" />
|
||||
</Upgrade>
|
||||
<Condition Message="A newer version of $(var.ProductName) is already installed.">NOT (WIX_DOWNGRADE_DETECTED OR WIX_X86_DOWNGRADE_DETECTED)</Condition>
|
||||
<?else ?>
|
||||
<Condition Message="A newer version of $(var.ProductName) is already installed.">NOT WIX_DOWNGRADE_DETECTED</Condition>
|
||||
<?endif ?>
|
||||
|
||||
<Media Id="1" Cabinet="promptflow.cab" EmbedCab="yes" CompressionLevel="high" />
|
||||
|
||||
<Icon Id="PromptflowIcon" SourceFile="$(var.ProductResources)logo32.ico" />
|
||||
|
||||
<Property Id="ARPPRODUCTICON" Value="PromptflowIcon" />
|
||||
<Property Id="ARPHELPLINK" Value="https://microsoft.github.io/promptflow/how-to-guides/quick-start.html" />
|
||||
<Property Id="ARPURLINFOABOUT" Value="https://microsoft.github.io/promptflow/how-to-guides/quick-start.html" />
|
||||
<Property Id="ARPURLUPDATEINFO" Value="https://microsoft.github.io/promptflow/how-to-guides/quick-start.html" />
|
||||
<Property Id="MSIFASTINSTALL" Value="7" />
|
||||
<Property Id="ApplicationFolderName" Value="promptflow" />
|
||||
<Property Id="WixAppFolder" Value="WixPerUserFolder" />
|
||||
|
||||
<Feature Id="ProductFeature" Title="promptflow" Level="1" AllowAdvertise="no">
|
||||
<ComponentGroupRef Id="ProductComponents" />
|
||||
</Feature>
|
||||
|
||||
<!--Custom action to propagate path env variable change-->
|
||||
<CustomActionRef Id="WixBroadcastEnvironmentChange" />
|
||||
|
||||
<!-- User Interface -->
|
||||
<WixVariable Id="WixUILicenseRtf" Value="$(var.ProductResources)CLI_LICENSE.rtf"/>
|
||||
|
||||
<UIRef Id="WixUI_ErrorProgressText"/>
|
||||
|
||||
<!-- Show message to restart any terminals only if the PATH is changed -->
|
||||
<CustomAction Id="Set_WIXUI_EXITDIALOGOPTIONALTEXT" Property="WIXUI_EXITDIALOGOPTIONALTEXT" Value="Please close and reopen any active terminal window to use prompt flow." />
|
||||
<InstallUISequence>
|
||||
<Custom Action="Set_WIXUI_EXITDIALOGOPTIONALTEXT" After="CostFinalize">NOT Installed AND NOT WIX_UPGRADE_DETECTED</Custom>
|
||||
</InstallUISequence>
|
||||
|
||||
<Property Id="WixQuietExec64CmdLine" Value=""[APPLICATIONFOLDER]pfcli.exe" pf service stop"/>
|
||||
<CustomAction Id="StopPromptFlowService"
|
||||
Execute="immediate"
|
||||
Return="ignore"
|
||||
BinaryKey="WixCA"
|
||||
DllEntry="WixQuietExec64"
|
||||
Impersonate="yes"/>
|
||||
<CustomAction Id="StartPromptFlowService"
|
||||
Directory="APPLICATIONFOLDER"
|
||||
Execute="deferred"
|
||||
ExeCommand="wscript.exe promptflow_service.vbs"
|
||||
Return="asyncNoWait" />
|
||||
<InstallExecuteSequence>
|
||||
<Custom Action="StopPromptFlowService" Before="InstallInitialize">Installed OR WIX_UPGRADE_DETECTED</Custom>
|
||||
<Custom Action="StartPromptFlowService" Before="InstallFinalize">NOT Installed OR WIX_UPGRADE_DETECTED</Custom>
|
||||
</InstallExecuteSequence>
|
||||
</Product>
|
||||
|
||||
<Fragment>
|
||||
<Directory Id="TARGETDIR" Name="SourceDir">
|
||||
<Directory Id="$(var.ProgramFilesFolder)">
|
||||
<Directory Id="APPLICATIONFOLDER" Name="promptflow" />
|
||||
</Directory>
|
||||
<Directory Id="StartupFolder" />
|
||||
</Directory>
|
||||
|
||||
<UIRef Id="WixUI_Advanced" />
|
||||
</Fragment>
|
||||
|
||||
<Fragment>
|
||||
<ComponentGroup Id="PromptflowCliSettingsGroup">
|
||||
<Component Id="RemovePromptflowFolder" Directory="APPLICATIONFOLDER" Guid="$(var.RemovePromptflowFolderGuid)">
|
||||
<RemoveFolder Id="APPLICATIONFOLDER" On="uninstall" />
|
||||
</Component>
|
||||
|
||||
<Component Id="PromptflowSystemPath" Directory="APPLICATIONFOLDER" Guid="$(var.PromptflowSystemPathGuid)">
|
||||
<Environment Id="PromptflowAddedToPATH"
|
||||
Name="PATH"
|
||||
Value="[APPLICATIONFOLDER]"
|
||||
Permanent="no"
|
||||
Part="first"
|
||||
Action="set"
|
||||
System="no" />
|
||||
<CreateFolder />
|
||||
</Component>
|
||||
|
||||
<Component Id="promptflow_service.vbs" Directory="APPLICATIONFOLDER" Guid="$(var.PromptflowServiceGuid)">
|
||||
<File Id="promptflow_service.vbs" Source="scripts\promptflow_service.vbs" KeyPath="yes" Checksum="yes"/>
|
||||
</Component>
|
||||
|
||||
<Component Id="ApplicationShortcut" Directory="StartupFolder" Guid="$(var.PromptflowCliRegistryGuid)">
|
||||
<Shortcut Id="ApplicationStartMenuShortcut"
|
||||
Name="Prompt flow service"
|
||||
Description="Prompt Flow Service"
|
||||
Target="[#promptflow_service.vbs]"
|
||||
WorkingDirectory="APPLICATIONFOLDER"
|
||||
Advertise="no">
|
||||
<Icon Id="PromptflowServiceIcon" SourceFile="$(var.ProductResources)logo32.ico" />
|
||||
</Shortcut>
|
||||
<RemoveFile Id="CleanUpShortCut" Directory="StartupFolder" Name="Prompt flow service" On="uninstall"/>
|
||||
<RegistryKey Root="HKCU" Key="Software\Microsoft\$(var.ProductName)" Action="createAndRemoveOnUninstall" ForceDeleteOnUninstall="yes">
|
||||
<RegistryValue Name="installed" Type="integer" Value="1" />
|
||||
<RegistryValue Name="version" Type="string" Value="$(var.ProductVersion)" KeyPath="yes"/>
|
||||
</RegistryKey>
|
||||
</Component>
|
||||
|
||||
|
||||
</ComponentGroup>
|
||||
|
||||
<ComponentGroup Id="ProductComponents">
|
||||
<ComponentGroupRef Id="PromptflowCliComponentGroup"/>
|
||||
<ComponentGroupRef Id="PromptflowCliSettingsGroup"/>
|
||||
</ComponentGroup>
|
||||
</Fragment>
|
||||
</Wix>
|
||||
@@ -0,0 +1,72 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<!-- Project -->
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
|
||||
<ProductVersion>3.10</ProductVersion>
|
||||
<ProjectGuid>04ff6707-750d-4474-89b3-7922c84721be</ProjectGuid>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<OutputName>promptflow-$(env.CLI_VERSION)</OutputName>
|
||||
<OutputType>Package</OutputType>
|
||||
<WixTargetsPath Condition=" '$(WixTargetsPath)' == '' AND '$(MSBuildExtensionsPath32)' != '' ">$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>
|
||||
<WixTargetsPath Condition=" '$(WixTargetsPath)' == '' ">$(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>
|
||||
</PropertyGroup>
|
||||
<!-- Local WiX -->
|
||||
<PropertyGroup>
|
||||
<LocalWixRoot>wix</LocalWixRoot>
|
||||
<WixToolPath>$(MSBuildThisFileDirectory)$(LocalWixRoot)</WixToolPath>
|
||||
<WixTargetsPath Condition="Exists('$(WixToolPath)\Wix.targets')">$(WixToolPath)\Wix.targets</WixTargetsPath>
|
||||
<WixTasksPath Condition="Exists('$(WixToolPath)\wixtasks.dll')">$(WixToolPath)\wixtasks.dll</WixTasksPath>
|
||||
<PromptflowSource>scripts\dist\promptflow</PromptflowSource>
|
||||
<LinkerAdditionalOptions>-fv</LinkerAdditionalOptions>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||
<OutputPath>out\$(Configuration)\</OutputPath>
|
||||
<IntermediateOutputPath>out\obj\$(Configuration)\</IntermediateOutputPath>
|
||||
<DefineConstants>Debug;PromptflowSource=$(PromptflowSource)</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||
<OutputPath>out\</OutputPath>
|
||||
<IntermediateOutputPath>out\obj\$(Configuration)\</IntermediateOutputPath>
|
||||
<DefineConstants>PromptflowSource=$(PromptflowSource)</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
|
||||
<OutputPath>out\$(Configuration)\</OutputPath>
|
||||
<IntermediateOutputPath>out\obj\$(Configuration)\</IntermediateOutputPath>
|
||||
<DefineConstants>Debug;PromptflowSource=$(PromptflowSource)</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
|
||||
<OutputPath>out\</OutputPath>
|
||||
<IntermediateOutputPath>out\obj\$(Configuration)\</IntermediateOutputPath>
|
||||
<DefineConstants>PromptflowSource=$(PromptflowSource)</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="out\promptflow.wxs">
|
||||
<Link>promptflow.wxs</Link>
|
||||
</Compile>
|
||||
<Compile Include="product.wxs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include=".\resources\logo_pf.png" />
|
||||
</ItemGroup>
|
||||
<!-- UI -->
|
||||
<ItemGroup>
|
||||
<WixExtension Include="WixUIExtension">
|
||||
<HintPath>$(WixExtDir)\WixUIExtension.dll</HintPath>
|
||||
<Name>WixUIExtension</Name>
|
||||
</WixExtension>
|
||||
<WixExtension Include="WixUtilExtension">
|
||||
<HintPath>$(WixExtDir)\WixUtilExtension.dll</HintPath>
|
||||
<Name>WixUtilExtension</Name>
|
||||
</WixExtension>
|
||||
</ItemGroup>
|
||||
<Import Project="$(WixTargetsPath)" Condition=" '$(WixTargetsPath)' != '' " />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\wix.targets" Condition=" '$(WixTargetsPath)' == '' AND Exists('$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\wix.targets') " />
|
||||
<Target Name="EnsureWixToolsetInstalled" Condition=" '$(WixTargetsImported)' != 'true' ">
|
||||
<Error Text="The WiX Toolset v3.10 build tools must be installed to build this project. To download the WiX Toolset, see https://wixtoolset.org/releases/v3.10/stable" />
|
||||
</Target>
|
||||
<Target Name="BeforeBuild">
|
||||
<HeatDirectory Directory="$(PromptflowSource)" ToolPath="$(WixToolPath)" AutogenerateGuids="true" ComponentGroupName="PromptflowCliComponentGroup" SuppressRootDirectory="true" DirectoryRefId="APPLICATIONFOLDER" OutputFile="out\promptflow.wxs" PreprocessorVariable="var.PromptflowSource" />
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -0,0 +1,120 @@
|
||||
{\rtf1\ansi\ansicpg1252\cocoartf1504\cocoasubrtf820
|
||||
{\fonttbl\f0\fnil\fcharset0 Tahoma;\f1\froman\fcharset0 TimesNewRomanPSMT;\f2\ftech\fcharset77 Symbol;
|
||||
}
|
||||
{\colortbl;\red255\green255\blue255;\red0\green0\blue255;}
|
||||
{\*\expandedcolortbl;;\csgenericrgb\c0\c0\c100000;}
|
||||
{\*\listtable{\list\listtemplateid1\listhybrid{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{decimal\}.}{\leveltext\leveltemplateid1\'02\'00.;}{\levelnumbers\'01;}\fi-360\li720\lin720 }{\listname ;}\listid1}
|
||||
{\list\listtemplateid2\listhybrid{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{decimal\}.}{\leveltext\leveltemplateid101\'02\'00.;}{\levelnumbers\'01;}\fi-360\li720\lin720 }{\listname ;}\listid2}
|
||||
{\list\listtemplateid3\listhybrid{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{lower-alpha\}.}{\leveltext\leveltemplateid201\'02\'00.;}{\levelnumbers\'01;}\fi-360\li720\lin720 }{\listname ;}\listid3}
|
||||
{\list\listtemplateid4\listhybrid{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{decimal\}.}{\leveltext\leveltemplateid301\'02\'00.;}{\levelnumbers\'01;}\fi-360\li720\lin720 }{\listname ;}\listid4}
|
||||
{\list\listtemplateid5\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid401\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid5}
|
||||
{\list\listtemplateid6\listhybrid{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{decimal\}.}{\leveltext\leveltemplateid501\'02\'00.;}{\levelnumbers\'01;}\fi-360\li720\lin720 }{\listname ;}\listid6}
|
||||
{\list\listtemplateid7\listhybrid{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{lower-alpha\}.}{\leveltext\leveltemplateid601\'02\'00.;}{\levelnumbers\'01;}\fi-360\li720\lin720 }{\listname ;}\listid7}
|
||||
{\list\listtemplateid8\listhybrid{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{decimal\}.}{\leveltext\leveltemplateid701\'02\'00.;}{\levelnumbers\'01;}\fi-360\li720\lin720 }{\listname ;}\listid8}}
|
||||
{\*\listoverridetable{\listoverride\listid1\listoverridecount0\ls1}{\listoverride\listid2\listoverridecount0\ls2}{\listoverride\listid3\listoverridecount0\ls3}{\listoverride\listid4\listoverridecount0\ls4}{\listoverride\listid5\listoverridecount0\ls5}{\listoverride\listid6\listoverridecount0\ls6}{\listoverride\listid7\listoverridecount0\ls7}{\listoverride\listid8\listoverridecount0\ls8}}
|
||||
\margl1440\margr1440\vieww10800\viewh8400\viewkind0
|
||||
\deftab720
|
||||
\pard\pardeftab720\ri0\sb120\sa120\partightenfactor0
|
||||
|
||||
\f0\b\fs20 \cf0 MICROSOFT SOFTWARE LICENSE TERMS\
|
||||
Microsoft prompt flow
|
||||
\f1 \
|
||||
\pard\pardeftab720\ri0\sb120\sa120\partightenfactor0
|
||||
|
||||
\f0\b0 \cf0 These license terms are an agreement between Microsoft Corporation (or based on where you live, one of its affiliates) and you. They apply to the software named above. The terms also apply to any Microsoft services or updates for the software, except to the extent those have different terms.
|
||||
\f1 \
|
||||
\pard\pardeftab720\ri0\sb120\sa120\partightenfactor0
|
||||
|
||||
\f0\b \cf0 IF YOU COMPLY WITH THESE LICENSE TERMS, YOU HAVE THE RIGHTS BELOW.
|
||||
\f1 \
|
||||
\pard\tx360\pardeftab720\li357\fi-357\ri0\sb120\sa120\partightenfactor0
|
||||
\ls1\ilvl0
|
||||
\f0 \cf0 1. INSTALLATION AND USE RIGHTS.
|
||||
\f1\b0 \
|
||||
\pard\pardeftab720\li357\ri0\sb120\sa120\partightenfactor0
|
||||
|
||||
\f0 \cf0 You may install and use any number of copies of the software.\
|
||||
\pard\tx450\pardeftab720\li447\fi-357\ri0\sb120\sa120\partightenfactor0
|
||||
\ls2\ilvl0
|
||||
\b \cf0 2. TERMS FOR SPECIFIC COMPONENTS
|
||||
\f1 .\
|
||||
\pard\tx4950\pardeftab720\li720\fi-270\ri0\sb120\sa120\partightenfactor0
|
||||
\ls3\ilvl0
|
||||
\f0 \cf0 a. Third Party Components
|
||||
\f1 .
|
||||
\f0\b0 The software may include third party components with separate legal notices or governed by other agreements, as may be described in the ThirdPartyNotices file(s) accompanying the software. Even if such components are governed by other agreements, the disclaimers and the limitations on and exclusions of damages below also apply.
|
||||
\f1 \
|
||||
\pard\tx450\pardeftab720\li450\fi-357\ri0\sb120\sa120\partightenfactor0
|
||||
\ls4\ilvl0
|
||||
\f0\b \cf0 3. DATA.
|
||||
\b0 The software may collect information about you and your use of the software, and send that to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may opt-out of many of these scenarios, but not all, as described in the product documentation. There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications and you should provide a copy of Microsoft\'92s privacy statement to your users. The Microsoft privacy statement is located here {\field{\*\fldinst{HYPERLINK "https://go.microsoft.com/fwlink/?LinkID=824704"}}{\fldrslt \cf2 \ul \ulc2 https://go.microsoft.com/fwlink/?LinkID=824704}}. You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices.\
|
||||
\pard\tx360\pardeftab720\li357\fi-357\ri0\sb120\sa120\partightenfactor0
|
||||
\ls4\ilvl0
|
||||
\b \cf0 4. SCOPE OF LICENSE.
|
||||
\b0 The software is licensed, not sold. This agreement only gives you some rights to use the software. Microsoft reserves all other rights. Unless applicable law gives you more rights despite this limitation, you may use the software only as expressly permitted in this agreement. In doing so, you must comply with any technical limitations in the software that only allow you to use it in certain ways. You may not\
|
||||
\pard\tx720\pardeftab720\li720\fi-363\ri0\sb120\sa120\partightenfactor0
|
||||
\ls5\ilvl0
|
||||
\f2 \cf0 \'a5
|
||||
\f0 work around any technical limitations in the software;\
|
||||
\ls5\ilvl0
|
||||
\f2 \'a5
|
||||
\f0 reverse engineer, decompile or disassemble the software, or otherwise attempt to derive the source code for the software except, and only to the extent required by third party licensing terms governing the use of certain open source components that may be included in the software;\
|
||||
\ls5\ilvl0
|
||||
\f2 \'a5
|
||||
\f0 remove, minimize, block or modify any notices of Microsoft or its suppliers in the software; \
|
||||
\ls5\ilvl0
|
||||
\f2 \'a5
|
||||
\f0 use the software in any way that is against the law; or\
|
||||
\ls5\ilvl0
|
||||
\f2 \'a5
|
||||
\f0 share, publish, rent or lease the software, or provide the software as a stand-alone hosted as solution for others to use, or transfer the software or this agreement to any third party.\
|
||||
\pard\tx360\pardeftab720\li357\fi-267\ri0\sb120\sa120\partightenfactor0
|
||||
\ls6\ilvl0
|
||||
\b \cf0 5. EXPORT RESTRICTIONS.
|
||||
\b0 You must comply with all domestic and international export laws and regulations that apply to the software, which include restrictions on destinations, end users, and end use. For further information on export restrictions, visit {\field{\*\fldinst{HYPERLINK "http://www.microsoft.com/exporting"}}{\fldrslt \cf2 \ul \ulc2 www.microsoft.com/exporting}}.
|
||||
\f1 \cf2 \ul \ulc2 \
|
||||
\pard\tx450\pardeftab720\li447\fi-357\ri0\sb120\sa120\partightenfactor0
|
||||
\ls6\ilvl0
|
||||
\f0\b \cf0 \ulnone 6. SUPPORT SERVICES.
|
||||
\b0 Because this software is \'93as is,\'94 we may not provide support services for it.\
|
||||
\ls6\ilvl0
|
||||
\b 7. ENTIRE AGREEMENT.
|
||||
\b0 This agreement, and the terms for supplements, updates, Internet-based services and support services that you use, are the entire agreement for the software and support services.\
|
||||
\ls6\ilvl0
|
||||
\b 8. APPLICABLE LAW.
|
||||
\b0 If you acquired the software in the United States, Washington law applies to interpretation of and claims for breach of this agreement, and the laws of the state where you live apply to all other claims. If you acquired the software in any other country, its laws apply.
|
||||
\f1\b \
|
||||
\ls6\ilvl0
|
||||
\f0 9. CONSUMER RIGHTS; REGIONAL VARIATIONS.
|
||||
\b0 This agreement describes certain legal rights. You may have other rights, including consumer rights, under the laws of your state or country. Separate and apart from your relationship with Microsoft, you may also have rights with respect to the party from which you acquired the software. This agreement does not change those other rights if the laws of your state or country do not permit it to do so. For example, if you acquired the software in one of the below regions, or mandatory country law applies, then the following provisions apply to you:\
|
||||
\pard\pardeftab720\li720\fi-270\ri0\sb120\sa120\partightenfactor0
|
||||
\ls7\ilvl0
|
||||
\b \cf0 b. Australia.
|
||||
\b0 You have statutory guarantees under the Australian Consumer Law and nothing in this agreement is intended to affect those rights.\
|
||||
\pard\pardeftab720\li717\fi-267\ri0\sb120\sa120\partightenfactor0
|
||||
\ls7\ilvl0
|
||||
\b \cf0 c. Canada.
|
||||
\b0 If you acquired this software in Canada, you may stop receiving updates by turning off the automatic update feature, disconnecting your device from the Internet (if and when you re-connect to the Internet, however, the software will resume checking for and installing updates), or uninstalling the software. The product documentation, if any, may also specify how to turn off updates for your specific device or software.\
|
||||
\ls7\ilvl0
|
||||
\b d. Germany and Austria
|
||||
\f1\b0 .\
|
||||
\pard\pardeftab720\li717\ri0\sb120\sa120\partightenfactor0
|
||||
|
||||
\f0\b \cf0 (i)
|
||||
\f1\b0
|
||||
\f0\b Warranty
|
||||
\b0 . The properly licensed software will perform substantially as described in any Microsoft materials that accompany the software. However, Microsoft gives no contractual guarantee in relation to the licensed software.\
|
||||
|
||||
\b (ii)
|
||||
\f1\b0
|
||||
\f0\b Limitation of Liability
|
||||
\b0 . In case of intentional conduct, gross negligence, claims based on the Product Liability Act, as well as, in case of death or personal or physical injury, Microsoft is liable according to the statutory law.\
|
||||
Subject to the foregoing clause (ii), Microsoft will only be liable for slight negligence if Microsoft is in breach of such material contractual obligations, the fulfillment of which facilitate the due performance of this agreement, the breach of which would endanger the purpose of this agreement and the compliance with which a party may constantly trust in (so-called "cardinal obligations"). In other cases of slight negligence, Microsoft will not be liable for slight negligence.\
|
||||
\pard\tx450\pardeftab720\li447\fi-357\ri0\sb120\sa120\partightenfactor0
|
||||
\ls8\ilvl0
|
||||
\b \cf0 10. DISCLAIMER OF WARRANTY. THE SOFTWARE IS LICENSED \'93AS-IS.\'94 YOU BEAR THE RISK OF USING IT. MICROSOFT GIVES NO EXPRESS WARRANTIES, GUARANTEES OR CONDITIONS. TO THE EXTENT PERMITTED UNDER YOUR LOCAL LAWS, MICROSOFT EXCLUDES THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.\
|
||||
11. LIMITATION ON AND EXCLUSION OF DAMAGES. YOU CAN RECOVER FROM MICROSOFT AND ITS SUPPLIERS ONLY DIRECT DAMAGES UP TO U.S. $5.00. YOU CANNOT RECOVER ANY OTHER DAMAGES, INCLUDING CONSEQUENTIAL, LOST PROFITS, SPECIAL, INDIRECT OR INCIDENTAL DAMAGES.\
|
||||
\pard\pardeftab720\li450\ri0\sb120\sa120\partightenfactor0
|
||||
|
||||
\b0 \cf0 This limitation applies to (a) anything related to the software, services, content (including code) on third party Internet sites, or third party applications; and (b) claims for breach of contract, breach of warranty, guarantee or condition, strict liability, negligence, or other tort to the extent permitted by applicable law.\
|
||||
It also applies even if Microsoft knew or should have known about the possibility of the damages. The above limitation or exclusion may not apply to you because your country may not allow the exclusion or limitation of incidental, consequential or other damages.}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 975 B |
@@ -0,0 +1,142 @@
|
||||
import ast
|
||||
import re
|
||||
import subprocess
|
||||
import copy
|
||||
from pip._vendor import tomli as toml
|
||||
from pathlib import Path
|
||||
from promptflow._sdk._utilities.general_utils import render_jinja_template
|
||||
|
||||
|
||||
def get_git_base_dir():
|
||||
return Path(
|
||||
subprocess.run(['git', 'rev-parse', '--show-toplevel'], stdout=subprocess.PIPE)
|
||||
.stdout.decode('utf-8').strip())
|
||||
|
||||
|
||||
def is_tool(name):
|
||||
"""Check whether `name` is on PATH and marked as executable."""
|
||||
|
||||
# from whichcraft import which
|
||||
from shutil import which
|
||||
|
||||
return which(name) is not None
|
||||
|
||||
|
||||
def extract_requirements(file_path):
|
||||
with open(file_path, 'r') as file:
|
||||
tree = ast.parse(file.read())
|
||||
|
||||
install_requires = []
|
||||
extras_requires = {}
|
||||
for node in ast.walk(tree):
|
||||
if isinstance(node, ast.Assign) and node.targets[0].id == 'REQUIRES':
|
||||
install_requires = [elt.s for elt in node.value.elts]
|
||||
elif isinstance(node, ast.Call) and getattr(node.func, 'id', None) == 'setup':
|
||||
for keyword in node.keywords:
|
||||
if keyword.arg == 'extras_require':
|
||||
extras_requires = ast.literal_eval(keyword.value)
|
||||
return install_requires, extras_requires
|
||||
|
||||
|
||||
def extract_package_names(packages):
|
||||
package_names = []
|
||||
for package in packages:
|
||||
match = re.match(r'^([a-zA-Z0-9-_.]+)', package)
|
||||
if match:
|
||||
package_names.append(match.group(1))
|
||||
return package_names
|
||||
|
||||
|
||||
def get_toml_dependencies(packages):
|
||||
file_list = ["promptflow-tracing", "promptflow-core", "promptflow-devkit", "promptflow-azure"]
|
||||
dependencies = []
|
||||
|
||||
for package in packages:
|
||||
if package in file_list:
|
||||
with open(get_git_base_dir() / "src" / package / "pyproject.toml", 'rb') as file:
|
||||
data = toml.load(file)
|
||||
extra_package_names = data.get('tool', {}).get('poetry', {}).get('dependencies', {})
|
||||
dependencies.extend(extra_package_names.keys())
|
||||
# hard-code promptflow-evals dependency here since it's not added in promptflow setup for now
|
||||
with open(get_git_base_dir() / "src" / "promptflow-evals" / "pyproject.toml", 'rb') as file:
|
||||
data = toml.load(file)
|
||||
extra_package_names = data.get('tool', {}).get('poetry', {}).get('dependencies', {})
|
||||
dependencies.extend(extra_package_names.keys())
|
||||
|
||||
dependencies = [dependency for dependency in dependencies
|
||||
if not dependency.startswith('promptflow') and not dependency == 'python']
|
||||
return dependencies
|
||||
|
||||
|
||||
def get_package_dependencies(package_name_list):
|
||||
dependencies = []
|
||||
for package_name in package_name_list:
|
||||
if (is_tool('conda')):
|
||||
result = subprocess.run('conda activate root | pip show {}'.format(package_name),
|
||||
shell=True, stdout=subprocess.PIPE)
|
||||
else:
|
||||
result = subprocess.run(['pip', 'show', package_name], stdout=subprocess.PIPE)
|
||||
print("---" + package_name)
|
||||
print(result.stdout)
|
||||
lines = result.stdout.decode('utf-8', errors="ignore").splitlines()
|
||||
for line in lines:
|
||||
if line.startswith('Requires'):
|
||||
dependency = line.split(': ')[1].split(', ')
|
||||
if dependency != ['']:
|
||||
dependencies.extend(dependency)
|
||||
break
|
||||
|
||||
dependencies = [dependency for dependency in dependencies if not dependency.startswith('promptflow')]
|
||||
return dependencies
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
dependencies = []
|
||||
install_requires, extras_requires = extract_requirements(get_git_base_dir() / 'src/promptflow/setup.py')
|
||||
install_requires_names = extract_package_names(install_requires)
|
||||
dependencies.extend(install_requires_names)
|
||||
|
||||
for key in extras_requires:
|
||||
extras_require_names = extract_package_names(extras_requires[key])
|
||||
dependencies.extend(extras_require_names)
|
||||
# get toml dependencies
|
||||
dependencies = list(set(dependencies))
|
||||
direct_package_dependencies = get_toml_dependencies(dependencies)
|
||||
|
||||
# get one step furture for dependencies
|
||||
dependencies = list(set(direct_package_dependencies))
|
||||
direct_package_dependencies = get_package_dependencies(dependencies)
|
||||
|
||||
# get all dependencies
|
||||
all_packages = list(set(dependencies) | set(direct_package_dependencies))
|
||||
|
||||
# remove all packages starting with promptflow
|
||||
all_packages = [package for package in all_packages if not package.startswith('promptflow')]
|
||||
|
||||
hidden_imports = copy.deepcopy(all_packages)
|
||||
meta_packages = copy.deepcopy(all_packages)
|
||||
|
||||
special_packages = ["streamlit-quill", "flask-cors", "flask-restx"]
|
||||
for i in range(len(hidden_imports)):
|
||||
# need special handeling because it use _ to import
|
||||
if hidden_imports[i] in special_packages:
|
||||
hidden_imports[i] = hidden_imports[i].replace('-', '_').lower()
|
||||
else:
|
||||
hidden_imports[i] = hidden_imports[i].replace('-', '.').lower()
|
||||
|
||||
hidden_imports.remove("azure.storage.file.share")
|
||||
hidden_imports.append("azure.storage.fileshare")
|
||||
hidden_imports.remove("azure.storage.file.datalake")
|
||||
hidden_imports.append("azure.storage.filedatalake")
|
||||
|
||||
render_context = {
|
||||
"hidden_imports": hidden_imports,
|
||||
"all_packages": all_packages,
|
||||
"meta_packages": meta_packages,
|
||||
}
|
||||
# always use unix line ending
|
||||
Path("./promptflow.spec").write_bytes(
|
||||
render_jinja_template(
|
||||
get_git_base_dir() / "scripts/installer/windows/scripts/promptflow.spec.jinja2", **render_context)
|
||||
.encode("utf-8")
|
||||
.replace(b"\r\n", b"\n"),)
|
||||
@@ -0,0 +1,19 @@
|
||||
@echo off
|
||||
setlocal
|
||||
|
||||
SET PF_INSTALLER=MSI
|
||||
set MAIN_EXE=%~dp0.\pfcli.exe
|
||||
REM Check if the first argument is 'start'
|
||||
if "%~1"=="service" (
|
||||
REM Check if the second argument is 'start'
|
||||
if "%~2"=="start" (
|
||||
cscript //nologo %~dp0.\start_pfs.vbs """%MAIN_EXE%"" pf %*"
|
||||
REM since we won't wait for vbs to finish, we need to wait for the output file to be flushed to disk
|
||||
timeout /t 5 >nul
|
||||
type "%~dp0output.txt"
|
||||
) else (
|
||||
"%MAIN_EXE%" pf %*
|
||||
)
|
||||
) else (
|
||||
"%MAIN_EXE%" pf %*
|
||||
)
|
||||
@@ -0,0 +1,5 @@
|
||||
@echo off
|
||||
setlocal
|
||||
|
||||
set MAIN_EXE=%~dp0.\pfcli.exe
|
||||
"%MAIN_EXE%" pfazure %*
|
||||
@@ -0,0 +1,17 @@
|
||||
import sys
|
||||
import multiprocessing
|
||||
|
||||
# use this file as the only entry point for the CLI to avoid packaging the same environment repeatedly
|
||||
|
||||
if __name__ == "__main__":
|
||||
multiprocessing.freeze_support()
|
||||
command = sys.argv[1] if len(sys.argv) > 1 else None
|
||||
sys.argv = sys.argv[1:]
|
||||
if command == 'pf':
|
||||
from promptflow._cli._pf.entry import main as pf_main
|
||||
pf_main()
|
||||
elif command == 'pfazure':
|
||||
from promptflow.azure._cli.entry import main as pfazure_main
|
||||
pfazure_main()
|
||||
else:
|
||||
print(f"Invalid command {sys.argv}. Please use 'pf', 'pfazure'.")
|
||||
@@ -0,0 +1,82 @@
|
||||
# -*- mode: python ; coding: utf-8 -*-
|
||||
from PyInstaller.utils.hooks import collect_data_files, collect_all, copy_metadata
|
||||
|
||||
datas = [('../resources/CLI_LICENSE.rtf', '.'), ('../../../../src/promptflow/NOTICE.txt', '.'),
|
||||
('../../../../src/promptflow-devkit/promptflow/_sdk/data/executable/', './promptflow/_sdk/data/executable/'),
|
||||
('../../../../src/promptflow-tools/promptflow/tools/', './promptflow/tools/'),
|
||||
('./pf.bat', '.'), ('./pfazure.bat', '.'), ('./start_pfs.vbs', '.')]
|
||||
|
||||
|
||||
all_packages = {{all_packages}}
|
||||
meta_packages = {{meta_packages}}
|
||||
|
||||
for package in all_packages:
|
||||
datas += collect_data_files(package)
|
||||
|
||||
for package in meta_packages:
|
||||
datas += copy_metadata(package)
|
||||
|
||||
opentelemetry_datas, opentelemetry_binaries, opentelemetry_hiddenimports = collect_all('opentelemetry')
|
||||
promptflow_datas, promptflow_binaries, promptflow_hiddenimports = collect_all('promptflow')
|
||||
datas += opentelemetry_datas
|
||||
datas += promptflow_datas
|
||||
datas += collect_data_files('streamlit_quill')
|
||||
|
||||
hidden_imports = ['win32timezone', 'promptflow', 'opentelemetry.context.contextvars_context', 'streamlit.runtime.scriptrunner.magic_funcs'] + {{hidden_imports}}
|
||||
|
||||
hidden_imports += opentelemetry_hiddenimports
|
||||
hidden_imports += promptflow_hiddenimports
|
||||
|
||||
binaries = []
|
||||
binaries += opentelemetry_binaries
|
||||
binaries += promptflow_binaries
|
||||
|
||||
block_cipher = None
|
||||
|
||||
pfcli_a = Analysis(
|
||||
['pfcli.py'],
|
||||
pathex=[],
|
||||
binaries=binaries,
|
||||
datas=datas,
|
||||
hiddenimports=hidden_imports,
|
||||
hookspath=[],
|
||||
hooksconfig={},
|
||||
runtime_hooks=[],
|
||||
excludes=[],
|
||||
win_no_prefer_redirects=False,
|
||||
win_private_assemblies=False,
|
||||
cipher=block_cipher,
|
||||
noarchive=False,
|
||||
)
|
||||
pfcli_pyz = PYZ(pfcli_a.pure, pfcli_a.zipped_data, cipher=block_cipher)
|
||||
pfcli_exe = EXE(
|
||||
pfcli_pyz,
|
||||
pfcli_a.scripts,
|
||||
[],
|
||||
exclude_binaries=True,
|
||||
name='pfcli',
|
||||
debug=False,
|
||||
bootloader_ignore_signals=False,
|
||||
strip=False,
|
||||
upx=True,
|
||||
console=True,
|
||||
disable_windowed_traceback=False,
|
||||
argv_emulation=False,
|
||||
target_arch=None,
|
||||
codesign_identity=None,
|
||||
entitlements_file=None,
|
||||
contents_directory='.',
|
||||
icon='../resources/logo32.ico',
|
||||
version="./version_info.txt",
|
||||
)
|
||||
|
||||
coll = COLLECT(
|
||||
pfcli_exe,
|
||||
pfcli_a.binaries,
|
||||
pfcli_a.zipfiles,
|
||||
pfcli_a.datas,
|
||||
strip=False,
|
||||
upx=True,
|
||||
upx_exclude=[],
|
||||
name='promptflow',
|
||||
)
|
||||
@@ -0,0 +1,3 @@
|
||||
DIM objshell
|
||||
set objshell = wscript.createobject("wscript.shell")
|
||||
iReturn = objshell.run("pfcli.exe pf service start --force", 0, true)
|
||||
@@ -0,0 +1,4 @@
|
||||
DIM objshell
|
||||
set objshell = wscript.createobject("wscript.shell")
|
||||
cmd = WScript.Arguments(0)
|
||||
iReturn = objshell.run(cmd, 0, false)
|
||||
@@ -0,0 +1,42 @@
|
||||
# UTF-8
|
||||
#
|
||||
# For more details about fixed file info 'ffi' see:
|
||||
# http://msdn.microsoft.com/en-us/library/ms646997.aspx
|
||||
VSVersionInfo(
|
||||
ffi=FixedFileInfo(
|
||||
# filevers and prodvers should be always a tuple with four items: (1, 2, 3, 4)
|
||||
# Set not needed items to zero 0.
|
||||
filevers=($(env.FILE_VERSION)),
|
||||
prodvers=(1, 0, 0, 0),
|
||||
# Contains a bitmask that specifies the valid bits 'flags'r
|
||||
mask=0x3f,
|
||||
# Contains a bitmask that specifies the Boolean attributes of the file.
|
||||
flags=0x0,
|
||||
# The operating system for which this file was designed.
|
||||
# 0x4 - NT and there is no need to change it.
|
||||
OS=0x4,
|
||||
# The general type of file.
|
||||
# 0x1 - the file is an application.
|
||||
fileType=0x1,
|
||||
# The function of the file.
|
||||
# 0x0 - the function is not defined for this fileType
|
||||
subtype=0x0,
|
||||
# Creation date and time stamp.
|
||||
date=(0, 0)
|
||||
),
|
||||
kids=[
|
||||
StringFileInfo(
|
||||
[
|
||||
StringTable(
|
||||
'040904E4',
|
||||
[StringStruct('CompanyName', 'Microsoft Corporation'),
|
||||
StringStruct('FileDescription', 'Microsoft prompt flow'),
|
||||
StringStruct('FileVersion', '1.0.0.0'),
|
||||
StringStruct('InternalName', 'setup'),
|
||||
StringStruct('LegalCopyright', 'Copyright (c) Microsoft Corporation. All rights reserved.'),
|
||||
StringStruct('ProductName', 'Microsoft prompt flow'),
|
||||
StringStruct('ProductVersion', '$(env.CLI_VERSION)')])
|
||||
]),
|
||||
VarFileInfo([VarStruct('Translation', [1033, 1252])])
|
||||
]
|
||||
)
|
||||
Reference in New Issue
Block a user