#!/usr/bin/env python3
# -*- encoding: utf-8 -*-
"""
Because we have a lot of Travis jobs, we try to avoid running unnecessary
tests and deploys.  This speeds up our builds, minimises deployment churn,
and reduces contention on our Travis infrastructure.

How we decide what to build:

                  | Relevant changes | No relevant changes
   ---------------+------------------+---------------------
    pull request  | Run tests        | Don't run tests
                  | Don't deploy     | Don't deploy
   ---------------+------------------+
    master        | Run tests        |
                  | Deploy to AWS    |
    --------------+------------------+---------------------
    cron          | Always run tests
                  | Never deploy to AWS

We run a full test suite in the cron tests so that even if we think a file
that has no relevant changes actually affects the tests, we still get
notice fairly quickly of the problem in master.

"""

import contextlib
import os
import subprocess
import sys

from travistooling import (
    build_report_output,
    get_changed_paths,
    git,
    make,
    should_run_build_task,
    unpack_secrets,
)


def _should_run_tests(task, travis_event_type):
    """
    Should we run the tests?
    """
    if travis_event_type == "cron":
        print("*** We always run tests in cron!")
        return True

    assert travis_event_type in ("pull_request", "push")

    if travis_event_type == "pull_request":
        changed_paths = get_changed_paths("HEAD", "master")
    else:
        git("fetch", "origin")
        changed_paths = get_changed_paths(os.environ["TRAVIS_COMMIT_RANGE"])

    result, report = should_run_build_task(changed_paths=changed_paths, task=task)
    print("\n" + build_report_output(report) + "\n")

    return result


def _should_run_publish(task, travis_event_type):
    """
    Should we run the publish step?
    """
    if travis_event_type in ("cron", "pull_request"):
        print("*** We never publish from cron or pull requests!")
        return False

    assert travis_event_type == "push"

    git("fetch", "origin")

    changed_paths = get_changed_paths(os.environ["TRAVIS_COMMIT_RANGE"])
    result, report = should_run_build_task(changed_paths=changed_paths, task=task)
    print("\n" + build_report_output(report) + "\n")

    return result


def main():
    # https://docs.travis-ci.com/user/environment-variables/
    travis_event_type = os.environ["TRAVIS_EVENT_TYPE"]
    task = os.environ["TASK"]

    if _should_run_tests(task=task, travis_event_type=travis_event_type):
        print("*** We're going to run tests")
    else:
        print("*** We don't need to run tests, exiting early")
        return 0

    unpack_secrets()

    make(task)

    if task in ["travis-format", "travistooling-test"]:
        print("*** Task %s does not have a publish step" % task)
        return 0

    publish_task = task.replace("-build", "-publish")
    publish_task = task.replace("-test", "-publish")

    if _should_run_publish(task=publish_task, travis_event_type=travis_event_type):
        print("*** We're going to run the publish task")
        make(publish_task)
    else:
        print("*** We don't need to run the publish task")

        # Doing a --dry-run checks that the associated publish task exists,
        # which protects us from merging a branch with no publish task.
        make(publish_task, "--dry-run")

    return 0


if __name__ == "__main__":
    sys.exit(main())

@@ -1163,16 +1163,298 @@
 ts,%0A)%0A%0A%0A
+@contextlib.contextmanager%0Adef timestamps():%0A    %22%22%22%0A    Print a timestamp to the log every minute (roughly!).%0A    %22%22%22%0A    proc = subprocess.Popen(%0A        'while true; do echo %22%5B%5Brun_travis_task.py%5D%5D %22$(date); sleep 60; done',%0A        shell=True,%0A    )%0A    yield%0A    proc.kill()%0A%0A%0A
 def _sho
@@ -2633,24 +2633,52 @@
 def main():%0A
+    with timestamps():%0A%0A    
     # https:
@@ -2730,16 +2730,20 @@
 es/%0A    
+  
+  
 travis_e
@@ -2786,16 +2786,20 @@
 _TYPE%22%5D%0A
+    
     task
@@ -2821,24 +2821,28 @@
 TASK%22%5D%0A%0A    
+  
+  
 if _should_r
@@ -2899,32 +2899,36 @@
 _type):%0A        
+    
 print(%22*** We're
@@ -2949,30 +2949,38 @@
 tests%22)%0A    
+ 
+   
 else:%0A
+    
         prin
@@ -3030,32 +3030,36 @@
 early%22)%0A        
+    
 return 0%0A%0A    un
@@ -3048,24 +3048,28 @@
   return 0%0A%0A
+    
     unpack_s
@@ -3078,16 +3078,20 @@
 rets()%0A%0A
+    
     make
@@ -3098,16 +3098,20 @@
 (task)%0A%0A
+    
     if t
@@ -3158,32 +3158,36 @@
 test%22%5D:%0A        
+    
 print(%22*** Task 
@@ -3227,32 +3227,36 @@
 %25 task)%0A        
+   
+ 
 return 0%0A%0A    pu
@@ -3245,24 +3245,28 @@
   return 0%0A%0A
+    
     publish_
@@ -3307,24 +3307,28 @@
 blish%22)%0A    
+   
+ 
 publish_task
@@ -3361,24 +3361,28 @@
 -publish%22)%0A%0A
+    
     if _shou
@@ -3453,32 +3453,36 @@
 _type):%0A        
+  
+  
 print(%22*** We're
@@ -3514,32 +3514,36 @@
  task%22)%0A        
+    
 make(publish_tas
@@ -3545,30 +3545,38 @@
 h_task)%0A    
+  
+  
 else:%0A
+    
         prin
@@ -3631,16 +3631,20 @@
         
+ 
+   
 # Doing 
@@ -3711,16 +3711,20 @@
         
+    
 # which 
@@ -3779,32 +3779,36 @@
 h task.%0A        
+ 
+   
 make(publish_tas
@@ -3820,24 +3820,28 @@
 -dry-run%22)%0A%0A
+    
     return 0

Revert "Don't bother logging timestamps; fail immediately"