This repository template contains the source code for the chatbot application, in addition to a step-by-step guide on how to deploy it to Azure.
Please see the main workshop repository githubuniverseworkshops/workshop-build-deploy-your-own-copilot
for additional resources and learning material.
Note
This repo is intended to give an introduction to various GitHub Copilot features, such as Copilot Chat and Copilot CLI. Hence the step-by-step guides below contain the general description of what needs to be done, and Copilot Chat and/or Copilot CLI can support you in generating the necessary commands.
Each step (where applicable) also contains a Cheatsheet
which can be used to validate the Copilot suggestion(s) against the correct command.
💡 Play around with different prompts and see how it affects the accuracy of the GitHub Copilot suggestions. E.g. Copilot CLI offers a 📝 Revise query
option that can be used to refine the suggestion without writing the whole prompt anew.
- Give a greeting when entering the chat
- List
markdown
files in any public GitHub.com repository as selectable options - Create an AI-generated summary of the selected
markdown
file, e.g. aREADME.md
- This chatbot source code is based on the Microsoft Bot Framework SDK
- The OpenAI API is used for generating text summaries
- The bot is intended for deployment to Azure
The VSCode Codespaces image (.devcontainer/devcontainer.json
) has been configured with the following tooling;
- GitHub Copilot (VSCode extension)
- Azure CLI
v1.2.1
Warning
Some of the resources used in this workshop might incur additional charges. Please see the main workshop repository githubuniverseworkshops/workshop-build-deploy-your-own-copilot
for links to the relevant billing information.
⏳ ~2min
- Click
Use this template
👉Create a new repository
- Set owner to your personal GitHub user
- Give it a name
- Set visibility to
Private
- Click
Create repository
⏳ ~3min
- In the newly created repo, click
Code
👉Codespaces
👉[ellipsis menu]
👉New with options
👉 Ensure thatDev container configuration
is set toDefault project configuration
👉Create codespace
- ❗If you're having problems launching the Codespace then you can also clone the repo and continue from here in your IDE
- There is no need to push changes back to the repo during the workshop
git clone https://github.com/<YOUR_NAME_SPACE>/<YOUR_REPO_NAME>.git
cd <YOUR_REPO_NAME>
⏳ ~3min
- Install GitHub Copilot CLI
npm i -g @githubnext/github-copilot-cli
eval "$(github-copilot-cli alias -- "$0")"
- 💡 The command below is necessary if you have not already authorized GitHub Copilot CLI
github-copilot-cli auth
- Verify that Copilot CLI is functioning by asking it a question
?? Which version of node is installed
- Expected output
──────────────────── Command ────────────────────
node --version
────────────────── Explanation ──────────────────
○ node is the Node.js runtime.
◆ --version specifies that we want to print the version of the runtime.
❯ ✅ Run this command
📝 Revise query
❌ Cancel
This will execute the suggested command in your shell.
Are you sure? (y/N)
🕛 Hold on, executing commmand...
v20.8.0
⏳ ~2min
- The Azure CLI is pre-installed on the Codespace
az login --use-device-code
- Run the command below to show the list of subscriptions tied to the logged in account
az account list
- Set the desired subscription
az account set --subscription "<subscription_id_OR_name>"
⏳ ~5min
- Sign in to your Open AI account
- If you don't have an account, create one here
- Create an API key
- 💡 Make sure that you have available an Credit balance for API consumption
Important
The steps below will require parameter values to be set. Where possible, the following default values have been used in the Cheatsheet
commands and in configuration files:
Universe2023CopilotRG
(Azure resource group name)westus
(location)Universe2023CopilotId
(Azure Identity resource name)Universe2023CopilotASP
(Azure App Service Plan name)
If you wish to use different values then keep track of them in order to ensure they are consistently used where needed.
Some values are part of a global namespace and can therefore not be defaulted, for these values only placeholders are provided in the Cheatsheet
and configuration files:
<appServiceName>
(Azure App Service name)<botName>
(Azure Bot resource name/handle)
⏳ ~5min
⏳ ~1min
Cheatsheet
az group create --name "Universe2023CopilotRG" --location "westus"
{
"id": "/subscriptions/xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx/resourceGroups/Universe2023CopilotRG",
"location": "westus",
"managedBy": null,
"name": "Universe2023CopilotRG",
"properties": {
"provisioningState": "Succeeded"
},
"tags": null,
"type": "Microsoft.Resources/resourceGroups"
}
⏳ ~1min
Important
The following output data from this command will be needed later:
clientId
tenantId
Cheatsheet
az identity create --resource-group "Universe2023CopilotRG" --name "Universe2023CopilotId"
{
"clientId": "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx",
"id": "/subscriptions/xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx/resourcegroups/Universe2023CopilotRG/providers/Microsoft.ManagedIdentity/userAssignedIdentities/Universe2023CopilotId",
"location": "westus",
"name": "Universe2023CopilotId",
"principalId": "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx",
"resourceGroup": "Universe2023CopilotRG",
"systemData": null,
"tags": {},
"tenantId": "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx",
"type": "Microsoft.ManagedIdentity/userAssignedIdentities"
}
4. Create an Azure App Service resource in the resource group. The ARM template is located in "./templates/template-appService.json" and the input parameters are in "./templates/parameters-template-appService.json".
⏳ ~5min
Important
Update the following parameters
inside ./templates/parameters-template-appService.json
:
appServiceName.value
- a globally unique name, e.g.<yourGitHubHandle>Universe2023CopilotAS
appId.value
- theclientId
of the identity resource created earlierUMSIName.value
- thename
of the identity resource created earlierUMSIResourceGroupName.value
- theresourceGroup
of the identity resource created earliertenantId.value
- thetenantId
of the identity resource created earlier
Cheatsheet
az deployment group create --resource-group "Universe2023CopilotRG" --template-file ./templates/template-appService.json --parameters ./templates/parameters-template-appService.json
{
"id": "/subscriptions/xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx/resourceGroups/Universe2023CopilotRG/providers/Microsoft.Resources/deployments/template-appService",
"location": null,
"name": "template-appService",
"properties": {
"correlationId": "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx",
"debugSetting": null,
"dependencies": [
{
"dependsOn": [
{
"id": "/subscriptions/xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx/resourceGroups/Universe2023CopilotRG/providers/Microsoft.Web/serverfarms/Universe2023CopilotASP",
"resourceGroup": "Universe2023CopilotRG",
"resourceName": "Universe2023CopilotASP",
"resourceType": "Microsoft.Web/serverfarms"
}
],
"id": "/subscriptions/xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx/resourceGroups/Universe2023CopilotRG/providers/Microsoft.Web/sites/StebjeUniverse2023CopilotAS",
"resourceGroup": "Universe2023CopilotRG",
"resourceName": "StebjeUniverse2023CopilotAS",
"resourceType": "Microsoft.Web/sites"
}
],
"duration": "PT36.4806494S",
"error": null,
"mode": "Incremental",
"onErrorDeployment": null,
"outputResources": [
{
"id": "/subscriptions/xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx/resourceGroups/Universe2023CopilotRG/providers/Microsoft.Web/serverfarms/Universe2023CopilotASP",
"resourceGroup": "Universe2023CopilotRG"
},
{
"id": "/subscriptions/xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx/resourceGroups/Universe2023CopilotRG/providers/Microsoft.Web/sites/StebjeUniverse2023CopilotAS",
"resourceGroup": "Universe2023CopilotRG"
}
],
"outputs": null,
"parameters": {
"appId": {
"type": "String",
"value": "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx"
},
"appSecret": {
"type": "String",
"value": ""
},
"appServiceName": {
"type": "String",
"value": "StebjeUniverse2023CopilotAS"
},
"appType": {
"type": "String",
"value": "UserAssignedMSI"
},
"existingAppServicePlanLocation": {
"type": "String",
"value": ""
},
"existingAppServicePlanName": {
"type": "String",
"value": ""
},
"newAppServicePlanLocation": {
"type": "String",
"value": "westus"
},
"newAppServicePlanName": {
"type": "String",
"value": "Universe2023CopilotASP"
},
"newAppServicePlanSku": {
"type": "Object",
"value": {
"capacity": 1,
"family": "S",
"name": "S1",
"size": "S1",
"tier": "Standard"
}
},
"tenantId": {
"type": "String",
"value": "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx"
},
"umsiName": {
"type": "String",
"value": "Universe2023CopilotId"
},
"umsiResourceGroupName": {
"type": "String",
"value": "Universe2023CopilotRG"
}
},
"parametersLink": null,
"providers": [
{
"id": null,
"namespace": "Microsoft.Web",
"providerAuthorizationConsentState": null,
"registrationPolicy": null,
"registrationState": null,
"resourceTypes": [
{
"aliases": null,
"apiProfiles": null,
"apiVersions": null,
"capabilities": null,
"defaultApiVersion": null,
"locationMappings": null,
"locations": [
"westus"
],
"properties": null,
"resourceType": "serverfarms",
"zoneMappings": null
},
{
"aliases": null,
"apiProfiles": null,
"apiVersions": null,
"capabilities": null,
"defaultApiVersion": null,
"locationMappings": null,
"locations": [
"westus"
],
"properties": null,
"resourceType": "sites",
"zoneMappings": null
}
]
}
],
"provisioningState": "Succeeded",
"templateHash": "xxxx",
"templateLink": null,
"timestamp": "2023-10-19T17:55:24.012856+00:00",
"validatedResources": null
},
"resourceGroup": "Universe2023CopilotRG",
"tags": null,
"type": "Microsoft.Resources/deployments"
}
5. Create an Azure Bot resource in the resource group. The ARM template is located in "./templates/template-botResource.json" and the input parameters are in "./templates/parameters-template-botResource.json".
⏳ ~5min
Important
Update the following parameters
inside ./templates/parameters-template-botResource.json
:
azureBotId.value
- a globally unique name, e.g.<yourGitHubHandle>Universe2023CopilotBot
botEndpoint.value
- the messaging endpoint for your bot;https://<appServiceName>.azurewebsites.net/api/messages
appId.value
- theclientId
of the identity resource created earlierUMSIName.value
- thename
of the identity resource created earlierUMSIResourceGroupName.value
- theresourceGroup
of the identity resource created earliertenantId.value
- thetenantId
of the identity resource created earlier
Cheatsheet
az deployment group create --resource-group "Universe2023CopilotRG" --template-file ./templates/template-botResource.json --parameters ./templates/parameters-template-botResource.json
{
"id": "/subscriptions/xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx/resourceGroups/Universe2023CopilotRG/providers/Microsoft.Resources/deployments/template-botResource",
"location": null,
"name": "template-botResource",
"properties": {
"correlationId": "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx",
"debugSetting": null,
"dependencies": [],
"duration": "PT7.9925706S",
"error": null,
"mode": "Incremental",
"onErrorDeployment": null,
"outputResources": [
{
"id": "/subscriptions/xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx/resourceGroups/Universe2023CopilotRG/providers/Microsoft.BotService/botServices/StebjeUniverse2023CopilotBot",
"resourceGroup": "Universe2023CopilotRG"
}
],
"outputs": null,
"parameters": {
"appId": {
"type": "String",
"value": "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx"
},
"appType": {
"type": "String",
"value": "UserAssignedMSI"
},
"azureBotId": {
"type": "String",
"value": "StebjeUniverse2023CopilotBot"
},
"azureBotRegion": {
"type": "String",
"value": "global"
},
"azureBotSku": {
"type": "String",
"value": "F0"
},
"botEndpoint": {
"type": "String",
"value": "https://StebjeUniverse2023CopilotAS.azurewebsites.net/api/messages"
},
"tenantId": {
"type": "String",
"value": "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx"
},
"umsiName": {
"type": "String",
"value": "Universe2023CopilotId"
},
"umsiResourceGroupName": {
"type": "String",
"value": "Universe2023CopilotRG"
}
},
"parametersLink": null,
"providers": [
{
"id": null,
"namespace": "Microsoft.BotService",
"providerAuthorizationConsentState": null,
"registrationPolicy": null,
"registrationState": null,
"resourceTypes": [
{
"aliases": null,
"apiProfiles": null,
"apiVersions": null,
"capabilities": null,
"defaultApiVersion": null,
"locationMappings": null,
"locations": [
"global"
],
"properties": null,
"resourceType": "botServices",
"zoneMappings": null
}
]
}
],
"provisioningState": "Succeeded",
"templateHash": "xxxxxxx",
"templateLink": null,
"timestamp": "2023-10-19T18:07:03.391786+00:00",
"validatedResources": null
},
"resourceGroup": "Universe2023CopilotRG",
"tags": null,
"type": "Microsoft.Resources/deployments"
}
⏳ ~2min
Important
Update the following values inside .env
:
MicrosoftAppId
- theclientId
of the identity resource created earlierMicrosoftAppTenantId
- thetenantId
of the identity resource created earlierOpenApiKey
- your OpenAI API key (if available)
Cheatsheet
cp .env.sample .env
MicrosoftAppType=UserAssignedMSI
MicrosoftAppId="<IdentityResource_ClientId>"
MicrosoftAppPassword=
MicrosoftAppTenantId="<IdentityResource_TenantId>"
OpenApiKey=
⏳ ~3min
Important
- Install
npm
dependencies - Build
web.config
file for Azure Bot - Compress all the content of the repository to a new
.zip
file
Cheatsheet
npm install
az bot prepare-deploy --lang JavaScript --code-dir "."
zip -r MyUniverse2023Bot.zip .
⏳ ~5min
Cheatsheet
az webapp deployment source config-zip --resource-group "Universe2023CopilotRG" --name <appServiceName> --src "./MyUniverse2023Bot.zip"
Getting scm site credentials for zip deployment
Starting zip deployment. This operation can take a while to complete ...
Deployment endpoint responded with status code 202
{
"active": true,
"author": "N/A",
"author_email": "N/A",
"complete": true,
"deployer": "ZipDeploy",
"end_time": "2023-10-19T18:32:35.3674841Z",
"id": "xxxxxxx",
"is_readonly": true,
"is_temp": false,
"last_success_end_time": "2023-10-19T18:32:35.3674841Z",
"log_url": "https://stebjeuniverse2023copilotas.scm.azurewebsites.net/api/deployments/latest/log",
"message": "Created via a push deployment",
"progress": "",
"provisioningState": "Succeeded",
"received_time": "2023-10-19T18:30:26.6594544Z",
"site_name": "StebjeUniverse2023CopilotAS",
"start_time": "2023-10-19T18:30:26.8157076Z",
"status": 4,
"status_text": "",
"url": "https://stebjeuniverse2023copilotas.scm.azurewebsites.net/api/deployments/latest"
}
⏳ ~2min
Cheatsheet
az webapp config appsettings set --resource-group "Universe2023CopilotRG" --name <appServiceName> --settings WEBSITE_NODE_DEFAULT_VERSION=18.12.1
[
{
"name": "WEBSITE_NODE_DEFAULT_VERSION",
"slotSetting": false,
"value": "18.12.1"
},
{
"name": "MicrosoftAppType",
"slotSetting": false,
"value": "UserAssignedMSI"
},
{
"name": "MicrosoftAppId",
"slotSetting": false,
"value": "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx"
},
{
"name": "MicrosoftAppPassword",
"slotSetting": false,
"value": ""
},
{
"name": "MicrosoftAppTenantId",
"slotSetting": false,
"value": "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx"
}
]
⏳ ~5min
- Navigate to Azure --> Bot services --> (your Bot) --> Test in Web Chat
- Ensure that the bot is responding to messages as expected
⏳ ~5min
⏳ ~2min
Note
Did you know? You can ask for GitHub-specific suggestions in the Copilot CLI by using the gh?
prefix.
Cheatsheet
gh codespace list
gh codespace delete --repo <user/repo>
NAME DISPLAY NAME REPOSITORY BRANCH STATE CREATED AT
ubiquitous-cod-9ww4jv5796fxj ubiquitous cod stebje/my-universe-copilot2 main Shutdown 9d
1 codespace(s) deleted successfully
- Please refer to the Microsoft Docs for troubleshooting specific services in scope for this workshop
- Alternatively, let Copilot Chat have a go at the error message 😉