codecov[bot]: # [Codecov](https://codecov.io/gh/pypa/twine/pull/405?src=pr&el=h1) Report
> Merging [#405](https://codecov.io/gh/pypa/twine/pull/405?src=pr&el=desc) into [master](https://codecov.io/gh/pypa/twine/commit/48adf29c7ec1ca1904a5b080afa9b317e5962b9e?src=pr&el=desc) will **increase** coverage by `1.89%`.
> The diff coverage is `n/a`.

[![Impacted file tree graph](https://codecov.io/gh/pypa/twine/pull/405/graphs/tree.svg?width=650&token=NrvN4iFbj6&height=150&src=pr)](https://codecov.io/gh/pypa/twine/pull/405?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master     #405      +/-   ##
==========================================
+ Coverage   76.09%   77.99%   +1.89%     
==========================================
  Files          14       14              
  Lines         728      727       -1     
  Branches      104      104              
==========================================
+ Hits          554      567      +13     
+ Misses        146      128      -18     
- Partials       28       32       +4
```


| [Impacted Files](https://codecov.io/gh/pypa/twine/pull/405?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [twine/commands/upload.py](https://codecov.io/gh/pypa/twine/pull/405/diff?src=pr&el=tree#diff-dHdpbmUvY29tbWFuZHMvdXBsb2FkLnB5) | `75% <ø> (+21.93%)` | :arrow_up: |
| [twine/wininst.py](https://codecov.io/gh/pypa/twine/pull/405/diff?src=pr&el=tree#diff-dHdpbmUvd2luaW5zdC5weQ==) | `31.57% <0%> (ø)` | :arrow_up: |
| [twine/utils.py](https://codecov.io/gh/pypa/twine/pull/405/diff?src=pr&el=tree#diff-dHdpbmUvdXRpbHMucHk=) | `83.6% <0%> (+1.63%)` | :arrow_up: |
| [twine/settings.py](https://codecov.io/gh/pypa/twine/pull/405/diff?src=pr&el=tree#diff-dHdpbmUvc2V0dGluZ3MucHk=) | `93.1% <0%> (+1.72%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/pypa/twine/pull/405?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/pypa/twine/pull/405?src=pr&el=footer). Last update [48adf29...dfc523e](https://codecov.io/gh/pypa/twine/pull/405?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

diff --git a/docs/changelog.rst b/docs/changelog.rst
index 4670170..477cae9 100644
--- a/docs/changelog.rst
+++ b/docs/changelog.rst
@@ -4,6 +4,7 @@
 Changelog
 =========
 
+* :bug:`404` Fix regression with upload exit code
 * :release:`1.12.0 <2018-09-24>`
 * :feature:`395 major` Add ``twine check`` command to check long description
 * :feature:`392 major` Drop support for Python 3.3
diff --git a/twine/commands/upload.py b/twine/commands/upload.py
index 01eea0f..b4d3f93 100644
--- a/twine/commands/upload.py
+++ b/twine/commands/upload.py
@@ -104,8 +104,6 @@ def upload(upload_settings, dists):
     # pool.
     repository.close()
 
-    return True
-
 
 def main(args):
     parser = argparse.ArgumentParser(prog="twine upload")

Release 1.12.0 Causes exit 1 on install
Release 1.12.0 causes the following error on pip install but previous releases have been ok. 


   Complete output from command python setup.py egg_info:

        No working compiler found, or bogus compiler options passed to
        the compiler from Python's standard "distutils" module.  See
        the error messages above.  Likely, the problem is not related
        to CFFI but generic to the setup.py of any Python package that
        tries to compile C code.  (Hints: on OS/X 10.8, for errors about
        -mno-fused-madd see http://stackoverflow.com/questions/22313407/
        Otherwise, see https://wiki.python.org/moin/CompLangPython or
        the IRC channel #python on irc.freenode.net.)
    Traceback (most recent call last):
      File "/usr/local/lib/python3.7/site-packages/setuptools/sandbox.py", line 154, in save_modules
        yield saved
      File "/usr/local/lib/python3.7/site-packages/setuptools/sandbox.py", line 195, in setup_context
        yield
      File "/usr/local/lib/python3.7/site-packages/setuptools/sandbox.py", line 250, in run_setup
        _execfile(setup_script, ns)
      File "/usr/local/lib/python3.7/site-packages/setuptools/sandbox.py", line 45, in _execfile
        exec(code, globals, locals)
      File "/tmp/easy_install-wz5r8c5j/cffi-1.11.5/setup.py", line 142, in <module>
      File "/tmp/easy_install-wz5r8c5j/cffi-1.11.5/setup.py", line 77, in ask_supports_thread
      File "/tmp/easy_install-wz5r8c5j/cffi-1.11.5/setup.py", line 59, in no_working_compiler_found
        cmdclass={
    SystemExit: 1
diff --git a/tests/test_upload.py b/tests/test_upload.py
index 181f613..870a26e 100644
--- a/tests/test_upload.py
+++ b/tests/test_upload.py
@@ -28,6 +28,40 @@ import helpers
 WHEEL_FIXTURE = 'tests/fixtures/twine-1.5.0-py2.py3-none-any.whl'
 
 
+def test_successful_upload(tmpdir):
+    pypirc = os.path.join(str(tmpdir), ".pypirc")
+    dists = ["tests/fixtures/twine-1.5.0-py2.py3-none-any.whl"]
+
+    with open(pypirc, "w") as fp:
+        fp.write(textwrap.dedent("""
+            [pypi]
+            username:foo
+            password:bar
+        """))
+
+    upload_settings = settings.Settings(
+        repository_name="pypi", sign=None, identity=None, username=None,
+        password=None, comment=None, cert=None, client_cert=None,
+        sign_with=None, config_file=pypirc, skip_existing=False,
+        repository_url=None, verbose=False,
+    )
+
+    stub_response = pretend.stub(
+        is_redirect=False, status_code=201, raise_for_status=lambda: None
+    )
+    stub_repository = pretend.stub(
+        upload=lambda package: stub_response, close=lambda: None
+    )
+
+    upload_settings.create_repository = lambda: stub_repository
+
+    result = upload.upload(upload_settings, dists)
+
+    # Raising an exception or returning anything truthy would mean that the
+    # upload has failed
+    assert result is None
+
+
 def test_get_config_old_format(tmpdir):
     pypirc = os.path.join(str(tmpdir), ".pypirc")
 
@@ -77,18 +111,18 @@ def test_deprecated_repo(tmpdir):
 
         upload.upload(upload_settings, dists)
 
-        assert err.args[0] == (
-            "You're trying to upload to the legacy PyPI site "
-            "'https://pypi.python.org/pypi/'. "
-            "Uploading to those sites is deprecated. \n "
-            "The new sites are pypi.org and test.pypi.org. Try using "
-            "https://upload.pypi.org/legacy/ "
-            "(or https://test.pypi.org/legacy/) "
-            "to upload your packages instead. "
-            "These are the default URLs for Twine now. \n "
-            "More at "
-            "https://packaging.python.org/guides/migrating-to-pypi-org/ ."
-            )
+    assert err.value.args[0] == (
+        "You're trying to upload to the legacy PyPI site "
+        "'https://pypi.python.org/pypi/'. "
+        "Uploading to those sites is deprecated. \n "
+        "The new sites are pypi.org and test.pypi.org. Try using "
+        "https://upload.pypi.org/legacy/ "
+        "(or https://test.pypi.org/legacy/) "
+        "to upload your packages instead. "
+        "These are the default URLs for Twine now. \n "
+        "More at "
+        "https://packaging.python.org/guides/migrating-to-pypi-org/ ."
+    )
 
 
 def test_skip_existing_skips_files_already_on_PyPI(monkeypatch):

pip install -e .[keyring]
parse_log_pytest
requirements.txt
pytest coverage pretend readme_renderer doc8 tox tox-pipenv
apt-get update apt-get install -y gcc
3.6
requirements/base.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
attrs==22.2.0
bleach==4.1.0
certifi==2021.5.30
cffi==1.15.1
charset-normalizer==2.0.12
coverage==6.2
cryptography==40.0.2
distlib==0.3.9
doc8==0.11.2
docutils==0.18.1
filelock==3.4.1
idna==3.10
importlib-metadata==4.8.3
importlib-resources==5.4.0
iniconfig==1.1.1
jeepney==0.7.1
keyring==23.4.1
packaging==21.3
pbr==6.1.1
pipenv==2022.4.8
pkginfo==1.10.0
platformdirs==2.4.0
pluggy==1.0.0
pretend==1.0.9
py==1.11.0
pycparser==2.21
Pygments==2.14.0
pyparsing==3.1.4
pytest==7.0.1
readme-renderer==34.0
requests==2.27.1
requests-toolbelt==1.0.0
restructuredtext-lint==1.4.0
SecretStorage==3.3.3
six==1.17.0
stevedore==3.5.2
toml==0.10.2
tomli==1.2.3
tox==3.28.0
tox-pipenv==1.10.1
tqdm==4.64.1
-e git+https://github.com/pypa/twine.git@48adf29c7ec1ca1904a5b080afa9b317e5962b9e#egg=twine
typing_extensions==4.1.1
urllib3==1.26.20
virtualenv==20.17.1
virtualenv-clone==0.5.7
webencodings==0.5.1
zipp==3.6.0

name: twine
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2021.5.30=py36h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.3=he6710b0_2
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - pip=21.2.2=py36h06a4308_0
  - python=3.6.13=h12debd9_1
  - readline=8.2=h5eee18b_0
  - setuptools=58.0.4=py36h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.37.1=pyhd3eb1b0_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - attrs==22.2.0
      - bleach==4.1.0
      - cffi==1.15.1
      - charset-normalizer==2.0.12
      - coverage==6.2
      - cryptography==40.0.2
      - distlib==0.3.9
      - doc8==0.11.2
      - docutils==0.18.1
      - filelock==3.4.1
      - idna==3.10
      - importlib-metadata==4.8.3
      - importlib-resources==5.4.0
      - iniconfig==1.1.1
      - jeepney==0.7.1
      - keyring==23.4.1
      - packaging==21.3
      - pbr==6.1.1
      - pipenv==2022.4.8
      - pkginfo==1.10.0
      - platformdirs==2.4.0
      - pluggy==1.0.0
      - pretend==1.0.9
      - py==1.11.0
      - pycparser==2.21
      - pygments==2.14.0
      - pyparsing==3.1.4
      - pytest==7.0.1
      - readme-renderer==34.0
      - requests==2.27.1
      - requests-toolbelt==1.0.0
      - restructuredtext-lint==1.4.0
      - secretstorage==3.3.3
      - six==1.17.0
      - stevedore==3.5.2
      - toml==0.10.2
      - tomli==1.2.3
      - tox==3.28.0
      - tox-pipenv==1.10.1
      - tqdm==4.64.1
      - typing-extensions==4.1.1
      - urllib3==1.26.20
      - virtualenv==20.17.1
      - virtualenv-clone==0.5.7
      - webencodings==0.5.1
      - zipp==3.6.0
prefix: /opt/conda/envs/twine

tests/test_upload.py::test_successful_upload
tests/test_upload.py::test_get_config_old_format tests/test_upload.py::test_deprecated_repo tests/test_upload.py::test_skip_existing_skips_files_already_on_PyPI tests/test_upload.py::test_skip_existing_skips_files_already_on_pypiserver tests/test_upload.py::test_skip_existing_skips_files_already_on_artifactory tests/test_upload.py::test_skip_upload_respects_skip_existing tests/test_upload.py::test_values_from_env
docs/changelog.rst twine/commands/upload.py
docs/changelog.rst twine/commands/upload.py