This guide will walk through everything needed in order to build a FlexDeploy Project with a GitHub webhook.
Table of Contents |
---|
Getting a GitHub message into FlexDeploy
The very first step before we can consider building a project is to simply get a Github message into FlexDeploy so we know what we are dealing with. For this to occur there are 4 things we need
A FlexDeploy Webhook Provider for GitHub
A FlexDeploy Webhook Function - this is what will ultimately build our Project
A public endpoint for GitHub to send the message to.
A GitHub Repository with Webhooks enabled.
Creating the GitHub Provider
Navigate to Administration → Incoming Webhooks
Click the Configuration button in the top right of the page, and then the button at the top right of the table to create a new Provider.
First lets edit the match script by changing tabs. I am simply going to return true here to allow any message through (we will update this later on but right now we just want the message to get through). Click Save.
Creating a BuildProject Function
Now that we have our Provider, navigate back to the Webhook Configuration screen. You should now see your GitHub Provider row in the table. Click Create Function in the row's context menu or click the button at the top right of the table to create a Function for the GitHub Provider.
Similar to the Provider Script, we will circle back here and flesh this out, but for now we just simply log that we ran the function and finish. Notice the Full Resource Path that is displayed within the Uri field. This is the resource path we will ultimately give to GitHub to call our Function. Select the Clipboard icon next to this to copy the full resource path. Make the updates as I have done here and click Save.
Creating a public endpoint (Optional)
GitHub is a publicly available service and if your FlexDeploy installation is local and not accessible from internet, then we need an endpoint that GitHub can use to send us information. We are going to use what is known as a reverse proxy, in this case Ngrok.
After downloading ngrok for your correct OS, simply run the following command:
ngrok
Code Block | ||
---|---|---|
| ||
ngrok http fd_server_host:fd_server_port |
If you are running this command on the FlexDeploy server you can omit the server and just specify the port. In this case that is exactly what we are doing:
Copy your new public endpoint (http or https works for GitHub). Lastly we need to append the Full Resource Path from our Function. Our full url looks like the following:
https://feac-24-106-28-162/flexdeploy/webhooks/v2/git/push
Info |
---|
Security WarningThe approach here is only meant for testing. We have just opened up a public url to our machine on port 8000. Anyone in the world can now hit that port. For real production setup see here. |
Adding a Webhook to GitHub
Now that we have our endpoint we just need to setup a webhook in GitHub with this endpoint.
Trying it out
With the GitHub webhook enabled all we need to do is push a change to the repository. After pushing a change, navigate back to Webhook Messages to ensure we received the event.
Click on the message row to view its details in a popup, and ensure that the logging went through.
Building the Project
Updating our BuildProject Function
Now that we have communication between GitHub and FlexDeploy we can enhance our scripts to make sure it does what we expect. Edit your BuildProject Function by selecting the dropdown icon on the GitHub Provider row and clicking on the name of your Function.
Update the Function script to the following:
Code Block | ||
---|---|---|
| ||
//Execute FLEXDEPLOY functions on an incoming webhook message def functionName = "BuildProject"; LOG.info("Running function: ${functionName}"); //build project according to projectId query param def projectId = QUERY_PARAMS.projectId; def branch = PAYLOAD.ref - 'refs/heads/'; if(projectId) { //convert the projectId to a Long def lprojectId = new Long(projectId); //we can optionally pass change logs to improve performance def logs = GITHUB.getChangeLogs(PAYLOAD); def streamId = FLEXDEPLOY.findStreamId(lprojectId,branch); //build our project FLEXDEPLOY.buildProject(streamId,lprojectId,logs); } else { LOG.warning("No project id passed to function!"); } |
We are using a relatively simple script where we will just build the project that is passed in the query parameter. For more complex examples checkout other samples.
Creating our FlexDeploy Project
If you have an existing FlexDeploy Project you would like to use here you can certainly do that. I am going to use my Natours2 FlexDeploy Project.
First we need to Enable Webhooks for the Project.
Testing it out
To verify our new setup lets do another push to our repository.
Info |
---|
ResubmittingYou also have the option to resubmit messages from the Webhook Messages UI. Since we added the query parameter, resubmitting the original message would not work in this case. |
Drill into the execution and check out the change logs to see the changes from your push.
Finishing the GitHub Provider
Updating the Match Script
We left our GitHub Provider script simply returning true. Its time to finish the script so it correctly matches GitHub messages. Navigate back to your GitHub Provider and update the script to the following:
GitHub Provider
Code Block | ||
---|---|---|
| ||
// perform checks and functions to ensure an incoming message is valid and matches this provider LOG.fine("Evaluating GitHub for incoming message"); def match = false; // validating based on GitHub secret if (HTTP_HEADERS['user-agent'] && HTTP_HEADERS['user-agent'].toLowerCase().contains('github-hookshot')) { //generate hmac string, be sure to replace with your github secret def HMAC_RESULT = HMAC.generateHmacSHA1(FLX_PRISTINE_PAYLOAD, 'abc123'); def RECEIVED_HMAC = HTTP_HEADERS['x-hub-signature']; match = RECEIVED_HMAC && RECEIVED_HMAC.contains(HMAC_RESULT); } LOG.fine("GitHub provider is a match: ${match}"); return match; |
Setting the GitHub Secret
We are going to make use of GitHub's Secret which makes use of Hmac encryptions. As you can see from the script above I used secret 'abc123', but you can use whatever you wish.
Info |
---|
PropertiesProviders also can also have secured properties associated with them. Normally this would be used instead of putting the secret in plain text in our script as seen here. |
Final Validation
Lastly lets push one more time and validate everything is still working.
If you didn’t apply security as suggested, be sure to turn off your ngrok tunnel when you are done.