async update()

in src/PrDisplay.js [241:409]


  async update(params) {
    // Set some global persistent state to redirect back to this window for log
    // ins
    localStorage.setItem("last_redirect", window.location.href);

    if (isOnDevelopmentHost()) {
      // If we're in development, prompt the user for a token to manually enter
      if (!localStorage.getItem("gh_pat")) {
        const token = prompt(
          'In development mode, GitHub API token not found. You can get it from hud.pytorch.org by running localStorage.getItem("gh_pat") in the JavaScript console.'
        );
        if (token) {
          localStorage.setItem("gh_pat", token);
        }
      }
    }

    if (this.hasError()) {
      return;
    }

    if (!localStorage.getItem("gh_pat")) {
      this.setState({ error_message: "GitHub token no found, please log in" });
      return;
    }
    let pr = undefined;
    let commit = undefined;
    if (this.isPr()) {
      // Fetch the PR's info from GitHub's GraphQL API
      let commitResponse = null;
      if (params && params.selectedCommit) {
        const selectedCommit = params.selectedCommit;
        commitResponse = await github.graphql(
          getCommitQuery(this.props.user, this.props.repo, selectedCommit)
        );
      }
      let [prResult, prCommits] = await Promise.all([
        github.graphql(
          getPrQuery(this.props.user, this.props.repo, this.props.pr_number)
        ),
        github.graphql(
          getCommitsForPrQuery(
            this.props.user,
            this.props.repo,
            this.props.pr_number
          )
        ),
      ]);
      pr = prResult.repository.pullRequest;
      pr.allCommits = prCommits.repository.pullRequest.commits.nodes
        .map((n) => [n.commit.oid, n.commit.messageHeadline])
        .reverse();
      if (pr === null || pr === undefined) {
        this.state.error_message = "Failed to fetch PR " + this.props.pr_number;
        this.setState(this.state);
        return;
      }
      if (commitResponse) {
        pr.commits.nodes = [
          { commit: commitResponse.repository.object.history.nodes[0] },
        ];
      }
      commit = pr.commits.nodes[0].commit;
    } else {
      let commitResponse = await github.graphql(
        getCommitQuery(this.props.user, this.props.repo, this.props.commit_hash)
      );
      if (commitResponse.repository.object == null) {
        this.setState({
          error_message: `Failed to fetch ${this.props.commit_hash}`,
        });
        return;
      }
      commit = commitResponse.repository.object.history.nodes[0];
    }

    // The GraphQL API doesn't have any types for artifacts (at least as far as
    // I can tell), so we have to fall back to iterating through them all via
    // the v3 JSON API
    let workflow_runs = commit.checkSuites.nodes;
    workflow_runs = workflow_runs.filter((x) => x.workflowRun);
    workflow_runs.forEach((run) => {
      run.checkRuns.nodes.forEach((check) => {
        check.log = {
          text: null,
          shown: false,
          logLevel: "Minimal",
        };
      });
    });
    await asyncAll(
      workflow_runs.map((run) => {
        return async () => {
          let id = run.workflowRun.databaseId;
          run.artifacts = await github.json(
            `repos/${this.props.user}/${this.props.repo}/actions/runs/${id}/artifacts`
          );
        };
      })
    );

    workflow_runs = workflow_runs.sort((a, b) =>
      a.workflowRun.workflow.name.toUpperCase() >
      b.workflowRun.workflow.name.toUpperCase()
        ? 1
        : -1
    );
    for (const run of workflow_runs) {
      run.status = this.mergeStatuses(
        run.checkRuns.nodes.map((check) => check.conclusion)
      );
    }
    let statuses = [];
    if (commit.status) {
      statuses = commit.status.contexts;
    }
    this.setState({
      pr: pr,
      commit: commit,
      runs: workflow_runs,
      statuses: statuses,
      loadingNewCommit: false,
      selectedCommit: commit.oid,
    });

    // Go through all the runs and check if there is a prefix for the workflow
    // run in S3 (indicating that there are some relevant artifacts stored
    // there)
    let promises = this.state.runs.map((run) => {
      run.s3_artifacts = [];
      if (this.props.repo !== "pytorch") {
        // Ignore for non-pytorch/pytorch repos
        return async () => {
          // Intentional no-op
          return;
        };
      }
      return async () => {
        // Check that the workflow run exists
        let result = await s3(
          `pytorch/pytorch/${run.workflowRun.databaseId}/`,
          "gha-artifacts"
        );

        let prefixes = this.extractItem(
          result.ListBucketResult,
          "CommonPrefixes"
        );

        // If anything was found, go through the results and add the items to
        // the 'run' object in place
        if (prefixes && prefixes.length > 0) {
          for (const prefixItem of prefixes) {
            let prefix = prefixItem.Prefix["#text"];
            let result = await s3(prefix, "gha-artifacts");
            let contents = this.extractItem(
              result.ListBucketResult,
              "Contents"
            );
            for (const content of contents) {
              run.s3_artifacts.push(content);
            }
          }
        }
      };
    });
    await asyncAll(promises);
    this.setState(this.state);
  }