def post(self, repo: Repository): """ Create a new build. """ schema = BuildCreateSchema(strict=True, context={"repository": repo}) result = self.schema_from_request(schema, partial=True) if result.errors: return self.respond(result.errors, 403) data = result.data # TODO(dcramer): only if we create a source via a patch will we need the author # author_data = data.pop('author') # if author_data.get('email'): # author = Author.query.filter( # Author.repository_id == repo.id, Author.email == author_data['email'] # ).first() # else: # author = None # if not author: # author = Author(repository_id=repo.id, **author_data) # db.session.add(author) # db.session.flush() # TODO(dcramer): need to handle patch case yet source = (Source.query.options( joinedload("author"), joinedload("revision")).filter( Source.revision_sha == data.pop("ref"), Source.repository_id == repo.id).first()) build = Build(repository=repo, **data) # TODO(dcramer): we should convert source in the schema build.source = source # build.source_id = source.id build.author = source.author if not source.patch_id: if not build.label: build.label = source.revision.message.split("\n")[0] if not build.label: return self.error("missing build label") db.session.add(build) try: db.session.commit() except IntegrityError: db.session.rollback() return self.respond(status=422) result = build_schema.dump(build) assert not result.errors, "this should never happen" publish("builds", "build.create", result.data) return self.respond(result.data, 200)
def post(self, repo: Repository): """ Create a new build. """ result = self.schema_from_request(build_create_schema, partial=True) if result.errors: return self.respond(result.errors, 403) data = result.data ref = data.pop('ref', None) if ref is None: return self.error('missing ref') try: revision = identify_revision(repo, ref) except UnknownRevision: current_app.logger.warn('invalid ref received', exc_info=True) return self.error('unable to find a revision matching ref') # TODO(dcramer): only if we create a source via a patch will we need the author # author_data = data.pop('author') # if author_data.get('email'): # author = Author.query.filter( # Author.repository_id == repo.id, Author.email == author_data['email'] # ).first() # else: # author = None # if not author: # author = Author(repository_id=repo.id, **author_data) # db.session.add(author) # db.session.flush() # TODO(dcramer): need to handle patch case yet source = Source.query.options(joinedload('author'), ).filter( Source.revision_sha == revision.sha, Source.repository_id == repo.id, ).first() build = Build(repository=repo, **data) # TODO(dcramer): we should convert source in the schema build.source = source # build.source_id = source.id build.author = source.author if not source.patch_id: if not build.label: build.label = source.revision.message.split('\n')[0] db.session.add(build) db.session.commit() return self.respond_with_schema(build_schema, build)
def build_instance(self, data, **kwargs): revision = self.context.get("resolved_revision") build = Build( repository=self.context.get("repository"), revision_sha=revision.sha if revision else None, **data ) if build.data is None: build.data = {} build.data["required_hook_ids"] = Hook.get_required_hook_ids( build.repository.id ) if revision: if not build.label: build.label = revision.message.split("\n")[0] if not build.authors and revision.authors: build.authors = revision.authors return build
def post(self, project: Project): """ Create a new build. """ result = self.schema_from_request(build_create_schema, partial=True) if result.errors: return self.respond(result.errors, 403) data = result.data revision_sha = data.pop('revision_sha') source = Source.query.filter( Source.revision_sha == revision_sha, Source.repository_id == project.repository_id, ).first() if not source: return self.error('invalid source') # TODO(dcramer): only if we create a source via a patch will we need the author # author_data = data.pop('author') # if author_data.get('email'): # author = Author.query.filter( # Author.repository_id == repo.id, Author.email == author_data['email'] # ).first() # else: # author = None # if not author: # author = Author(repository_id=repo.id, **author_data) # db.session.add(author) # db.session.flush() build = Build(**data) build.organization_id = project.organization_id build.project_id = project.id # TODO(dcramer): we should convert source in the schema build.source = source build.source_id = source.id if not source.patch_id: if not build.label: build.label = source.revision.message.split('\n')[0] assert build.source_id db.session.add(build) db.session.commit() return self.respond_with_schema(build_schema, build)
def merge_build_group(build_group): if len(build_group) == 1: build = build_group[0] build.original = [build] return build providers = groupby(build_group, lambda build: build.provider) latest_builds = [ max(build, key=lambda build: build.number) for _, build in providers ] if len(latest_builds) == 1: build = latest_builds[0] build.original = [build] return build build = Build() build.original = [] return reduce(merge_builds, latest_builds, build)
def merge_build_group( build_group: Tuple[Any, List[Build]], required_hook_ids: List[str] = None ) -> Build: # XXX(dcramer): required_hook_ids is still dirty here, but its our simplest way # to get it into place grouped_builds = groupby( build_group, lambda build: (str(build.hook_id), build.provider) ) latest_builds = [ max(build, key=lambda build: build.number) for _, build in grouped_builds ] build = Build() build.original = [] if set(required_hook_ids or ()).difference( set(str(b.hook_id) for b in build_group) ): build.result = Result.failed return reduce(merge_builds, latest_builds, build)