2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-31 14:35:26 +00:00

new: dev: generate changelog from git log

Use a single source of truth, the git log, to generate the list of CHANGES. Use the .rst format and include it in the ARM for a quick reference with proper gitlab links to issues and merge requests.

Closes #75

Merge branch 'nicki/add-gitchangelog' into 'main'

Closes #75

See merge request isc-projects/bind9!9152
This commit is contained in:
Nicki Křížek
2024-07-29 12:15:49 +00:00
23 changed files with 24893 additions and 22525 deletions

1
.gitchangelog.rc Symbolic link
View File

@@ -0,0 +1 @@
contrib/gitchangelog/changelog.rc.py

View File

@@ -513,18 +513,6 @@ misc:
- checklibs.out
when: on_failure
changes:
<<: *precheck_job
except:
- pipelines
script:
- sh util/tabify-changes < CHANGES > CHANGES.tmp
- diff -urNap CHANGES CHANGES.tmp
- perl util/check-changes CHANGES
- sh util/check-line-length.sh CHANGES
- rm CHANGES.tmp
needs: []
black:
<<: *precheck_job
needs: []
@@ -581,7 +569,7 @@ pylint:
variables:
PYTHONPATH: "${CI_PROJECT_DIR}/bin/tests/system"
script:
- pylint --rcfile $CI_PROJECT_DIR/.pylintrc $(git ls-files '*.py' | grep -vE '(ans\.py|dangerfile\.py|^bin/tests/system/)')
- pylint --rcfile $CI_PROJECT_DIR/.pylintrc $(git ls-files '*.py' | grep -vE '(ans\.py|dangerfile\.py|^bin/tests/system/|^contrib/)')
# Ignore Pylint wrong-import-position error in system test to enable use of pytest.importorskip
- pylint --rcfile $CI_PROJECT_DIR/.pylintrc --disable=wrong-import-position $(git ls-files 'bin/tests/system/*.py' | grep -vE 'ans\.py')

View File

@@ -46,7 +46,6 @@ confidential!
- [ ] [:link:][step_backports] **(SwEng)** Prepare backports of the merge request addressing the problem for all affected (and still maintained) branches of a given product
- [ ] [:link:][step_finish_advisory] **(Support)** Finish preparing the Security Advisory
- [ ] [:link:][step_meta_issue] **(QA)** Create (or update) the private issue containing links to fixes & reproducers for all CVEs fixed in a given release cycle
- [ ] [:link:][step_changes] **(QA)** (BIND 9 only) Reserve a block of `CHANGES` placeholders once the complete set of vulnerabilities fixed in a given release cycle is determined
- [ ] [:link:][step_merge_fixes] **(QA)** Merge the CVE fixes in CVE identifier order
- [ ] [:link:][step_patches] **(QA)** Prepare a standalone patch for the last stable release of each affected (and still maintained) product branch
- [ ] [:link:][step_asn_releases] **(QA)** Prepare ASN releases (as outlined in the Release Checklist)

View File

