Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Skip the checks if the news file was changed #337

Merged
merged 21 commits into from
Feb 13, 2022
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -163,3 +163,17 @@ Furthermore, you can add your own fragment types using:
directory = "deprecation"
name = "Deprecations"
showcontent = true


Automatic pull request checks
-----------------------------

To check if a feature branch adds at least one news fragment, run::

towncrier check

By default this compares the current branch against ``origin/master``. You can use ``--compare-with`` if the trunk is named differently::

towncrier check --compare-with origin/main

The check is automatically skipped when the main news file is modified inside the branch as this signals a release branch that is expected to not have news fragments.
5 changes: 5 additions & 0 deletions src/towncrier/check.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ def __main(comparewith, directory, config):
click.echo("{}. {}".format(n, change))
click.echo("----")

news_file = os.path.normpath(os.path.join(base_directory, config["filename"]))
if news_file in files:
click.echo("Checks SKIPPED: news file changes detected.")
sys.exit(0)

if config.get("directory"):
fragment_base_directory = os.path.abspath(config["directory"])
fragment_directory = None
Expand Down
5 changes: 5 additions & 0 deletions src/towncrier/newsfragments/337.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Make the check subcommand succeed for branches that change the news file

This should enable the ``check`` subcommand to be used as a CI lint step and
not fail when a pull request only modifies the configured news file (i.e. when
the news file is being assembled for the next release).
75 changes: 75 additions & 0 deletions src/towncrier/test/test_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# See LICENSE for details.

import os
import os.path
import sys

from twisted.trial.unittest import TestCase
Expand Down Expand Up @@ -30,6 +31,29 @@ def create_project(pyproject_path):
call(["git", "checkout", "-b", "otherbranch"])


def commit(message):
call(["git", "add", "."])
call(["git", "commit", "-m", message])


def write(path, contents):
dir = os.path.dirname(path)
if dir:
try:
os.makedirs(dir)
except OSError:
pass
with open(path, "w") as f:
f.write(contents)


def initial_commit():
hexagonrecursion marked this conversation as resolved.
Show resolved Hide resolved
call(["git", "init", "--initial-branch=main"])
call(["git", "config", "user.name", "user"])
call(["git", "config", "user.email", "user@example.com"])
commit("Initial Commit")


class TestChecker(TestCase):
maxDiff = None

Expand Down Expand Up @@ -148,3 +172,54 @@ def test_none_stdout_encoding_works(self):

self.assertEqual(0, proc.returncode)
self.assertEqual(b"", stderr)

def test_first_release(self):
hexagonrecursion marked this conversation as resolved.
Show resolved Hide resolved
"""The checks should be skipped on a branch that creates the news file.

If the checkes are not skipped in this case, towncrier check would fail
for the first release that has a changelog"""
runner = CliRunner()

with runner.isolated_filesystem():
# Arrange
write("towncrier.toml", "[tool.towncrier]")
write("newsfragments/123.feature", "Foo the bar")
initial_commit()

call(["git", "checkout", "-b", "next-resease"])
call(["towncrier", "--yes", "--version", "1.0"])
commit("Prepare a release")

# Act
result = runner.invoke(_main, ["--compare-with", "main"])

# Assert
self.assertEqual(0, result.exit_code, (result, result.output))
self.assertIn("Checks SKIPPED: news file changes detected", result.output)

def test_second_release(self):
hexagonrecursion marked this conversation as resolved.
Show resolved Hide resolved
"""The checks should be skipped on a branch that modifies the news file."""
runner = CliRunner()

with runner.isolated_filesystem():
# Arrange
write("towncrier.toml", "[tool.towncrier]")
write("newsfragments/.gitignore", "!.gitignore")
Copy link
Member

@adiroiban adiroiban Apr 7, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this ignore here?
I guess that this is a replacement for write("newsfragments/123.feature", "Foo the bar")
For me, writing an explicit news fragment is easier to read and understand what is going on here.

initial_commit()

call(["towncrier", "--yes", "--version", "1.0"])
commit("First release")

write("newsfragments/123.feature", "Foo the bar")
commit("Foo the bar")

call(["git", "checkout", "-b", "next-resease"])
call(["towncrier", "--yes", "--version", "2.0"])
commit("Second release")

# Act
result = runner.invoke(_main, ["--compare-with", "main"])

# Assert
self.assertEqual(0, result.exit_code, (result, result.output))
self.assertIn("Checks SKIPPED: news file changes detected", result.output)