async function buildSite() {
	// Load the HTML from the WP.com blog site
	const $ = cheerio.load( await request( 'https://blog.remoteintech.company/' ) );

	// Load stylesheets from the WP.com blog site
	const wpcomStylesheets = $( 'style, link[rel=stylesheet]' ).map( ( i, el ) => {
		const $el = $( el );
		const stylesheet = {
			id: $el.attr( 'id' ) || null,
			media: $el.attr( 'media' ) || null,
		};
		if ( $el.is( 'style' ) ) {
			stylesheet.content = $el.html();
		} else {
			stylesheet.url = $el.attr( 'href' );
			if ( /^\/\//.test( stylesheet.url ) ) {
				stylesheet.url = 'https:' + stylesheet.url;
			}
		}
		return stylesheet;
	} ).toArray();

	// Fetch the contents of stylesheets included via <link> tags
	await Promise.all(
		wpcomStylesheets.filter( s => !! s.url ).map( stylesheet => {
			return request( stylesheet.url ).then( content => {
				stylesheet.content = content;
			} );
		} )
	);
	// TODO: Most URLs that appear inside these CSS files are broken because
	// they refer to relative URLs against s[012].wp.com
	const wpcomStylesheetContent = wpcomStylesheets
		.filter( stylesheet => !! stylesheet.content.trim() )
		.map( stylesheet => {
			const lines = [ '/**' ];
			const idString = (
				stylesheet.id ? ' (id="' + stylesheet.id + '")' : ''
			);
			if ( stylesheet.url ) {
				lines.push( ' * WP.com external style' + idString );
				lines.push( ' * ' + stylesheet.url );
			} else {
				lines.push( ' * WP.com inline style' + idString );
			}
			lines.push( ' */' );
			if ( stylesheet.media && stylesheet.media !== 'all' ) {
				lines.push( '@media ' + stylesheet.media + ' {' );
			}
			lines.push( stylesheet.content.trim() );
			if ( stylesheet.media && stylesheet.media !== 'all' ) {
				lines.push( '} /* @media ' + stylesheet.media + ' */' );
			}
			return lines.join( '\n' );
		} ).join( '\n\n' ) + '\n';

	// Use the emoji code from WP.com
	// Most platforms will display emoji natively, but e.g. Linux does not
	let wpcomEmojiScript = null;
	$( 'script' ).each( ( i, el ) => {
		const scriptContents = $( el ).html();
		if ( /\bwindow\._wpemojiSettings\s*=\s*{/.test( scriptContents ) ) {
			wpcomEmojiScript = scriptContents;
		}
	} );

	// Set up the site build directory (start fresh each time)
	rimraf.sync( siteBuildPath );
	fs.mkdirSync( siteBuildPath );
	fs.mkdirSync( path.join( siteBuildPath, 'assets' ) );
	copyAssetToBuild( 'remoteintech.png', null, false );
	copyAssetToBuild( 'external-link.svg', null, false );

	// Set up styles/scripts to be included on all pages
	const stylesheets = [ {
		url: copyAssetToBuild( 'wpcom-blog-styles.css', wpcomStylesheetContent ),
	}, {
		url: '//fonts.googleapis.com/css?family=Source+Sans+Pro:r%7CSource+Sans+Pro:r,i,b,bi&amp;subset=latin,latin-ext,latin,latin-ext',
	}, {
		url: copyAssetToBuild( 'site.css' ),
	} ];
	const scripts = [];
	if ( wpcomEmojiScript ) {
		scripts.push( {
			url: copyAssetToBuild( 'wpcom-emoji.js', wpcomEmojiScript ),
		} );
	}

	// Set up styles/scripts for specific pages
	const indexScripts = [ {
		url: '//cdnjs.cloudflare.com/ajax/libs/lunr.js/2.3.7/lunr.min.js',
	}, {
		url: copyAssetToBuild( 'companies-table.js' ),
	} ];
	const notFoundStyles = [ {
		url: copyAssetToBuild( '404.css' )
	} ];

	// Copy favicon files
	console.log( 'Copying favicon files' );
	const faviconPath = path.join( sitePath, 'assets', 'favicon-package' );
	fs.readdirSync( faviconPath ).forEach( f => {
		fs.copyFileSync( path.join( faviconPath, f ), path.join( siteBuildPath, f ) );
	} );

	// Generate search index
	console.log( 'Generating search index' );
	const searchIndexData = JSON.stringify( buildSearchData( data ) );
	const searchIndexFilename = copyAssetToBuild(
		'search.js',
		searchIndexData
	);

	// Generate the index.html file from the main README
	// TODO: Build this page and its table dynamically; more filters
	const readmeTemplate = swig.compileFile(
		path.join( sitePath, 'templates', 'index.html' )
	);
	console.log( 'Writing main page' );
	writePage( 'index.html', readmeTemplate( {
		stylesheets,
		scripts: scripts.concat( indexScripts ),
		inlineScripts: [
			'\n\t\tvar searchIndexFilename = ' + JSON.stringify( searchIndexFilename ) + ';'
			+ '\n\t\tvar searchIndexSize = ' + JSON.stringify( searchIndexData.length ) + ';'
			+ '\n\t\t',
		],
		pageContent: data.readmeContent,
		editUrl: githubEditUrl( 'README.md' ),
	} ) );

	// Generate the page for each company
	const companyTemplate = swig.compileFile(
		path.join( sitePath, 'templates', 'company.html' )
	);
	process.stdout.write( 'Writing company pages..' );
	data.companies.forEach( ( company, i ) => {
		const dirname = company.linkedFilename.replace( /\.md$/, '' );
		const missingHeadings = Object.keys( headingPropertyNames )
			.filter( h => ! company.profileContent[ h ] );

		writePage( path.join( dirname, 'index.html' ), companyTemplate( {
			stylesheets,
			scripts,
			inlineScripts: [],
			company,
			headingPropertyNames,
			missingHeadings,
			editUrl: githubEditUrl( 'company-profiles/' + company.linkedFilename ),
		} ) );

		if ( i % 10 === 0 ) {
			process.stdout.write( '.' );
		}
	} );

	// Generate custom 404 page
	console.log();
	console.log( 'Writing custom 404 page' );
	const notFoundTemplate = swig.compileFile(
		path.join( sitePath, 'templates', '404.html' )
	);
	writePage( '404.html', notFoundTemplate( {
		notFoundStyles
	} ) );
	
	// Add empty robots.txt
	console.log();
	console.log( 'Writing empty robots.txt' );
	writePage( 'robots.txt', '' );

	console.log();
	console.log( 'Site files are ready in "site/build/"' );
}
The main function that prepares the static site.