Compare commits

..

3 Commits

Author SHA1 Message Date
Ivan Li
2720e09b05 build: 构建流程。 2021-04-04 12:19:14 +08:00
Ivan Li
148dcfee06 fix(pipeline-tasks): 任务详情 多次订阅任务变化的问题。 2021-04-04 10:44:30 +08:00
Ivan Li
df5a6963e1 feat: 提交日志列表添加所属任务列表 2021-04-04 10:38:51 +08:00
14 changed files with 2265 additions and 26191 deletions

File diff suppressed because it is too large Load Diff

25228
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,7 @@
"version": "0.0.0", "version": "0.0.0",
"license": "MIT", "license": "MIT",
"scripts": { "scripts": {
"build": "preact build", "build": "preact build --no-prerender",
"serve": "sirv build --port 7123 --cors --single", "serve": "sirv build --port 7123 --cors --single",
"dev": "preact watch --port 7123", "dev": "preact watch --port 7123",
"predev": "npm run graphql", "predev": "npm run graphql",
@ -25,38 +25,39 @@
"build/*" "build/*"
], ],
"dependencies": { "dependencies": {
"@apollo/client": "^3.3.11", "@apollo/client": "^3.3.13",
"@fortawesome/fontawesome-svg-core": "^1.2.34", "@fortawesome/fontawesome-svg-core": "^1.2.35",
"@fortawesome/free-solid-svg-icons": "^5.15.2", "@fortawesome/free-solid-svg-icons": "^5.15.3",
"@fortawesome/react-fontawesome": "^0.1.14", "@fortawesome/react-fontawesome": "^0.1.14",
"@tailwindcss/postcss7-compat": "^2.0.3", "@tailwindcss/postcss7-compat": "^2.0.4",
"@types/classnames": "^2.2.11",
"@types/ramda": "^0.27.39",
"autoprefixer": "^9.8.6", "autoprefixer": "^9.8.6",
"classnames": "^2.2.6", "classnames": "^2.3.1",
"formik": "^2.2.6", "formik": "^2.2.6",
"graphql": "^15.5.0", "graphql": "^15.5.0",
"mobx": "^6.1.7", "mobx": "^6.1.8",
"mobx-react": "^7.1.0", "mobx-react": "^7.1.0",
"postcss": "^7.0.35", "postcss": "^7.0.35",
"preact": "^10.3.1", "preact": "^10.5.13",
"preact-jsx-chai": "^3.0.0", "preact-jsx-chai": "^3.0.0",
"preact-markup": "^2.1.1", "preact-markup": "^2.1.1",
"preact-render-to-string": "^5.1.4", "preact-render-to-string": "^5.1.18",
"preact-router": "^3.2.1", "preact-router": "^3.2.1",
"ramda": "^0.27.1", "ramda": "^0.27.1",
"subscriptions-transport-ws": "^0.9.18", "subscriptions-transport-ws": "^0.9.18",
"tailwindcss": "npm:@tailwindcss/postcss7-compat@^2.0.3" "tailwindcss": "npm:@tailwindcss/postcss7-compat@^2.0.3"
}, },
"devDependencies": { "devDependencies": {
"@graphql-codegen/cli": "^1.21.1", "@graphql-codegen/cli": "^1.21.3",
"@graphql-codegen/introspection": "^1.18.1", "@graphql-codegen/introspection": "^1.18.1",
"@graphql-codegen/typescript-operations": "^1.17.14", "@graphql-codegen/typescript-operations": "^1.17.15",
"@graphql-codegen/typescript-react-apollo": "^2.2.1", "@graphql-codegen/typescript-react-apollo": "^2.2.3",
"@teamsupercell/typings-for-css-modules-loader": "^2.2.0", "@teamsupercell/typings-for-css-modules-loader": "^2.5.1",
"@types/classnames": "^2.2.11",
"@types/enzyme": "^3.10.5", "@types/enzyme": "^3.10.5",
"@types/jest": "^26.0.8", "@types/jest": "^26.0.22",
"@types/ramda": "0.27.35",
"@types/webpack-env": "^1.15.1", "@types/webpack-env": "^1.15.1",
"@types/ws": "^7.4.1",
"@typescript-eslint/eslint-plugin": "^2.25.0", "@typescript-eslint/eslint-plugin": "^2.25.0",
"@typescript-eslint/parser": "^2.25.0", "@typescript-eslint/parser": "^2.25.0",
"css-loader": "^3.5.3", "css-loader": "^3.5.3",
@ -65,7 +66,7 @@
"eslint": "^6.8.0", "eslint": "^6.8.0",
"eslint-config-prettier": "^6.10.1", "eslint-config-prettier": "^6.10.1",
"eslint-plugin-prettier": "^3.1.2", "eslint-plugin-prettier": "^3.1.2",
"eslint-plugin-react": "^7.19.0", "eslint-plugin-react": "^7.23.1",
"eslint-plugin-react-hooks": "^3.0.0", "eslint-plugin-react-hooks": "^3.0.0",
"husky": "^4.2.1", "husky": "^4.2.1",
"jest": "^26.2.2", "jest": "^26.2.2",

1
size-plugin.json Normal file
View File

@ -0,0 +1 @@
[{"timestamp":1617509072250,"files":[{"filename":"bundle.*****.esm.js","previous":112647,"size":112647,"diff":0},{"filename":"polyfills.*****.esm.js","previous":2177,"size":2177,"diff":0},{"filename":"sw-esm.js","previous":8486,"size":8486,"diff":0},{"filename":"sw.js","previous":8482,"size":8482,"diff":0},{"filename":"polyfills.03bf6.js","previous":2175,"size":2175,"diff":0},{"filename":"index.html","previous":1017,"size":1102,"diff":85},{"filename":"200.html","previous":1023,"size":1108,"diff":85},{"filename":"bundle.cfced.css","previous":3513,"size":0,"diff":-3513},{"filename":"bundle.4663d.js","previous":113123,"size":0,"diff":-113123},{"filename":"bundle.7a645.css","previous":0,"size":4569,"diff":4569},{"filename":"bundle.49e2d.js","previous":0,"size":113122,"diff":113122}]},{"timestamp":1617508895910,"files":[{"filename":"bundle.*****.esm.js","previous":112647,"size":112647,"diff":0},{"filename":"polyfills.*****.esm.js","previous":2177,"size":2177,"diff":0},{"filename":"sw-esm.js","previous":8486,"size":8486,"diff":0},{"filename":"sw.js","previous":8482,"size":8482,"diff":0},{"filename":"polyfills.03bf6.js","previous":2175,"size":2175,"diff":0},{"filename":"index.html","previous":1018,"size":1017,"diff":-1},{"filename":"200.html","previous":1024,"size":1023,"diff":-1},{"filename":"bundle.49cd0.css","previous":3513,"size":0,"diff":-3513},{"filename":"bundle.9466b.js","previous":113123,"size":0,"diff":-113123},{"filename":"bundle.cfced.css","previous":0,"size":3513,"diff":3513},{"filename":"bundle.4663d.js","previous":0,"size":113123,"diff":113123}]},{"timestamp":1617508710764,"files":[{"filename":"bundle.*****.esm.js","previous":112647,"size":112647,"diff":0},{"filename":"polyfills.*****.esm.js","previous":2177,"size":2177,"diff":0},{"filename":"sw-esm.js","previous":8486,"size":8486,"diff":0},{"filename":"sw.js","previous":8482,"size":8482,"diff":0},{"filename":"polyfills.03bf6.js","previous":2175,"size":2175,"diff":0},{"filename":"index.html","previous":1102,"size":1018,"diff":-84},{"filename":"200.html","previous":1108,"size":1024,"diff":-84},{"filename":"bundle.7a645.css","previous":4569,"size":0,"diff":-4569},{"filename":"bundle.49e2d.js","previous":113122,"size":0,"diff":-113122},{"filename":"bundle.49cd0.css","previous":0,"size":3513,"diff":3513},{"filename":"bundle.9466b.js","previous":0,"size":113123,"diff":113123}]},{"timestamp":1617508442140,"files":[{"filename":"bundle.8730a.css","previous":440652,"size":0,"diff":-440652},{"filename":"bundle.*****.esm.js","previous":112647,"size":112647,"diff":0},{"filename":"polyfills.*****.esm.js","previous":2177,"size":2177,"diff":0},{"filename":"sw-esm.js","previous":8486,"size":8486,"diff":0},{"filename":"sw.js","previous":8482,"size":8482,"diff":0},{"filename":"bundle.7a35f.js","previous":113123,"size":0,"diff":-113123},{"filename":"polyfills.03bf6.js","previous":2175,"size":2175,"diff":0},{"filename":"index.html","previous":1101,"size":1102,"diff":1},{"filename":"200.html","previous":1107,"size":1108,"diff":1},{"filename":"bundle.7a645.css","previous":0,"size":4569,"diff":4569},{"filename":"bundle.49e2d.js","previous":0,"size":113122,"diff":113122}]},{"timestamp":1617506457357,"files":[{"filename":"bundle.8730a.css","previous":0,"size":440652,"diff":440652},{"filename":"bundle.*****.esm.js","previous":0,"size":112647,"diff":112647},{"filename":"polyfills.*****.esm.js","previous":0,"size":2177,"diff":2177},{"filename":"sw-esm.js","previous":0,"size":8486,"diff":8486},{"filename":"sw.js","previous":0,"size":8482,"diff":8482},{"filename":"bundle.7a35f.js","previous":0,"size":113123,"diff":113123},{"filename":"polyfills.03bf6.js","previous":0,"size":2175,"diff":2175},{"filename":"index.html","previous":0,"size":1101,"diff":1101},{"filename":"200.html","previous":0,"size":1107,"diff":1107}]}]

View File

@ -1,23 +0,0 @@
.component {
@apply bg-red-200;
}
.item {
@apply bg-gray-50 p-2 text-red-400 border-red-500 my-px
transition-colors
flex justify-between items-center w-32
overflow-ellipsis select-none cursor-pointer;
@apply hover:bg-red-50;
svg {
@apply hidden;
}
}
.itemActive {
@apply bg-red-400 text-white;
@apply hover:bg-red-400;
svg {
@apply inline-block;
}
}

View File

@ -1,12 +0,0 @@
// This file is automatically generated from your CSS. Any edits will be overwritten.
declare namespace BranchesListScssNamespace {
export interface IBranchesListScss {
component: string;
item: string;
itemActive: string;
}
}
declare const BranchesListScssModule: BranchesListScssNamespace.IBranchesListScss;
export = BranchesListScssModule;

View File

@ -1,78 +0,0 @@
import {
LogList,
Project,
ListLogsArgs,
ListBranchesArgs,
BranchList
} from '../../generated/graphql';
import { h } from 'preact';
import { gql, useQuery } from '@apollo/client';
import styles from './branches-list.scss';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faChevronRight } from '@fortawesome/free-solid-svg-icons';
import { action, makeObservable, observable } from 'mobx';
import { PropTypes, useLocalObservable, useObserver } from 'mobx-react';
const LIST_BRANCHES = gql`
query ListBranches($args: ListBranchesArgs!) {
listBranches(listBranchesArgs: $args) {
all
}
}
`;
interface Props {
project: Project;
onSelect?: (branch: string) => void;
}
class Store {
constructor() {
makeObservable(this);
}
@observable
currBranch?: string;
@action
setCurrBranch(branch?: string) {
this.currBranch = branch;
}
}
export const BranchesList = ({ project, onSelect }: Props) => {
const store = useLocalObservable(() => new Store());
const { data, loading } = useQuery<
{ listBranches: BranchList },
{ args: ListBranchesArgs }
>(LIST_BRANCHES, {
variables: { args: { projectId: project.id } }
});
const list = useObserver(() =>
data?.listBranches?.all?.map(text => {
return (
<li
key={text}
className={[
styles.item,
store.currBranch === text ? styles.itemActive : ''
].join(' ')}
onClick={() => {
store.setCurrBranch(text);
onSelect?.(text);
}}
>
{text.replace(/^.*\/(.+?)$/, '$1')}
<FontAwesomeIcon icon={faChevronRight} />
</li>
);
})
);
return (
<section className={styles.component}>
{loading ? <span>Loading...</span> : <ol>{list}</ol>}
</section>
);
};

View File

@ -5,16 +5,19 @@
@apply bg-gray-100 overflow-auto max-h-full; @apply bg-gray-100 overflow-auto max-h-full;
} }
.item { .item {
@apply grid grid-cols-2 grid-rows-2; header {
@apply bg-white text-gray-700; @apply relative;
@apply py-2 px-4 my-px; @apply bg-white text-gray-700;
@apply hover:bg-gray-50; @apply py-2 px-4 my-px;
@apply hover:bg-gray-50;
}
time { time {
@apply col-start-1; @apply col-start-1;
@apply text-sm text-gray-400; @apply text-sm text-gray-400;
} }
:global(.commit-actions) { :global(.commit-actions) {
@apply col-start-2 row-start-1 row-span-2 justify-self-end self-center; @apply absolute right-0 top-0 bottom-0;
@apply justify-self-end self-center;
} }
} }

