update-docs-branch.js 2.05 KB
Newer Older
vicotor's avatar
vicotor committed
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 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
const proc = require('child_process');
const read = cmd => proc.execSync(cmd, { encoding: 'utf8' }).trim();
const run = cmd => {
  proc.execSync(cmd, { stdio: 'inherit' });
};
const tryRead = cmd => {
  try {
    return read(cmd);
  } catch (e) {
    return undefined;
  }
};

const releaseBranchRegex = /^release-v(?<version>(?<major>\d+)\.(?<minor>\d+)(?:\.(?<patch>\d+))?)$/;

const currentBranch = read('git rev-parse --abbrev-ref HEAD');
const match = currentBranch.match(releaseBranchRegex);

if (!match) {
  console.error('Not currently on a release branch');
  process.exit(1);
}

const pkgVersion = require('../package.json').version;

if (pkgVersion.includes('-') && !pkgVersion.includes('.0.0-')) {
  console.error('Refusing to update docs: non-major prerelease detected');
  process.exit(0);
}

const current = match.groups;
const docsBranch = `docs-v${current.major}.x`;

// Fetch remotes and find the docs branch if it exists
run('git fetch --all --no-tags');
const matchingDocsBranches = tryRead(`git rev-parse --glob='*/${docsBranch}'`);

if (!matchingDocsBranches) {
  // Create the branch
  run(`git checkout --orphan ${docsBranch}`);
} else {
  const [publishedRef, ...others] = new Set(matchingDocsBranches.split('\n'));
  if (others.length > 0) {
    console.error(
      `Found conflicting ${docsBranch} branches.\n` +
        'Either local branch is outdated or there are multiple matching remote branches.',
    );
    process.exit(1);
  }
  const publishedVersion = JSON.parse(read(`git show ${publishedRef}:package.json`)).version;
  const publishedMinor = publishedVersion.match(/\d+\.(?<minor>\d+)\.\d+/).groups.minor;
  if (current.minor < publishedMinor) {
    console.error('Refusing to update docs: newer version is published');
    process.exit(0);
  }

  run('git checkout --quiet --detach');
  run(`git reset --soft ${publishedRef}`);
  run(`git checkout ${docsBranch}`);
}

run('npm run prepare-docs');
run('git add -f docs'); // --force needed because generated docs files are gitignored
run('git commit -m "Update docs"');
run(`git checkout ${currentBranch}`);