Skip to content
Open
Changes from all commits
Commits
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
125 changes: 86 additions & 39 deletions bin/release
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/python
#!/usr/bin/env python3

#
# This file is part of Galette Helloasso plugin (https://galette-plugins.github.io/plugin-helloasso).
Expand All @@ -7,7 +7,7 @@
#

import os, sys, argparse, re, git, http.client, subprocess, glob
import urlgrabber.progress, tarfile, shutil, gitdb, time, fnmatch
import tarfile, shutil, gitdb, time, fnmatch
from datetime import datetime
from termcolor import colored
from urllib.parse import urlparse
Expand Down Expand Up @@ -42,6 +42,38 @@ def print_err(msg):
print(colored(msg, 'red', attrs=['bold']))


def run(cmd, cwd=None):
"""
Run a command, and stop the build if it failed.

Every subprocess here used to be started and waited for without its exit
code ever being looked at, so a failed composer install produced an archive
without vendor/ and the script still exited 0, announcing a release.
"""
p1 = subprocess.Popen(cmd, shell=True, cwd=cwd)
p1.communicate()
if p1.returncode != 0:
print_err('Command failed with exit code %d: %s' % (p1.returncode, cmd))
exit(1)


def remote_exists(url):
"""
Check whether a URL exists, with a HEAD request.

The scheme is honoured. The download repository is served over HTTPS, and
asking for it on port 80 answers a 301 rather than a 200, so this check used
to report that nothing existed whatever the version being built.
"""
parsed = urlparse(url)
if parsed.scheme == 'https':
connection = http.client.HTTPSConnection(parsed.netloc)
else:
connection = http.client.HTTPConnection(parsed.netloc)
connection.request('HEAD', parsed.path)
return connection.getresponse().status == 200


