1

I have a SVN repository for a PHP package that multiple people work together on. We wish to make the package publicly available, so we have added it to packagist with the url svn://svn.xxxx.com/my-package

How do I add a hook to the repository such that whenever a developer makes a commit, packagist is automatically updated, similar to the service hook available in Github?


Update

I managed to find the what I was looking for on this page of packagist with the relevant section below:

enter image description here

I have written a script in PHP to do this for me (simply because I am far more comfortable with PHP than python), for which you will need to install PHP5-cli and php curl packages, which can be done on ubuntu with the following command:

sudo apt-get install php5-cli php5-curl -y

post-commit file

#!/usr/bin/php

<?php

# Code for sending post request taken from:
# https://stackoverflow.com/questions/16920291/post-request-with-json-body

define('API_TOKEN', 'xxx');
define('USER', 'xxx');
define('REPO_URL', 'https://packagist.org/packages/xxx/xxx');
#define('REPO_URL', 'svn://svn.xxx.com/xxx');


$data = array(
    'repository' => array('url' => REPO_URL)
);

// Setup cURL
$url = 'https://packagist.org/api/update-package?username=' . USER . '&apiToken=' . API_TOKEN;
$ch = curl_init($url);

curl_setopt_array($ch, array(
    CURLOPT_POST            => TRUE,
    CURLOPT_RETURNTRANSFER  => TRUE,
    CURLOPT_HTTPHEADER      => array('Content-Type: application/json'),
    CURLOPT_POSTFIELDS      => json_encode($data)
));

// Send the request
$response = curl_exec($ch);

// Check for errors
if ($response === FALSE)
{
    die(curl_error($ch));
}

// Decode the response
$responseData = json_decode($response, TRUE);

// Print the date from the response
var_dump($responseData);

Make sure to chmod +x the file after creating it.

Current Issue

Unfortunately, this I get stuck with the following response error message:

array(2) {
  ["status"]=>
  string(5) "error"
  ["message"]=>
  string(38) "Could not parse payload repository URL"
}

When I var_dump the data I am sending, it is as follows:

string(43) "{"repository":{"url":"xxx/table-creator"}}"
Community
  • 1
  • 1
Programster
  • 12,242
  • 9
  • 49
  • 55
  • I think you have problem with the REPO_URL structure. The error says "Could not parse payload repository URL", which possibly could mean that your composer.json file is not present at the top of your repository. Is your REPO_URL pointing to packagist.org or your svn repository url? It should be pointing to your svn url. – Boris Feb 21 '15 at 17:28
  • Yes, the issue appears to be with the payload url. Thanks for clarifying which URL it is supposed to point to, I am now experimenting with that (still not working). Perhaps packagist does not support the SVN protocol through hooks even though it does manually? Do I need to expand the url with a revision number or something? – Programster Feb 22 '15 at 08:51
  • I just dug through the code and found the url regex that it's expecting, which seems to disqualify svn repositories, but supports git ( updatePackageAction method in https://github.com/composer/packagist/blob/master/src/Packagist/WebBundle/Controller/ApiController.php). Is this a matter of the guys at packagist just not supporting SVN which I concluded from this bug report: https://github.com/composer/packagist/issues/151 – Programster Feb 22 '15 at 09:05
  • 1
    You can expose your svn repository through http/https protocols. Setting up apache svn module is not very difficult. – Boris Feb 22 '15 at 16:34
  • @Boris Yes I'll have to get back to that. Last time I tried I got stuck on "webdav" – Programster Feb 23 '15 at 08:20

1 Answers1

0

You can do this by using svn post-commit hook. This code is very close to what you are asking for. It is written in python, and you can easily rewrite it in bash or even php. I assume that you have standard svn repository structure with the trunk, tags and branches directories. Also, you will have to change package name and directory paths.

#!/usr/bin/env python

import sys
import tempfile
import subprocess
import tarfile
import shutil

SVN = '/usr/bin/svn'
SVNLOOK = '/usr/bin/svnlook'
PACKAGE_NAME = 'my-package'

if __name__ == '__main__':
    repository = sys.argv[1]
    revision = sys.argv[2]

    tmpdir = tempfile.mkdtemp()
    exportdir = tmpdir + '/' + PACKAGE_NAME
    archive = tmpdir + '/' + PACKAGE_NAME + '.tar.gz'

    # Stop hook from running recursively
    cmd = SVNLOOK + ' dirs-changed -r ' + str(revision) + ' ' + repository
    output = subprocess.check_output(cmd, shell = True)
    if 'tags' in output:
        sys.exit(0)

    cmd = SVN + ' export ' + 'file://' + repository + '/trunk ' + exportdir
    output = subprocess.check_output(cmd, shell = True)
    if 'Exported' in output:
        tar = tarfile.open(archive, 'w:gz')
        tar.add(exportdir, arcname = PACKAGE_NAME)
        tar.close()

        # Copy archive to the final destination or add package back to your repository
        # Example 1:
        # shutil.copyfile(archive, '/path/to/new/location/file.tar.gz')

        # Example 2:
        cmd = SVN + ' rm file://' + repository + '/tags/' + PACKAGE_NAME + '.tar.gz -m \"Removed old package.\"'
        output = subprocess.check_output(cmd, shell = True)
        cmd = SVN + ' import ' +  archive + ' file://' + repository + '/tags/' + PACKAGE_NAME + '.tar.gz --force -m \"Imported new package.\"'
        output = subprocess.check_output(cmd, shell = True)

    shutil.rmtree(tmpdir)
    sys.exit(0)

Make sure you add this into the /path/to/repository/hooks/post-commit file, and please test this thoroughly before putting it into the production repository.

Boris
  • 2,275
  • 20
  • 21
  • Thanks for your answer, it contains some useful info, but reading through the script, I can't quite figure out what is going on. I think perhaps my initial question was confusing. Could you read my further update in order to resolve my issue? – Programster Feb 21 '15 at 14:01
  • My answer is only supposed to give you guidelines how to preform post-commit action on repository. Your script looks like it should work fine, except the REPO_URL part. Let me know if you are having issues with it and I'll register for the packagist.org site and try to debug it. – Boris Feb 21 '15 at 18:27