Skip to content

Commit

Permalink
Change Azure PR deploy storage (#17429)
Browse files Browse the repository at this point in the history
  • Loading branch information
ecraig12345 authored Mar 17, 2021
1 parent bc7f238 commit 82ad36f
Show file tree
Hide file tree
Showing 17 changed files with 192 additions and 167 deletions.
12 changes: 12 additions & 0 deletions .devops/templates/tools.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,15 @@ steps:
- script: |
echo "##vso[task.setvariable variable=shellopts]braceexpand:hashall:interactive-comments:errexit:errtrace"
displayName: Force exit on error (bash)
# Log all the environment variables since it can be useful for debugging.
# (This happens automatically for the built-in agents, but not for custom agents.)
- script: |
printenv | sort
echo "SHELLOPTS $SHELLOPTS"
echo 'deployBasePath "$(deployBasePath)"'
echo 'deployUrl "$(deployUrl)"'
echo 'isPR "$(isPR)"'
echo 'targetBranch "$(targetBranch)"'
displayName: Log environment variables (Linux)
condition: eq(variables['Agent.OS'], 'Linux')
24 changes: 15 additions & 9 deletions .devops/templates/variables.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
parameters:
# For customizing the deployment path in non-PR builds
- name: deployBasePath
type: string
default: ''

- name: azureSubscription
type: string
default: 'UI Fabric (bac044cf-49e1-4843-8dda-1ce9662606c8)'

# Skip the component governance detection step (injected by a pipeline decorator from an
# internal extension) by default because we run it separately. Since all our pipelines
# in each branch install the same packages, only one pipeline (currently the daily release)
Expand All @@ -16,17 +13,26 @@ parameters:
default: true

variables:
deployBasePath: ${{ coalesce(parameters.deployBasePath, 'pr-deploy-site/$(Build.SourceBranch)') }}
# Also accessed as process.env.DEPLOYHOST
deployHost: 'fluentuipr.z22.web.core.windows.net'

deployHost: 'fabricweb.z5.web.core.windows.net'
# Also accessed as process.env.DEPLOYURL
deployUrl: 'https://$(deployHost)/$(deployBasePath)'

azureSubscription: ${{ parameters.azureSubscription }}
# This service principal ("subscription" is a misleading name) only has access to the fluentuipr storage account
azureSubscription: Azure PR deploy
azureStorage: fluentuipr

${{ if ne(variables['Build.SourceBranch'], 'refs/heads/master') }}:
${{ if not(startsWith(variables['Build.SourceBranch'], 'refs/heads/')) }}:
isPR: true
targetBranch: 'origin/$(System.PullRequest.TargetBranch)'
${{ if eq(variables['Build.SourceBranch'], 'refs/heads/master') }}:
# Deploy PRs under "pull/####" unless otherwise requested
# (this is also accessed as process.env.DEPLOYBASEPATH)
deployBasePath: ${{ coalesce(parameters.deployBasePath, 'pull/$(System.PullRequest.PullRequestNumber)') }}
${{ if startsWith(variables['Build.SourceBranch'], 'refs/heads/') }}:
isPR: false
targetBranch: ''
# Deploy master under "heads/branchname" unless otherwise requested
deployBasePath: ${{ coalesce(parameters.deployBasePath, replace(variables['Build.SourceBranch'], 'refs/', '')) }}

skipComponentGovernanceDetection: ${{ parameters.skipComponentGovernanceDetection }}
4 changes: 2 additions & 2 deletions apps/perf-test/tasks/fluentPerfRegressions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ export function getFluentPerfRegressions() {
}

function linkToFlamegraph(value: string, filename: string) {
const urlForDeployPath = process.env.BUILD_SOURCEBRANCH
? `http://fabricweb.z5.web.core.windows.net/pr-deploy-site/${process.env.BUILD_SOURCEBRANCH}/perf-test-northstar`
const urlForDeployPath = process.env.DEPLOYURL
? `${process.env.DEPLOYURL}/perf-test-northstar`
: 'file://' + config.paths.packageDist('perf-test');

return `[${value}](${urlForDeployPath}/${path.basename(filename)})`;
Expand Down
44 changes: 16 additions & 28 deletions apps/perf-test/tasks/perf-test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import fs from 'fs';
import path from 'path';
import flamegrill, { CookResults, Scenarios, ScenarioConfig } from 'flamegrill';
import flamegrill, { CookResults, Scenarios, ScenarioConfig, CookResult } from 'flamegrill';
import scenarioIterations from '../src/scenarioIterations';
import { scenarioRenderTypes, DefaultRenderTypes } from '../src/scenarioRenderTypes';
import { argv } from '@fluentui/scripts';
Expand Down Expand Up @@ -102,8 +102,8 @@ const iterationsDefault = 5000;
// await page.goto(testUrl);
// await page.tracing.stop();

const urlForDeployPath = process.env.BUILD_SOURCEBRANCH
? `http://fabricweb.z5.web.core.windows.net/pr-deploy-site/${process.env.BUILD_SOURCEBRANCH}/perf-test`
const urlForDeployPath = process.env.DEPLOYURL
? `${process.env.DEPLOYURL}/perf-test`
: 'file://' + path.resolve(__dirname, '../dist/');

// Temporarily comment out deploy site usage to speed up CI build time and support parallelization.
Expand All @@ -112,14 +112,17 @@ const urlForDeployPath = process.env.BUILD_SOURCEBRANCH
// const urlForDeploy = urlForDeployPath + '/index.html';
const urlForDeploy = 'file://' + path.resolve(__dirname, '../dist/') + '/index.html';

const urlForMaster = process.env.SYSTEM_PULLREQUEST_TARGETBRANCH
? `http://fabricweb.z5.web.core.windows.net/pr-deploy-site/refs/heads/${process.env.SYSTEM_PULLREQUEST_TARGETBRANCH}/perf-test/index.html`
: 'http://fabricweb.z5.web.core.windows.net/pr-deploy-site/refs/heads/master/perf-test/index.html';
const targetPath = `heads/${process.env.SYSTEM_PULLREQUEST_TARGETBRANCH || 'master'}`;
const urlForMaster = `https://${process.env.DEPLOYHOST}/${targetPath}/perf-test/index.html`;

const outDir = path.join(__dirname, '../dist');
const tempDir = path.join(__dirname, '../logfiles');

export async function getPerfRegressions() {
// For debugging, in case the environment variables used to generate these have unexpected values
console.log(`urlForDeployPath: "${urlForDeployPath}"`);
console.log(`urlForMaster: "${urlForMaster}"`);

const iterationsArgv: number = argv().iterations;
const iterationsArg = Number.isInteger(iterationsArgv) && iterationsArgv;

Expand All @@ -129,7 +132,7 @@ export async function getPerfRegressions() {
.map(name => path.basename(name, '.tsx'));

const scenariosArgv: string = argv().scenarios;
const scenariosArg = (scenariosArgv && scenariosArgv.split && scenariosArgv.split(',')) || [];
const scenariosArg = scenariosArgv?.split?.(',') || [];
scenariosArg.forEach(scenario => {
if (!scenariosAvailable.includes(scenario)) {
throw new Error(`Invalid scenario: ${scenario}.`);
Expand Down Expand Up @@ -195,9 +198,7 @@ export async function getPerfRegressions() {

const scenarioResults: CookResults = await flamegrill.cook(scenarios, scenarioConfig);

let comment = createReport(scenarioSettings, scenarioResults);

comment = comment.concat(getFluentPerfRegressions());
const comment = createReport(scenarioSettings, scenarioResults) + getFluentPerfRegressions();

// TODO: determine status according to perf numbers
const status = 'success';
Expand All @@ -214,11 +215,8 @@ export async function getPerfRegressions() {

/**
* Create test summary based on test results.
*
* @param {CookResults} testResults
* @returns {string}
*/
function createReport(scenarioSettings, testResults) {
function createReport(scenarioSettings, testResults: CookResults) {
const report = '## [Perf Analysis](https://github.com/microsoft/fluentui/wiki/Perf-Testing)\n'

// Show only significant changes by default.
Expand All @@ -234,12 +232,9 @@ function createReport(scenarioSettings, testResults) {

/**
* Create a table of scenario results.
*
* @param {CookResults} testResults
* @param {boolean} showAll Show only significant results by default.
* @returns {string}
* @param showAll Show only significant results by default.
*/
function createScenarioTable(scenarioSettings, testResults, showAll) {
function createScenarioTable(scenarioSettings, testResults: CookResults, showAll: boolean) {
const resultsToDisplay = Object.keys(testResults).filter(
key =>
showAll ||
Expand Down Expand Up @@ -291,12 +286,8 @@ function createScenarioTable(scenarioSettings, testResults, showAll) {

/**
* Helper that renders an output cell based on a test result.
*
* @param {CookResult} testResult
* @param {boolean} getBaseline
* @returns {string}
*/
function getCell(testResult, getBaseline) {
function getCell(testResult: CookResult, getBaseline: boolean) {
let flamegraphFile = testResult.processed.output && testResult.processed.output.flamegraphFile;
let errorFile = testResult.processed.error && testResult.processed.error.errorFile;
let numTicks = testResult.analysis && testResult.analysis.numTicks;
Expand All @@ -319,11 +310,8 @@ function getCell(testResult, getBaseline) {

/**
* Helper that renders an output cell based on a test result.
*
* @param {CookResult} testResult
* @returns {string}
*/
function getRegression(testResult) {
function getRegression(testResult: CookResult) {
const cell =
testResult.analysis && testResult.analysis.regression && testResult.analysis.regression.isRegression
? testResult.analysis.regression.regressionFile
Expand Down
20 changes: 20 additions & 0 deletions apps/pr-deploy-site/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"extends": ["plugin:@fluentui/eslint-plugin/node"],
"root": true,
"overrides": [
{
// pr-deploy-site.js is run without transpiling in all browsers, which means it must use
// IE 11-compatible syntax as long as we still support IE 11.
"files": ["pr-deploy-site.js"],
"plugins": ["es5"],
"extends": ["plugin:es5/no-es2015"],
"rules": {
// turn off conflicting or unwanted rules from normal set
"curly": "off",
"no-var": "off",
"vars-on-top": "off",
"prefer-arrow-callback": "off"
}
}
]
}
4 changes: 2 additions & 2 deletions apps/pr-deploy-site/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# PR deployed demo site

This is the site that gets deployed for each PR at `https://fabricweb.z5.web.core.windows.net/pr-deploy-site/refs/pull/#####/merge/` or `https://fluentuipr.z22.web.core.windows.net/pr-deploy-site/refs/pull/#####/merge/` (where `#####` is the real PR number).
This is the site that gets deployed for each PR at `https://fluentuipr.z22.web.core.windows.net/pull/#####/` (where `#####` is the real PR number).

It's also deployed during CI builds for [`master`](https://fabricweb.z5.web.core.windows.net/pr-deploy-site/refs/heads/master/), [`7.0`](https://fluentuipr.z22.web.core.windows.net/pr-deploy-site/refs/heads/7.0/), and [`6.0`](https://fluentuipr.z22.web.core.windows.net/pr-deploy-site/refs/heads/7.0/).
It's also deployed during CI builds for [`master`](https://fluentuipr.z22.web.core.windows.net/heads/master/), [`7.0`](https://fluentuipr.z22.web.core.windows.net/heads/7.0/), and [`6.0`](https://fluentuipr.z22.web.core.windows.net/heads/6.0/).

## How to add a new package to the site

Expand Down
26 changes: 0 additions & 26 deletions apps/pr-deploy-site/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,31 +22,5 @@ <h1>Deployed sites for <a href="#" id="prLink"></a></h1>
</ul>

<script src="./pr-deploy-site.js"></script>

<script>
// @ts-check
// NOTE: use var and string concatenation (not templates) here to ensure compat
var hrefMatch = window.location.href.match(/refs\/(pull|heads)\/([^/]+)/);
var repoUrl = 'https://github.com/microsoft/fluentui';
if (hrefMatch) {
var link = /** @type {HTMLAnchorElement} */ (document.getElementById('prLink'));
if (hrefMatch[1] === 'heads') {
// master or other branch CI
link.innerHTML = hrefMatch[2];
link.href = repoUrl + '/tree/' + hrefMatch[2];
// remove the PR-specific explanation
var prExplanation = document.getElementById('prExplanation');
prExplanation.parentElement.removeChild(prExplanation);
} else {
// PR
link.innerHTML = 'PR #' + hrefMatch[2];
link.href = repoUrl + '/pull/' + hrefMatch[2];
}
}
</script>

<script>
renderSiteLinks(/* insert packages here */);
</script>
</body>
</html>
42 changes: 23 additions & 19 deletions apps/pr-deploy-site/just.config.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import fs from 'fs';
import path from 'path';
import { preset, series, task, copyInstructionsTask, copyInstructions } from '@fluentui/scripts';
import { series, task, copyInstructionsTask, copyInstructions } from '@fluentui/scripts';
import { findGitRoot, getAllPackageInfo } from '@fluentui/scripts/monorepo/index';

const gitRoot = findGitRoot();
let instructions = copyInstructions.copyFilesToDestinationDirectory(
['pr-deploy-site.js', 'pr-deploy-site.css', 'chiclet-test.html'],
const instructions = copyInstructions.copyFilesToDestinationDirectory(
['pr-deploy-site.css', 'chiclet-test.html', 'index.html'],
'dist',
);

Expand All @@ -32,40 +32,44 @@ const allPackages = getAllPackageInfo();
const repoDeps = dependencies.map(dep => allPackages[dep]);
const deployedPackages = new Set<string>();
repoDeps.forEach(dep => {
const distPath = path.join(gitRoot, dep.packagePath, 'dist');

if (fs.existsSync(distPath)) {
let sourcePath = distPath;
const packageDist = path.join(gitRoot, dep.packagePath, 'dist');

if (fs.existsSync(packageDist)) {
if (dep.packageJson.name === '@fluentui/docs') {
instructions.push(...copyInstructions.copyFilesInDirectory(sourcePath, path.join('dist', 'react-northstar')));
instructions.push(...copyInstructions.copyFilesInDirectory(packageDist, path.join('dist', 'react-northstar')));
deployedPackages.add(dep.packageJson.name);
} else if (dep.packageJson.name === '@fluentui/perf-test') {
instructions.push(...copyInstructions.copyFilesInDirectory(sourcePath, path.join('dist', 'perf-test-northstar')));
instructions.push(
...copyInstructions.copyFilesInDirectory(packageDist, path.join('dist', 'perf-test-northstar')),
);
deployedPackages.add(dep.packageJson.name);
} else {
instructions.push(
...copyInstructions.copyFilesInDirectory(sourcePath, path.join('dist', path.basename(dep.packagePath))),
...copyInstructions.copyFilesInDirectory(packageDist, path.join('dist', path.basename(dep.packagePath))),
);
deployedPackages.add(dep.packageJson.name);
}
}
});

preset();

/**
* Renders a site with tiles that are potentially from a partial set of deployed packages
* Sets the list of tiles to render based on which packages were actually built
*/
task('generate:index', () => {
const indexContent = fs.readFileSync(path.join(__dirname, './index.html'), 'utf-8');
task('generate:js', () => {
const jsContent = fs.readFileSync(path.join(__dirname, './pr-deploy-site.js'), 'utf-8');

if (!jsContent.includes('var packages;')) {
console.error('pr-deploy-site.js must contain a line "var packages;" to replace with the actual packages');
process.exit(1);
}

fs.writeFileSync(
path.join('dist', 'index.html'),
indexContent.replace('/* insert packages here */', JSON.stringify([...deployedPackages])),
path.join('dist', 'pr-deploy-site.js'),
jsContent.replace('var packages;', `var packages = ${JSON.stringify([...deployedPackages])};`),
);
});

/**
* Copies all the built (potentially partially) dist files and then generates a index HTML for it
* Copies all the built dist files and updates the JS to load the ones that were actually built
*/
task('generate:site', series(copyInstructionsTask({ copyInstructions: instructions }), 'generate:index'));
task('generate:site', series(copyInstructionsTask({ copyInstructions: instructions }), 'generate:js'));
3 changes: 2 additions & 1 deletion apps/pr-deploy-site/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@
"private": true,
"scripts": {
"generate:site": "just-scripts generate:site",
"just": "just-scripts"
"lint": "eslint --ext .js,.ts ."
},
"license": "MIT",
"devDependencies": {
"@fluentui/eslint-plugin": "^1.0.1",
"@fluentui/scripts": "^1.0.0"
}
}
Loading

0 comments on commit 82ad36f

Please sign in to comment.