Skip to content

Commit

Permalink
rpm-ch: implement tagging options
Browse files Browse the repository at this point in the history
Implement '--tag' command line option (and other related options for
e.g. signing) for creating and tagging a release. These correspond the
tagging options in gbp-buildpackage-rpm.

A slight difference is that gbp buildpackage-rpm never commits anything
to git. However, in rpm-ch the '--tag' option automatically enables
--commit which causes the changelog modifications (and, all other staged
changes) to be committed to git before creating the tag. This makes it
possible to create a release and document the packaging/release tag name
in the rpm changelog.

Signed-off-by: Markus Lehtonen <[email protected]>
  • Loading branch information
marquiz committed Feb 26, 2018
1 parent 9daa22e commit 7ea85a1
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 7 deletions.
57 changes: 57 additions & 0 deletions docs/manpages/gbp-rpm-ch.xml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@
<arg><option>--editor-cmd=</option><replaceable>EDITOR</replaceable></arg>
<arg><option>--commit</option></arg>
<arg><option>--commit-msg</option><replaceable>MSG-FORMAT</replaceable></arg>
<arg><option>--tag</option></arg>
<arg><option>--retag</option></arg>
<arg><option>--packaging-tag-msg</option><replaceable>MSG-FORMAT</replaceable></arg>
<arg><option>--[no-]sign-tags</option></arg>
<arg><option>--keyid=</option><replaceable>GPG-KEYID</replaceable></arg>
<arg><option>--customizations=</option><replaceable>CUSTOMIZATION-FILE</replaceable></arg>
<arg choice="plain"><replaceable>[PATH1 PATH2]</replaceable></arg>
</cmdsynopsis>
Expand Down Expand Up @@ -287,6 +292,58 @@
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--tag</option>
</term>
<listitem>
<para>
Commit the changes and create a packaging (release) tag. Similarly to
<option>--commit</option>, all staged changes are committed to git
before creating the tag. This option makes it possible to create a
release and correctly document the the tag name in the rpm changelog
(by using %(tagname)s in the <option>--changelog-revision</option>
string).
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--retag</option>
</term>
<listitem>
<para>
Don't fail tag operations if a tag with the same version already
exists, but, overwrite the existing tag, instead.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--packaging-tag-msg=</option><replaceable>MSG-FORMAT</replaceable>
</term>
<listitem>
<para>
Format string for the tag message
(when <option>--tag</option> is given).
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--[no-]sign-tags</option>
</term>
<listitem>
<para>
GPG sign all created tags.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--keyid=</option><replaceable>GPG-KEYID</replaceable>
</term>
<listitem>
<para>
Use this keyid for gpg signing tags.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--customizations=</option><replaceable>CUSTOMIZATION-FILE</replaceable>
</term>
Expand Down
46 changes: 39 additions & 7 deletions gbp/scripts/rpm_ch.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,13 @@
import gbp.log
from gbp.config import GbpOptionParserRpm, GbpOptionGroup
from gbp.errors import GbpError
from gbp.git.modifier import GitModifier
from gbp.rpm import (guess_spec, NoSpecError, SpecFile, split_version_str,
compose_version_str)
from gbp.rpm.changelog import Changelog, ChangelogParser, ChangelogError
from gbp.rpm.git import GitRepositoryError, RpmGitRepository
from gbp.rpm.policy import RpmPkgPolicy
from gbp.scripts.buildpackage_rpm import packaging_tag_data
from gbp.scripts.common import ExitCodes
from gbp.tmpfile import init_tmpdir, del_tmpdir

Expand Down Expand Up @@ -145,7 +147,7 @@ def check_repo_state(repo, options):
gbp.log.err("Unstaged changes in:\n %s" %
'\n '.join(unstaged))
raise GbpError("Please commit or stage your changes before using "
"the --commit option")
"the --commit or --tag option")


def parse_spec_file(repo, options):
Expand Down Expand Up @@ -294,11 +296,21 @@ def update_changelog(changelog, entries, repo, spec, options):
# Get info for section header
now = datetime.now()
name, email = get_author(repo, options.git_author)
author = None
committer = None
rev_str_fields = dict(spec.version,
version=compose_version_str(spec.version),
vendor=options.vendor,
tagname=repo.describe('HEAD', longfmt=True,
always=True))
vendor=options.vendor)
if options.tag:
# Get fake information for the to-be-created git commit
author = committer = GitModifier(date=now)
tag, msg = packaging_tag_data(repo, 'HEAD', spec.name, spec.version,
options)
else:
tag = repo.describe('HEAD', longfmt=True, always=True)
msg = None
rev_str_fields['tagname'] = tag

try:
revision = options.changelog_revision % rev_str_fields
except KeyError as err:
Expand All @@ -318,6 +330,7 @@ def update_changelog(changelog, entries, repo, spec, options):
# Add new entries to the topmost section
for entry in entries:
top_section.append_entry(entry)
return (tag, msg, author, committer)


