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 FilePath locateValidFileInWorkspace(String relLocation) throws IOException { FilePath filePath = build.getWorkspace().child(relLocation); try { if (!filePath.exists()) { throw new IllegalStateException("File does not exists"); } } catch (InterruptedException ie) { throw new RuntimeException(ie); } return filePath; }
protected static String resolveParametersInString( AbstractBuild<?, ?> build, BuildListener listener, String input) { try { return build.getEnvironment(listener).expand(input); } catch (Exception e) { listener .getLogger() .println( "Failed to resolve parameters in string \"" + input + "\" due to following error:\n" + e.getMessage()); } return input; }
/** * ************************************************** * * <p>public boolean workspaceExists() throws IOException, InterruptedException { * * <p>Call <tt>scm history</tt> command. * * <p> * * <p>Will check if the workspace exists. * * @return <tt>true</tt> on exists * @throws IOException * @throws InterruptedException ************************************************** */ public boolean workspaceExists(AbstractBuild build) throws IOException, InterruptedException { // output to console. PrintStream output = listener.getLogger(); Command cmd = new HistoryCommand(configuration); output.println( " RTC SCM - Jazz Client: Run History command to determine if workspace exists - it is OK if an error is returned below: (Problem running 'history')"); // Get variables from system. String jobName = ""; try { jobName = build.getEnvironment(null).get("JOB_NAME"); } catch (Exception e) { listener.error("" + e); } // Add the abstract build to the configuration. // This call happens before the load and accept so we can set these items for later use. configuration.setBuild(build); configuration.setTaskListener(listener); configuration.setJobName(jobName); configuration.consoleOut(" -- Initializing build object --"); StringBuffer strBuf = new StringBuffer(); joinWithPossibleTimeout(run(cmd.getArguments()), listener, strBuf, build, null); boolean result = true; String stdOut = strBuf.toString(); if (stdOut.contains("did not match any workspaces") || stdOut.contains("Unmatched workspace")) { listener.error("The workspace probably doesn't exist."); output.println(" RTC SCM - Jazz Client: Specified workspace does not exist..."); result = false; } else { output.println(" RTC SCM - Jazz Client: Specified workspace already exists..."); } return result; }
@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; }
/** Factory method to create the job url for our feed. */ public static String GenerateJobUrl(AbstractBuild<?, ?> build) { return getRootUrl() + build.getUrl(); }
@Override public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException { listener.getLogger().println("[htmlpublisher] Archiving HTML reports..."); // Grab the contents of the header and footer as arrays ArrayList<String> headerLines; ArrayList<String> footerLines; try { headerLines = this.readFile("/htmlpublisher/HtmlPublisher/header.html"); footerLines = this.readFile("/htmlpublisher/HtmlPublisher/footer.html"); } catch (FileNotFoundException e1) { e1.printStackTrace(); return false; } catch (IOException e1) { e1.printStackTrace(); return false; } for (int i = 0; i < this.reportTargets.size(); i++) { // Create an array of lines we will eventually write out, initially the header. ArrayList<String> reportLines = new ArrayList<String>(headerLines); HtmlPublisherTarget reportTarget = this.reportTargets.get(i); boolean keepAll = reportTarget.getKeepAll(); FilePath archiveDir = build .getWorkspace() .child(resolveParametersInString(build, listener, reportTarget.getReportDir())); FilePath targetDir = reportTarget.getArchiveTarget(build); String levelString = keepAll ? "BUILD" : "PROJECT"; listener .getLogger() .println( "[htmlpublisher] Archiving at " + levelString + " level " + archiveDir + " to " + targetDir); // The index name might be a comma separated list of names, so let's figure out all the pages // we should index. String[] csvReports = resolveParametersInString(build, listener, reportTarget.getReportFiles()).split(","); ArrayList<String> reports = new ArrayList<String>(); for (int j = 0; j < csvReports.length; j++) { String report = csvReports[j]; report = report.trim(); // Ignore blank report names caused by trailing or double commas. if (report.equals("")) { continue; } reports.add(report); String tabNo = "tab" + (j + 1); // Make the report name the filename without the extension. int end = report.lastIndexOf("."); String reportName; if (end > 0) { reportName = report.substring(0, end); } else { reportName = report; } String tabItem = "<li id=\"" + tabNo + "\" class=\"unselected\" onclick=\"updateBody('" + tabNo + "');\" value=\"" + report + "\">" + reportName + "</li>"; reportLines.add(tabItem); } // Add the JS to change the link as appropriate. String hudsonUrl = Hudson.getInstance().getRootUrl(); AbstractProject job = build.getProject(); reportLines.add( "<script type=\"text/javascript\">document.getElementById(\"hudson_link\").innerHTML=\"Back to " + job.getName() + "\";</script>"); // If the URL isn't configured in Hudson, the best we can do is attempt to go Back. if (hudsonUrl == null) { reportLines.add( "<script type=\"text/javascript\">document.getElementById(\"hudson_link\").onclick = function() { history.go(-1); return false; };</script>"); } else { String jobUrl = hudsonUrl + job.getUrl(); reportLines.add( "<script type=\"text/javascript\">document.getElementById(\"hudson_link\").href=\"" + jobUrl + "\";</script>"); } reportLines.add( "<script type=\"text/javascript\">document.getElementById(\"zip_link\").href=\"*zip*/" + reportTarget.getSanitizedName() + ".zip\";</script>"); try { if (!archiveDir.exists()) { listener.error("Specified HTML directory '" + archiveDir + "' does not exist."); build.setResult(Result.FAILURE); return true; } else if (!keepAll) { // We are only keeping one copy at the project level, so remove the old one. targetDir.deleteRecursive(); } if (archiveDir.copyRecursiveTo("**/*", targetDir) == 0) { listener.error( "Directory '" + archiveDir + "' exists but failed copying to '" + targetDir + "'."); if (build.getResult().isBetterOrEqualTo(Result.UNSTABLE)) { // If the build failed, don't complain that there was no coverage. // The build probably didn't even get to the point where it produces coverage. listener.error("This is especially strange since your build otherwise succeeded."); } build.setResult(Result.FAILURE); return true; } } catch (IOException e) { Util.displayIOException(e, listener); e.printStackTrace(listener.fatalError("HTML Publisher failure")); build.setResult(Result.FAILURE); return true; } reportTarget.handleAction(build); // Now add the footer. reportLines.addAll(footerLines); // And write this as the index try { writeFile(reportLines, new File(targetDir.getRemote(), reportTarget.getWrapperName())); } catch (IOException e) { e.printStackTrace(); } } return true; }
@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; }