Exemplo n.º 1
0
def add(repository, provider):
    repo_bits = repository.split('/', 2)
    assert len(
        repo_bits
    ) == 3, 'repository not in valid format: {provider}/{owner}/{name}'
    repo = Repository.query.unrestricted_unsafe().filter(
        Repository.provider == RepositoryProvider(repo_bits[0]),
        Repository.owner_name == repo_bits[1],
        Repository.name == repo_bits[2],
    ).first()
    assert repo

    hook = Hook(
        repository_id=repo.id,
        provider=provider,
    )
    db.session.add(hook)
    db.session.commit()

    click.echo('Hook created:')
    click.echo('-> id           = {}'.format(str(hook.id)))
    click.echo('-> token        = {}'.format(
        urlsafe_b64encode(hook.token).decode('utf-8')))
    click.echo('-> provider     = {}'.format(hook.provider))
    click.echo('-> base_path    = /hooks/{}/{}'.format(str(hook.id),
                                                       hook.get_signature()))
Exemplo n.º 2
0
def upsert_job(build: Build,
               hook: Hook,
               external_id: str,
               data: dict = None) -> Response:
    provider_name = hook.get_provider().get_name(hook.config)
    lock_key = "upsert:job:{build_id}:{provider}:{job_xid}".format(
        build_id=build.id, provider=provider_name, job_xid=external_id)
    with redis.lock(lock_key):
        json = data.copy() if data else {}
        json["external_id"] = external_id
        json["provider"] = provider_name
        json["hook_id"] = str(hook.id)

        job = Job.query.filter(
            Job.provider == provider_name,
            Job.external_id == external_id,
            Job.build_id == build.id,
        ).first()

        if job:
            return client.put(
                "/repos/{}/builds/{}/jobs/{}".format(
                    build.repository.get_full_name(), job.build.number,
                    job.number),
                json=json,
            )

        return client.post(
            "/repos/{}/builds/{}/jobs".format(build.repository.get_full_name(),
                                              build.number),
            json=json,
        )
Exemplo n.º 3
0
def upsert_build(hook: Hook, external_id: str, data: dict = None) -> Response:
    provider_name = hook.get_provider().get_name(hook.config)
    lock_key = "hook:build:{repo_id}:{provider}:{build_xid}".format(
        repo_id=hook.repository_id,
        provider=provider_name,
        build_xid=external_id)
    with redis.lock(lock_key):
        json = data.copy() if data else {}
        json["external_id"] = external_id
        json["provider"] = provider_name
        json["hook_id"] = str(hook.id)

        build = Build.query.filter(Build.provider == provider_name,
                                   Build.external_id == external_id).first()

        if build:
            return client.put(
                "/repos/{}/builds/{}".format(hook.repository.get_full_name(),
                                             build.number),
                json=json,
            )

        return client.post("/repos/{}/builds".format(
            hook.repository.get_full_name()),
                           json=json)
Exemplo n.º 4
0
def upsert_build(hook: Hook, external_id: str, data: dict = None) -> Response:
    provider_name = hook.get_provider().get_name(hook.config)
    lock_key = "hook:build:{repo_id}:{provider}:{build_xid}".format(
        repo_id=hook.repository_id, provider=provider_name, build_xid=external_id
    )
    # TODO (here and in other upsert_* functions): it's better to move all the locking
    # code to async tasks.
    with redis.lock(lock_key, timeout=BUILD_LOCK_TIMEOUT, expire=30):
        json = data.copy() if data else {}
        json["external_id"] = external_id
        json["provider"] = provider_name
        json["hook_id"] = str(hook.id)

        build = Build.query.filter(
            Build.provider == provider_name, Build.external_id == external_id
        ).first()

        if build:
            return client.put(
                "/repos/{}/builds/{}".format(
                    hook.repository.get_full_name(), build.number
                ),
                json=json,
            )

        return client.post(
            "/repos/{}/builds".format(hook.repository.get_full_name()), json=json
        )
Exemplo n.º 5
0
 def make_hook(self, data):
     if self.context.get('hook'):
         hook = self.context['hook']
         for key, value in data.items():
             setattr(hook, key, value)
     else:
         hook = Hook(**data)
     return hook
Exemplo n.º 6
0
 def make_hook(self, data, **kwargs):
     if self.context.get("hook"):
         hook = self.context["hook"]
         for key, value in data.items():
             setattr(hook, key, value)
     else:
         hook = Hook(**data)
     return hook
Exemplo n.º 7
0
def add(repository_url, provider):
    repo = Repository.query.unrestricted_unsafe().filter(
        Repository.url == repository_url, ).first()
    assert repo

    hook = Hook(
        repository_id=repo.id,
        provider=provider,
    )
    db.session.add(hook)
    db.session.commit()

    click.echo('Hook created:')
    click.echo('-> id           = {}'.format(str(hook.id)))
    click.echo('-> token        = {}'.format(
        urlsafe_b64encode(hook.token).decode('utf-8')))
    click.echo('-> provider     = {}'.format(hook.provider))
    click.echo('-> base_path    = /hooks/{}/{}'.format(str(hook.id),
                                                       hook.get_signature()))
Exemplo n.º 8
0
 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
Exemplo n.º 9
0
 def make_hook(self, data):
     return Hook(**data)
Exemplo n.º 10
0
def test_get_required_hook_ids(default_repo):
    hook = factories.HookFactory.create(repository=default_repo,
                                        is_required=True)
    factories.HookFactory.create(repository=default_repo, is_required=False)

    assert Hook.get_required_hook_ids(default_repo.id) == [str(hook.id)]
Exemplo n.º 11
0
    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).one_or_none())
        assert source

        # we need to write/sync the required hook IDs in case they've changed
        required_hook_ids = Hook.get_required_hook_ids(repo.id)
        if (source.data or {}).get("required_hook_ids") != required_hook_ids:
            if source.data is None:
                source.data = {}
            source.data["required_hook_ids"] = required_hook_ids
            db.session.add(source)

        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)