mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-01-08 12:40:49 -08:00
Automate more of the release registration steps.
Copied from Perforce Change: 184892 ServerID: perforce.ravenbrook.com
This commit is contained in:
parent
bddb20f682
commit
6726b6ddc7
3 changed files with 95 additions and 37 deletions
|
|
@ -183,10 +183,6 @@ On a Unix (including OS X) machine:
|
|||
p4 -c $CLIENT client -d $CLIENT
|
||||
rm -rf /tmp/$CLIENT
|
||||
|
||||
|
||||
7. Registering the release
|
||||
--------------------------
|
||||
|
||||
#. Edit the index of releases (``release/index.html``) and add the
|
||||
release to the table, in a manner consistent with previous releases.
|
||||
|
||||
|
|
@ -201,6 +197,10 @@ On a Unix (including OS X) machine:
|
|||
|
||||
p4 submit -d "MPS: registered release $RELEASE."
|
||||
|
||||
|
||||
7. Registering the release
|
||||
--------------------------
|
||||
|
||||
#. Visit the `project
|
||||
updater <http://info.ravenbrook.com/infosys/cgi/data_update.cgi>`__,
|
||||
select “mps” from the dropdown, and hit “Find releases”.
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ VERSION_BRANCH_ENTRY = '''
|
|||
{description}
|
||||
</td>
|
||||
<td>
|
||||
<a href="https://info.ravenbrook.com/infosys/cgi/perfbrowse.cgi?@describe+{base}">base</a><br>
|
||||
<a href="https://info.ravenbrook.com/infosys/cgi/perfbrowse.cgi?@describe+{base}">base</a><br />
|
||||
<a href="https://info.ravenbrook.com/infosys/cgi/perfbrowse.cgi?@changes+{depot}/project/{project}/{child}/...">changelists</a>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
@ -80,9 +80,8 @@ def main(argv):
|
|||
help='Changelevel at which to make the branch.')
|
||||
parser.add_argument('-d', '--description',
|
||||
help='Description of the branch (for the branch spec).')
|
||||
parser.add_argument('-y', '--commit', action='store_true',
|
||||
help='Carry out the operation (by default, just '
|
||||
'show a preview).')
|
||||
parser.add_argument('-y', '--yes', action='store_true',
|
||||
help='Yes, really make the branch.')
|
||||
group = parser.add_mutually_exclusive_group(required=True)
|
||||
group.add_argument('-c', '--child',
|
||||
help='Name of the child branch.')
|
||||
|
|
@ -92,6 +91,7 @@ def main(argv):
|
|||
help='Name of the task branch.')
|
||||
args = parser.parse_args(argv[1:])
|
||||
args.depot = DEPOT
|
||||
args.today = datetime.date.today().strftime('%Y-%m-%d')
|
||||
fmt = lambda s: s.format_map(vars(args))
|
||||
|
||||
if not args.project:
|
||||
|
|
@ -133,8 +133,7 @@ def main(argv):
|
|||
if args.task:
|
||||
if not re.match(TASK_RE, args.task):
|
||||
raise Error(fmt("Invalid task: {task}"))
|
||||
args.child = fmt(datetime.date.today()
|
||||
.strftime('branch/%Y-%m-%d/{task}'))
|
||||
args.child = fmt('branch/{today}/{task}')
|
||||
print(fmt("child={child}"))
|
||||
elif args.version:
|
||||
# Deduce version number from code/version.c.
|
||||
|
|
@ -172,12 +171,12 @@ def main(argv):
|
|||
if any(p4.run('branches', '-E', args.branch)):
|
||||
print(fmt("Branch spec {branch} already exists: skipping."))
|
||||
have_branch = True
|
||||
elif args.commit:
|
||||
elif args.yes:
|
||||
print(fmt("Creating branch spec {branch}."))
|
||||
p4.run('branch', '-i').send(branch_spec).done()
|
||||
have_branch = True
|
||||
else:
|
||||
print("-y/--commit not specified: skipping branch creation.")
|
||||
print("--yes omitted: skipping branch creation.")
|
||||
|
||||
# Populate the branch
|
||||
if any(p4.run('dirs', fmt('{depot}/project/{project}/{child}'))):
|
||||
|
|
@ -188,15 +187,15 @@ def main(argv):
|
|||
'-b', args.branch,
|
||||
'-d', fmt("Branching {parent} to {child}."),
|
||||
'-s', srcs]
|
||||
if args.commit:
|
||||
if args.yes:
|
||||
print(fmt("Populating branch {branch}..."))
|
||||
populate_args.remove('-n')
|
||||
p4.do(*populate_args)
|
||||
elif have_branch:
|
||||
print("-y/--commit not specified: dry-run (-n) only.")
|
||||
print("--yes omitted: populate -n ...")
|
||||
p4.do(*populate_args)
|
||||
else:
|
||||
print("-y/--commit not specified: skipping populate.")
|
||||
print("--yes omitted: skipping populate.")
|
||||
|
||||
# Determine the first change on the branch
|
||||
cmd = p4.run('changes', fmt('{depot}/project/{project}/{child}/...'))
|
||||
|
|
@ -204,7 +203,7 @@ def main(argv):
|
|||
args.base = int(deque(cmd, maxlen=1).pop()['change'])
|
||||
print(fmt("base={base}"))
|
||||
except IndexError:
|
||||
args.commit = False
|
||||
args.yes = False
|
||||
args.base = args.changelevel
|
||||
print(fmt("Branch {child} not populated: using base={base}"))
|
||||
|
||||
|
|
@ -225,11 +224,10 @@ def main(argv):
|
|||
for result in conn.run('diff'):
|
||||
if 'data' in result:
|
||||
print(result['data'])
|
||||
if args.commit:
|
||||
if args.yes:
|
||||
conn.do('submit', '-d', fmt("Registering {child}."), filename)
|
||||
else:
|
||||
print(fmt("-y/--commit not specified: skipping submit of\n"
|
||||
" {filespec}."))
|
||||
print(fmt("--yes omitted: skipping submit of {filespec}"))
|
||||
|
||||
# Task branches
|
||||
if not args.version:
|
||||
|
|
@ -247,7 +245,7 @@ def main(argv):
|
|||
if any(p4.run('clients', '-E', args.git_client)):
|
||||
print(fmt("client {git_client} already exists: skipping."))
|
||||
have_git_branch = True
|
||||
elif args.commit:
|
||||
elif args.yes:
|
||||
client_spec = dict(
|
||||
Client=args.git_client,
|
||||
Description=fmt("Git-fusion client for syncing {project} "
|
||||
|
|
@ -260,7 +258,7 @@ def main(argv):
|
|||
p4.run('client', '-i').send(client_spec).done()
|
||||
have_git_branch = True
|
||||
else:
|
||||
print("-y/--commit not specified: skipping git branch creation.")
|
||||
print(fmt("--yes omitted: skipping {git_client}"))
|
||||
|
||||
# Update table of pushes
|
||||
register('{depot}/infosys/robots/git-fusion/etc/pushes',
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
from __future__ import unicode_literals
|
||||
import argparse
|
||||
from contextlib import contextmanager
|
||||
import datetime
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
|
|
@ -39,15 +40,34 @@ def pushdir(dir):
|
|||
yield
|
||||
os.chdir(cwd)
|
||||
|
||||
ROOT = '//info.ravenbrook.com/project'
|
||||
DEPOT = '//info.ravenbrook.com'
|
||||
PROJECT_RE = r'[a-z][a-z0-9.-]*'
|
||||
PROJECT_FILESPEC_RE = r'{}/({})/'.format(re.escape(ROOT), PROJECT_RE)
|
||||
PROJECT_FILESPEC_RE = r'{}/project/({})/'.format(re.escape(DEPOT), PROJECT_RE)
|
||||
VERSION_RE = r'\d+\.\d+'
|
||||
CUSTOMER_RE = r'[a-z][a-z0-9.-]*'
|
||||
BRANCH_RE = (r'master|(?:custom/({})/)?(?:main|version/({}))'
|
||||
.format(CUSTOMER_RE, VERSION_RE))
|
||||
BRANCH_FILESPEC_RE = r'{}({})(?:/|$)'.format(PROJECT_FILESPEC_RE, BRANCH_RE)
|
||||
|
||||
RELEASE_ENTRY = '''
|
||||
|
||||
<tr valign="top">
|
||||
<td><a href="{release}/">{release}</a></td>
|
||||
<td>{today}<br />
|
||||
<a href="https://info.ravenbrook.com/infosys/cgi/perfbrowse.cgi?@files+{origin}/...@{changelevel}">{branch}/...@{changelevel}</a></td>
|
||||
<td>
|
||||
{description}
|
||||
</td>
|
||||
<td>
|
||||
<a href="/project/{project}/issue/?action=known&sort=Priority%3AJob&release={release}">Known</a> <br />
|
||||
<a href="/project/{project}/issue/?action=fixed&release={release}">Fixed</a>
|
||||
</td>
|
||||
</tr>
|
||||
'''
|
||||
|
||||
VERSION_ENTRY = ''' <a href="/project/{project}/release/{release}/">{release}</a>
|
||||
'''
|
||||
|
||||
def main(argv):
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('-P', '--project',
|
||||
|
|
@ -56,11 +76,13 @@ def main(argv):
|
|||
help='Name of the branch to make the release from.')
|
||||
parser.add_argument('-C', '--changelevel', type=int,
|
||||
help='Changelevel at which to make the release.')
|
||||
parser.add_argument('-y', '--commit', action='store_true',
|
||||
help='Carry out the operation (by default, just '
|
||||
'show a preview).')
|
||||
parser.add_argument('-d', '--description',
|
||||
help='Description of the release.')
|
||||
parser.add_argument('-y', '--yes', action='store_true',
|
||||
help='Yes, really make the release.')
|
||||
args = parser.parse_args(argv[1:])
|
||||
args.root = ROOT
|
||||
args.depot = DEPOT
|
||||
args.today = datetime.date.today().strftime('%Y-%m-%d')
|
||||
fmt = lambda s: s.format_map(vars(args))
|
||||
|
||||
if not args.project:
|
||||
|
|
@ -72,7 +94,7 @@ def main(argv):
|
|||
args.project = m.group(1)
|
||||
print(fmt("project={project}"))
|
||||
|
||||
if not any(p4.run('dirs', fmt('{root}/{project}'))):
|
||||
if not any(p4.run('dirs', fmt('{depot}/project/{project}'))):
|
||||
raise Error(fmt("No such project: {project}"))
|
||||
|
||||
if not args.branch:
|
||||
|
|
@ -97,16 +119,17 @@ def main(argv):
|
|||
if args.version:
|
||||
print(fmt("version={version}"))
|
||||
|
||||
if not any(p4.run('dirs', fmt('{root}/{project}/{branch}'))):
|
||||
args.origin = fmt('{depot}/project/{project}/{branch}')
|
||||
if not any(p4.run('dirs', args.origin)):
|
||||
raise Error(fmt("No such branch: {branch}"))
|
||||
|
||||
if not args.changelevel:
|
||||
cmd = p4.run('changes', '-m', '1', fmt('{root}/{project}/{branch}/...'))
|
||||
cmd = p4.run('changes', '-m', '1', fmt('{origin}/...'))
|
||||
args.changelevel = int(next(cmd)['change'])
|
||||
print(fmt("changelevel={changelevel}"))
|
||||
|
||||
# Deduce release from code/version.c.
|
||||
f = fmt('{root}/{project}/{branch}/code/version.c@{changelevel}')
|
||||
f = fmt('{origin}/code/version.c@{changelevel}')
|
||||
m = re.search(r'^#define MPS_RELEASE "release/((\d+\.\d+)\.\d+)"$',
|
||||
p4.contents(f), re.M)
|
||||
if not m:
|
||||
|
|
@ -116,15 +139,19 @@ def main(argv):
|
|||
if args.version and args.version != m.group(2):
|
||||
raise Error(fmt("Version {version} does not match release {release}"))
|
||||
if args.customer:
|
||||
args.reldir = fmt('{root}/{project}/custom/{customer}/release/{release}')
|
||||
args.reldir = fmt('{depot}/project/{project}/custom/{customer}/release/{release}')
|
||||
else:
|
||||
args.reldir = fmt('{root}/{project}/release/{release}')
|
||||
args.reldir = fmt('{depot}/project/{project}/release/{release}')
|
||||
|
||||
if not args.description:
|
||||
args.description = fmt("Release {release}.")
|
||||
print(fmt("description={description}"))
|
||||
|
||||
args.kit = fmt('mps-kit-{release}')
|
||||
client_spec = dict(
|
||||
View0=fmt('{root}/{project}/{branch}/... //__CLIENT__/{kit}/...'),
|
||||
View0=fmt('{origin}/... //__CLIENT__/{kit}/...'),
|
||||
View1=fmt('{reldir}/... //__CLIENT__/release/{release}/...'))
|
||||
srcs = fmt('{root}/{project}/{branch}/...@{changelevel}')
|
||||
srcs = fmt('{origin}/...@{changelevel}')
|
||||
for line_end, args.ext, cmd in (('local', 'tar.gz', ['tar', 'czf']),
|
||||
('win', 'zip', ['zip', '-r'])):
|
||||
client_spec['LineEnd'] = line_end
|
||||
|
|
@ -139,8 +166,8 @@ def main(argv):
|
|||
os.makedirs(fmt('release/{release}'))
|
||||
subprocess.check_call(cmd + [archive, args.kit],
|
||||
stdout=subprocess.DEVNULL)
|
||||
if not args.commit:
|
||||
print("-y/--commit not specified: skipping.")
|
||||
if not args.yes:
|
||||
print(fmt("--yes omitted: skipping submit of {kit}.{ext}"))
|
||||
else:
|
||||
conn.do('add', os.path.join(client_root, archive))
|
||||
desc = fmt("Adding the MPS Kit {ext} archive for "
|
||||
|
|
@ -149,6 +176,39 @@ def main(argv):
|
|||
else:
|
||||
print("{} already exists: skipping.".format(archive))
|
||||
|
||||
def register(filespec, search, replace):
|
||||
args.filespec = fmt(filespec)
|
||||
if p4.contents(args.filespec).find(args.release) != -1:
|
||||
print(fmt("{filespec} already updated: skipping."))
|
||||
return
|
||||
client_spec = dict(View0=fmt('{filespec} //__CLIENT__/target'))
|
||||
with p4.temp_client(client_spec) as (conn, client_root):
|
||||
filename = os.path.join(client_root, 'target')
|
||||
conn.do('sync', filename)
|
||||
conn.do('edit', filename)
|
||||
with open(filename, encoding='utf8') as f:
|
||||
text = re.sub(search, fmt(replace), f.read(), 1)
|
||||
with open(filename, 'w', encoding='utf8') as f:
|
||||
f.write(text)
|
||||
for result in conn.run('diff'):
|
||||
if 'data' in result:
|
||||
print(result['data'])
|
||||
if args.yes:
|
||||
conn.do('submit', '-d', fmt("Registering release {release}."),
|
||||
filename)
|
||||
else:
|
||||
print(fmt("--yes omitted: skipping submit of {filespec}"))
|
||||
|
||||
if not args.customer:
|
||||
register('{depot}/project/{project}/release/index.html',
|
||||
'(?<=<tbody>\n)', RELEASE_ENTRY)
|
||||
register('{depot}/project/{project}/version/index.html',
|
||||
(r'(?<=<td><a href="{0}/">{0}</a></td>\n <td>\n)'
|
||||
.format(re.escape(args.version), re.escape(args.project))),
|
||||
VERSION_ENTRY)
|
||||
register('{depot}/project/{project}/index.rst',
|
||||
r'release/\d+\.\d+\.\d+', 'release/{release}')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main(sys.argv)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue