...@@ -8,7 +8,7 @@ module WorkerAttributes ...@@ -8,7 +8,7 @@ module WorkerAttributes
VALID_RESOURCE_BOUNDARIES = [:memory, :cpu, :unknown].freeze VALID_RESOURCE_BOUNDARIES = [:memory, :cpu, :unknown].freeze
# Urgencies that workers can declare through the `urgencies` attribute # Urgencies that workers can declare through the `urgencies` attribute
VALID_URGENCIES = [:high, :default, :none].freeze VALID_URGENCIES = [:high, :low, :throttled].freeze
NAMESPACE_WEIGHTS = { NAMESPACE_WEIGHTS = {
auto_devops: 2, auto_devops: 2,
...@@ -65,7 +65,7 @@ module WorkerAttributes ...@@ -65,7 +65,7 @@ module WorkerAttributes
end end
def get_urgency def get_urgency
worker_attributes[:urgency] || :default worker_attributes[:urgency] || :low
end end
# Set this attribute on a job when it will call to services outside of the # Set this attribute on a job when it will call to services outside of the
... ...
......
...@@ -26,8 +26,8 @@ class ErrorTrackingIssueLinkWorker # rubocop:disable Scalability/IdempotentWorke ...@@ -26,8 +26,8 @@ class ErrorTrackingIssueLinkWorker # rubocop:disable Scalability/IdempotentWorke
logger.info("Linking Sentry issue #{sentry_issue_id} to GitLab issue #{issue.id}") logger.info("Linking Sentry issue #{sentry_issue_id} to GitLab issue #{issue.id}")
sentry_client.create_issue_link(integration_id, sentry_issue_id, issue) sentry_client.create_issue_link(integration_id, sentry_issue_id, issue)
rescue Sentry::Client::Error rescue Sentry::Client::Error => e
logger.info("Failed to link Sentry issue #{sentry_issue_id} to GitLab issue #{issue.id}") logger.info("Failed to link Sentry issue #{sentry_issue_id} to GitLab issue #{issue.id} with error: #{e.message}")
end end
end end
... ...
......
...@@ -18,21 +18,7 @@ class UpdateMergeRequestsWorker # rubocop:disable Scalability/IdempotentWorker ...@@ -18,21 +18,7 @@ class UpdateMergeRequestsWorker # rubocop:disable Scalability/IdempotentWorker
user = User.find_by(id: user_id) user = User.find_by(id: user_id)
return unless user return unless user
# TODO: remove this benchmarking when we have rich logging
time = Benchmark.measure do
MergeRequests::RefreshService.new(project, user).execute(oldrev, newrev, ref) MergeRequests::RefreshService.new(project, user).execute(oldrev, newrev, ref)
end end
args_log = [
"elapsed=#{time.real}",
"project_id=#{project_id}",
"user_id=#{user_id}",
"oldrev=#{oldrev}",
"newrev=#{newrev}",
"ref=#{ref}"
].join(',')
Rails.logger.info("UpdateMergeRequestsWorker#perform #{args_log}") if time.real > LOG_TIME_THRESHOLD # rubocop:disable Gitlab/RailsLogger
end
# rubocop: enable CodeReuse/ActiveRecord # rubocop: enable CodeReuse/ActiveRecord
end end
---
title: Replace avatar and favicon upload type consistency validation with content whitelist validation
merge_request: 25401
author:
type: changed
---
title: Introduce database table for user highest roles
merge_request: 26987
author:
type: added
...@@ -6,8 +6,8 @@ en: ...@@ -6,8 +6,8 @@ en:
carrierwave_download_error: could not be downloaded carrierwave_download_error: could not be downloaded
extension_whitelist_error: "You are not allowed to upload %{extension} files, allowed types: %{allowed_types}" extension_whitelist_error: "You are not allowed to upload %{extension} files, allowed types: %{allowed_types}"
extension_blacklist_error: "You are not allowed to upload %{extension} files, prohibited types: %{prohibited_types}" extension_blacklist_error: "You are not allowed to upload %{extension} files, prohibited types: %{prohibited_types}"
content_type_whitelist_error: "You are not allowed to upload %{content_type} files" content_type_whitelist_error: "file format is not supported. Please try one of the following supported formats: %{allowed_types}"
content_type_blacklist_error: "You are not allowed to upload %{content_type} files" content_type_blacklist_error: "You are not allowed to upload %{content_type} files, prohibited types: %{allowed_types}"
rmagick_processing_error: "Failed to manipulate with rmagick, maybe it is not an image?" rmagick_processing_error: "Failed to manipulate with rmagick, maybe it is not an image?"
mini_magick_processing_error: "Failed to manipulate with MiniMagick, maybe it is not an image? Original Error: %{e}" mini_magick_processing_error: "Failed to manipulate with MiniMagick, maybe it is not an image? Original Error: %{e}"
min_size_error: "File size should be greater than %{min_size}" min_size_error: "File size should be greater than %{min_size}"
... ...
......
# frozen_string_literal: true
class CreateUserHighestRoles < ActiveRecord::Migration[6.0]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
def up
with_lock_retries do
create_table :user_highest_roles, id: false do |t|
t.datetime_with_timezone :updated_at, null: false
t.references :user, primary_key: true, default: nil, index: false, foreign_key: { on_delete: :cascade }
t.integer :highest_access_level
t.index [:user_id, :highest_access_level]
end
end
end
def down
with_lock_retries do
drop_table :user_highest_roles
end
end
end
...@@ -4251,6 +4251,12 @@ ActiveRecord::Schema.define(version: 2020_03_11_165635) do ...@@ -4251,6 +4251,12 @@ ActiveRecord::Schema.define(version: 2020_03_11_165635) do
t.index ["user_id"], name: "index_user_details_on_user_id", unique: true t.index ["user_id"], name: "index_user_details_on_user_id", unique: true
end end
create_table "user_highest_roles", primary_key: "user_id", id: :bigint, default: nil, force: :cascade do |t|
t.datetime_with_timezone "updated_at", null: false
t.integer "highest_access_level"
t.index ["user_id", "highest_access_level"], name: "index_user_highest_roles_on_user_id_and_highest_access_level"
end
create_table "user_interacted_projects", id: false, force: :cascade do |t| create_table "user_interacted_projects", id: false, force: :cascade do |t|
t.integer "user_id", null: false t.integer "user_id", null: false
t.integer "project_id", null: false t.integer "project_id", null: false
...@@ -5135,6 +5141,7 @@ ActiveRecord::Schema.define(version: 2020_03_11_165635) do ...@@ -5135,6 +5141,7 @@ ActiveRecord::Schema.define(version: 2020_03_11_165635) do
add_foreign_key "user_callouts", "users", on_delete: :cascade add_foreign_key "user_callouts", "users", on_delete: :cascade
add_foreign_key "user_custom_attributes", "users", on_delete: :cascade add_foreign_key "user_custom_attributes", "users", on_delete: :cascade
add_foreign_key "user_details", "users", on_delete: :cascade add_foreign_key "user_details", "users", on_delete: :cascade
add_foreign_key "user_highest_roles", "users", on_delete: :cascade
add_foreign_key "user_interacted_projects", "projects", name: "fk_722ceba4f7", on_delete: :cascade add_foreign_key "user_interacted_projects", "projects", name: "fk_722ceba4f7", on_delete: :cascade
add_foreign_key "user_interacted_projects", "users", name: "fk_0894651f08", on_delete: :cascade add_foreign_key "user_interacted_projects", "users", name: "fk_0894651f08", on_delete: :cascade
add_foreign_key "user_preferences", "users", on_delete: :cascade add_foreign_key "user_preferences", "users", on_delete: :cascade
... ...
......
...@@ -30,7 +30,7 @@ This configuration is supported in [GitLab Starter, Premium and Ultimate](https: ...@@ -30,7 +30,7 @@ This configuration is supported in [GitLab Starter, Premium and Ultimate](https:
References: References:
- [Installation Docs](../../install/README.html) - [Installation Docs](../../install/README.md)
- [Backup/Restore Docs](https://docs.gitlab.com/omnibus/settings/backups.html#backup-and-restore-omnibus-gitlab-configuration) - [Backup/Restore Docs](https://docs.gitlab.com/omnibus/settings/backups.html#backup-and-restore-omnibus-gitlab-configuration)
### Level 2: Multiple application servers ### Level 2: Multiple application servers
...@@ -68,7 +68,7 @@ This configuration is supported in [GitLab Premium and Ultimate](https://about.g ...@@ -68,7 +68,7 @@ This configuration is supported in [GitLab Premium and Ultimate](https://about.g
References: References:
- [Geo Documentation](../../gitlab-geo/README.html) - [Geo Documentation](../../gitlab-geo/README.html)
- [GitLab Geo with a highly available configuration](../geo/replication/high_availability.html) - [GitLab Geo with a highly available configuration](../geo/replication/high_availability.md)
## Recommended setups based on number of users ## Recommended setups based on number of users
... ...
......
...@@ -130,7 +130,7 @@ following attributes: ...@@ -130,7 +130,7 @@ following attributes:
- `has_external_dependencies` - whether or not the queue connects to external - `has_external_dependencies` - whether or not the queue connects to external
services. For example, all importers have this set to `true`. services. For example, all importers have this set to `true`.
- `urgency` - how important it is that this queue's jobs run - `urgency` - how important it is that this queue's jobs run
quickly. Can be `high`, `default`, or `none`. For example, the quickly. Can be `high`, `low`, or `throttled`. For example, the
`authorized_projects` queue is used to refresh user permissions, and `authorized_projects` queue is used to refresh user permissions, and
is high urgency. is high urgency.
- `name` - the queue name. The other attributes are typically more useful as - `name` - the queue name. The other attributes are typically more useful as
... ...
......
...@@ -3757,7 +3757,7 @@ input IssueSetConfidentialInput { ...@@ -3757,7 +3757,7 @@ input IssueSetConfidentialInput {
""" """
The iid of the issue to mutate The iid of the issue to mutate
""" """
iid: String! iid: ID!
""" """
The project the issue to mutate is in The project the issue to mutate is in
...@@ -3802,7 +3802,7 @@ input IssueSetDueDateInput { ...@@ -3802,7 +3802,7 @@ input IssueSetDueDateInput {
""" """
The iid of the issue to mutate The iid of the issue to mutate
""" """
iid: String! iid: ID!
""" """
The project the issue to mutate is in The project the issue to mutate is in
...@@ -3842,7 +3842,7 @@ input IssueSetWeightInput { ...@@ -3842,7 +3842,7 @@ input IssueSetWeightInput {
""" """
The iid of the issue to mutate The iid of the issue to mutate
""" """
iid: String! iid: ID!
""" """
The project the issue to mutate is in The project the issue to mutate is in
...@@ -4150,7 +4150,7 @@ type MergeRequest implements Noteable { ...@@ -4150,7 +4150,7 @@ type MergeRequest implements Noteable {
""" """
Internal ID of the merge request Internal ID of the merge request
""" """
iid: String! iid: ID!
""" """
Commit SHA of the merge request if merge is in progress Commit SHA of the merge request if merge is in progress
...@@ -4550,7 +4550,7 @@ input MergeRequestSetAssigneesInput { ...@@ -4550,7 +4550,7 @@ input MergeRequestSetAssigneesInput {
""" """
The iid of the merge request to mutate The iid of the merge request to mutate
""" """
iid: String! iid: ID!
""" """
The operation to perform. Defaults to REPLACE. The operation to perform. Defaults to REPLACE.
...@@ -4595,7 +4595,7 @@ input MergeRequestSetLabelsInput { ...@@ -4595,7 +4595,7 @@ input MergeRequestSetLabelsInput {
""" """
The iid of the merge request to mutate The iid of the merge request to mutate
""" """
iid: String! iid: ID!
""" """
The Label IDs to set. Replaces existing labels by default. The Label IDs to set. Replaces existing labels by default.
...@@ -4645,7 +4645,7 @@ input MergeRequestSetLockedInput { ...@@ -4645,7 +4645,7 @@ input MergeRequestSetLockedInput {
""" """
The iid of the merge request to mutate The iid of the merge request to mutate
""" """
iid: String! iid: ID!
""" """
Whether or not to lock the merge request. Whether or not to lock the merge request.
...@@ -4690,7 +4690,7 @@ input MergeRequestSetMilestoneInput { ...@@ -4690,7 +4690,7 @@ input MergeRequestSetMilestoneInput {
""" """
The iid of the merge request to mutate The iid of the merge request to mutate
""" """
iid: String! iid: ID!
""" """
The milestone to assign to the merge request. The milestone to assign to the merge request.
...@@ -4735,7 +4735,7 @@ input MergeRequestSetSubscriptionInput { ...@@ -4735,7 +4735,7 @@ input MergeRequestSetSubscriptionInput {
""" """
The iid of the merge request to mutate The iid of the merge request to mutate
""" """
iid: String! iid: ID!
""" """
The project the merge request to mutate is in The project the merge request to mutate is in
...@@ -4780,7 +4780,7 @@ input MergeRequestSetWipInput { ...@@ -4780,7 +4780,7 @@ input MergeRequestSetWipInput {
""" """
The iid of the merge request to mutate The iid of the merge request to mutate
""" """
iid: String! iid: ID!
""" """
The project the merge request to mutate is in The project the merge request to mutate is in
...@@ -5351,7 +5351,7 @@ type Pipeline { ...@@ -5351,7 +5351,7 @@ type Pipeline {
""" """
Internal ID of the pipeline Internal ID of the pipeline
""" """
iid: String! iid: ID!
""" """
SHA of the pipeline's commit SHA of the pipeline's commit
...@@ -5629,12 +5629,12 @@ type Project { ...@@ -5629,12 +5629,12 @@ type Project {
""" """
IID of the issue. For example, "1" IID of the issue. For example, "1"
""" """
iid: String iid: ID
""" """
List of IIDs of issues. For example, [1, 2] List of IIDs of issues. For example, [1, 2]
""" """
iids: [String!] iids: [ID!]
""" """
Labels applied to this issue Labels applied to this issue
...@@ -5724,12 +5724,12 @@ type Project { ...@@ -5724,12 +5724,12 @@ type Project {
""" """
IID of the issue. For example, "1" IID of the issue. For example, "1"
""" """
iid: String iid: ID
""" """
List of IIDs of issues. For example, [1, 2] List of IIDs of issues. For example, [1, 2]
""" """
iids: [String!] iids: [ID!]
""" """
Labels applied to this issue Labels applied to this issue
...@@ -5799,12 +5799,12 @@ type Project { ...@@ -5799,12 +5799,12 @@ type Project {
""" """
The IID of the merge request, e.g., "1" The IID of the merge request, e.g., "1"
""" """
iid: String iid: ID
""" """
The list of IIDs of issues, e.g., [1, 2] The list of IIDs of issues, e.g., [1, 2]
""" """
iids: [String!] iids: [ID!]
): MergeRequest ): MergeRequest
""" """
...@@ -5829,12 +5829,12 @@ type Project { ...@@ -5829,12 +5829,12 @@ type Project {
""" """
The IID of the merge request, e.g., "1" The IID of the merge request, e.g., "1"
""" """
iid: String iid: ID
""" """
The list of IIDs of issues, e.g., [1, 2] The list of IIDs of issues, e.g., [1, 2]
""" """
iids: [String!] iids: [ID!]
""" """
Returns the last _n_ elements from the list. Returns the last _n_ elements from the list.
...@@ -8112,7 +8112,7 @@ input UpdateIssueInput { ...@@ -8112,7 +8112,7 @@ input UpdateIssueInput {
""" """
The iid of the issue to mutate The iid of the issue to mutate
""" """
iid: String! iid: ID!
""" """
The project the issue to mutate is in The project the issue to mutate is in
... ...
......
...@@ -702,7 +702,7 @@ ...@@ -702,7 +702,7 @@
"description": "IID of the issue. For example, \"1\"", "description": "IID of the issue. For example, \"1\"",
"type": { "type": {
"kind": "SCALAR", "kind": "SCALAR",
"name": "String", "name": "ID",
"ofType": null "ofType": null
}, },
"defaultValue": null "defaultValue": null
...@@ -718,7 +718,7 @@ ...@@ -718,7 +718,7 @@
"name": null, "name": null,
"ofType": { "ofType": {
"kind": "SCALAR", "kind": "SCALAR",
"name": "String", "name": "ID",
"ofType": null "ofType": null
} }
} }
...@@ -881,7 +881,7 @@ ...@@ -881,7 +881,7 @@
"description": "IID of the issue. For example, \"1\"", "description": "IID of the issue. For example, \"1\"",
"type": { "type": {
"kind": "SCALAR", "kind": "SCALAR",
"name": "String", "name": "ID",
"ofType": null "ofType": null
}, },
"defaultValue": null "defaultValue": null
...@@ -897,7 +897,7 @@ ...@@ -897,7 +897,7 @@
"name": null, "name": null,
"ofType": { "ofType": {
"kind": "SCALAR", "kind": "SCALAR",
"name": "String", "name": "ID",
"ofType": null "ofType": null
} }
} }
...@@ -1156,7 +1156,7 @@ ...@@ -1156,7 +1156,7 @@
"description": "The IID of the merge request, e.g., \"1\"", "description": "The IID of the merge request, e.g., \"1\"",
"type": { "type": {
"kind": "SCALAR", "kind": "SCALAR",
"name": "String", "name": "ID",
"ofType": null "ofType": null
}, },
"defaultValue": null "defaultValue": null
...@@ -1172,7 +1172,7 @@ ...@@ -1172,7 +1172,7 @@
"name": null, "name": null,
"ofType": { "ofType": {
"kind": "SCALAR", "kind": "SCALAR",
"name": "String", "name": "ID",
"ofType": null "ofType": null
} }
} }
...@@ -1197,7 +1197,7 @@ ...@@ -1197,7 +1197,7 @@
"description": "The IID of the merge request, e.g., \"1\"", "description": "The IID of the merge request, e.g., \"1\"",
"type": { "type": {
"kind": "SCALAR", "kind": "SCALAR",
"name": "String", "name": "ID",
"ofType": null "ofType": null
}, },
"defaultValue": null "defaultValue": null
...@@ -1213,7 +1213,7 @@ ...@@ -1213,7 +1213,7 @@
"name": null, "name": null,
"ofType": { "ofType": {
"kind": "SCALAR", "kind": "SCALAR",
"name": "String", "name": "ID",
"ofType": null "ofType": null
} }
} }
...@@ -14425,7 +14425,7 @@ ...@@ -14425,7 +14425,7 @@
"name": null, "name": null,
"ofType": { "ofType": {
"kind": "SCALAR", "kind": "SCALAR",
"name": "String", "name": "ID",
"ofType": null "ofType": null
} }
}, },
...@@ -16204,7 +16204,7 @@ ...@@ -16204,7 +16204,7 @@
"name": null, "name": null,
"ofType": { "ofType": {
"kind": "SCALAR", "kind": "SCALAR",
"name": "String", "name": "ID",
"ofType": null "ofType": null
} }
}, },
...@@ -20999,7 +20999,7 @@ ...@@ -20999,7 +20999,7 @@
"name": null, "name": null,
"ofType": { "ofType": {
"kind": "SCALAR", "kind": "SCALAR",
"name": "String", "name": "ID",
"ofType": null "ofType": null
} }
}, },
...@@ -21129,7 +21129,7 @@ ...@@ -21129,7 +21129,7 @@
"name": null, "name": null,
"ofType": { "ofType": {
"kind": "SCALAR", "kind": "SCALAR",
"name": "String", "name": "ID",
"ofType": null "ofType": null
} }
}, },
...@@ -21259,7 +21259,7 @@ ...@@ -21259,7 +21259,7 @@
"name": null, "name": null,
"ofType": { "ofType": {
"kind": "SCALAR", "kind": "SCALAR",
"name": "String", "name": "ID",
"ofType": null "ofType": null
} }
}, },
...@@ -21425,7 +21425,7 @@ ...@@ -21425,7 +21425,7 @@
"name": null, "name": null,
"ofType": { "ofType": {
"kind": "SCALAR", "kind": "SCALAR",
"name": "String", "name": "ID",
"ofType": null "ofType": null
} }
}, },
...@@ -21602,7 +21602,7 @@ ...@@ -21602,7 +21602,7 @@
"name": null, "name": null,
"ofType": { "ofType": {
"kind": "SCALAR", "kind": "SCALAR",
"name": "String", "name": "ID",
"ofType": null "ofType": null
} }
}, },
...@@ -21732,7 +21732,7 @@ ...@@ -21732,7 +21732,7 @@
"name": null, "name": null,
"ofType": { "ofType": {
"kind": "SCALAR", "kind": "SCALAR",
"name": "String", "name": "ID",
"ofType": null "ofType": null
} }
}, },
...@@ -21858,7 +21858,7 @@ ...@@ -21858,7 +21858,7 @@
"name": null, "name": null,
"ofType": { "ofType": {
"kind": "SCALAR", "kind": "SCALAR",
"name": "String", "name": "ID",
"ofType": null "ofType": null
} }
}, },
...@@ -21988,7 +21988,7 @@ ...@@ -21988,7 +21988,7 @@
"name": null, "name": null,
"ofType": { "ofType": {
"kind": "SCALAR", "kind": "SCALAR",
"name": "String", "name": "ID",
"ofType": null "ofType": null
} }
}, },
...@@ -22118,7 +22118,7 @@ ...@@ -22118,7 +22118,7 @@
"name": null, "name": null,
"ofType": { "ofType": {
"kind": "SCALAR", "kind": "SCALAR",
"name": "String", "name": "ID",
"ofType": null "ofType": null
} }
}, },
...@@ -24554,7 +24554,7 @@ ...@@ -24554,7 +24554,7 @@
"name": null, "name": null,
"ofType": { "ofType": {
"kind": "SCALAR", "kind": "SCALAR",
"name": "String", "name": "ID",
"ofType": null "ofType": null
} }
}, },
... ...
......
...@@ -630,7 +630,7 @@ Autogenerated return type of MarkAsSpamSnippet ...@@ -630,7 +630,7 @@ Autogenerated return type of MarkAsSpamSnippet
| `forceRemoveSourceBranch` | Boolean | Indicates if the project settings will lead to source branch deletion after merge | | `forceRemoveSourceBranch` | Boolean | Indicates if the project settings will lead to source branch deletion after merge |
| `headPipeline` | Pipeline | The pipeline running on the branch HEAD of the merge request | | `headPipeline` | Pipeline | The pipeline running on the branch HEAD of the merge request |
| `id` | ID! | ID of the merge request | | `id` | ID! | ID of the merge request |
| `iid` | String! | Internal ID of the merge request | | `iid` | ID! | Internal ID of the merge request |
| `inProgressMergeCommitSha` | String | Commit SHA of the merge request if merge is in progress | | `inProgressMergeCommitSha` | String | Commit SHA of the merge request if merge is in progress |
| `mergeCommitMessage` **{warning-solid}** | String | **Deprecated:** Renamed to defaultMergeCommitMessage | | `mergeCommitMessage` **{warning-solid}** | String | **Deprecated:** Renamed to defaultMergeCommitMessage |
| `mergeCommitSha` | String | SHA of the merge request commit (set once merged) | | `mergeCommitSha` | String | SHA of the merge request commit (set once merged) |
...@@ -834,7 +834,7 @@ Information about pagination in a connection. ...@@ -834,7 +834,7 @@ Information about pagination in a connection.
| `duration` | Int | Duration of the pipeline in seconds | | `duration` | Int | Duration of the pipeline in seconds |
| `finishedAt` | Time | Timestamp of the pipeline's completion | | `finishedAt` | Time | Timestamp of the pipeline's completion |
| `id` | ID! | ID of the pipeline | | `id` | ID! | ID of the pipeline |
| `iid` | String! | Internal ID of the pipeline | | `iid` | ID! | Internal ID of the pipeline |
| `sha` | String! | SHA of the pipeline's commit | | `sha` | String! | SHA of the pipeline's commit |
| `startedAt` | Time | Timestamp when the pipeline was started | | `startedAt` | Time | Timestamp when the pipeline was started |
| `status` | PipelineStatusEnum! | Status of the pipeline (CREATED, WAITING_FOR_RESOURCE, PREPARING, PENDING, RUNNING, FAILED, SUCCESS, CANCELED, SKIPPED, MANUAL, SCHEDULED) | | `status` | PipelineStatusEnum! | Status of the pipeline (CREATED, WAITING_FOR_RESOURCE, PREPARING, PENDING, RUNNING, FAILED, SUCCESS, CANCELED, SKIPPED, MANUAL, SCHEDULED) |
... ...
......
...@@ -541,7 +541,7 @@ argument :project_path, GraphQL::ID_TYPE, ...@@ -541,7 +541,7 @@ argument :project_path, GraphQL::ID_TYPE,
required: true, required: true,
description: "The project the merge request to mutate is in" description: "The project the merge request to mutate is in"
argument :iid, GraphQL::STRING_TYPE, argument :iid, GraphQL::ID_TYPE,
required: true, required: true,
description: "The iid of the merge request to mutate" description: "The iid of the merge request to mutate"
... ...
......
...@@ -124,13 +124,13 @@ Consider skipping the cop if you're not confident your job can safely run multip ...@@ -124,13 +124,13 @@ Consider skipping the cop if you're not confident your job can safely run multip
## Job urgency ## Job urgency
Jobs can have an `urgency` attribute set, which can be `:high`, Jobs can have an `urgency` attribute set, which can be `:high`,
`:default`, or `:none`. These have the below targets: `:low`, or `:throttled`. These have the below targets:
| **Urgency** | **Queue Scheduling Target** | **Execution Latency Requirement** | | **Urgency** | **Queue Scheduling Target** | **Execution Latency Requirement** |
|-------------|-----------------------------|------------------------------------| |--------------|-----------------------------|------------------------------------|
| `:high` | 100 milliseconds | p50 of 1 second, p99 of 10 seconds | | `:high` | 100 milliseconds | p50 of 1 second, p99 of 10 seconds |
| `:default` | 1 minute | Maximum run time of 1 hour | | `:low` | 1 minute | Maximum run time of 1 hour |
| `:none` | None | Maximum run time of 1 hour | | `:throttled` | None | Maximum run time of 1 hour |
To set a job's urgency, use the `urgency` class method: To set a job's urgency, use the `urgency` class method:
...@@ -175,7 +175,7 @@ these jobs also have very strict execution duration requirements: ...@@ -175,7 +175,7 @@ these jobs also have very strict execution duration requirements:
If a worker cannot meet these expectations, then it cannot be treated as a If a worker cannot meet these expectations, then it cannot be treated as a
`urgency :high` worker: consider redesigning the worker, or splitting the `urgency :high` worker: consider redesigning the worker, or splitting the
work between two different workers, one with `urgency :high` code that work between two different workers, one with `urgency :high` code that
executes quickly, and the other with `urgency :default`, which has no executes quickly, and the other with `urgency :low`, which has no
execution latency requirements (but also has lower scheduling targets). execution latency requirements (but also has lower scheduling targets).
## Jobs with External Dependencies ## Jobs with External Dependencies
... ...
......
...@@ -6,6 +6,7 @@ module Gitlab ...@@ -6,6 +6,7 @@ module Gitlab
module Test module Test
class Junit class Junit
JunitParserError = Class.new(Gitlab::Ci::Parsers::ParserError) JunitParserError = Class.new(Gitlab::Ci::Parsers::ParserError)
ATTACHMENT_TAG_REGEX = /\[\[ATTACHMENT\|(?<path>.+?)\]\]/.freeze
def parse!(xml_data, test_suite) def parse!(xml_data, test_suite)
root = Hash.from_xml(xml_data) root = Hash.from_xml(xml_data)
...@@ -49,6 +50,7 @@ module Gitlab ...@@ -49,6 +50,7 @@ module Gitlab
if data['failure'] if data['failure']
status = ::Gitlab::Ci::Reports::TestCase::STATUS_FAILED status = ::Gitlab::Ci::Reports::TestCase::STATUS_FAILED
system_output = data['failure'] system_output = data['failure']
attachment = attachment_path(data['system_out'])
elsif data['error'] elsif data['error']
status = ::Gitlab::Ci::Reports::TestCase::STATUS_ERROR status = ::Gitlab::Ci::Reports::TestCase::STATUS_ERROR
system_output = data['error'] system_output = data['error']
...@@ -63,9 +65,17 @@ module Gitlab ...@@ -63,9 +65,17 @@ module Gitlab
file: data['file'], file: data['file'],
execution_time: data['time'], execution_time: data['time'],
status: status, status: status,
system_output: system_output system_output: system_output,
attachment: attachment
) )
end end
def attachment_path(data)
return unless data
matches = data.match(ATTACHMENT_TAG_REGEX)
matches[:path] if matches
end
end end
end end
end end
... ...
......
...@@ -10,9 +10,9 @@ module Gitlab ...@@ -10,9 +10,9 @@ module Gitlab
STATUS_ERROR = 'error' STATUS_ERROR = 'error'
STATUS_TYPES = [STATUS_SUCCESS, STATUS_FAILED, STATUS_SKIPPED, STATUS_ERROR].freeze STATUS_TYPES = [STATUS_SUCCESS, STATUS_FAILED, STATUS_SKIPPED, STATUS_ERROR].freeze
attr_reader :name, :classname, :execution_time, :status, :file, :system_output, :stack_trace, :key attr_reader :name, :classname, :execution_time, :status, :file, :system_output, :stack_trace, :key, :attachment
def initialize(name:, classname:, execution_time:, status:, file: nil, system_output: nil, stack_trace: nil) def initialize(name:, classname:, execution_time:, status:, file: nil, system_output: nil, stack_trace: nil, attachment: nil)
@name = name @name = name
@classname = classname @classname = classname
@file = file @file = file
...@@ -21,6 +21,11 @@ module Gitlab ...@@ -21,6 +21,11 @@ module Gitlab
@system_output = system_output @system_output = system_output
@stack_trace = stack_trace @stack_trace = stack_trace
@key = sanitize_key_name("#{classname}_#{name}") @key = sanitize_key_name("#{classname}_#{name}")
@attachment = attachment
end
def has_attachment?
attachment.present?
end end
private private
... ...
......
...@@ -3406,9 +3406,6 @@ msgstr "" ...@@ -3406,9 +3406,6 @@ msgstr ""
msgid "Changing group path can have unintended side effects." msgid "Changing group path can have unintended side effects."
msgstr "" msgstr ""
   
msgid "Charts"
msgstr ""
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}" msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr "" msgstr ""
   
...@@ -19917,10 +19914,10 @@ msgstr "" ...@@ -19917,10 +19914,10 @@ msgstr ""
msgid "There was an error fetching median data for stages" msgid "There was an error fetching median data for stages"
msgstr "" msgstr ""
   
msgid "There was an error fetching the Designs" msgid "There was an error fetching the Node's Groups"
msgstr "" msgstr ""
   
msgid "There was an error fetching the Node's Groups" msgid "There was an error fetching the designs"
msgstr "" msgstr ""
   
msgid "There was an error fetching the environments information." msgid "There was an error fetching the environments information."
...@@ -19965,7 +19962,7 @@ msgstr "" ...@@ -19965,7 +19962,7 @@ msgstr ""
msgid "There was an error subscribing to this label." msgid "There was an error subscribing to this label."
msgstr "" msgstr ""
   
msgid "There was an error syncing the Design Repositories." msgid "There was an error syncing the designs."
msgstr "" msgstr ""
   
msgid "There was an error trying to validate your query" msgid "There was an error trying to validate your query"
... ...
......
...@@ -10,7 +10,6 @@ module QA ...@@ -10,7 +10,6 @@ module QA
element :group_settings_item element :group_settings_item
element :group_members_item element :group_members_item
element :general_settings_link element :general_settings_link
element :contribution_analytics_link
end end
view 'app/views/layouts/nav/sidebar/_analytics_links.html.haml' do view 'app/views/layouts/nav/sidebar/_analytics_links.html.haml' do
... ...
......
# frozen_string_literal: true
FactoryBot.define do
factory :test_case, class: 'Gitlab::Ci::Reports::TestCase' do
name { "test-1" }
classname { "trace" }
file { "spec/trace_spec.rb" }
execution_time { 1.23 }
status { "success" }
system_output { nil }
attachment { nil }
trait :with_attachment do
attachment { "some/path.png" }
end
skip_create
initialize_with do
new(
name: name,
classname: classname,
file: file,
execution_time: execution_time,
status: status,
system_output: system_output,
attachment: attachment
)
end
end
end