Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

The majority of webhook use cases for GitHub stem from changes being pushed to the repository. The most common example being building FlexDeploy projects from a repository push eventMicrosoft Teams that are referred to on this page are in regards to Approvals completed in the Microsoft Teams UI.

Info

Microsoft Teams Groovy Reference

...

Adding Webhooks in Microsoft Teams

Adding webhooks to Github is covered in official GitHub documentationSee the Teams plugin configuration pages for information on how to set up FlexDeploy and Microsoft Teams. 

Configuring FlexDeploy for Teams Webhook Operations

and

Configuring FlexDeploy for Teams Operations using User Credentials

Incoming

Provider Match Script

This provider match script for GitHub validates based on the secret configured on your GitHub webhook. This script is largely based around GitHub's Hmac encryption. Note that using the secret is optional but it is strongly recommended to make use of itMicrosoft Teams validates that it is a message from a card that FlexDeploy created.

Additional security checks are performed after match and before completing processing of approval tasks. These checks are in regards to the security that Microsoft provides on the incoming message, and the users and groups setup in FlexDeploy.

...

Code Block
languagegroovy
// 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;
def gitHubSecret = 'REPLACE_ME';
 
// 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, gitHubSecret);
    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;

Building Projects and/or Packages from a Push Event

The below function builds both Projects and Packages from a GitHub push event. You can optionally send a projectId query parameter to limit the build results to a specific project.

Code Block
languagegroovy
//Execute FLEXDEPLOY functions on an incoming webhook message
def functionName = "BuildGitHub";
LOG.info("Running function: ${functionName}");
 
//Find and build projects from the payload
//If the QUERY_PARAMS include a projectId that single project will be built instead
//Lastly, the 3rd argument, when true, will create streams on the projects when the branch does not exist
GITHUB.buildProjects(PAYLOAD, QUERY_PARAMS, true);
GITHUB.buildPackages(PAYLOAD, QUERY_PARAMS, true);

Create a FlexDeploy Project when a GitHub repository is created

This sample GitHub function script creates a FlexDeploy SCM instance and project with the assumption it will be triggered only from a GitHub create repo event. The function will first use the repository name to create an SCM Instance with the given name and git url. Next the function creates and configures the project to use the newly created SCM Instance. Finally the function will update the necessary properties on the project. In this example we are creating an EBS project. You will need to replace certain values in the function with specific Ids from your FlexDeploy environment.

Info

Note that this webhook is created at the User/Org level in GitHub since it doesnt apply to any specific repository.

Code Block
languagegroovy
import flexagon.fd.model.pojos.rest.topology.integrations.SCMInstancePojo;
import flexagon.fd.model.pojos.rest.properties.PropertyValuePojo;
import flexagon.fd.model.pojos.rest.project.*;
import flexagon.fd.core.enums.SCMTypeEnum;
import flexagon.fd.core.enums.ProjectTypeEnum;
import flexagon.fd.model.pojos.rest.properties.PropertyValuePojo;
 
//Execute FLEXDEPLOY functions on an incoming webhook message
def functionName = "myFunction";
LOG.info("Running function: ${functionName}");
 
def CEMLI_ID= PAYLOAD.repository.name;
LOG.info("CEMLI_ID: " + CEMLI_ID);
 
def scmInstance = new SCMInstancePojo();
scmInstance.setInstanceCode(CEMLI_ID);
scmInstance.setInstanceName(CEMLI_ID);
scmInstance.setScmType("GIT");
def props = [new PropertyValuePojo("FDGIT_URL", PAYLOAD.repository.git_url), new PropertyValuePojo("FDGIT_USER", "flexagon9"), new PropertyValuePojo("FDGIT_PASSWORD", null, 12345L)];
 
scmInstance.setProperties(props);
 
LOG.info(scmInstance.toString());
 
def scmId = FLEXDEPLOY.createSCMInstance(scmInstance);
LOG.info(scmId.toString());
 
def proj = new ProjectPojo();
proj.setProjectName(CEMLI_ID);
proj.setApplicationId(880708L);
proj.setPartialDeployment(true);
proj.setProjectType(ProjectTypeEnum.EBS);
proj.setScmType(SCMTypeEnum.GIT);
 
def buildInfo = new ProjectBuildInfo();
def deployInfo = new ProjectDeployInfo();
 
buildInfo.setWorkflowId(566261L);
buildInfo.setInstanceId(566269L);
 
deployInfo.setWorkflowId(566260L);
deployInfo.setInstanceIds([566269L]);
 
