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;
 }
예제 #5
0
  /**
   * **************************************************
   *
   * <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;
  }