fix(py_wheel.publish): allow twine tags and args (#1271)

Also fix missing runfiles on the py_wheel.dist target.

Fixes #1130
Fixes #1270

---------

Co-authored-by: Richard Levasseur <rlevasseur@google.com>
diff --git a/docs/packaging.md b/docs/packaging.md
index 16fa00c..74d68da 100755
--- a/docs/packaging.md
+++ b/docs/packaging.md
@@ -121,7 +121,7 @@
 ## py_wheel
 
 <pre>
-py_wheel(<a href="#py_wheel-name">name</a>, <a href="#py_wheel-twine">twine</a>, <a href="#py_wheel-kwargs">kwargs</a>)
+py_wheel(<a href="#py_wheel-name">name</a>, <a href="#py_wheel-twine">twine</a>, <a href="#py_wheel-publish_args">publish_args</a>, <a href="#py_wheel-kwargs">kwargs</a>)
 </pre>
 
 Builds a Python Wheel.
@@ -201,6 +201,7 @@
 | :------------- | :------------- | :------------- |
 | <a id="py_wheel-name"></a>name |  A unique name for this target.   |  none |
 | <a id="py_wheel-twine"></a>twine |  A label of the external location of the py_library target for twine   |  <code>None</code> |
+| <a id="py_wheel-publish_args"></a>publish_args |  arguments passed to twine, e.g. ["--repository-url", "https://pypi.my.org/simple/"]. These are subject to make var expansion, as with the <code>args</code> attribute. Note that you can also pass additional args to the bazel run command as in the example above.   |  <code>[]</code> |
 | <a id="py_wheel-kwargs"></a>kwargs |  other named parameters passed to the underlying [py_wheel rule](#py_wheel_rule)   |  none |
 
 
diff --git a/python/packaging.bzl b/python/packaging.bzl
index 45d5c96..d9b9d02 100644
--- a/python/packaging.bzl
+++ b/python/packaging.bzl
@@ -50,7 +50,7 @@
         use_default_shell_env = True,
     )
     return [
-        DefaultInfo(files = depset([dir])),
+        DefaultInfo(files = depset([dir]), runfiles = ctx.runfiles([dir])),
     ]
 
 py_wheel_dist = rule(
@@ -69,7 +69,7 @@
     },
 )
 
-def py_wheel(name, twine = None, **kwargs):
+def py_wheel(name, twine = None, publish_args = [], **kwargs):
     """Builds a Python Wheel.
 
     Wheels are Python distribution format defined in https://www.python.org/dev/peps/pep-0427/.
@@ -142,6 +142,9 @@
     Args:
         name:  A unique name for this target.
         twine: A label of the external location of the py_library target for twine
+        publish_args: arguments passed to twine, e.g. ["--repository-url", "https://pypi.my.org/simple/"].
+            These are subject to make var expansion, as with the `args` attribute.
+            Note that you can also pass additional args to the bazel run command as in the example above.
         **kwargs: other named parameters passed to the underlying [py_wheel rule](#py_wheel_rule)
     """
     _dist_target = "{}.dist".format(name)
@@ -158,21 +161,22 @@
         if not twine.endswith(":pkg"):
             fail("twine label should look like @my_twine_repo//:pkg")
         twine_main = twine.replace(":pkg", ":rules_python_wheel_entry_point_twine.py")
+        twine_args = ["upload"]
+        twine_args.extend(publish_args)
+        twine_args.append("$(rootpath :{})/*".format(_dist_target))
 
         # TODO: use py_binary from //python:defs.bzl after our stardoc setup is less brittle
         # buildifier: disable=native-py
         native.py_binary(
             name = "{}.publish".format(name),
             srcs = [twine_main],
-            args = [
-                "upload",
-                "$(rootpath :{})/*".format(_dist_target),
-            ],
+            args = twine_args,
             data = [_dist_target],
             imports = ["."],
             main = twine_main,
             deps = [twine],
             visibility = kwargs.get("visibility"),
+            **copy_propagating_kwargs(kwargs)
         )
 
 py_wheel_rule = _py_wheel