install.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. 'use strict';
  2. const nunjucks = require('nunjucks');
  3. const path = require('path');
  4. const fs = require('fs');
  5. const engine = nunjucks.configure({
  6. autoescape: false,
  7. watch: false,
  8. });
  9. let root;
  10. // support npminstall path
  11. if (__dirname.indexOf('.npminstall') >= 0) {
  12. root = path.join(__dirname, '../../../../..');
  13. } else {
  14. root = path.join(__dirname, '../..');
  15. }
  16. if (process.env.CI_ROOT_FOR_TEST) {
  17. root = process.env.CI_ROOT_FOR_TEST;
  18. }
  19. let pkg;
  20. try {
  21. pkg = require(path.join(root, 'package.json'));
  22. } catch (err) {
  23. console.error('read package.json error: %s', err.message);
  24. console.error('[egg-ci] stop create ci yml');
  25. process.exit(0);
  26. }
  27. const config = Object.assign({
  28. type: 'travis, appveyor, github', // default is travis, appveyor and github
  29. version: '',
  30. npminstall: true,
  31. // auto detect nyc_output/*.json files, please use on travis windows platfrom
  32. nyc: false,
  33. license: false,
  34. }, pkg.ci);
  35. if (!('afterScript' in config)) {
  36. const codecovCMD = config.nyc ? 'codecov --disable=gcov -f .nyc_output/*.json' : 'codecov';
  37. if (config.npminstall) {
  38. config.afterScript = `
  39. after_script:
  40. - npminstall codecov && ${codecovCMD}
  41. `.trim();
  42. } else {
  43. config.afterScript = `
  44. after_script:
  45. - npm i codecov && ${codecovCMD}
  46. `.trim();
  47. }
  48. }
  49. config.types = arrayify(config.type);
  50. config.versions = arrayify(config.version);
  51. if (config.services) config.services = arrayify(config.services);
  52. if (config.versions.length === 0) {
  53. const installNode = pkg.engines && (pkg.engines['install-node'] ||
  54. pkg.engines['install-alinode']);
  55. if (!installNode) {
  56. // default version is LTS
  57. config.versions = [ '8', '10', '12' ];
  58. }
  59. }
  60. const defaultOS = {
  61. travis: '',
  62. 'azure-pipelines': 'linux, windows, macos',
  63. github: 'linux, windows, macos',
  64. };
  65. if (pkg.ci && pkg.ci.os) {
  66. config.os = Object.assign(defaultOS, pkg.ci.os);
  67. } else {
  68. config.os = defaultOS;
  69. }
  70. for (const platfrom in config.os) {
  71. config.os[platfrom] = arrayify(config.os[platfrom]);
  72. }
  73. if (config.os && config.os.travis && config.os.travis.length === 0) {
  74. config.os.travis = null;
  75. }
  76. const originCommand = config.command;
  77. if (typeof originCommand === 'string') {
  78. config.command = {
  79. travis: originCommand,
  80. appveyor: originCommand,
  81. github: originCommand,
  82. 'azure-pipelines': originCommand,
  83. };
  84. }
  85. config.command = Object.assign({
  86. travis: 'ci',
  87. appveyor: 'test',
  88. 'azure-pipelines': 'ci',
  89. github: 'ci',
  90. }, config.command);
  91. let ymlName = '';
  92. let ymlContent = '';
  93. let ymlName2 = '';
  94. let ymlContent2 = '';
  95. for (const type of config.types) {
  96. if (type === 'travis') {
  97. ymlContent = engine.renderString(getTpl('travis'), config);
  98. ymlName = '.travis.yml';
  99. } else if (type === 'appveyor') {
  100. ymlContent = engine.renderString(getTpl('appveyor'), config);
  101. ymlName = 'appveyor.yml';
  102. } else if (type === 'github') {
  103. const os = config.os.github.map(name => {
  104. if (name === 'linux') name = 'ubuntu';
  105. return `${name}-latest`;
  106. });
  107. ymlContent = getTpl('github.yml')
  108. .replace('{{github_node_version}}', config.versions.join(', '))
  109. .replace('{{github_os}}', os.join(', '))
  110. .replace('{{github_command_ci}}', config.command.github)
  111. .replace('{{github_npm_install}}', config.npminstall ? 'npm i -g npminstall@5 && npminstall' : 'npm i');
  112. ymlName = '.github/workflows/nodejs.yml';
  113. let dir = path.join(root, '.github');
  114. if (!fs.existsSync(dir)) fs.mkdirSync(dir);
  115. dir = path.join(root, '.github', 'workflows');
  116. if (!fs.existsSync(dir)) fs.mkdirSync(dir);
  117. } else if (type === 'azure-pipelines') {
  118. ymlContent = engine.renderString(getTpl('azure-pipelines.yml'), config);
  119. ymlName = 'azure-pipelines.yml';
  120. ymlContent2 = engine.renderString(getTpl('azure-pipelines.template.yml'), config);
  121. ymlName2 = 'azure-pipelines.template.yml';
  122. } else {
  123. throw new Error(`${type} type not support`);
  124. }
  125. const ymlPath = path.join(root, ymlName);
  126. fs.writeFileSync(ymlPath, ymlContent);
  127. console.log(`[egg-ci] create ${ymlPath} success`);
  128. if (ymlName2) {
  129. const ymlPath2 = path.join(root, ymlName2);
  130. fs.writeFileSync(ymlPath2, ymlContent2);
  131. console.log(`[egg-ci] create ${ymlPath2} success`);
  132. }
  133. }
  134. if (config.license) {
  135. let data = {
  136. year: '2017',
  137. fullname: 'Alibaba Group Holding Limited and other contributors.',
  138. };
  139. if (typeof config.license === 'object') {
  140. data = Object.assign(data, config.license);
  141. }
  142. if (Number(data.year) < new Date().getFullYear()) {
  143. data.year = `${data.year}-present`;
  144. }
  145. const licenseContent = engine.renderString(getTpl('license'), data);
  146. const licensePath = path.join(root, 'LICENSE');
  147. fs.writeFileSync(licensePath, licenseContent);
  148. console.log(`[egg-ci] create ${licensePath} success`);
  149. }
  150. function getTpl(name) {
  151. return fs.readFileSync(path.join(__dirname, 'templates', name), 'utf8');
  152. }
  153. function arrayify(str) {
  154. if (Array.isArray(str)) return str;
  155. return str.split(/\s*,\s*/).filter(s => !!s);
  156. }