after-version-bump.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. #!/usr/bin/env node
  2. /* eslint-disable import/no-dynamic-require */
  3. /* eslint-disable global-require */
  4. // Called by the `version` npm script.
  5. // This is run _after_ lerna updates the version numbers,
  6. // but _before_ it commits, so we have time to update the
  7. // version numbers throughout the repo and add it to the
  8. // release commit.
  9. // After updating version numbers, this runs a full
  10. // IS_RELEASE_BUILD=1 build, so that the version numbers
  11. // are properly embedded in the JS bundles.
  12. // NOTE this _amends_ the previous commit, which should
  13. // already be a "Release" commit generated by bin/release.
  14. const lastCommitMessage = require('last-commit-message')
  15. const { spawn } = require('child_process')
  16. const { readFile, writeFile } = require('fs/promises')
  17. const once = require('events.once')
  18. const globby = require('globby')
  19. async function replaceInFile (filename, replacements) {
  20. let content = await readFile(filename, 'utf8')
  21. for (const [rx, replacement] of replacements) {
  22. content = content.replace(rx, replacement)
  23. }
  24. await writeFile(filename, content, 'utf8')
  25. }
  26. async function updateVersions (files, packageName) {
  27. const { version } = require(`../packages/${packageName}/package.json`)
  28. // uppy → uppy
  29. // @uppy/robodog → uppy/robodog
  30. const urlPart = packageName === 'uppy' ? packageName : packageName.slice(1)
  31. const replacements = new Map([
  32. [RegExp(`${urlPart}/v\\d+\\.\\d+\\.\\d+\\/`, 'g'), `${urlPart}/v${version}/`],
  33. // maybe more later
  34. ])
  35. console.log('replacing', replacements, 'in', files.length, 'files')
  36. for (const f of files) {
  37. // eslint-disable-next-line no-await-in-loop
  38. await replaceInFile(f, replacements)
  39. }
  40. }
  41. async function gitAdd (files) {
  42. const git = spawn('git', ['add', ...files], { stdio: 'inherit' })
  43. const [exitCode] = await once(git, 'exit')
  44. if (exitCode !== 0) {
  45. throw new Error(`git add failed with ${exitCode}`)
  46. }
  47. }
  48. // Run the build as a release build (that inlines version numbers etc.)
  49. async function npmRunBuild () {
  50. const npmRun = spawn('yarn', ['run', 'build'], {
  51. stdio: 'inherit',
  52. env: {
  53. ...process.env,
  54. FRESH: true, // force rebuild everything
  55. IS_RELEASE_BUILD: true,
  56. },
  57. })
  58. const [exitCode] = await once(npmRun, 'exit')
  59. if (exitCode !== 0) {
  60. throw new Error(`yarn run build failed with ${exitCode}`)
  61. }
  62. }
  63. async function main () {
  64. if (process.env.ENDTOEND === '1') {
  65. console.log('Publishing for e2e tests, skipping version number sync.')
  66. process.exit(0)
  67. }
  68. const message = await lastCommitMessage()
  69. if (!message.trim().includes('Release')) {
  70. console.error(`Last commit is not a release commit, but '${message}'`)
  71. process.exit(1)
  72. }
  73. const files = await globby([
  74. 'README.md',
  75. 'BUNDLE-README.md',
  76. 'examples/**/*.html',
  77. 'packages/*/README.md',
  78. 'packages/@uppy/*/README.md',
  79. 'website/src/docs/**',
  80. 'website/src/examples/**',
  81. 'website/themes/uppy/layout/**',
  82. '!**/node_modules/**',
  83. ])
  84. await updateVersions(files, 'uppy')
  85. await updateVersions(files, '@uppy/robodog')
  86. await updateVersions(files, '@uppy/locales')
  87. // gitignored files were updated for the npm package, but can't be updated
  88. // on git.
  89. const isIgnored = await globby.gitignore()
  90. await gitAdd(files.filter((filename) => !isIgnored(filename)))
  91. await npmRunBuild()
  92. }
  93. main().catch((err) => {
  94. console.error(err.stack)
  95. process.exit(1)
  96. })