Skip to content

Fix publish --build prompt behavior in non-interactive mode#10769

Merged
radoering merged 6 commits intopython-poetry:mainfrom
SergioChan:fix-10760-no-interaction-build-prompt
Mar 28, 2026
Merged

Fix publish --build prompt behavior in non-interactive mode#10769
radoering merged 6 commits intopython-poetry:mainfrom
SergioChan:fix-10760-no-interaction-build-prompt

Conversation

@SergioChan
Copy link
Copy Markdown
Contributor

@SergioChan SergioChan commented Mar 11, 2026

Pull Request Check List

Resolves: #10760

  • Added tests for changed code.
  • Updated documentation for changed code.

Summary

  • Respect --no-interaction in poetry publish --build when dist/ already contains artifacts.
  • In non-interactive mode, skip the confirmation prompt and proceed with the build/publish flow.
  • Keep interactive behavior unchanged (still asks before rebuilding existing artifacts).

Testing

  • poetry run pytest tests/console/commands/test_publish.py -q
    • Added coverage for pre-existing dist/ artifacts under non-interactive execution.
    • Existing prompt behavior remains covered for interactive mode.

Summary by Sourcery

Tests:

  • Add regression test ensuring poetry publish --build --no-interaction skips the confirmation prompt and still performs the build/publish flow when artifacts already exist in dist/.

@sourcery-ai
Copy link
Copy Markdown

sourcery-ai bot commented Mar 11, 2026

Reviewer's Guide

Adjusts the publish command to respect non-interactive mode when build artifacts already exist, and adds a regression test ensuring the confirmation prompt is skipped while the build/publish flow still runs.

Sequence diagram for non-interactive publish --build with existing artifacts

sequenceDiagram
    actor User
    participant CLI
    participant PublishCommand
    participant IO
    participant Publisher

    User->>CLI: poetry publish --build --no-interaction
    CLI->>PublishCommand: handle()
    PublishCommand->>PublishCommand: option("build") == True
    PublishCommand->>Publisher: check files
    Publisher-->>PublishCommand: files list (non empty)
    PublishCommand->>IO: is_interactive()
    IO-->>PublishCommand: False
    Note over PublishCommand: Condition publisher.files and IO.is_interactive() fails
    PublishCommand->>Publisher: build()
    Publisher-->>PublishCommand: build result
    PublishCommand->>Publisher: publish()
    Publisher-->>PublishCommand: publish result
    PublishCommand-->>CLI: exit code 0
    CLI-->>User: Command completed without prompt
Loading

Flow diagram for publish --build prompt and abort logic

flowchart TD
    A[Start handle] --> B{option build is True}
    B -- No --> Z[Proceed with publish without build]
    B -- Yes --> C{publisher.files is non empty}
    C -- No --> D[Run build]
    D --> E[Run publish]
    E --> F[Return success]
    C -- Yes --> G{IO is_interactive is True}
    G -- No --> D
    G -- Yes --> H{confirm Build anyway}
    H -- Yes --> D
    H -- No --> I[Print Aborted]
    I --> J[Return failure]
    Z --> E
Loading

File-Level Changes

Change Details Files
Gate the existing rebuild confirmation prompt behind an interactivity check so non-interactive runs skip the prompt and proceed.
  • Wrap the existing publisher.files confirmation logic in an io.is_interactive() check.
  • Preserve the existing confirmation and abort behavior for interactive sessions when artifacts already exist in dist/.
  • Ensure non-interactive runs with --build no longer attempt to prompt and thus proceed with build/publish flow.
src/poetry/console/commands/publish.py
Add a test that verifies publish --build --no-interaction skips the confirmation prompt when artifacts already exist and still triggers build and publish.
  • Patch Publisher.files to simulate pre-existing artifacts in dist/.
  • Mock PublishCommand.confirm, PublishCommand.call, and Publisher.publish to assert behavior in non-interactive mode.
  • Execute publish --build --no-interaction --dry-run and assert exit code, that confirm is never called, build is invoked once with the expected args, and publish is called once.
tests/console/commands/test_publish.py

Assessment against linked issues