proj.setBuildInfo(buildInfo);
proj.setDeployInfo(deployInfo);
 
proj.setMainStreamName("master");
 
def projectSCMPojo = new ProjectSCMPojo();
def projectSCMConfig = new ProjectSCMConfig();
projectSCMConfig.setInstanceId(scmId);
def scmConfigs = [new ProjectSCMConfigValue("BranchScript", "StreamName"), new ProjectSCMConfigValue("TagScript", "ProjectVersion"), new ProjectSCMConfigValue("SparseCheckoutFoldersScript", "\"XXHR\""), new ProjectSCMConfigValue("CheckoutFolderScript", "ProjectName")];
projectSCMConfig.setConfigValues(scmConfigs);
projectSCMConfig.setSourceNumber(1);
 
projectSCMPojo.setSources([projectSCMConfig]);
 
proj.setScmConfiguration(projectSCMPojo);
 
def projId = FLEXDEPLOY.createProject(proj);
LOG.info(projId.toString());
 
LOG.info("Updating Project Properties.");
def properties = [
  new PropertyValuePojo("FDEBS_APPLICATION_SHORT_NAME", "XXHR"),
  new PropertyValuePojo("FDEBS_JAVA_ROOT_SOURCE_DIR", "java"),
  new PropertyValuePojo("FDEBS_JAVA_ROOT_DESTINATION_DIR", "\$XXHR_TOP/java"),
  new PropertyValuePojo("FDEBS_LOAD_JAVA_ROOT_DESTINATION_DIR", "\$XXHR_TOP/java"),
  new PropertyValuePojo("FDEBS_AOL_ROOT_DESTINATION_DIR", "\$XXHR_TOP/patch/115/import/us"),
  new PropertyValuePojo("FDEBS_FILE_PERMISSIONS", "755"),
  new PropertyValuePojo("FD_PARTIAL_FILE_EXCLUDES", "*/misc/*")
  ];
 
FLEXDEPLOY.updateProjectProperties(projId, properties);
return HTTP_HEADERS.containsKey("flex-sync-webhook") && "TeamsTask".equals(HTTP_HEADERS.get("flex-sync-webhook"));

Function Script - Update Tasks from Teams Messages

Microsoft Teams Incoming Webhooks are validated and processed Synchronously. Behind the scenes, the JWT token is validated and the message is checked for unauthorized modification. The user that clicked the button is matched to a FlexDeploy user account behind the scenes using the JWT Token found in the HTTP Headers. If the matched user is authorized to approve/reject the linked FlexDeploy task, the task is approved or rejected and the card is updated to indicate that the task was processed. 

Code Block
languagegroovy
MICROSOFTTEAMS.updateTask(QUERY_PARAMS,HTTP_HEADERS,"<Teams Messaging Integration Account Code>");

Outgoing

Create Teams Approval Tasks

This sample sends an interactive message to a Microsoft Teams channel that allows members of the channel to approve or reject an associated FlexDeploy task. As shown in this script, you can add conditions to handle sending to multiple different channels in one listener depending on some condition. (e.g. environment, pipeline, release, etc.) You could also apply similar logic to the webhook listener filter to customize when and where the Teams message should be sent.

See the incoming samples also. An incoming webhook is needed to capture the button clicks that users perform on the Teams messages and ultimately approve/reject the task in FlexDeploy.

...

Expand
titleSend Teams Approval Message Listener
Code Block
// Function Script - Create Approvable Tasks in Teams Channels (Outgoing Webhook)
String message = MICROSOFTTEAMS.makeTaskCreatedMessageForWebhook(EVENT.payload,"https://<urlToYourFlexDeployServerOrExternalProxy>/flexdeploy/webhooks/v1/<uri setup in Incoming Webhook>");

String webhookUrlBI = "https://flexagon.webhook.office.com/webhookb2/cb7f2430-...9ee6-98a7eae43f9f";
String webhookUrlMule = "https://flexagon.webhook.office.com/webhookb2/cb7f2430-9...-98a7eae43f9f";
String webhookUrlSF = "https://flexagon.webhook.office.com/webhookb2/cb7f2430-96dc-4....-98a7eae43f9f";

if(condition for BI Approval){
MICROSOFTTEAMS.sendTeamsWebhookMessage(webhookUrlBI,message);
} else if(condition for Mule Approval){
MICROSOFTTEAMS.sendTeamsWebhookMessage(webhookUrlMule,message);
} else if(condition for SF Approval){
MICROSOFTTEAMS.sendTeamsWebhookMessage(webhookUrlSF,message);
}