def create_commit_message(spec, options):
Expand Down Expand Up @@ -387,6 +400,8 @@ def build_parser(name):
dest="packaging_branch")
naming_grp.add_config_file_option(option_name="packaging-tag",
dest="packaging_tag")
naming_grp.add_config_file_option(option_name="packaging-tag-msg",
dest="packaging_tag_msg")
naming_grp.add_config_file_option(option_name="packaging-dir",
dest="packaging_dir")
naming_grp.add_config_file_option(option_name="changelog-file",
Expand Down Expand Up @@ -416,11 +431,19 @@ def build_parser(name):
dest="spawn_editor")
format_grp.add_config_file_option(option_name="editor-cmd",
dest="editor_cmd")
# Commit group options
# Commit/tag group options
commit_grp.add_option("-c", "--commit", action="store_true",
help="commit changes")
commit_grp.add_config_file_option(option_name="commit-msg",
dest="commit_msg")
commit_grp.add_option("--tag", action="store_true",
help="commit the changes and create a"
"packaging/release tag")
commit_grp.add_option("--retag", action="store_true",
help="Overwrite packaging tag if it already exists")
commit_grp.add_boolean_config_file_option(option_name="sign-tags",
dest="sign_tags")
commit_grp.add_config_file_option(option_name="keyid", dest="keyid")
return parser


Expand All @@ -432,6 +455,8 @@ def parse_args(argv):

options, args = parser.parse_args(argv[1:])

if options.tag:
options.commit = True
if not options.changelog_revision:
options.changelog_revision = RpmPkgPolicy.Changelog.header_rev_format

Expand Down Expand Up @@ -474,7 +499,9 @@ def main(argv):
# Do the actual update
entries = entries_from_commits(ch_file.changelog, repo, commits,
options)
update_changelog(ch_file.changelog, entries, repo, spec, options)
tag, tag_msg, author, committer = update_changelog(ch_file.changelog,
entries, repo, spec,
options)
# Write to file
ch_file.write()

Expand All @@ -484,7 +511,12 @@ def main(argv):
if options.commit:
edit = True if editor_cmd else False
msg = create_commit_message(spec, options)
commit_changelog(repo, ch_file, msg, None, None, edit)
commit_changelog(repo, ch_file, msg, author, committer, edit)
if options.tag:
if options.retag and repo.has_tag(tag):
repo.delete_tag(tag)
repo.create_tag(tag, tag_msg, 'HEAD', options.sign_tags,
options.keyid)

except (GbpError, GitRepositoryError, ChangelogError, NoSpecError) as err:
if len(err.__str__()):
Expand Down
42 changes: 42 additions & 0 deletions tests/component/rpm/test_rpm_ch.py
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,48 @@ def test_option_commit_msg(self):
eq_(mock_ch(['--commit', '--since=HEAD^', '--commit-msg=%(foo)s']), 1)
self._check_log(-1, "gbp:error: Unknown key 'foo' in commit-msg string")

def test_tagging(self):
"""Test commiting/tagging"""
repo = self.init_test_repo('gbp-test-native')

# Update and commit+tag
eq_(mock_ch(['--tag', '--packaging-tag=new-tag', '--since=HEAD^']), 0)
ok_(repo.has_tag('new-tag'))
sha = repo.rev_parse('HEAD')
eq_(sha, repo.rev_parse('new-tag^0'))

# Should fail if the tag already exists
eq_(mock_ch(['--tag', '--packaging-tag=new-tag', '--since=HEAD^']), 1)

# Update and commit+tag
eq_(mock_ch(['--tag', '--packaging-tag=new-tag', '--since=HEAD^',
'--retag']), 0)
ok_(repo.has_tag('new-tag'))
sha2 = repo.rev_parse('HEAD')
ok_(sha2 != sha)
eq_(sha2, repo.rev_parse('new-tag^0'))

def test_tagging2(self):
"""Test commiting/tagging spec file"""
repo = self.init_test_repo('gbp-test2')

# Check unclean repo
with open('untracked-file', 'w') as fobj:
fobj.write('this file is not tracked\n')
with open('README', 'a') as fobj:
fobj.write('some new content\n')

# Unstaged file (README) -> failure
eq_(mock_ch(['--tag', '--packaging-tag=new-tag', '--since=HEAD^']), 1)
self._check_log(-1, 'gbp:error: Please commit or stage your changes')

# Add file, update and commit+tag, untracked file should be ignored
repo.add_files('README')
eq_(mock_ch(['--tag', '--packaging-tag=new-tag', '--since=HEAD^']), 0)
ok_(repo.has_tag('new-tag'))
sha = repo.rev_parse('HEAD')
eq_(sha, repo.rev_parse('new-tag^0'))

def test_option_editor_cmd(self):
"""Test the --editor-cmd and --spawn-editor cmdline options"""
repo = self.init_test_repo('gbp-test-native')
Expand Down

0 comments on commit 7ea85a1

Please sign in to comment.