Skip to content

Commit

Permalink
Introduce command "b4 rn" to produce release for pull requests
Browse files Browse the repository at this point in the history
Associate patches in patch queue to patch series and for every patch
series provide a lore link to latest revision.

Can be used to produce release notes draft to add to a pull request:

  git format-patch <revision range> --stdout | b4 rn -m -

To produce release notes before merging a pull request:

  b4 pr -e -o - <PR msgid> | b4 rn -m -

And to produce release notes from a merged pull request:

  b4 pr -e -o - <PR tracker reply msgid> | b4 rn -m -

See tests/linux_rn.sh for examples.

Signed-off-by: Amir Goldstein <amir73il@gmail.com>
  • Loading branch information
amir73il committed Apr 26, 2022
1 parent fb46481 commit f596636
Show file tree
Hide file tree
Showing 5 changed files with 253 additions and 1 deletion.
14 changes: 14 additions & 0 deletions b4/command.py
Expand Up @@ -103,6 +103,11 @@ def cmd_diff(cmdargs):
b4.diff.main(cmdargs)


def cmd_rn(cmdargs):
import b4.rn
b4.rn.main(cmdargs)


def cmd():
# noinspection PyTypeChecker
parser = argparse.ArgumentParser(
Expand Down Expand Up @@ -250,6 +255,15 @@ def cmd():
help='Show all developer keys found in a thread')
sp_kr.set_defaults(func=cmd_kr)

# b4 rn
sp_rn = subparsers.add_parser('rn', help='Generate release notes from pull request')
cmd_retrieval_common_opts(sp_rn)
sp_rn.add_argument('-g', '--gitdir', default=None,
help='Operate on this git tree instead of current dir')
sp_rn.add_argument('-o', '--output-file', dest='outfile', default=None,
help='Write release notes into this file instead of outputting to stdout')
sp_rn.set_defaults(func=cmd_rn)

cmdargs = parser.parse_args()

logger.setLevel(logging.DEBUG)
Expand Down
107 changes: 107 additions & 0 deletions b4/rn.py
@@ -0,0 +1,107 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (C) 2022 CTERA Networks. All Rights Reserved.
#
__author__ = 'Amir Goldstein <amir73il@gmail.com>'

import os
import sys
import b4
import b4.mbox
import mailbox
import email
import shutil
import pathlib

logger = b4.logger

def note_series(lser, notes, fh):
cover = None
if lser.has_cover:
cover = lser.patches[0]
elif len(lser.patches) > 1:
cover = lser.patches[1]

if not cover:
logger.critical('No cover letter found for patch series')
return

if cover.msgid in notes:
logger.debug('Duplicate series: %s', cover.subject)
return

notes[cover.msgid] = cover
config = b4.get_main_config()
fh.write('\n- %s\n' % cover.full_subject)
fh.write(' [%s]\n' % (config['linkmask'] % cover.msgid))


def note_latest_series(msgs, notes, fh):
count = len(msgs)
logger.debug('---')
logger.debug('Analyzing %s messages in the thread', count)
lmbx = b4.LoreMailbox()
# Add covers of all revisions first, so we are sure to find the right cover
# when we add the message
for msg in msgs:
lmbx.add_message(msg, needcover=True)

lser = lmbx.get_series()
if lser is None or len(lser.patches) == 0:
logger.critical('No posted patches found')
return None

note_series(lser, notes, fh)


# Breakup patch queue into series and report notes for every series
def release_notes(msgs, cmdargs, fh):
fh.write('\n---\n')
notes = {}

for msg in msgs:
# Strip prefixes from subject
lsub = b4.LoreSubject(msg['Subject'])
if not lsub.subject:
continue;
logger.debug('Message: %s', lsub.subject)
if lsub.counter == 0:
# Cover letter of PR
prsub = lsub.subject
if prsub.startswith('Re: '):
prsub = prsub[4:]
fh.write('Changes in %s:\n' % prsub)
prmsgid = b4.LoreMessage.get_clean_msgid(msg, header='In-Reply-To')
if prmsgid:
config = b4.get_main_config()
fh.write(' [%s]\n' % (config['linkmask'] % prmsgid))
continue;

# Find public-inbox series whose first patch matches this msg subject
ser_msgs = b4.mbox.get_extra_series([], base_msg=msg, direction=0,
nocache=cmdargs.nocache,
useproject=cmdargs.useproject)
# Report notes for found series
if len(ser_msgs) > 0:
note_latest_series(ser_msgs, notes, fh)

