Repository: twisted/towncrier

Issue:
no issue names are considered invalid when using `issue_pattern`
using `+abcdefg.feature` fails when using `issue_pattern` 
```
Error: Issue name '' does not match the configured pattern, '[A-Z]+-\d+'
```
I think it's okay to ignore these when checking for the pattern - wdyt? Maybe in the future we can add a flag to require a name and prevent non-issues (beyond my needs & scope for now)

Discussion:

Patch:
diff --git a/src/towncrier/_builder.py b/src/towncrier/_builder.py
index 878d3b1..dca09da 100644
--- a/src/towncrier/_builder.py
+++ b/src/towncrier/_builder.py
@@ -177,7 +177,11 @@ def find_fragments(
                 counter = orphan_fragment_counter[category]
                 orphan_fragment_counter[category] += 1
 
-            if config.issue_pattern and not re.fullmatch(config.issue_pattern, issue):
+            if (
+                config.issue_pattern
+                and issue  # not orphan
+                and not re.fullmatch(config.issue_pattern, issue)
+            ):
                 raise ClickException(
                     f"Issue name '{issue}' does not match the "
                     f"configured pattern, '{config.issue_pattern}'"
diff --git a/src/towncrier/newsfragments/655.bugfix.rst b/src/towncrier/newsfragments/655.bugfix.rst
new file mode 100644
index 0000000..ef5fde6
--- /dev/null
+++ b/src/towncrier/newsfragments/655.bugfix.rst
@@ -0,0 +1,1 @@
+Fixed a bug where orphan news fragments (e.g. +abc1234.feature) would fail when an `issue_pattern` is configured. Orphan news fragments are now excempt from `issue_pattern` checks.


Test patch:
diff --git a/src/towncrier/test/test_check.py b/src/towncrier/test/test_check.py
index ddf8afc..9d8c05a 100644
--- a/src/towncrier/test/test_check.py
+++ b/src/towncrier/test/test_check.py
@@ -529,14 +529,32 @@ class TestChecker(TestCase):
             "pyproject.toml",
             extra_config='issue_pattern = "\\\\d+"',
         )
-        write(
-            "foo/newsfragments/AAA.BBB.feature.md",
-            "This fragment has an invalid name (should be digits only)",
-        )
         write(
             "foo/newsfragments/123.feature",
             "This fragment has a valid name",
         )
+        write(
+            "foo/newsfragments/+abcdefg.feature",
+            "This fragment has a valid name (orphan fragment)",
+        )
+        commit("add stuff")
+
+        result = runner.invoke(towncrier_check, ["--compare-with", "main"])
+        self.assertEqual(0, result.exit_code, result.output)
+
+    @with_isolated_runner
+    def test_issue_pattern_invalid_with_suffix(self, runner):
+        """
+        Fails if an issue name goes against the configured pattern.
+        """
+        create_project(
+            "pyproject.toml",
+            extra_config='issue_pattern = "\\\\d+"',
+        )
+        write(
+            "foo/newsfragments/AAA.BBB.feature.md",
+            "This fragment has an invalid name (should be digits only)",
+        )
         commit("add stuff")
 
         result = runner.invoke(towncrier_check, ["--compare-with", "main"])
@@ -545,11 +563,25 @@ class TestChecker(TestCase):
             "Error: Issue name 'AAA.BBB' does not match the configured pattern, '\\d+'",
             result.output,
         )
-        self.assertNotIn(
-            "Error: Issue '123' does not match the configured pattern, '\\d+'",
-            result.output,
+
+    @with_isolated_runner
+    def test_issue_pattern_invalid(self, runner):
+        """
+        Fails if an issue name goes against the configured pattern.
+        """
+        create_project(
+            "pyproject.toml",
+            extra_config='issue_pattern = "\\\\d+"',
         )
-        self.assertNotIn(
-            "Error: Issue '123.feature' does not match the configured pattern, '\\d+'",
+        write(
+            "foo/newsfragments/AAA.BBB.feature",
+            "This fragment has an invalid name (should be digits only)",
+        )
+        commit("add stuff")
+
+        result = runner.invoke(towncrier_check, ["--compare-with", "main"])
+        self.assertEqual(1, result.exit_code, result.output)
+        self.assertIn(
+            "Error: Issue name 'AAA.BBB' does not match the configured pattern, '\\d+'",
             result.output,
         )