Skip to content

Commit

Permalink
Merge pull request #69 from chromaui/tom/ap-3544-implement-build-of-o…
Browse files Browse the repository at this point in the history
…ut-date-behaviour-2

Separate running/latest build from viewed stories
  • Loading branch information
tmeasday authored Sep 4, 2023
2 parents 27eeff9 + 503ff0c commit 5a822e1
Show file tree
Hide file tree
Showing 18 changed files with 752 additions and 265 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
"dependencies": {
"@storybook/csf-tools": "7.4.0",
"@storybook/design-system": "^7.15.15",
"chromatic": "6.24.0",
"chromatic": "7.1.0-canary.3",
"date-fns": "^2.30.0",
"pluralize": "^8.0.0",
"ts-dedent": "^2.2.0",
Expand Down
62 changes: 16 additions & 46 deletions src/Panel.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,24 @@
import { logger } from "@storybook/client-logger";
import { Spinner } from "@storybook/design-system";
import type { API } from "@storybook/manager-api";
import { useChannel, useStorybookState } from "@storybook/manager-api";
// eslint-disable-next-line import/no-unresolved
import { GitInfo } from "chromatic/node";
import React, { useCallback, useState } from "react";

import {
ADDON_ID,
BUILD_ANNOUNCED,
BUILD_STARTED,
DEV_BUILD_ID_KEY,
GIT_INFO,
GitInfoPayload,
PANEL_ID,
RUNNING_BUILD,
RunningBuildPayload,
START_BUILD,
} from "./constants";
import { Authentication } from "./screens/Authentication/Authentication";
import { LinkedProject } from "./screens/LinkProject/LinkedProject";
import { LinkingProjectFailed } from "./screens/LinkProject/LinkingProjectFailed";
import { LinkProject } from "./screens/LinkProject/LinkProject";
import { VisualTests } from "./screens/VisualTests/VisualTests";
import { useAddonState } from "./useAddonState/manager";
import { client, Provider, useAccessToken } from "./utils/graphQLClient";
import { StatusUpdate } from "./utils/testsToStatusUpdate";
import { useProjectId } from "./utils/useProjectId";
Expand All @@ -29,50 +28,15 @@ interface PanelProps {
api: API;
}

const {
GIT_USER_EMAIL,
GIT_USER_EMAIL_HASH,
GIT_BRANCH,
GIT_SLUG,
GIT_COMMIT,
GIT_UNCOMMITTED_HASH,
} = process.env;
const initialGitInfo: GitInfoPayload = {
userEmail: GIT_USER_EMAIL,
userEmailHash: GIT_USER_EMAIL_HASH,
branch: GIT_BRANCH,
commit: GIT_COMMIT,
slug: GIT_SLUG,
uncommittedHash: GIT_UNCOMMITTED_HASH,
};

logger.debug("Initial Git info:", initialGitInfo);

const storedBuildId = localStorage.getItem(DEV_BUILD_ID_KEY);

export const Panel = ({ active, api }: PanelProps) => {
const [accessToken, setAccessToken] = useAccessToken();
const { storyId } = useStorybookState();

const [isStarting, setIsStarting] = useState(false);
const [lastBuildId, setLastBuildId] = useState(storedBuildId);
const [gitInfo, setGitInfo] = useState(initialGitInfo);

const emit = useChannel(
{
[START_BUILD]: () => setIsStarting(true),
[BUILD_STARTED]: () => setIsStarting(false),
[BUILD_ANNOUNCED]: (buildId: string) => {
setLastBuildId(buildId);
localStorage.setItem(DEV_BUILD_ID_KEY, buildId);
},
[GIT_INFO]: (info: GitInfoPayload) => {
setGitInfo(info);
logger.debug("Updated Git info:", info);
},
},
[]
);
const [gitInfo] = useAddonState<GitInfoPayload>(GIT_INFO);
const [runningBuild] = useAddonState<RunningBuildPayload>(RUNNING_BUILD);
const emit = useChannel({});

const updateBuildStatus = useCallback(
(update: StatusUpdate) => {
Expand All @@ -81,6 +45,7 @@ export const Panel = ({ active, api }: PanelProps) => {
[api]
);
const {
loading: projectInfoLoading,
projectId,
projectToken,
configDir,
Expand All @@ -98,6 +63,11 @@ export const Panel = ({ active, api }: PanelProps) => {
// Render the Authentication flow if the user is not signed in.
if (!accessToken) return <Authentication key={PANEL_ID} setAccessToken={setAccessToken} />;

// Momentarily wait on addonState (should be very fast)
if (projectInfoLoading || !gitInfo) {
return <Spinner />;
}

if (!projectId)
return (
<Provider key={PANEL_ID} value={client}>
Expand Down Expand Up @@ -128,14 +98,14 @@ export const Panel = ({ active, api }: PanelProps) => {
</Provider>
);
}

return (
<Provider key={PANEL_ID} value={client}>
<VisualTests
projectId={projectId}
gitInfo={gitInfo}
isStarting={isStarting}
lastDevBuildId={lastBuildId}
startDevBuild={() => isStarting || emit(START_BUILD)}
runningBuild={runningBuild}
startDevBuild={() => emit(START_BUILD)}
setAccessToken={setAccessToken}
updateBuildStatus={updateBuildStatus}
storyId={storyId}
Expand Down
19 changes: 6 additions & 13 deletions src/Tool.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,20 @@ import { useChannel } from "@storybook/manager-api";
import React, { useState } from "react";

import { RunTestsButton } from "./components/RunTestsButton";
import { BUILD_STARTED, START_BUILD, TOOL_ID } from "./constants";
import { RUNNING_BUILD, RunningBuildPayload, START_BUILD, TOOL_ID } from "./constants";
import { useAddonState } from "./useAddonState/manager";
import { useAccessToken } from "./utils/graphQLClient";
import { useProjectId } from "./utils/useProjectId";

export const Tool = () => {
const [isStarting, setIsStarting] = useState(false);
const { projectId } = useProjectId();
const [accessToken] = useAccessToken();
const isLoggedIn = !!accessToken;

const emit = useChannel(
{
[START_BUILD]: () => setIsStarting(true),
[BUILD_STARTED]: () => setIsStarting(false),
},
[]
);

const startBuild = () => {
emit(START_BUILD);
};
const [runningBuild] = useAddonState<RunningBuildPayload>(RUNNING_BUILD);
const emit = useChannel({});
const startBuild = () => emit(START_BUILD);

const isStarting = ["initializing"].includes(runningBuild?.step);
return <RunTestsButton key={TOOL_ID} {...{ isStarting, projectId, isLoggedIn, startBuild }} />;
};
46 changes: 28 additions & 18 deletions src/constants.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { GitInfo } from "chromatic/node";
import type { GitInfo, TaskName } from "chromatic/node";

export const {
CHROMATIC_INDEX_URL,
Expand All @@ -15,24 +15,34 @@ export const ACCESS_TOKEN_KEY = `${ADDON_ID}/access-token/${CHROMATIC_BASE_URL}`
export const DEV_BUILD_ID_KEY = `${ADDON_ID}/dev-build-id`;

export const GIT_INFO = `${ADDON_ID}/gitInfo`;
export type GitInfoPayload = Omit<GitInfo, "committedAt" | "committerEmail" | "committerName">;
export const START_BUILD = `${ADDON_ID}/startBuild`;
export const BUILD_ANNOUNCED = `${ADDON_ID}/buildAnnounced`;
export const BUILD_STARTED = `${ADDON_ID}/buildStarted`;
export type GitInfoPayload = Omit<GitInfo, "committerEmail" | "committerName">;

export const UPDATE_PROJECT = `${ADDON_ID}/updateProject`;
export type UpdateProjectPayload = {
projectId: string;
projectToken: string;
export const PROJECT_INFO = `${ADDON_ID}/projectInfo`;
export type ProjectInfoPayload = {
projectId?: string;
projectToken?: string;
written?: boolean;
configDir?: string;
mainPath?: string;
};

export const PROJECT_UPDATED = `${ADDON_ID}/projectUpdated`;
export type ProjectUpdatedPayload = {
mainPath: string;
configDir: string;
};
export const PROJECT_UPDATING_FAILED = `${ADDON_ID}/projectUpdatingFailed`;
export type ProjectUpdatingFailedPayload = {
mainPath?: string;
configDir: string;
// The CLI may have other steps that we don't respond to, so we just ignore updates
// to those steps and focus on the ones we know.
type KnownTask = Extract<TaskName, "initialize" | "build" | "upload" | "verify" | "snapshot">;
export function isKnownTask(task: TaskName): task is KnownTask {
return ["initialize", "build", "upload", "verify", "snapshot"].includes(task);
}

export const START_BUILD = `${ADDON_ID}/startBuild`;
export const RUNNING_BUILD = `${ADDON_ID}/runningBuild`;
export type RunningBuildPayload = {
// Possibly this should be a type exported by the CLI -- these correspond to tasks
/** The step of the build process we have reached */
step: KnownTask | "complete";
/** The id of the build, available after the initialize step */
id?: string;
/** progress pertains to the current step, and may not be set */
progress?: number;
/** total pertains to the current step, and may not be set */
total?: number;
};
Loading

0 comments on commit 5a822e1

Please sign in to comment.