View File

@ -1,14 +1,11 @@
import { import { LogList, Pipeline, LogFields } from '../../generated/graphql';
LogList,
Project,
ListLogsArgs,
Pipeline
} from '../../generated/graphql';
import { h } from 'preact'; import { h } from 'preact';
import { gql, useQuery, useSubscription } from '@apollo/client'; import { gql, useQuery, useSubscription } from '@apollo/client';
import styles from './commit-log-list.scss'; import styles from './commit-log-list.scss';
import { CommitActions } from '../commit-actions/commit-actions'; import { CommitActions } from '../commit-actions/commit-actions';
import { FIND_PIPELINE } from '../pipelines/pipeline-list.constants'; import { FIND_PIPELINE } from '../pipelines/pipeline-list.constants';
import { route } from 'preact-router';
import { PipelineTaskStatus } from '../pipeline-tasks/pipeline-task-status';
const LIST_LOGS = gql` const LIST_LOGS = gql`
subscription listLogsForPipeline($id: String!) { subscription listLogsForPipeline($id: String!) {
@ -18,6 +15,13 @@ const LIST_LOGS = gql`
author_email author_email
message message
hash hash
tasks {
id
status
startedAt
endedAt
units
}
} }
total total
} }
@ -41,17 +45,34 @@ export const CommitLogList = ({ pipelineId }: Props) => {
variables: { id: pipelineId } variables: { id: pipelineId }
}); });
const pipeline = queryResult.data?.pipeline; const pipeline = queryResult.data?.pipeline;
const list = data?.listLogs?.all?.map(log => { const Item = ({ log }: { log: LogFields }) => (
return ( <li className={styles.item}>
<li className={styles.item} key={log.hash}> <header>
<h4>{log.message}</h4> <h4>{log.message}</h4>
<time dateTime={log.date}>{log.date}</time> <time dateTime={log.date}>{log.date}</time>
{pipeline ? ( {pipeline ? (
<CommitActions pipeline={pipeline} commit={log.hash} /> <CommitActions pipeline={pipeline} commit={log.hash} />
) : null} ) : null}
</li> </header>
); <ol>
}); {log.tasks.map(task => (
<li
key={task.id}
onClick={() =>
route(
`/projects/${pipeline?.projectId}/pipelines/${pipeline?.id}/tasks/${task.id}`
)
}
>
<PipelineTaskStatus status={task.status} /> {task.startedAt}
</li>
))}
</ol>
</li>
);
const list = data?.listLogs?.all?.map(log => (
<Item log={log} key={log.hash} />
));
return ( return (
<section className={styles.component}> <section className={styles.component}>

View File

@ -118,10 +118,14 @@ export const PipelineTaskDetails = ({ taskId }: Props) => {
{ taskId: string } { taskId: string }
>(FIND_PIPELINE_TASK, { variables: { taskId } }); >(FIND_PIPELINE_TASK, { variables: { taskId } });
subscribeToMore({ useMemo(
document: PIPELINE_TASK_CHANGED, () =>
variables: { taskId } subscribeToMore({
}); document: PIPELINE_TASK_CHANGED,
variables: { taskId }
}),
[subscribeToMore, taskId]
);
const store = useLocalObservable(() => new Store()); const store = useLocalObservable(() => new Store());

View File

@ -1,14 +1,8 @@
import { h } from 'preact'; import { h } from 'preact';
import styles from './pipeline-tasks.scss'; import styles from './pipeline-tasks.scss';
import { gql, useQuery } from '@apollo/client'; import { gql, useQuery } from '@apollo/client';
import { PipelineTask, TaskStatuses } from '../../generated/graphql'; import { PipelineTask } from '../../generated/graphql';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { PipelineTaskStatus } from './pipeline-task-status';
import {
faCheckCircle,
faClock,
faExclamationCircle,
faRunning
} from '@fortawesome/free-solid-svg-icons';
const LIST_TASKS = gql` const LIST_TASKS = gql`
query ListTasks($pipelineId: String!) { query ListTasks($pipelineId: String!) {
@ -55,7 +49,7 @@ export const PipelineTaskList = ({ pipelineId }: Props) => {
const Item = ({ task }: { task: PipelineTask }) => { const Item = ({ task }: { task: PipelineTask }) => {
return ( return (
<li key={task.id} className={styles.item}> <li key={task.id} className={styles.item}>
<Status status={task.status} /> <PipelineTaskStatus status={task.status} />
<span>{task.id}</span> <span>{task.id}</span>
<span>{task.commit}</span> <span>{task.commit}</span>
<span>{task.startedAt}</span> <span>{task.startedAt}</span>
@ -68,23 +62,3 @@ const Item = ({ task }: { task: PipelineTask }) => {
</li> </li>
); );
}; };
const Status = ({ status }: { status: TaskStatuses }) => {
let icon;
switch (status) {
case TaskStatuses.Failed:
icon = faExclamationCircle;
break;
case TaskStatuses.Success:
icon = faCheckCircle;
break;
case TaskStatuses.Pending:
icon = faClock;
break;
case TaskStatuses.Working:
icon = faRunning;
break;
}
return <FontAwesomeIcon icon={icon} />;
};

View File

@ -0,0 +1,45 @@
import { h } from 'preact';
import { TaskStatuses } from '../../generated/graphql';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import {
faCheckCircle,
faExclamationCircle,
faPauseCircle,
faSpinner
} from '@fortawesome/free-solid-svg-icons';
import classNames from 'classnames';
export const PipelineTaskStatus = ({ status }: { status: TaskStatuses }) => {
switch (status) {
case TaskStatuses.Working:
return (
<FontAwesomeIcon
icon={faSpinner}
className={classNames(['animate-spin', 'text-blue-500'])}
/>
);
case TaskStatuses.Failed:
return (
<FontAwesomeIcon
icon={faExclamationCircle}
className={classNames(['text-red-700'])}
/>
);
case TaskStatuses.Success:
return (
<FontAwesomeIcon
icon={faCheckCircle}
className={classNames(['text-green-500'])}
/>
);
case TaskStatuses.Pending:
return (
<FontAwesomeIcon
icon={faPauseCircle}
className={classNames(['text-yellow-500'])}
/>
);
default:
return null;
}
};

View File

@ -14,14 +14,20 @@ export type Scalars = {
DateTime: any; DateTime: any;
}; };
export type Hello = { export type CreatePipelineInput = {
__typename?: 'Hello'; projectId: Scalars['String'];
message: Scalars['String']; branch: Scalars['String'];
name: Scalars['String'];
workUnitMetadata: WorkUnitMetadataInput;
}; };
export type Project = { export type CreatePipelineTaskInput = {
__typename?: 'Project'; pipelineId: Scalars['String'];
id: Scalars['ID']; commit: Scalars['String'];
units: Array<PipelineUnits>;
};
export type CreateProjectInput = {
name: Scalars['String']; name: Scalars['String'];
comment: Scalars['String']; comment: Scalars['String'];
sshUrl: Scalars['String']; sshUrl: Scalars['String'];
@ -29,35 +35,10 @@ export type Project = {
webHookSecret?: Maybe<Scalars['String']>; webHookSecret?: Maybe<Scalars['String']>;
}; };
export type WorkUnit = {
__typename?: 'WorkUnit';
type: PipelineUnits;
scripts: Array<Scalars['String']>;
};
/** 流水线单元 */ export type Hello = {
export enum PipelineUnits { __typename?: 'Hello';
Checkout = 'checkout', message: Scalars['String'];
InstallDependencies = 'installDependencies',
Test = 'test',
Deploy = 'deploy',
CleanUp = 'cleanUp'
}
export type WorkUnitMetadata = {
__typename?: 'WorkUnitMetadata';
version: Scalars['Float'];
units: Array<WorkUnit>;
};
export type Pipeline = {
__typename?: 'Pipeline';
id: Scalars['ID'];
project: Project;
projectId: Scalars['String'];
branch: Scalars['String'];
name: Scalars['String'];
workUnitMetadata: WorkUnitMetadata;
}; };
export type LogFields = { export type LogFields = {
@ -69,6 +50,7 @@ export type LogFields = {
body: Scalars['String']; body: Scalars['String'];
author_name: Scalars['String']; author_name: Scalars['String'];
author_email: Scalars['String']; author_email: Scalars['String'];
tasks: Array<PipelineTask>;
}; };
export type LogList = { export type LogList = {
@ -78,90 +60,6 @@ export type LogList = {
latest: LogFields; latest: LogFields;
}; };
export type PipelineTaskLogs = {
__typename?: 'PipelineTaskLogs';
unit: PipelineUnits;
status: TaskStatuses;
startedAt?: Maybe<Scalars['DateTime']>;
endedAt?: Maybe<Scalars['DateTime']>;
logs: Scalars['String'];
};
/** 任务状态 */
export enum TaskStatuses {
Success = 'success',
Failed = 'failed',
Working = 'working',
Pending = 'pending'
}
export type PipelineTask = {
__typename?: 'PipelineTask';
id: Scalars['ID'];
pipeline: Pipeline;
pipelineId: Scalars['String'];
commit: Scalars['String'];
units: Array<PipelineUnits>;
logs: Array<PipelineTaskLogs>;
status: TaskStatuses;
startedAt?: Maybe<Scalars['DateTime']>;
endedAt?: Maybe<Scalars['DateTime']>;
};
export type PipelineTaskLogMessage = {
__typename?: 'PipelineTaskLogMessage';
unit?: Maybe<PipelineUnits>;
time: Scalars['DateTime'];
message: Scalars['String'];
};
export type WorkUnitInput = {
type: PipelineUnits;
scripts: Array<Scalars['String']>;
};
export type WorkUnitMetadataInput = {
version?: Maybe<Scalars['Float']>;
units: Array<WorkUnitInput>;
};
export type Query = {
__typename?: 'Query';
hello: Hello;
findProjects: Array<Project>;
findProject: Project;
listPipelines: Array<Pipeline>;
findPipeline: Pipeline;
listPipelineTaskByPipelineId: Array<PipelineTask>;
findPipelineTask: PipelineTask;
};
export type QueryFindProjectArgs = {
id: Scalars['String'];
};
export type QueryListPipelinesArgs = {
projectId?: Maybe<Scalars['String']>;
};
export type QueryFindPipelineArgs = {
id: Scalars['String'];
};
export type QueryListPipelineTaskByPipelineIdArgs = {
pipelineId: Scalars['String'];
};
export type QueryFindPipelineTaskArgs = {
id: Scalars['String'];
};
export type Mutation = { export type Mutation = {
__typename?: 'Mutation'; __typename?: 'Mutation';
createProject: Project; createProject: Project;
@ -210,46 +108,106 @@ export type MutationCreatePipelineTaskArgs = {
task: CreatePipelineTaskInput; task: CreatePipelineTaskInput;
}; };
export type CreateProjectInput = { export type Pipeline = {
name: Scalars['String']; __typename?: 'Pipeline';
comment: Scalars['String']; id: Scalars['ID'];
sshUrl: Scalars['String']; project: Project;
webUrl?: Maybe<Scalars['String']>;
webHookSecret?: Maybe<Scalars['String']>;
};
export type UpdateProjectInput = {
name: Scalars['String'];
comment: Scalars['String'];
sshUrl: Scalars['String'];
webUrl?: Maybe<Scalars['String']>;
webHookSecret?: Maybe<Scalars['String']>;
};
export type CreatePipelineInput = {
projectId: Scalars['String']; projectId: Scalars['String'];
branch: Scalars['String']; branch: Scalars['String'];
name: Scalars['String']; name: Scalars['String'];
workUnitMetadata: WorkUnitMetadataInput; workUnitMetadata: WorkUnitMetadata;
}; };
export type UpdatePipelineInput = { export type PipelineTask = {
projectId: Scalars['String']; __typename?: 'PipelineTask';
branch: Scalars['String']; id: Scalars['ID'];
name: Scalars['String']; pipeline: Pipeline;
workUnitMetadata: WorkUnitMetadataInput;
};
export type CreatePipelineTaskInput = {
pipelineId: Scalars['String']; pipelineId: Scalars['String'];
commit: Scalars['String']; commit: Scalars['String'];
units: Array<PipelineUnits>; units: Array<PipelineUnits>;
logs: Array<PipelineTaskLogs>;
status: TaskStatuses;
startedAt?: Maybe<Scalars['DateTime']>;
endedAt?: Maybe<Scalars['DateTime']>;
};
export type PipelineTaskLogMessage = {
__typename?: 'PipelineTaskLogMessage';
unit?: Maybe<PipelineUnits>;
time: Scalars['DateTime'];
message: Scalars['String'];
isError: Scalars['Boolean'];
};
export type PipelineTaskLogs = {
__typename?: 'PipelineTaskLogs';
unit: PipelineUnits;
status: TaskStatuses;
startedAt?: Maybe<Scalars['DateTime']>;
endedAt?: Maybe<Scalars['DateTime']>;
logs: Scalars['String'];
};
/** 流水线单元 */
export enum PipelineUnits {
Checkout = 'checkout',
InstallDependencies = 'installDependencies',
Test = 'test',
Deploy = 'deploy',
CleanUp = 'cleanUp'
}
export type Project = {
__typename?: 'Project';
id: Scalars['ID'];
name: Scalars['String'];
comment: Scalars['String'];
sshUrl: Scalars['String'];
webUrl?: Maybe<Scalars['String']>;
webHookSecret?: Maybe<Scalars['String']>;
};
export type Query = {
__typename?: 'Query';
hello: Hello;
findProjects: Array<Project>;
findProject: Project;
listPipelines: Array<Pipeline>;
findPipeline: Pipeline;
listPipelineTaskByPipelineId: Array<PipelineTask>;
findPipelineTask: PipelineTask;
};
export type QueryFindProjectArgs = {
id: Scalars['String'];
};
export type QueryListPipelinesArgs = {
projectId?: Maybe<Scalars['String']>;
};
export type QueryFindPipelineArgs = {
id: Scalars['String'];
};
export type QueryListPipelineTaskByPipelineIdArgs = {
pipelineId: Scalars['String'];
};
export type QueryFindPipelineTaskArgs = {
id: Scalars['String'];
}; };
export type Subscription = { export type Subscription = {
__typename?: 'Subscription'; __typename?: 'Subscription';
listLogsForPipeline: LogList; listLogsForPipeline: LogList;
pipelineTaskLog: PipelineTaskLogMessage; pipelineTaskLog: PipelineTaskLogMessage;
pipelineTaskChanged: PipelineTask;
}; };
@ -261,3 +219,53 @@ export type SubscriptionListLogsForPipelineArgs = {
export type SubscriptionPipelineTaskLogArgs = { export type SubscriptionPipelineTaskLogArgs = {
taskId: Scalars['String']; taskId: Scalars['String'];
}; };
export type SubscriptionPipelineTaskChangedArgs = {
id: Scalars['String'];
};
/** 任务状态 */
export enum TaskStatuses {
Success = 'success',
Failed = 'failed',
Working = 'working',
Pending = 'pending'
}
export type UpdatePipelineInput = {
projectId: Scalars['String'];
branch: Scalars['String'];
name: Scalars['String'];
workUnitMetadata: WorkUnitMetadataInput;
};
export type UpdateProjectInput = {
name: Scalars['String'];
comment: Scalars['String'];
sshUrl: Scalars['String'];
webUrl?: Maybe<Scalars['String']>;
webHookSecret?: Maybe<Scalars['String']>;
};
export type WorkUnit = {
__typename?: 'WorkUnit';
type: PipelineUnits;
scripts: Array<Scalars['String']>;
};
export type WorkUnitInput = {
type: PipelineUnits;
scripts: Array<Scalars['String']>;
};
export type WorkUnitMetadata = {
__typename?: 'WorkUnitMetadata';
version: Scalars['Float'];
units: Array<WorkUnit>;
};
export type WorkUnitMetadataInput = {
version?: Maybe<Scalars['Float']>;
units: Array<WorkUnitInput>;
};

View File

@ -1,5 +1,8 @@
module.exports = { module.exports = {
purge: [], purge: {
enabled: true,
content: ['./src/**/*']
},
darkMode: 'class', // or 'media' or 'class' darkMode: 'class', // or 'media' or 'class'
theme: { theme: {
extend: {} extend: {}