All files / publisher/pages/Build Build.tsx

46.15% Statements 6/13
70.58% Branches 12/17
50% Functions 1/2
46.15% Lines 6/13

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126                              6x 6x                                       6x   6x         6x   6x                                                                                                                                                                
import { useParams, Link } from "react-router-dom";
import { useQuery } from "react-query";
import { Strip, Row, Col, MainTable } from "@canonical/react-components";
import { formatDistanceToNow } from "date-fns";
 
import SectionNav from "../../components/SectionNav";
 
import {
  formatBuildStatus,
  formatDurationString,
  setPageTitle,
} from "../../utils";
import { GitCommitLink } from "../../utils/formatGitCommit";
 
function Build(): React.JSX.Element {
  const { buildId, snapId } = useParams();
  const { data, isFetched, isLoading, isFetching } = useQuery({
    queryKey: ["build", snapId, buildId],
    queryFn: async () => {
      const response = await fetch(`/api/${snapId}/builds/${buildId}`);
 
      if (!response.ok) {
        throw new Error("There was a problem trying to fetch build data");
      }
 
      const responseData = await response.json();
 
      if (!responseData.success) {
        throw new Error("There was a problem trying to fetch build data");
      }
 
      return responseData.data;
    },
    refetchOnWindowFocus: false,
  });
 
  const build = data?.snap_build;
  const isDataLoading =
    isLoading ||
    isFetching ||
    !data ||
    (build && build.id.toString() !== buildId);
 
  setPageTitle(`Build ${buildId} for ${snapId}`);
 
  return (
    <>
      <h1 className="p-heading--4" aria-live="polite">
        <a href="/snaps">My snaps</a> / <a href={`/${snapId}`}>{snapId}</a> /{" "}
        <Link to={`/${snapId}/builds`}>Builds</Link> / Build #{buildId}
      </h1>
      <SectionNav activeTab="builds" snapName={snapId} />
      {isDataLoading && (
        <Strip shallow>
          <p>
            <i className="p-icon--spinner u-animation--spin"></i>&nbsp;Loading{" "}
            {snapId} build data
          </p>
        </Strip>
      )}
      {!isDataLoading && isFetched && data && (
        <Strip shallow>
          <MainTable
            headers={[
              { content: "id" },
              { content: "Architecture" },
              { content: "Git commit" },
              { content: "Build duration" },
              { content: "Result" },
              { content: "Build finished", className: "u-align-text--right" },
            ]}
            rows={[
              {
                columns: [
                  { content: buildId },
                  { content: build.arch_tag },
                  {
                    content: (
                      <GitCommitLink
                        commitId={build.revision_id}
                        githubRepository={build.github_repository}
                      />
                    ),
                  },
                  { content: formatDurationString(build.duration) },
                  { content: formatBuildStatus(build.status) },
                  {
                    content: build.datebuilt
                      ? formatDistanceToNow(build.datebuilt, {
                          addSuffix: true,
                        })
                      : "-",
                    className: "u-align--right",
                  },
                ],
              },
            ]}
          />
          <Row>
            <Col size={6}>
              <h2 className="p-heading--4">Build log</h2>
            </Col>
            <Col size={6} className="u-align-text--right">
              <a className="p-button--base" href="#footer">
                Scroll to bottom
              </a>
              <a
                target="_blank"
                href={build.logs}
                className="p-button"
                rel="noreferrer"
              >
                View raw
              </a>
            </Col>
          </Row>
          <pre>{data.raw_logs}</pre>
        </Strip>
      )}
      <div id="footer"></div>
    </>
  );
}
 
export default Build;