Building and deploying fractal.build to Azure from Team Foundation Server

This year we started with creating a Design Language System for Nextens. It runs on Fractal, “a tool to help you build and document web component libraries, and then integrate them into your projects”. We use it to create and document the atoms, molecules and organisms that make up our components.

The site is deployed continuously to an App Service in Azure from our on-premise Microsoft Visual Studio Team Foundation Server 2017.3.1. This post documents how this is done.

web.config

In the source folder we have a web.config that fixes the MIME types of fonts so they load correctly in Azure, and which adds a rewrite rule that enables extension-less URLs in the documentation pages of Fractal.

The latter is needed because we have this setting in \gulp\fractal-setup.js:

1
fractal.web.set('builder.urls.ext', null); // default is '.html'

The content of web.config:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0"/>
</system.web>
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
</httpProtocol>
<staticContent>
<remove fileExtension=".svg" />
<remove fileExtension=".woff" />
<remove fileExtension=".woff2" />
<mimeMap fileExtension=".svg" mimeType="image/svg+xml" />
<mimeMap fileExtension=".woff" mimeType="application/x-font-woff" />
<mimeMap fileExtension=".woff2" mimeType="application/font-woff2" />
</staticContent>
<rewrite>
<rules>
<rule name="docs/pattern-overview">
<match url="(^docs|^components)(\/.+)+$"/>
<action type="Rewrite" url="{R:0}.html"/>
<conditions>
<add input="{URL}" pattern=".(html|svg|scss|css)$" negate="true"/>
</conditions>
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>

The web.config file is copied from the source folder to the public folder by a gulp task (gulp\gulp-tasks\copy.js):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/* global module */
module.exports = function (gulp, config, plugins, build_base) {
'use strict';

gulp.task('copy:js', function (done) {
gulp.src(config.src.js)
.pipe(plugins.plumber({ errorHandler: config.onError }))
.pipe(plugins.include())
.pipe(plugins.uglify())
.pipe(gulp.dest(config.build.js))

gulp.src(config.fractal.docsImages)
.pipe(gulp.dest(build_base + 'docs/'))

gulp.src(config.src.path + '*.*') // favicon.ico and web.config
.pipe(gulp.dest(build_base))

done();
});
};

The config.src.path is __dirname + '/source/'

The Build tasks

NPM install

To install the npm packages defined in your package.json file add an npm task with these settings:

  • The working folder should point to the directory that contains the package.json file.
  • The npm command to use is install

Install gulp –save-dev

To install the gulp npm package add an npm task with these settings:

  • npm command: install
  • arguments: gulp --save-dev

Install gulp-cli –save-dev

To install the gulp-cli npm package add an npm task with these settings:

  • npm command: install
  • arguments: gulp-cli --save-dev

Gulp build

To run the actual Gulp build task add a Gulp task with these settings:

  • Gulp File Path: the path to your gulpfile.js
  • Gulp Task(s): build
  • Advanced > Working Directory: the same as the working folder in the first two tasks
  • Advanced > gulp.js location: node_modules/gulp/bin/gulp.js

The log of this task should look something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
##[section]Starting: gulp build
[...]
[00:44:44] Starting 'build'...
[...]
[00:45:41] Finished 'build:all' after 55 s
[00:45:41] Starting 'fractal:build'...
[?25l⚑ Exported 1 of 635 items
[...]
[?25l⚑ Exported 635 of 635 items
✔ Fractal build completed!
[00:51:17] Finished 'fractal:build' after 5.6 min
[00:51:17] Finished 'build' after 6.55 min
##[section]Finishing: gulp build

Publish Build Artifacts

Add a Publish Build Artifacts task with these settings:

Path to Publish

The path to publish is the folder named public created by the Gulp build.

1
$/Cumulus/Stitch-DLS/$(BranchName)/rbi-stitch/public

Artifact Name

1
drop

The Release

The release is done with an Azure App Service Deploy task.

Point the Package or folder to the public folder created by the build:
$(System.DefaultWorkingDirectory)/Dev05-Stitch/drop

The log of this task should look something like this:

1
2
3
4
5
6
Info: Updating file (*****\assets.html).
[...]
Info: Updating file (*****\themes\mandelbrot\js\mandelbrot.js.map).
Info: Updating file (*****\Web.config).
Total changes: 1211 (0 added, 0 deleted, 1211 updated, 0 parameters changed, 75632972 bytes copied)
Successfully deployed web package to App Service.