Skip to content

Commit

Permalink
Merge pull request #1268 from OfficeDev/dev
Browse files Browse the repository at this point in the history
build: TTK v5.8.0 release
  • Loading branch information
eriolchan authored May 8, 2024
2 parents 40efa16 + 2db7660 commit 1e8f7ac
Show file tree
Hide file tree
Showing 73 changed files with 465 additions and 7,705 deletions.
36 changes: 18 additions & 18 deletions .config/samples-config-v3.json

Large diffs are not rendered by default.

21 changes: 21 additions & 0 deletions .github/actions/send-email-report/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: Send Email Report
description: Send Email Report
runs:
using: "composite"
steps:
- run: |
response=$(curl \
--request POST \
--header "Content-Type: application/x-www-form-urlencoded" \
--data "grant_type=client_credentials&client_id=${{ env.MAIL_CLIENT_ID }}&client_secret=${{ env.MAIL_CLIENT_SECRET }}&resource=https://management.core.windows.net" \
"https://login.microsoftonline.com/${{ env.MAIL_TENANT_ID }}/oauth2/token")
access_token=`echo $response | jq -r '. | select(.access_token) | .access_token'`
curl \
--request POST \
--header "Content-Type: application/json" \
--header "Authorization: Bearer $access_token" \
--data '{"to": "${{ env.TO }}", "body": ${{ env.BODY }}, "subject": "${{ env.SUBJECT }}"}' \
'https://prod-18.northcentralus.logic.azure.com:443/workflows/b33d7861bfc64832a6f62cc8f2213988/triggers/manual/paths/invoke?api-version=2016-10-01&sp=%2Ftriggers%2Fmanual%2Frun&sv=1.0'
shell: bash
362 changes: 362 additions & 0 deletions .github/scripts/getSampleDependencies.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,362 @@
const axios = require("axios");
const glob = require("glob");
const fs = require("fs");
const path = require("path");

const repoRoot = "../TeamsFx-Samples";

const codeOwnerMap = new Map([
["adaptive-card-notification", "[email protected]"],
["basic-blazor-tab-app", "[email protected]"],
["bot-sso", "[email protected]"],
["bot-sso-docker", "[email protected]"],
["command-bot-with-sso", "[email protected]"],
["developer-assist-dashboard", "[email protected]"],
["graph-connector-app", "[email protected]"],
["graph-connector-bot", "[email protected]"],
["graph-toolkit-contact-exporter", "[email protected]"],
["graph-toolkit-one-productivity-hub", "[email protected]"],
["hello-world-bot-with-tab", "[email protected]"],
["hello-world-in-meeting", "[email protected]"],
["hello-world-tab-codespaces", "[email protected]"],
["hello-world-tab-docker", "[email protected]"],
["hello-world-tab-with-backend", "[email protected]"],
["hello-world-teams-tab-and-outlook-add-in", "[email protected]"],
["incoming-webhook-notification", "[email protected]"],
["intelligent-data-chart-generator", "[email protected]"],
["large-scale-notification", "[email protected]"],
["live-share-dice-roller", "[email protected]"],
["notification-codespaces", "[email protected]"],
["NPM-search-connector-M365", "[email protected]"],
["NPM-search-message-extension-codespaces", "[email protected]"],
["query-org-user-with-message-extension-sso", "[email protected]"],
["react-retail-dashboard", "[email protected]"],
["share-now", "[email protected]"],
["spfx-productivity-dashboard", "[email protected]"],
["sso-enabled-tab-via-apim-proxy", "[email protected]"],
["stocks-update-notification-bot", "[email protected]"],
["stocks-update-notification-bot-dotnet", "[email protected]"],
["team-central-dashboard", "[email protected]"],
["test-tool-sample-app", "[email protected]"],
["todo-list-SPFx", "[email protected]"],
["todo-list-with-Azure-backend", "[email protected]"],
["todo-list-with-Azure-backend-M365", "[email protected]"],
["whos-next-meeting-app", "[email protected]"],
]);

async function getSamplesDependencies() {
var dependenciesMap = new Map();
const samplePkgJsonPath = `${repoRoot}/**/package.json`;
const packageJsonFiles = await glob.glob(samplePkgJsonPath, {
ignore: "node_modules/**",
});

packageJsonFiles.forEach((packageJsonFile) => {
const packageJson = JSON.parse(fs.readFileSync(packageJsonFile, "utf8"));
let sampleDir = path.relative(`${repoRoot}`, path.dirname(packageJsonFile));
let codeOwners = "";
if (sampleDir.includes("validation-tool")) {
return;
}

for (const [key, value] of codeOwnerMap) {
if (
key === path.basename(sampleDir) ||
key === path.dirname(sampleDir) ||
key === path.dirname(path.dirname(sampleDir))
) {
codeOwners = value;
}
}
let dependencies = packageJson["dependencies"] ?? {};
Object.assign(dependencies, packageJson["devDependencies"]);
for (dependency in dependencies) {
if (
dependenciesMap.has(dependency) &&
dependenciesMap.get(dependency).has(codeOwners)
) {
dependenciesMap.get(dependency).get(codeOwners).push({
sampleDir,
version: dependencies[dependency],
});
} else if (dependenciesMap.has(dependency)) {
dependenciesMap
.get(dependency)
.set(codeOwners, [{ sampleDir, version: dependencies[dependency] }]);
} else {
const codeOwnerTemplateMap = new Map([
[codeOwners, [{ sampleDir, version: dependencies[dependency] }]],
]);
dependenciesMap.set(dependency, codeOwnerTemplateMap);
}
}
});

return dependenciesMap;
}

