<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Recent changes to Using the Release API</title><link>https://sourceforge.net/p/forge/documentation/Using%2520the%2520Release%2520API/</link><description>Recent changes to Using the Release API</description><atom:link href="https://sourceforge.net/p/forge/documentation/Using%20the%20Release%20API/feed" rel="self"/><language>en</language><lastBuildDate>Fri, 22 Apr 2022 21:27:24 -0000</lastBuildDate><atom:link href="https://sourceforge.net/p/forge/documentation/Using%20the%20Release%20API/feed" rel="self" type="application/rss+xml"/><item><title>Using the Release API modified by SourceForge Support</title><link>https://sourceforge.net/p/forge/documentation/Using%2520the%2520Release%2520API/</link><description>&lt;div class="markdown_content"&gt;&lt;pre&gt;--- v1
+++ v2
@@ -12,7 +12,7 @@

 The typical release process on SourceForge used to look like this:

-1. [Upload your new files via SFTP, SCP, or rsync](documentation:Release Files for Download).
+1. [Upload your new files via SFTP, SCP, or rsync](documentation: Release Files for Download).
 2. Use the web interface to set the new files as the default downloads for their appropriate platforms.

 The first step was easily scriptable as part of a release process. The second step was manual, which was a problem. One of Larry Wall's [programmer virtues](http://en.wikipedia.org/wiki/Larry_Wall#Virtues_of_a_programmer) is laziness and having to take a manual step is a violation of that virtue. Here's the good news: that second step is now also automatable via a RESTful API. Here is how you can use that API to automate your entire release process.
@@ -54,7 +54,7 @@
 -d "default=windows&amp;amp;default=mac&amp;amp;default=linux&amp;amp;default=bsd&amp;amp;default=solaris&amp;amp;default=others"
 ~~~~

-In our case we want to set the `default` property (i.e., the default download) to a selection of different OSes. Your own data may vary depending on your situation; for example, you may only need to specify Windows for `.exe` or `.msi` files.
+In our case, we want to set the `default` property (i.e., the default download) to a selection of different OSes. Your data may vary depending on your situation; for example, you may only need to specify Windows for `.exe` or `.msi` files.

 Other possible parameters besides `default` are:

@@ -68,7 +68,7 @@

 The next piece of data could have been included above, but it is important enough to examine separately. The API key is how we know this request is coming from you. Once we have the API key, we will use your permissions in determining whether or not the file can be updated.

-Please treat the API key as a password. Don't share it with others. Don't include it in your script. Have your script read the password from a local config file. If you have multiple people in your project with the ability to do a release, they should each have their own API key. Finally: make sure you're always transmitting your API key over a secured connection, i.e., HTTPS.
+Please treat the API key as a password. Don't share it with others. Don't include it in your script. Have your script read the password from a local config file. If you have multiple people in your project with the ability to do a release, they should each have their API key. Finally: make sure you're always transmitting your API key over a secured connection, i.e., HTTPS.

 ----

@@ -90,7 +90,7 @@
 https://sourceforge.net/projects/[PROJECT NAME]/files/[FILE PATH]
 ~~~~

-Note the "https": keep your API key safe!
+Note the "HTTPS": keep your API key safe!

 We are back to the full command:

@@ -146,8 +146,9 @@
 }
 ~~~~

-In this case the JSON object is the file object, with all of its attributes, including the updated data. You can see the `default` attribute above now lists all the OSes we submitted in our PUT request.
+In this case, the JSON object is the file object, with all of its attributes, including the updated data. You can see the `default` attribute above now lists all the OSes we submitted in our PUT request.

-To check which which file is currently marked as default, use the `http://sourceforge.net/projects/[PROJECT NAME]/best_release.json` API.   The first section of that result will vary depending on the User-Agent requested, so you can specify an android user-agent for example, to see what it is for android.  The `platform_releases` section below it is for convenience since win/mac/linux are the most popular platforms.  Note it may be delayed slightly if you have just changed a default flag.  Example:
+To check which file is currently marked as default, use the `http://sourceforge.net/projects/[PROJECT NAME]/best_release.json` API.   The first section of that result will vary depending on the User-Agent requested, so you can specify an android user-agent for example, to see what it is for android.  The `platform_releases` section below it is for convenience since win/mac/linux are the most popular platforms.  Note it may be delayed slightly if you have just changed a default flag.  Example:

     curl -s -A 'Mozilla/5.0 (Windows NT 6.1) ...' "http://sourceforge.net/projects/[PROJECT NAME]/best_release.json"
