Skip to content

Expose epic groupings in boards

charlie ablett requested to merge 218040-graphql-expose-board-epics into master

What does this MR do?

Expose epic groupings under issue boards via GraphQL. This will allow the frontend to use them for #218040 (closed).

Query:

for project:

query {
  project(fullPath: "h5bp/html5-boilerplate") {
    id
    board(id: "gid://gitlab/Board/1") {
        epics(issueFilters: {labelName: "test"}) {
          nodes {
            id
            iid
            title
          }
        }
      }
  }
}

for group:

query {
  group(fullPath: "h5bp") {
    id
    board(id: "gid://gitlab/Board/2") {
        epics(issueFilters: {labelName: "test"}) {
          nodes {
            id
            iid
            title
          }
        }
      }
  }
}

DB queries

Getting paginated epics for issues on the board (with devopsplan label filter): https://explain.depesz.com/s/AyGv
SELECT "epics".*
FROM "epics"
WHERE "epics"."id" IN
    (SELECT DISTINCT epic_issues.epic_id
     FROM "issues"
     INNER JOIN "projects" ON "projects"."id" = "issues"."project_id"
     INNER JOIN "label_links" ON "label_links"."target_type" = 'Issue'
     AND "label_links"."target_id" = "issues"."id"
     INNER JOIN "labels" ON "labels"."id" = "label_links"."label_id"
     INNER JOIN "epic_issues" ON "epic_issues"."issue_id" = "issues"."id"
     LEFT JOIN project_features ON projects.id = project_features.project_id
     WHERE (issues.confidential IS NOT TRUE
            OR (issues.confidential = TRUE
                AND (issues.author_id = 1642716
                     OR EXISTS
                       (SELECT TRUE
                        FROM issue_assignees
                        WHERE user_id = 1642716
                          AND issue_id = issues.id)
                     OR EXISTS
                       (SELECT 1
                        FROM "project_authorizations"
                        WHERE "project_authorizations"."user_id" = 1642716
                          AND (project_authorizations.project_id = issues.project_id)
                          AND (project_authorizations.access_level >= 20)))))
       AND "projects"."namespace_id" IN
         (WITH RECURSIVE "base_and_descendants" AS (
                                                      (SELECT "namespaces".*
                                                       FROM "namespaces"
                                                       WHERE "namespaces"."type" = 'Group'
                                                         AND "namespaces"."id" = 9970)
                                                    UNION
                                                      (SELECT "namespaces".*
                                                       FROM "namespaces",
                                                            "base_and_descendants"
                                                       WHERE "namespaces"."type" = 'Group'
                                                         AND "namespaces"."parent_id" = "base_and_descendants"."id")) SELECT "namespaces"."id"
          FROM "base_and_descendants" AS "namespaces")
       AND (EXISTS
              (SELECT 1
               FROM "project_authorizations"
               WHERE "project_authorizations"."user_id" = 1642716
                 AND (project_authorizations.project_id = projects.id)
                 AND (project_authorizations.access_level >= 10))
            OR projects.visibility_level IN (10,
                                             20))
       AND ("project_features"."issues_access_level" IS NULL
            OR "project_features"."issues_access_level" IN (20,
                                                            30)
            OR ("project_features"."issues_access_level" = 10
                AND EXISTS
                  (SELECT 1
                   FROM "project_authorizations"
                   WHERE "project_authorizations"."user_id" = 1642716
                     AND (project_authorizations.project_id = projects.id)
                     AND (project_authorizations.access_level >= 10))))
       AND "projects"."archived" = FALSE
       AND "labels"."title" = 'devops::plan'
       AND "issues"."id" IN
         (SELECT "epic_issues"."issue_id"
          FROM "epic_issues"
          WHERE "epic_issues"."epic_id" IN
              (SELECT "epics"."id"
               FROM "epics"
               WHERE "epics"."group_id" IN
                   (WITH RECURSIVE "base_and_ancestors" AS (
                                                              (SELECT "namespaces".*
                                                               FROM "namespaces"
                                                               WHERE "namespaces"."type" = 'Group'
                                                                 AND "namespaces"."id" = 9970)
                                                            UNION
                                                              (SELECT "namespaces".*
                                                               FROM "namespaces",
                                                                    "base_and_ancestors"
                                                               WHERE "namespaces"."type" = 'Group'
                                                                 AND "namespaces"."id" = "base_and_ancestors"."parent_id")),
                                   "base_and_descendants" AS (
                                                                (SELECT "namespaces".*
                                                                 FROM "namespaces"
                                                                 WHERE "namespaces"."type" = 'Group'
                                                                   AND "namespaces"."id" = 9970)
                                                              UNION
                                                                (SELECT "namespaces".*
                                                                 FROM "namespaces",
                                                                      "base_and_descendants"
                                                                 WHERE "namespaces"."type" = 'Group'
                                                                   AND "namespaces"."parent_id" = "base_and_descendants"."id")) SELECT "namespaces"."id"
                    FROM (
                            (SELECT "namespaces".*
                             FROM "base_and_ancestors" AS "namespaces"
                             WHERE "namespaces"."type" = 'Group')
                          UNION
                            (SELECT "namespaces".*
                             FROM "base_and_descendants" AS "namespaces"
                             WHERE "namespaces"."type" = 'Group')) namespaces
                    WHERE "namespaces"."type" = 'Group')
                 AND "epics"."state_id" = 1
               ORDER BY "epics"."id" DESC)))
ORDER BY "epics"."id" DESC
LIMIT 100

Screenshots

Does this MR meet the acceptance criteria?

Conformity

Availability and Testing

Security

If this MR contains changes to processing or storing of credentials or tokens, authorization and authentication methods and other items described in the security review guidelines:

  • Label as security and @ mention @gitlab-com/gl-security/appsec
  • The MR includes necessary changes to maintain consistency between UI, API, email, or other methods
  • Security reports checked/validated by a reviewer from the AppSec team

Related to #218040 (closed) and #229149 (closed)

Edited by Jan Provaznik

Merge request reports