How to create a Windows Installer from tagged commits
I working on an open-source Python project, an editor for knit work called the "KnitEditor". Development takes place at Github. Here, I would like to give some insight in how we automated deployment of the application to a Windows installer. The process works like this: Create a tag with git and push it to Github. AppVeyor build the application. AppVeyor pushes the application to the Github release. (1) Create a tag and push it Tags should reflect the version of the software. Version "0.0.1" is in tag "v0.0.1". We automated the tagging with the "setup.py" in the repository. Now, you can run py -3.4 setup.py tag_and_deploy Which checks that there is no such tag already. Several commits have the same version, so, we like to make sure that we do not have two versions with the same name. Also, this can only be executed on the master branch. This way, the software has gone through all the automated quality assurance. Here is the code from the setup.py: from distutils.core import Command # ... class TagAndDeployCommand(Command): description = "Create a git tag for this version and push it to origin."\ "To trigger a travis-ci build and and deploy." user_options = [] name = "tag_and_deploy" remote = "origin" branch = "master" def initialize_options(self): pass def finalize_options(self): pass def run(self): if subprocess.call(["git", "--version"]) != 0: print("ERROR:\n\tPlease install git.") exit(1) status_lines = subprocess.check_output( ["git", "status"]).splitlines() current_branch = status_lines[0].strip().split()[-1].decode() print("On branch {}.".format(current_branch)) if current_branch != self.branch: print("ERROR:\n\tNew tags can only be made from branch" " \"{}\".".format(self.branch)) print("\tYou can use \"git checkout {}\" to switch" " the branch.".format(self.branch)) exit(1) tags_output = subprocess.check_output(["git", "tag"]) tags = [tag.strip().decode() for tag in tags_output.splitlines()] tag = "v" + __version__ if tag in tags: print("Warning: \n\tTag {} already exists.".format(tag)) print("\tEdit the version information in {}".format( os.path.join(HERE, PACKAGE_NAME, "__init__.py") )) else: print("Creating tag \"{}\".".format(tag)) subprocess.check_call(["git", "tag", tag]) print("Pushing tag \"{}\" to remote \"{}\"." "".format(tag, self.remote)) subprocess.check_call(["git", "push", self.remote, tag]) # ... SETUPTOOLS_METADATA = dict( # ... cmdclass={ # ... TagAndDeployCommand.name: TagAndDeployCommad }, ) # ... if __name__ == "__main__": import setuptools METADATA.update(SETUPTOOLS_METADATA) setuptools.setup(**METADATA) # METADATA can be found in several other Above, you can see a "distutils" command that executed git through the command line interface. (2) AppVeyor builds the application As mentioned above, you can configure AppVeyor to build your application. Here are some parts of the "appveyor.yml" file, that I comment on inline: # see https://packaging.python.org/appveyor/#adding-appveyor-support-to-your-project environment: PYPI_USERNAME: niccokunzmann3 PYPI_PASSWORD: secure: Gxrd9WI60wyczr9mHtiQHvJ45Oq0UyQZNrvUtKs2D5w= # For Python versions available on Appveyor, see # http://www.appveyor.com/docs/installed-software#python # The list here is complete (excluding Python 2.6, which # isn't covered by this document) at the time of writing. # we only need Python 3.4 for kivy PYTHON: "C:\\Python34" install: - "%PYTHON%\\python.exe -m pip install docutils pygments pypiwin32 kivy.deps.sdl2 kivy.deps.glew" - "%PYTHON%\\python.exe -m pip install -r requirements.txt" - "%PYTHON%\\python.exe -m pip install -r test-requirements.txt" - "%PYTHON%\\python.exe setup.py install" build_script: - cmd: cmd /c windows-build\build.bat test_script: # Put your test command here. # If you don't need to build C extensions on 64-bit Python 3.3 or 3.4,…
