Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
fdfde5a37a
commit
4e81d9c050
10
.rubocop.yml
10
.rubocop.yml
|
@ -461,3 +461,13 @@ Performance/ChainArrayAllocation:
|
|||
- 'lib/gitlab/import_export/**/*'
|
||||
- 'ee/lib/gitlab/import_export/**/*'
|
||||
- 'ee/lib/ee/gitlab/import_export/**/*'
|
||||
|
||||
Rails/TimeZone:
|
||||
Enabled: true
|
||||
EnforcedStyle: 'flexible'
|
||||
Include:
|
||||
- 'app/services/**/*'
|
||||
- 'spec/services/**/*'
|
||||
- 'ee/app/services/**/*'
|
||||
- 'ee/spec/services/**/*'
|
||||
|
||||
|
|
|
@ -121,7 +121,7 @@ export default {
|
|||
/>
|
||||
</form>
|
||||
</template>
|
||||
<template slot="modal-footer">
|
||||
<template #modal-footer>
|
||||
<gl-deprecated-button variant="secondary" @click="onCancel">{{
|
||||
s__('Cancel')
|
||||
}}</gl-deprecated-button>
|
||||
|
|
|
@ -85,7 +85,7 @@ Once you confirm %{deleteAccount}, it cannot be undone or recovered.`),
|
|||
kind="danger"
|
||||
@submit="onSubmit"
|
||||
>
|
||||
<template slot="body" slot-scope="props">
|
||||
<template #body="props">
|
||||
<p v-html="props.text"></p>
|
||||
|
||||
<form ref="form" :action="actionUrl" method="post">
|
||||
|
|
|
@ -76,10 +76,10 @@ export default {
|
|||
</gl-link>
|
||||
|
||||
<expand-button>
|
||||
<template slot="short">
|
||||
<template #short>
|
||||
<span class="js-short monospace">{{ shortSha(index) }}</span>
|
||||
</template>
|
||||
<template slot="expanded">
|
||||
<template #expanded>
|
||||
<span class="js-expanded monospace gl-pl-1-deprecated-no-really-do-not-use-me">{{
|
||||
sha(index)
|
||||
}}</span>
|
||||
|
|
|
@ -138,8 +138,8 @@ export default {
|
|||
:width="width"
|
||||
:include-legend-avg-max="false"
|
||||
>
|
||||
<template slot="tooltipTitle">{{ tooltipPopoverTitle }}</template>
|
||||
<template slot="tooltipContent">{{ tooltipPopoverContent }}</template>
|
||||
<template #tooltipTitle>{{ tooltipPopoverTitle }}</template>
|
||||
<template #tooltipContent>{{ tooltipPopoverContent }}</template>
|
||||
</gl-area-chart>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -207,7 +207,7 @@ export default {
|
|||
category="primary"
|
||||
variant="success"
|
||||
:disabled="updatePrevented"
|
||||
data-qa-selector="create_snippet_button"
|
||||
data-qa-selector="submit_button"
|
||||
@click="handleFormSubmit"
|
||||
>{{ saveButtonLabel }}</gl-button
|
||||
>
|
||||
|
|
|
@ -99,6 +99,7 @@ export default {
|
|||
class="mr-2"
|
||||
:ssh-link="snippet.sshUrlToRepo"
|
||||
:http-link="snippet.httpUrlToRepo"
|
||||
data-qa-selector="clone_button"
|
||||
/>
|
||||
</template>
|
||||
</blob-header>
|
||||
|
|
|
@ -207,6 +207,8 @@ export default {
|
|||
:category="action.category"
|
||||
:class="action.cssClass"
|
||||
:href="action.href"
|
||||
data-qa-selector="snippet_action_button"
|
||||
:data-qa-action="action.text"
|
||||
@click="action.click ? action.click() : undefined"
|
||||
>
|
||||
{{ action.text }}
|
||||
|
|
|
@ -57,6 +57,7 @@ export default {
|
|||
v-gl-tooltip.hover
|
||||
:title="$options.copyURLTooltip"
|
||||
:data-clipboard-text="sshLink"
|
||||
data-qa-selector="copy_ssh_url_button"
|
||||
icon="copy-to-clipboard"
|
||||
class="d-inline-flex"
|
||||
/>
|
||||
|
@ -75,6 +76,7 @@ export default {
|
|||
v-gl-tooltip.hover
|
||||
:title="$options.copyURLTooltip"
|
||||
:data-clipboard-text="httpLink"
|
||||
data-qa-selector="copy_http_url_button"
|
||||
icon="copy-to-clipboard"
|
||||
class="d-inline-flex"
|
||||
/>
|
||||
|
|
|
@ -88,12 +88,12 @@ class Iteration < ApplicationRecord
|
|||
# ensure dates are in the future
|
||||
def future_date
|
||||
if start_date_changed?
|
||||
errors.add(:start_date, s_("Iteration|cannot be in the past")) if start_date < Date.today
|
||||
errors.add(:start_date, s_("Iteration|cannot be in the past")) if start_date < Date.current
|
||||
errors.add(:start_date, s_("Iteration|cannot be more than 500 years in the future")) if start_date > 500.years.from_now
|
||||
end
|
||||
|
||||
if due_date_changed?
|
||||
errors.add(:due_date, s_("Iteration|cannot be in the past")) if due_date < Date.today
|
||||
errors.add(:due_date, s_("Iteration|cannot be in the past")) if due_date < Date.current
|
||||
errors.add(:due_date, s_("Iteration|cannot be more than 500 years in the future")) if due_date > 500.years.from_now
|
||||
end
|
||||
end
|
||||
|
|
|
@ -52,7 +52,7 @@ module Auth
|
|||
end
|
||||
|
||||
def self.token_expire_at
|
||||
Time.now + Gitlab::CurrentSettings.container_registry_token_expire_delay.minutes
|
||||
Time.current + Gitlab::CurrentSettings.container_registry_token_expire_delay.minutes
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -201,7 +201,7 @@ module Ci
|
|||
labels[:shard] = shard.gsub(METRICS_SHARD_TAG_PREFIX, '') if shard
|
||||
end
|
||||
|
||||
job_queue_duration_seconds.observe(labels, Time.now - job.queued_at) unless job.queued_at.nil?
|
||||
job_queue_duration_seconds.observe(labels, Time.current - job.queued_at) unless job.queued_at.nil?
|
||||
attempt_counter.increment
|
||||
end
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ module Clusters
|
|||
end
|
||||
|
||||
def timed_out?
|
||||
Time.now.utc - app.updated_at.utc > ClusterWaitForAppInstallationWorker::TIMEOUT
|
||||
Time.current.utc - app.updated_at.utc > ClusterWaitForAppInstallationWorker::TIMEOUT
|
||||
end
|
||||
|
||||
def remove_installation_pod
|
||||
|
|
|
@ -31,7 +31,7 @@ module Clusters
|
|||
end
|
||||
|
||||
def timed_out?
|
||||
Time.now.utc - app.updated_at.utc > WaitForUninstallAppWorker::TIMEOUT
|
||||
Time.current.utc - app.updated_at.utc > WaitForUninstallAppWorker::TIMEOUT
|
||||
end
|
||||
|
||||
def remove_uninstallation_pod
|
||||
|
|
|
@ -46,7 +46,7 @@ module Clusters
|
|||
end
|
||||
|
||||
def timed_out?
|
||||
Time.now.utc - app.updated_at.to_time.utc > ::ClusterWaitForAppUpdateWorker::TIMEOUT
|
||||
Time.current.utc - app.updated_at.to_time.utc > ::ClusterWaitForAppUpdateWorker::TIMEOUT
|
||||
end
|
||||
|
||||
def remove_pod
|
||||
|
|
|
@ -16,9 +16,9 @@ module Clusters
|
|||
return unless application
|
||||
|
||||
if recently_scheduled?
|
||||
worker_class.perform_in(BACKOFF_DELAY, application.name, application.id, project.id, Time.now)
|
||||
worker_class.perform_in(BACKOFF_DELAY, application.name, application.id, project.id, Time.current)
|
||||
else
|
||||
worker_class.perform_async(application.name, application.id, project.id, Time.now)
|
||||
worker_class.perform_async(application.name, application.id, project.id, Time.current)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -31,7 +31,7 @@ module Clusters
|
|||
def recently_scheduled?
|
||||
return false unless application.last_update_started_at
|
||||
|
||||
application.last_update_started_at.utc >= Time.now.utc - BACKOFF_DELAY
|
||||
application.last_update_started_at.utc >= Time.current.utc - BACKOFF_DELAY
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -35,7 +35,7 @@ module Clusters
|
|||
end
|
||||
|
||||
def elapsed_time_from_creation(operation)
|
||||
Time.now.utc - operation.start_time.to_time.utc
|
||||
Time.current.utc - operation.start_time.to_time.utc
|
||||
end
|
||||
|
||||
def finalize_creation
|
||||
|
|
|
@ -54,8 +54,8 @@ module Clusters
|
|||
cert = OpenSSL::X509::Certificate.new
|
||||
cert.version = 2
|
||||
cert.serial = 0
|
||||
cert.not_before = Time.now
|
||||
cert.not_after = Time.now + 1000.years
|
||||
cert.not_before = Time.current
|
||||
cert.not_after = Time.current + 1000.years
|
||||
|
||||
cert.public_key = key.public_key
|
||||
cert.subject = name
|
||||
|
|
|
@ -221,7 +221,7 @@ class IssuableBaseService < BaseService
|
|||
issuable.assign_attributes(params)
|
||||
|
||||
if has_title_or_description_changed?(issuable)
|
||||
issuable.assign_attributes(last_edited_at: Time.now, last_edited_by: current_user)
|
||||
issuable.assign_attributes(last_edited_at: Time.current, last_edited_by: current_user)
|
||||
end
|
||||
|
||||
before_update(issuable)
|
||||
|
@ -270,7 +270,7 @@ class IssuableBaseService < BaseService
|
|||
|
||||
if issuable.changed? || params.present?
|
||||
issuable.assign_attributes(params.merge(updated_by: current_user,
|
||||
last_edited_at: Time.now,
|
||||
last_edited_at: Time.current,
|
||||
last_edited_by: current_user))
|
||||
|
||||
before_update(issuable, skip_spam_check: true)
|
||||
|
|
|
@ -8,7 +8,7 @@ module Members
|
|||
source.members.create(
|
||||
access_level: Gitlab::Access::DEVELOPER,
|
||||
user: current_user,
|
||||
requested_at: Time.now.utc)
|
||||
requested_at: Time.current.utc)
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -33,7 +33,7 @@ module Projects
|
|||
end
|
||||
|
||||
def order_by_date(tags)
|
||||
now = DateTime.now
|
||||
now = DateTime.current
|
||||
tags.sort_by { |tag| tag.created_at || now }.reverse
|
||||
end
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ module Projects
|
|||
#
|
||||
# @param [String] new_path
|
||||
def discard_path!(new_path)
|
||||
discarded_path = "#{new_path}-#{Time.now.utc.to_i}"
|
||||
discarded_path = "#{new_path}-#{Time.current.utc.to_i}"
|
||||
|
||||
logger.info("Moving existing empty attachments folder from '#{new_path}' to '#{discarded_path}', (PROJECT_ID=#{project.id})")
|
||||
FileUtils.mv(new_path, discarded_path)
|
||||
|
|
|
@ -121,7 +121,7 @@ module Projects
|
|||
end
|
||||
|
||||
def moved_path(path)
|
||||
"#{path}+#{project.id}+moved+#{Time.now.to_i}"
|
||||
"#{path}+#{project.id}+moved+#{Time.current.to_i}"
|
||||
end
|
||||
|
||||
# The underlying FetchInternalRemote call uses a `git fetch` to move data
|
||||
|
|
|
@ -26,7 +26,7 @@ module ResourceEvents
|
|||
def since_fetch_at(events)
|
||||
return events unless params[:last_fetched_at].present?
|
||||
|
||||
last_fetched_at = Time.at(params.fetch(:last_fetched_at).to_i)
|
||||
last_fetched_at = Time.zone.at(params.fetch(:last_fetched_at).to_i)
|
||||
events.created_after(last_fetched_at - NotesFinder::FETCH_OVERLAP)
|
||||
end
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ module ResourceEvents
|
|||
class ChangeMilestoneService
|
||||
attr_reader :resource, :user, :event_created_at, :milestone, :old_milestone
|
||||
|
||||
def initialize(resource, user, created_at: Time.now, old_milestone:)
|
||||
def initialize(resource, user, created_at: Time.current, old_milestone:)
|
||||
@resource = resource
|
||||
@user = user
|
||||
@event_created_at = created_at
|
||||
|
|
|
@ -17,7 +17,7 @@ module Spam
|
|||
params = {
|
||||
type: 'comment',
|
||||
text: text,
|
||||
created_at: DateTime.now,
|
||||
created_at: DateTime.current,
|
||||
author: owner_name,
|
||||
author_email: owner_email,
|
||||
referrer: options[:referrer]
|
||||
|
|
|
@ -42,7 +42,7 @@ module Terraform
|
|||
|
||||
state.lock_xid = params[:lock_id]
|
||||
state.locked_by_user = current_user
|
||||
state.locked_at = Time.now
|
||||
state.locked_at = Time.current
|
||||
|
||||
state.save!
|
||||
end
|
||||
|
|
|
@ -37,7 +37,7 @@ class VerifyPagesDomainService < BaseService
|
|||
# Prevent any pre-existing grace period from being truncated
|
||||
reverify = [domain.enabled_until, VERIFICATION_PERIOD.from_now].compact.max
|
||||
|
||||
domain.assign_attributes(verified_at: Time.now, enabled_until: reverify, remove_at: nil)
|
||||
domain.assign_attributes(verified_at: Time.current, enabled_until: reverify, remove_at: nil)
|
||||
domain.save!(validate: false)
|
||||
|
||||
if was_disabled
|
||||
|
@ -73,7 +73,7 @@ class VerifyPagesDomainService < BaseService
|
|||
|
||||
# A domain is only expired until `disable!` has been called
|
||||
def expired?
|
||||
domain.enabled_until && domain.enabled_until < Time.now
|
||||
domain.enabled_until && domain.enabled_until < Time.current
|
||||
end
|
||||
|
||||
def dns_record_present?
|
||||
|
|
|
@ -44,9 +44,9 @@
|
|||
|
||||
.form-actions
|
||||
- if @snippet.new_record?
|
||||
= f.submit 'Create snippet', class: "btn-success btn qa-create-snippet-button"
|
||||
= f.submit 'Create snippet', class: "btn-success btn", data: { qa_selector: 'submit_button' }
|
||||
- else
|
||||
= f.submit 'Save changes', class: "btn-success btn"
|
||||
= f.submit 'Save changes', class: "btn-success btn", data: { qa_selector: 'submit_button' }
|
||||
|
||||
- if @snippet.project_id
|
||||
= link_to "Cancel", project_snippets_path(@project), class: "btn btn-cancel"
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Update deprecated slot syntax in ./app/assets/javascripts/pages/admin/users/components/delete_user_modal.vue
|
||||
merge_request: 31992
|
||||
author: Gilang Gumilar
|
||||
type: other
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Update deprecated slot syntax in ./app/assets/javascripts/profile/account/components/delete_account_modal.vue
|
||||
merge_request: 32007
|
||||
author: Gilang Gumilar
|
||||
type: other
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Update deprecated slot syntax in ./app/assets/javascripts/serverless/components/area.vue
|
||||
merge_request: 32015
|
||||
author: Gilang Gumilar
|
||||
type: other
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Update deprecated slot syntax in ./app/assets/javascripts/releases/components/evidence_block.vue
|
||||
merge_request: 32019
|
||||
author: Gilang Gumilar
|
||||
type: other
|
|
@ -0,0 +1,34 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class CreatePackagesNugetMetadata < ActiveRecord::Migration[6.0]
|
||||
include Gitlab::Database::MigrationHelpers
|
||||
|
||||
DOWNTIME = false
|
||||
|
||||
disable_ddl_transaction!
|
||||
|
||||
LICENSE_URL_CONSTRAINT_NAME = 'packages_nuget_metadata_license_url_constraint'
|
||||
PROJECT_URL_CONSTRAINT_NAME = 'packages_nuget_metadata_project_url_constraint'
|
||||
ICON_URL_CONSTRAINT_NAME = 'packages_nuget_metadata_icon_url_constraint'
|
||||
|
||||
def up
|
||||
unless table_exists?(:packages_nuget_metadata)
|
||||
with_lock_retries do
|
||||
create_table :packages_nuget_metadata, id: false do |t|
|
||||
t.references :package, primary_key: true, default: nil, index: false, foreign_key: { to_table: :packages_packages, on_delete: :cascade }, type: :bigint
|
||||
t.text :license_url
|
||||
t.text :project_url
|
||||
t.text :icon_url
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
add_text_limit :packages_nuget_metadata, :license_url, 255, constraint_name: LICENSE_URL_CONSTRAINT_NAME
|
||||
add_text_limit :packages_nuget_metadata, :project_url, 255, constraint_name: PROJECT_URL_CONSTRAINT_NAME
|
||||
add_text_limit :packages_nuget_metadata, :icon_url, 255, constraint_name: ICON_URL_CONSTRAINT_NAME
|
||||
end
|
||||
|
||||
def down
|
||||
drop_table :packages_nuget_metadata
|
||||
end
|
||||
end
|
|
@ -4656,6 +4656,16 @@ CREATE TABLE public.packages_nuget_dependency_link_metadata (
|
|||
CONSTRAINT packages_nuget_dependency_link_metadata_target_framework_constr CHECK ((char_length(target_framework) <= 255))
|
||||
);
|
||||
|
||||
CREATE TABLE public.packages_nuget_metadata (
|
||||
package_id bigint NOT NULL,
|
||||
license_url text,
|
||||
project_url text,
|
||||
icon_url text,
|
||||
CONSTRAINT packages_nuget_metadata_icon_url_constraint CHECK ((char_length(icon_url) <= 255)),
|
||||
CONSTRAINT packages_nuget_metadata_license_url_constraint CHECK ((char_length(license_url) <= 255)),
|
||||
CONSTRAINT packages_nuget_metadata_project_url_constraint CHECK ((char_length(project_url) <= 255))
|
||||
);
|
||||
|
||||
CREATE TABLE public.packages_package_files (
|
||||
id bigint NOT NULL,
|
||||
package_id bigint NOT NULL,
|
||||
|
@ -8538,6 +8548,9 @@ ALTER TABLE ONLY public.packages_maven_metadata
|
|||
ALTER TABLE ONLY public.packages_nuget_dependency_link_metadata
|
||||
ADD CONSTRAINT packages_nuget_dependency_link_metadata_pkey PRIMARY KEY (dependency_link_id);
|
||||
|
||||
ALTER TABLE ONLY public.packages_nuget_metadata
|
||||
ADD CONSTRAINT packages_nuget_metadata_pkey PRIMARY KEY (package_id);
|
||||
|
||||
ALTER TABLE ONLY public.packages_package_files
|
||||
ADD CONSTRAINT packages_package_files_pkey PRIMARY KEY (id);
|
||||
|
||||
|
@ -12606,6 +12619,9 @@ ALTER TABLE ONLY public.serverless_domain_cluster
|
|||
ALTER TABLE ONLY public.ci_job_variables
|
||||
ADD CONSTRAINT fk_rails_fbf3b34792 FOREIGN KEY (job_id) REFERENCES public.ci_builds(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY public.packages_nuget_metadata
|
||||
ADD CONSTRAINT fk_rails_fc0c19f5b4 FOREIGN KEY (package_id) REFERENCES public.packages_packages(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY public.cluster_groups
|
||||
ADD CONSTRAINT fk_rails_fdb8648a96 FOREIGN KEY (cluster_id) REFERENCES public.clusters(id) ON DELETE CASCADE;
|
||||
|
||||
|
@ -13809,6 +13825,7 @@ COPY "schema_migrations" (version) FROM STDIN;
|
|||
20200429181955
|
||||
20200429182245
|
||||
20200430103158
|
||||
20200430130048
|
||||
20200505164958
|
||||
20200505171834
|
||||
20200505172405
|
||||
|
|
|
@ -2,18 +2,18 @@
|
|||
type: reference
|
||||
---
|
||||
|
||||
# Gitaly Cluster **(PREMIUM)**
|
||||
|
||||
NOTE: **Note:**
|
||||
Support for Gitaly Cluster is only available through [Priority
|
||||
Support](https://about.gitlab.com/support/#priority-support) for self-managed
|
||||
Premium and Ultimate customers.
|
||||
# Gitaly Cluster
|
||||
|
||||
[Gitaly](index.md), the service that provides storage for Git repositories, can
|
||||
be run in a clustered configuration to increase fault tolerance. In this
|
||||
configuration, every Git repository is stored on every Gitaly node in the
|
||||
cluster. Multiple clusters (or shards), can be configured.
|
||||
|
||||
NOTE: **Note:**
|
||||
Gitaly Clusters can be created using [GitLab Core](https://about.gitlab.com/pricing/#self-managed)
|
||||
and higher tiers. However, technical support is limited to GitLab Premium and Ultimate customers
|
||||
only. Not available in GitLab.com.
|
||||
|
||||
Praefect is a router and transaction manager for Gitaly, and a required
|
||||
component for running a Gitaly Cluster.
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ GET /issues?confidential=true
|
|||
| `author_id` | integer | no | Return issues created by the given user `id`. Mutually exclusive with `author_username`. Combine with `scope=all` or `scope=assigned_to_me`. _([Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/13004) in GitLab 9.5)_ |
|
||||
| `author_username` | string | no | Return issues created by the given `username`. Similar to `author_id` and mutually exclusive with `author_id`. |
|
||||
| `assignee_id` | integer | no | Return issues assigned to the given user `id`. Mutually exclusive with `assignee_username`. `None` returns unassigned issues. `Any` returns issues with an assignee. _([Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/13004) in GitLab 9.5)_ |
|
||||
| `assignee_username` | string array | no | Return issues assigned to the given `username`. Similar to `assignee_id` and mutually exclusive with `assignee_id`. In CE version `assignee_username` array should only contain a single value or an invalid parameter error will be returned otherwise. |
|
||||
| `assignee_username` | string array | no | Return issues assigned to the given `username`. Similar to `assignee_id` and mutually exclusive with `assignee_id`. In GitLab CE `assignee_username` array should only contain a single value or an invalid parameter error will be returned otherwise. |
|
||||
| `my_reaction_emoji` | string | no | Return issues reacted by the authenticated user by the given `emoji`. `None` returns issues not given a reaction. `Any` returns issues given at least one reaction. _([Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/14016) in GitLab 10.0)_ |
|
||||
| `weight` **(STARTER)** | integer | no | Return issues with the specified `weight`. `None` returns issues with no weight assigned. `Any` returns issues with a weight assigned. |
|
||||
| `iids[]` | integer array | no | Return only the issues having the given `iid` |
|
||||
|
@ -211,7 +211,7 @@ GET /groups/:id/issues?confidential=true
|
|||
| `author_id` | integer | no | Return issues created by the given user `id`. Mutually exclusive with `author_username`. Combine with `scope=all` or `scope=assigned_to_me`. _([Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/13004) in GitLab 9.5)_ |
|
||||
| `author_username` | string | no | Return issues created by the given `username`. Similar to `author_id` and mutually exclusive with `author_id`. |
|
||||
| `assignee_id` | integer | no | Return issues assigned to the given user `id`. Mutually exclusive with `assignee_username`. `None` returns unassigned issues. `Any` returns issues with an assignee. _([Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/13004) in GitLab 9.5)_ |
|
||||
| `assignee_username` | string array | no | Return issues assigned to the given `username`. Similar to `assignee_id` and mutually exclusive with `assignee_id`. In CE version `assignee_username` array should only contain a single value or an invalid parameter error will be returned otherwise. |
|
||||
| `assignee_username` | string array | no | Return issues assigned to the given `username`. Similar to `assignee_id` and mutually exclusive with `assignee_id`. In GitLab CE `assignee_username` array should only contain a single value or an invalid parameter error will be returned otherwise. |
|
||||
| `my_reaction_emoji` | string | no | Return issues reacted by the authenticated user by the given `emoji`. `None` returns issues not given a reaction. `Any` returns issues given at least one reaction. _([Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/14016) in GitLab 10.0)_ |
|
||||
| `weight` **(STARTER)** | integer | no | Return issues with the specified `weight`. `None` returns issues with no weight assigned. `Any` returns issues with a weight assigned. |
|
||||
| `order_by` | string | no | Return issues ordered by `created_at`, `updated_at`, `priority`, `due_date`, `relative_position`, `label_priority`, `milestone_due`, `popularity`, `weight` fields. Default is `created_at` |
|
||||
|
@ -366,7 +366,7 @@ GET /projects/:id/issues?confidential=true
|
|||
| `author_id` | integer | no | Return issues created by the given user `id`. Mutually exclusive with `author_username`. Combine with `scope=all` or `scope=assigned_to_me`. _([Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/13004) in GitLab 9.5)_ |
|
||||
| `author_username` | string | no | Return issues created by the given `username`. Similar to `author_id` and mutually exclusive with `author_id`. |
|
||||
| `assignee_id` | integer | no | Return issues assigned to the given user `id`. Mutually exclusive with `assignee_username`. `None` returns unassigned issues. `Any` returns issues with an assignee. _([Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/13004) in GitLab 9.5)_ |
|
||||
| `assignee_username` | string array | no | Return issues assigned to the given `username`. Similar to `assignee_id` and mutually exclusive with `assignee_id`. In CE version `assignee_username` array should only contain a single value or an invalid parameter error will be returned otherwise. |
|
||||
| `assignee_username` | string array | no | Return issues assigned to the given `username`. Similar to `assignee_id` and mutually exclusive with `assignee_id`. In GitLab CE `assignee_username` array should only contain a single value or an invalid parameter error will be returned otherwise. |
|
||||
| `my_reaction_emoji` | string | no | Return issues reacted by the authenticated user by the given `emoji`. `None` returns issues not given a reaction. `Any` returns issues given at least one reaction. _([Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/14016) in GitLab 10.0)_ |
|
||||
| `weight` **(STARTER)** | integer | no | Return issues with the specified `weight`. `None` returns issues with no weight assigned. `Any` returns issues with a weight assigned. |
|
||||
| `order_by` | string | no | Return issues ordered by `created_at`, `updated_at`, `priority`, `due_date`, `relative_position`, `label_priority`, `milestone_due`, `popularity`, `weight` fields. Default is `created_at` |
|
||||
|
|
|
@ -34,7 +34,7 @@ GET /issues_statistics?confidential=true
|
|||
| `author_id` | integer | no | Return issues created by the given user `id`. Mutually exclusive with `author_username`. Combine with `scope=all` or `scope=assigned_to_me`. |
|
||||
| `author_username` | string | no | Return issues created by the given `username`. Similar to `author_id` and mutually exclusive with `author_id`. |
|
||||
| `assignee_id` | integer | no | Return issues assigned to the given user `id`. Mutually exclusive with `assignee_username`. `None` returns unassigned issues. `Any` returns issues with an assignee. |
|
||||
| `assignee_username` | string array | no | Return issues assigned to the given `username`. Similar to `assignee_id` and mutually exclusive with `assignee_id`. In CE version `assignee_username` array should only contain a single value or an invalid parameter error will be returned otherwise. |
|
||||
| `assignee_username` | string array | no | Return issues assigned to the given `username`. Similar to `assignee_id` and mutually exclusive with `assignee_id`. In GitLab CE `assignee_username` array should only contain a single value or an invalid parameter error will be returned otherwise. |
|
||||
| `my_reaction_emoji` | string | no | Return issues reacted by the authenticated user by the given `emoji`. `None` returns issues not given a reaction. `Any` returns issues given at least one reaction. |
|
||||
| `iids[]` | integer array | no | Return only the issues having the given `iid` |
|
||||
| `search` | string | no | Search issues against their `title` and `description` |
|
||||
|
@ -92,7 +92,7 @@ GET /groups/:id/issues_statistics?confidential=true
|
|||
| `author_id` | integer | no | Return issues created by the given user `id`. Mutually exclusive with `author_username`. Combine with `scope=all` or `scope=assigned_to_me`. |
|
||||
| `author_username` | string | no | Return issues created by the given `username`. Similar to `author_id` and mutually exclusive with `author_id`. |
|
||||
| `assignee_id` | integer | no | Return issues assigned to the given user `id`. Mutually exclusive with `assignee_username`. `None` returns unassigned issues. `Any` returns issues with an assignee. |
|
||||
| `assignee_username` | string array | no | Return issues assigned to the given `username`. Similar to `assignee_id` and mutually exclusive with `assignee_id`. In CE version `assignee_username` array should only contain a single value or an invalid parameter error will be returned otherwise. |
|
||||
| `assignee_username` | string array | no | Return issues assigned to the given `username`. Similar to `assignee_id` and mutually exclusive with `assignee_id`. In GitLab CE `assignee_username` array should only contain a single value or an invalid parameter error will be returned otherwise. |
|
||||
| `my_reaction_emoji` | string | no | Return issues reacted by the authenticated user by the given `emoji`. `None` returns issues not given a reaction. `Any` returns issues given at least one reaction. |
|
||||
| `search` | string | no | Search group issues against their `title` and `description` |
|
||||
| `created_after` | datetime | no | Return issues created on or after the given time |
|
||||
|
@ -148,7 +148,7 @@ GET /projects/:id/issues_statistics?confidential=true
|
|||
| `author_id` | integer | no | Return issues created by the given user `id`. Mutually exclusive with `author_username`. Combine with `scope=all` or `scope=assigned_to_me`. |
|
||||
| `author_username` | string | no | Return issues created by the given `username`. Similar to `author_id` and mutually exclusive with `author_id`. |
|
||||
| `assignee_id` | integer | no | Return issues assigned to the given user `id`. Mutually exclusive with `assignee_username`. `None` returns unassigned issues. `Any` returns issues with an assignee. |
|
||||
| `assignee_username` | string array | no | Return issues assigned to the given `username`. Similar to `assignee_id` and mutually exclusive with `assignee_id`. In CE version `assignee_username` array should only contain a single value or an invalid parameter error will be returned otherwise. |
|
||||
| `assignee_username` | string array | no | Return issues assigned to the given `username`. Similar to `assignee_id` and mutually exclusive with `assignee_id`. In GitLab CE `assignee_username` array should only contain a single value or an invalid parameter error will be returned otherwise. |
|
||||
| `my_reaction_emoji` | string | no | Return issues reacted by the authenticated user by the given `emoji`. `None` returns issues not given a reaction. `Any` returns issues given at least one reaction. |
|
||||
| `search` | string | no | Search project issues against their `title` and `description` |
|
||||
| `created_after` | datetime | no | Return issues created on or after the given time |
|
||||
|
|
|
@ -1,5 +1,12 @@
|
|||
# Pipelines API
|
||||
|
||||
## Pipelines pagination
|
||||
|
||||
By default, `GET` requests return 20 results at a time because the API results
|
||||
are paginated.
|
||||
|
||||
Read more on [pagination](README.md#pagination).
|
||||
|
||||
## List project pipelines
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/5837) in GitLab 8.11
|
||||
|
|
|
@ -98,6 +98,7 @@ Complementary reads:
|
|||
- [Rails initializers](rails_initializers.md)
|
||||
- [Code comments](code_comments.md)
|
||||
- [Renaming features](renaming_features.md)
|
||||
- [Windows Development on GCP](windows.md)
|
||||
|
||||
## Performance guides
|
||||
|
||||
|
|
|
@ -0,0 +1,139 @@
|
|||
---
|
||||
type: reference, howto
|
||||
---
|
||||
|
||||
# Windows Development
|
||||
|
||||
There are times in development where a Windows development machine is needed.
|
||||
This is a guide for how to get a Windows development virtual machine on Google Cloud Platform
|
||||
(GCP) with the same preinstalled tools as the GitLab shared Windows runners.
|
||||
|
||||
## Why Windows in Google Cloud?
|
||||
|
||||
Use of Microsoft Windows operating systems on company laptops is banned under GitLab's [Approved Operating Systems policy](https://about.gitlab.com/handbook/security/approved_os.html#windows).
|
||||
|
||||
This can make it difficult to develop features for the Windows platforms. Using GCP will allow us to have a temporary Windows machine that can be removed once we're done with it.
|
||||
|
||||
## Shared Windows runners
|
||||
|
||||
You can use the shared Windows runners in the case that you don't need a full Windows development machine.
|
||||
The [GitLab 12.7 Release Post](https://about.gitlab.com/releases/2020/01/22/gitlab-12-7-released/#windows-shared-runners-on-gitlabcom-beta)
|
||||
and [Windows shared runner beta blog post](https://about.gitlab.com/blog/2020/01/21/windows-shared-runner-beta/#getting-started) both
|
||||
outline quite a bit of useful information.
|
||||
|
||||
To use the shared Windows runners add the following `tags` to relevant jobs in your `.gitlab-ci.yml` file:
|
||||
|
||||
```yaml
|
||||
tags:
|
||||
- shared-windows
|
||||
- windows
|
||||
- windows-1809
|
||||
```
|
||||
|
||||
A list of software preinstalled on the Windows images is available at: [Preinstalled software](https://gitlab.com/gitlab-org/ci-cd/shared-runners/images/gcp/windows-containers/blob/master/cookbooks/preinstalled-software/README.md).
|
||||
|
||||
## GCP Windows image for development
|
||||
|
||||
The [shared Windows GitLab
|
||||
runners](https://about.gitlab.com/releases/2020/01/22/gitlab-12-7-released/#windows-shared-runners-on-gitlabcom-beta)
|
||||
are built with [Packer](https://www.packer.io/).
|
||||
|
||||
The Infrastructure as Code repository for building the Google Cloud images is available at:
|
||||
[GitLab Google Cloud Platform Shared Runner Images](https://gitlab.com/gitlab-org/ci-cd/shared-runners/images/gcp/windows-containers).
|
||||
|
||||
### Build image
|
||||
|
||||
There is a chance that your Google Cloud group may already have an image
|
||||
built. Search the available images before you do the work to build your
|
||||
own.
|
||||
|
||||
Build a Google Cloud image with the above shared runners repo by doing the following:
|
||||
|
||||
1. Install [Packer](https://www.packer.io/) (tested to work with version 1.5.1).
|
||||
1. Install Packer Windows Update Provisioner.
|
||||
1. Clone the repository <https://github.com/rgl/packer-provisioner-windows-update> and `cd` into the cloned directory.
|
||||
1. Run the command `go build -o packer-provisioner-windows-update` (requires `go` to be installed).
|
||||
1. Verify `packer-provisioner-windows-update` is in the `PATH` environment variable.
|
||||
1. Add all [required environment variables](https://gitlab.com/gitlab-org/ci-cd/shared-runners/images/gcp/windows-containers/-/blob/master/packer.json#L2-10)
|
||||
in the `packer.json` file to your environment (perhaps use [direnv](https://direnv.net/)).
|
||||
1. Build the image by running the command: `packer build packer.json`.
|
||||
|
||||
## How to use a Windows image in GCP
|
||||
|
||||
1. In a web browser, go to <https://console.cloud.google.com/compute/images>.
|
||||
1. Filter images by the name you used when creating image, `windows` is likely all you need to filter by.
|
||||
1. Click the image's name.
|
||||
1. Click the **CREATE INSTANCE** link.
|
||||
1. Important: Change name to what you'd like as you can't change it later.
|
||||
1. Optional: Change Region to be closest to you as well as any other option you'd like.
|
||||
1. Click **Create** at the bottom of the page.
|
||||
1. Click the name of your newly created VM Instance (optionally you can filter to find it).
|
||||
1. Click **Set Windows password**.
|
||||
1. Optional: Set a username or use default.
|
||||
1. Click **Next**.
|
||||
1. Copy and save the password as it won't be shown again.
|
||||
1. Click **RDP** down arrow.
|
||||
1. Click **Download the RDP file**.
|
||||
1. Open the downloaded RDP file with the Windows remote desktop app (<https://docs.microsoft.com/en-us/windows-server/remote/remote-desktop-services/clients/remote-desktop-clients>).
|
||||
1. Click **Continue** to accept the certificate.
|
||||
1. Enter the password and click **Next**.
|
||||
|
||||
You should now be remoted into a Windows machine with a command prompt.
|
||||
|
||||
### Optional: Use GCP VM Instance as a runner
|
||||
|
||||
- Register the runner with a project: `gitlab-runner.exe register`.
|
||||
- Install the runner:`gitlab-runner.exe install`.
|
||||
- Start the runner: `gitlab-runner.exe start`.
|
||||
|
||||
For more information, see [Install GitLab Runner on Windows](https://docs.gitlab.com/runner/install/windows.html)
|
||||
and [Registering Runners](https://docs.gitlab.com/runner/register/index.html).
|
||||
|
||||
## Developer tips
|
||||
|
||||
Here are a few tips on GCP and Windows.
|
||||
|
||||
### GCP cost savings
|
||||
|
||||
To minimise the cost of your GCP VM instance, stop it when you're not using it.
|
||||
If you do, you'll need to redownload the RDP file from the console as the IP
|
||||
address changes every time you stop and start it.
|
||||
|
||||
### chocolatey
|
||||
|
||||
Chocolatey is a package manager for Windows. You can search for packages on <https://chocolatey.org/>.
|
||||
|
||||
- `choco install vim`
|
||||
|
||||
### Visual Studio (install / usage for full GUI)
|
||||
|
||||
You can install Visual Studio and run it within the Windows Remote Desktop app.
|
||||
|
||||
Install it by running: `choco install visualstudio2019community`
|
||||
|
||||
Start it by running: `"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\devenv.exe" .`
|
||||
|
||||
### .NET 3 support
|
||||
|
||||
You can install .NET version 3 support with the following `DISM` command:
|
||||
|
||||
`DISM /Online /Enable-Feature /FeatureName:NetFx3 /All`
|
||||
|
||||
### nix -> Windows cmd tips
|
||||
|
||||
The first tip for using the Windows command shell is to open Powershell and use that instead.
|
||||
|
||||
Start Powershell: `start powershell`.
|
||||
|
||||
Powershell has aliases for all of the following commands so you don't have to learn the native commands:
|
||||
|
||||
- `ls` ---> `dir`
|
||||
- `rm` ---> `del`
|
||||
- `rm -rf nonemptydir` ---> `rmdir /S nonemptydir`
|
||||
- `/` ---> `\` (path separator)
|
||||
- `cat` ---> `type`
|
||||
- `mv` ---> `move`
|
||||
- Redirection works the same (i.e. `>` and `2>&1`)
|
||||
- `.\some.exe` to call a local executable
|
||||
- curl is available
|
||||
- `..` and `.` are available
|
|
@ -325,6 +325,7 @@ Some analyzers can be customized with environment variables.
|
|||
| `MAVEN_REPO_PATH` | SpotBugs | Path to the Maven local repository (shortcut for the `maven.repo.local` property). |
|
||||
| `SBT_PATH` | SpotBugs | Path to the `sbt` executable. |
|
||||
| `FAIL_NEVER` | SpotBugs | Set to `1` to ignore compilation failure. |
|
||||
| `SAST_GOSEC_CONFIG` | Gosec | Path to configuration for Gosec (optional). |
|
||||
|
||||
#### Custom environment variables
|
||||
|
||||
|
|
|
@ -14630,6 +14630,9 @@ msgstr ""
|
|||
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
|
||||
msgstr ""
|
||||
|
||||
msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
|
||||
msgstr ""
|
||||
|
||||
msgid "Number of %{itemTitle}"
|
||||
msgstr ""
|
||||
|
||||
|
|
1
qa/qa.rb
1
qa/qa.rb
|
@ -191,6 +191,7 @@ module QA
|
|||
autoload :New, 'qa/page/dashboard/snippet/new'
|
||||
autoload :Index, 'qa/page/dashboard/snippet/index'
|
||||
autoload :Show, 'qa/page/dashboard/snippet/show'
|
||||
autoload :Edit, 'qa/page/dashboard/snippet/edit'
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -122,6 +122,14 @@ module QA
|
|||
run("git merge #{branch}")
|
||||
end
|
||||
|
||||
def init_repository
|
||||
run("git init")
|
||||
end
|
||||
|
||||
def pull(repository = nil, branch = nil)
|
||||
run(['git', 'pull', repository, branch].compact.join(' '))
|
||||
end
|
||||
|
||||
def commits
|
||||
run('git log --oneline').to_s.split("\n")
|
||||
end
|
||||
|
@ -177,6 +185,10 @@ module QA
|
|||
save_netrc_content
|
||||
end
|
||||
|
||||
def file_content(file)
|
||||
run("cat #{file}").to_s
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :uri, :username, :password, :known_hosts_file,
|
||||
|
|
|
@ -133,8 +133,13 @@ module QA
|
|||
end
|
||||
|
||||
# replace with (..., page = self.class)
|
||||
def click_element(name, page = nil, text: nil, wait: Capybara.default_max_wait_time)
|
||||
find_element(name, text: text, wait: wait).click
|
||||
def click_element(name, page = nil, **kwargs)
|
||||
wait_for_requests
|
||||
|
||||
wait = kwargs.delete(:wait) || Capybara.default_max_wait_time
|
||||
text = kwargs.delete(:text)
|
||||
|
||||
find(element_selector_css(name, kwargs), text: text, wait: wait).click
|
||||
page.validate_elements_present! if page
|
||||
end
|
||||
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module QA
|
||||
module Page
|
||||
module Dashboard
|
||||
module Snippet
|
||||
class Edit < Page::Base
|
||||
view 'app/views/shared/snippets/_form.html.haml' do
|
||||
element :submit_button
|
||||
end
|
||||
|
||||
view 'app/assets/javascripts/snippets/components/edit.vue' do
|
||||
element :submit_button
|
||||
end
|
||||
|
||||
def add_to_file_content(content)
|
||||
finished_loading?
|
||||
text_area.set content
|
||||
text_area.has_text?(content) # wait for changes to take effect
|
||||
end
|
||||
|
||||
def save_changes
|
||||
click_element(:submit_button)
|
||||
wait_until { assert_no_element(:submit_button) }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def text_area
|
||||
find('#editor textarea', visible: false)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -6,7 +6,7 @@ module QA
|
|||
module Snippet
|
||||
class New < Page::Base
|
||||
view 'app/assets/javascripts/snippets/components/edit.vue' do
|
||||
element :create_snippet_button
|
||||
element :submit_button
|
||||
end
|
||||
|
||||
view 'app/assets/javascripts/snippets/components/snippet_description_edit.vue' do
|
||||
|
@ -31,7 +31,7 @@ module QA
|
|||
element :description_placeholder
|
||||
element :snippet_title
|
||||
element :snippet_file_name
|
||||
element :create_snippet_button
|
||||
element :submit_button
|
||||
end
|
||||
|
||||
view 'app/views/projects/_zen.html.haml' do
|
||||
|
@ -63,8 +63,8 @@ module QA
|
|||
end
|
||||
|
||||
def click_create_snippet_button
|
||||
wait_until(reload: false) { !find_element(:create_snippet_button).disabled? }
|
||||
click_element :create_snippet_button
|
||||
wait_until(reload: false) { !find_element(:submit_button).disabled? }
|
||||
click_element :submit_button
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -35,6 +35,20 @@ module QA
|
|||
element :file_content
|
||||
end
|
||||
|
||||
view 'app/assets/javascripts/snippets/components/snippet_header.vue' do
|
||||
element :snippet_action_button
|
||||
element :delete_snippet_button
|
||||
end
|
||||
|
||||
view 'app/assets/javascripts/snippets/components/snippet_blob_view.vue' do
|
||||
element :clone_button
|
||||
end
|
||||
|
||||
view 'app/assets/javascripts/vue_shared/components/clone_dropdown.vue' do
|
||||
element :copy_http_url_button
|
||||
element :copy_ssh_url_button
|
||||
end
|
||||
|
||||
def has_snippet_title?(snippet_title)
|
||||
has_element? :snippet_title, text: snippet_title
|
||||
end
|
||||
|
@ -61,6 +75,30 @@ module QA
|
|||
has_text?(file_content)
|
||||
end
|
||||
end
|
||||
|
||||
def click_edit_button
|
||||
finished_loading?
|
||||
click_element(:snippet_action_button, action: 'Edit')
|
||||
end
|
||||
|
||||
def click_delete_button
|
||||
finished_loading?
|
||||
click_element(:snippet_action_button, action: 'Delete')
|
||||
click_element(:delete_snippet_button)
|
||||
finished_loading? # wait for the page to reload after deletion
|
||||
end
|
||||
|
||||
def get_repository_uri_http
|
||||
finished_loading?
|
||||
click_element(:clone_button)
|
||||
Git::Location.new(find_element(:copy_http_url_button)['data-clipboard-text']).uri.to_s
|
||||
end
|
||||
|
||||
def get_repository_uri_ssh
|
||||
finished_loading?
|
||||
click_element(:clone_button)
|
||||
Git::Location.new(find_element(:copy_ssh_url_button)['data-clipboard-text']).uri.to_s
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module QA
|
||||
context 'Create' do
|
||||
describe 'Version control for personal snippets' do
|
||||
let(:new_file) { 'new_snippet_file' }
|
||||
let(:changed_content) { 'changes' }
|
||||
let(:commit_message) { 'Changes to snippets' }
|
||||
let(:added_content) { 'updated ' }
|
||||
let(:branch_name) { 'master' }
|
||||
|
||||
let(:snippet) do
|
||||
Resource::Snippet.fabricate! do |snippet|
|
||||
snippet.file_name = new_file
|
||||
end
|
||||
end
|
||||
|
||||
let(:ssh_key) do
|
||||
Resource::SSHKey.fabricate_via_api! do |resource|
|
||||
resource.title = "my key title #{Time.now.to_f}"
|
||||
end
|
||||
end
|
||||
|
||||
let(:repository_uri_http) do
|
||||
snippet
|
||||
Page::Dashboard::Snippet::Show.perform(&:get_repository_uri_http)
|
||||
end
|
||||
|
||||
let(:repository_uri_ssh) do
|
||||
ssh_key
|
||||
snippet
|
||||
Page::Dashboard::Snippet::Show.perform(&:get_repository_uri_ssh)
|
||||
end
|
||||
|
||||
before do
|
||||
Flow::Login.sign_in
|
||||
end
|
||||
|
||||
it 'clones, pushes, and pulls a snippet over HTTP, edits via UI' do
|
||||
Resource::Repository::Push.fabricate! do |push|
|
||||
push.repository_http_uri = repository_uri_http
|
||||
push.file_name = new_file
|
||||
push.file_content = changed_content
|
||||
push.commit_message = commit_message
|
||||
push.new_branch = false
|
||||
end
|
||||
|
||||
page.refresh
|
||||
verify_changes_in_ui
|
||||
|
||||
Page::Dashboard::Snippet::Show.perform(&:click_edit_button)
|
||||
|
||||
Page::Dashboard::Snippet::Edit.perform do |snippet|
|
||||
snippet.add_to_file_content(added_content)
|
||||
snippet.save_changes
|
||||
end
|
||||
|
||||
Git::Repository.perform do |repository|
|
||||
repository.init_repository
|
||||
repository.pull(repository_uri_http, branch_name)
|
||||
|
||||
expect(repository.commits.size).to eq(3)
|
||||
expect(repository.commits.first).to include('Update snippet')
|
||||
expect(repository.file_content(new_file)).to include("#{added_content}#{changed_content}")
|
||||
end
|
||||
end
|
||||
|
||||
it 'clones, pushes, and pulls a snippet over SSH, deletes via UI' do
|
||||
Resource::Repository::Push.fabricate! do |push|
|
||||
push.repository_ssh_uri = repository_uri_ssh
|
||||
push.ssh_key = ssh_key
|
||||
push.file_name = new_file
|
||||
push.file_content = changed_content
|
||||
push.commit_message = commit_message
|
||||
push.new_branch = false
|
||||
end
|
||||
|
||||
page.refresh
|
||||
verify_changes_in_ui
|
||||
|
||||
Page::Dashboard::Snippet::Show.perform(&:click_delete_button)
|
||||
|
||||
# attempt to pull a deleted snippet, get a missing repository error
|
||||
Git::Repository.perform do |repository|
|
||||
repository.uri = repository_uri_ssh
|
||||
repository.use_ssh_key(ssh_key)
|
||||
repository.init_repository
|
||||
|
||||
expect { repository.pull(repository_uri_ssh, branch_name) }
|
||||
.to raise_error(QA::Git::Repository::RepositoryCommandError, /[fatal: Could not read from remote repository.]+/)
|
||||
end
|
||||
end
|
||||
|
||||
def verify_changes_in_ui
|
||||
Page::Dashboard::Snippet::Show.perform do |snippet|
|
||||
expect(snippet).to have_file_name(new_file)
|
||||
expect(snippet).to have_file_content(changed_content)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -37,7 +37,6 @@ exports[`User Operation confirmation modal renders modal with form included 1`]
|
|||
value=""
|
||||
/>
|
||||
</form>
|
||||
|
||||
<gl-deprecated-button-stub
|
||||
size="md"
|
||||
variant="secondary"
|
||||
|
|
|
@ -41,6 +41,7 @@ exports[`Clone Dropdown Button rendering matches the snapshot 1`] = `
|
|||
category="tertiary"
|
||||
class="d-inline-flex"
|
||||
data-clipboard-text="ssh://foo.bar"
|
||||
data-qa-selector="copy_ssh_url_button"
|
||||
icon="copy-to-clipboard"
|
||||
size="medium"
|
||||
title="Copy URL"
|
||||
|
@ -81,6 +82,7 @@ exports[`Clone Dropdown Button rendering matches the snapshot 1`] = `
|
|||
category="tertiary"
|
||||
class="d-inline-flex"
|
||||
data-clipboard-text="http://foo.bar"
|
||||
data-qa-selector="copy_http_url_button"
|
||||
icon="copy-to-clipboard"
|
||||
size="medium"
|
||||
title="Copy URL"
|
||||
|
|
|
@ -35,11 +35,11 @@ describe Auth::ContainerRegistryAuthenticationService do
|
|||
it { expect(payload).to include('access') }
|
||||
|
||||
context 'a expirable' do
|
||||
let(:expires_at) { Time.at(payload['exp']) }
|
||||
let(:expires_at) { Time.zone.at(payload['exp']) }
|
||||
let(:expire_delay) { 10 }
|
||||
|
||||
context 'for default configuration' do
|
||||
it { expect(expires_at).not_to be_within(2.seconds).of(Time.now + expire_delay.minutes) }
|
||||
it { expect(expires_at).not_to be_within(2.seconds).of(Time.current + expire_delay.minutes) }
|
||||
end
|
||||
|
||||
context 'for changed configuration' do
|
||||
|
@ -47,7 +47,7 @@ describe Auth::ContainerRegistryAuthenticationService do
|
|||
stub_application_setting(container_registry_token_expire_delay: expire_delay)
|
||||
end
|
||||
|
||||
it { expect(expires_at).to be_within(2.seconds).of(Time.now + expire_delay.minutes) }
|
||||
it { expect(expires_at).to be_within(2.seconds).of(Time.current + expire_delay.minutes) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -87,7 +87,7 @@ describe Boards::Issues::ListService do
|
|||
let!(:opened_issue1) { create(:labeled_issue, project: project, milestone: m1, title: 'Issue 1', labels: [bug]) }
|
||||
let!(:opened_issue2) { create(:labeled_issue, project: project, milestone: m2, title: 'Issue 2', labels: [p2, p2_project]) }
|
||||
let!(:opened_issue3) { create(:labeled_issue, project: project_archived, milestone: m1, title: 'Issue 3', labels: [bug]) }
|
||||
let!(:reopened_issue1) { create(:issue, state: 'opened', project: project, title: 'Reopened Issue 1', closed_at: Time.now ) }
|
||||
let!(:reopened_issue1) { create(:issue, state: 'opened', project: project, title: 'Reopened Issue 1', closed_at: Time.current ) }
|
||||
|
||||
let!(:list1_issue1) { create(:labeled_issue, project: project, milestone: m1, labels: [p2, p2_project, development]) }
|
||||
let!(:list1_issue2) { create(:labeled_issue, project: project, milestone: m2, labels: [development]) }
|
||||
|
|
|
@ -571,7 +571,7 @@ module Ci
|
|||
end
|
||||
|
||||
describe '#register_success' do
|
||||
let!(:current_time) { Time.new(2018, 4, 5, 14, 0, 0) }
|
||||
let!(:current_time) { Time.zone.local(2018, 4, 5, 14, 0, 0) }
|
||||
let!(:attempt_counter) { double('Gitlab::Metrics::NullMetric') }
|
||||
let!(:job_queue_duration_seconds) { double('Gitlab::Metrics::NullMetric') }
|
||||
|
||||
|
|
|
@ -13,10 +13,10 @@ describe Clusters::Applications::ScheduleUpdateService do
|
|||
context 'when application is able to be updated' do
|
||||
context 'when the application was recently scheduled' do
|
||||
it 'schedules worker with a backoff delay' do
|
||||
application = create(:clusters_applications_prometheus, :installed, last_update_started_at: Time.now + 5.minutes)
|
||||
application = create(:clusters_applications_prometheus, :installed, last_update_started_at: Time.current + 5.minutes)
|
||||
service = described_class.new(application, project)
|
||||
|
||||
expect(::ClusterUpdateAppWorker).to receive(:perform_in).with(described_class::BACKOFF_DELAY, application.name, application.id, project.id, Time.now).once
|
||||
expect(::ClusterUpdateAppWorker).to receive(:perform_in).with(described_class::BACKOFF_DELAY, application.name, application.id, project.id, Time.current).once
|
||||
|
||||
service.execute
|
||||
end
|
||||
|
@ -27,7 +27,7 @@ describe Clusters::Applications::ScheduleUpdateService do
|
|||
application = create(:clusters_applications_prometheus, :installed)
|
||||
service = described_class.new(application, project)
|
||||
|
||||
expect(::ClusterUpdateAppWorker).to receive(:perform_async).with(application.name, application.id, project.id, Time.now).once
|
||||
expect(::ClusterUpdateAppWorker).to receive(:perform_async).with(application.name, application.id, project.id, Time.current).once
|
||||
|
||||
service.execute
|
||||
end
|
||||
|
|
|
@ -120,8 +120,8 @@ describe Clusters::Kubernetes::ConfigureIstioIngressService, '#execute' do
|
|||
|
||||
expect(certificate.subject.to_s).to include(serverless_domain_cluster.knative.hostname)
|
||||
|
||||
expect(certificate.not_before).to be_within(1.minute).of(Time.now)
|
||||
expect(certificate.not_after).to be_within(1.minute).of(Time.now + 1000.years)
|
||||
expect(certificate.not_before).to be_within(1.minute).of(Time.current)
|
||||
expect(certificate.not_after).to be_within(1.minute).of(Time.current + 1000.years)
|
||||
|
||||
expect(WebMock).to have_requested(:put, api_url + '/api/v1/namespaces/istio-system/secrets/istio-ingressgateway-ca-certs').with(
|
||||
body: hash_including(
|
||||
|
|
|
@ -13,7 +13,7 @@ describe CohortsService do
|
|||
6.times do |months_ago|
|
||||
months_ago_time = (months_ago * 2).months.ago
|
||||
|
||||
create(:user, created_at: months_ago_time, last_activity_on: Time.now)
|
||||
create(:user, created_at: months_ago_time, last_activity_on: Time.current)
|
||||
create(:user, created_at: months_ago_time, last_activity_on: months_ago_time)
|
||||
end
|
||||
|
||||
|
|
|
@ -315,7 +315,7 @@ describe Git::BranchPushService, services: true do
|
|||
let(:issue) { create :issue, project: project }
|
||||
let(:commit_author) { create :user }
|
||||
let(:commit) { project.commit }
|
||||
let(:commit_time) { Time.now }
|
||||
let(:commit_time) { Time.current }
|
||||
|
||||
before do
|
||||
project.add_developer(commit_author)
|
||||
|
|
|
@ -6,7 +6,7 @@ describe IncidentManagement::CreateIssueService do
|
|||
let(:project) { create(:project, :repository, :private) }
|
||||
let_it_be(:user) { User.alert_bot }
|
||||
let(:service) { described_class.new(project, alert_payload) }
|
||||
let(:alert_starts_at) { Time.now }
|
||||
let(:alert_starts_at) { Time.current }
|
||||
let(:alert_title) { 'TITLE' }
|
||||
let(:alert_annotations) { { title: alert_title } }
|
||||
|
||||
|
@ -302,7 +302,7 @@ describe IncidentManagement::CreateIssueService do
|
|||
|
||||
private
|
||||
|
||||
def build_alert_payload(annotations: {}, starts_at: Time.now)
|
||||
def build_alert_payload(annotations: {}, starts_at: Time.current)
|
||||
{
|
||||
'annotations' => annotations.stringify_keys
|
||||
}.tap do |payload|
|
||||
|
|
|
@ -146,7 +146,7 @@ describe Issues::CloseService do
|
|||
|
||||
context 'when `metrics.first_mentioned_in_commit_at` is already set' do
|
||||
before do
|
||||
issue.metrics.update!(first_mentioned_in_commit_at: Time.now)
|
||||
issue.metrics.update!(first_mentioned_in_commit_at: Time.current)
|
||||
end
|
||||
|
||||
it 'does not update the metrics' do
|
||||
|
|
|
@ -510,7 +510,7 @@ describe Issues::UpdateService, :mailer do
|
|||
end
|
||||
|
||||
it 'updates updated_at' do
|
||||
expect(issue.reload.updated_at).to be > Time.now
|
||||
expect(issue.reload.updated_at).to be > Time.current
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -118,7 +118,7 @@ describe MergeRequests::MergeService do
|
|||
|
||||
it 'closes GitLab issue tracker issues' do
|
||||
issue = create :issue, project: project
|
||||
commit = instance_double('commit', safe_message: "Fixes #{issue.to_reference}", date: Time.now, authored_date: Time.now)
|
||||
commit = instance_double('commit', safe_message: "Fixes #{issue.to_reference}", date: Time.current, authored_date: Time.current)
|
||||
allow(merge_request).to receive(:commits).and_return([commit])
|
||||
merge_request.cache_merge_request_closes_issues!
|
||||
|
||||
|
|
|
@ -635,7 +635,7 @@ describe MergeRequests::RefreshService do
|
|||
references: [issue],
|
||||
author_name: commit_author.name,
|
||||
author_email: commit_author.email,
|
||||
committed_date: Time.now
|
||||
committed_date: Time.current
|
||||
)
|
||||
|
||||
allow_any_instance_of(MergeRequest).to receive(:commits).and_return(CommitCollection.new(@project, [commit], 'feature'))
|
||||
|
|
|
@ -453,7 +453,7 @@ describe MergeRequests::UpdateService, :mailer do
|
|||
end
|
||||
|
||||
it 'updates updated_at' do
|
||||
expect(merge_request.reload.updated_at).to be > Time.now
|
||||
expect(merge_request.reload.updated_at).to be > Time.current
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -25,18 +25,18 @@ describe NoteSummary do
|
|||
it 'returns note hash' do
|
||||
Timecop.freeze do
|
||||
expect(create_note_summary.note).to eq(noteable: noteable, project: project, author: user, note: 'note',
|
||||
created_at: Time.now)
|
||||
created_at: Time.current)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when noteable is a commit' do
|
||||
let(:noteable) { build(:commit, system_note_timestamp: Time.at(43)) }
|
||||
let(:noteable) { build(:commit, system_note_timestamp: Time.zone.at(43)) }
|
||||
|
||||
it 'returns note hash specific to commit' do
|
||||
expect(create_note_summary.note).to eq(
|
||||
noteable: nil, project: project, author: user, note: 'note',
|
||||
noteable_type: 'Commit', commit_id: noteable.id,
|
||||
created_at: Time.at(43)
|
||||
created_at: Time.zone.at(43)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -425,7 +425,7 @@ describe Notes::CreateService do
|
|||
expect do
|
||||
existing_note
|
||||
|
||||
Timecop.freeze(Time.now + 1.minute) { subject }
|
||||
Timecop.freeze(Time.current + 1.minute) { subject }
|
||||
|
||||
existing_note.reload
|
||||
end.to change { existing_note.type }.from(nil).to('DiscussionNote')
|
||||
|
|
|
@ -119,7 +119,7 @@ describe PagesDomains::ObtainLetsEncryptCertificateService do
|
|||
|
||||
cert = OpenSSL::X509::Certificate.new
|
||||
cert.subject = cert.issuer = OpenSSL::X509::Name.parse(subject)
|
||||
cert.not_before = Time.now
|
||||
cert.not_before = Time.current
|
||||
cert.not_after = 1.year.from_now
|
||||
cert.public_key = key.public_key
|
||||
cert.serial = 0x0
|
||||
|
|
|
@ -72,7 +72,7 @@ describe Projects::Alerting::NotifyService do
|
|||
|
||||
describe '#execute' do
|
||||
let(:token) { 'invalid-token' }
|
||||
let(:starts_at) { Time.now.change(usec: 0) }
|
||||
let(:starts_at) { Time.current.change(usec: 0) }
|
||||
let(:service) { described_class.new(project, nil, payload) }
|
||||
let(:payload_raw) do
|
||||
{
|
||||
|
@ -121,7 +121,7 @@ describe Projects::Alerting::NotifyService do
|
|||
expect(last_alert_attributes).to match(
|
||||
project_id: project.id,
|
||||
title: payload_raw.fetch(:title),
|
||||
started_at: Time.parse(payload_raw.fetch(:start_time)),
|
||||
started_at: Time.zone.parse(payload_raw.fetch(:start_time)),
|
||||
severity: payload_raw.fetch(:severity),
|
||||
status: AlertManagement::Alert::STATUSES[:triggered],
|
||||
events: 1,
|
||||
|
@ -154,7 +154,7 @@ describe Projects::Alerting::NotifyService do
|
|||
expect(last_alert_attributes).to match(
|
||||
project_id: project.id,
|
||||
title: payload_raw.fetch(:title),
|
||||
started_at: Time.parse(payload_raw.fetch(:start_time)),
|
||||
started_at: Time.zone.parse(payload_raw.fetch(:start_time)),
|
||||
severity: 'critical',
|
||||
status: AlertManagement::Alert::STATUSES[:triggered],
|
||||
events: 1,
|
||||
|
|
|
@ -31,7 +31,7 @@ describe Projects::HashedStorage::BaseAttachmentService do
|
|||
expect(Dir.exist?(target_path)).to be_truthy
|
||||
|
||||
Timecop.freeze do
|
||||
suffix = Time.now.utc.to_i
|
||||
suffix = Time.current.utc.to_i
|
||||
subject.send(:discard_path!, target_path)
|
||||
|
||||
expected_renamed_path = "#{target_path}-#{suffix}"
|
||||
|
|
|
@ -50,7 +50,7 @@ describe Projects::Prometheus::Alerts::CreateEventsService do
|
|||
let(:events) { service.execute }
|
||||
|
||||
context 'with a firing payload' do
|
||||
let(:started_at) { truncate_to_second(Time.now) }
|
||||
let(:started_at) { truncate_to_second(Time.current) }
|
||||
let(:firing_event) { alert_payload(status: 'firing', started_at: started_at) }
|
||||
let(:alerts_payload) { { 'alerts' => [firing_event] } }
|
||||
|
||||
|
@ -87,7 +87,7 @@ describe Projects::Prometheus::Alerts::CreateEventsService do
|
|||
end
|
||||
|
||||
context 'with a resolved payload' do
|
||||
let(:started_at) { truncate_to_second(Time.now) }
|
||||
let(:started_at) { truncate_to_second(Time.current) }
|
||||
let(:ended_at) { started_at + 1 }
|
||||
let(:payload_key) { PrometheusAlertEvent.payload_key_for(alert.prometheus_metric_id, utc_rfc3339(started_at)) }
|
||||
let(:resolved_event) { alert_payload(status: 'resolved', started_at: started_at, ended_at: ended_at) }
|
||||
|
@ -285,7 +285,7 @@ describe Projects::Prometheus::Alerts::CreateEventsService do
|
|||
|
||||
private
|
||||
|
||||
def alert_payload(status: 'firing', started_at: Time.now, ended_at: Time.now, gitlab_alert_id: alert.prometheus_metric_id, title: nil, environment: nil)
|
||||
def alert_payload(status: 'firing', started_at: Time.current, ended_at: Time.current, gitlab_alert_id: alert.prometheus_metric_id, title: nil, environment: nil)
|
||||
payload = {}
|
||||
|
||||
payload['status'] = status if status
|
||||
|
|
|
@ -8,7 +8,7 @@ describe Projects::UpdateRepositoryStorageService do
|
|||
subject { described_class.new(repository_storage_move) }
|
||||
|
||||
describe "#execute" do
|
||||
let(:time) { Time.now }
|
||||
let(:time) { Time.current }
|
||||
|
||||
before do
|
||||
allow(Time).to receive(:now).and_return(time)
|
||||
|
|
|
@ -361,7 +361,7 @@ describe QuickActions::InterpretService do
|
|||
expect(updates).to eq(spend_time: {
|
||||
duration: 3600,
|
||||
user_id: developer.id,
|
||||
spent_at: DateTime.now.to_date
|
||||
spent_at: DateTime.current.to_date
|
||||
})
|
||||
end
|
||||
|
||||
|
@ -379,7 +379,7 @@ describe QuickActions::InterpretService do
|
|||
expect(updates).to eq(spend_time: {
|
||||
duration: -1800,
|
||||
user_id: developer.id,
|
||||
spent_at: DateTime.now.to_date
|
||||
spent_at: DateTime.current.to_date
|
||||
})
|
||||
end
|
||||
end
|
||||
|
|
|
@ -110,6 +110,8 @@ describe RepositoryArchiveCleanUpService do
|
|||
|
||||
def create_temporary_files(dir, extensions, mtime)
|
||||
FileUtils.mkdir_p(dir)
|
||||
# rubocop: disable Rails/TimeZone
|
||||
FileUtils.touch(extensions.map { |ext| File.join(dir, "sample.#{ext}") }, mtime: Time.now - mtime)
|
||||
# rubocop: enable Rails/TimeZone
|
||||
end
|
||||
end
|
||||
|
|
|
@ -21,7 +21,7 @@ describe ResourceEvents::MergeIntoNotesService do
|
|||
let_it_be(:resource) { create(:issue, project: project) }
|
||||
let_it_be(:label) { create(:label, project: project) }
|
||||
let_it_be(:label2) { create(:label, project: project) }
|
||||
let(:time) { Time.now }
|
||||
let(:time) { Time.current }
|
||||
|
||||
describe '#execute' do
|
||||
it 'merges label events into notes in order of created_at' do
|
||||
|
|
|
@ -9,7 +9,7 @@ describe MergeRequestMetricsService do
|
|||
it 'updates metrics' do
|
||||
user = create(:user)
|
||||
service = described_class.new(metrics)
|
||||
event = double(Event, author_id: user.id, created_at: Time.now)
|
||||
event = double(Event, author_id: user.id, created_at: Time.current)
|
||||
|
||||
service.merge(event)
|
||||
|
||||
|
@ -22,7 +22,7 @@ describe MergeRequestMetricsService do
|
|||
it 'updates metrics' do
|
||||
user = create(:user)
|
||||
service = described_class.new(metrics)
|
||||
event = double(Event, author_id: user.id, created_at: Time.now)
|
||||
event = double(Event, author_id: user.id, created_at: Time.current)
|
||||
|
||||
service.close(event)
|
||||
|
||||
|
|
|
@ -348,7 +348,7 @@ describe VerifyPagesDomainService do
|
|||
end
|
||||
|
||||
it 'does not shorten any grace period' do
|
||||
grace = Time.now + 1.year
|
||||
grace = Time.current + 1.year
|
||||
domain.update!(enabled_until: grace)
|
||||
disallow_resolver!
|
||||
|
||||
|
|
Loading…
Reference in New Issue