async function getCsharpSampleDependencies() {
var dependenciesMap = new Map();
const sampleCsprojPath = `${repoRoot}/**/*.csproj`;
const csprojFiles = await glob.glob(sampleCsprojPath);
csprojFiles.forEach((csprojFile) => {
const csproj = fs.readFileSync(csprojFile, "utf8");
let sampleDir = path.relative(`${repoRoot}`, path.dirname(csprojFile));
let codeOwners = "";
for (const [key, value] of codeOwnerMap) {
if (
key === path.basename(sampleDir) ||
key === path.dirname(sampleDir) ||
key === path.dirname(path.dirname(sampleDir))
) {
codeOwners = value;
}
}

const dependencies = csproj
.split("\n")
.filter((line) => line.includes("<PackageReference"))
.map((line) => {
const name = line.match(/Include="(.*)" Version/)[1];
const version = line.match(/Version="(.*)"/)[1];
return { name, version };
});

for (dependency in dependencies) {
const dependencyName = dependencies[dependency].name;
const dependencyVersion = dependencies[dependency].version;
if (
dependenciesMap.has(dependencyName) &&
dependenciesMap.get(dependencyName).has(codeOwners)
) {
dependenciesMap.get(dependencyName).get(codeOwners).push({
sampleDir,
version: dependencyVersion,
});
} else if (dependenciesMap.has(dependencyName)) {
dependenciesMap
.get(dependencyName)
.set(codeOwners, [{ sampleDir, version: dependencyVersion }]);
} else {
const codeOwnerSampleMap = new Map([
[codeOwners, [{ sampleDir, version: dependencyVersion }]],
]);
dependenciesMap.set(dependencyName, codeOwnerSampleMap);
}
}
});

return dependenciesMap;
}

function generateAdaptiveCardColumnSets(arr) {
if (arr.length === 0) {
return [];
}
let columnSets = [
{
type: "ColumnSet",
columns: [
{
type: "Column",
width: 22,
items: [
{
type: "TextBlock",
text: "Package",
wrap: true,
weight: "Bolder",
},
],
verticalContentAlignment: "Center",
},
{
type: "Column",
width: 38,
items: [
{
type: "TextBlock",
text: "Templates",
wrap: true,
weight: "Bolder",
},
],
verticalContentAlignment: "Center",
},
{
type: "Column",
width: 17,
items: [
{
type: "TextBlock",
text: "Version",
wrap: true,
weight: "Bolder",
},
],
verticalContentAlignment: "Center",
},
{
type: "Column",
width: 23,
items: [
{
type: "TextBlock",
text: "Owners",
wrap: true,
weight: "Bolder",
},
],
verticalContentAlignment: "Center",
},
],
separator: true,
},
];
for (package of arr) {
let ownerColumnSets = [];
package.ownerMap.forEach(function (templatesInfo, owner) {
ownerColumnSets.push({
type: "ColumnSet",
separator: true,
columns: [
{
type: "Column",
width: 56,
items: templatesInfo.map((templateInfo) => {
return {
type: "ColumnSet",
columns: [
{
type: "Column",
width: 40,
items: [
{
type: "TextBlock",
text: templateInfo.sampleDir,
wrap: true,
size: "Small",
},
],
},
{
type: "Column",
width: 16,
items: [
{
type: "TextBlock",
text:
templateInfo.version[0] === ">"
? "\\" + templateInfo.version
: templateInfo.version,
wrap: true,
size: "Small",
},
],
},
],
};
}),
},
{
type: "Column",
width: 24,
items: [
{
type: "TextBlock",
text: owner,
wrap: true,
size: "Small",
},
],
},
],
});
});

columnSets.push({
type: "ColumnSet",
columns: [
{
type: "Column",
width: 20,
items: [
{
type: "TextBlock",
text:
`[${package.name}](${
package.ownerMap
.values()
.next()
.value[0].sampleDir.includes("csharp")
? `https://www.nuget.org/packages/${package.name}`
: `https://www.npmjs.com/package/${package.name}`
})` +
"\n\r" +
`LTS-${package.version}`,
wrap: true,
size: "Small",
},
],
},
{
type: "Column",
width: 80,
items: ownerColumnSets,
},
],
separator: true,
});
}

return columnSets;
}

async function main() {
const dependenciesMap = await getSamplesDependencies();
let arr = [];
for (const entry of dependenciesMap.entries()) {
await axios
.get(`https://registry.npmjs.org/${entry[0]}`)
.then((response) => {
const ltsVersion = response.data["dist-tags"].latest;
const ltsVersionTime = response.data.time[ltsVersion];
const timeDiff = (new Date() - new Date(ltsVersionTime)) / 1000;
if (timeDiff <= 86400) {
arr.push({
name: entry[0],
version: ltsVersion,
ownerMap: entry[1],
});
}
});
}

const csharpDependencyMap = await getCsharpSampleDependencies();
for (const entry of csharpDependencyMap.entries()) {
await axios
.get(
`https://api.nuget.org/v3/registration5-gz-semver2/${entry[0].toLowerCase()}/index.json`
)
.then((response) => {
const ltsVersion = response.data["items"].at(-1).upper;
const ltsVersionTime = response.data.commitTimeStamp;
const timeDiff = (new Date() - new Date(ltsVersionTime)) / 1000;
if (timeDiff <= 86400) {
arr.push({
name: entry[0],
version: ltsVersion,
ownerMap: entry[1],
});
}
});
}

const table = generateAdaptiveCardColumnSets(arr);
const tableString = JSON.stringify(table);
return JSON.stringify(tableString);
}

main().then((result) => {
console.log(result);
});
Loading

0 comments on commit 1e8f7ac

Please sign in to comment.