if not notes:
logger.critical('No posted patches found')

fh.write('\n---\n')


def main(cmdargs):
msgid, msgs = b4.mbox.get_msgs(cmdargs)
if not msgs:
logger.critical('Unable to retrieve messages')
sys.exit(1)

if cmdargs.outfile is not None:
logger.info('Writing %s', cmdargs.outfile)
fh = open(cmdargs.outfile, 'w')
else:
fh = sys.stdout

release_notes(msgs, cmdargs, fh)
23 changes: 22 additions & 1 deletion man/b4.5.rst
Expand Up @@ -13,7 +13,7 @@ Work with code submissions in a public-inbox archive

SYNOPSIS
--------
b4 {mbox,am,shazam,attest,pr,ty,diff} [options]
b4 {mbox,am,shazam,attest,pr,rn,ty,diff} [options]

DESCRIPTION
-----------
Expand All @@ -31,6 +31,7 @@ SUBCOMMANDS
* *b4 am*: Create an mbox file that is ready to git-am
* *b4 shazam*: Similar to *am*, but lets you apply patches directly
* *b4 pr*: Work with pull requests
* *b4 rn*: Generate release notes
* *b4 diff*: Show range-diff style diffs between patch versions
* *b4 ty*: Create templated replies for processed patches and pull requests
* *b4 attest*: (EXPERIMENTAL) Add cryptographic attestation to patches
Expand Down Expand Up @@ -249,6 +250,26 @@ optional arguments:

*Example*: b4 kr --show-keys 20210521184811.617875-1-konstantin@linuxfoundation.org

b4 rn
~~~~~
usage:
command.py rn [-h] [-g GITDIR] [-p USEPROJECT] [-C] [-c] [msgid]

positional arguments:
msgid Message ID to process, or pipe a raw message

optional arguments:
-h, --help show this help message and exit
-g GITDIR, --gitdir GITDIR
Operate on this git tree instead of current dir
-p USEPROJECT, --use-project USEPROJECT
Use a specific project instead of guessing (linux-mm, linux-hardening, etc)
-o OUTFILE, --output-file OUTFILE
Write release notes into this file instead of outputting to stdout
-C, --no-cache Do not use local cache

*Example*: b4 rn 202003292120.2BDCB41@keescook

CONFIGURATION
-------------
B4 configuration is handled via git-config(1), so you can store it in
Expand Down
86 changes: 86 additions & 0 deletions tests/linux_rn.sh
@@ -0,0 +1,86 @@
#!/bin/sh
#
# b4 rn examples to be run from linux source tree
#
# Usage:
#
# T=$PWD/tests/
# cd ~/src/linux
# $T/linux_rn.sh -d 2>rn.log
# $T/linux_rn.sh -d $T/xfs-5.10..5.17.in -p linux-xfs
#

if ! (git rev-parse v2.6.12-rc2 2> /dev/null | \
grep -q 9e734775f7c22d2f89943ad6c745571f1930105f); then
echo "Please run this test from a linux source tree"
exit 1
fi

RNMBX=/tmp/linux_rn.mbx
RNOUT=/tmp/linux_rn.out

if [ "$1" = "-d" ]; then
RNDEBUG=$1
shift
fi
RNOPTS="$*"

git_fixes_rn()
{
local descr="$1"
local range="$2"
local path="$3"

echo "---"
echo "GIT log - $descr"
echo "---"
git log -p --grep Fixes: --pretty=email $range -- $path | \
b4 $RNDEBUG rn $RNOPTS -m -
}

pr_tracker_rn()
{
local descr="$1"
local msgid="$2"

rm -rf $RNMBX $RNOUT

echo "---"
echo "PR tracker - $descr"
echo "---"
b4 $RNDEBUG pr -e -o $RNMBX "$msgid"
b4 $RNDEBUG rn $RNOPTS -m $RNMBX -o $RNOUT
cat $RNOUT
}


# Process PR list from input file
if [ -f "$1" ]; then
PRFILE="$1"
shift
RNOPTS="$*"
cat "$PRFILE" | while read pr name; do
echo "Writing release notes of $pr to $name.out..."
>"$name".out 2>"$name".log </dev/null \
pr_tracker_rn "$name" "$pr"
done
exit
fi