+
&lt;/pre&gt;
&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">SourceForge Support</dc:creator><pubDate>Fri, 22 Apr 2022 21:27:24 -0000</pubDate><guid>https://sourceforge.net4c389f4d5e7391ad293564ef693cc81a34494e6f</guid></item><item><title>Using the Release API modified by Dave Brondsema</title><link>https://sourceforge.net/p/forge/documentation/Using%2520the%2520Release%2520API/</link><description>&lt;div class="markdown_content"&gt;&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#intended-audience"&gt;Intended Audience&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#purpose"&gt;Purpose&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#making-the-request"&gt;Making the Request&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#the-response"&gt;The Response&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1 id="intended-audience"&gt;Intended Audience&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;Level:&lt;/strong&gt; Advanced&lt;/p&gt;
&lt;p&gt;The release API is a tool for project admins and release techs. We will be using the command line tool &lt;code&gt;curl&lt;/code&gt; and discussing basic HTTP and REST API concepts.&lt;/p&gt;
&lt;h1 id="purpose"&gt;Purpose&lt;/h1&gt;
&lt;p&gt;The typical release process on SourceForge used to look like this:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a class="" href="/p/forge/documentation/Release%20Files%20for%20Download/"&gt;Upload your new files via SFTP, SCP, or rsync&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Use the web interface to set the new files as the default downloads for their appropriate platforms.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The first step was easily scriptable as part of a release process. The second step was manual, which was a problem. One of Larry Wall's &lt;a class="" href="http://en.wikipedia.org/wiki/Larry_Wall#Virtues_of_a_programmer" rel="nofollow"&gt;programmer virtues&lt;/a&gt; is laziness and having to take a manual step is a violation of that virtue. Here's the good news: that second step is now also automatable via a RESTful API. Here is how you can use that API to automate your entire release process.&lt;/p&gt;
&lt;h1 id="making-the-request"&gt;Making the Request&lt;/h1&gt;
&lt;p&gt;We will walk through using &lt;code&gt;curl&lt;/code&gt; to interact with the API, but you should be able to adapt this process to a variety of release scripts. Here is the full command; we will look at each part in detail:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="n"&gt;curl&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;H&lt;/span&gt; &lt;span class="s"&gt;"Accept: application/json"&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="n"&gt;PUT&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="s"&gt;"default=windows&amp;amp;default=mac&amp;amp;default=linux&amp;amp;default=bsd&amp;amp;default=solaris&amp;amp;default=others"&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="s"&gt;"api_key=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"&lt;/span&gt; &lt;span class="nl"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//sourceforge.net/projects/[PROJECT NAME]/files/[FILE PATH]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The API uses JSON, so the first step is to let SourceForge know that you will accept a JSON response by sending the appropriate &lt;a class="" href="http://www.gethifi.com/blog/browser-rest-http-accept-headers" rel="nofollow"&gt;Accept header&lt;/a&gt;:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;-H "Accept: application/json"
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Note that while the header is optional, it ensures you will always get a JSON response.&lt;/p&gt;
&lt;hr/&gt;
&lt;p&gt;&lt;strong&gt;RESTful Grammar&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;RESTful APIs always pair an action (the verb) with a resource (the noun). For HTTP, the verbs are the HTTP methods &lt;a class="" href="http://en.wikipedia.org/wiki/Representational_state_transfer#RESTful_web_services" rel="nofollow"&gt;POST, GET, PUT, and DELETE&lt;/a&gt;. These verbs correspond with Create, Read, Update, and Delete operations (&lt;a class="" href="http://en.wikipedia.org/wiki/Create,_read,_update_and_delete" rel="nofollow"&gt;CRUD&lt;/a&gt;).&lt;/p&gt;
&lt;hr/&gt;
&lt;p&gt;Since we're updating information about a file, we need to specify the HTTP method PUT:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;-X PUT
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Next comes that data, the new information with which we want to update our file. For curl, this data is specified as a &lt;a class="" href="http://en.wikipedia.org/wiki/Query_string#URL_encoding" rel="nofollow"&gt;URL-encoded string&lt;/a&gt;, like so:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;-d "default=windows&amp;amp;default=mac&amp;amp;default=linux&amp;amp;default=bsd&amp;amp;default=solaris&amp;amp;default=others"
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;In our case we want to set the &lt;code&gt;default&lt;/code&gt; property (i.e., the default download) to a selection of different OSes. Your own data may vary depending on your situation; for example, you may only need to specify Windows for &lt;code&gt;.exe&lt;/code&gt; or &lt;code&gt;.msi&lt;/code&gt; files.&lt;/p&gt;
&lt;p&gt;Other possible parameters besides &lt;code&gt;default&lt;/code&gt; are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;download_label&lt;/code&gt; which is the text used for the download button&lt;/li&gt;
&lt;li&gt;&lt;code&gt;stage&lt;/code&gt; - for folders only.  If set, will "stage" the folder, making it not listed for 3 days.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;name&lt;/code&gt; which will rename the file&lt;/li&gt;
&lt;/ul&gt;
&lt;hr/&gt;
&lt;p&gt;&lt;strong&gt;Keep It Secret&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The next piece of data could have been included above, but it is important enough to examine separately. The API key is how we know this request is coming from you. Once we have the API key, we will use your permissions in determining whether or not the file can be updated.&lt;/p&gt;
&lt;p&gt;Please treat the API key as a password. Don't share it with others. Don't include it in your script. Have your script read the password from a local config file. If you have multiple people in your project with the ability to do a release, they should each have their own API key. Finally: make sure you're always transmitting your API key over a secured connection, i.e., HTTPS.&lt;/p&gt;
&lt;hr/&gt;
&lt;p&gt;Here is how to get your API key:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Go to your account page.&lt;/li&gt;
&lt;li&gt;Click on the "Generate" button under the Releases API Key.&lt;/li&gt;
&lt;li&gt;Copy and paste the key that appears into your script's config file, etc.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Once you have the API key, pass it along with the rest of the data as the &lt;code&gt;api_key&lt;/code&gt; parameter:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;-d "api_key=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The last piece of the puzzle is to specify the REST noun: the file we're updating. SourceForge files follow a predictable URL pattern: &lt;code&gt;https://sourceforge.net/projects/[PROJECT NAME]/files/[FILE PATH]&lt;/code&gt;. You can also get the URL by right-clicking on the file in the Files web interface and selecting Copy Link. You will get the download URL, which is actually &lt;code&gt;https://sourceforge.net/projects/[PROJECT NAME]/files/[FILE PATH]/download&lt;/code&gt;, so remove the &lt;code&gt;/download&lt;/code&gt; string at the end and you will have the correct URL:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="nl"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//sourceforge.net/projects/[PROJECT NAME]/files/[FILE PATH]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Note the "https": keep your API key safe!&lt;/p&gt;
&lt;p&gt;We are back to the full command:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="n"&gt;curl&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;H&lt;/span&gt; &lt;span class="s"&gt;"Accept: application/json"&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="n"&gt;PUT&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="s"&gt;"default=windows&amp;amp;default=mac&amp;amp;default=linux&amp;amp;default=bsd&amp;amp;default=solaris&amp;amp;default=others"&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="s"&gt;"api_key=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"&lt;/span&gt; &lt;span class="nl"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//sourceforge.net/projects/[PROJECT NAME]/files/[FILE PATH]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Once you make that request, you will get JSON in response.&lt;/p&gt;
&lt;h1 id="the-response"&gt;The Response&lt;/h1&gt;
&lt;p&gt;There are two basic responses: success and error. Here is what the JSON response looks like when there is an error:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;{ "error": "You are not authorized for this operation." }
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The actual error message may vary, but the error attribute will be present and set to a &lt;a class="" href="http://james.padolsey.com/javascript/truthy-falsey/" rel="nofollow"&gt;truthy&lt;/a&gt; value in the JSON object.&lt;/p&gt;
&lt;p&gt;Here is what you will see when everything works:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;{
  "result": {
    "file_type": "C program text (Zip archive data)",
    "explicitly_staged": false,
    "date": "Fri, 01 Jan 2000 12:00:00 GMT",
    "mtime": 100000000,
    "id": 1,
    "size": 10000,
    "x_sf": {
      "default": "windows,mac,linux,bsd,solaris,others"
    },
    "x_stage": 0,
    "downloadable": true,
    "stage": 0,
    "type": "f",
    "mime_type": "application\/x-zip",
    "staged_dir": 0,
    "vscan": "OK",
    "path": "",
    "crtime": 1262354489,
    "md5": "...",
    "sha1": "...",
    "name": "foo-1.0.0.zip",
    "staged": false,
    "modified": "Fri, 01 Jan 2000 12:00:00 GMT",
    "project": "example",
    "vscan_prog": null,
    "vscan_when": null
  }
}
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;In this case the JSON object is the file object, with all of its attributes, including the updated data. You can see the &lt;code&gt;default&lt;/code&gt; attribute above now lists all the OSes we submitted in our PUT request.&lt;/p&gt;
&lt;p&gt;To check which which file is currently marked as default, use the &lt;code&gt;http://sourceforge.net/projects/[PROJECT NAME]/best_release.json&lt;/code&gt; API.   The first section of that result will vary depending on the User-Agent requested, so you can specify an android user-agent for example, to see what it is for android.  The &lt;code&gt;platform_releases&lt;/code&gt; section below it is for convenience since win/mac/linux are the most popular platforms.  Note it may be delayed slightly if you have just changed a default flag.  Example:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="n"&gt;curl&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;Mozilla&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;5.0&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Windows&lt;/span&gt; &lt;span class="n"&gt;NT&lt;/span&gt; &lt;span class="mf"&gt;6.1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt; &lt;span class="s"&gt;"http://sourceforge.net/projects/[PROJECT NAME]/best_release.json"&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Dave Brondsema</dc:creator><pubDate>Fri, 19 Feb 2016 17:43:09 -0000</pubDate><guid>https://sourceforge.nete67ffd4dab4c9cb21eeb0f5550277303e74e6abf</guid></item></channel></rss>