@@ -191,6 +191,8 @@ Files: **/.clang-format
.readthedocs.yaml
.tsan-suppress
.uncrustify.cfg
contrib/gitchangelog/changelog.rc.py
contrib/gitchangelog/relnotes.rc.py
doc/misc/*.zoneopt
doc/misc/options
doc/misc/rndc.grammar

22105
CHANGES

File diff suppressed because it is too large Load Diff

1
CHANGES Symbolic link
View File

@@ -0,0 +1 @@
doc/arm/changelog.rst

2
NEWS
View File

@@ -1 +1 @@
CHANGES
doc/arm/changelog.rst

View File

@@ -20,7 +20,6 @@ information regarding copyright ownership.
1. [Building BIND](#build)
1. [Automated testing](#testing)
1. [Documentation](#doc)
1. [Change log](#changes)
1. [Acknowledgments](#ack)
### <a name="intro"/> Introduction
@@ -49,8 +48,7 @@ ongoing maintenance and improvement. BIND is open source software
licensed under the terms of the Mozilla Public License, version 2.0.
For a detailed list of changes made throughout the history of BIND 9, see
the file [CHANGES](CHANGES). See [below](#changes) for details on the
CHANGES file format.
the [changelog](doc/arm/changelog.rst).
For up-to-date versions and release notes, see
[https://www.isc.org/download/](https://www.isc.org/download/).
@@ -163,35 +161,6 @@ can be found in the ISC Knowledgebase at
Additional information on various subjects can be found in other
`README` files throughout the source tree.
### <a name="changes"/> Change log
A detailed list of all changes that have been made throughout the
development of BIND 9 is included in the file CHANGES, with the most recent
changes listed first. Change notes include tags indicating the category of
the change that was made; these categories are:
|Category |Description |
|-------------- |-----------------------------------------------|
| [func] | New feature |
| [bug] | General bug fix |
| [security] | Fix for a significant security flaw |
| [experimental] | Used for new features when the syntax or other aspects of the design are still in flux and may change |
| [port] | Portability enhancement |
| [maint] | Updates to built-in data such as root server addresses and keys |
| [tuning] | Changes to built-in configuration defaults and constants to improve performance |
| [performance] | Other changes to improve server performance |
| [protocol] | Updates to the DNS protocol such as new RR types |
| [test] | Changes to the automatic tests, not affecting server functionality |
| [cleanup] | Minor corrections and refactoring |
| [doc] | Documentation |
| [contrib] | Changes to the contributed tools and libraries in the 'contrib' subdirectory |
| [placeholder] | Used in the main development branch to reserve change numbers for use in other branches, e.g., when fixing a bug that only exists in older releases |
In general, [func] and [experimental] tags only appear in new-feature
releases (i.e., those with version numbers ending in zero). Some new
functionality may be backported to older releases on a case-by-case basis.
All other change types may be applied to all currently supported releases.
#### Bug report identifiers
Most notes in the CHANGES file include a reference to a bug report or

View File

@@ -1248,10 +1248,10 @@ AM_CONDITIONAL([HAVE_SPHINX_BUILD], [test -n "$SPHINX_BUILD"])
AM_CONDITIONAL([BUILD_MANPAGES], [test -e doc/man/named.conf.5in || test -n "$SPHINX_BUILD"])
#
# Pull release date from CHANGES file last modification date
# Pull release date from changelog.rst file last modification date
# for reproducible builds
#
release_date=`date -u -r CHANGES +%Y-%m-%d`
release_date=`date -u -r doc/arm/changelog.rst +%Y-%m-%d`
AC_SUBST([RELEASE_DATE], $release_date)
#

View File

@@ -27,5 +27,9 @@ be fixed as time permits.
named at runtime, enabling access to external data sources including
LDAP, MySQL, Berkeley DB, perl scripts, etc.
- gitchangelog/
QA utility to produce changelog and release notes from git log.
Some links to useful software and other resources related to BIND 9 and
DNS can be found at https://www.isc.org/dns-tools-and-resources.

View File

@@ -0,0 +1,341 @@
##
## Format
##
## ACTION: [AUDIENCE:] COMMIT_MSG
##
## Description
##
## ACTION is one of 'chg', 'fix', 'new', 'rem', 'sec'
##
## Is WHAT the change is about.
##
## 'chg' is for refactor, small improvement, cosmetic changes...
## 'fix' is for bug fixes
## 'new' is for new features, big improvement
## 'rem' is for removed features
## 'sec' is for security fixes
##
## Each MR title should have exactly one ACTION, and no non-merge commits should have these.
##
## AUDIENCE is optional and can be 'dev', 'usr', 'pkg', 'test', 'doc'
##
## Is WHO is concerned by the change.
##
## Included in release notes and changelog:
## 'usr' is for final users
## 'pkg' is for packagers
##
## Included in changelog:
## 'dev' is for developers
##
## Omitted from changelog:
## 'test' is for test-only changes
## 'doc' is for doc-only changes
##
## COMMIT_MSG is ... well ... the commit message itself.
##
##
## Examples:
##
## If you want to add a release note, mark it for usr or pkg audience:
##
## sec: usr: Fix CVE-YYYY-NNNN
## rem: usr: Deprecate feature xyz
## new: pkg: libngtcp2 is now required
##
## If you want to mention it just in the changelog, add dev audience:
##
## chg: dev: Refactor xyz
## fix: dev: Fix a rare edge case of xyz
## new: dev: Add new QTYPE
##
## If you don't specify audience context, or use a custom one, it won't end
## up in the changelog:
##
## chg: doc: Tidy up the docs
## fix: test: Fix a broken test
## chg: Do some cleanup
## sec: test: Add a test case for CVE-YYYY-NNNN
##
## Please note that multi-line commit messages are supported; only the first
## line will be considered as the "summary" of the commit message. So tags
## and other rules only apply to the summary. The body of the commit
## message will be displayed in the changelog without reformatting.
##
## ``ignore_regexps`` is a line of regexps
##
## Any commit having its full commit message matching any regexp listed here
## will be ignored and won't be reported in the changelog.
##
ignore_regexps = [
r"^$", ## ignore commits with empty messages
]
## ``section_regexps`` is a list of 2-tuples associating a string label and a
## list of regexp
##
## Commit messages will be classified in sections thanks to this. Section
## titles are the label, and a commit is classified under this section if any
## of the regexps associated is matching.
##
## Please note that ``section_regexps`` will only classify commits and won't
## make any changes to the contents. So you'll probably want to go check
## ``subject_process`` (or ``body_process``) to do some changes to the subject,
## whenever you are tweaking this variable.
##
section_regexps = [
(
"Security Fixes",
[
r"^(\[9\.[0-9]{2}(-S)?\])?\s*(\[[^]]*\]\s*)?sec:\s*(dev|usr|pkg)\s*:\s*([^\n]*)$",
],
),
(
"New Features",
[
r"^(\[9\.[0-9]{2}(-S)?\])?\s*(\[[^]]*\]\s*)?new:\s*(dev|usr|pkg)\s*:\s*([^\n]*)$",
],
),
(
"Removed Features",
[
r"^(\[9\.[0-9]{2}(-S)?\])?\s*(\[[^]]*\]\s*)?rem:\s*(dev|usr|pkg)\s*:\s*([^\n]*)$",
],
),
(
"Feature Changes",
[
r"^(\[9\.[0-9]{2}(-S)?\])?\s*(\[[^]]*\]\s*)?chg:\s*(dev|usr|pkg)\s*:\s*([^\n]*)$",
],
),
(
"Bug Fixes",
[
r"^(\[9\.[0-9]{2}(-S)?\])?\s*(\[[^]]*\]\s*)?fix:\s*(dev|usr|pkg)\s*:\s*([^\n]*)$",
],
),
]
## ``body_process`` is a callable
##
## This callable will be given the original body and result will
## be used in the changelog.
##
## Available constructs are:
##
## - any python callable that take one txt argument and return txt argument.
##
## - ReSub(pattern, replacement): will apply regexp substitution.
##
## - Indent(chars=" "): will indent the text with the prefix
## Please remember that template engines gets also to modify the text and
## will usually indent themselves the text if needed.
##
## - Wrap(regexp=r"\n\n"): re-wrap text in separate paragraph to fill 80-Columns
##
## - noop: do nothing
##
## - ucfirst: ensure the first letter is uppercase.
## (usually used in the ``subject_process`` pipeline)
##
## - final_dot: ensure text finishes with a dot
## (usually used in the ``subject_process`` pipeline)
##
## - strip: remove any spaces before or after the content of the string
##
## - SetIfEmpty(msg="No commit message."): will set the text to
## whatever given ``msg`` if the current text is empty.
##
## Additionally, you can `pipe` the provided filters, for instance:
# body_process = Wrap(regexp=r'\n(?=\w+\s*:)') | Indent(chars=" ")
# body_process = Wrap(regexp=r'\n(?=\w+\s*:)')
# body_process = noop
body_process = (
ReSub(r"\n*See merge request isc-private/bind9!\d+", r"")
| ReSub(r"https://gitlab.isc.org/isc-projects/bind9/-/issues/", r"#")
| ReSub(r"https://gitlab.isc.org/isc-projects/bind9/-/merge_requests/", r"!")
| ReSub(
r"\n*(Closes|Fixes|Related|See):?\s*(isc-projects/bind9)?((#|!)\d+)",
r" :gl:`\3`",
)
| ReSub(r"\n*Backport of [^\n]+", r"")
| ReSub(r"\n*(Replaces|Supersedes)[^\n]+", r"")
| ReSub(r"\n*Merge branch '[^']+' into [^\n]+", r"")
| ReSub(r"\n*isc-private/bind9", r"")
| ReSub(r"\n*See merge request isc-projects/bind9(!\d+)", r" :gl:`\1`")
| Wrap(regexp="\n\n", separator="\n\n")
| strip
)
## ``subject_process`` is a callable
##
## This callable will be given the original subject and result will
## be used in the changelog.
##
## Available constructs are those listed in ``body_process`` doc.
subject_process = (
strip
| ReSub(
r"^(\[9\.[0-9]{2}(-S)?\])?\s*(\[[^]]*\]\s*)?(chg|fix|new|rem|sec):\s*((dev|usr|pkg)\s*:\s*)?([^\n]*)$",
r"\3\7",
)
| SetIfEmpty("No commit message.")
| ucfirst
| final_dot
)
## ``tag_filter_regexp`` is a regexp
##
## Tags that will be used for the changelog must match this regexp.
##
tag_filter_regexp = r"^v9\.[0-9]+\.[0-9]+(-S[0-9]+)?$"
## ``unreleased_version_label`` is a string or a callable that outputs a string
##
## This label will be used as the changelog Title of the last set of changes
## between last valid tag and HEAD if any.
unreleased_version_label = "(-dev)"
## ``include_commit_sha`` is a boolean to indicate whether the sha of the
## commit should be included in the change
include_commit_sha = True
## ``output_engine`` is a callable
##
## This will change the output format of the generated changelog file
##
## Available choices are:
##
## - rest_py
##
## Legacy pure python engine, outputs ReSTructured text.
## This is the default.
##
## - mustache(<template_name>)
##
## Template name could be any of the available templates in
## ``templates/mustache/*.tpl``.
## Requires python package ``pystache``.
## Examples:
## - mustache("markdown")
## - mustache("restructuredtext")
##
## - makotemplate(<template_name>)
##
## Template name could be any of the available templates in
## ``templates/mako/*.tpl``.
## Requires python package ``mako``.
## Examples:
## - makotemplate("restructuredtext")
##
output_engine = rest_py
# output_engine = mustache("restructuredtext")
# output_engine = mustache("markdown")
# output_engine = makotemplate("restructuredtext")
## ``include_merge`` is a boolean
##
## This option tells git-log whether to include merge commits in the log.
## The default is to include them.
include_merge = True
## ``log_encoding`` is a string identifier
##
## This option tells gitchangelog what encoding is outputed by ``git log``.
## The default is to be clever about it: it checks ``git config`` for
## ``i18n.logOutputEncoding``, and if not found will default to git's own
## default: ``utf-8``.
# log_encoding = 'utf-8'
## ``publish`` is a callable
##
## Sets what ``gitchangelog`` should do with the output generated by
## the output engine. ``publish`` is a callable taking one argument
## that is an interator on lines from the output engine.
##
## Some helper callable are provided:
##
## Available choices are:
##
## - stdout
##
## Outputs directly to standard output
## (This is the default)
##
## - FileInsertAtFirstRegexMatch(file, pattern, idx=lamda m: m.start())
##
## Creates a callable that will parse given file for the given
## regex pattern and will insert the output in the file.
## ``idx`` is a callable that receive the matching object and
## must return a integer index point where to insert the
## the output in the file. Default is to return the position of
## the start of the matched string.
##
## - FileRegexSubst(file, pattern, replace, flags)
##
## Apply a replace inplace in the given file. Your regex pattern must
## take care of everything and might be more complex. Check the README
## for a complete copy-pastable example.
##
# publish = FileInsertIntoFirstRegexMatch(
# "CHANGELOG.rst",
# r'/(?P<rev>[0-9]+\.[0-9]+(\.[0-9]+)?)\s+\([0-9]+-[0-9]{2}-[0-9]{2}\)\n--+\n/',
# idx=lambda m: m.start(1)
# )
# publish = stdout
publish = FileInsertAtFirstRegexMatch(
"doc/arm/changelog.rst",
r"for changes relevant to them.\n\n",
idx=lambda m: m.end(0),
)
## ``revs`` is a list of callable or a list of string
##
## callable will be called to resolve as strings and allow dynamical
## computation of these. The result will be used as revisions for
## gitchangelog (as if directly stated on the command line). This allows
## to filter exaclty which commits will be read by gitchangelog.
##
## To get a full documentation on the format of these strings, please
## refer to the ``git rev-list`` arguments. There are many examples.
##
## Using callables is especially useful, for instance, if you
## are using gitchangelog to generate incrementally your changelog.
##
## Some helpers are provided, you can use them::
##
## - FileFirstRegexMatch(file, pattern): will return a callable that will
## return the first string match for the given pattern in the given file.
## If you use named sub-patterns in your regex pattern, it'll output only
## the string matching the regex pattern named "rev".
##
## - Caret(rev): will return the rev prefixed by a "^", which is a
## way to remove the given revision and all its ancestor.
##
## Please note that if you provide a rev-list on the command line, it'll
## replace this value (which will then be ignored).
##
## If empty, then ``gitchangelog`` will act as it had to generate a full
## changelog.
##
## The default is to use all commits to make the changelog.
# revs = ["^1.0.3", ]
# revs = [
# Caret(
# FileFirstRegexMatch(
# "CHANGELOG.rst",
# r"(?P<rev>[0-9]+\.[0-9]+(\.[0-9]+)?)\s+\([0-9]+-[0-9]{2}-[0-9]{2}\)\n--+\n")),
# "HEAD"
# ]
revs = []

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,11 @@
SPDXVersion: SPDX-2.2
DataLicense: CC0-1.0
SPDXID: SPDXRef-DOCUMENT
DocumentName: gitchangelog
DocumentNamespace: https://gitlab.isc.org/isc-projects/bind9/-/tree/main/contrib/gitchangelog/
PackageName: gitchangelog
SPDXID: SPDXRef-Package-gitchangelog
PackageDownloadLocation: git+https://github.com/vaab/gitchangelog.git@95fe8d5bd171db29922b40d9d3a13dab5af094c0#src/gitchangelog
PackageOriginator: Person: Valentin Lab <valentin.lab@kalysto.org>
PackageLicenseDeclared: BSD-3-Clause

View File

@@ -0,0 +1,78 @@
ignore_regexps = [
r"^$", ## ignore commits with empty messages
]
section_regexps = [
(
"Security Fixes",
[
r"^(\[9\.[0-9]{2}(-S)?\])?\s*(\[[^]]*\]\s*)?sec:\s*(usr|pkg)\s*:\s*([^\n]*)$",
],
),
(
"New Features",
[
r"^(\[9\.[0-9]{2}(-S)?\])?\s*(\[[^]]*\]\s*)?new:\s*(usr|pkg)\s*:\s*([^\n]*)$",
],
),
(
"Removed Features",
[
r"^(\[9\.[0-9]{2}(-S)?\])?\s*(\[[^]]*\]\s*)?rem:\s*(usr|pkg)\s*:\s*([^\n]*)$",
],
),
(
"Feature Changes",
[
r"^(\[9\.[0-9]{2}(-S)?\])?\s*(\[[^]]*\]\s*)?chg:\s*(usr|pkg)\s*:\s*([^\n]*)$",
],
),
(
"Bug Fixes",
[
r"^(\[9\.[0-9]{2}(-S)?\])?\s*(\[[^]]*\]\s*)?fix:\s*(usr|pkg)\s*:\s*([^\n]*)$",
],
),
]
body_process = (
ReSub(r"\n*See merge request isc-private/bind9!\d+", r"")
| ReSub(r"https://gitlab.isc.org/isc-projects/bind9/-/issues/", r"#")
| ReSub(r"https://gitlab.isc.org/isc-projects/bind9/-/merge_requests/", r"!")
| ReSub(
r"\n*(Closes|Fixes|Related|See):?\s*(isc-projects/bind9)?((#|!)\d+)",
r" :gl:`\3`",
)
| ReSub(r"\n*Backport of [^\n]+", r"")
| ReSub(r"\n*(Replaces|Supercedes)[^\n]+", r"")
| ReSub(r"\n*Merge branch '[^']+' into [^\n]+", r"")
| ReSub(r"\n*isc-private/bind9", r"")
| ReSub(r"\n*See merge request isc-projects/bind9(!\d+)", r" :gl:`\1`")
| Wrap(regexp="\n\n", separator="\n\n")
| strip
)
subject_process = (
strip
| ReSub(
r"^(\[9\.[0-9]{2}(-S)?\])?\s*(\[[^]]*\]\s*)?(chg|fix|new|rem|sec):\s*((usr|pkg)\s*:\s*)?([^\n]*)$",
r"\3\7",
)
| SetIfEmpty("No commit message.")
| ucfirst
| final_dot
)
tag_filter_regexp = r"^v9\.[0-9]+\.[0-9]+(-S[0-9]+)?$"
unreleased_version_label = "(-dev)"
include_commit_sha = False
output_engine = rest_py
include_merge = True
publish = stdout
revs = []

View File

@@ -43,15 +43,14 @@ def lines_containing(lines, string):
changes_issue_or_mr_id_regex = re.compile(rb"\[(GL [#!]|RT #)[0-9]+\]")
relnotes_issue_or_mr_id_regex = re.compile(rb":gl:`[#!][0-9]+`")
release_notes_regex = re.compile(r"doc/(arm|notes)/notes-.*\.(rst|xml)")
rdata_regex = re.compile(r"lib/dns/rdata/")
mr_issue_link_regex = re.compile(r"^(Closes|Fixes):?\s*[^\n]*#[0-9]+", re.MULTILINE)
modified_files = danger.git.modified_files
affected_files = (
danger.git.modified_files + danger.git.created_files + danger.git.deleted_files
)
mr_title = danger.gitlab.mr.title
mr_title = re.sub(r"^Draft:\s*", r"", danger.gitlab.mr.title)
mr_labels = danger.gitlab.mr.labels
source_branch = danger.gitlab.mr.source_branch
target_branch = danger.gitlab.mr.target_branch
@@ -69,14 +68,25 @@ mr = proj.mergerequests.get(os.environ["CI_MERGE_REQUEST_IID"])
# MERGE REQUEST INFORMATION
###############################################################################
#
# - WARN if the merge request's title looks like an auto-generated one.
# - FAIL if the MR title doesn't have the expected format
#
# - FAIL if the MR title doesn't contain changelog action
if mr_title.replace("Draft: ", "").startswith('Resolve "'):
warn(
f"This merge request's title (`{mr_title}`) looks like an "
"auto-generated one. Please change it so that it accurately "
"describes the changes contained in this merge request."
)
MR_TITLE_RE = re.compile(
r"^(\[9\.[0-9]{2}(-S)?\])?\s*(\[[^]]*\]\s*)?((chg|fix|new|rem|sec):)?\s*((dev|usr|pkg|doc|test)\s*:)?\s*([^\n]*)$",
)
mr_title_match = MR_TITLE_RE.match(mr_title)
mr_title_cve = mr_title_match.group(3) if mr_title_match else None
mr_title_action = mr_title_match.group(5) if mr_title_match else None
mr_title_audience = mr_title_match.group(7) if mr_title_match else None
if not mr_title_match:
fail("Merge request's title is invalid. Fix it or contact QA for assistance.")
else:
if mr_title_action is None:
fail(
"Add one of `chg:`|`fix:`|`new:`|`rem:`|`sec:` to the MR title to categorize this change."
)
###############################################################################
# BRANCH NAME
@@ -106,6 +116,8 @@ if match:
# * The subject line starts with a prohibited word indicating a work in
# progress commit (e.g. "WIP").
#
# * The subject line contains a changelog action.
#
# * The subject line contains a trailing dot.
#
# * There is no empty line between the subject line and the log message.
@@ -138,7 +150,7 @@ fixup_error_logged = False
for commit in danger.git.commits:
message_lines = commit.message.splitlines()
subject = message_lines[0]
is_merge = subject.startswith("Merge branch ")
is_merge = len(commit.parents) >= 2
is_fixup = (
subject.startswith("fixup!")
or subject.startswith("amend!")
@@ -156,6 +168,12 @@ for commit in danger.git.commits:
f"Prohibited keyword `{match.groups()[0]}` detected "
f"at the start of a subject line in commit {commit.sha}."
)
match = MR_TITLE_RE.match(subject)
if match and match.group(5) is not None and not is_merge:
fail(
f"Changelog action `{match.group(5)}` detected in non-merge"
f"commit {commit.sha}. Use MR title instead."
)
if len(subject) > 72 and not is_merge and not is_fixup:
warn(
f"Subject line for commit {commit.sha} is too long: "
@@ -314,51 +332,30 @@ elif not approved:
)
###############################################################################
# 'CHANGES' FILE
# Changelog entries
###############################################################################
#
# FAIL if any of the following is true:
#
# * The merge request does not update the CHANGES file, but it does not have
# the "No CHANGES" label set. (This attempts to ensure that the author of
# the MR did not forget about adding a CHANGES entry.)
# * The merge request title doesn't produce a changelog entry, but it does not have
# the "No CHANGES" label set.
#
# * The merge request updates the CHANGES file, but it has the "No CHANGES"
# label set. (This attempts to ensure that the "No CHANGES" label is used in
# a sane way.)
#
# * The merge request adds any placeholder entries to the CHANGES file, but it
# does not target the "main" branch.
#
# * The merge request adds a new CHANGES entry that is not a placeholder and
# does not contain any GitLab/RT issue/MR identifiers.
# * The merge request title produces a changelog entry, but it has the "No CHANGES"
# label set.
changes_modified = "CHANGES" in modified_files or "CHANGES.SE" in modified_files
changes_modified = mr_title_audience in ["usr", "pkg", "dev"]
no_changes_label_set = "No CHANGES" in mr_labels
if not changes_modified and not no_changes_label_set:
fail(
"This merge request does not modify `CHANGES`. "
"Add a `CHANGES` entry or set the *No CHANGES* label."
"MR title doesn't produce a new changelog entry. "
"Add a `dev:`|`usr:`|`pkg:` audience to MR title or set the *No CHANGES* label."
)
if changes_modified and no_changes_label_set:
fail(
"This merge request modifies `CHANGES`. "
"Revert `CHANGES` modifications or unset the *No Changes* label."
"MR title produces a new changelog entry. Unset the *No Changes* label "
"or remove the `dev:`|`usr:`|`pkg:` audience from the MR title."
)
changes_added_lines = added_lines(target_branch, ["CHANGES", "CHANGES.SE"])
placeholders_added = lines_containing(changes_added_lines, "[placeholder]")
identifiers_found = filter(changes_issue_or_mr_id_regex.search, changes_added_lines)
if changes_added_lines:
if placeholders_added:
if target_branch != "main":
fail(
"This MR adds at least one placeholder entry to `CHANGES`. "
"It should be targeting the `main` branch."
)
elif not any(identifiers_found):
fail("No valid issue/MR identifiers found in added `CHANGES` entries.")
###############################################################################
# RELEASE NOTES
###############################################################################
@@ -388,23 +385,23 @@ if changes_added_lines:
# label set. (Except for trivial changes, all merge requests which may
# be of interest to customers should include a release note.)
#
# * This merge request updates release notes, but no GitLab/RT issue/MR
# identifiers are found in the lines added to the release notes by this
# MR.
# * This merge request updates release notes, but no GitLab issue was
# linked with the `Closes` or `Fixes` keyword in the MR description.
release_notes_regex = re.compile(r"doc/(arm|notes)/notes-.*\.(rst|xml)")
release_notes_changed = list(filter(release_notes_regex.match, affected_files))
release_notes_changed = mr_title_audience in ["usr", "pkg"]
release_notes_label_set = "Release Notes" in mr_labels
if not release_notes_changed:
if release_notes_label_set:
fail(
"This merge request has the *Release Notes* label set. "
"Update release notes or unset the *Release Notes* label."
"Update the MR title to include `usr:`|`pkg:` audience or "
"unset the *Release Notes* label."
)
elif "Customer" in mr_labels:
warn(
"This merge request has the *Customer* label set. "
"Update release notes unless the changes introduced are trivial."
"Update the MR title to include `usr:`|`pkg:` audience "
"unless the changes introduced are trivial."
)
rdata_types_add_rm = list(
filter(rdata_regex.match, danger.git.created_files + danger.git.deleted_files)
@@ -414,12 +411,12 @@ if not release_notes_changed:
"This merge request adds new files to `lib/dns/rdata/` and/or "
"deletes existing files from that directory, which almost certainly "
"means that it adds support for a new RR type or removes support "
"for an existing one. Please add a relevant release note."
"for an existing one. Update the MR title to include `usr:` audience."
)
if release_notes_changed and not release_notes_label_set:
fail(
"This merge request modifies release notes. "
"Revert release note modifications or set the *Release Notes* label."
"The MR title produces a release note. Set the *Release Notes* label "
"or remove the `usr:`|`pkg:` audience from the MR title."
)
if (
release_notes_label_set
@@ -428,38 +425,26 @@ if (
):
fail(
"This merge request is labeled with both *Release notes* and *No CHANGES*. "
"A user-visible change should also be mentioned in the `CHANGES` file."
"A user-visible change should also be mentioned in the changelog."
)
if release_notes_changed:
modified_or_new_files = danger.git.modified_files + danger.git.created_files
release_notes_added = list(filter(release_notes_regex.match, modified_or_new_files))
notes_added_lines = added_lines(target_branch, release_notes_added)
identifiers_found = filter(relnotes_issue_or_mr_id_regex.search, notes_added_lines)
if notes_added_lines and not any(identifiers_found):
warn("No valid issue/MR identifiers found in added release notes.")
else:
notes_added_lines = []
if release_notes_changed and not mr_issue_link_regex.search(
danger.gitlab.mr.description
):
warn("No issue was linked via `Closes`|`Fixes` in the MR description.")
###############################################################################
# CVE IDENTIFIERS
###############################################################################
#
# FAIL if the merge request adds a CHANGES entry of type [security] and a CVE
# identifier is missing from either the added CHANGES entry or the added
# release note.
# WARN if the merge request title indicates a security issue, but there is no
# CVE identifier in the MR title.
if lines_containing(changes_added_lines, "[security]"):
if not lines_containing(changes_added_lines, "(CVE-20"):
fail(
"This merge request fixes a security issue. "
"Please add a CHANGES entry which includes a CVE identifier."
)
if not lines_containing(notes_added_lines, ":cve:`20"):
fail(
"This merge request fixes a security issue. "
"Please add a release note which includes a CVE identifier."
)
if mr_title_action == "sec" and (mr_title_cve is None or "CVE-20" not in mr_title_cve):
warn(
"This merge request fixes a security issue. "
"Please add `[CVE-XXXX-YYYY]` to the MR title if a CVE was issued."
)
###############################################################################
# PAIRWISE TESTING

View File

@@ -5,6 +5,7 @@ EXTRA_DIST = \
advanced.inc.rst \
build.inc.rst \
catz.inc.rst \
changelog.rst \
chapter10.rst \
chapter1.rst \
chapter2.rst \

22125
doc/arm/changelog.rst Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -37,6 +37,7 @@ BIND 9 Administrator Reference Manual
:maxdepth: 2
notes
changelog
dnssec-guide
history
general

View File

@@ -9,6 +9,8 @@
.. See the COPYRIGHT file distributed with this work for additional
.. information regarding copyright ownership.
.. _relnotes:
Release Notes
=============
@@ -21,8 +23,8 @@ BIND 9.21 is an unstable development release of BIND. This document
summarizes new features and functional changes that have been introduced
on this branch. With each development release leading up to the stable
BIND 9.22 release, this document will be updated with additional
features added and bugs fixed. Please see the CHANGES file for a more
detailed list of changes and bug fixes.
features added and bugs fixed. Please see the :ref:`changelog` file for
a more detailed list of changes and bug fixes.
Supported Platforms
-------------------

View File

@@ -1,62 +0,0 @@
#!/usr/bin/perl
#
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# SPDX-License-Identifier: MPL-2.0
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
eval 'exec /usr/bin/perl -S $0 ${1+"$@"}'
if $running_under_some_shell;
# this emulates #! processing on NIH machines.
# (remove #! line above if indigestible)
$master = 1;
eval '$'.$1.'$2;' while $ARGV[0] =~ /^([A-Za-z_0-9]+=)(.*)/ && shift;
# process any FOO=bar switches
$, = ' '; # set output field separator
$\ = "\n"; # set output record separator
$change = 0;
$status = 0;
$wasblank = 1;
line: while (<>) {
($Fld1,$Fld2,$Fld3,$Fld4) = split(' ', $_, 9999);
$change = 0 if (!$master && /^\s+--- .* ---$/);
if ($Fld1 =~ /^[1-9][0-9]*\.$/ && $Fld2 =~ /^\[.*\]$/) {
if ($change != 0 && $Fld1 >= $change) {
print 'bad change number', $Fld1;
$status = 1;
}
if ($master && $change != 0 && $Fld1 + 1 != $change) {
print 'bad change number', $Fld1;
$status = 1;
}
$change = $Fld1;
if (!$wasblank) {
print 'missing blank line before change', $Fld1;
$status = 1;
}
}
if (/^\s+--- .* ---$/) {
if (!$wasblank) {
print 'missing blank line before release marker for', $Fld2;
$status = 1;
}
}
if ($Fld1 eq "") {
$wasblank = 1;
} else {
$wasblank = 0;
}
}
exit $status;

View File

@@ -1,26 +0,0 @@
#!/bin/sh
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# SPDX-License-Identifier: MPL-2.0
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
expand "$1" \
| awk -v file="$1" 'length > 80 {
if (logged == 0) {
print file ": Line Too Long"
logged = 1
}
print
}
END {
if (logged == 1) {
exit(1)
}
}'

View File

@@ -1,92 +0,0 @@
#!/usr/bin/perl
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# SPDX-License-Identifier: MPL-2.0
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
# Given two CHANGES files, list [bug] entries present in the
# first one but not in the second one.
#
use FileHandle;
# $/ = "";
# Read the CHANGES file $fn and return a hash of change
# texts and categories indexed by change number.
sub readfile {
my ($fn) = @_;
my $fh = new FileHandle($fn, "r")
or die "open: $fn: $!";
my $changes = { };
my ($changeid, $category);
$changeid = "none";
$category = "none";
while (<$fh>) {
if (m/^\s*(\d+)\.\s+\[(\w+)\]/) {
$changeid = $1;
$category = $2;
# print "*** $1 $2\n";
} elsif (m/---.* released ---/) {
$changeid = "none";
$category = "none";
next;
} elsif (m/^# /) {
$changeid = "none";
$category = "none";
next;
}
if ($changeid eq "none") {
next;
}
$changes->{$changeid}->{text} .= $_;
$changes->{$changeid}->{category} = $category;
}
return $changes;
}
@ARGV == 2 || @ARGV == 3 or die "usage: $0 changes-file-1 changes-file-2\n";
my $c1 = readfile($ARGV[0]);
my $c2 = readfile($ARGV[1]);
if (@ARGV == 3) {
$c3 = readfile($ARGV[2]);
} else {
my $c3 = { };
}
my $msg = "";
foreach my $c (sort {$a <=> $b} keys %$c1) {
my $category = $c1->{$c}->{category};
my $text = $c1->{$c}->{text};
if ($category ne "func" && $category ne "placeholder" &&
!exists($c2->{$c}) && !exists($c3->{$c})) {
if ($msg ne "MISSING\n") {
$msg = "MISSING\n";
print $msg;
}
print $c1->{$c}->{text};
}
if (exists($c2->{$c}) && $category ne "placeholder" &&
$c2->{$c}->{text} ne $text && !exists($c3->{$c})) {
if ($msg ne "TEXT\n") {
$msg = "TEXT\n";
print $msg;
}
print $c2->{$c}->{text};
print $c1->{$c}->{text};
}
}

View File

@@ -1,78 +0,0 @@
#!/usr/bin/perl
#
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# SPDX-License-Identifier: MPL-2.0
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
#
# Given two CHANGES files, list [bug] entries present in the
# first one but not in the second one.
#
use FileHandle;
# $/ = "";
# Read the CHANGES file $fn and return a hash of change
# texts and categories indexed by change number.
sub readfile {
my ($fn) = @_;
my $fh = new FileHandle($fn, "r")
or die "open: $fn: $!";
my $changes = { };
my ($changeid, $category);
$changeid = "none";
$category = "none";
while (<$fh>) {
if (m/^\s*(\d+)\.\s+\[(\w+)\]/) {
$changeid = $1;
$category = $2;
# print "*** $1 $2\n";
} elsif (m/---.* released ---/) {
$changeid = "none";
$category = "none";
next;
} elsif (m/^# /) {
$changeid = "none";
$category = "none";
next;
}
if ($changeid eq "none") {
next;
}
$changeid =~ s/\.$//;
$changes->{$changeid}->{text} .= $_;
$changes->{$changeid}->{category} = $category;
}
return $changes;
}
@ARGV == 2 || @ARGV == 3 or die "usage: $0 changes-file-1 changes-file-2\n";
my $c1 = readfile($ARGV[0]);
my $c2 = readfile($ARGV[1]);
if (@ARGV == 3) {
$c3 = readfile($ARGV[2]);
} else {
my $c3 = { };
}
foreach my $c (sort {$a <=> $b} keys %$c1) {
my $category = $c1->{$c}->{category};
my $text = $c1->{$c}->{text};
if ($category eq "func" && !exists($c2->{$c}) && !exists($c3->{$c})) {
print $c1->{$c}->{text};
}
}

View File

@@ -1,35 +0,0 @@
#!/bin/sh
#
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# SPDX-License-Identifier: MPL-2.0
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
expand ${1} \
| sed \
-e 's/^\([1-9][0-9][0-9][0-9][0-9][0-9]\.\) */\1 /' \
-e 's/^\([1-9][0-9][0-9][0-9][0-9]\.\) */\1 /' \
-e 's/^\([1-9][0-9][0-9][0-9]\.\) */\1 /' \
-e 's/^\( [1-9][0-9][0-9]\.\) */\1 /' \
-e 's/^\( [1-9][0-9]\.\) */\1 /' \
-e 's/^\( [1-9]\.\) */\1 /' \
-e 's/\( \[.\]\) */\1 /' \
-e 's/\( \[..\]\) */\1 /' \
-e 's/\( \[...\]\) */\1 /' \
-e 's/\( \[....\]\) */\1 /' \
-e 's/\( \[.....\]\) */\1 /' \
-e 's/\( \[......\]\) */\1 /' \
-e 's/\( \[.......\]\) */\1 /' \
-e 's/\( \[........\]\) */\1 /' \
-e 's/\( \[.........\]\) */\1 /' \
-e 's/\( \[..........\]\) */\1 /' \
-e 's/\( \[...........\]\) */\1 /' \
-e 's/\( \[............\]\) */\1 /' \
-e 's/[ ]*$//' \
| unexpand