git_fixes_rn "series with fix patches for subsystem" \
v5.13..v5.14 fs/xfs

pr_tracker_rn "patches not posted" \
164374837231.6282.14818932060276777076.pr-tracker-bot@kernel.org

pr_tracker_rn "individual patch posted" \
164590250253.22829.8421551678388979175.pr-tracker-bot@kernel.org

pr_tracker_rn "patch series posted" \
164408216661.7836.4930013315804213982.pr-tracker-bot@kernel.org

pr_tracker_rn "patch series including partial reroll" \
164817214223.9489.12483808836905609419.pr-tracker-bot@kernel.org

pr_tracker_rn "many patch series" \
163060423908.29568.14182828511329643634.pr-tracker-bot@kernel.org
24 changes: 24 additions & 0 deletions tests/xfs-5.10..5.17.in
@@ -0,0 +1,24 @@
164590250253.22829.8421551678388979175.pr-tracker-bot@kernel.org [GIT PULL] xfs: fixes for 5.17-rc6
164408216661.7836.4930013315804213982.pr-tracker-bot@kernel.org [GIT PULL] xfs: fixes for 5.17-rc3
164284441552.7666.5195906929759259618.pr-tracker-bot@kernel.org [GIT PULL] xfs: fixes for 5.17-rc1
164274816250.27527.6119097451475838528.pr-tracker-bot@kernel.org [GIT PULL] xfs: DMAPI ioctl housecleaning for 5.17-rc1
164274816283.27527.4445590209473650660.pr-tracker-bot@kernel.org [GIT PULL] xfs: legacy Irix ioctl housecleaning for 5.17-rc1, part 2
164274816267.27527.14866415947964585469.pr-tracker-bot@kernel.org [GIT PULL] xfs: legacy Irix ioctl housecleaning for 5.17-rc1, part 1
164194642310.21161.8563846497332350289.pr-tracker-bot@kernel.org [GIT PULL] xfs: new code for 5.17
163926928546.10000.18339109912268195117.pr-tracker-bot@kernel.org [GIT PULL] xfs: bug fixes for 5.16-rc4
163866768073.6146.4028609779231917827.pr-tracker-bot@kernel.org [GIT PULL] xfs: bug fixes for 5.16-rc3
163804699189.3764.12554584751673448384.pr-tracker-bot@kernel.org [GIT PULL] xfs: bug fixes for 5.16-rc2
163692146690.4278.335385691531056076.pr-tracker-bot@kernel.org [GIT PULL] xfs: cleanups and resyncs for 5.16
163588274577.22794.1156896528638745710.pr-tracker-bot@kernel.org [GIT PULL] xfs: new code for 5.16
163060423908.29568.14182828511329643634.pr-tracker-bot@kernel.org [GIT PULL] xfs: new code for 5.15
162784611031.1186.18214929758593020802.pr-tracker-bot@kernel.org [GIT PULL] xfs: bug fixes for 5.14-rc4
162663410637.7372.13651239253430897917.pr-tracker-bot@kernel.org [GIT PULL] xfs: bug fixes for 5.14-rc2
162526246366.28144.4236351495860897999.pr-tracker-bot@kernel.org [GIT PULL] xfs: new code for 5.14
162234900431.23697.17510919033109580334.pr-tracker-bot@kernel.org [GIT PULL] xfs: fixes for 5.13-rc4
162170495407.3077.13033559630823026395.pr-tracker-bot@kernel.org [GIT PULL] xfs: fixes for 5.13-rc3
162037389652.26493.11092818693927608843.pr-tracker-bot@kernel.org [GIT PULL] xfs: more new code for 5.13
161971872723.11214.4279033295206868895.pr-tracker-bot@kernel.org [GIT PULL] xfs: new code for 5.13
161609653113.4441.2474187984850625994.pr-tracker-bot@kernel.org [GIT PULL] xfs: fixes for 5.12-rc4
161454325648.2182.2660010480088666972.pr-tracker-bot@kernel.org [GIT PULL] xfs: fixes for 5.12-rc1
161393278374.20435.8997839961461434518.pr-tracker-bot@kernel.org [GIT PULL] xfs: new code for 5.12
160832487637.19372.7448008445325982345.pr-tracker-bot@kernel.org [GIT PULL] xfs: new code for 5.11

0 comments on commit f596636

Please sign in to comment.