Commit 21eb6cc3 authored by Robert Lyon's avatar Robert Lyon
parents 3c1385e7 fc9180da
#!/usr/bin/python
# Copyright (c) 2009 Canonical Ltd.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any
# later version.
#
# lp-project-upload is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
# Authors:
# Martin Pitt <martin.pitt@ubuntu.com>, based on
# http://blog.launchpad.net/api/recipe-for-uploading-files-via-the-api
# Dustin Kirkland <kirkland@ubuntu.com>
# - support files for changelog and release notes
'''Upload a release tarball to a Launchpad project.'''
import datetime
import os
import sys
import tempfile
from launchpadlib.errors import HTTPError
import subprocess
from lptools import config
def create_release(project, version):
'''Create new release and milestone for LP project.'''
print 'Release %s could not be found for project. Create it? (Y/n)' % \
version
answer = sys.stdin.readline().strip()
if answer.startswith('n'):
sys.exit(0)
n_series = len(project.series)
if n_series == 1:
series = project.series[0]
elif n_series > 1:
msg = 'More than one series exist. Which one would you like to ' \
'upload to? Possible series are (listed as index, name):'
print msg
for idx, serie in enumerate(project.series):
print '\t%i - %s' % (idx, serie.name)
print 'Enter series index: '
answer = sys.stdin.readline().strip()
try:
series = project.series[int(answer)]
except (ValueError, IndexError):
print >> sys.stderr, 'The series index is invalid (%s).' % answer
sys.exit(3)
else:
print "Using series named '%s'" % series.name
else:
print >> sys.stderr, ('Does not support creating releases if no '
'series exists.')
sys.exit(3)
release_date = datetime.date.today().strftime('%Y-%m-%d')
milestone = series.newMilestone(name=version,
date_targeted=release_date)
return milestone.createProductRelease(date_released=release_date)
def edit_file(prefix, description):
(fd, f) = tempfile.mkstemp(prefix=prefix+'.')
os.write(fd, '\n\n#------\n# Please enter the %s here. '
'Lines which start with "#" are ignored.\n' % description)
os.close(fd)
subprocess.call(['sensible-editor', f])
return cat_file(f)
def cat_file(f):
content = ''
for line in open(f):
if line.startswith('#'):
continue
content += line
return content.strip()
def main():
if len(sys.argv) < 4 or len(sys.argv) > 6:
print >> sys.stderr, '''Upload a release tarball to a Launchpad project.
Usage: %s <project name> <version> <tarball> [changelog file] [releasenotes file]''' % sys.argv[0]
sys.exit(1)
new_milestone = None
changelog_file = None
releasenotes_file = None
if len(sys.argv) == 4:
(project, version, tarball) = sys.argv[1:]
elif len(sys.argv) == 5:
(project, version, tarball, changelog_file) = sys.argv[1:]
elif len(sys.argv) == 6:
(project, version, tarball, changelog_file, releasenotes_file) = sys.argv[1:]
print "Uploading..."
launchpad = config.get_launchpad("project-upload")
try:
# Look up the project using the Launchpad instance.
proj = launchpad.projects[project]
# Find the release in the project's releases collection.
release = None
for rel in proj.releases:
if rel.version == version:
release = rel
break
if not release:
for milestone in proj.all_milestones:
if milestone.name == version:
today = datetime.date.today().strftime('%Y-%m-%d')
release = milestone.createProductRelease(date_released=today)
if not release:
release = create_release(proj, version)
# Get the file contents.
file_content = open(tarball, 'r').read()
# Get the signature, if available.
signature = tarball + '.asc'
if not os.path.exists(signature):
print 'Calling GPG to create tarball signature...'
cmd = ['gpg', '--armor', '--sign', '--detach-sig', tarball]
if subprocess.call(cmd) != 0:
print >> sys.stderr, 'gpg failed, aborting'
if os.path.exists(signature):
signature_content = open(signature, 'r').read()
else:
signature_content = None
# Create a new product release file.
filename = os.path.basename(tarball)
release.add_file(filename=filename, description='release tarball',
file_content=file_content, content_type='application/x-gzip',
file_type='Code Release Tarball', signature_filename=signature,
signature_content=signature_content)
if changelog_file is not None:
changelog = cat_file(changelog_file)
else:
changelog = edit_file('changelog', 'changelog')
if changelog:
release.changelog = changelog
if releasenotes_file is not None:
release_notes = cat_file(releasenotes_file)
else:
release_notes = edit_file('releasenotes', 'release notes')
if release_notes:
release.release_notes = release_notes
release.lp_save()
# Create a new milestone if requested
if new_milestone is not None:
mil = release.milestone
for series in proj.series:
if mil.name in [milestone.name for milestone in series.all_milestones]:
series.newMilestone(name=new_milestone)
except HTTPError, error:
print 'An error happened in the upload:', error.content
sys.exit(1)
if __name__ == '__main__':
main()
......@@ -13,32 +13,37 @@ define('CLI', 1);
# the changelog.
#
$usage = <<<STRING
Usage is ${argv[0]} [version] [branch] [<changesetnumber>...]
e.g. ${argv[0]} 16.04.3 16.04_STABLE
e.g. ${argv[0]} 15.10.1 15.10_STABLE 5793 5795
STRING;
if (count($argv) < 3) {
echo "Usage is ${argv[0]} [version] [branch] [<patchfile>...]";
echo "e.g. ${argv[0]} 16.04.3 16.04_STABLE";
echo "e.g. ${argv[0]} 15.10.1 15.10_STABLE";
echo $usage;
exit(1);
}
# Check for git gpg lp-project-upload
if (!@is_executable('/usr/bin/gpg')) {
echo "You need to install gpg: apt-get install gnupg";
echo "You need to install gpg: apt-get install gnupg\n";
exit(1);
}
if (!@is_executable('/usr/bin/git')) {
echo "You need to install git: apt-get install git-core";
echo "You need to install git: apt-get install git-core\n";
exit(1);
}
if (!@is_executable('/usr/bin/lp-project-upload')) {
echo "You need to install lp-project-upload: apt-get install ubuntu-dev-tools (maverick or earlier) or lptools";
echo "You need to install lp-project-upload: apt-get install ubuntu-dev-tools (maverick or earlier) or lptools\n";
exit(1);
}
if (!@is_executable('/usr/bin/m4')) {
echo "You need to install m4: apt-get install m4";
echo "You need to install m4: apt-get install m4\n";
exit(1);
}
......@@ -46,7 +51,7 @@ $GIT_MAJOR = `git --version | cut -d' ' -f 3 | cut -d'.' -f 1`;
$GIT_MINOR = `git --version | cut -d' ' -f 3 | cut -d'.' -f 2`;
if ($GIT_MAJOR < 1 || ($GIT_MAJOR == 1 && $GIT_MINOR < 6 )) {
echo "Your version of git is too old. Install git 1.6.";
echo "Your version of git is too old. Install git 1.6.\n";
exit(1);
}
......@@ -56,7 +61,8 @@ $VERSION=$argv[1];
$result = preg_match('/([0-9]+\.[0-9]+)(\.|rc)([0-9]+)/i', $VERSION, $matches);
if (!$result) {
echo "Invalid version number. It must match the pattern \"15.04.1\" or \"15.04rc1\".";
echo "Invalid version number. It must match the pattern \"15.04.1\" or \"15.04rc1\".\n";
echo $usage;
exit(1);
}
$MAJOR = $matches[1];
......@@ -114,6 +120,36 @@ passthru("git fetch -q mahara");
passthru("git checkout -b ${BRANCH} mahara/${BRANCH}");
passthru("git fetch -q -t");
// Applying gerrit patches named on the command line
if (count($argv) > 3) {
$successwithpatches = true;
for ($i = 3; $i < count($argv); $i++) {
$patchno = $argv[$i];
$refline = shell_exec("ssh reviews.mahara.org -p 29418 gerrit query --current-patch-set --format=TEXT change:'{$patchno}'| grep ref");
if ($refline) {
$result = preg_match('#ref: (refs/changes/[/0-9]+)#', $refline, $matches);
if ($result) {
$return_var = passthru("git fetch ssh://reviews.mahara.org:29418/mahara {$matches[1]} && git cherry-pick FETCH_HEAD");
if ($return_var != 0) {
echo "Couldn't cherry-pick Gerrit change number {$patchno}.\n";
$successwithpatches = false;
}
}
else {
echo "Couldn't find latest patch number for Gerrit change number {$patchno}.\n";
$succesoverall = false;
}
} else {
echo "Couldn't retrieve information about Gerrit change number {$patchno}.\n";
$successwithpatches = false;
}
}
if (!$successwithpatches) {
exit();
}
}
# Edit ChangeLog
if (!file_exists("ChangeLog")) {
echo "The ChangeLog file is missing and this is a stable release. Create an empty file called ChangeLog and commit it.";
......@@ -163,7 +199,7 @@ passthru("git tag -s ${RELEASETAG} -m \"$RELEASE release\"");
# Build the css
if ($OLDVERSION >= 2015091700) {
echo "Building css...\n";
echo `make css >> ../css.log 2>&1`;
passthru("make css >> ../css.log 2>&1");
if (!file_exists('htdocs/theme/raw/style/style.css')) {
echo "CSS files did not build correctly! Check $BUILDDIR/css.log for details.";
exit(1);
......@@ -234,14 +270,17 @@ else {
# Prepare release notes
// TODO: Replace this with a simple find/replace, to remove the m4 dependency
$TMP_M4_FILE = '/tmp/mahara-releasenotes.m4.tmp';
passthru("sed 's/^/ * /g' ${CURRENTDIR}/changes.temp >> ${CURRENTDIR}/changes.withasterisks.temp");
$m4script = <<<STRING
changecom
define(\\`__RELEASE__',\\`${RELEASE}')dnl
define(\\`__OLDRELEASE__',\\`${OLDRELEASE}')dnl
define(\\`__MAJOR__',\\`${MAJOR}')dnl
define(`__RELEASE__',`${RELEASE}')dnl
define(`__OLDRELEASE__',`${OLDRELEASE}')dnl
define(`__MAJOR__',`${MAJOR}')dnl
define(`__CHANGES__',`include(`${CURRENTDIR}/changes.withasterisks.temp')')dnl
STRING;
file_put_contents($TMP_M4_FILE, $m4script);
if ($releasecandidate) {
$TEMPLATE = 'releasenotes.rc.template';
}
......@@ -280,9 +319,9 @@ gpg --armor --sign --detach-sig ${CURRENTDIR}/mahara-${RELEASE}.tar.bz2
gpg --armor --sign --detach-sig ${CURRENTDIR}/mahara-${RELEASE}.zip
cd ${CURRENTDIR}
lp-project-upload mahara ${RELEASE} mahara-${RELEASE}.tar.gz
lp-project-upload mahara ${RELEASE} mahara-${RELEASE}.tar.bz2
lp-project-upload mahara ${RELEASE} mahara-${RELEASE}.zip
${CURRENTDIR}/lptools/lp-project-upload mahara ${RELEASE} mahara-${RELEASE}.tar.gz changes.withasterisks.temp releasenotes-${RELEASE}.txt
${CURRENTDIR}/lptools/lp-project-upload mahara ${RELEASE} mahara-${RELEASE}.tar.bz2 changes.withasterisks.temp releasenotes-${RELEASE}.txt
${CURRENTDIR}/lptools/lp-project-upload mahara ${RELEASE} mahara-${RELEASE}.zip changes.withasterisks.temp releasenotes-${RELEASE}.txt
echo
echo "All done. Once you've checked that the files were uploaded successfully, run this:"
......@@ -293,10 +332,11 @@ file_put_contents($CLEANUPSCRIPT, $cleanup);
chmod($CLEANUPSCRIPT, 0700);
# Clean up
passthru("rm ${VERSIONFILE}.temp");
passthru("rm ${CURRENTDIR}/ChangeLog.temp");
passthru("rm ${CURRENTDIR}/changes.temp");
passthru("rm ${TMP_M4_FILE}");
// Let people clean these up manually. They might be useful for debugging.
// passthru("rm ${VERSIONFILE}.temp");
// passthru("rm ${CURRENTDIR}/ChangeLog.temp");
// passthru("rm ${CURRENTDIR}/changes.temp");
// passthru("rm ${TMP_M4_FILE}");
echo "\n\nTarballs, release notes & changelog for Launchpad:\n\n";
chdir($CURRENTDIR);
......
This diff is collapsed.
......@@ -10,6 +10,3 @@ upgrade, we encourage you to make a copy of your website and test the
upgrade on it first, to minimise the effect of any potential
unforeseen problems.
Changes from __OLDRELEASE__:
__CHANGES__
\ No newline at end of file
<?php
/**
* This is a (very minimal) command-line script to help search the Mahara
* code base for broken URLs.
*/
/**
* Part 1: Run this to locate files with URLs in them. Pipe those to a CSV file.
*/
// $dir = '../test';
// exec('find ' . $dir . ' -type f -exec grep -PHIon \'https?://([a-z]+\.)?mahara.org([^\s"]+)\' {} \;', $results);
// foreach ($results as $match) {
// list($file, $line, $url) = explode(':', $match, 3);
// echo csvescape($file) . ',' . csvescape($line) . ',' . csvescape($url) . "\n";
// }
// function csvescape($string) {
// return '"' . str_replace('"', '""', $string) . '"';
// }
/**
* Part 2: Manually check the URLs in the CSV file and clean up any that have
* formatting on them still (like '; on the end). Finding these automatically
* would require parsing every type of language in Mahara, so it's easier to
* just look at them manually. Also look for \' and \" to replace them with
* ' and "
*/
/**
* Part 3: Pipe in the cleaned CSV file. The script will now check every
* URL to make sure it's valid.
*/
$filename = 'urls-cleaned.csv';
$lines = file($filename, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$urlschecked = array();
foreach ($lines as $line) {
// This might not work, depending on how fancy the CSV-export in your
// spreadsheet is.
list($file, $line, $url) = explode(',', $line);
if (isset($urlschecked[$url])) {
$status = $urlschecked[$url];
}
else {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_exec($ch);
$status = curl_getinfo($ch);
curl_close($ch);
$status = $status['http_code'];
$urlschecked[$url] = $status;
}
if ($status != 200) {
echo "$file : $line : $url : STATUS $status\n";
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment