def _checkout_repo(self, gevent, repo_path): clone_url = clone_url_with_auth(gevent.clone_url, "bot:%s" % self.github.token) try_count = 0 while try_count < 3: try: time.sleep(1) gitbin = Repo.clone_from(clone_url, repo_path).git break except Exception: try_count = try_count + 1 if try_count >= 3: raise gitbin.config("http.postBuffer", "1524288000") gitbin.config("--local", "user.name", "FailFast-ci Bot") gitbin.config("--local", "user.email", "*****@*****.**") if gevent.pr_id == "": gitbin.checkout(gevent.refname) else: pr_branch = "pr-%s" % gevent.pr_id gitbin.fetch('origin', "pull/%s/head:%s" % (gevent.pr_id, pr_branch)) gitbin.checkout(pr_branch) if not gitbin.rev_parse('HEAD') == gevent.head_sha: raise Unexpected("git sha don't match", { 'expected_sha': gevent.head_sha, 'sha': gitbin.rev_parse('HEAD') }) return gitbin
def trigger_pipeline(self): gevent = self.ghevent gitlab_user = self.config.gitlab['robot-user'] dirpath = tempfile.mkdtemp() repo_path = os.path.join(dirpath, "repo") gitbin = self._checkout_repo(gevent, repo_path) try: ci_file = self._get_ci_file(repo_path) except ResourceNotFound: raise Unexpected("Could not find a CI config file in: %s" % (repo_path)) try: content = self._parse_ci_file(ci_file['content'], ci_file['file']) except YAMLComposeError: raise Unexpected("Could not parse CI file: %s" % (ci_file['file']), {}) lint_resp = GitlabClient().gitlabci_lint(ci_file['content']) logger.error(lint_resp) logger.error(content) if 'status' not in lint_resp or lint_resp['status'] != 'valid': raise Unexpected(".gitlab-ci.yml syntax error", {}) variables = content.get('variables', dict()) namespace = variables.get('FAILFASTCI_NAMESPACE', self.config.gitlab.get('namespace', None)) repo = variables.get('GITLAB_REPOSITORY', None) reponame = gevent.repo.replace("/", "_") if repo: namespace, reponame = repo.split('/') gitlab_endpoint = variables.get( 'GITLAB_URL', self.config.gitlab.get('gitlab_url', None)) self.gitlab = GitlabClient(gitlab_endpoint, config=self.config) ci_project = self.gitlab.initialize_project(reponame, namespace) # @Todo(ant31) check if clone_url is required # clone_url = clone_url_with_auth(gevent.clone_url, "bot:%s" % self.github.token) target_url = clone_url_with_auth( ci_project['http_url_to_repo'], "%s:%s" % (gitlab_user, self.gitlab.gitlab_token)) gitbin.remote('add', 'target', target_url) variables.update({ 'EVENT': gevent.event_type, 'PR_ID': str(gevent.pr_id), 'SHA': gevent.head_sha, 'SHA8': gevent.head_sha[0:8], 'FAILFASTCI_STATUS_API': ('%s/api/v1/github_status' % (self.config.failfast['failfast_url'], )), 'SOURCE_REF': gevent.refname, 'REF_NAME': gevent.refname, 'CI_REF': gevent.target_refname, 'GITHUB_INSTALLATION_ID': str(gevent.installation_id), 'GITHUB_REPO': gevent.repo }) content['variables'] = variables self.gitlab.set_variables( ci_project['id'], { 'GITHUB_INSTALLATION_ID': str(gevent.installation_id), 'GITHUB_REPO': gevent.repo }) perform_sync = variables.get("FAILFAST_SYNC_REPO", "false") if ((perform_sync == "true") or (DEFAULT_MODE == "sync")): # Full synchronize the repo) gitbin.push("target", 'HEAD:%s' % gevent.target_refname, "-f") ci_sha = str(gitbin.rev_parse('HEAD')) return { # NOTE: the GitHub reference details for subsequent tasks. 'sha': gevent.head_sha, 'ci_sha': ci_sha, 'ref': gevent.refname, 'ci_ref': gevent.target_refname, 'ci_project_id': ci_project['id'], 'installation_id': gevent.installation_id, 'github_repo': gevent.repo, 'context': self.config.github['context'] } else: self.sync_only_ci_file(gevent, content, ci_project, ci_file)
def trigger_pipeline(self): gevent = self.ghevent gitlab_user = GITLAB_USER dirpath = tempfile.mkdtemp() repo_path = os.path.join(dirpath, "repo") gitbin = self._checkout_repo(gevent, repo_path) try: ci_file = self._get_ci_file(repo_path) except ResourceNotFound as e: raise Unexpected("Could not find a CI config file in: %s" % (repo_path, )) try: content = self._parse_ci_file(ci_file['content'], ci_file['file']) except YAMLComposeError as e: raise Unexpected("Could not parse CI file: %s" % (ci_file['file'], )) variables = content.get('variables', dict()) namespace = variables.get('FAILFASTCI_NAMESPACE', None) gitlab_endpoint = variables.get('GITLAB_URL', None) self.gitlab = GitlabClient(gitlab_endpoint) ci_project = self.gitlab.initialize_project( gevent.repo.replace("/", "_"), namespace) # @Todo(ant31) check if clone_url is required # clone_url = clone_url_with_auth(gevent.clone_url, "bot:%s" % self.github.token) target_url = clone_url_with_auth( ci_project['http_url_to_repo'], "%s:%s" % (gitlab_user, self.gitlab.gitlab_token)) gitbin.remote('add', 'target', target_url) variables.update({ 'EVENT': gevent.event_type, 'PR_ID': str(gevent.pr_id), 'SHA': gevent.head_sha, 'SHA8': gevent.head_sha[0:8], 'FAILFASTCI_STATUS_API': ('%s/api/v1/github_status' % (FAILFASTCI_API, )), 'SOURCE_REF': gevent.refname, 'REF_NAME': gevent.refname, 'CI_REF': gevent.target_refname, 'GITHUB_INSTALLATION_ID': str(gevent.installation_id), 'GITHUB_REPO': gevent.repo }) content['variables'] = variables self._append_update_stage(content) perform_sync = variables.get("FAILFAST_SYNC_REPO", "false") if ((perform_sync == "true") or (DEFAULT_MODE == "sync")): # Full synchronize the repo path = os.path.join(repo_path, ".gitlab-ci.yml") with open(path, 'w') as gitlabcifile: gitlabcifile.write( yaml.safe_dump(content, default_style='"', width=float("inf"))) gitbin.commit( "-a", "-m", "build %s \n\n @ %s" % (gevent.head_sha, gevent.commit_url)) gitbin.push("target", 'HEAD:%s' % gevent.target_refname, "-f") ci_sha = str(gitbin.rev_parse('HEAD')) return { # NOTE: the GitHub reference details for subsequent tasks. 'sha': gevent.head_sha, 'ci_sha': ci_sha, 'ref': gevent.refname, 'ci_ref': gevent.target_refname, 'ci_project_id': ci_project['id'], 'installation_id': gevent.installation_id, 'github_repo': gevent.repo } else: self.sync_only_ci_file(gevent, content, ci_project, ci_file)