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 |
---|
...
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 | ||
---|---|---|
| ||
// 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 | ||
---|---|---|
| ||
//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 | ||
---|---|---|
| ||
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 | ||
---|---|---|
| ||
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 | ||
---|---|---|
| ||
|