def _get_attached_bugs(self, advisories): # get bugs attached to all advisories bugs = set() try: for advisory in advisories: green_print(f"Retrieving bugs for advisory {advisory}") bugs.update(errata.get_bug_ids(advisory)) except GSSError: exit_unauthenticated() green_print(f"Found {len(bugs)} bugs") return list(bzutil.get_bugs(self.bzapi, list(bugs)).values())
async def run(self): self.working_dir.mkdir(parents=True, exist_ok=True) build_data_repo = self.working_dir / "ocp-build-data-push" shutil.rmtree(build_data_repo, ignore_errors=True) shutil.rmtree(self.elliott_working_dir, ignore_errors=True) shutil.rmtree(self.doozer_working_dir, ignore_errors=True) release_config = None group_config = await self.load_group_config() if self.assembly != "stream": releases_config = await self.load_releases_config() release_config = releases_config.get("releases", {}).get(self.assembly, {}) if not release_config: raise ValueError( f"Assembly {self.assembly} is not defined in releases.yml for group {self.group_name}." ) group_config = assembly_group_config( Model(releases_config), self.assembly, Model(group_config)).primitive() asssembly_type = release_config.get("assembly", {}).get("type", "standard") if asssembly_type == "standard": self.release_name = self.assembly self.release_version = tuple( map(int, self.release_name.split(".", 2))) elif asssembly_type == "custom": self.release_name = f"{self.release_version[0]}.{self.release_version[1]}.0-assembly.{self.assembly}" elif asssembly_type == "candidate": self.release_name = f"{self.release_version[0]}.{self.release_version[1]}.0-{self.assembly}" nightlies = release_config.get("assembly", {}).get( "basis", {}).get("reference_releases", {}).values() self.candidate_nightlies = self.parse_nighties(nightlies) if release_config and asssembly_type != "standard": _LOGGER.warning("No need to check Blocker Bugs for assembly %s", self.assembly) else: _LOGGER.info("Checking Blocker Bugs for release %s...", self.release_name) self.check_blockers() advisories = {} if self.default_advisories: advisories = group_config.get("advisories", {}) else: _LOGGER.info("Creating advisories for release %s...", self.release_name) if release_config: advisories = group_config.get("advisories", {}).copy() if self.release_version[2] == 0: # GA release if advisories.get("rpm", 0) <= 0: advisories["rpm"] = self.create_advisory( "RHEA", "rpm", "ga") if advisories.get("image", 0) <= 0: advisories["image"] = self.create_advisory( "RHEA", "image", "ga") else: # z-stream release if advisories.get("rpm", 0) <= 0: advisories["rpm"] = self.create_advisory( "RHBA", "rpm", "standard") if advisories.get("image", 0) <= 0: advisories["image"] = self.create_advisory( "RHBA", "image", "standard") if self.release_version[0] > 3: if advisories.get("extras", 0) <= 0: advisories["extras"] = self.create_advisory( "RHBA", "image", "extras") if advisories.get("metadata", 0) <= 0: advisories["metadata"] = self.create_advisory( "RHBA", "image", "metadata") _LOGGER.info("Ensuring JIRA ticket for release %s...", self.release_name) jira_issue_key = group_config.get("release_jira") jira_template_vars = { "release_name": self.release_name, "x": self.release_version[0], "y": self.release_version[1], "z": self.release_version[2], "release_date": self.release_date, "advisories": advisories, "candidate_nightlies": self.candidate_nightlies, } if jira_issue_key: _LOGGER.info("Reusing existing release JIRA %s", jira_issue_key) jira_issue = self._jira_client.get_issue(jira_issue_key) subtasks = [ self._jira_client.get_issue(subtask.key) for subtask in jira_issue.fields.subtasks ] self.update_release_jira(jira_issue, subtasks, jira_template_vars) else: _LOGGER.info("Creating a release JIRA...") jira_issues = self.create_release_jira(jira_template_vars) jira_issue = jira_issues[0] if jira_issues else None jira_issue_key = jira_issue.key if jira_issue else None _LOGGER.info("Updating ocp-build-data...") build_data_changed = await self.update_build_data( advisories, jira_issue_key) _LOGGER.info("Sweep builds into the the advisories...") for kind, advisory in advisories.items(): if not advisory: continue if kind == "rpm": self.sweep_builds("rpm", advisory) elif kind == "image": self.sweep_builds("image", advisory, only_payload=self.release_version[0] >= 4) elif kind == "extras": self.sweep_builds("image", advisory, only_non_payload=True) elif kind == "metadata": await self.build_and_attach_bundles(advisory) # bugs should be swept after builds to have validation # for only those bugs to be attached which have corresponding brew builds # attached to the advisory # currently for rpm advisory and cves only _LOGGER.info("Sweep bugs into the the advisories...") self.sweep_bugs(check_builds=True) _LOGGER.info("Adding placeholder bugs...") for kind, advisory in advisories.items(): bug_ids = get_bug_ids(advisory) if not bug_ids: # Only create placeholder bug if the advisory has no attached bugs _LOGGER.info("Create placeholder bug for %s advisory %s...", kind, advisory) self.create_and_attach_placeholder_bug(kind, advisory) # Verify the swept builds match the nightlies if self.release_version[0] < 4: _LOGGER.info("Don't verify payloads for OCP3 releases") else: _LOGGER.info("Verify the swept builds match the nightlies...") for _, payload in self.candidate_nightlies.items(): self.verify_payload(payload, advisories["image"]) if build_data_changed or self.candidate_nightlies: _LOGGER.info("Sending a notification to QE and multi-arch QE...") if self.dry_run: jira_issue_link = "https://jira.example.com/browse/FOO-1" else: jira_issue_link = jira_issue.permalink() self.send_notification_email(advisories, jira_issue_link) # Move advisories to QE for kind, advisory in advisories.items(): try: if kind == "metadata": # Verify attached operators await self.verify_attached_operators( advisories["image"], advisories["extras"], advisories["metadata"]) self.change_advisory_state(advisory, "QE") except CalledProcessError as ex: _LOGGER.warning( f"Unable to move {kind} advisory {advisory} to QE: {ex}")