def view_build(path): build = get_target_for(path) if not isinstance(build, Build): return abort(404) restart = request.args.get('restart', '').strip().lower() == 'true' if restart: if build.status != Build.Status_Building: build.delete_build() build.status = Build.Status_Queued build.date_started = None build.date_finished = None models.commit() enqueue(build) return redirect(build.url()) stop = request.args.get('stop', '').strip().lower() == 'true' if stop: if build.status == Build.Status_Queued: build.status = Build.Status_Stopped elif build.status == Build.Status_Building: terminate_build(build) return redirect(build.url()) return render_template('view_build.html', user=request.user, build=build)
def build(): repo_id = request.args.get('repo_id', '') ref_name = request.args.get('ref', '') if not repo_id or not ref_name: return abort(400) if not request.user.can_manage: return abort(403) commit = '0' * 32 repo = Repository.get(id=repo_id) build = Build(repo=repo, commit_sha=commit, num=repo.build_count, ref=ref_name, status=Build.Status_Queued, date_queued=datetime.now(), date_started=None, date_finished=None) repo.build_count += 1 models.commit() enqueue(build) return redirect(repo.url())
def hook_push(logger): ''' PUSH event webhook. The URL parameter ``api`` must be specified for Flux to expect the correct JSON payload format. Supported values for ``api`` are * ``gogs`` * ``github`` * ``gitea`` * ``gitbucket`` * ``bitbucket`` * ``bitbucket-cloud`` * ``gitlab`` * ``bare`` If no or an invalid value is specified for this parameter, a 400 Invalid Request response is generator. ''' api = request.args.get('api') if api not in (API_GOGS, API_GITHUB, API_GITEA, API_GITBUCKET, API_BITBUCKET, API_BITBUCKET_CLOUD, API_GITLAB, API_BARE): logger.error('invalid `api` URL parameter: {!r}'.format(api)) return 400 logger.info('PUSH event received. Processing JSON payload.') try: # XXX Determine encoding from Request Headers, if possible. data = json.loads(request.data.decode('utf8')) except (UnicodeDecodeError, ValueError) as exc: logger.error('Invalid JSON data received: {}'.format(exc)) return 400 if api == API_GOGS: owner = utils.get(data, 'repository.owner.username', str) name = utils.get(data, 'repository.name', str) ref = utils.get(data, 'ref', str) commit = utils.get(data, 'after', str) secret = utils.get(data, 'secret', str) get_repo_secret = lambda r: r.secret elif api == API_GITHUB: event = request.headers.get('X-Github-Event') if event != 'push': logger.error( "Payload rejected (expected 'push' event, got {!r})".format( event)) return 400 owner = utils.get(data, 'repository.owner.name', str) name = utils.get(data, 'repository.name', str) ref = utils.get(data, 'ref', str) commit = utils.get(data, 'after', str) secret = request.headers.get('X-Hub-Signature', '').replace('sha1=', '') get_repo_secret = lambda r: utils.get_github_signature( r.secret, request.data) elif api == API_GITEA: event = request.headers.get('X-Gitea-Event') if event != 'push': logger.error( "Payload rejected (expected 'push' event, got {!r})".format( event)) return 400 owner = utils.get(data, 'repository.owner.username', str) name = utils.get(data, 'repository.name', str) ref = utils.get(data, 'ref', str) commit = utils.get(data, 'after', str) secret = utils.get(data, 'secret', str) get_repo_secret = lambda r: r.secret elif api == API_GITBUCKET: event = request.headers.get('X-Github-Event') if event != 'push': logger.error( "Payload rejected (expected 'push' event, got {!r})".format( event)) return 400 owner = utils.get(data, 'repository.owner.login', str) name = utils.get(data, 'repository.name', str) ref = utils.get(data, 'ref', str) commit = utils.get(data, 'after', str) secret = request.headers.get('X-Hub-Signature', '').replace('sha1=', '') if secret: get_repo_secret = lambda r: utils.get_github_signature( r.secret, request.data) else: get_repo_secret = lambda r: r.secret elif api == API_BITBUCKET: event = request.headers.get('X-Event-Key') if event != 'repo:refs_changed': logger.error( "Payload rejected (expected 'repo:refs_changed' event, got {!r})" .format(event)) return 400 owner = utils.get(data, 'repository.project.name', str) name = utils.get(data, 'repository.name', str) ref = utils.get(data, 'changes.0.refId', str) commit = utils.get(data, 'changes.0.toHash', str) secret = request.headers.get('X-Hub-Signature', '').replace('sha256=', '') if secret: get_repo_secret = lambda r: utils.get_bitbucket_signature( r.secret, request.data) else: get_repo_secret = lambda r: r.secret elif api == API_BITBUCKET_CLOUD: event = request.headers.get('X-Event-Key') if event != 'repo:push': logger.error( "Payload rejected (expected 'repo:push' event, got {!r})". format(event)) return 400 owner = utils.get(data, 'repository.project.project', str) name = utils.get(data, 'repository.name', str) ref_type = utils.get(data, 'push.changes.0.new.type', str) ref_name = utils.get(data, 'push.changes.0.new.name', str) ref = "refs/" + ("heads/" if ref_type == "branch" else "tags/") + ref_name commit = utils.get(data, 'push.changes.0.new.target.hash', str) secret = None get_repo_secret = lambda r: r.secret elif api == API_GITLAB: event = utils.get(data, 'object_kind', str) if event != 'push' and event != 'tag_push': logger.error( "Payload rejected (expected 'push' or 'tag_push' event, got {!r})" .format(event)) return 400 owner = utils.get(data, 'project.namespace', str) name = utils.get(data, 'project.name', str) ref = utils.get(data, 'ref', str) commit = utils.get(data, 'checkout_sha', str) secret = request.headers.get('X-Gitlab-Token') get_repo_secret = lambda r: r.secret elif api == API_BARE: owner = utils.get(data, 'owner', str) name = utils.get(data, 'name', str) ref = utils.get(data, 'ref', str) commit = utils.get(data, 'commit', str) secret = utils.get(data, 'secret', str) get_repo_secret = lambda r: r.secret else: assert False, "unreachable" if not name: logger.error('invalid JSON: no repository name received') return 400 if not owner: logger.error('invalid JSON: no repository owner received') return 400 if not ref: logger.error('invalid JSON: no Git ref received') return 400 if not commit: logger.error('invalid JSON: no commit SHA received') return 400 if len(commit) != 40: logger.error('invalid JSON: commit SHA has invalid length') return 400 if secret == None: secret = '' name = owner + '/' + name repo = Repository.get(name=name) if not repo: logger.error('PUSH event rejected (unknown repository)') return 400 if get_repo_secret(repo) != secret: logger.error('PUSH event rejected (invalid secret)') return 400 if not repo.check_accept_ref(ref): logger.info( 'Git ref {!r} not whitelisted. No build dispatched'.format(ref)) return 200 build = Build(repo=repo, commit_sha=commit, num=repo.build_count, ref=ref, status=Build.Status_Queued, date_queued=datetime.now(), date_started=None, date_finished=None) repo.build_count += 1 models.commit() enqueue(build) logger.info('Build #{} for repository {} queued'.format( build.num, repo.name)) logger.info(utils.strip_url_path(config.app_url) + build.url()) return 200