diff --git a/.github/workflows/copilot-build-backend.yml b/.github/workflows/copilot-build-backend.yml
index e82da790e..aa463eb0c 100644
--- a/.github/workflows/copilot-build-backend.yml
+++ b/.github/workflows/copilot-build-backend.yml
@@ -34,23 +34,35 @@ jobs:
- uses: actions/checkout@v3
with:
clean: true
+ fetch-depth: 0
- - name: Package Copilot Chat WebAPI
- run: |
- scripts\deploy\package-webapi.ps1 -Configuration Release -DotnetFramework net6.0 -TargetRuntime win-x64 -OutputDirectory ${{ github.workspace }}\scripts\deploy
+ - name: Install GitVersion
+ uses: gittools/actions/gitversion/setup@v0
+ with:
+ versionSpec: '5.x'
- - name: Check formatting of Copilot Chat WebAPI
- run: |
- cd webapi/
- dotnet format --verify-no-changes --verbosity diagnostic
+ - name: Determine version
+ id: gitversion
+ uses: gittools/actions/gitversion/execute@v0
- name: Set version tag
id: versiontag
run: |
- $VERSION_TAG="$(Get-Date -Format "MMddHHmmss")"
+ $VERSION_TAG = "${{ steps.gitversion.outputs.Major }}."
+ $VERSION_TAG += "${{ steps.gitversion.outputs.Minor }}."
+ $VERSION_TAG += "${{ steps.gitversion.outputs.CommitsSinceVersionSource }}"
echo $VERSION_TAG
Write-Output "versiontag=$VERSION_TAG" >> $env:GITHUB_OUTPUT
+ - name: Package Copilot Chat WebAPI
+ run: |
+ scripts\deploy\package-webapi.ps1 -Configuration Release -DotnetFramework net6.0 -TargetRuntime win-x64 -OutputDirectory ${{ github.workspace }}\scripts\deploy -Version ${{ steps.versiontag.outputs.versiontag }} -InformationalVersion "Built from commit ${{ steps.gitversion.outputs.ShortSha }} on $(Get-Date -Format "yyyy-MM-dd")"
+
+ - name: Check formatting of Copilot Chat WebAPI
+ run: |
+ cd webapi/
+ dotnet format --verify-no-changes --verbosity diagnostic
+
- name: Upload package to artifacts
uses: actions/upload-artifact@v3
with:
diff --git a/.github/workflows/copilot-deploy-frontend.yml b/.github/workflows/copilot-deploy-frontend.yml
index 77ee5fb9c..c32cdb5d4 100644
--- a/.github/workflows/copilot-deploy-frontend.yml
+++ b/.github/workflows/copilot-deploy-frontend.yml
@@ -38,6 +38,7 @@ jobs:
- uses: actions/checkout@v3
with:
clean: true
+ fetch-depth: 0
- name: Install Azure CLI
run: |
@@ -69,6 +70,24 @@ jobs:
echo "::add-mask::$swaToken"
echo "SWA_CLI_DEPLOYMENT_TOKEN=$swaToken" >> $GITHUB_ENV
+ - name: Install GitVersion
+ uses: gittools/actions/gitversion/setup@v0
+ with:
+ versionSpec: '5.x'
+
+ - name: Determine version
+ id: gitversion
+ uses: gittools/actions/gitversion/execute@v0
+
+ - name: Set version tag
+ id: versiontag
+ run: |
+ $VERSION_TAG = "${{ steps.gitversion.outputs.Major }}."
+ $VERSION_TAG += "${{ steps.gitversion.outputs.Minor }}."
+ $VERSION_TAG += "${{ steps.gitversion.outputs.CommitsSinceVersionSource }}"
+ echo $VERSION_TAG
+ Write-Output "versiontag=$VERSION_TAG" >> $env:GITHUB_OUTPUT
+
- name: Deploy SWA
run: |
- scripts/deploy/deploy-webapp.sh --subscription ${{secrets.AZURE_SUBSCRIPTION_ID}} --resource-group ${{vars.CC_DEPLOYMENT_GROUP_NAME}} --deployment-name ${{inputs.DEPLOYMENT_NAME}} --application-id ${{vars.APPLICATION_CLIENT_ID}} --authority ${{secrets.APPLICATION_AUTHORITY}} --no-redirect
+ scripts/deploy/deploy-webapp.sh --subscription ${{secrets.AZURE_SUBSCRIPTION_ID}} --resource-group ${{vars.CC_DEPLOYMENT_GROUP_NAME}} --deployment-name ${{inputs.DEPLOYMENT_NAME}} --application-id ${{vars.APPLICATION_CLIENT_ID}} --authority ${{secrets.APPLICATION_AUTHORITY}} --no-redirect -version ${{ steps.versiontag.outputs.versiontag }} -version-info "Built from commit ${{ steps.gitversion.outputs.ShortSha }} on $(Get-Date -Format "yyyy-MM-dd")"
diff --git a/.github/workflows/update-version.sh b/.github/workflows/update-version.sh
deleted file mode 100644
index 5db3622f6..000000000
--- a/.github/workflows/update-version.sh
+++ /dev/null
@@ -1,107 +0,0 @@
-#!/bin/bash
-
-POSITIONAL_ARGS=()
-
-while [[ $# -gt 0 ]]; do
- case $1 in
- -f|--file)
- file="$2"
- shift # past argument
- shift # past value
- ;;
- -p|--propsFile)
- propsFile="$2"
- shift # past argument
- shift # past value
- ;;
- -b|--buildAndRevisionNumber)
- buildAndRevisionNumber="$2"
- shift # past argument
- shift # past value
- ;;
- -*|--*)
- echo "Unknown option $1"
- exit 1
- ;;
- *)
- POSITIONAL_ARGS+=("$1") # save positional arg
- shift # past argument
- ;;
- esac
-done
-
-set -- "${POSITIONAL_ARGS[@]}" # restore positional parameters
-
-if [ -z "$file" ]; then
- echo "ERROR: Parameter file (-f|--file) not provided"
- exit 1;
-elif [ ! -f "$file" ]; then
- echo "ERROR: file ${file} not found"
- exit 1;
-fi
-
-if [ -n "$(cat $file | grep -i "false")" ]; then
- echo "Project is marked as NOT packable - skipping."
- exit 0;
-fi
-
-if [ -z "$propsFile" ]; then
- echo "ERROR: Parameter propsFile (-f|--file) not provided"
- exit 1;
-elif [ ! -f "$propsFile" ]; then
- echo "ERROR: propsFile ${file} not found"
- exit 1;
-fi
-
-if [ -z "$buildAndRevisionNumber" ]; then
- echo "ERROR: Parameter buildAndRevisionNumber (-b|--buildAndRevisionNumber) not provided"
- exit 1;
-fi
-
-propsVersionString=$(cat $propsFile | grep -i "");
-regex="([0-9.]*)<\/Version>"
-if [[ $propsVersionString =~ $regex ]]; then
- propsVersion=${BASH_REMATCH[1]}
-else
- echo "ERROR: Version tag not found in propsFile"
- exit 1;
-fi
-
-if [ -z "$propsVersion" ]; then
- echo "ERROR: Version tag not found in propsFile"
- exit 1;
-elif [[ ! "$propsVersion" =~ ^0.* ]]; then
- echo "ERROR: Version expected to start with 0. Actual: ${propsVersion}"
- exit 1;
-fi
-
-fullVersionString="${propsVersion}.${buildAndRevisionNumber}-preview"
-
-if [[ ! "$fullVersionString" =~ ^0.* ]]; then
- echo "ERROR: Version expected to start with 0. Actual: ${fullVersionString}"
- exit 1;
-fi
-
-echo "==== Project: ${file} ====";
-echo "propsFile = ${propsFile}"
-echo "buildAndRevisionNumber = ${buildAndRevisionNumber}"
-echo "version prefix from propsFile = ${propsVersion}"
-echo "full version string: ${fullVersionString}"
-
-versionInProj=$(cat $file | grep -i "");
-if [ -n "$versionInProj" ]; then
- # Version tag already exists in the csproj. Let's replace it.
- echo "Updating version tag..."
- content=$(cat $file | sed --expression="s/\([0-9]*.[0-9]*\)<\/Version>/$fullVersionString<\/Version>/g");
-else
- # Version tag not found in the csproj. Let's add it.
- echo "Project is packable - adding version tag..."
- content=$(cat $file | sed --expression="s/<\/Project>/$fullVersionString<\/Version><\/PropertyGroup><\/Project>/g");
-fi
-
-if [ $? -ne 0 ]; then exit 1; fi
-echo "$content" && echo "$content" > $file;
-if [ $? -ne 0 ]; then exit 1; fi
-
-echo "DONE";
-echo "";
diff --git a/.gitignore b/.gitignore
index 719f5ba7d..99475c678 100644
--- a/.gitignore
+++ b/.gitignore
@@ -485,5 +485,8 @@ webapp/public/.well-known*
# Auto-generated solution file from Visual Studio
webapi/CopilotChatWebApi.sln
+# Files created for deployments
+/deploy/
+
# Tesseract OCR language data files
-*.traineddata
\ No newline at end of file
+*.traineddata
diff --git a/scripts/deploy/deploy-webapp.ps1 b/scripts/deploy/deploy-webapp.ps1
index 88b3d1c99..0be6c23d8 100644
--- a/scripts/deploy/deploy-webapp.ps1
+++ b/scripts/deploy/deploy-webapp.ps1
@@ -27,7 +27,15 @@ param(
[Parameter(Mandatory=$false)]
[string]
# Authority for client applications that are not configured as multi-tenant.
- $Authority="https://login.microsoftonline.com/common"
+ $Authority="https://login.microsoftonline.com/common",
+
+ [string]
+ # Version to display in UI.
+ $Version = "",
+
+ [string]
+ # Additional information given in version info. (Ex: commit SHA)
+ $VersionInfo = ""
)
Write-Host "Setting up Azure credentials..."
@@ -64,6 +72,8 @@ Write-Host "Writing environment variables to '$envFilePath'..."
"REACT_APP_AAD_AUTHORITY=$Authority" | Out-File -FilePath $envFilePath -Append
"REACT_APP_AAD_CLIENT_ID=$ApplicationClientId" | Out-File -FilePath $envFilePath -Append
"REACT_APP_SK_API_KEY=$webapiApiKey" | Out-File -FilePath $envFilePath -Append
+"REACT_APP_SK_VERSION=$Version" | Out-File -FilePath $envFilePath -Append
+"REACT_APP_SK_BUILD_INFO=$VersionInfo" | Out-File -FilePath $envFilePath -Append
Write-Host "Generating SWA config..."
$swaConfig = $(Get-Content "$PSScriptRoot/../../webapp/template.swa-cli.config.json" -Raw)
diff --git a/scripts/deploy/deploy-webapp.sh b/scripts/deploy/deploy-webapp.sh
index 66ef188cc..3414d7b3f 100755
--- a/scripts/deploy/deploy-webapp.sh
+++ b/scripts/deploy/deploy-webapp.sh
@@ -15,6 +15,8 @@ usage() {
echo " -d, --deployment-name DEPLOYMENT_NAME Name of the deployment from a 'deploy-azure.sh' deployment (mandatory)"
echo " -a, --application-id APPLICATION_ID Client application ID (mandatory)"
echo " -au, --authority Authority to use for client applications that are not configured as multi-tenant. Defaults to (https://login.microsoftonline.com/common) if not specified."
+ echo " -v --version VERSION Version to display in UI (default: 1.0.0)"
+ echo " -i --version-info INFO Additional info to put in version details"
echo " -nr, --no-redirect Do not attempt to register redirect URIs with the client application"
}
@@ -47,6 +49,16 @@ while [[ $# -gt 0 ]]; do
shift
shift
;;
+ -v|--version)
+ VERSION="$2"
+ shift
+ shift
+ ;;
+ -i|--version-nfo)
+ VERSION_INFO="$2"
+ shift
+ shift
+ ;;
-nr|--no-redirect)
NO_REDIRECT=true
shift
@@ -97,6 +109,8 @@ echo "REACT_APP_BACKEND_URI=https://$WEB_API_URL/" > $ENV_FILE_PATH
echo "REACT_APP_AAD_AUTHORITY=$AUTHORITY" >> $ENV_FILE_PATH
echo "REACT_APP_AAD_CLIENT_ID=$APPLICATION_ID" >> $ENV_FILE_PATH
echo "REACT_APP_SK_API_KEY=$WEB_API_KEY" >> $ENV_FILE_PATH
+echo "REACT_APP_SK_VERSION=$VERSION" >> $ENV_FILE_PATH
+echo "REACT_APP_SK_BUILD_INFO=$VERSION_INFO" >> $ENV_FILE_PATH
echo "Writing swa-cli.config.json..."
SWA_CONFIG_FILE_PATH="$SCRIPT_ROOT/../../webapp/swa-cli.config.json"
diff --git a/scripts/deploy/package-webapi.ps1 b/scripts/deploy/package-webapi.ps1
index 81ae21ccf..586570751 100755
--- a/scripts/deploy/package-webapi.ps1
+++ b/scripts/deploy/package-webapi.ps1
@@ -18,7 +18,15 @@ param(
[string]
# Output directory for published assets.
- $OutputDirectory = "$PSScriptRoot"
+ $OutputDirectory = "$PSScriptRoot",
+
+ [string]
+ # Version to give to assemblies and files.
+ $Version = "1.0.0",
+
+ [string]
+ # Additional information given in version info.
+ $InformationalVersion = ""
)
Write-Host "BuildConfiguration: $BuildConfiguration"
@@ -37,7 +45,7 @@ if (!(Test-Path $publishOutputDirectory)) {
}
Write-Host "Build configuration: $BuildConfiguration"
-dotnet publish "$PSScriptRoot/../../webapi/CopilotChatWebApi.csproj" --configuration $BuildConfiguration --framework $DotNetFramework --runtime $TargetRuntime --self-contained --output "$publishOutputDirectory"
+dotnet publish "$PSScriptRoot/../../webapi/CopilotChatWebApi.csproj" --configuration $BuildConfiguration --framework $DotNetFramework --runtime $TargetRuntime --self-contained --output "$publishOutputDirectory" /p:AssemblyVersion=$Version /p:FileVersion=$Version /p:InformationalVersion=$InformationalVersion
if ($LASTEXITCODE -ne 0) {
exit $LASTEXITCODE
}
diff --git a/scripts/deploy/package-webapi.sh b/scripts/deploy/package-webapi.sh
index f4fe48f19..972ff86fd 100644
--- a/scripts/deploy/package-webapi.sh
+++ b/scripts/deploy/package-webapi.sh
@@ -14,7 +14,9 @@ usage() {
echo " -c, --configuration CONFIGURATION Build configuration (default: Release)"
echo " -d, --dotnet DOTNET_FRAMEWORK_VERSION Target dotnet framework (default: net6.0)"
echo " -r, --runtime TARGET_RUNTIME Runtime identifier (default: linux-x64)"
- echo " -p, --output OUTPUT_DIRECTORY Output directory (default: $SCRIPT_ROOT)"
+ echo " -o, --output OUTPUT_DIRECTORY Output directory (default: $SCRIPT_ROOT)"
+ echo " -v --version VERSION Version to set files to (default: 1.0.0)"
+ echo " -i --info INFO Additional info to put in version details"
echo " -nz, --no-zip Do not zip package (default: false)"
}
@@ -42,6 +44,16 @@ while [[ $# -gt 0 ]]; do
shift
shift
;;
+ -v|--version)
+ VERSION="$2"
+ shift
+ shift
+ ;;
+ -i|--info)
+ INFO="$2"
+ shift
+ shift
+ ;;
-nz|--no-zip)
NO_ZIP=true
shift
@@ -58,6 +70,8 @@ done
: "${CONFIGURATION:="Release"}"
: "${DOTNET:="net6.0"}"
: "${RUNTIME:="linux-x64"}"
+: "${VERSION:="1.0.0"}"
+: "${INFO:=""}"
: "${OUTPUT_DIRECTORY:="$SCRIPT_ROOT"}"
PUBLISH_OUTPUT_DIRECTORY="$OUTPUT_DIRECTORY/publish"
@@ -72,7 +86,7 @@ if [[ ! -d "$PUBLISH_ZIP_DIRECTORY" ]]; then
fi
echo "Build configuration: $CONFIGURATION"
-dotnet publish "$SCRIPT_ROOT/../../webapi/CopilotChatWebApi.csproj" --configuration $CONFIGURATION --framework $DOTNET --runtime $RUNTIME --self-contained --output "$PUBLISH_OUTPUT_DIRECTORY"
+dotnet publish "$SCRIPT_ROOT/../../webapi/CopilotChatWebApi.csproj" --configuration $CONFIGURATION --framework $DOTNET --runtime $RUNTIME --self-contained --output "$PUBLISH_OUTPUT_DIRECTORY" /p:AssemblyVersion=$VERSION /p:FileVersion=$VERSION /p:InformationalVersion=$INFO
if [ $? -ne 0 ]; then
exit 1
fi
diff --git a/webapi/Controllers/ServiceOptionsController.cs b/webapi/Controllers/ServiceOptionsController.cs
index 28adf3758..e0dd66e5a 100644
--- a/webapi/Controllers/ServiceOptionsController.cs
+++ b/webapi/Controllers/ServiceOptionsController.cs
@@ -1,6 +1,8 @@
// Copyright (c) Microsoft. All rights reserved.
using System;
+using System.Diagnostics;
+using System.Reflection;
using CopilotChat.WebApi.Models.Response;
using CopilotChat.WebApi.Options;
using Microsoft.AspNetCore.Authorization;
@@ -39,15 +41,24 @@ public ServiceOptionsController(
[ProducesResponseType(StatusCodes.Status200OK)]
public IActionResult GetServiceOptions()
{
- return this.Ok(
- new ServiceOptionsResponse()
+ var response = new ServiceOptionsResponse()
+ {
+ MemoryStore = new MemoryStoreOptionResponse()
{
- MemoryStore = new MemoryStoreOptionResponse()
- {
- Types = Enum.GetNames(typeof(MemoryStoreOptions.MemoryStoreType)),
- SelectedType = this._memoryStoreOptions.Type.ToString()
- }
- }
- );
+ Types = Enum.GetNames(typeof(MemoryStoreOptions.MemoryStoreType)),
+ SelectedType = this._memoryStoreOptions.Type.ToString()
+ },
+ Version = GetAssemblyFileVersion()
+ };
+
+ return this.Ok(response);
+ }
+
+ private static string GetAssemblyFileVersion()
+ {
+ Assembly assembly = Assembly.GetExecutingAssembly();
+ FileVersionInfo fileVersion = FileVersionInfo.GetVersionInfo(assembly.Location);
+
+ return fileVersion.FileVersion ?? string.Empty;
}
}
diff --git a/webapi/Models/Response/ServiceOptionsResponse.cs b/webapi/Models/Response/ServiceOptionsResponse.cs
index d5eda9cba..dad1cb091 100644
--- a/webapi/Models/Response/ServiceOptionsResponse.cs
+++ b/webapi/Models/Response/ServiceOptionsResponse.cs
@@ -13,6 +13,12 @@ public class ServiceOptionsResponse
///
[JsonPropertyName("memoryStore")]
public MemoryStoreOptionResponse MemoryStore { get; set; } = new MemoryStoreOptionResponse();
+
+ ///
+ /// Version of this application.
+ ///
+ [JsonPropertyName("version")]
+ public string Version { get; set; } = string.Empty;
}
///
diff --git a/webapp/src/components/header/settings-dialog/SettingsDialog.tsx b/webapp/src/components/header/settings-dialog/SettingsDialog.tsx
index 9b82bcc32..f7c614ad5 100644
--- a/webapp/src/components/header/settings-dialog/SettingsDialog.tsx
+++ b/webapp/src/components/header/settings-dialog/SettingsDialog.tsx
@@ -56,7 +56,7 @@ interface ISettingsDialogProps {
export const SettingsDialog: React.FC = ({ open, closeDialog }) => {
const classes = useClasses();
const dialogClasses = useDialogClasses();
- const { settings, tokenUsage } = useAppSelector((state: RootState) => state.app);
+ const { serviceOptions, settings, tokenUsage } = useAppSelector((state: RootState) => state.app);
return (