private static void screenCaptureToFile(AbstractBuild build, AndroidDeviceContext device) throws IOException, InterruptedException { FilePath screencapFile = build.getWorkspace().createTempFile("screencap", ".png"); OutputStream screencapStream = screencapFile.write(); FilterOutputStream replaceFilterStream = new ReplaceFilterOutputStream(screencapStream); device.screenshot(replaceFilterStream); screencapFile.copyTo(new FilePath(build.getArtifactsDir()).child("screencap.png")); }
private String discoverAndroidSdkHome( AbstractBuild build, Launcher launcher, BuildListener listener) { final EnvVars envVars = Utils.getEnvironment(build, listener); final Map<String, String> buildVars = build.getBuildVariables(); // SDK location Node node = Computer.currentComputer().getNode(); String androidHome = Utils.expandVariables(envVars, buildVars, descriptor.androidHome); androidHome = SdkUtils.discoverAndroidHome(launcher, node, envVars, androidHome); return androidHome; }
private String getNodeDefinedMavenHome(AbstractBuild<?, ?> build) { Node currentNode = build.getBuiltOn(); DescribableList<NodeProperty<?>, NodePropertyDescriptor> properties = currentNode.getNodeProperties(); ToolLocationNodeProperty toolLocation = properties.get(ToolLocationNodeProperty.class); if (toolLocation != null) { List<ToolLocationNodeProperty.ToolLocation> locations = toolLocation.getLocations(); if (locations != null) { for (ToolLocationNodeProperty.ToolLocation location : locations) { if (location.getType().isSubTypeOf(Maven.MavenInstallation.class)) { String installationHome = location.getHome(); if (StringUtils.isNotBlank(installationHome)) { return installationHome; } } } } } return null; }
@Override public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException { EnvVars env = build.getEnvironment(listener); FilePath workDir = build.getModuleRoot(); ArgumentListBuilder cmdLine = buildMavenCmdLine(build, listener, env); StringBuilder javaPathBuilder = new StringBuilder(); JDK configuredJdk = build.getProject().getJDK(); if (configuredJdk != null) { javaPathBuilder .append(build.getProject().getJDK().getBinDir().getCanonicalPath()) .append(File.separator); } javaPathBuilder.append("java"); if (!launcher.isUnix()) { javaPathBuilder.append(".exe"); } String[] cmds = cmdLine.toCommandArray(); try { // listener.getLogger().println("Executing: " + cmdLine.toStringWithQuote()); int exitValue = launcher .launch() .cmds(new File(javaPathBuilder.toString()), cmds) .envs(env) .stdout(listener) .pwd(workDir) .join(); boolean success = (exitValue == 0); build.setResult(success ? Result.SUCCESS : Result.FAILURE); return success; } catch (IOException e) { Util.displayIOException(e, listener); e.printStackTrace(listener.fatalError("command execution failed")); build.setResult(Result.FAILURE); return false; } }
private ArgumentListBuilder buildMavenCmdLine( AbstractBuild<?, ?> build, BuildListener listener, EnvVars env) throws IOException, InterruptedException { FilePath mavenHome = getMavenHomeDir(build, listener, env); if (!mavenHome.exists()) { listener.error("Couldn't find Maven home: " + mavenHome.getRemote()); throw new Run.RunnerAbortedException(); } ArgumentListBuilder args = new ArgumentListBuilder(); FilePath mavenBootDir = new FilePath(mavenHome, "boot"); FilePath[] classworldsCandidates = mavenBootDir.list("plexus-classworlds*.jar"); if (classworldsCandidates == null || classworldsCandidates.length == 0) { listener.error("Couldn't find classworlds jar under " + mavenBootDir.getRemote()); throw new Run.RunnerAbortedException(); } FilePath classWorldsJar = classworldsCandidates[0]; // classpath args.add("-classpath"); // String cpSeparator = launcher.isUnix() ? ":" : ";"; args.add(classWorldsJar.getRemote()); // maven home args.addKeyValuePair("-D", "maven.home", mavenHome.getRemote(), false); String buildInfoPropertiesFile = env.get(BuildInfoConfigProperties.PROP_PROPS_FILE); boolean artifactoryIntegration = StringUtils.isNotBlank(buildInfoPropertiesFile); listener .getLogger() .println("Artifactory integration is " + (artifactoryIntegration ? "enabled" : "disabled")); String classworldsConfPath; if (artifactoryIntegration) { args.addKeyValuePair( "-D", BuildInfoConfigProperties.PROP_PROPS_FILE, buildInfoPropertiesFile, false); // use the classworlds conf packaged with this plugin and resolve the extractor libs File maven3ExtractorJar = Which.jarFile(Maven3BuildInfoLogger.class); FilePath actualDependencyDirectory = PluginDependencyHelper.getActualDependencyDirectory(build, maven3ExtractorJar); if (getMavenOpts() == null || !getMavenOpts().contains("-Dm3plugin.lib")) { args.addKeyValuePair("-D", "m3plugin.lib", actualDependencyDirectory.getRemote(), false); } URL classworldsResource = getClass() .getClassLoader() .getResource("org/jfrog/hudson/maven3/classworlds-freestyle.conf"); File classworldsConfFile = new File(URLDecoder.decode(classworldsResource.getFile(), "utf-8")); if (!classworldsConfFile.exists()) { listener.error( "Unable to locate classworlds configuration file under " + classworldsConfFile.getAbsolutePath()); throw new Run.RunnerAbortedException(); } // If we are on a remote slave, make a temp copy of the customized classworlds conf if (Computer.currentComputer() instanceof SlaveComputer) { FilePath remoteClassworlds = build.getWorkspace().createTextTempFile("classworlds", "conf", "", false); remoteClassworlds.copyFrom(classworldsResource); classworldsConfPath = remoteClassworlds.getRemote(); } else { classworldsConfPath = classworldsConfFile.getCanonicalPath(); } } else { classworldsConfPath = new FilePath(mavenHome, "bin/m2.conf").getRemote(); } args.addKeyValuePair("-D", "classworlds.conf", classworldsConfPath, false); // maven opts if (StringUtils.isNotBlank(getMavenOpts())) { String mavenOpts = Util.replaceMacro(getMavenOpts(), build.getBuildVariableResolver()); args.add(mavenOpts); } // classworlds launcher main class args.add(CLASSWORLDS_LAUNCHER); // pom file to build String rootPom = getRootPom(); if (StringUtils.isNotBlank(rootPom)) { args.add("-f", rootPom); } // maven goals args.addTokenized(getGoals()); return args; }
@Override public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) { // This method deserves a refactor and cleanup. boolean success = true; Log log = new Log(listener); if (Result.FAILURE.equals(build.getResult())) { log.info("Not deploying due to job being in FAILED state."); return success; } logStartHeader(log); // todo: getting from descriptor is ugly. refactor? getDescriptorImpl().setGlobalConfiguration(); OctopusApi api = getDescriptorImpl().api; VariableResolver resolver = build.getBuildVariableResolver(); EnvVars envVars; try { envVars = build.getEnvironment(listener); } catch (Exception ex) { log.fatal( String.format( "Failed to retrieve environment variables for this build - '%s'", ex.getMessage())); return false; } EnvironmentVariableValueInjector envInjector = new EnvironmentVariableValueInjector(resolver, envVars); // NOTE: hiding the member variables of the same name with their env-injected equivalents String project = envInjector.injectEnvironmentVariableValues(this.project); String releaseVersion = envInjector.injectEnvironmentVariableValues(this.releaseVersion); String environment = envInjector.injectEnvironmentVariableValues(this.environment); String variables = envInjector.injectEnvironmentVariableValues(this.variables); com.octopusdeploy.api.Project p = null; try { p = api.getProjectByName(project); } catch (Exception ex) { log.fatal( String.format( "Retrieving project name '%s' failed with message '%s'", project, ex.getMessage())); success = false; } com.octopusdeploy.api.Environment env = null; try { env = api.getEnvironmentByName(environment); } catch (Exception ex) { log.fatal( String.format( "Retrieving environment name '%s' failed with message '%s'", environment, ex.getMessage())); success = false; } if (p == null) { log.fatal("Project was not found."); success = false; } if (env == null) { log.fatal("Environment was not found."); success = false; } if (!success) // Early exit { return success; } Set<com.octopusdeploy.api.Release> releases = null; try { releases = api.getReleasesForProject(p.getId()); } catch (Exception ex) { log.fatal( String.format( "Retrieving releases for project '%s' failed with message '%s'", project, ex.getMessage())); success = false; } if (releases == null) { log.fatal("Releases was not found."); return false; } Release releaseToDeploy = null; for (Release r : releases) { if (releaseVersion.equals(r.getVersion())) { releaseToDeploy = r; break; } } if (releaseToDeploy == null) // early exit { log.fatal( String.format( "Unable to find release version %s for project %s", releaseVersion, project)); return false; } Properties properties = new Properties(); try { properties.load(new StringReader(variables)); } catch (Exception ex) { log.fatal( String.format( "Unable to load entry variables failed with message '%s'", ex.getMessage())); success = false; } // TODO: Can we tell if we need to call? For now I will always try and get variable and use if I // find them Set<com.octopusdeploy.api.Variable> variablesForDeploy = null; try { String releaseId = releaseToDeploy.getId(); String environmentId = env.getId(); variablesForDeploy = api.getVariablesByReleaseAndEnvironment(releaseId, environmentId, properties); } catch (Exception ex) { log.fatal( String.format( "Retrieving variables for release '%s' to environment '%s' failed with message '%s'", releaseToDeploy.getId(), env.getName(), ex.getMessage())); success = false; } try { String results = api.executeDeployment(releaseToDeploy.getId(), env.getId(), variablesForDeploy); if (isTaskJson(results)) { JSON resultJson = JSONSerializer.toJSON(results); String urlSuffix = ((JSONObject) resultJson).getJSONObject("Links").getString("Web"); String url = getDescriptorImpl().octopusHost; if (url.endsWith("/")) { url = url.substring(0, url.length() - 2); } log.info("Deployment executed: \n\t" + url + urlSuffix); build.addAction( new BuildInfoSummary( BuildInfoSummary.OctopusDeployEventType.Deployment, url + urlSuffix)); if (waitForDeployment) { log.info("Waiting for deployment to complete."); String resultState = waitForDeploymentCompletion(resultJson, api, log); if (resultState == null) { log.info("Marking build failed due to failure in waiting for deployment to complete."); success = false; } if ("Failed".equals(resultState)) { log.info("Marking build failed due to deployment task status."); success = false; } } } } catch (IOException ex) { log.fatal("Failed to deploy: " + ex.getMessage()); success = false; } return success; }
@Override public BuildWrapper.Environment setUp( AbstractBuild build, Launcher launcher, BuildListener listener) throws IOException, InterruptedException { final PrintStream logger = listener.getLogger(); final DeviceFarmApi api = new DeviceFarmApiImpl(); long start = System.currentTimeMillis(); try { EnvVars environment = build.getEnvironment(listener); String expendedTag = environment.expand(tag); log(logger, Messages.TRYING_TO_CONNECT_API_SERVER(deviceApiUrl, expendedTag)); api.connectApiServer( logger, deviceApiUrl, expendedTag, build.getProject().getAbsoluteUrl() + build.getNumber()); final RemoteDevice reserved = api.waitApiResponse( logger, DEVICE_WAIT_TIMEOUT_IN_MILLIS, DEVICE_READY_CHECK_INTERVAL_IN_MS); log( logger, Messages.DEVICE_IS_READY(passedSeconds(start), reserved.ip, reserved.port, reserved.url)); if (descriptor == null) { descriptor = Hudson.getInstance().getDescriptorByType(DescriptorImpl.class); } // Substitute environment and build variables into config final String androidHome = discoverAndroidSdkHome(build, launcher, listener); log(logger, Messages.USING_SDK(androidHome)); AndroidSdk sdk = new AndroidSdk(androidHome, androidHome); final AndroidDeviceContext device = new AndroidDeviceContext(build, launcher, listener, sdk, reserved.ip, reserved.port); // disconnect first to workaround previous error device.disconnect(); // connect device with adb device.connect(DEVICE_CONNECT_TIMEOUT_IN_MILLIS); device.waitDeviceReady(logger, DEVICE_CONNECT_TIMEOUT_IN_MILLIS, 1000); // check availability device.devices(); // unlock screen device.unlockScreen(); // Start dumping logcat to temporary file final LogcatCollector logcatCollector = new LogcatCollector(build, device); logcatCollector.start(); return new BuildWrapper.Environment() { @Override public void buildEnvVars(Map<String, String> env) { env.put("ANDROID_IP", device.ip()); env.put("ANDROID_HOME", androidHome); env.put("ANDROID_SDK_HOME", androidHome); env.put("ANDROID_PORT", Integer.toString(device.port())); env.put("ANDROID_SERIAL", device.serial()); } @Override public boolean tearDown(AbstractBuild build, BuildListener listener) throws IOException, InterruptedException { cleanUp(build, device, api, logcatCollector); return true; } }; } catch (FailedToConnectApiServerException e) { log(logger, Messages.FAILED_TO_CONNECT_API_SERVER()); } catch (MalformedResponseException e) { log(logger, Messages.FAILED_TO_PARSE_DEVICE_FARM_RESPONSE()); } catch (TimeoutException e) { log(logger, Messages.DEVICE_WAIT_TIMEOUT(passedSeconds(start))); } catch (NoDeviceAvailableException e) { log(logger, Messages.NO_SUCH_DEVICE()); } build.setResult(Result.NOT_BUILT); cleanUp(null, null, api, null); return null; }