package org.jfrog.hudson; import hudson.EnvVars; import hudson.Util; import hudson.model.AbstractBuild; import hudson.model.Cause; import hudson.model.Run; import hudson.model.TaskListener; import jenkins.model.Jenkins; import org.apache.commons.lang.StringUtils; import org.jfrog.build.api.*; import org.jfrog.build.api.builder.BuildInfoBuilder; import org.jfrog.build.api.builder.PromotionStatusBuilder; import org.jfrog.build.api.release.Promotion; import org.jfrog.build.extractor.clientConfiguration.IncludeExcludePatterns; import org.jfrog.build.extractor.clientConfiguration.PatternMatcher; import org.jfrog.build.extractor.clientConfiguration.client.ArtifactoryBuildInfoClient; import org.jfrog.hudson.action.ActionableHelper; import org.jfrog.hudson.release.ReleaseAction; import org.jfrog.hudson.util.BuildUniqueIdentifierHelper; import org.jfrog.hudson.util.ExtractorUtils; import org.jfrog.hudson.util.IncludesExcludes; import org.jfrog.hudson.util.IssuesTrackerHelper; import java.io.IOException; import java.util.Calendar; import java.util.Enumeration; import java.util.Map; import java.util.Properties; /** * Handles build info creation and deployment * * @author Shay Yaakov */ public class AbstractBuildInfoDeployer { protected Run build; protected TaskListener listener; protected ArtifactoryBuildInfoClient client; private BuildInfoAwareConfigurator configurator; private EnvVars env; public AbstractBuildInfoDeployer(BuildInfoAwareConfigurator configurator, Run build, TaskListener listener, ArtifactoryBuildInfoClient client) throws IOException, InterruptedException { this.configurator = configurator; this.build = build; this.listener = listener; this.client = client; this.env = build.getEnvironment(listener); } protected Build createBuildInfo(String buildAgentName, String buildAgentVersion, BuildType buildType) { String buildName = BuildUniqueIdentifierHelper.getBuildNameConsiderOverride(configurator, build); BuildInfoBuilder builder = new BuildInfoBuilder(buildName) .number(BuildUniqueIdentifierHelper.getBuildNumber(build)).type(buildType) .artifactoryPluginVersion(ActionableHelper.getArtifactoryPluginVersion()) .buildAgent(new BuildAgent(buildAgentName, buildAgentVersion)) .agent(new Agent("hudson", Jenkins.VERSION)); String buildUrl = ActionableHelper.getBuildUrl(build); if (StringUtils.isNotBlank(buildUrl)) { builder.url(buildUrl); } Calendar startedTimestamp = build.getTimestamp(); builder.startedDate(startedTimestamp.getTime()); long duration = System.currentTimeMillis() - startedTimestamp.getTimeInMillis(); builder.durationMillis(duration); String artifactoryPrincipal = configurator.getArtifactoryServer().getResolvingCredentialsConfig().provideUsername(build.getParent()); if (StringUtils.isBlank(artifactoryPrincipal)) { artifactoryPrincipal = ""; } builder.artifactoryPrincipal(artifactoryPrincipal); String userCause = ActionableHelper.getUserCausePrincipal(build); if (userCause != null) { builder.principal(userCause); } Cause.UpstreamCause parent = ActionableHelper.getUpstreamCause(build); if (parent != null) { String parentProject = ExtractorUtils.sanitizeBuildName(parent.getUpstreamProject()); int parentNumber = parent.getUpstreamBuild(); builder.parentName(parentProject); builder.parentNumber(parentNumber + ""); if (StringUtils.isBlank(userCause)) { builder.principal("auto"); } } String revision = ExtractorUtils.getVcsRevision(env); if (StringUtils.isNotBlank(revision)) { builder.vcsRevision(revision); } addBuildInfoProperties(builder); LicenseControl licenseControl = new LicenseControl(configurator.isRunChecks()); if (configurator.isRunChecks()) { if (StringUtils.isNotBlank(configurator.getViolationRecipients())) { licenseControl.setLicenseViolationsRecipientsList( Util.replaceMacro(configurator.getViolationRecipients(), env) ); } if (StringUtils.isNotBlank(configurator.getScopes())) { licenseControl.setScopesList( Util.replaceMacro(configurator.getScopes(), env) ); } } licenseControl.setIncludePublishedArtifacts(configurator.isIncludePublishArtifacts()); licenseControl.setAutoDiscover(configurator.isLicenseAutoDiscovery()); builder.licenseControl(licenseControl); BlackDuckProperties blackDuckProperties = new BlackDuckProperties(); blackDuckProperties.setRunChecks(configurator.isBlackDuckRunChecks()); blackDuckProperties.setAppName( Util.replaceMacro(configurator.getBlackDuckAppName(), env) ); blackDuckProperties.setAppVersion( Util.replaceMacro(configurator.getBlackDuckAppVersion(), env) ); blackDuckProperties.setReportRecipients( Util.replaceMacro(configurator.getBlackDuckReportRecipients(), env) ); blackDuckProperties.setScopes( Util.replaceMacro(configurator.getBlackDuckScopes(), env) ); blackDuckProperties.setIncludePublishedArtifacts(configurator.isBlackDuckIncludePublishedArtifacts()); blackDuckProperties.setAutoCreateMissingComponentRequests(configurator.isAutoCreateMissingComponentRequests()); blackDuckProperties.setAutoDiscardStaleComponentRequests(configurator.isAutoDiscardStaleComponentRequests()); Governance governance = new Governance(); governance.setBlackDuckProperties(blackDuckProperties); builder.governance(governance); if ((Jenkins.getInstance().getPlugin("jira") != null) && configurator.isEnableIssueTrackerIntegration()) { new IssuesTrackerHelper(build, listener, configurator.isAggregateBuildIssues(), configurator.getAggregationBuildStatus()).setIssueTrackerInfo(builder); } // add staging status if it is a release build ReleaseAction release = ActionableHelper.getLatestAction(build, ReleaseAction.class); if (release != null) { String stagingRepoKey = release.getStagingRepositoryKey(); if (StringUtils.isBlank(stagingRepoKey)) { stagingRepoKey = Util.replaceMacro(configurator.getRepositoryKey(), env); } builder.addStatus(new PromotionStatusBuilder(Promotion.STAGED) .timestampDate(startedTimestamp.getTime()) .comment(release.getStagingComment()) .repository(stagingRepoKey) .ciUser(userCause).user(artifactoryPrincipal).build()); } Build buildInfo = builder.build(); // for backwards compatibility for Artifactory 2.2.3 if (parent != null) { buildInfo.setParentBuildId(parent.getUpstreamProject()); } return buildInfo; } protected void addBuildInfoProperties(BuildInfoBuilder builder) { if (configurator.isIncludeEnvVars()) { IncludesExcludes envVarsPatterns = configurator.getEnvVarsPatterns(); if (envVarsPatterns != null) { IncludeExcludePatterns patterns = new IncludeExcludePatterns( Util.replaceMacro(envVarsPatterns.getIncludePatterns(), env), Util.replaceMacro(envVarsPatterns.getExcludePatterns(), env)); // First add all build related variables addBuildVariables(builder, patterns); // Then add env variables addEnvVariables(builder, patterns); // And finally add system variables addSystemVariables(builder, patterns); } } } private void addBuildVariables(BuildInfoBuilder builder, IncludeExcludePatterns patterns) { if (!(build instanceof AbstractBuild)) { return; } Map<String, String> buildVariables = ((AbstractBuild) build).getBuildVariables(); for (Map.Entry<String, String> entry : buildVariables.entrySet()) { String varKey = entry.getKey(); if (PatternMatcher.pathConflicts(varKey, patterns)) { continue; } builder.addProperty(BuildInfoProperties.BUILD_INFO_ENVIRONMENT_PREFIX + varKey, entry.getValue()); } } private void addEnvVariables(BuildInfoBuilder builder, IncludeExcludePatterns patterns) { for (Map.Entry<String, String> entry : env.entrySet()) { String varKey = entry.getKey(); if (PatternMatcher.pathConflicts(varKey, patterns)) { continue; } builder.addProperty(BuildInfoProperties.BUILD_INFO_ENVIRONMENT_PREFIX + varKey, entry.getValue()); } } private void addSystemVariables(BuildInfoBuilder builder, IncludeExcludePatterns patterns) { Properties systemProperties = System.getProperties(); Enumeration<?> enumeration = systemProperties.propertyNames(); while (enumeration.hasMoreElements()) { String propertyKey = (String) enumeration.nextElement(); if (PatternMatcher.pathConflicts(propertyKey, patterns)) { continue; } builder.addProperty(propertyKey, systemProperties.getProperty(propertyKey)); } } }