diff --git a/lib/grunt/utils.js b/lib/grunt/utils.js index 7b772c34f520..24788bff8260 100644 --- a/lib/grunt/utils.js +++ b/lib/grunt/utils.js @@ -2,6 +2,7 @@ var fs = require('fs'); var shell = require('shelljs'); var grunt = require('grunt'); var spawn = require('child_process').spawn; +var semver = require('semver'); var version; var CSP_CSS_HEADER = '/* Include this file in your html if you are using the CSP mode. */\n\n'; @@ -32,31 +33,82 @@ module.exports = { getVersion: function(){ if (version) return version; - var package = JSON.parse(fs.readFileSync('package.json', 'UTF-8')); - var match = package.version.match(/^([^\-]*)(?:\-(.+))?$/); - var semver = match[1].split('.'); + try { + + var gitTag = getTagOfCurrentCommit(); + var semVerVersion, codeName, fullVersion; + if (gitTag) { + // tagged release + fullVersion = semVerVersion = semver.valid(gitTag); + codeName = getTaggedReleaseCodeName(gitTag); + } else { + // snapshot release + semVerVersion = getSnapshotVersion(); + fullVersion = semVerVersion + '-' + getSnapshotSuffix(); + codeName = 'snapshot' + } + + var versionParts = semVerVersion.match(/(\d+)\.(\d+)\.(\d+)/); + + version = { + full: fullVersion, + major: versionParts[1], + minor: versionParts[2], + dot: versionParts[3], + codename: codeName, + cdn: package.cdnVersion + }; - var fullVersion = match[1]; + return version; - if (match[2]) { - fullVersion += '-'; - fullVersion += (match[2] == 'snapshot') ? getSnapshotSuffix() : match[2]; + } catch (e) { + grunt.fail.warn(e); } - version = { - full: fullVersion, - major: semver[0], - minor: semver[1], - dot: semver[2].replace(/rc\d+/, ''), - codename: package.codename, - cdn: package.cdnVersion - }; + function getTagOfCurrentCommit() { + var gitTagResult = shell.exec('git describe --exact-match', {silent:true}); + var gitTagOutput = gitTagResult.output.trim(); + var branchVersionPattern = new RegExp(package.branchVersion.replace('.', '\\.').replace('*', '\\d+')); + if (gitTagResult.code === 0 && gitTagOutput.match(branchVersionPattern)) { + return gitTagOutput; + } else { + return null; + } + } - return version; + function getTaggedReleaseCodeName(tagName) { + var tagMessage = shell.exec('git cat-file -p '+ tagName +' | grep "codename"', {silent:true}).output; + var codeName = tagMessage && tagMessage.match(/codename\((.*)\)/)[1]; + if (!codeName) { + throw new Error("Could not extract release code name. The message of tag "+tagName+ + " must match '*codename(some release name)*'"); + } + return codeName; + } + + function getSnapshotVersion() { + var oldTags = shell.exec('git tag -l v'+package.branchVersion, {silent:true}).output.trim().split('\n'); + // ignore non semver versions. + oldTags = oldTags.filter(function(version) { + return version && semver.valid(version); + }); + if (oldTags.length) { + oldTags.sort(semver.compare); + semVerVersion = oldTags[oldTags.length-1]; + if (semVerVersion.indexOf('-') !== -1) { + semVerVersion = semver.inc(semVerVersion, 'prerelease'); + } else { + semVerVersion = semver.inc(semVerVersion, 'patch'); + } + } else { + semVerVersion = semver.valid(package.branchVersion.replace(/\*/g, '0')); + } + return semVerVersion; + } function getSnapshotSuffix() { - var jenkinsBuild = process.env.BUILD_NUMBER || 'local'; + var jenkinsBuild = process.env.TRAVIS_BUILD_NUMBER || process.env.BUILD_NUMBER || 'local'; var hash = shell.exec('git rev-parse --short HEAD', {silent: true}).output.replace('\n', ''); return 'build.'+jenkinsBuild+'+sha.'+hash; } diff --git a/package.json b/package.json index 56eb00a478b8..e7283aa8708f 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,7 @@ { "name": "angularjs", - "version": "1.2.12-snapshot", + "branchVersion": "1.2.*", "cdnVersion": "1.2.11", - "codename": "cauliflower-eradication", "repository": { "type": "git", "url": "https://github.com/angular/angular.js.git" diff --git a/scripts/angular.js/finalize-version.sh b/scripts/angular.js/finalize-version.sh deleted file mode 100755 index e885fd1465e6..000000000000 --- a/scripts/angular.js/finalize-version.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash - -echo "############################################" -echo "## Remove "-snapshot" from version ########" -echo "############################################" - -ARG_DEFS=() - -function run { - cd ../.. - - replaceJsonProp "package.json" "version" "(.*)-snapshot" "\2" - VERSION=$(readJsonProp "package.json" "version") - - git add package.json - git commit -m "chore(release): cut v$VERSION release" - git tag -m "v$VERSION" v$VERSION -} - -source $(dirname $0)/../utils.inc diff --git a/scripts/angular.js/initialize-new-version.sh b/scripts/angular.js/initialize-new-version.sh deleted file mode 100755 index 9d0605554f8c..000000000000 --- a/scripts/angular.js/initialize-new-version.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/bash - -echo "############################################" -echo "## Increment version, add "-snapshot" and set version name ##" -echo "############################################" - -ARG_DEFS=( - "--next-version-type=(patch|minor|major)" - "--next-version-name=(.+)" -) - -function run { - cd ../.. - - grunt bump:$NEXT_VERSION_TYPE - NEXT_VERSION=$(readJsonProp "package.json" "version") - replaceJsonProp "package.json" "version" "(.*)" "\2-snapshot" - replaceJsonProp "package.json" "codename" ".*" "$NEXT_VERSION_NAME" - - git add package.json - git commit -m "chore(release): start v$NEXT_VERSION ($NEXT_VERSION)" -} - -source $(dirname $0)/../utils.inc diff --git a/scripts/angular.js/publish.sh b/scripts/angular.js/publish.sh deleted file mode 100755 index 8de5b11b27f5..000000000000 --- a/scripts/angular.js/publish.sh +++ /dev/null @@ -1,42 +0,0 @@ -#!/bin/bash - -# Script for updating angular.js repo from current local build. - -echo "#################################" -echo "## Update angular.js ###" -echo "#################################" - -ARG_DEFS=( - "--action=(prepare|publish)" - "--next-version-type=(patch|minor|major)" - "--next-version-name=(.+)" - "[--no-test=(true|false)]" -) - -function init { - cd ../.. -} - -function prepare() { - ./scripts/angular.js/finalize-version.sh - - # Build - if [[ $NO_TEST == "true" ]]; then - npm install --color false - grunt ci-checks package --no-color - else - ./jenkins_build.sh - fi - - ./scripts/angular.js/initialize-new-version.sh --next-version-type=$NEXT_VERSION_TYPE --next-version-name=$NEXT_VERSION_NAME -} - -function publish() { - BRANCH=$(git rev-parse --abbrev-ref HEAD) - # push the commits to github - git push origin $BRANCH - # push the release tag - git push origin v`cat build/version.txt` -} - -source $(dirname $0)/../utils.inc diff --git a/scripts/angular.js/tag-release.sh b/scripts/angular.js/tag-release.sh new file mode 100755 index 000000000000..fbb6e2defb07 --- /dev/null +++ b/scripts/angular.js/tag-release.sh @@ -0,0 +1,42 @@ +#!/bin/bash + +# Tags a release +# so that travis can do the actual release. + +echo "#################################" +echo "## Tag angular.js for a release #" +echo "#################################" + +ARG_DEFS=( + "--action=(prepare|publish)" + "--commit-sha=(.*)" + # the version number of the release. + # e.g. 1.2.12 or 1.2.12-rc.1 + "--version-number=([0-9]+\.[0-9]+\.[0-9]+(-[a-z]+\.[0-9]+)?)" + "--version-name=(.+)" +) + +function checkVersionNumber() { + BRANCH_PATTERN=$(readJsonProp "package.json" "branchVersion") + if [[ $VERSION_NUMBER != $BRANCH_PATTERN ]]; then + echo "version-number needs to match $BRANCH_PATTERN on this branch" + usage + fi +} + +function init { + cd ../.. + checkVersionNumber + TAG_NAME="v$VERSION_NUMBER" +} + +function prepare() { + git tag "$TAG_NAME" -m "chore(release): $TAG_NAME codename($VERSION_NAME)" "$COMMIT_SHA" +} + +function publish() { + # push the tag to github + git push origin $TAG_NAME +} + +source $(dirname $0)/../utils.inc diff --git a/scripts/jenkins/release.sh b/scripts/jenkins/release.sh index 744a1a288bf5..8c1e46bc09b0 100755 --- a/scripts/jenkins/release.sh +++ b/scripts/jenkins/release.sh @@ -1,38 +1,63 @@ #!/bin/bash +# tags the current commit as a release and publishes all artifacts to +# the different repositories. +# Note: This will also works if the commit is in the past! + echo "#################################" -echo "#### Cut release ################" +echo "#### cut release ############" echo "#################################" ARG_DEFS=( - "--next-version-type=(patch|minor|major)" - "--next-version-name=(.+)" # require the git dryrun flag so the script can't be run without # thinking about this! "--git-push-dryrun=(true|false)" - "[--no-test=(true|false)]" + # The sha to release. Needs to be the same as HEAD. + # given as parameter to double check. + "--commit-sha=(.*)" + # the version number of the release. + # e.g. 1.2.12 or 1.2.12-rc.1 + "--version-number=([0-9]+\.[0-9]+\.[0-9]+(-[a-z]+\.[0-9]+)?)" + # the codename of the release + "--version-name=(.+)" ) function init { - NG_ARGS=("$@") + if [[ $(git rev-parse --short HEAD) != $COMMIT_SHA ]]; then + echo "HEAD is not at $COMMIT_SHA" + usage + fi + if [[ ! $VERBOSE ]]; then VERBOSE=false fi - if [[ ! $NO_TEST ]]; then - NO_TEST=false - fi VERBOSE_ARG="--verbose=$VERBOSE" - NO_TEST_ARG="--no_test=$NO_TEST" +} + +function build { + cd ../.. + + npm install --color false + grunt ci-checks package --no-color + + cd $SCRIPT_DIR } function phase { ACTION_ARG="--action=$1" - ../angular.js/publish.sh $ACTION_ARG $VERBOSE_ARG $NO_TEST_ARG \ - --next-version-type=$NEXT_VERSION_TYPE --next-version-name=$NEXT_VERSION_NAME + ../angular.js/tag-release.sh $ACTION_ARG $VERBOSE_ARG\ + --version-number=$VERSION_NUMBER --version-name=$VERSION_NAME\ + --commit-sha=$COMMIT_SHA + + if [[ $1 == "prepare" ]]; then + # The build requires the tag to be set already! + build + fi + ../code.angularjs.org/publish.sh $ACTION_ARG $VERBOSE_ARG ../bower/publish.sh $ACTION_ARG $VERBOSE_ARG - ../angular-seed/publish.sh $ACTION_ARG $VERBOSE_ARG $NO_TEST_ARG - ../angular-phonecat/publish.sh $ACTION_ARG $VERBOSE_ARG $NO_TEST_ARG + ../angular-seed/publish.sh $ACTION_ARG $VERBOSE_ARG --no-test=true + ../angular-phonecat/publish.sh $ACTION_ARG $VERBOSE_ARG --no-test=true } function run {