Issue Objective Addressed Explanation
#10760 Ensure poetry publish with --no-interaction does not prompt for confirmation when build artifacts already exist in dist/, so that CI/non-interactive environments are not blocked.
#10760 In non-interactive mode with --no-interaction, automatically proceed with the build/publish flow (equivalent to answering 'yes' to the prompt) even when dist/ already contains artifacts, while preserving the existing interactive behavior.

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey - I've found 1 issue

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="tests/console/commands/test_publish.py" line_range="221-230" />
<code_context>
     assert "- Uploading simple_project-1.2.3-py2.py3-none-any.whl" in error
+
+
+def test_publish_build_no_interaction_skips_confirmation(
+    app_tester: ApplicationTester, mocker: MockerFixture
+) -> None:
+    mocker.patch(
+        "poetry.publishing.publisher.Publisher.files",
+        new_callable=PropertyMock,
+        return_value=[Path("dist/simple_project-1.2.3-py2.py3-none-any.whl")],
+    )
+    confirm = mocker.patch("poetry.console.commands.publish.PublishCommand.confirm")
+    command_call = mocker.patch("poetry.console.commands.publish.PublishCommand.call")
+    publisher_publish = mocker.patch("poetry.publishing.Publisher.publish")
+
+    exit_code = app_tester.execute("publish --build --no-interaction --dry-run")
+
+    assert exit_code == 0
+    confirm.assert_not_called()
+    command_call.assert_called_once_with("build", args="--output dist")
+    assert publisher_publish.call_count == 1
</code_context>
<issue_to_address>
**suggestion (testing):** Also assert that the confirmation prompt text is not present in the command output

To better cover the user-facing behavior, please also assert that the confirmation prompt text (e.g. "Build anyway?") does not appear in stdout/stderr when running with `--no-interaction`, by capturing the `app_tester` output as done in other tests.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@SergioChan
Copy link
Copy Markdown
Contributor Author

Addressed in 8614fbc.

  • Extended test_publish_build_no_interaction_skips_confirmation to capture command output/error.
  • Added assertions that prompt text ("Build anyway?") does not appear in either stream under --no-interaction.

Targeted validation:

  • poetry run pytest tests/console/commands/test_publish.py -k "test_publish_build_no_interaction_skips_confirmation"

@dimbleby
Copy link
Copy Markdown
Contributor

dimbleby commented Mar 14, 2026

What's the difference between this and #10768?

@SergioChan
Copy link
Copy Markdown
Contributor Author

Great question.

#10769 is effectively a follow-up/superseding version of #10768.

The code path fix is the same, but #10769 also includes the additional regression coverage around user-visible output (explicitly asserting the confirmation prompt text does not appear under --no-interaction).

To avoid split discussion, I’ll close #10768 and keep #10769 as the single active PR unless you’d prefer the opposite.

@SergioChan SergioChan force-pushed the fix-10760-no-interaction-build-prompt branch from 8614fbc to e34c55a Compare March 21, 2026 12:04
@SergioChan
Copy link
Copy Markdown
Contributor Author

Rebased this branch on the latest main to clear the behind state.

Validation in this environment:

  • python -m pytest tests/console/commands/test_publish.py -k "build and no_interaction" -q (cannot run here: ModuleNotFoundError: poetry.config before tests execute)
  • python -m compileall src/poetry/console/commands/publish.py tests/console/commands/test_publish.py ?

No functional changes beyond the rebase.

@SergioChan
Copy link
Copy Markdown
Contributor Author

Pushed follow-up commit 2ef46346 to address the suggestion about non-interactive behavior when dist/ already contains files.

What changed

  • Keep the existing interactive confirmation (Build anyway?) unchanged.
  • In non-interactive mode, skip the prompt and emit a warning that existing distribution files were found before continuing with build/publish.
  • Extended test_publish_build_no_interaction_skips_confirmation to assert the warning text is emitted.

Validation

  • PYTHONPATH=src python -m pytest tests/console/commands/test_publish.py -k "no_interaction_skips_confirmation" -q (pass)

@SergioChan
Copy link
Copy Markdown
Contributor Author

