Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ script:
# GitHub Wiki deploy
echo "This page was automatically deployed by doctr on $(date)" > deploy-test.md;
python -m doctr deploy --sync --key-path deploy_key.enc --no-require-master --deploy-repo drdoctr/doctr.wiki . --built-docs deploy-test.md;
# Build on tags
python -m doctr deploy --sync --key-path deploy_key.enc "tag-$TRAVIS_TAG" --build-tags --branch-whitelist;
fi
- if [[ "${TESTS}" == "true" ]]; then
pyflakes doctr;
Expand Down
29 changes: 29 additions & 0 deletions docs/recipes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,35 @@ For security purposes, it is not possible to deploy from branches on forks
requests from forks). If you want to deploy the docs for a branch from a pull
request, you will need to push it up to the main repository.

Deploy docs from git tags
=========================

Travis CI runs separate builds for git tags that are pushed to your repo. By
default, doctr does not deploy on these builds, but it can be enabled with the
``--build-tags`` flag to ``doctr deploy``. This is useful if you want to use
doctr to deploy versioned docs for releases, for example.

On Travis CI, the tag is set to the environment variable ``$TRAVIS_TAG``,
which is empty otherwise. The following will deploy the docs to ``dev`` for
normal ``master`` builds, and ``version-<TAG NAME>`` for tag builds:

.. code:: yaml

- if [[ -z "$TRAVIS_TAG" ]]; then
DEPLOY_DIR=dev;
else
DEPLOY_DIR="version-$TRAVIS_TAG";
fi
- doctr deploy --build-tags --built-docs build/ $DEPLOY_DIR

If you want to deploy only on a tag, use ``--branch-whitelist`` with no
arguments to tell doctr to not deploy from any branch. For instance, to deploy
only tags to ``latest``:

.. code:: yaml

- doctr deploy latest --built-docs build/ --build-tags --branch-whitelist

Deploy to a separate repo
=========================

