Introduction
This tutorial provides instructions to create a REST Plugin called SampleGithubREST
that has two functional procedures as described below. These are implemented using the GitHub REST APIs.
-
getUser
, which takes ausername
and returns user information. -
Create Release
, which creates aRelease
and uploads an artifact associated with that release, to a repository.
Prerequisites
These are assumptions for this Tutorial.
-
Introductory tutorial has been completed.
-
pdk
is installed and setup. -
An active CloudBees CD/RO instance.
-
Internet connection.
-
A GitHub account.
-
Write access to a Git repository.
-
An asset (for example a zip file) that can be uploaded to this repository.
Step 1 : Generate a plugin using sample spec from GitHub
After making sure pdk
is available in your PATH
, create a plugin
workspace, typing the name SampleGithubREST
for the plugin. Copy
pluginspec.yaml
from the cloned repository to the config directory of
your plugin and generate the plugin.
cd ~/work git clone https://github.com/electric-cloud-community/flowpdf ~/temp `pdk generate workspace` cp ~/temp/flowpdf/perl/SampleGithubREST/config/pluginspec.yaml SampleGithubREST/config cd SampleGithubREST `pdk generate plugin`
Once done, it should look like this.
INFO: Working in /vagrant/flowpdk/SampleGithubREST INFO: Fetching repository from https://github.com/electric-cloud/flowpdf-plugin-layout.git INFO: Switching to the ref origin/master INFO: Loaded version 1.1.0 from the manifest INFO: Inflated plugin metafile (plugin.xml) INFO: Generated promote.groovy INFO: Inflated demote.groovy INFO: Wrote ec_setup.pl INFO: Wrote initial README.md INFO: Wrote BasePlugin.groovy INFO: Saved generic check connection step INFO: Generated procedure.dsl for the CreateConfiguration procedure INFO: Wrote createConfiguration.pl step INFO: Created DeleteConfiguration/procedure.dsl INFO: Inflated form for DeleteConfiguration INFO: Created step for DeleteConfiguration INFO: Saved procedure.dsl for the EditConfiguration procedure INFO: Configuration has been inflated INFO: Saved procedure.dsl for the procedure Get User INFO: Saved form.xml for the procedure Get User INFO: Fetching repository from https://github.com/electric-cloud/flowpdf-perl-lib.git INFO: Switching to the ref origin/master INFO: Loaded version 1.2.0 from the manifest INFO: Updated Flow Logic class INFO: Wrote step code for step Get User: Get User INFO: Copied Perl core library files INFO: Generated editable boilerplate: dsl/properties/perl/lib/FlowPlugin/SampleGithubREST.pm INFO: Generated editable boilerplate: dsl/properties/perl/lib/FlowPlugin/SampleGithubRESTRESTClient.pm INFO: Inflating REST Client SampleGithubRESTRESTClient INFO: Saved procedure.dsl for the procedure Create Release INFO: Saved form.xml for the procedure Create Release INFO: Updated Flow Logic class INFO: Wrote step code for step Create Release: Create Release INFO: Copied Perl core library files INFO: Generated editable boilerplate: dsl/properties/perl/lib/FlowPlugin/SampleGithubREST.pm INFO: Generated editable boilerplate: dsl/properties/perl/lib/FlowPlugin/SampleGithubRESTRESTClient.pm INFO: Inflating REST Client SampleGithubRESTRESTClient INFO: Icon placeholder is placed into /vagrant/flowpdk/SampleGithubREST/htdocs/pdfperl/icon-plugin.svg INFO: Copied Perl core library files INFO: Generated editable boilerplate: dsl/properties/perl/lib/FlowPlugin/SampleGithubREST.pm INFO: Generated editable boilerplate: dsl/properties/perl/lib/FlowPlugin/SampleGithubRESTRESTClient.pm INFO: Inflating REST Client SampleGithubRESTRESTClient INFO: Inflated core library perl INFO: Setting Perl core repository version to 1.2.0 in the flowpdf pluginspec
Step 2 : Build a plugin
Build the plugin as follows.
vagrant@commander5:/vagrant/flowpdk/SampleGithubREST$ flowpdk build Plugin Key: SampleGithubREST Plugin Version: 1.0.0.0 INFO: Added fallback code to the ec_setup.pl Adding plugin icon pdfperl/icon-plugin.svg Adding folder /vagrant/flowpdk/SampleGithubREST/config to the archive Adding folder /vagrant/flowpdk/SampleGithubREST/htdocs to the archive Adding folder /vagrant/flowpdk/SampleGithubREST/pages to the archive Archive /vagrant/flowpdk/SampleGithubREST/build/SampleGithubREST.zip has been created
Step 3 : Apply and test the plugin for checkconnection
Using the CloudBees CD/RO plugin manager, upload the zip from the previous step and create a plugin configuration. If this step is successful you should be able to add the plugin in a pipeline task as in the picture below. Note that the procedures may still not be fully functional. The purpose of this step is to verify that the built plugin from the previous step can successfully connect to GitHub.
Step 4 : Modify the plugin
While the plugin has generated code for Create Release
and Get User
from
the previous steps, what is missing is that the Create Release
would
require an artifact to be uploaded. This is implemented using the
following approach.
In SampleGithubRESTRESTClient.pm
define a new method called
_uploadReleaseAsset
in the REST client module, which can upload to
GitHub based on an asset path provided.
sub _uploadReleaseAsset { my ($self, $request, $params) = @_; my $assetPath = $params->{assetPath} or die "No asset path was provided"; my $length = -s $assetPath; open my $fh, $assetPath or die "Cannot open $assetPath: $!"; binmode $fh; my $content = join '' => <$fh>; close $fh; $request->content($content); $request->header('Content-Length', $length); my $uri = $request->uri; $uri->host('uploads.github.com'); if ($params->{assetName}) { $uri->query_form(name => $params->{assetName}); } $request->uri($uri); return $request; }
Then, extend augmentRequest
to trigger _uploadReleaseAsset
. In essence,
this ensures that when uploadReleaseAsset
gets called, the
augmentRequest
that kicks in calls _uploadReleaseAsset
.
sub augmentRequest { my ($self, $r, $params) = @_; # empty, for user to fill if ($self->method eq 'uploadReleaseAsset') { $r = $self->_uploadReleaseAsset($r, $params); } return $r; }
In SampleGithubREST.pm
extend createRelease
in the following ways.
-
Get the parameters from the step.
-
Invoke the REST API to get the
Release by
tag name. -
Invoke the
createRelease
REST API if a release does not exist. -
Call
uploadReleaseAsset
.
sub createRelease { my ($pluginObject, $r) = @_; my $context = $pluginObject->getContext(); my $params = $context->getStepParameters(); my $client = $pluginObject->getSampleGithubRESTRESTClient; # If you have changed your parameters in the procedure declaration, add/remove them here my %restParams = ( repositoryOwner => $params->getParameter('repositoryOwner')->getValue, repositoryName => $params->getParameter('repositoryName')->getValue, tag_name => $params->getParameter('tagName')->getValue, name => $r->{NAME}, ); my $release = eval { $client->getReleaseByTagName(%restParams, tag => $params->getParameter('tagName')->getValue); }; if (!$release) { $release = $client->createRelease(%restParams); } logInfo "Release: ", $release; my $releaseId = $release->{id}; my $asset = eval { $client->uploadReleaseAsset( %restParams, releaseId => $releaseId, assetPath => $params->getParameter('assetPath')->getValue, assetName => $r->{assetName}, ); }; logInfo "Asset", $asset; logInfo("Got response from the server: ", $release); my $stepResult = $context->newStepResult; $stepResult->apply(); }
Step 5 : Apply and test the plugin for Create Release
Run the Create Release
as in the picture below. Note the following:
-
The Repository Owner is the name of the organization.
-
If the Release Name is blank, it defaults to the name of the Tag.
Running the above creates the following:
Step 6: Summary
This summary is provided in order to help a developer conceptualize the steps involved in the creation of this plugin.
-
Specification
-
pluginspec.yaml
provides the declarative interface for the plugin procedures (Create Release, Get User) as well as their dependencies viz., the REST methods getReleaseTagByName and uploadReleaseAsset. -
The interface specification in
pluginspec.yaml
for the Create Release and Get User procedures, include REST end points that help implement their functionality.
-
-
Generated code
-
pdk
generates boiler plate code for procedures inSampleGithubREST.pm
as well asSampleGithubRESTRESTClient.pm
. The former consists of boiler plate code for collecting step parameters and the later for making REST calls. -
pdk
generates boiler plate code for all REST MethodsuploadReleaseAsset
,getReleaseByTagName
,createRelease
andgetUser
all in the REST client module.
-
-
User Modifications
-
Implement a new method called
_uploadReleaseAsset
to upload the asset. -
Extend
uploadReleaseAsset
by usingaugmentRequest
to call_uploadReleaseAsset
.
-