Quick follow-up on the red CI:\n\n- The only failing check in the latest run is Windows (Python 3.12) / pytest, with a single failure in ests/utils/env/test_env.py::test_call_does_not_block_on_full_pipe[sys.stderr].\n- I tried to rerun failed jobs, but GitHub rejected it from my account (Must have admin rights to Repository).\n\nI did run focused local validation on this branch:\n- python -m pytest tests/console/commands/test_publish.py::test_publish_build_no_interaction_skips_confirmation -vv ✅\n- python -m pytest tests/console/commands/test_publish.py::test_publish_dist_dir_and_build_options -vv ✅ (3 cases)\n- python -m pytest tests/utils/env/test_env.py::test_call_does_not_block_on_full_pipe[sys.stderr] -vv ✅ (passes locally on Windows/Python 3.14)\n\nGiven the failure pattern (1/2964 tests), this looks potentially environment/flaky rather than a deterministic regression from this patch, but I can investigate further if you want me to chase it specifically under a 3.12 setup.

@SergioChan
Copy link
Copy Markdown
Contributor Author

Pushed follow-up commit 67202901 to address the Windows 3.12 pytest regression from the previous warning output change.

What changed

  • Kept the non-interactive warning (per review feedback) but routed it through self.line(...) (stdout) instead of self.line_error(...).
  • Updated the regression test assertion to expect the warning text in command output.

Targeted validation

  • PYTHONPATH=src python -m pytest tests/console/commands/test_publish.py::test_publish_build_no_interaction_skips_confirmation -q
  • PYTHONPATH=src python -m pytest tests/utils/env/test_env.py::test_call_does_not_block_on_full_pipe[sys.stderr] -q

Both pass locally on this branch.

@radoering radoering changed the title Fix publish --build prompt behavior in non-interactive mode Fix publish --build prompt behavior in non-interactive mode Mar 28, 2026
@radoering radoering force-pushed the fix-10760-no-interaction-build-prompt branch from 6720290 to 1a0fe5d Compare March 28, 2026 12:14
@radoering radoering merged commit 0b81284 into python-poetry:main Mar 28, 2026
54 checks passed
@dosubot
Copy link
Copy Markdown

dosubot bot commented Mar 28, 2026

Documentation Updates

3 document(s) were updated by changes in this PR:

cli
View Changes
@@ -735,6 +735,12 @@
 It can also build the package if you pass it the `--build` option.
 
 {{% note %}}
+When using `--build` with existing artifacts in the dist directory:
+- In interactive mode, Poetry prompts "There are X files ready for publishing in dist. Build anyway?" and waits for confirmation.
+- In non-interactive mode (with `--no-interaction`), Poetry displays a warning message and proceeds with the build without prompting.
+{{% /note %}}
+
+{{% note %}}
 See [Publishable Repositories]({{< relref "repositories/#publishable-repositories" >}}) for more information
 on how to configure and use publishable repositories.
 {{% /note %}}
libraries
View Changes
@@ -116,6 +116,8 @@
 
 If you want to build and publish your packages together,
 just pass the `--build` option.
+
+If you run `publish --build` and Poetry finds existing artifacts in the `dist/` directory, it will prompt you in interactive mode asking if you want to build anyway. To skip this prompt in automated environments (like CI/CD), use the `--no-interaction` flag: `poetry publish --build --no-interaction`. In non-interactive mode, Poetry will display a warning about existing artifacts but proceed with rebuilding.
 {{% /note %}}
 
 Once this is done, your library will be available to anyone.
repositories
View Changes
@@ -105,6 +105,18 @@
 poetry publish --build --repository foo-pub
 ```
 
+{{% note %}}
+
+If artifacts already exist in the `dist/` directory, Poetry will prompt before rebuilding when running in interactive mode. For CI/CD or automated workflows, add the `--no-interaction` flag to skip the prompt:
+
+```bash
+poetry publish --build --repository foo-pub --no-interaction
+```
+
+In non-interactive mode, Poetry displays a warning about existing artifacts but proceeds with the build and publish.
+
+{{% /note %}}
+
 ## Package Sources
 
 By default, if you have not configured any primary source,

How did I do? Any feedback?  Join Discord

radoering pushed a commit that referenced this pull request Mar 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

poetry publish --no-interaction still prompts when build artifacts exist in dist/, blocking CI pipelines

3 participants