175 lines
5.6 KiB
Python
175 lines
5.6 KiB
Python
|
#!/usr/bin/env python
|
||
|
|
||
|
"""
|
||
|
Script responsible for deploying both snowplow-tracker-core and snowplow-tracker
|
||
|
Need to be executed in Travis CI environment by tag (core/x.y.z OR x.y.z)
|
||
|
Publish core locally, build tracker using locally publiched core and then
|
||
|
publish altogether
|
||
|
"""
|
||
|
|
||
|
from contextlib import contextmanager
|
||
|
import os
|
||
|
import sys
|
||
|
import subprocess
|
||
|
|
||
|
|
||
|
# Initial setup
|
||
|
|
||
|
if 'TRAVIS_TAG' in os.environ:
|
||
|
TRAVIS_TAG = os.environ.get('TRAVIS_TAG')
|
||
|
else:
|
||
|
sys.exit("Environment variable TRAVIS_TAG is unavailable")
|
||
|
|
||
|
if 'TRAVIS_BUILD_DIR' in os.environ:
|
||
|
TRAVIS_BUILD_DIR = os.environ.get('TRAVIS_BUILD_DIR')
|
||
|
else:
|
||
|
sys.exit("Environment variable TRAVIS_BUILD_DIR is unavailable")
|
||
|
|
||
|
if 'NPM_AUTH_TOKEN' in os.environ:
|
||
|
NPM_AUTH_TOKEN = os.environ.get('NPM_AUTH_TOKEN')
|
||
|
else:
|
||
|
sys.exit("Environment variable NPM_AUTH_TOKEN is unavailable")
|
||
|
|
||
|
if TRAVIS_TAG.startswith('core/'):
|
||
|
PROJECT = 'core'
|
||
|
VERSION = TRAVIS_TAG[5:]
|
||
|
else:
|
||
|
PROJECT = 'tracker'
|
||
|
VERSION = TRAVIS_TAG
|
||
|
|
||
|
if 'AWS_ACCESS_KEY' in os.environ:
|
||
|
AWS_ACCESS_KEY = os.environ.get('AWS_ACCESS_KEY')
|
||
|
else:
|
||
|
sys.exit("Environment variable AWS_ACCESS_KEY is unavailable (required for tracker publishing)")
|
||
|
|
||
|
if 'AWS_SECRET_KEY' in os.environ:
|
||
|
AWS_SECRET_KEY = os.environ.get('AWS_SECRET_KEY')
|
||
|
else:
|
||
|
sys.exit("Environment variable AWS_SECRET_KEY is unavailable (required for tracker publishing)")
|
||
|
|
||
|
if 'AWS_S3_BUCKET' in os.environ:
|
||
|
AWS_S3_BUCKET = os.environ.get('AWS_S3_BUCKET')
|
||
|
else:
|
||
|
sys.exit("Environment variable AWS_S3_BUCKET is unavailable (required for tracker publishing)")
|
||
|
|
||
|
if 'AWS_REGION' in os.environ:
|
||
|
AWS_REGION = os.environ.get('AWS_REGION')
|
||
|
else:
|
||
|
sys.exit("Environment variable AWS_REGION is unavailable (required for tracker publishing)")
|
||
|
|
||
|
if 'AWS_CF_DISTRIBUTION' in os.environ:
|
||
|
AWS_CF_DISTRIBUTION = os.environ.get('AWS_CF_DISTRIBUTION')
|
||
|
else:
|
||
|
sys.exit("Environment variable AWS_CF_DISTRIBUTION is unavailable (required for tracker publishing)")
|
||
|
|
||
|
|
||
|
# Helper functions
|
||
|
|
||
|
def output_if_error(sbt_output):
|
||
|
"""Callback to print stderr and fail deploy if exit status not successful"""
|
||
|
(stdout, stderr) = sbt_output.communicate()
|
||
|
if sbt_output.returncode != 0:
|
||
|
print("Process has been failed.\n" + stdout)
|
||
|
sys.exit(stderr)
|
||
|
|
||
|
|
||
|
def execute(command, callback=output_if_error):
|
||
|
"""Execute shell command with optional callback"""
|
||
|
formatted_command = " ".join(command) if (type(command) == list) else command
|
||
|
print("Executing [{0}]".format(formatted_command))
|
||
|
output = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||
|
if hasattr(callback, '__call__'):
|
||
|
return callback(output)
|
||
|
else:
|
||
|
return output
|
||
|
|
||
|
|
||
|
def check_version():
|
||
|
"""Fail deploy if tag version doesn't match SBT version"""
|
||
|
if PROJECT == 'core':
|
||
|
get_version = """var fs=require('fs'); fs.readFile('./core/package.json', 'utf8', function(e,d) { console.log(JSON.parse(d)['version']) });"""
|
||
|
elif PROJECT == 'tracker':
|
||
|
get_version = """var fs=require('fs'); fs.readFile('./package.json', 'utf8', function(e,d) { console.log(JSON.parse(d)['version']) });"""
|
||
|
else:
|
||
|
sys.exit("Unknown project " + str(PROJECT))
|
||
|
|
||
|
node_output = execute(['node', '-e', get_version], None)
|
||
|
print(node_output.stderr.read())
|
||
|
for line in node_output.stdout.read().split("\n"):
|
||
|
print(line)
|
||
|
if line:
|
||
|
if line != VERSION:
|
||
|
sys.exit("Version extracted from TRAVIS_TAG [{0}] doesn't conform declared in package.json [{1}]".format(VERSION, line))
|
||
|
else:
|
||
|
return
|
||
|
|
||
|
sys.exit("Cannot find version in core output:\n" + str(node_output))
|
||
|
|
||
|
|
||
|
@contextmanager
|
||
|
def npm_credentials():
|
||
|
"""Context manager allowing to use different credentials and delete them after use"""
|
||
|
npmrc = os.path.expanduser("~/.npmrc")
|
||
|
|
||
|
if os.path.isfile(npmrc):
|
||
|
os.remove(npmrc)
|
||
|
print("WARNING! ~/.npmrc already exists. It should be deleted after each use")
|
||
|
print("Overwriting existing ~/.npmrc")
|
||
|
else:
|
||
|
print("Creating ~/.npmrc")
|
||
|
|
||
|
with open(npmrc, 'a') as f:
|
||
|
f.write("registry=https://registry.npmjs.org/\n//registry.npmjs.org/:_authToken=" + NPM_AUTH_TOKEN)
|
||
|
|
||
|
yield
|
||
|
|
||
|
print("Deleting ~/.npmrc")
|
||
|
os.remove(npmrc)
|
||
|
|
||
|
|
||
|
@contextmanager
|
||
|
def aws_credentials():
|
||
|
"""Context manager allowing to use different credentials and delete them after use"""
|
||
|
awsjson = os.path.join(TRAVIS_BUILD_DIR, "aws.json")
|
||
|
|
||
|
if os.path.isfile(awsjson):
|
||
|
sys.exit("aws.json already exists. It should be deleted after each use")
|
||
|
else:
|
||
|
print("Creating aws.json")
|
||
|
with open(awsjson, 'a') as f:
|
||
|
f.write(
|
||
|
'{"key":"%(key)s","secret":"%(secret)s","bucket":"%(bucket)s","region":"%(region)s", "distribution":"%(distribution)s"}' % \
|
||
|
{'key': AWS_ACCESS_KEY, 'secret': AWS_SECRET_KEY, 'bucket': AWS_S3_BUCKET, 'distribution': AWS_CF_DISTRIBUTION, 'region': AWS_REGION}
|
||
|
)
|
||
|
|
||
|
yield
|
||
|
|
||
|
print("Deleting aws.json")
|
||
|
os.remove(awsjson)
|
||
|
|
||
|
|
||
|
def publish_core():
|
||
|
os.chdir(os.path.join(TRAVIS_BUILD_DIR, "core"))
|
||
|
with npm_credentials():
|
||
|
execute(['npm', 'publish'])
|
||
|
|
||
|
|
||
|
def publish_tracker():
|
||
|
os.chdir(TRAVIS_BUILD_DIR)
|
||
|
with aws_credentials():
|
||
|
execute(['grunt', 'publish'])
|
||
|
|
||
|
|
||
|
def publish():
|
||
|
if PROJECT == 'core':
|
||
|
publish_core()
|
||
|
elif PROJECT == 'tracker':
|
||
|
publish_tracker()
|
||
|
else:
|
||
|
sys.exit("Unknown project " + str(PROJECT))
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
# Publish locally all dependencies
|
||
|
check_version()
|
||
|
publish()
|