1

I am trying to display the latest version of roundcube. I get the results I want with

curl https://api.github.com/repos/roundcube/roundcubemail/releases | grep tag_name | grep -o "1.2.[0-9]\{1,\}" | sort -n | tail -1

I am trying to work this into a RC plugin, so I have to do this via php and it is not working as I would hope.

<?php
$ch = curl_init();
curl_setopt_array(
$ch, array(
CURLOPT_URL => 'https://api.github.com/repos/roundcube/roundcubemail/releases',
CURLOPT_USERAGENT => $_SERVER['HTTP_USER_AGENT'],
CURLOPT_POSTFIELDS => 'grep tag_name | grep -o \"1.2.[0-9]\{1,\}\" | sort -n | tail -1'));

$output = curl_exec($ch);
echo $output;
?>

It returns

{ "message": "Not Found", "documentation_url": "https://developer.github.com/v3" } 1

Any help is appreciated. Thanks

MultiplyByZer0
  • 6,302
  • 3
  • 32
  • 48

1 Answers1

0

You are setting CURLOPT_POSTFIELDS to grep tag_name | grep -o \"1.2.[0-9]\{1,\}\" | sort -n | tail -1. This has the effect of making a HTTP POST request to the GitHub Releases API, and sending that shell command as the POST data.

There are many problems with your approach:

  1. The /repos/:owner/:repo/releases endpoint only accepts HTTP GET requests. Sending a POST request is not supported and causes an error message.
  2. The grep... commands are not executed by the GitHub servers. They are Unix commands that are executed on your local machine. Therefore, there is no reason to send them as part of the API request.
  3. You should not be using grep and friends to parse the output. The response from the GitHub API is in a standard format called JSON. You should use json_decode instead, which will be faster and more reliable than regular expressions. You can replace the sort command with PHP sorting functions.
  4. If you only want the latest release, you should use the /repos/:owner/:repo/releases/latest endpoint instead. Since this only returns one release, you do not need to sort, and you can access the tag_name attribute directly.
  5. You are missing several important options:

    • CURLOPT_RETURNTRANSFER => true, to have curl_exec actually return the response.
    • CURLOPT_SSL_VERIFYHOST => false and CURLOPT_SSL_VERIFYPEER => false, to disable HTTPS certificate checking, which is annoying to deal with.

Here is how I would implement it:

<?php
$ch = curl_init();
curl_setopt_array($ch, array(
    CURLOPT_URL => 'https://api.github.com/repos/roundcube/roundcubemail/releases/latest',
    CURLOPT_USERAGENT => $_SERVER['HTTP_USER_AGENT'],
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_SSL_VERIFYHOST => false,
    CURLOPT_SSL_VERIFYPEER => false
));
$output = json_decode(curl_exec($ch))->tag_name;
echo $output;
MultiplyByZer0
  • 6,302
  • 3
  • 32
  • 48
  • I looked into that approach to begin with, but I couldn't find anything for a beginner to even begin to figure out how to pull it off ... – texxasrulez May 11 '17 at 01:52
  • @texxasrulez Updated again, and this time it's tested. – MultiplyByZer0 May 11 '17 at 03:10
  • Thank you for your help there. This almost gets it. It displays the first tag_name, but not the highest release. It shows 1.0.11 and 1.2.5 is the highest release. I do have this working as a cronjob to save a text file and print_file_contents in plugin to display version. A pretty backwards work around, but with the example you have shown here helps me learn. I do appreciate your assistance. – texxasrulez May 11 '17 at 03:48
  • @texxasrulez Thanks. I should mention that your shell grep regex (`1.2.[0-9]\{1,\}\ `) will only match versions that begin with `1.2`, and as soon as the package maintainer releases version `1.3`, you will need to update it. – MultiplyByZer0 May 11 '17 at 04:08
  • @texxasrulez In general, it is difficult to write code that attempts to automatically determine the highest release, because version strings can be in almost any format. Roundcube seems to use [semver](http://semver.org/), and you can use PHP parsers for it, but their maintainers might deviate from the standard at any time. It is much easier to determine the version that was released most recently (which is what my code does), as opposed to the highest version. – MultiplyByZer0 May 11 '17 at 04:09
  • I did change it to [0-9].[0-9].[0-9]\{1,\} so I wouldn't have to change it when 1.3 comes out .... I will figure this out ... again Thanks for taking your time helping me ... – texxasrulez May 11 '17 at 04:10