Expand Down
19 changes: 17 additions & 2 deletions doctr/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,10 @@ def get_parser(config=None):
help=argparse.SUPPRESS)
deploy_parser_add_argument('--deploy-repo', default=None, help="""Repo to
deploy the docs to. By default, it deploys to the repo Doctr is run from.""")
deploy_parser_add_argument('--branch-whitelist', default=None, nargs='*',
help="""Branches to deploy from. Pass no arguments to not build on any branch
(typically used in conjunction with --build-tags). Note that you can
deploy from every branch with --no-require-master.""", type=set, metavar="BRANCH")
deploy_parser_add_argument('--no-require-master', dest='require_master', action='store_false',
default=True, help="""Allow docs to be pushed from a branch other than master""")
deploy_parser_add_argument('--command', default=None,
Expand All @@ -163,6 +167,11 @@ def get_parser(config=None):
deploy_parser_add_argument('--no-push', dest='push', action='store_false',
default=True, help="Run all the steps except the last push step. "
"Useful for debugging")
deploy_parser_add_argument('--build-tags', action='store_true',
default=False, help="""Deploy on tag builds. On a tag build,
$TRAVIS_TAG is set to the name of the tag. The default is to not
deploy on tag builds. Note that this will still build on a branch,
unless --branch-whitelist (with no arguments) is passed.""")
deploy_parser_add_argument('--gh-pages-docs', default=None,
help="""!!DEPRECATED!! Directory to deploy the html documentation to on gh-pages.
The default is %(default)r. The deploy directory should be passed as
Expand Down Expand Up @@ -273,13 +282,19 @@ def deploy(args, parser):

current_commit = subprocess.check_output(['git', 'rev-parse', 'HEAD']).decode('utf-8').strip()
try:
branch_whitelist = {'master'} if args.require_master else set(get_travis_branch())
branch_whitelist = set() if args.require_master else set(get_travis_branch())
branch_whitelist.update(set(config.get('branches',set({}))))
if args.branch_whitelist is not None:
branch_whitelist.update(args.branch_whitelist)
if not args.branch_whitelist:
branch_whitelist = {'master'}

canpush = setup_GitHub_push(deploy_repo, deploy_branch=deploy_branch,
auth_type='token' if args.token else 'deploy_key',
full_key_path=keypath,
branch_whitelist=branch_whitelist, env_name=env_name)
branch_whitelist=branch_whitelist,
build_tags=args.build_tags,
env_name=env_name)

if args.sync:
built_docs = args.built_docs or find_sphinx_build_dir()
Expand Down
59 changes: 47 additions & 12 deletions doctr/tests/test_travis.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,16 +144,51 @@ def test_sync_from_log(src, dst):
os.chdir(old_curdir)


@pytest.mark.parametrize("travis_branch, travis_pr, whitelist, canpush",
[('doctr', 'true', 'master', False),
('doctr', 'false', 'master', False),
('master', 'true', 'master', False),
('master', 'false', 'master', True),
('doctr', 'True', 'doctr', False),
('doctr', 'false', 'doctr', True),
('doctr', 'false', 'set()', False),
])
def test_determine_push_rights(travis_branch, travis_pr, whitelist, canpush, monkeypatch):
branch_whitelist = {whitelist}
@pytest.mark.parametrize("""branch_whitelist, TRAVIS_BRANCH,
TRAVIS_PULL_REQUEST, TRAVIS_TAG, build_tags,
canpush""",
[

('master', 'doctr', 'true', "", False, False),
('master', 'doctr', 'false', "", False, False),
('master', 'master', 'true', "", False, False),
('master', 'master', 'false', "", False, True),
('doctr', 'doctr', 'True', "", False, False),
('doctr', 'doctr', 'false', "", False, True),
('set()', 'doctr', 'false', "", False, False),

('master', 'doctr', 'true', "tagname", False, False),
('master', 'doctr', 'false', "tagname", False, False),
('master', 'master', 'true', "tagname", False, False),
('master', 'master', 'false', "tagname", False, False),
('doctr', 'doctr', 'True', "tagname", False, False),
('doctr', 'doctr', 'false', "tagname", False, False),
('set()', 'doctr', 'false', "tagname", False, False),

('master', 'doctr', 'true', "", True, False),
('master', 'doctr', 'false', "", True, False),
('master', 'master', 'true', "", True, False),
('master', 'master', 'false', "", True, True),
('doctr', 'doctr', 'True', "", True, False),
('doctr', 'doctr', 'false', "", True, True),
('set()', 'doctr', 'false', "", True, False),

('master', 'doctr', 'true', "tagname", True, True),
('master', 'doctr', 'false', "tagname", True, True),
('master', 'master', 'true', "tagname", True, True),
('master', 'master', 'false', "tagname", True, True),
('doctr', 'doctr', 'True', "tagname", True, True),
('doctr', 'doctr', 'false', "tagname", True, True),
('set()', 'doctr', 'false', "tagname", True, True),

assert determine_push_rights(branch_whitelist, travis_branch, travis_pr) == canpush
])
def test_determine_push_rights(branch_whitelist, TRAVIS_BRANCH,
TRAVIS_PULL_REQUEST, TRAVIS_TAG, build_tags, canpush, monkeypatch):
branch_whitelist = {branch_whitelist}

assert determine_push_rights(
branch_whitelist=branch_whitelist,
TRAVIS_BRANCH=TRAVIS_BRANCH,
TRAVIS_PULL_REQUEST=TRAVIS_PULL_REQUEST,
TRAVIS_TAG=TRAVIS_TAG,
build_tags=build_tags) == canpush
30 changes: 24 additions & 6 deletions doctr/travis.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,10 @@ def get_travis_branch():
else:
return os.environ.get("TRAVIS_BRANCH", "")

def setup_GitHub_push(deploy_repo, auth_type='deploy_key', full_key_path='github_deploy_key.enc',
require_master=None, branch_whitelist=None, deploy_branch='gh-pages', env_name='DOCTR_DEPLOY_ENCRYPTION_KEY'):
def setup_GitHub_push(deploy_repo, *, auth_type='deploy_key',
full_key_path='github_deploy_key.enc', require_master=None,
branch_whitelist=None, deploy_branch='gh-pages',
env_name='DOCTR_DEPLOY_ENCRYPTION_KEY', build_tags=False):
"""
Setup the remote to push to GitHub (to be run on Travis).

Expand All @@ -196,6 +198,8 @@ def setup_GitHub_push(deploy_repo, auth_type='deploy_key', full_key_path='github

For ``auth_type='deploy_key'``, this sets up the remote with ssh access.
"""
# Set to the name of the tag for tag builds
TRAVIS_TAG = os.environ.get("TRAVIS_TAG", "")

if not branch_whitelist:
branch_whitelist={'master'}
Expand All @@ -213,8 +217,12 @@ def setup_GitHub_push(deploy_repo, auth_type='deploy_key', full_key_path='github
TRAVIS_BRANCH = os.environ.get("TRAVIS_BRANCH", "")
TRAVIS_PULL_REQUEST = os.environ.get("TRAVIS_PULL_REQUEST", "")

canpush = determine_push_rights(branch_whitelist, TRAVIS_BRANCH,
TRAVIS_PULL_REQUEST)
canpush = determine_push_rights(
branch_whitelist=branch_whitelist,
TRAVIS_BRANCH=TRAVIS_BRANCH,
TRAVIS_PULL_REQUEST=TRAVIS_PULL_REQUEST,
TRAVIS_TAG=TRAVIS_TAG,
build_tags=build_tags)

print("Setting git attributes")
set_git_user_email()
Expand Down Expand Up @@ -441,6 +449,9 @@ def commit_docs(*, added, removed):
TRAVIS_COMMIT = os.environ.get("TRAVIS_COMMIT", "<unknown>")
TRAVIS_REPO_SLUG = os.environ.get("TRAVIS_REPO_SLUG", "<unknown>")
TRAVIS_JOB_ID = os.environ.get("TRAVIS_JOB_ID", "")
TRAVIS_TAG = os.environ.get("TRAVIS_TAG", "")
branch = "tag" if TRAVIS_TAG else "branch"

DOCTR_COMMAND = ' '.join(map(shlex.quote, sys.argv))

for f in added:
Expand All @@ -452,7 +463,7 @@ def commit_docs(*, added, removed):
Update docs after building Travis build {TRAVIS_BUILD_NUMBER} of
{TRAVIS_REPO_SLUG}

The docs were built from the branch '{TRAVIS_BRANCH}' against the commit
The docs were built from the {branch} '{TRAVIS_BRANCH}' against the commit
{TRAVIS_COMMIT}.

The Travis build that generated this commit is at
Expand All @@ -462,6 +473,7 @@ def commit_docs(*, added, removed):

{DOCTR_COMMAND}
""".format(
branch=branch,
TRAVIS_BUILD_NUMBER=TRAVIS_BUILD_NUMBER,
TRAVIS_BRANCH=TRAVIS_BRANCH,
TRAVIS_COMMIT=TRAVIS_COMMIT,
Expand Down Expand Up @@ -504,12 +516,18 @@ def push_docs(deploy_branch='gh-pages', retries=3):
return
sys.exit("Giving up...")

def determine_push_rights(branch_whitelist, TRAVIS_BRANCH, TRAVIS_PULL_REQUEST):
def determine_push_rights(*, branch_whitelist, TRAVIS_BRANCH,
TRAVIS_PULL_REQUEST, TRAVIS_TAG, build_tags):
"""Check if Travis is running on ``master`` (or a whitelisted branch) to
determine if we can/should push the docs to the deploy repo
"""
canpush = True

if TRAVIS_TAG:
if not build_tags:
print("The docs are not pushed on tag builds. To push on future tag builds, use --build-tags")
return build_tags

if not any([re.compile(x).match(TRAVIS_BRANCH) for x in branch_whitelist]):
print("The docs are only pushed to gh-pages from master. To allow pushing from "
"a non-master branch, use the --no-require-master flag", file=sys.stderr)
Expand Down