blob: 8d632b3015fe3c81c4a1a99bb3ef5e173ba3e641 [file] [log] [blame]
#!/usr/bin/env python3
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
Print out steps for a "Report Manager" to execute when preparing the
Incubator's monthly report to the ASF Board of Directors.
"""
import sys
if sys.version_info < (3, 2):
raise Exception("Python 3.2 or above is required")
import argparse
import datetime
import calendar
from report_timeline import Timeline
def header(options):
return strip_indent("""
##################################################################
# This doc is meant to be a guide to preparing the incubator
# report for a given month. Each section has a heading, starting
# with mechanical, editorial, or Chair. If you have volunteered
# to perform any of these actions, please pay attention to
# those sections.
##################################################################
""")
def timeline_email(options):
timeline = Timeline(month=options['month']).to_email()
return strip_indent("""
##################################################################
# mechanical -- Send report timeline email.
#
# On the last Wednesday of the month, send an email to
# general@incubator announcing the report timeline, using the
# following content.
##################################################################
{timeline}
""").format(timeline=timeline, **options)
def assemble_release_list(options):
month = ((options['month'] + 10) % 12) + 1
year = options['year'] if month != 12 else options['year'] - 1
date = datetime.date(day=1, month=month, year=year)
found = calendar.monthrange(year, month)
end = date + datetime.timedelta(days=found[1])
template = "{{{date:%Y}-{date:%m}-{date:%d}}}:{{{end:%Y}-{end:%m}-{end:%d}}}"
date_spec = template.format(date=date, end=end)
return strip_indent("""
##################################################################
# editorial -- Assemble list of releases.
#
# The Board report must contain a list of releases by the
# Incubator project during the reporting period. This can be
# assembled manually from the history of our dist area.
#
# The date of each release is the date it appeared in our dist
# area. We provide a list of all releases that entered
# distribution during the previous month.
##################################################################
# History of our dist area during the reporting month.
svn log -v -r {0} https://dist.apache.org/repos/dist/release/incubator
""".format(date_spec))
def summarize_podling_reports(options):
return strip_indent("""
##################################################################
# editorial -- Create podling summary.
#
# After the podling reporting deadline has passed, group
# podlings into the following categories (additional categories
# may be added if appropriate):
#
# * Still getting started at the Incubator
# * Not yet ready to graduate
# * No release
# * Community growth
# * Ready to graduate
# * Did not report, expected next month
#
##################################################################
# For any podlings that did not report, add a "monthly" attribute
# in podlings.xml. See http://s.apache.org/At0 for a sample commit.
# mechanical -- Assign podlings which do not report to "monthly".
[... edit podlings.xml with your editor of choice ...]
svn ci -m "Assign podlings which did not report to 'monthly'."
##################################################################
# editorial -- Write narrative, misc, legal, infrastructure, etc.
# sections.
#
# After the podlings are compiled, please add the various sections
# listed above. To do this, visit the incubator mail archives for
# the preceeding month and review any actions performed. Were
# there any code donations? Podlings renamed? Unexpected outages?
##################################################################
""")
def normalize_formatting(options):
return strip_indent("""
##################################################################
# mechanical -- Normalize report formatting
#
# Normalize the formatting of the podling reports and shepherd
# reviews. Remove any blank entries.
#
# The report will ultimately be published as part of the Board
# minutes in monospaced plain text. Here's a style guide:
#
# * Wrap text at 76 characters.
# * Normalize indentation. For all podling reports, questions are
# flush left, answers indented two spaces.
* * No more than one blank line anywhere.
# * All URLs which would cause lines to exceed 76 characters
# should be shortened using <http://s.apache.org>.
##################################################################
""")
def send_draft_to_general(options):
return strip_indent("""
##################################################################
# mechanical -- Send "shepherding" email.
#
# Once the deadline has passed for the editorial and shepherding
# tasks, a draft of the report should be sent to
# general@incubator for review.
#
# It is important to send this email in a timely manner so that
# there is an adequate window for review. If the report is
# incomplete, send out the draft anyway.
#
# Suggested subject:
#
# Draft Report {date:%B} {date:%Y} - please review
#
##################################################################
""").format(**options)
def file_report(options):
return strip_indent("""
##################################################################
# Chair -- Deliver report to Board.
#
# On the day that the report is due to be submitted to the Board,
# no action by the Report Manager is required.
#
# The IPMC Chair will perform a final review for completeness and
# consistency, mark the wiki page as final, then file the report.
##################################################################
""").format(**options)
def prep_next_wiki_report_template(options):
next_month = (options['month'] % 12) + 1
return strip_indent("""
##################################################################
# mechanical -- Prepare next month's report template.
#
# Prepare next month's wiki report template.
##################################################################
# Edit podlings.xml: remove the "monthly" attribute for podlings
# where it has expired. Commit any changes.
[... edit podlings.xml with your editor of choice ...]
svn ci -m "Remove expired 'monthly' attributes."
# Run clutch, regenerate the website, commit and publish
python3 clutch.py
svn ci -m "Run clutch."
login to CMS and publish the Incubator website.
# Assign shepherds.
python3 assign_shepherds.py --month={next_month}
svn ci -m "Assign shepherds."
# Generate report template and publish on the wiki.
python3 clutch2report.py --month={next_month} --upload
""").format(next_month=next_month, **options)
def strip_indent(text):
# Fragile hack, but good enough for this simple script.
return text.replace("\n ", "\n")
def process_cli_args():
parser = argparse.ArgumentParser()
parser.add_argument('--apache-id', type=str, required=True)
parser.add_argument('--month', type=int, required=True, help="1-12")
options = vars(parser.parse_args())
now = datetime.datetime.now()
if options['month'] >= now.month:
options['year'] = now.year
else:
options['year'] = now.year + 1
for day in range(15, 22):
date = datetime.date(day=day, month=options['month'],
year=options['year'])
if date.weekday() == 2:
options['date'] = date
break
return options
def main():
options = process_cli_args()
text = ""
text += header(options)
text += timeline_email(options)
text += summarize_podling_reports(options)
text += assemble_release_list(options)
text += normalize_formatting(options)
text += send_draft_to_general(options)
text += file_report(options)
text += prep_next_wiki_report_template(options)
print(text)
if __name__ == '__main__':
main()