Automate release workflow on Windows too.

I initially hoped to have a single Makefile or script that
worked on Linux and Windows, but was unable to make it work
without massive over-complication.

So now we have makefile targets for Linux, and powershell
scripts for Windows. Documented in the README.
diff --git a/.gitignore b/.gitignore
index 202551b..b8d794f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,11 +2,12 @@
 *.egg-info
 .coverage
 .tox/
-MANIFEST
-dist
-tags
+/MANIFEST
+/build/
+/dist/
+/sandbox/
+/tags
 virtualenv
-build
 
 # PyCharm
 .idea
diff --git a/Makefile b/Makefile
index 632d293..5368284 100644
--- a/Makefile
+++ b/Makefile
@@ -27,6 +27,7 @@
 
 $(virtualenv):
 	$(syspython) -m venv --clear $(virtualenv)
+	$(pip) install --upgrade pip
 
 venv: $(virtualenv) ## Create or clear a virtualenv
 .PHONY: venv
@@ -58,7 +59,7 @@
 	./test-release
 .PHONY: test-release
 
-upload: ## Upload our sdist and wheel
+release: ## Upload our sdist and wheel
 	$(twine) upload dist/colorama-$(version)-*
 .PHONY: release
 
diff --git a/README.rst b/README.rst
index 13d0f1a..e44933d 100644
--- a/README.rst
+++ b/README.rst
@@ -311,15 +311,43 @@
 
 Tested on CPython 2.7, 3.5, 3.6, 3.7 and 3.8.
 
-No requirements. Development requirements are captured in requirements-dev.txt.
+No requirements other than the standard library.
+Development requirements are captured in requirements-dev.txt.
 
-Tests are written using standard library ``unittest``. To run them, see
-Makefile target 'test', along with a few other handy commands.
+To create and populate a virtual environment::
+
+    ./bootstrap.ps1 # Windows
+    make bootstrap # Linux
+
+To run tests::
+
+   ./test.ps1 # Windows
+   make test # Linux
 
 If you use nose to run the tests, you must pass the ``-s`` flag; otherwise,
 ``nosetests`` applies its own proxy to ``stdout``, which confuses the unit
 tests.
 
+To build a local wheel file::
+
+    ./build.ps1 # Windows
+    make build # Linux
+
+To test the wheel, (upload to test PyPI, then 'pip install' & use it)::
+
+    ./test-release.ps1 # Windows
+    make test-release # Linux
+
+To upload the wheel to PyPI::
+
+    ./release.ps1 # Windows
+    make release # Linux
+
+To clean all generated files, builds, virtualenv::
+
+    ./clean.ps1 # Windows
+    make clean # Linux
+
 
 Professional support
 --------------------
diff --git a/bootstrap.ps1 b/bootstrap.ps1
new file mode 100644
index 0000000..3260f8b
--- /dev/null
+++ b/bootstrap.ps1
@@ -0,0 +1,9 @@
+$syspython="python3.8.exe"
+$ve="$HOME\.virtualenvs\colorama"
+$bin="$ve\Scripts"
+
+echo "Create $syspython virtualenv $ve"
+& $syspython -m venv --clear "$ve"
+& $bin\python.exe -m pip install --upgrade pip
+& $bin\python.exe -m pip install -r requirements.txt -r requirements-dev.txt
+
diff --git a/build.ps1 b/build.ps1
new file mode 100644
index 0000000..a48e357
--- /dev/null
+++ b/build.ps1
@@ -0,0 +1,6 @@
+$ve="$HOME\.virtualenvs\colorama"
+$bin="$ve\Scripts"
+
+& $bin\python.exe -m pip install --upgrade setuptools wheel
+& $bin\python.exe setup.py sdist bdist_wheel
+
diff --git a/clean.ps1 b/clean.ps1
new file mode 100644
index 0000000..de9ba5a
--- /dev/null
+++ b/clean.ps1
@@ -0,0 +1,6 @@
+$syspython="python3.8.exe"
+$ve="$HOME\.virtualenvs\colorama"
+
+remove-item -r -fo * -I build,dist,MANIFEST,colorama.egg-info,$ve,sandbox
+& $syspython -Bc "import pathlib, shutil; [shutil.rmtree(p) for p in pathlib.Path('.').rglob('__pycache__')]"
+
diff --git a/release.ps1 b/release.ps1
new file mode 100644
index 0000000..e01014d
--- /dev/null
+++ b/release.ps1
@@ -0,0 +1,7 @@
+$ve="$HOME\.virtualenvs\colorama"
+$bin="$ve\Scripts"
+$version="$(& $bin\python.exe setup.py --version)"
+
+# Upload to PyPI.
+& $bin\twine.exe upload dist\colorama-$version-*
+
diff --git a/test-release b/test-release
index c896669..fc20b06 100644
--- a/test-release
+++ b/test-release
@@ -18,7 +18,7 @@
 version=$($bin/python setup.py --version)
 sandbox=test-release-playground
 
-# Upload to the test pypi.
+# Upload to the test PyPI.
 $bin/twine upload --repository testpypi dist/colorama-$version-* \
     || echo "  > Expect a 400 if package was already uploaded."
 
@@ -27,13 +27,13 @@
 (
     cd $sandbox
 
-    # Create a new virtualenv
+    # Create a temporary disposable virtualenv.
     $syspython -m venv --clear venv
 
-    # Install the package we just uploaded
+    # Install the package we just uploaded.
     venv/bin/python -m pip --quiet install --index-url https://test.pypi.org/simple colorama==$version
 
-    # Test the package can be imported
+    # Import and use Colorama from the temp virtualenv.
     venv/bin/python -c "import colorama; colorama.init(); print(colorama.Fore.GREEN + \"OK: Colorama\", colorama.__version__, \"from test pypi install.\")"
 )
 
diff --git a/test-release.ps1 b/test-release.ps1
new file mode 100644
index 0000000..0466cf9
--- /dev/null
+++ b/test-release.ps1
@@ -0,0 +1,29 @@
+$syspython="python3.8.exe"
+$ve="$HOME\.virtualenvs\colorama"
+$bin="$ve\Scripts"
+$version="$(& $bin\python.exe setup.py --version)"
+
+# Upload to the test PyPI.
+& $bin\twine.exe upload --repository testpypi dist\colorama-$version-*
+if(!$?) {
+    write-host "  > Expect a 400 if package was already uploaded"
+}
+
+# cd elsewhere so we cannot import from local source.
+mkdir -force sandbox | out-null
+cd sandbox
+
+# Create a temporary disposable virtualenv.
+& $syspython -m venv --clear venv
+
+# Install the package we just uploaded.
+venv\Scripts\python -m pip --quiet install --index-url https://test.pypi.org/simple colorama==$version
+# Import and use colorama from the temp virtualenv.
+venv\Scripts\python.exe -c @"
+import colorama;
+colorama.init();
+print(colorama.Fore.GREEN + ""OK Colorama "" + colorama.__version__ + "" from test pypi install."")
+"@
+
+cd ..
+
diff --git a/test.ps1 b/test.ps1
new file mode 100644
index 0000000..03ea144
--- /dev/null
+++ b/test.ps1
@@ -0,0 +1,5 @@
+$ve="$HOME\.virtualenvs\colorama"
+$bin="$ve\Scripts"
+
+& $bin\python.exe -m unittest discover -p *_test.py
+