feat(pipelines): 添加流水线模块。

This commit is contained in:
Ivan 2021-03-01 15:22:45 +08:00
parent ea4ca724e3
commit e3e698b8cb
11 changed files with 208 additions and 1 deletions

View File

@ -7,6 +7,7 @@ import { AppResolver } from './app.resolver';
import { AppService } from './app.service'; import { AppService } from './app.service';
import { ProjectsModule } from './projects/projects.module'; import { ProjectsModule } from './projects/projects.module';
import { ReposModule } from './repos/repos.module'; import { ReposModule } from './repos/repos.module';
import { PipelinesModule } from './pipelines/pipelines.module';
import configuration from './commons/config/configuration'; import configuration from './commons/config/configuration';
@Module({ @Module({
@ -39,6 +40,7 @@ import configuration from './commons/config/configuration';
}), }),
ProjectsModule, ProjectsModule,
ReposModule, ReposModule,
PipelinesModule,
], ],
controllers: [AppController], controllers: [AppController],
providers: [AppService, AppResolver], providers: [AppService, AppResolver],

View File

@ -0,0 +1,26 @@
import { InputType } from '@nestjs/graphql';
import {
IsObject,
IsOptional,
IsString,
IsUUID,
MaxLength,
} from 'class-validator';
@InputType({ isAbstract: true })
export class CreatePipelineInput {
@IsUUID()
projectId: string;
@IsString()
@MaxLength(100)
branch: string;
@IsString()
@MaxLength(32)
name: string;
@IsOptional()
@IsObject()
workUnitMetadata = {};
}

View File

@ -0,0 +1,8 @@
import { ArgsType } from '@nestjs/graphql';
import { IsUUID } from 'class-validator';
@ArgsType()
export class ListPipelineArgs {
@IsUUID()
projectId?: string;
}

View File

@ -0,0 +1,5 @@
import { InputType } from '@nestjs/graphql';
import { CreatePipelineInput } from './create-pipeline.input';
@InputType()
export class UpdatePipelineInput extends CreatePipelineInput {}

View File

@ -0,0 +1,22 @@
import { Column, Entity, ManyToOne } from 'typeorm';
import { AppBaseEntity } from '../commons/entities/app-base-entity';
import { Project } from '../projects/project.entity';
import { ObjectType } from '@nestjs/graphql';
@ObjectType()
@Entity()
export class Pipeline extends AppBaseEntity {
@ManyToOne(() => Project)
project: Project;
@Column()
projectId: string;
@Column({ comment: 'eg: remotes/origin/master' })
branch: string;
@Column()
name: string;
@Column({ type: 'jsonb' })
workUnitMetadata: any;
}

View File

@ -0,0 +1,11 @@
import { Module } from '@nestjs/common';
import { PipelinesResolver } from './pipelines.resolver';
import { PipelinesService } from './pipelines.service';
import { TypeOrmModule } from '@nestjs/typeorm';
import { Pipeline } from './pipeline.entity';
@Module({
imports: [TypeOrmModule.forFeature([Pipeline])],
providers: [PipelinesResolver, PipelinesService],
})
export class PipelinesModule {}

View File

@ -0,0 +1,25 @@
import { Test, TestingModule } from '@nestjs/testing';
import { PipelinesResolver } from './pipelines.resolver';
import { PipelinesService } from './pipelines.service';
describe('PipelinesResolver', () => {
let resolver: PipelinesResolver;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
PipelinesResolver,
{
provide: PipelinesService,
useValue: {},
},
],
}).compile();
resolver = module.get<PipelinesResolver>(PipelinesResolver);
});
it('should be defined', () => {
expect(resolver).toBeDefined();
});
});

View File

