deploy.js (3246B)
1 /** 2 * React Starter Kit (https://www.reactstarterkit.com/) 3 * 4 * Copyright © 2014-present Kriasoft, LLC. All rights reserved. 5 * 6 * This source code is licensed under the MIT license found in the 7 * LICENSE.txt file in the root directory of this source tree. 8 */ 9 10 import path from 'path'; 11 import fetch from 'node-fetch'; 12 import { spawn } from './lib/cp'; 13 import { makeDir, moveDir, cleanDir } from './lib/fs'; 14 import run from './run'; 15 16 // GitHub Pages 17 const remote = { 18 name: 'github', 19 url: 'https://github.com/<user>/<repo>.git', 20 branch: 'gh-pages', 21 website: 'https://<user>.github.io/<repo>/', 22 static: true, 23 }; 24 25 // Heroku 26 // const remote = { 27 // name: 'heroku', 28 // url: 'https://git.heroku.com/<app>.git', 29 // branch: 'master', 30 // website: 'https://<app>.herokuapp.com', 31 // }; 32 33 // Azure Web Apps 34 // const remote = { 35 // name: 'azure', 36 // url: 'https://<user>@<app>.scm.azurewebsites.net:443/<app>.git', 37 // branch: 'master', 38 // website: `http://<app>.azurewebsites.net`, 39 // }; 40 41 const options = { 42 cwd: path.resolve(__dirname, '../build'), 43 stdio: ['ignore', 'inherit', 'inherit'], 44 }; 45 46 /** 47 * Deploy the contents of the `/build` folder to a remote server via Git. 48 */ 49 async function deploy() { 50 // Initialize a new repository 51 await makeDir('build'); 52 await spawn('git', ['init', '--quiet'], options); 53 54 // Changing a remote's URL 55 let isRemoteExists = false; 56 try { 57 await spawn('git', ['config', '--get', `remote.${remote.name}.url`], options); 58 isRemoteExists = true; 59 } catch (error) { 60 /* skip */ 61 } 62 await spawn('git', ['remote', isRemoteExists ? 'set-url' : 'add', remote.name, remote.url], options); 63 64 // Fetch the remote repository if it exists 65 let isRefExists = false; 66 try { 67 await spawn('git', ['ls-remote', '--quiet', '--exit-code', remote.url, remote.branch], options); 68 isRefExists = true; 69 } catch (error) { 70 await spawn('git', ['update-ref', '-d', 'HEAD'], options); 71 } 72 if (isRefExists) { 73 await spawn('git', ['fetch', remote.name], options); 74 await spawn('git', ['reset', `${remote.name}/${remote.branch}`, '--hard'], options); 75 await spawn('git', ['clean', '--force'], options); 76 } 77 78 // Build the project in RELEASE mode which 79 // generates optimized and minimized bundles 80 process.argv.push('--release'); 81 if (remote.static) process.argv.push('--static'); 82 await run(require('./build').default); 83 if (process.argv.includes('--static')) { 84 await cleanDir('build/*', { 85 nosort: true, 86 dot: true, 87 ignore: ['build/.git', 'build/public'], 88 }); 89 await moveDir('build/public', 'build'); 90 } 91 92 // Push the contents of the build folder to the remote server via Git 93 await spawn('git', ['add', '.', '--all'], options); 94 try { 95 await spawn('git', ['diff', '--cached', '--exit-code', '--quiet'], options); 96 } catch (error) { 97 await spawn('git', ['commit', '--message', `Update ${new Date().toISOString()}`], options); 98 } 99 await spawn('git', ['push', remote.name, `master:${remote.branch}`, '--set-upstream'], options); 100 101 // Check if the site was successfully deployed 102 const response = await fetch(remote.website); 103 console.log(`${remote.website} => ${response.status} ${response.statusText}`); 104 } 105 106 export default deploy;