Add ownerProject field to RunnerType
What does this MR do and why?
This MR adds an ownerProject
field to the RunnerType
GraphQL query. This field looks at the first Ci::RunnerProject
association for a certain runner and returns the project from the association. See Project runners should have a clear root project (#355740 - closed) for the logic of doing this.
Screenshots or screen recordings
How to set up and validate locally
Numbered steps to set up and validate the change are strongly suggested.
-
Ensure that you have a project runner created on a project, such as http://gdk.test:3000/gitlab-org/gitlab-shell/-/settings/ci_cd
-
Enable the project runner for a second project, such as http://gdk.test:3000/gitlab-org/gitlab-test/-/settings/ci_cd
-
Open http://gdk.test:3000/-/graphql-explorer and enter the following query:
{ runners(type: PROJECT_TYPE) { nodes { id runnerType ownerProject { fullPath } projects { nodes { fullPath } } description } } }
-
The result should show gitlab-org/gitlab-shell as the owner project for the project runner
Database query plans
Details and visualization: https://postgres.ai/console/gitlab/gitlab-production-tunnel-pg12/sessions/10609/commands/38176.
Ci::RunnerProject Load - app/graphql/resolvers/ci/runner_owner_project_resolver.rb:33:in `group_by'
SELECT "id", "runner_id", "project_id"
FROM (
SELECT id, runner_id, project_id, ROW_NUMBER() OVER (PARTITION BY runner_id ORDER BY id ASC)
FROM "ci_runner_projects"
WHERE "ci_runner_projects"."runner_id" IN (1210, 1207, 2, 1)) temp
WHERE row_number = 1
Index Scan using projects_pkey on public.projects (cost=0.44..6.71 rows=2 width=613) (actual time=13.308..26.149 rows=2 loops=1)
Index Cond: (projects.id = ANY ('{1,20}'::integer[]))
Buffers: shared hit=6 read=5
I/O Timings: read=26.040 write=0.000
Project Load - app/graphql/resolvers/ci/runner_owner_project_resolver.rb:36:in `block in resolve_owner'
Details and visualization: https://postgres.ai/console/gitlab/gitlab-production-tunnel-pg12/sessions/10609/commands/38177.
SELECT "projects"."id", "projects"."name", "projects"."path", "projects"."description",
"projects"."created_at", "projects"."updated_at", "projects"."creator_id", "projects"."namespace_id",
"projects"."last_activity_at", "projects"."import_url", "projects"."visibility_level", "projects"."archived",
"projects"."avatar", "projects"."merge_requests_template", "projects"."star_count", "projects"."merge_requests_rebase_enabled",
"projects"."import_type", "projects"."import_source", "projects"."approvals_before_merge", "projects"."reset_approvals_on_push",
"projects"."merge_requests_ff_only_enabled", "projects"."issues_template", "projects"."mirror", "projects"."mirror_user_id",
"projects"."shared_runners_enabled", "projects"."runners_token", "projects"."build_coverage_regex",
"projects"."build_allow_git_fetch",
"projects"."build_timeout", "projects"."mirror_trigger_builds", "projects"."pending_delete", "projects"."public_builds",
"projects"."last_repository_check_failed", "projects"."last_repository_check_at",
"projects"."only_allow_merge_if_pipeline_succeeds", "projects"."has_external_issue_tracker",
"projects"."repository_storage", "projects"."repository_read_only", "projects"."request_access_enabled",
"projects"."has_external_wiki",
"projects"."ci_config_path", "projects"."lfs_enabled", "projects"."description_html",
"projects"."only_allow_merge_if_all_discussions_are_resolved",
"projects"."repository_size_limit", "projects"."printing_merge_request_link_enabled",
"projects"."auto_cancel_pending_pipelines", "projects"."service_desk_enabled",
"projects"."cached_markdown_version", "projects"."delete_error", "projects"."last_repository_updated_at",
"projects"."disable_overriding_approvers_per_merge_request",
"projects"."storage_version", "projects"."resolve_outdated_diff_discussions",
"projects"."remote_mirror_available_overridden", "projects"."only_mirror_protected_branches",
"projects"."pull_mirror_available_overridden", "projects"."jobs_cache_index",
"projects"."external_authorization_classification_label", "projects"."mirror_overwrites_diverged_branches",
"projects"."pages_https_only", "projects"."external_webhook_token", "projects"."packages_enabled",
"projects"."merge_requests_author_approval",
"projects"."pool_repository_id", "projects"."runners_token_encrypted", "projects"."bfg_object_map",
"projects"."detected_repository_languages",
"projects"."merge_requests_disable_committers_approval", "projects"."require_password_to_approve",
"projects"."emails_disabled", "projects"."max_pages_size",
"projects"."max_artifacts_size", "projects"."remove_source_branch_after_merge", "projects"."marked_for_deletion_at",
"projects"."marked_for_deletion_by_user_id",
"projects"."autoclose_referenced_issues", "projects"."suggestion_commit_message", "projects"."project_namespace_id",
"projects"."hidden"
FROM "projects"
WHERE "projects"."id" IN (1, 20)
Index Scan using projects_pkey on public.projects (cost=0.44..6.71 rows=2 width=613) (actual time=0.076..0.083 rows=2 loops=1)
Index Cond: (projects.id = ANY ('{1,20}'::integer[]))
Buffers: shared hit=11
I/O Timings: read=0.000 write=0.000
Route Load - app/graphql/resolvers/ci/runner_owner_project_resolver.rb:36:in `block in resolve_owner'
Details and visualization: https://postgres.ai/console/gitlab/gitlab-production-tunnel-pg12/sessions/10609/commands/38178.
SELECT "routes".*
FROM "routes"
WHERE "routes"."source_type" = 'Project'
AND "routes"."source_id" IN (1, 20)
Index Scan using index_routes_on_source_type_and_source_id on public.routes (cost=0.56..6.94 rows=2 width=90) (actual time=10.642..14.732 rows=2 loops=1)
Index Cond: (((routes.source_type)::text = 'Project'::text) AND (routes.source_id = ANY ('{1,20}'::integer[])))
Buffers: shared hit=7 read=6
I/O Timings: read=14.571 write=0.000
MR acceptance checklist
This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.
-
I have evaluated the MR acceptance checklist for this MR.
Part of #355740 (closed)