@ -0,0 +1,44 @@
import { Args, Mutation, Query, Resolver } from '@nestjs/graphql';
import { CreatePipelineInput } from './dtos/create-pipeline.input';
import { UpdatePipelineInput } from './dtos/update-pipeline.input';
import { Pipeline } from './pipeline.entity';
import { PipelinesService } from './pipelines.service';
import { ListPipelineArgs } from './dtos/list-pipelines.args';
@Resolver()
export class PipelinesResolver {
constructor(private readonly service: PipelinesService) {}
@Query(() => [Pipeline])
async findPipelines(@Args('listPipelineArgs') dto: ListPipelineArgs) {
return await this.service.list(dto);
}
@Query(() => Pipeline)
async findPipeline(@Args('id', { type: () => String }) id: string) {
return await this.service.findOne(id);
}
@Mutation(() => Pipeline)
async createPipeline(
@Args('Pipeline', { type: () => CreatePipelineInput })
dto: UpdatePipelineInput,
) {
return await this.service.create(dto);
}
@Mutation(() => Pipeline)
async modifyPipeline(
@Args('id', { type: () => String }) id: string,
@Args('Pipeline', { type: () => UpdatePipelineInput })
dto: UpdatePipelineInput,
) {
const tmp = await this.service.update(id, dto);
console.log(tmp);
return tmp;
}
@Mutation(() => Number)
async deletePipeline(@Args('id', { type: () => String }) id: string) {
return await this.service.remove(id);
}
}

View File

@ -0,0 +1,26 @@
import { Test, TestingModule } from '@nestjs/testing';
import { PipelinesService } from './pipelines.service';
import { Pipeline } from './pipeline.entity';
import { getRepositoryToken } from '@nestjs/typeorm';
describe('PipelinesService', () => {
let service: PipelinesService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
PipelinesService,
{
provide: getRepositoryToken(Pipeline),
useValue: {},
},
],
}).compile();
service = module.get<PipelinesService>(PipelinesService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});

View File

@ -0,0 +1,37 @@
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Pipeline } from './pipeline.entity';
import { Repository } from 'typeorm';
import { BaseDbService } from '../commons/services/base-db.service';
import { CreatePipelineInput } from './dtos/create-pipeline.input';
import { UpdatePipelineInput } from './dtos/update-pipeline.input';
import { ListPipelineArgs } from './dtos/list-pipelines.args';
@Injectable()
export class PipelinesService extends BaseDbService<Pipeline> {
readonly uniqueFields: Array<keyof Pipeline> = ['branch', 'projectId'];
constructor(
@InjectRepository(Pipeline)
readonly repository: Repository<Pipeline>,
) {
super(repository);
}
async list(dto: ListPipelineArgs) {
return this.repository.find(dto);
}
async create(dto: CreatePipelineInput) {
await this.isDuplicateEntity(dto);
return await this.repository.save(this.repository.create(dto));
}
async update(id: string, dto: UpdatePipelineInput) {
await this.isDuplicateEntityForUpdate(id, dto);
const old = await this.findOne(id);
return await this.repository.save(this.repository.merge(old, dto));
}
async remove(id: string) {
return (await this.repository.softDelete({ id })).affected;
}
}

View File

@ -4,6 +4,7 @@ import { BaseDbService } from '../commons/services/base-db.service';
import { Repository } from 'typeorm'; import { Repository } from 'typeorm';
import { CreateProjectInput } from './dtos/create-project.input'; import { CreateProjectInput } from './dtos/create-project.input';
import { Project } from './project.entity'; import { Project } from './project.entity';
import { UpdateProjectInput } from './dtos/update-project.input';
@Injectable() @Injectable()
export class ProjectsService extends BaseDbService<Project> { export class ProjectsService extends BaseDbService<Project> {
@ -24,7 +25,7 @@ export class ProjectsService extends BaseDbService<Project> {
return await this.repository.save(this.repository.create(dto)); return await this.repository.save(this.repository.create(dto));
} }
async update(id: string, dto: CreateProjectInput) { async update(id: string, dto: UpdateProjectInput) {
await this.isDuplicateEntityForUpdate(id, dto); await this.isDuplicateEntityForUpdate(id, dto);
const old = await this.findOne(id); const old = await this.findOne(id);
return await this.repository.save(this.repository.merge(old, dto)); return await this.repository.save(this.repository.merge(old, dto));