def get_numeric_version(ver):
"""
Returns all numeric version
Expand Down Expand Up @@ -77,15 +109,15 @@ def propose_version():
last_minor = '0'

for tagref in tagrefs:
tag = tagref.tag
if valid_version(tag.tag):
# name is set on annotated and lightweight tags alike
if valid_version(tagref.name):
# last minor version is always the last one :)
if tag.tag > last_minor:
last_minor = tag.tag
if tagref.name > last_minor:
last_minor = tagref.name

# last major version
if len(tag.tag) == 5 and tag.tag > last_major:
last_major = tag.tag
if len(tagref.name) == 5 and tagref.name > last_major:
last_major = tagref.name

if verbose:
print('last minor: %s | last major %s' % (last_minor, last_major))
Expand Down Expand Up @@ -116,25 +148,28 @@ def get_latest_version():

last = None
for tagref in tagrefs:
tag = tagref.tag
if tag is not None and valid_version(tag.tag):
# name is set on annotated and lightweight tags alike
if valid_version(tagref.name):
# last minor version is always the last one :)
if last is None or tag.tag > last.tag:
last = tag
if last is None or tagref.name > last.name:
last = tagref

if last is None:
print_err('No version tag found, cannot guess a version to build!')
sys.exit(1)

tag_commit = last.hexsha
return last.tag
tag_commit = last.commit.hexsha
return last.name


def is_existing_version(ver):
"""
Look specified version exists
"""
for tagref in tagrefs:
tag = tagref.tag
if valid_version(tag.tag):
if tag.tag == ver:
return True
# name is set on annotated and lightweight tags alike
if valid_version(tagref.name) and tagref.name == ver:
return True
return False

def ask_user_confirm(msg):
Expand Down Expand Up @@ -195,6 +230,9 @@ def _do_build(ver):
archive_name
)

if not os.path.exists(local_dl_repo):
os.makedirs(local_dl_repo)

if not force:
# first check if a version
local = False
Expand All @@ -206,12 +244,7 @@ def _do_build(ver):
if is_local:
exists = os.path.isfile(url)
else:
parsed = urlparse(url)

connection = http.client.HTTPConnection(parsed[1], 80)
connection.request('HEAD', parsed[2])
response = connection.getresponse()
exists = response.status == 200
exists = remote_exists(url)

if not exists:
# also check from local repo
Expand All @@ -222,11 +255,7 @@ def _do_build(ver):
if is_local:
ascexists = os.path.isfile(urlasc)
else:
ascparsed = urlparse(urlasc)
connection = http.client.HTTPConnection(ascparsed[1], 80)
connection.request('HEAD', ascparsed[2])
response = connection.getresponse()
ascexists = response.status == 200
ascexists = remote_exists(urlasc)

if not ascexists:
# also check from local repo
Expand Down Expand Up @@ -254,7 +283,7 @@ def _do_build(ver):
if msg is not None:
msg += ' and has been %ssigned!' % loctxt
else:
msg += 'Release has been %ssigned!' % loctxt
msg = 'Release has been %ssigned!' % loctxt

msg += '\n\nYou will *NOT* build another one :)'
print_err(msg)
Expand Down Expand Up @@ -296,8 +325,7 @@ def _do_build(ver):
else:
print('Archiving GIT tag %s' % ver)

p1 = subprocess.Popen(archive_cmd, shell=True)
p1.communicate()
run(archive_cmd)

print('Adding vendor libraries')
add_libs(rel_name, galette_archive)
Expand All @@ -315,8 +343,7 @@ def _do_build(ver):

def do_sign(archive):
sign_cmd = 'gpg --detach-sign --armor %s' % archive
p1 = subprocess.Popen(sign_cmd, shell=True)
p1.communicate()
run(sign_cmd)


def do_upload(galette_archive):
Expand Down Expand Up @@ -345,8 +372,7 @@ def do_scp(archive):
else:
scp_cmd = 'scp -r %s* %s:%s' % (archive, ssh_host, path)
print(scp_cmd)
p1 = subprocess.Popen(scp_cmd, shell=True)
p1.communicate()
run(scp_cmd)


def do_cp(archive):
Expand Down Expand Up @@ -400,8 +426,17 @@ def add_libs(rel_name, galette_archive):

if has_composer:
composer_cmd = 'composer install --no-dev'
p1 = subprocess.Popen(composer_cmd, shell=True, cwd=composer_dir)
p1.wait()
run(composer_cmd, cwd=composer_dir)

# cleaunp files not required in releases
todrop = [
'composer.lock',
'composer.json',
'composer.json.checker'
]
for td in todrop:
if os.path.exists(os.path.join(src_dir, rel_name, td)):
os.remove(os.path.join(src_dir, rel_name, td))

#cleanup vendors
for root, dirnames, filenames in os.walk(os.path.join(composer_dir, 'vendor')):
Expand Down Expand Up @@ -435,6 +470,9 @@ def add_libs(rel_name, galette_archive):
if root.endswith('tcpdf/fonts'):
if dirname != 'dejavu-fonts-ttf-2.34':
shutil.rmtree(os.path.join(root, dirname))
if root.endswith('vendor'):
if dirname == 'bin':
shutil.rmtree(os.path.join(root, dirname))

for filename in filenames:
if os.path.islink(os.path.join(root, filename)):
Expand Down Expand Up @@ -541,6 +579,11 @@ def main():
help='Be more verbose',
action="store_true"
)
parser.add_argument(
'--no-sign',
help='Do not sign the archive',
action='store_true'
)
parser.add_argument(
'-n',
'--nightly',
Expand Down Expand Up @@ -585,11 +628,15 @@ def main():
repo = git.Repo(galette_repo)
tagrefs = repo.tags

assume_yes = args.assume_yes

if args.f == True:
force = ask_user_confirm(
'Are you *REALLY* sure you mean -f when you typed -f? [yes/No] '
)
assume_yes = args.assume_yes

if args.no_sign:
sign = False

if args.local:
if not args.download_url:
Expand Down