mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
build: prevent publishing from the wrong branch (#12831)
* Patch releases should be published from patch publish branches with the format: `{}.{}.x`
* Minor releases should be published from minor publish branches with the format: `{}.x`
* Major releases should be published from the `master` branch.
Closes #12655
This commit is contained in:
committed by
Jeremy Elbourn
parent
29d517361e
commit
e5e5b68a93
@@ -28,7 +28,8 @@ import './tasks/example-module';
|
||||
import './tasks/lint';
|
||||
import './tasks/material-release';
|
||||
import './tasks/payload';
|
||||
import './tasks/publish';
|
||||
import './tasks/unit-test';
|
||||
import './tasks/universal';
|
||||
import './tasks/validate-release';
|
||||
|
||||
import './tasks/publish/publish-task';
|
||||
import './tasks/publish/validate-release';
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
import {bold} from 'chalk';
|
||||
import {spawnSync} from 'child_process';
|
||||
import {buildConfig} from 'material2-build-tools';
|
||||
|
||||
/** Regular expression that matches version names and the individual version segments. */
|
||||
export const versionNameRegex = /^(\d+)\.(\d+)\.(\d+)(?:-(alpha|beta|rc)\.(\d)+)?/;
|
||||
|
||||
/** Regular expression that matches publish branch names and their Semver digits. */
|
||||
const publishBranchNameRegex = /^([0-9]+)\.([x0-9]+)(?:\.([x0-9]+))?$/;
|
||||
|
||||
/** Checks if the specified version can be released from the current Git branch. */
|
||||
export function checkPublishBranch(version: string) {
|
||||
const versionType = getSemverVersionType(version);
|
||||
const branchName = spawnSync('git', ['symbolic-ref', '--short', 'HEAD'],
|
||||
{cwd: buildConfig.projectDir}).stdout.toString().trim();
|
||||
|
||||
if (branchName === 'master') {
|
||||
if (versionType === 'major') {
|
||||
return;
|
||||
}
|
||||
|
||||
throw `Publishing of "${versionType}" releases should not happen inside of the ` +
|
||||
`${bold('master')} branch.`;
|
||||
}
|
||||
|
||||
const branchNameMatch = branchName.match(publishBranchNameRegex) || [];
|
||||
const branchDigits = branchNameMatch.slice(1, 4);
|
||||
|
||||
if (branchDigits[2] === 'x' && versionType !== 'patch') {
|
||||
throw `Cannot publish a "${versionType}" release inside of a patch branch (${branchName})`;
|
||||
}
|
||||
|
||||
if (branchDigits[1] === 'x' && versionType !== 'minor') {
|
||||
throw `Cannot publish a "${versionType}" release inside of a minor branch (${branchName})`;
|
||||
}
|
||||
|
||||
throw `Cannot publish a "${versionType}" release from branch: "${branchName}". Releases should `
|
||||
+ `be published from "master" or the according publish branch (e.g. "6.x", "6.4.x")`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the type of the specified semver version. Can be either a major, minor or
|
||||
* patch version.
|
||||
*/
|
||||
export function getSemverVersionType(version: string): 'major' | 'minor' | 'patch' {
|
||||
const versionNameMatch = version.match(versionNameRegex);
|
||||
|
||||
if (!versionNameMatch) {
|
||||
throw `Could not parse version: ${version}. Cannot properly determine version type.`;
|
||||
}
|
||||
|
||||
const versionDigits = versionNameMatch.slice(1, 4);
|
||||
|
||||
if (versionDigits[1] === '0' && versionDigits[2] === '0') {
|
||||
return 'major';
|
||||
} else if (versionDigits[2] === '0') {
|
||||
return 'minor';
|
||||
} else {
|
||||
return 'patch';
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,12 @@
|
||||
import {green, grey, red, yellow} from 'chalk';
|
||||
import {spawn} from 'child_process';
|
||||
import {existsSync, statSync} from 'fs-extra';
|
||||
import {join} from 'path';
|
||||
import {task} from 'gulp';
|
||||
import {execTask} from '../util/task_helpers';
|
||||
import {buildConfig, sequenceTask} from 'material2-build-tools';
|
||||
import {yellow, green, red, grey} from 'chalk';
|
||||
import * as minimist from 'minimist';
|
||||
import {join} from 'path';
|
||||
import {execTask} from '../../util/task_helpers';
|
||||
import {checkPublishBranch, versionNameRegex} from './branch-check';
|
||||
|
||||
/** Packages that will be published to NPM by the release task. */
|
||||
export const releasePackages = [
|
||||
@@ -16,9 +17,6 @@ export const releasePackages = [
|
||||
'material-moment-adapter'
|
||||
];
|
||||
|
||||
/** Regular Expression that matches valid version numbers of Angular Material. */
|
||||
export const validVersionRegex = /^\d+\.\d+\.\d+(-(alpha|beta|rc)\.\d+)?$/;
|
||||
|
||||
/** Parse command-line arguments for release task. */
|
||||
const argv = minimist(process.argv.slice(3));
|
||||
|
||||
@@ -50,38 +48,39 @@ task(':publish', async () => {
|
||||
const version = buildConfig.projectVersion;
|
||||
const currentDir = process.cwd();
|
||||
|
||||
if (!version.match(validVersionRegex)) {
|
||||
console.log(red(`Error: Cannot publish due to an invalid version name. Version "${version}" ` +
|
||||
`is not following our semver format.`));
|
||||
console.log(yellow(`A version should follow this format: X.X.X, X.X.X-beta.X, X.X.X-alpha.X, ` +
|
||||
`X.X.X-rc.X`));
|
||||
if (!version.match(versionNameRegex)) {
|
||||
console.error(red(`Error: Cannot publish due to an invalid version name. Version ` +
|
||||
`"${version}" is not following our semver format.`));
|
||||
console.error(yellow(`A version should follow this format: X.X.X, X.X.X-beta.X, ` +
|
||||
`X.X.X-alpha.X, X.X.X-rc.X`));
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('');
|
||||
console.log();
|
||||
if (!tag) {
|
||||
console.log(grey('> You can specify the tag by passing --tag=labelName.\n'));
|
||||
console.log(green(`Publishing version "${version}" to the latest tag...`));
|
||||
} else {
|
||||
console.log(yellow(`Publishing version "${version}" to the ${tag} tag...`));
|
||||
}
|
||||
console.log('');
|
||||
|
||||
console.log();
|
||||
|
||||
if (version.match(/(alpha|beta|rc)/) && (!tag || tag === 'latest')) {
|
||||
console.log(red(`Publishing ${version} to the "latest" tag is not allowed.`));
|
||||
console.log(red(`Alpha, Beta or RC versions shouldn't be published to "latest".`));
|
||||
console.log();
|
||||
console.error(red(`Publishing ${version} to the "latest" tag is not allowed.`));
|
||||
console.error(red(`Alpha, Beta or RC versions shouldn't be published to "latest".`));
|
||||
console.error();
|
||||
return;
|
||||
}
|
||||
|
||||
if (releasePackages.length > 1) {
|
||||
console.warn(red('Warning: Multiple packages will be released if proceeding.'));
|
||||
console.warn(red('Warning: Packages to be released:', releasePackages.join(', ')));
|
||||
console.log();
|
||||
console.warn(yellow('Warning: Multiple packages will be released.'));
|
||||
console.warn(yellow('Warning: Packages to be released:', releasePackages.join(', ')));
|
||||
console.warn();
|
||||
}
|
||||
|
||||
console.log(yellow('> Make sure to check the "angularVersion" in the build config.'));
|
||||
checkPublishBranch(version);
|
||||
|
||||
console.log(yellow('> Make sure to check the "requiredAngularVersion" in the package.json.'));
|
||||
console.log(yellow('> The version in the config defines the peer dependency of Angular.'));
|
||||
console.log();
|
||||
|
||||
@@ -2,7 +2,7 @@ import {task} from 'gulp';
|
||||
import {readFileSync, existsSync} from 'fs';
|
||||
import {join} from 'path';
|
||||
import {green, red} from 'chalk';
|
||||
import {releasePackages} from './publish';
|
||||
import {releasePackages} from './publish-task';
|
||||
import {sync as glob} from 'glob';
|
||||
import {spawnSync} from 'child_process';
|
||||
import {buildConfig, sequenceTask} from 'material2-build-tools';
|
||||
@@ -10,7 +10,7 @@ import {buildConfig, sequenceTask} from 'material2-build-tools';
|
||||
const {projectDir, projectVersion, outputDir} = buildConfig;
|
||||
|
||||
/** Git repository URL that has been read out from the project package.json file. */
|
||||
const repositoryGitUrl = require('../../../package.json').repository.url;
|
||||
const repositoryGitUrl = require('../../../../package.json').repository.url;
|
||||
|
||||
/** Path to the directory where all releases are created. */
|
||||
const releasesDir = join(outputDir, 'releases');
|
||||
Reference in New Issue
Block a user