=======
Satsuki
=======

.. image:: https://img.shields.io/github/license/YakDriver/satsuki.svg
    :target: ./LICENSE
    :alt: License
.. image:: https://travis-ci.org/YakDriver/satsuki.svg?branch=master
    :target: http://travis-ci.org/YakDriver/satsuki
    :alt: Build Status
.. image:: https://img.shields.io/pypi/pyversions/satsuki.svg
    :target: https://pypi.python.org/pypi/satsuki
    :alt: Python Version Compatibility
.. image:: https://img.shields.io/pypi/v/satsuki.svg
    :target: https://pypi.python.org/pypi/satsuki
    :alt: Version


**Satsuki** is a Python package that helps manage GitHub releases and release assets.
Satsuki is especially useful paired with Continuous Integration/
Continuous Deployment (CI/CD)
tools such as `Travis CI <https://travis-ci.org>`_ and `AppVeyor <https://www.appveyor.com>`_.

Why not just use the Travis CI GitHub Releases provider? Good question.
The simple answer is that the provider doesn't work very well yet.
In specific, you can't update an existing release or add files
(assets) to a release or provide a release message and a release asset
at the same time.

Satsuki and Travis CI Example
=============================

This example shows setting up Travis CI with your GitHub OAUTH token
for use by Satsuki, and then creating releases and uploading assets.

**Step 1: Encrypt OAUTH Token**

Using Travis's command line tool, encrypt your OAUTH token *with* the
environment variable name. NOTE: the encrypt is on a repo by repo
basis so the encrypted value will only work on the repo under it was
created.

.. code-block:: bash

    $ cd myrepodir
    $ travis encrypt SATS_TOKEN=YOUR_GITHUB_OATH_TOKEN
    Please add the following to your .travis.yml file:

    secure: " "


**Step 2: Add Token to Travis YAML**

Now, we'll add this secure value to the ``.travis.yml`` file in our repo.
Only Travis CI can decrypt this value now. (Although this shows Python
as the language, Satsuki will work with projects in other languages
as long as you install Python 3 and pip.)

.. code-block:: yaml

    language: python
    sudo: false
    env:
      global:
        - secure:  

**Step 3: Setup the Travis YAML Script Step**

We'll use the ``script`` step to build an application into a OS-
machine specific binary using `GravityBee <https://github.com/YakDriver/gravitybee>`_.

.. code-block:: yaml

    install:
      - pip install gravitybee satsuki
    script:
      - gravitybee --src-dir src --verbose --clean


**Step 4: Setup the Travis YAML Before Deploy Step**

Here assign
values to environment variables so that Satsuki can use them to
create the release and we'll tag the release.

.. code-block:: yaml

    before_deploy:
      - export SATS_TAG=$(grep "version = " $TRAVIS_BUILD_DIR/setup.cfg | sed "s/version = //")
      - export SATS_BODY="* Here is the message for the release"
      - export SATS_FILE="mysuperapp-1.2.3-standalone-linux-x86_64"
      - git tag -a $SATS_TAG -m "This is the v$SATS_TAG message"


**Step 5: Setup the Travis YAML Deploy Step**

Everything should be set now to deploy.

.. code-block:: yaml

    deploy:
      - provider: script
        script: satsuki
        skip_cleanup: true
        on:
          branch: master
          repo: YakDriver/mysuperapp
          python: "3.6"


Now if you've enabled your repo on Travis CI, when you commit to the
master branch, if all goes well, you'll get a release with your binary
file associated with it.


Reference
=========

Satsuki can be used with command line (CL) options or environment
variables, or a mix of both. If both are provided, command line
options take precedence.


Options
-------

