git-release 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
@@ -0,0 +1,8 @@
1
+
2
+ before_script:
3
+ - git config --global user.email "testing-git-release@example.com"
4
+ - git config --global user.name "Testing git-release git user"
5
+
6
+ script:
7
+ - echo $(bash --version)
8
+ - test/bin/run_all
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in git-release.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Tom Meier
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,150 @@
1
+ # Git-Release (BETA - work in progress)
2
+
3
+ Bash only (language agnostic) git release script for tagging and bagging a release candidate with changelog text generation
4
+
5
+ [![Build Status](https://travis-ci.org/tommeier/git-release.png)](https://travis-ci.org/tommeier/git-release)
6
+
7
+ This project performs two simple tasks:
8
+
9
+ * Generate a changelog based on git commits and tag with a custom tag prefix
10
+ * Generate a changelog based on git commits at deploy time and tag with a custom deploy tag prefix
11
+
12
+ Everything is configurable via command line parameters. Run with help command (`-h`) to list all possible configurations.
13
+
14
+ ## Dependencies
15
+
16
+ * Git
17
+ * Bash (Mac OSX / *nix )
18
+ * Grep
19
+
20
+ ## Installation
21
+
22
+ This is the base language agnostic script. Git clone this repo somewhere on your system and ensure the `git-release` and `git-release-deployed` bin files are accessible in the PATH.
23
+
24
+ ## Looking for?
25
+
26
+ Additional implementations using this base script to wrap functionality and share across languages:
27
+
28
+ * Ruby (coming soon)
29
+ * Python (coming soon)
30
+ * Node NPM (coming soon)
31
+
32
+ ## Example flow
33
+
34
+ The usage flow for this app is as follows:
35
+
36
+ * Run `git-release` at the end of a release cycle defining whether it is a major, minor or patch release. This generates a `CHANGELOG` in the root of the projet, and a `VERSION` file with content. If you've released before, this will find the last release and generate changelog and version number accordingly. A tag will be generated for this release with the generated changelog.
37
+
38
+ * During the deploy of this release tag, run `git-release-deployed` on successful deployment. This will generate a new changelog, compared to the last deploy. The reason for this is simple. You may create many releases, but only some versions hit different environments. For example, you create release 0.0.1, deploy to staging, fix many issues, then deploy to production with all the additional fixes. The changelog for staging, for each release, is very different to that of production with all the changes grouped together.
39
+
40
+ ## Version file
41
+
42
+ This file simple contains the raw version number (e.g. `1.4.21`). Useful for parsing in a deployed app to display the current version number. In some applications I use this to provide a `meta` tag with the version information.
43
+
44
+ ## Changelog file
45
+
46
+ Generation is based on all git commits between a start and end point ordered by recency. With nothing provided, by default, the scripts will work out the last commit for a tag prefix, or last deploy and generate up to HEAD.
47
+
48
+ Developers that follow feature branches can pass an optional parameter to generate the changelog only on the pull requests merged in (the 'epics') providing a much cleaner list of content.
49
+
50
+ Tagged content of the changelog is limited at the moment, I'm looking at ways to make this dynamic. But right now, any commit with the following prefixes (ignoring spaces and case) will group the commits in the `CHANGELOG` and present under ordered headings:
51
+
52
+ * `[feature]`
53
+ * `[security]`
54
+ * `[bug]`
55
+
56
+ ## Deploy
57
+
58
+ After a deploy running `git-release-deployed` with the release tag passed in provides the ability to generate the changelog based only on the last deploy. With a custom deploy prefix, for example `deployed/staging` you can scope the changelog to a given environment.
59
+
60
+ ## Full examples
61
+
62
+ ### Git-Release
63
+
64
+ Release with defaults (first time):
65
+ ```
66
+ $> git-release -v 'minor'
67
+ ```
68
+ Generates:
69
+ * version file: `0.1.0`
70
+ * tag : `release/v0.1.0`
71
+ * Changelog : all commits text up until now
72
+
73
+ ---
74
+
75
+ Release with defaults (second time):
76
+ ```
77
+ $> git-release -v 'major'
78
+ ```
79
+ Generates:
80
+ * version file: `1.1.0`
81
+ * tag : `release/v1.1.0`
82
+ * Changelog : all commits between last release and this one
83
+
84
+ ---
85
+
86
+ Release with only pull requests for changelog generation:
87
+ ```
88
+ $> git-release -v 'major' -P
89
+ ```
90
+ Generates:
91
+ * version file: `1.1.0`
92
+ * tag : `release/v1.1.0`
93
+ * Changelog : all merged pull requests and the body text of the merge commit
94
+
95
+ (TODO: git-release-deployed info)
96
+
97
+ ## Contributing
98
+
99
+ All fork + pull requests welcome!
100
+
101
+ 1. Fork it
102
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
103
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
104
+ 4. Push to the branch (`git push origin my-new-feature`)
105
+ 5. Ensure all tests still run
106
+ 6. Create new Pull Request
107
+
108
+ To run the tests locally:
109
+
110
+ ```Bash
111
+
112
+ $> test/bin/run_all
113
+
114
+ ```
115
+
116
+ ## TODO
117
+
118
+ - [ ] Merge capture and help text into language agnostic file, so ruby can load in ruby and return loaded ENV variables
119
+ - [ ] Create remaining TODO items as issues in Github
120
+ - [ ] Test mode should display processes it would run (--dry-run option)
121
+ - [ ] Change output of script to hide most output (unless dry run activated)
122
+ - [ ] Create Ruby gem branch and release as a gem. Use better OPTPARSER to use more human readable variables to pass to - der lying script
123
+ - [ ] Create Node NPM branch and release as an NPM.
124
+ - [ ] Create Python PIP branch and release as a PIP.
125
+ - [ ] Test on variety of systems and servers
126
+ - [ ] [potentially] Fix issue in tests where the time can very rarely cross over a second boundary (make specs ignore seconds difference)
127
+ - [ ] [potentially] Change git-release to work out prefix if given a start or an end point and no prefix
128
+ - [ ] [potentially] Make test helpers for generating the content (changing the style now will break a lot of tests)
129
+ - [ ] [potentially] Make CHANGELOG tagging dynamic (search for initial square brackets), with features + bugs on top of listing
130
+ - [ ] [potentially] Make CHANGELOG generation read in optional template, with wildcards to apply logic to view
131
+ - [ ] [potentially] Work out how to test git push being fired, mocking a git command
132
+ - [ ] [potentially] Use an left pad command to align help text correctly
133
+ - [*] Add full examples to Readme
134
+ - [*] Optionally force push of tags, otherwise ask for confirmation to send
135
+ - [*] Remove the 'skip execute' code
136
+ - [*] Create language maps (bash first, to make ruby only etc) for argument naming. Use everywhere in specs
137
+ - [*] Make test helpers for setting argument mapping (for easily changing in other wrappers)
138
+ - [*] Review argument naming and choose better letters
139
+ - [*] Remove unnessary $(output)= statements in tests
140
+ - [*] Update git-release to remove the division of release and version prefix, make just one prefix (simpler)
141
+ - [*] Write success cases for git-release-deployed script
142
+ - [*] Split up functions and specs into more logical divisions (changelog, git) rather than one large support file
143
+ - [*] Remove *.sh filenames and rely on shebangs on each executable file. Support files keep for editors to use.
144
+ - [*] Split into seperate github repo with migrated history
145
+ - [*] Load Travis-CI
146
+
147
+
148
+
149
+
150
+
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,135 @@
1
+ #!/bin/bash -e
2
+ set -e
3
+
4
+ ############################################################
5
+ ##### Git-Release #####
6
+ ### Pure bash script for handling git release versioning ###
7
+ ############################################################
8
+
9
+
10
+ ############################################################
11
+ ##### DEFAULTS #####
12
+ ############################################################
13
+
14
+ RELEASE_PREFIX='release/v'
15
+ CHANGELOG_FILE='CHANGELOG'
16
+ VERSION_FILE='VERSION'
17
+ CHANGELOG_SCOPE=':all_commits'
18
+ CHANGELOG_STRATEGY=':overwrite'
19
+
20
+ START_POINT=''
21
+ END_POINT=''
22
+
23
+ #Supporting functions
24
+ . "${BASH_SOURCE[0]%/*}/../support/support-functions.sh"
25
+
26
+ USAGE_OUTPUT="
27
+ usage : $(basename "$0") $(arg_for $ARG_VERSION '<version>') [$(arg_for $ARG_RELEASE_PREFIX '<prefix>')] [$(arg_for $ARG_START '<start>')] [$(arg_for $ARG_FINISH '<finish>')]
28
+ [$(arg_for $ARG_APPEND)] [$(arg_for $ARG_FORCE)] [$(arg_for $ARG_PULL_REQUESTS)] [$(arg_for $ARG_CHANGELOG '<changelog_file>')] [$(arg_for $ARG_VERSION_FILE '<version_file>')]
29
+ [$(arg_for $ARG_HELP_TEXT)]
30
+ --- create git release tag with changelog
31
+
32
+ options:
33
+ required:
34
+ $(arg_for $ARG_VERSION '<version>') set the software versioning type (major or minor or patch)
35
+ optional:
36
+ [$(arg_for $ARG_RELEASE_PREFIX '<prefix>')] set the release prefix (default: '${RELEASE_PREFIX}')
37
+ [$(arg_for $ARG_FORCE)] force push of new tags (default: commit changes but do not push)
38
+ changelog:
39
+ [$(arg_for $ARG_START '<start>')] set the start point (default: the last tag name that matches the prefix)
40
+ [$(arg_for $ARG_FINISH '<finish>')] set the end/finish point (default: HEAD)
41
+ [$(arg_for $ARG_APPEND)] append to changelog (default: ${CHANGELOG_STRATEGY})
42
+ [$(arg_for $ARG_PULL_REQUESTS)] set to only pull requests (default: ${CHANGELOG_SCOPE})
43
+ [$(arg_for $ARG_CHANGELOG '<changelog_file>')] set the changelog filename (default: ${CHANGELOG_FILE})
44
+ [$(arg_for $ARG_VERSION_FILE '<version_file>')] set the version file name (default: ${VERSION_FILE})
45
+ general:
46
+ $(arg_for $ARG_HELP_TEXT) show this help text
47
+
48
+
49
+ usage examples:
50
+
51
+ 1) Basic usage with defaults
52
+ Given the last release was at 1.0.4, with a tag of 'our-releases/REL1.0.4' :
53
+
54
+ $(basename "$0") $(arg_for $ARG_VERSION 'minor') $(arg_for $ARG_RELEASE_PREFIX 'our-releases/REL-')
55
+
56
+ Tag generated : our-releases/REL1.1.4
57
+ Version file contains : 1.1.4
58
+ CHANGELOG file contains : commit information for all commits between last release and HEAD
59
+
60
+ 2) Pull requests only (changelog generated only with body of pull request titles)
61
+
62
+ $(basename "$0") $(arg_for $ARG_VERSION 'minor') $(arg_for $ARG_PULL_REQUESTS)
63
+
64
+ 3) Generate custom changelog and version file
65
+
66
+ $(basename "$0") $(arg_for $ARG_VERSION 'minor') $(arg_for $ARG_CHANGELOG 'MYCHANGELOGFILE') $(arg_for $ARG_VERSION_FILE 'MYVERSIONFILE')
67
+
68
+ "
69
+
70
+ ############################################################
71
+ ##### INPUT CAPTURE #####
72
+ ############################################################
73
+
74
+ while getopts "$ARG_FORCE""$ARG_HELP_TEXT""$ARG_APPEND""$ARG_PULL_REQUESTS""$ARG_VERSION":"$ARG_START":"$ARG_FINISH":"$ARG_RELEASE_PREFIX":"$ARG_CHANGELOG":"$ARG_VERSION_FILE": option
75
+ do
76
+ case "${option}"
77
+ in
78
+ $ARG_HELP_TEXT)
79
+ echo "$USAGE_OUTPUT" >&2
80
+ exit 0
81
+ ;;
82
+ $ARG_PULL_REQUESTS) CHANGELOG_SCOPE=":pulls_only";;
83
+ $ARG_APPEND) CHANGELOG_STRATEGY=":append";;
84
+ $ARG_FORCE) FORCE_PUSH='true';;
85
+ $ARG_VERSION) VERSION_TYPE="$OPTARG";;
86
+ $ARG_RELEASE_PREFIX) RELEASE_PREFIX="$OPTARG";;
87
+ $ARG_START) START_POINT="$OPTARG";;
88
+ $ARG_FINISH) END_POINT="$OPTARG";;
89
+ $ARG_CHANGELOG) CHANGELOG_FILE="$OPTARG";;
90
+ $ARG_VERSION_FILE) VERSION_FILE="$OPTARG";;
91
+
92
+ ?)
93
+ printf "illegal option: '%s'\n" "$OPTARG" >&2
94
+ echo "$USAGE_OUTPUT" >&2
95
+ exit 1
96
+ ;;
97
+ esac
98
+ done
99
+ shift $((OPTIND - 1))
100
+
101
+ ############################################################
102
+ ##### VALIDATION #####
103
+ ############################################################
104
+
105
+ validate_version_type "$VERSION_TYPE" "$USAGE_OUTPUT"
106
+ ensure_git_directory
107
+ ensure_git_is_clean
108
+
109
+ ############################################################
110
+ ##### RELEASE #####
111
+ ############################################################
112
+ last_tag_name=$(get_last_tag_name $RELEASE_PREFIX);
113
+
114
+ if [[ "$START_POINT" = '' ]]; then
115
+ START_POINT=$last_tag_name
116
+ fi;
117
+
118
+ next_version_number=$(get_next_version_number_from_tag $VERSION_TYPE $last_tag_name)
119
+ next_tag_name="${RELEASE_PREFIX}${next_version_number}"
120
+ generate_version_file "$next_version_number" "$VERSION_FILE"
121
+
122
+ changelog_content=$(generate_changelog_content "$next_version_number" "$CHANGELOG_SCOPE" "$START_POINT" "$END_POINT")
123
+
124
+ generate_changelog_file "$changelog_content" "$CHANGELOG_STRATEGY" "$CHANGELOG_FILE"
125
+
126
+ set +e #Allow commit to fail if no files have changed
127
+ git add -A
128
+ git commit -m "Release : ${next_tag_name}"
129
+ set -e
130
+
131
+ git tag $next_tag_name
132
+
133
+ if [[ "$FORCE_PUSH" = 'true' ]]; then
134
+ git push $next_tag_name
135
+ fi;
@@ -0,0 +1,140 @@
1
+ #!/bin/bash -e
2
+ set -e
3
+
4
+ ############################################################
5
+ ##### Git-Release-Deployed #####
6
+ ### Pure bash script for handling deployed releases ###
7
+ ### Providing a tag with generated changelog ###
8
+ ############################################################
9
+
10
+ ############################################################
11
+ ##### DEFAULTS #####
12
+ ############################################################
13
+
14
+ DEPLOYED_PREFIX='deployed/'
15
+ CHANGELOG_FILE='CHANGELOG'
16
+ CHANGELOG_SCOPE=':all_commits'
17
+ CHANGELOG_STRATEGY=':overwrite'
18
+
19
+ START_POINT=''
20
+ END_POINT=''
21
+
22
+ #Supporting functions
23
+ . "${BASH_SOURCE[0]%/*}/../support/support-functions.sh"
24
+
25
+ USAGE_OUTPUT="
26
+ usage : $(basename "$0") $(arg_for $ARG_DEPLOYED_TAG '<deployed_tag>') [$(arg_for $ARG_RELEASE_PREFIX '<prefix>')] [$(arg_for $ARG_START '<start>')] [$(arg_for $ARG_FINISH '<finish>')]
27
+ [$(arg_for $ARG_APPEND)] [$(arg_for $ARG_FORCE)] [$(arg_for $ARG_PULL_REQUESTS)] [$(arg_for $ARG_CHANGELOG '<changelog_file>')]
28
+ [$(arg_for $ARG_HELP_TEXT)]
29
+ --- create git release tag for a deployed release with a generated changelog.
30
+
31
+ options:
32
+ required:
33
+ $(arg_for $ARG_DEPLOYED_TAG '<deployed_tag>') set the deployed tag name
34
+ optional:
35
+ [$(arg_for $ARG_RELEASE_PREFIX '<prefix>')] set the prefix for the new deployment tag (default: '${DEPLOYED_PREFIX}')
36
+ [$(arg_for $ARG_FORCE)] force push of new deploy tag (default: commit changes but do not push)
37
+ changelog:
38
+ [$(arg_for $ARG_START '<start>')] set the start point (default: the last deployed tag)
39
+ [$(arg_for $ARG_FINISH '<finish>')] set the end/finish point (default: HEAD)
40
+ [$(arg_for $ARG_APPEND)] append to changelog (default: ${CHANGELOG_STRATEGY})
41
+ [$(arg_for $ARG_PULL_REQUESTS)] set to only pull requests (default: ${CHANGELOG_SCOPE})
42
+ [$(arg_for $ARG_CHANGELOG '<changelog_file>')] set the changelog filename (default: ${CHANGELOG_FILE})
43
+ general:
44
+ [$(arg_for $ARG_HELP_TEXT)] show this help text
45
+
46
+
47
+ usage examples:
48
+
49
+ 1) Basic usage with defaults
50
+ Given the last deployed release was 'releases/v1.1.4' :
51
+
52
+ $(basename "$0") $(arg_for $ARG_DEPLOYED_TAG 'releases/v1.1.4') $(arg_for $ARG_RELEASE_PREFIX 'deploys/staging')
53
+
54
+ Tag generated : deploys/staging/our-releases/REL1.1.4
55
+ CHANGELOG file contains : commit information for all commits between last deployed version and current release
56
+
57
+ 2) Pull requests only (changelog generated only with body of pull request titles)
58
+
59
+ $(basename "$0") $(arg_for $ARG_DEPLOYED_TAG 'releases/v1.0.4') $(arg_for $ARG_PULL_REQUESTS)
60
+
61
+ 3) Generate custom changelog for deployed versions
62
+
63
+ $(basename "$0") $(arg_for $ARG_DEPLOYED_TAG 'releases/v1.0.4') $(arg_for $ARG_CHANGELOG 'DEPLOYEDCHANGELOG')
64
+
65
+ "
66
+
67
+ ############################################################
68
+ ##### INPUT CAPTURE #####
69
+ ############################################################
70
+
71
+ while getopts "$ARG_FORCE""$ARG_HELP_TEXT""$ARG_APPEND""$ARG_PULL_REQUESTS""$ARG_DEPLOYED_TAG":"$ARG_START":"$ARG_CHANGELOG":"$ARG_FINISH":"$ARG_RELEASE_PREFIX": option
72
+ do
73
+ case "${option}"
74
+ in
75
+ $ARG_DEPLOYED_TAG) DEPLOYED_TAG="$OPTARG";;
76
+ $ARG_RELEASE_PREFIX) DEPLOYED_PREFIX="$OPTARG";;
77
+ $ARG_START) START_POINT="$OPTARG";;
78
+ $ARG_FINISH) END_POINT="$OPTARG";;
79
+ $ARG_APPEND) CHANGELOG_STRATEGY=":append";;
80
+ $ARG_FORCE) FORCE_PUSH='true';;
81
+ $ARG_PULL_REQUESTS) CHANGELOG_SCOPE=":pulls_only";;
82
+ $ARG_CHANGELOG) CHANGELOG_FILE="$OPTARG";;
83
+ $ARG_HELP_TEXT)
84
+ echo "$USAGE_OUTPUT" >&2
85
+ exit 0
86
+ ;;
87
+ ?)
88
+ printf "illegal option: '%s'\n" "$OPTARG" >&2
89
+ echo "$USAGE_OUTPUT" >&2
90
+ exit 1
91
+ ;;
92
+ esac
93
+ done
94
+ shift $((OPTIND - 1))
95
+
96
+ ############################################################
97
+ ##### VALIDATION #####
98
+ ############################################################
99
+
100
+ ensure_git_directory
101
+ ensure_git_is_clean
102
+ validate_deploy_tag "$DEPLOYED_TAG" "$USAGE_OUTPUT"
103
+
104
+ ############################################################
105
+ ##### RELEASE-DEPLOYED #####
106
+ ############################################################
107
+
108
+ #Checkout existing deployed tag
109
+ next_deploy_tag_name="${DEPLOYED_PREFIX}${DEPLOYED_TAG}"
110
+
111
+ if [[ $(check_tag_exists "$next_deploy_tag_name" && echo $?) = "0" ]]; then
112
+ #Delete existing
113
+ git tag -d $next_deploy_tag_name
114
+ fi;
115
+ git checkout -f --no-track -B "$next_deploy_tag_name" "$DEPLOYED_TAG"
116
+
117
+ #Capture versioning prefix from new deploy tag
118
+ versioning_prefix=$(get_versioning_prefix_from_tag "$next_deploy_tag_name")
119
+
120
+ #Find last deployed tag for this versioning style
121
+ last_tag_name=$(get_last_tag_name $versioning_prefix)
122
+
123
+ deployed_version_number=$(get_version_number_from_tag "$next_deploy_tag_name")
124
+ if [[ "$START_POINT" = '' ]]; then
125
+ START_POINT=$last_tag_name
126
+ fi;
127
+
128
+ changelog_content=$( generate_changelog_content "$deployed_version_number" "$CHANGELOG_SCOPE" "$START_POINT" "$END_POINT" )
129
+
130
+ generate_changelog_file "$changelog_content" "$CHANGELOG_STRATEGY" "$CHANGELOG_FILE"
131
+
132
+ #Create tag and optionally push
133
+ git add -A
134
+ git commit -m "Release deployed : ${DEPLOYED_TAG}"
135
+
136
+ git tag -f $next_deploy_tag_name
137
+
138
+ if [[ "$FORCE_PUSH" = 'true' ]]; then
139
+ git push $next_deploy_tag_name
140
+ fi;