diff --git a/scripts/skrooge-release-debian.tar.gz b/scripts/skrooge-release-debian.tar.gz index 11723ccad..73033c725 100644 Binary files a/scripts/skrooge-release-debian.tar.gz and b/scripts/skrooge-release-debian.tar.gz differ diff --git a/scripts/skrooge-release.py b/scripts/skrooge-release.py index 30e391a6a..735d7ce9f 100755 --- a/scripts/skrooge-release.py +++ b/scripts/skrooge-release.py @@ -1,376 +1,376 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- #************************************************************************** #* Copyright (C) 2017 by S. MANKOWSKI / G. DE BURE support@mankowski.fr #* Redistribution and use in source and binary forms, with or without #* modification, are permitted provided that the following conditions #* are met: #* #* 1. Redistributions of source code must retain the above copyright #* notice, this list of conditions and the following disclaimer. #* 2. Redistributions in binary form must reproduce the above copyright #* notice, this list of conditions and the following disclaimer in the #* documentation and/or other materials provided with the distribution. #* #* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR #* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES #* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. #* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, #* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT #* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, #* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY #* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT #* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF #* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #************************************************************************** import argparse import datetime import os import shutil import subprocess import sys import fileinput __VERSION__ = '1.0.0' toolPath=os.path.dirname(os.path.realpath(__file__)) localPath=os.path.dirname(toolPath) tempDir='/data' class Releasor(object): def __init__(self, args): - self.ubuntuVersions=['xenial', 'bionic', 'cuttlefish'] + self.ubuntuVersions=['bionic', 'cosmic'] self.workdingDir=os.path.join(tempDir, 'skrooge-release_' + args.version) print("# Working directory :" + self.workdingDir) if args.version.endswith(".0") or args.stable: self.ppa = "ppa" self.ppatotreat = ["beta", self.ppa] else: self.ppa = "beta" self.ppatotreat = [self.ppa] if os.path.exists(self.workdingDir): self.logfile = open(os.path.join(self.workdingDir, 'log.txt'), 'w') else: self.logfile = None def prepareWorkingDirectory(self, args): print('# Prepare the working directory') if os.path.exists(self.workdingDir): print('# Remove '+self.workdingDir) shutil.rmtree(self.workdingDir) os.mkdir(self.workdingDir) os.chdir(self.workdingDir) self.logfile = open(os.path.join(self.workdingDir, 'log.txt'), 'w') print('# DONE') return 0 def makeTarFile(self, args): print('# Make the tar file') cmd = ['git', 'clone', 'https://github.com/KDE/releaseme.git'] self.logfile.write('### '+' '.join(cmd)+'\n') rc = subprocess.call(cmd, stdout=self.logfile, stderr=self.logfile) if rc == 0: cmd = ['releaseme/tarme.rb', '--version', args.version, '--origin', 'trunk', 'skrooge'] self.logfile.write('### '+' '.join(cmd)+'\n') rc = subprocess.call(cmd, stdout=self.logfile, stderr=self.logfile) shutil.rmtree(os.path.join(self.workdingDir, 'skrooge-'+args.version)) shutil.rmtree('releaseme') os.remove(os.path.join(self.workdingDir, 'release_data')) sig_file = os.path.join(self.workdingDir, 'skrooge-'+args.version+'.tar.xz.sig') if os.path.exists(sig_file): os.remove(sig_file) print('# '+("DONE" if rc == 0 else "FAILED")) return rc def updateTarFile(self, args): print('# Update the tar file') os.chdir(self.workdingDir) p = 'skrooge-'+args.version if os.path.exists(p): shutil.rmtree(p) tarfile = 'skrooge-'+args.version+'.tar.xz' print('# Untar '+tarfile) cmd = ['tar', '-xvf', tarfile] self.logfile.write('### '+' '.join(cmd)+'\n') rc = subprocess.call(cmd, stdout=self.logfile, stderr=self.logfile) if rc == 0: print('# Change the CMakeLists.txt') with open(os.path.join(p, 'CMakeLists.txt'), 'r') as fileCMakeLists: CMakeListsContent = '' for line in fileCMakeLists: if line.startswith('SET(SKG_VERSION'): print('# SKG_VERSION changes to "'+args.version+'"') CMakeListsContent += 'SET(SKG_VERSION "'+args.version+'")\n' else: if line.startswith('SET(SKG_BETA'): bb = 'BETA' if self.ppa == "beta" else '' print('# SKG_BETA changes to "'+bb+'"') CMakeListsContent += 'SET(SKG_BETA "'+bb+'")\n' else: if line.startswith('FEATURE_SUMMARY'): CMakeListsContent += line break else: CMakeListsContent += line with open(os.path.join(p, 'CMakeLists.txt'), 'w') as fileCMakeLists: fileCMakeLists.write(CMakeListsContent) print('# Build the new splash screen') buildPath = os.path.join(p, 'build') os.mkdir(buildPath) os.chdir(buildPath) cmd = ['cmake', '..', '-DCMAKE_INSTALL_PREFIX=`kf5-config --prefix`', '-DQT_PLUGIN_INSTALL_DIR=`kf5-config --qt-plugins`'] self.logfile.write('### '+' '.join(cmd)+'\n') rc = subprocess.call(cmd, stdout=self.logfile, stderr=self.logfile) if rc == 0: cmd = ['make', 'splash'] self.logfile.write('### '+' '.join(cmd)+'\n') rc = subprocess.call(cmd, stdout=self.logfile, stderr=self.logfile) if rc == 0: print('# Create the tar file') os.chdir(self.workdingDir) shutil.rmtree(buildPath) os.remove(tarfile) cmd = ['tar', '-cJf', tarfile, p] rc = subprocess.call(cmd, stdout=self.logfile, stderr=self.logfile) self.logfile.write('### '+' '.join(cmd)+'\n') if rc == 0: cmd = ['gpg2', '--armor', '--detach-sig', '-o', tarfile+'.sig', tarfile] self.logfile.write('### '+' '.join(cmd)+'\n') rc = subprocess.call(cmd, stdout=self.logfile, stderr=self.logfile) if rc == 0: print("Skrooge "+args.version+" released\n\nHi,\n\nCould you publish the following files in skrooge/"+("stable" if args.stable else "unstable")+"?\n") cmd = ['sha256sum', tarfile] self.logfile.write('### '+' '.join(cmd)+'\n') rc = subprocess.call(cmd) if rc == 0: cmd = ['sha256sum', tarfile+'.sig'] self.logfile.write('### '+' '.join(cmd)+'\n') rc = subprocess.call(cmd) print("Thank you.\nRegards.\n" ) if rc == 0: shutil.rmtree(p) print('# '+("DONE" if rc == 0 else "FAILED")) return rc def modify(self, args): print('# Get dsc') os.chdir(self.workdingDir) cmd = ['apt', 'source', 'skrooge'] self.logfile.write('### '+' '.join(cmd)+'\n') rc = subprocess.call(cmd, stdout=self.logfile, stderr=self.logfile) if rc == 0: previousPackage = [os.path.join(self.workdingDir, o) for o in os.listdir(self.workdingDir) if os.path.isdir(os.path.join(self.workdingDir, o)) and o.startswith('skrooge-')][0] print('# previousPackage='+previousPackage) os.chdir(previousPackage) if os.path.exists('debian'): shutil.rmtree('debian') cmd = ['tar', '-xvf', os.path.join(toolPath, 'skrooge-release-debian.tar.gz')] self.logfile.write('### '+' '.join(cmd)+'\n') rc = subprocess.call(cmd, stdout=self.logfile, stderr=self.logfile) if rc == 0: cmd = ['uupdate', '-u', 'skrooge-'+args.version+'.tar.xz'] self.logfile.write('### '+' '.join(cmd)+'\n') rc = subprocess.call(cmd, stdout=self.logfile, stderr=self.logfile) if rc == 0: # Read the changelog os.chdir('../skrooge-'+args.version) with open(os.path.join(self.workdingDir, 'skrooge-'+args.version+'/CHANGELOG'), 'r') as fileChangelog: fileChangelog.readline() # To pass the first line changelogContent = '' done = False for line in fileChangelog: if line.strip() == '' and done == False: changelogContent += ' -- Stephane MANKOWSKI (Perso) {}\n'.format(datetime.datetime.now().strftime('%a, %d %b %Y %H:%M:%S +0100')) done = True if not line.startswith(' -- '): changelogContent += line # for ppa in self.ppatotreat: for i in range(len(self.ubuntuVersions)): print('# {}/{}: {} - {}'.format(i+1, len(self.ubuntuVersions), self.ubuntuVersions[i], ppa)) f = open(os.path.join(self.workdingDir, 'skrooge-'+args.version+'/debian/skrooge-kf5-common.install'), 'r') cf = f.read() f.close() if self.ubuntuVersions[i] == 'xenial' and 'usr/share/metainfo/*.xml' in cf: print('# make changes for '+self.ubuntuVersions[i]) f = open(os.path.join(self.workdingDir, 'skrooge-'+args.version+'/debian/skrooge-kf5-common.install'), 'w') f.write(cf.replace('usr/share/metainfo/*.xml', 'usr/share/appdata/*.xml')) f.close() if self.ubuntuVersions[i] != 'xenial' and 'usr/share/appdata/*.xml' in cf: print('# make changes for '+self.ubuntuVersions[i]) f = open(os.path.join(self.workdingDir, 'skrooge-'+args.version+'/debian/skrooge-kf5-common.install'), 'w') f.write(cf.replace('usr/share/appdata/*.xml', 'usr/share/metainfo/*.xml')) f.close() with open(os.path.join(self.workdingDir, 'skrooge-'+args.version+'/debian/changelog'), 'w') as fileDebianChangelog: fileDebianChangelog.write('skrooge ('+args.version+'-0ubuntu1~'+ppa+str(i+1)+') '+self.ubuntuVersions[i]+'; urgency=medium\n') fileDebianChangelog.write(changelogContent+'\n') cmd = ['debuild', '-S', '-sa'] self.logfile.write('### '+' '.join(cmd)+'\n') rc = subprocess.call(cmd, stdout=self.logfile, stderr=self.logfile) if rc!=0: break if rc!=0: break print('# '+("DONE" if rc == 0 else "FAILED")) return rc def publishLaunchpad(self, args): print('# Publish on launchpad') rc = 0 if not args.publish: print('# Publication ignored') os.chdir(self.workdingDir) for ppa in self.ppatotreat: for i in range(len(self.ubuntuVersions)): print('# {}/{}: {} {}'.format(i+1, len(self.ubuntuVersions), self.ubuntuVersions[i], ppa)) cmd = ['dput', '-f', 'ppa:s-mankowski/'+ppa+'-kf5', 'skrooge_'+args.version+'-0ubuntu1~'+ppa+str(i+1)+'_source.changes'] if not args.publish: print('# '+' '.join(cmd)+'\n') else: self.logfile.write('### '+' '.join(cmd)+'\n') rc = subprocess.call(cmd, stdout=self.logfile, stderr=self.logfile) if rc!=0: break print('# '+("DONE" if rc == 0 else "FAILED")) return rc def publishKDE(self, args): print('# Publish on kde') rc = 0 if not args.publish: print("# Publication ignored") os.chdir(self.workdingDir) cmd = ['kdecp5', 'skrooge-'+args.version+'.tar.xz', 'ftp://upload.kde.org/incoming'] if not args.publish: print('# '+' '.join(cmd)+'\n') else: self.logfile.write('### '+' '.join(cmd)+'\n') rc = subprocess.call(cmd, stdout=self.logfile, stderr=self.logfile) if rc == 0: self.logfile.write('### '+' '.join(cmd)+'\n') cmd = ['kdecp5', 'skrooge-'+args.version+'.tar.xz.sig', 'ftp://upload.kde.org/incoming'] if not args.publish: print('# '+' '.join(cmd)+'\n') else: self.logfile.write('### '+' '.join(cmd)+'\n') rc = subprocess.call(cmd, stdout=self.logfile, stderr=self.logfile) print('# '+("DONE" if rc == 0 else "FAILED")) return rc def buildAppImage(self, args): print('# Generate App Image') os.chdir(self.workdingDir) targteappimage = os.path.join(self.workdingDir, "skrooge-"+args.version+'-x86_64.AppImage') if os.path.exists(targteappimage): os.remove(targteappimage) cmd = ['wget', '-c', '-nv', 'https://raw.githubusercontent.com/probonopd/AppImages/master/pkg2appimage'] self.logfile.write('### '+' '.join(cmd)+'\n') rc = subprocess.call(cmd, stdout=self.logfile, stderr=self.logfile) if rc == 0: for line in fileinput.input(['pkg2appimage'], inplace=True): - print(line.replace('trusty', 'xenial'), end='') + print(line.replace('trusty', 'cosmic'), end='') os.chmod('./pkg2appimage', 0o775) if args.fromlocal: print('# Get appimage.yml from local path') cmd = ['cp', os.path.join(localPath, 'appimage.yml'), '.'] else: cmd = ['wget', '-c', '-nv', 'https://cgit.kde.org/skrooge.git/plain/appimage.yml'] self.logfile.write('### '+' '.join(cmd)+'\n') rc = subprocess.call(cmd, stdout=self.logfile, stderr=self.logfile) if rc == 0: if not args.stable: for line in fileinput.input(['appimage.yml'], inplace=True): print(line.replace('ppa-kf5', 'beta-kf5'), end='') cmd = ['./pkg2appimage', 'appimage.yml'] self.logfile.write('### '+' '.join(cmd)+'\n') rc = subprocess.call(cmd, stdout=self.logfile, stderr=self.logfile) if rc == 0: appimage_file = [os.path.join(self.workdingDir, "out/"+o) for o in os.listdir("./out") if o.endswith('.AppImage')][0] shutil.move(appimage_file, targteappimage) print('# '+("DONE" if rc == 0 else "FAILED")) return rc def buildSnap(self, args): print('# Generate Snap') os.chdir(self.workdingDir) targteappimage = os.path.join(self.workdingDir, "skrooge_"+args.version+'_amd64.snap') if os.path.exists(targteappimage): os.remove(targteappimage) if args.fromlocal: print('# Get snapcraft.yaml from local path') cmd = ['cp', os.path.join(localPath, 'snapcraft.yaml'), '.'] else: cmd = ['wget', '-c', '-nv', 'https://cgit.kde.org/skrooge.git/plain/snapcraft.yaml'] self.logfile.write('### '+' '.join(cmd)+'\n') rc = subprocess.call(cmd, stdout=self.logfile, stderr=self.logfile) if rc == 0: for line in fileinput.input(['snapcraft.yaml'], inplace=True): print(line.replace('version: "X.X.X"', 'version: "'+args.version+'"').replace('source: XXX', 'source: '+localPath if args.fromlocal else 'source: git://anongit.kde.org/skrooge.git'), end='') cmd = ['snapcraft'] self.logfile.write('### '+' '.join(cmd)+'\n') rc = subprocess.call(cmd, stdout=self.logfile, stderr=self.logfile) print('# '+("DONE" if rc == 0 else "FAILED")) # TO PUBLISH https://docs.snapcraft.io/build-snaps/c # snapcraft push --release=edge skrooge_*.snap return rc def main(): parser = argparse.ArgumentParser(prog='skrooge-release', description='skrooge release maker') # Global arguments parser.add_argument('--version', required=True, help='The release version') parser.add_argument('--pwd', required=False, help='The password') parser.add_argument('--stable', action='store_true', help='To define this version as a master version') parser.add_argument('--publish', action='store_true', help='To publish on launchpad and KDE') parser.add_argument('--appimage', action='store_true', help='To generate the appimage only') parser.add_argument('--snap', action='store_true', help='To generate the snap only') parser.add_argument('--fromlocal', action='store_true', help='To generate The snap and the appimage from local path (' + localPath + ')') args = parser.parse_args() print("#####################") print("# Launching release #") print("#####################") print("# Version :" + args.version) print("# Stable :" + ("Y" if args.stable else "N")) print("# Publish :" + ("Y" if args.publish else "N")) print("# Appimage :" + ("Y" if args.appimage else "N")) print("# Snap :" + ("Y" if args.snap else "N")) if args.fromlocal: print("# From local path :" + localPath) # Launch the release r = Releasor(args) rc = 0 rc=r.prepareWorkingDirectory(args) if(rc == 0 and not (args.appimage or args.snap)): rc=r.makeTarFile(args) if(rc == 0 and not (args.appimage or args.snap)): rc=r.updateTarFile(args) if(rc == 0 and not (args.appimage or args.snap)): rc=r.modify(args) if(rc == 0 and not (args.appimage or args.snap)): rc=r.publishLaunchpad(args) if(rc == 0 and not (args.appimage or args.snap)): rc=r.publishKDE(args) if(rc == 0 and args.appimage): rc=r.buildAppImage(args) if(rc == 0 and args.snap): rc=r.buildSnap(args) print("#####################") print("# End of release #" if rc == 0 else "# FAILURE #") print("#####################") return rc if __name__ == '__main__': sys.exit(main())