diff --git a/.travis.yml b/.travis.yml index 5e0cee53..5badcd81 100644 --- a/.travis.yml +++ b/.travis.yml @@ -41,7 +41,10 @@ script: echo `date` >> test python -m doctr deploy --key-path deploy_key.enc --no-require-master docs; # Test syncing a tracked file with a change - python -m doctr deploy --sync --key-path deploy_key.enc stash-test --built-docs test; + python -m doctr deploy --sync --key-path deploy_key.enc stash-test/ --built-docs test; + # Test syncing a single file + echo `date` >> test-file + python -m doctr deploy --sync --key-path deploy_key.enc . --built-docs test-file; # Test deploy branch creation. Delete the branch gh-pages-testing on drdoctr/doctr whenever you want to test this. python -m doctr deploy --sync --key-path deploy_key.enc --no-require-master --deploy-branch gh-pages-testing docs; # Test pushing to .github.io @@ -64,7 +67,7 @@ script: fi - if [[ "${TESTS}" == "true" ]]; then pyflakes doctr; - py.test doctr; + py.test doctr -v -rs; fi doctr: diff --git a/doctr/tests/test_local.py b/doctr/tests/test_local.py index 78064556..70ea9c94 100644 --- a/doctr/tests/test_local.py +++ b/doctr/tests/test_local.py @@ -68,10 +68,11 @@ def test_GIT_URL(): assert not GIT_URL.fullmatch('https://gitlab.com/drdoctr/doctr.git') +@pytest.mark.skipif(os.environ.get('TRAVIS_REPO_SLUG', '') != 'drdoctr/doctr', reason="Not run on Travis fork builds") +@pytest.mark.skipif(not on_travis(), reason="Not on Travis") def test_guess_github_repo(): """ Only works if run in this repo, and if cloned from origin. For safety, - only run on Travis + only run on Travis and not run on fork builds. """ - if on_travis(): - assert guess_github_repo() == 'drdoctr/doctr' + assert guess_github_repo() == 'drdoctr/doctr' diff --git a/doctr/tests/test_travis.py b/doctr/tests/test_travis.py index 09b9e5bf..81286cec 100644 --- a/doctr/tests/test_travis.py +++ b/doctr/tests/test_travis.py @@ -221,46 +221,91 @@ def test_sync_from_log(src, dst): os.chdir(old_curdir) +@pytest.mark.parametrize("dst", ['dst', 'dst/']) +def test_sync_from_log_file_to_dir(dst): + with tempfile.TemporaryDirectory() as dir: + try: + old_curdir = os.path.abspath(os.curdir) + os.chdir(dir) + + src = 'file' + + with open(src, 'w') as f: + f.write('test1') + + # Test that the sync happens + added, removed = sync_from_log(src, dst, 'logfile') + + assert added == [ + os.path.join('dst', 'file'), + 'logfile', + ] + + assert removed == [] + + assert os.path.isdir(dst) + # Make sure dst is a file + with open(os.path.join('dst', 'file')) as f: + assert f.read() == 'test1' + + + with open('logfile') as f: + assert f.read() == '\n'.join([ + os.path.join('dst', 'file') + ]) + + finally: + os.chdir(old_curdir) + + @pytest.mark.parametrize("""branch_whitelist, TRAVIS_BRANCH, - TRAVIS_PULL_REQUEST, TRAVIS_TAG, build_tags, + TRAVIS_PULL_REQUEST, TRAVIS_TAG, fork, 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), + ('master', 'doctr', 'true', "", False, False, False), + ('master', 'doctr', 'false', "", False, False, False), + ('master', 'master', 'true', "", False, False, False), + ('master', 'master', 'false', "", False, False, True), + ('doctr', 'doctr', 'True', "", False, False, False), + ('doctr', 'doctr', 'false', "", False, False, True), + ('set()', 'doctr', 'false', "", False, False, False), + + ('master', 'doctr', 'true', "tagname", False, False, False), + ('master', 'doctr', 'false', "tagname", False, False, False), + ('master', 'master', 'true', "tagname", False, False, False), + ('master', 'master', 'false', "tagname", False, False, False), + ('doctr', 'doctr', 'True', "tagname", False, False, False), + ('doctr', 'doctr', 'false', "tagname", False, False, False), + ('set()', 'doctr', 'false', "tagname", False, False, False), + + ('master', 'doctr', 'true', "", False, True, False), + ('master', 'doctr', 'false', "", False, True, False), + ('master', 'master', 'true', "", False, True, False), + ('master', 'master', 'false', "", False, True, True), + ('doctr', 'doctr', 'True', "", False, True, False), + ('doctr', 'doctr', 'false', "", False, True, True), + ('set()', 'doctr', 'false', "", False, True, False), + + ('master', 'doctr', 'true', "tagname", False, True, True), + ('master', 'doctr', 'false', "tagname", False, True, True), + ('master', 'master', 'true', "tagname", False, True, True), + ('master', 'master', 'false', "tagname", False, True, True), + ('doctr', 'doctr', 'True', "tagname", False, True, True), + ('doctr', 'doctr', 'false', "tagname", False, True, True), + ('set()', 'doctr', 'false', "tagname", False, True, True), + + ('master', 'doctr', 'true', "", True, False, False), + ('master', 'doctr', 'false', "", True, False, False), + ('master', 'master', 'true', "", True, False, False), + ('master', 'master', 'false', "", True, False, False), + ('doctr', 'doctr', 'True', "", True, False, False), + ('doctr', 'doctr', 'false', "", True, False, False), + ('set()', 'doctr', 'false', "", True, False, False), ]) def test_determine_push_rights(branch_whitelist, TRAVIS_BRANCH, - TRAVIS_PULL_REQUEST, TRAVIS_TAG, build_tags, canpush, monkeypatch): + TRAVIS_PULL_REQUEST, TRAVIS_TAG, build_tags, fork, canpush, monkeypatch): branch_whitelist = {branch_whitelist} assert determine_push_rights( @@ -268,6 +313,7 @@ def test_determine_push_rights(branch_whitelist, TRAVIS_BRANCH, TRAVIS_BRANCH=TRAVIS_BRANCH, TRAVIS_PULL_REQUEST=TRAVIS_PULL_REQUEST, TRAVIS_TAG=TRAVIS_TAG, + fork=fork, build_tags=build_tags) == canpush @pytest.mark.parametrize("src", ["src", "."]) diff --git a/doctr/travis.py b/doctr/travis.py index 8df96da2..5f34d682 100644 --- a/doctr/travis.py +++ b/doctr/travis.py @@ -13,6 +13,8 @@ import tempfile import time +import requests + from cryptography.fernet import Fernet from .common import red, blue @@ -214,10 +216,21 @@ def setup_GitHub_push(deploy_repo, *, auth_type='deploy_key', TRAVIS_BRANCH = os.environ.get("TRAVIS_BRANCH", "") TRAVIS_PULL_REQUEST = os.environ.get("TRAVIS_PULL_REQUEST", "") + # Check if the repo is a fork + TRAVIS_REPO_SLUG = os.environ["TRAVIS_REPO_SLUG"] + REPO_URL = 'https://api.github.com/repos/{slug}' + r = requests.get(REPO_URL.format(slug=TRAVIS_REPO_SLUG)) + fork = r.json().get('fork', False) + # Rate limits prevent this check from working every time. By default, we + # assume it isn't a fork so that things just work on non-fork builds. + if r.status_code == 403: + print(red("Warning: GitHub's API rate limits prevented doctr from detecting if this build is a fork. If it is, doctr will fail with an error like 'DOCTR_DEPLOY_ENCRYPTION_KEY environment variable is not set'. This error can be safely ignored. If this is not a fork build, you can ignore this warning."), file=sys.stderr) + canpush = determine_push_rights( branch_whitelist=branch_whitelist, TRAVIS_BRANCH=TRAVIS_BRANCH, TRAVIS_PULL_REQUEST=TRAVIS_PULL_REQUEST, + fork=fork, TRAVIS_TAG=TRAVIS_TAG, build_tags=build_tags) @@ -434,14 +447,17 @@ def sync_from_log(src, dst, log_file, exclude=()): files = glob.iglob(join(src, '**'), recursive=True) else: files = [src] - src = os.path.dirname(src) + os.sep + src = os.path.dirname(src) + os.sep if os.sep in src else '' + + os.makedirs(dst, exist_ok=True) # sorted makes this easier to test for f in sorted(files): if any(is_subdir(f, os.path.join(src, i)) for i in exclude): continue new_f = join(dst, f[len(src):]) - if isdir(f): + + if isdir(f) or f.endswith(os.sep): os.makedirs(new_f, exist_ok=True) else: shutil.copy2(f, new_f) @@ -549,7 +565,7 @@ def last_commit_by_doctr(): return False def determine_push_rights(*, branch_whitelist, TRAVIS_BRANCH, - TRAVIS_PULL_REQUEST, TRAVIS_TAG, build_tags): + TRAVIS_PULL_REQUEST, TRAVIS_TAG, build_tags, fork): """Check if Travis is running on ``master`` (or a whitelisted branch) to determine if we can/should push the docs to the deploy repo """ @@ -570,6 +586,10 @@ def determine_push_rights(*, branch_whitelist, TRAVIS_BRANCH, print("The website and docs are not pushed to gh-pages on pull requests", file=sys.stderr) canpush = False + if fork: + print("The website and docs are not pushed to gh-pages on fork builds.", file=sys.stderr) + canpush = False + if last_commit_by_doctr(): print(red("The last commit on this branch was pushed by doctr. Not pushing to " "avoid an infinite build-loop."), file=sys.stderr)