Using Satsuki, you can create releases. A release is a GitHub feature.
However, a release is related to a tag, which is a pure Git feature. (If
the tag doesn't exist, Satsuki will create it along with the release.)
You can also create assets (e.g., binary files) that are
associated with releases. Thus Satsuki has options that relate to each:
Asset ==> Release ==> Tag.

Options from each, tag, release, and asset, can be provided at once,
and Satsuki
will attempt to act appropriately on each. For example, in one
command you can create a tag, release, and asset.

If an environment variable is used as a flag, the existence of the
environment variable
is sufficient to trigger the flag. It can be set to any value.

Release/Satsuki Related
-----------------------

================  ===============   ==========================================
ENV VAR           CL Options        Desciption
================  ===============   ==========================================
SATS_TOKEN        --token           **[Required]** An OAUTH token with
                                    repo access.
SATS_COMMAND      -c, --command     The operation to perform on the GitHub
                                    release. Choose from ``upsert`` or
                                    ``delete``. If ``delete`` is selected and a
                                    file is provided, the file (release
                                    asset) is deleted instead of the release.
                                    *Default:* ``upsert``
SATS_SLUG         -s, --slug        **[Required]** Either repo and user or
                                    the slug (in the form user/repo) must be
                                    provided. *If not provided, it will default
                                    to the value provided by Travis CI or
                                    AppVeyor, if any.*
SATS_REPO         -r, --repo        **[Required]** The GitHub repository to
                                    work with.
SATS_USER         -u, --user        **[Required]** The owner of the repository
                                    to work with.
SATS_REL_NAME     -n, --rel-name    The name of the release.
                                    *Default: tag name*
SATS_LATEST       --latest          **[Required][Flag]** Either this option
                                    *OR* ``--tag`` must be used.
                                    When used, Satsuki will perform any
                                    operations on the latest release.
                                    *Default: Not*
SATS_BODY         -b, --body        The message that shows up with releases.
                                    *Default: Release <tag>*
SATS_PRE          -p, --pre         **[Flag]** Whether or not this release
                                    is a prerelease. *Default: Not*
SATS_DRAFT        -d, --draft       **[Flag]** Whether or not this release
                                    is a draft. *Default: Not*
SATS_VERBOSE      -v, --verbose     **[Flag]** Verbose mode. *Default: Not*
================  ===============   ==========================================


Tag Related
-----------

================  ===============   ==========================================
ENV VAR           CL Options        Desciption
================  ===============   ==========================================
SATS_TAG          -t, --tag         **[Required]** Either the tag
                                    *OR* the ``--latest`` option must be
                                    provided. If both are used, tag
                                    takes precedence. In finding existing
                                    releases, the "tag" value may be either
                                    the release ID (e.g., 10746271) or tag
                                    name (e.g., v0.1.0). However, if a
                                    release ID is provided, and it does not
                                    exist, an error will be thrown to avoid
                                    creating a tag with an ID-like name.
                                    *If not provided,
                                    will default
                                    to the value provided by Travis CI or
                                    AppVeyor, if any.*
SATS_COMMITISH    --commitish       Can be any branch or commit SHA. Unused
                                    if the Git tag already exists.
                                    *If not provided, it will
                                    default
                                    to the TRAVIS_COMMIT environment variable
                                    provided by
                                    Travis CI or APPVEYOR_REPO_COMMIT from
                                    AppVeyor, if any. If none is provided,
                                    GitHub will default to the default branch.*
SATS_INCLUDE_TAG  --include-tag     Whether to delete the tag when deleting the
                                    release. If the provided tag does not match
                                    a release, the tag will be deleted. If the
                                    tag includes a POSIX-style filename pattern
                                    match, all tags which aren't associated
                                    with releases will be deleted. This is
                                    handy for cleaning up tags. If you have
                                    many tags to cleanup, you may need to run
                                    this multiple times to complete the
                                    cleaning. *Default: Not*
================  ===============   ==========================================

Here is an example of using Satsuki to clean up tags. To be able to clean tags,
Satsuki must be run from the ``git`` directory of the repo.

.. code-block:: bash

    $ cd coolproject
    $ satsuki --slug "Owner/coolproject" --token <YOUR_GITHUB_OATH_TOKEN> \
    --tag Test-* --command delete -v --include-tag


Asset Related
-------------

These options can be used multiple times. If there is one label or one MIME
type, and multiple files, the same label and MIME type will be applied to each
file. Otherwise, there must be the same number of labels and/or MIME types as
files, or an error will be thrown.

================  ===============   ==========================================
ENV VAR           CL Options        Desciption
================  ===============   ==========================================
SATS_FILE         -f, --file        File(s) to be uploaded as release asset(s).
                                    If the file name contains an asterik (*)
                                    it will be treated as a POSIX-style glob
                                    and all matching files will be uploaded.
                                    This option can be used multiple times
                                    to upload multiple files.
                                    *Default: No file is uploaded.*
SATS_FILE_FILE    --file-file       Name of file containing name(s) of files
                                    to be uploaded.
                                    *Default: Will look for*
                                    ``gravitybee.file``
SATS_LABEL        -l, --label       Label to display for files instead of the
                                    file name. Not recommended with multiple
                                    file upload since all will share the same
                                    lable. *Default: GitHub will use the raw
                                    file name.*
SATS_MIME         -m, --mime        The mime type for files. *Default:
                                    A guess of the file type or*
                                    ``application/octet-stream`` *if all else
                                    fails.*
================  ===============   ==========================================


The Files File
--------------

Satsuki also accepts a JSON-formatted file containing information about
assets to be uploaded (see the ``--file-file`` option above). The file
can contain information about multiple files and should contain
information about files
accessible to Satsuki, with paths relative to the directory in which
Satsuki is run.

This is an example of the format.

.. code-block::

    [{'filename': 'gbtestapp-4.2.6-standalone-osx-x86_64',
      'label': 'gbtestapp Standalone Executable (gbtestapp-4.2.6-standalone-osx-x86_64) [GravityBee Build]',
      'mime-type': 'application/x-executable',
      'path': '/path/to/file/gbtestapp-4.2.6-standalone-osx-x86_64'}]

