Skip to content

Add finder for group-level jobs

What does this MR do?

As part of the effort to implement the changes proposed by #37366 (closed), I understand a new finder is required to fill a gap when managing Jobs on the group level. The goal of this MR is to add GroupJobsFinder, that will get all Jobs related to a given group, in all nested level of the Descendants groups.

  • Regarding the GroupJobsFinder, it’ll get all jobs belonging to projects within a given group. The jobs can also be filtered by scope, if a params object is passed along with the call of the execute method.

This is the second MR to address the issue and will be followed by more MRs addressing controller and view changes.

Are there points in the code the reviewer needs to double check?

No, they follow the existing finders structure.

Does this MR meet the acceptance criteria?

  • Documentation created/updated - N/A
  • Added tests for this feature/bug
  • In case of conflicts with master - no conflicts

DB queries

SQL query produced by "Ci::JobsFinder.new(current_user: , group: ).execute.limit(30)":
SELECT
  "ci_builds".*
FROM
  "ci_builds"
WHERE
  "ci_builds"."type" = 'Ci::Build'
  AND "ci_builds"."project_id" IN (
    WITH "projects_cte" AS (
      SELECT
        "projects".*
      FROM
        "projects"
        LEFT JOIN project_features ON projects.id = project_features.project_id
      WHERE
        "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
            "id"
          FROM
            "base_and_descendants" AS "namespaces"
        )
        AND (
          "project_features"."builds_access_level" > 0
          OR "project_features"."builds_access_level" IS NULL
        )
        AND (
          (
            "projects"."id" IN (
              SELECT
                "projects"."id"
              FROM
                "projects"
                INNER JOIN "project_authorizations" ON "projects"."id" = "project_authorizations"."project_id"
              WHERE
                "project_authorizations"."user_id" = 7
                AND (project_authorizations.access_level >= 20)
            )
            OR "projects"."id" IN (
              SELECT
                "projects"."id"
              FROM
                "projects"
                INNER JOIN "project_authorizations" ON "projects"."id" = "project_authorizations"."project_id"
              WHERE
                "project_authorizations"."user_id" = 7
                AND (project_authorizations.access_level >= 10)
            )
            AND "projects"."public_builds" = TRUE
          )
          OR "projects"."visibility_level" IN (20, 10)
          AND "projects"."public_builds" = TRUE
        )
    )
    SELECT
      "projects"."id"
    FROM
      "projects_cte" AS "projects"
  )
ORDER BY
  ci_builds.id DESC
LIMIT 30
One of four (all four queries are similar) SQL queries produced by "Ci::JobsFinder.new(current_user: , group: ).limited_counts_by_state"
SELECT
  COUNT(*)
FROM
  (
    SELECT
      1 AS one
    FROM
      "ci_builds"
    WHERE
      "ci_builds"."type" = 'Ci::Build'
      AND "ci_builds"."project_id" IN (
        WITH "projects_cte" AS (
          SELECT
            "projects".*
          FROM
            "projects"
            LEFT JOIN project_features ON projects.id = project_features.project_id
          WHERE
            "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
                "id"
              FROM
                "base_and_descendants" AS "namespaces"
            )
            AND (
              "project_features"."builds_access_level" > 0
              OR "project_features"."builds_access_level" IS NULL
            )
            AND (
              (
                "projects"."id" IN (
                  SELECT
                    "projects"."id"
                  FROM
                    "projects"
                    INNER JOIN "project_authorizations" ON "projects"."id" = "project_authorizations"."project_id"
                  WHERE
                    "project_authorizations"."user_id" = 7
                    AND (project_authorizations.access_level >= 20)
                )
                OR "projects"."id" IN (
                  SELECT
                    "projects"."id"
                  FROM
                    "projects"
                    INNER JOIN "project_authorizations" ON "projects"."id" = "project_authorizations"."project_id"
                  WHERE
                    "project_authorizations"."user_id" = 7
                    AND (project_authorizations.access_level >= 10)
                )
                AND "projects"."public_builds" = TRUE
              )
              OR "projects"."visibility_level" IN (20, 10)
              AND "projects"."public_builds" = TRUE
            )
        )
        SELECT
          "projects"."id"
        FROM
          "projects_cte" AS "projects"
      )
    LIMIT
      1001
  ) subquery_for_count
## What are the relevant issue numbers? #37366 (closed)
Edited by Arthur de Lapertosa Lisboa

Merge request reports