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,…

Continue ReadingHow to create a Windows Installer from tagged commits

Code Quality in the knittingpattern Python Library

In our Google Summer of Code project a part of our work is to bring knitting to the digital age. We is Kirstin Heidler and Nicco Kunzmann. Our knittingpattern library aims at being the exchange and conversion format between different types of knit work representations: hand knitting instructions, machine commands for different machines and SVG schemata.               The image above was generated by this Python code: import knittingpattern, webbrowser example = knittingpattern.load_from().example("Cafe.json") webbrowser.open(example.to_svg(25).temporary_path(".svg")) So far about the context. Now about the Quality tools we use: Continuous integration We use Travis CI [FOSSASIA] to upload packages of a specific git tag  automatically. The Travis build runs under Python 3.3 to 3.5. It first builds the package and then installs it with its dependencies. To upload tags automatically, one can configure Travis, preferably with the command line interface, to save username and password for the Python Package Index (Pypi).[TravisDocs] Our process of releasing a new version is the following: Increase the version in the knitting pattern library and create a new pull request for it. Merge the pull request after the tests passed. Pull and create a new release with a git tag using setup.py tag_and_deploy Travis then builds the new tag and uploads it to Pypi. With this we have a basic quality assurance. Pull-requests need to run all tests before they can be merge. Travis can be configured to automatically reject a request with errors. Documentation Driven Development As mentioned in a blog post, documentation-driven development was something worth to check out. In our case that means writing the documentation first, then the tests and then the code. Writing the documentation first means thinking in the space of the mental model you have for the code. It defines the interfaces you would be happy to use. A lot of edge cases can be thought of at this point. When writing the tests, they are often split up and do not represent the flow of thought any more that you had when thinking about your wishes. Tests can be seen as the glue between the code and the documentation. As it is with writing code to pass the tests, in the conversation between the tests and the documentation I find out some things I have forgotten. When writing the code in a test-driven way, another conversation starts. I call implementing the tests conversation because the tests talk to the code that it should be different and the code tells the tests their inconsistencies like misspellings and bloated interfaces. With writing documentation first, we have the chance to have two conversations about our code, in spoken language and in code. I like it when the code hears my wishes, so I prefer to talk a bit more. Testing the Documentation Our documentation is hosted on Read the Docs. It should have these properties: Every module is documented. Everything that is public is documented. The documentation is syntactically correct. These are qualities that can be tested, so they…

Continue ReadingCode Quality in the knittingpattern Python Library

Knitting Pattern Conversion

We can convert knitting patterns to svg (middle) which proves the concept but is still a different from the original (right) Our goal is to create a knit-work exchange format. This includes the conversion to a scematic view of the knittting pattern as svg - to make it endlessly scalable and allow conversions to png, pdf and paper. This week we ended the prototype of the SVG conversion. The positions are a bit off and instructions are placed above eachother. Most of the work is done. We are also able to load and save knitting patterns a png files. (1) (2) (3) We loaded them (1), converted them to a knitting pattern and then saved them again as png (2). This way we path our way towards using the ayab software and actually knitting the pattern. Also we can convert the knitting pattern to an svg consisting all of knit instructions (3). Here is the code for it in version 0.0.8. >>> import knittingpattern >>> from knittingpattern.convert.image_to_knittingpattern import * >>> convert_image_to_knitting_pattern.path("head-band.png").temporary_path(".json") "head-band.json" >>> k = knittingpattern.load_from_path("head-band.json") >>> k.to_svg(10).temporary_path(".svg") "head-band.svg" Here you can see a proof of concept video:  

Continue ReadingKnitting Pattern Conversion

Towards a unified digital aproach to knitting

Our idea is to create a knitting library for a format that allows conversion of knitting projects, patterns and tutorials. Usually, communities will only focus on the knitting format for their machines. Our approach should be different and be able to support any knitting communities efforts. Here is our strategy to achieve this: We connect to different communities to get a broader view on what their needs are. Our knitting format is based on knitting instructions like knit, purl, yarn over, skp. We found a comprehensive list on Wikipedia. Other Communities From time to time we meet with other people who also knit and could use our software. First, we met with Viktoria from ETIB Berlin. She taught us a lot about knitting, how she does it, that almost everything could be created from one peace with the machine. Also, that AYAB is used for lace patterns. We saw examples where she let meshes fall so that larger holes were created. Our goal is to support laces in the file format.  Color patterns should be possible across sewing edges. We are also in touch with Valentina Project. With their software we would be able to connect to yet another community and use their sewing patterns for custom-fit clothes. We got in touch with Kniterate. They and we share a lot of goals. Because they create a startup, they are very cautious what they release. They focus on their open-source knitting machine first and later on the software. They already created an editor much like we imagined ours to be, but as a web application. A way of collaboration could be that we understand their file format and see how we can support it. Only talking about our GSoC project is worth it as other people may have seen alike at Maker Faires and other hacky places. We have the chance to bring communities and efforts together. Knitting Format A universal knitting format has many concerns: Languages of users differ It should be possible to knit by hand Mesh sizes and wool differ Different knitting machines with different abilities A knitting format for exchange is never complete. A knitting format for machines must be complete. In contrast to a knitting format for a automatic machine, it is possible, to have machines operate in semi-automatic modes or just to knit by hand. In both cases, meshes could be changed in a way that was never foreseen. This is why we did not base it on meshes and mesh types but rather on instructions - closer to the mental model of the knitters who perform instructions with their hand. Some of the instructions are understood by the machines, some could be adapted a bit so the machine can do it automatically or faster and some are still necessary to be done by hand. We created a Python module for that, "knittingpattern". We work on it in a test-driven way.  

Continue ReadingTowards a unified digital aproach to knitting