Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
f2151c65d5
commit
d84f18d66c
|
@ -45,22 +45,24 @@ export default {
|
|||
:markdown-docs-path="markdownDocsPath"
|
||||
:can-attach-file="canAttachFile"
|
||||
:enable-autocomplete="enableAutocomplete"
|
||||
:textarea-value="formState.description"
|
||||
>
|
||||
<textarea
|
||||
id="issue-description"
|
||||
ref="textarea"
|
||||
slot="textarea"
|
||||
v-model="formState.description"
|
||||
class="note-textarea js-gfm-input js-autosize markdown-area
|
||||
qa-description-textarea"
|
||||
dir="auto"
|
||||
data-supports-quick-actions="false"
|
||||
:aria-label="__('Description')"
|
||||
:placeholder="__('Write a comment or drag your files here…')"
|
||||
@keydown.meta.enter="updateIssuable"
|
||||
@keydown.ctrl.enter="updateIssuable"
|
||||
>
|
||||
</textarea>
|
||||
<template #textarea>
|
||||
<textarea
|
||||
id="issue-description"
|
||||
ref="textarea"
|
||||
v-model="formState.description"
|
||||
class="note-textarea js-gfm-input js-autosize markdown-area
|
||||
qa-description-textarea"
|
||||
dir="auto"
|
||||
data-supports-quick-actions="false"
|
||||
:aria-label="__('Description')"
|
||||
:placeholder="__('Write a comment or drag your files here…')"
|
||||
@keydown.meta.enter="updateIssuable"
|
||||
@keydown.ctrl.enter="updateIssuable"
|
||||
>
|
||||
</textarea>
|
||||
</template>
|
||||
</markdown-field>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -14,13 +14,7 @@ import axios from '~/lib/utils/axios_utils';
|
|||
|
||||
Vue.use(Translate);
|
||||
|
||||
export default () => {
|
||||
const { dataset } = document.querySelector('.js-pipeline-details-vue');
|
||||
|
||||
const mediator = new PipelinesMediator({ endpoint: dataset.endpoint });
|
||||
|
||||
mediator.fetchPipeline();
|
||||
|
||||
const createPipelinesDetailApp = mediator => {
|
||||
// eslint-disable-next-line no-new
|
||||
new Vue({
|
||||
el: '#js-pipeline-graph-vue',
|
||||
|
@ -50,7 +44,9 @@ export default () => {
|
|||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const createPipelineHeaderApp = mediator => {
|
||||
// eslint-disable-next-line no-new
|
||||
new Vue({
|
||||
el: '#js-pipeline-header-vue',
|
||||
|
@ -94,7 +90,9 @@ export default () => {
|
|||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const createPipelinesTabs = dataset => {
|
||||
const tabsElement = document.querySelector('.pipelines-tabs');
|
||||
const testReportsEnabled =
|
||||
window.gon && window.gon.features && window.gon.features.junitPipelineView;
|
||||
|
@ -119,27 +117,40 @@ export default () => {
|
|||
|
||||
tabsElement.addEventListener('click', tabClickHandler);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-new
|
||||
new Vue({
|
||||
el: '#js-pipeline-tests-detail',
|
||||
components: {
|
||||
TestReports,
|
||||
},
|
||||
render(createElement) {
|
||||
return createElement('test-reports');
|
||||
},
|
||||
});
|
||||
|
||||
axios
|
||||
.get(dataset.testReportsCountEndpoint)
|
||||
.then(({ data }) => {
|
||||
if (!data.total_count) {
|
||||
return;
|
||||
}
|
||||
|
||||
document.querySelector('.js-test-report-badge-counter').innerHTML = data.total_count;
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
};
|
||||
|
||||
const createTestDetails = detailsEndpoint => {
|
||||
// eslint-disable-next-line no-new
|
||||
new Vue({
|
||||
el: '#js-pipeline-tests-detail',
|
||||
components: {
|
||||
TestReports,
|
||||
},
|
||||
render(createElement) {
|
||||
return createElement('test-reports');
|
||||
},
|
||||
});
|
||||
|
||||
axios
|
||||
.get(detailsEndpoint)
|
||||
.then(({ data }) => {
|
||||
if (!data.total_count) {
|
||||
return;
|
||||
}
|
||||
|
||||
document.querySelector('.js-test-report-badge-counter').innerHTML = data.total_count;
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
|
||||
export default () => {
|
||||
const { dataset } = document.querySelector('.js-pipeline-details-vue');
|
||||
const mediator = new PipelinesMediator({ endpoint: dataset.endpoint });
|
||||
mediator.fetchPipeline();
|
||||
|
||||
createPipelinesDetailApp(mediator);
|
||||
createPipelineHeaderApp(mediator);
|
||||
createPipelinesTabs(dataset);
|
||||
createTestDetails(dataset.testReportsCountEndpoint);
|
||||
};
|
||||
|
|
|
@ -56,7 +56,7 @@
|
|||
min-height: 68px;
|
||||
|
||||
&:last-child {
|
||||
background-color: $gray-normal;
|
||||
background-color: $gray-10;
|
||||
|
||||
&::before {
|
||||
content: none !important;
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Admin::Ci::VariablesController < Admin::ApplicationController
|
||||
def show
|
||||
respond_to do |format|
|
||||
format.json { render_instance_variables }
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
service = Ci::UpdateInstanceVariablesService.new(variables_params)
|
||||
|
||||
if service.execute
|
||||
respond_to do |format|
|
||||
format.json { render_instance_variables }
|
||||
end
|
||||
else
|
||||
respond_to do |format|
|
||||
format.json { render_error(service.errors) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def variables
|
||||
@variables ||= Ci::InstanceVariable.all
|
||||
end
|
||||
|
||||
def render_instance_variables
|
||||
render status: :ok,
|
||||
json: {
|
||||
variables: Ci::InstanceVariableSerializer.new.represent(variables)
|
||||
}
|
||||
end
|
||||
|
||||
def render_error(errors)
|
||||
render status: :bad_request, json: errors
|
||||
end
|
||||
|
||||
def variables_params
|
||||
params.permit(variables_attributes: [*variable_params_attributes])
|
||||
end
|
||||
|
||||
def variable_params_attributes
|
||||
%i[id variable_type key secret_value protected masked _destroy]
|
||||
end
|
||||
end
|
|
@ -34,8 +34,6 @@ class Release < ApplicationRecord
|
|||
|
||||
delegate :repository, to: :project
|
||||
|
||||
after_commit :notify_new_release, on: :create, unless: :importing?
|
||||
|
||||
MAX_NUMBER_TO_DISPLAY = 3
|
||||
|
||||
def to_param
|
||||
|
@ -92,10 +90,6 @@ class Release < ApplicationRecord
|
|||
repository.find_tag(tag)
|
||||
end
|
||||
end
|
||||
|
||||
def notify_new_release
|
||||
NewReleaseWorker.perform_async(id)
|
||||
end
|
||||
end
|
||||
|
||||
Release.prepend_if_ee('EE::Release')
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Ci
|
||||
class BasicVariableEntity < Grape::Entity
|
||||
expose :id
|
||||
expose :key
|
||||
expose :value
|
||||
expose :variable_type
|
||||
|
||||
expose :protected?, as: :protected
|
||||
expose :masked?, as: :masked
|
||||
end
|
||||
end
|
|
@ -0,0 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Ci
|
||||
class InstanceVariableSerializer < BaseSerializer
|
||||
entity BasicVariableEntity
|
||||
end
|
||||
end
|
|
@ -1,11 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class GroupVariableEntity < Grape::Entity
|
||||
expose :id
|
||||
expose :key
|
||||
expose :value
|
||||
expose :variable_type
|
||||
|
||||
expose :protected?, as: :protected
|
||||
expose :masked?, as: :masked
|
||||
class GroupVariableEntity < Ci::BasicVariableEntity
|
||||
end
|
||||
|
|
|
@ -1,12 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class VariableEntity < Grape::Entity
|
||||
expose :id
|
||||
expose :key
|
||||
expose :value
|
||||
expose :variable_type
|
||||
|
||||
expose :protected?, as: :protected
|
||||
expose :masked?, as: :masked
|
||||
class VariableEntity < Ci::BasicVariableEntity
|
||||
expose :environment_scope
|
||||
end
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# This class is a simplified version of assign_nested_attributes_for_collection_association from ActiveRecord
|
||||
# https://github.com/rails/rails/blob/v6.0.2.1/activerecord/lib/active_record/nested_attributes.rb#L466
|
||||
|
||||
module Ci
|
||||
class UpdateInstanceVariablesService
|
||||
UNASSIGNABLE_KEYS = %w(id _destroy).freeze
|
||||
|
||||
def initialize(params)
|
||||
@params = params[:variables_attributes]
|
||||
end
|
||||
|
||||
def execute
|
||||
instantiate_records
|
||||
persist_records
|
||||
end
|
||||
|
||||
def errors
|
||||
@records.to_a.flat_map { |r| r.errors.full_messages }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :params
|
||||
|
||||
def existing_records_by_id
|
||||
@existing_records_by_id ||= Ci::InstanceVariable
|
||||
.all
|
||||
.index_by { |var| var.id.to_s }
|
||||
end
|
||||
|
||||
def instantiate_records
|
||||
@records = params.map do |attributes|
|
||||
find_or_initialize_record(attributes).tap do |record|
|
||||
record.assign_attributes(attributes.except(*UNASSIGNABLE_KEYS))
|
||||
record.mark_for_destruction if has_destroy_flag?(attributes)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def find_or_initialize_record(attributes)
|
||||
id = attributes[:id].to_s
|
||||
|
||||
if id.blank?
|
||||
Ci::InstanceVariable.new
|
||||
else
|
||||
existing_records_by_id.fetch(id) { raise ActiveRecord::RecordNotFound }
|
||||
end
|
||||
end
|
||||
|
||||
def persist_records
|
||||
Ci::InstanceVariable.transaction do
|
||||
success = @records.map do |record|
|
||||
if record.marked_for_destruction?
|
||||
record.destroy
|
||||
else
|
||||
record.save
|
||||
end
|
||||
end.all?
|
||||
|
||||
raise ActiveRecord::Rollback unless success
|
||||
|
||||
success
|
||||
end
|
||||
end
|
||||
|
||||
def has_destroy_flag?(hash)
|
||||
Gitlab::Utils.to_boolean(hash['_destroy'])
|
||||
end
|
||||
end
|
||||
end
|
|
@ -47,11 +47,17 @@ module Releases
|
|||
|
||||
release.save!
|
||||
|
||||
notify_create_release(release)
|
||||
|
||||
success(tag: tag, release: release)
|
||||
rescue => e
|
||||
error(e.message, 400)
|
||||
end
|
||||
|
||||
def notify_create_release(release)
|
||||
NotificationService.new.async.send_new_release_notifications(release)
|
||||
end
|
||||
|
||||
def build_release(tag)
|
||||
project.releases.build(
|
||||
name: name,
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# TODO: Worker can be removed in 13.2:
|
||||
# https://gitlab.com/gitlab-org/gitlab/-/issues/218231
|
||||
class NewReleaseWorker # rubocop:disable Scalability/IdempotentWorker
|
||||
include ApplicationWorker
|
||||
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Add admin controller actions for interacting with instance variables
|
||||
merge_request: 30385
|
||||
author:
|
||||
type: added
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Update alert management table background colour to correct gray
|
||||
merge_request: 32068
|
||||
author:
|
||||
type: other
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Move release notification from model callbacks to service
|
||||
merge_request: 29853
|
||||
author: Ravishankar
|
||||
type: performance
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Update deprecated slot syntax in ./app/assets/javascripts/issue_show/components/fields/description.vue
|
||||
merge_request: 31979
|
||||
author: Gilang Gumilar
|
||||
type: other
|
|
@ -154,6 +154,10 @@ namespace :admin do
|
|||
end
|
||||
end
|
||||
|
||||
namespace :ci do
|
||||
resource :variables, only: [:show, :update]
|
||||
end
|
||||
|
||||
concerns :clusterable
|
||||
|
||||
get '/dashboard/stats', to: 'dashboard#stats'
|
||||
|
|
|
@ -499,7 +499,7 @@ to start again from scratch, there are a few steps that can help you:
|
|||
|
||||
1. Refresh Foreign Data Wrapper tables
|
||||
|
||||
```sh
|
||||
```shell
|
||||
gitlab-rake geo:db:refresh_foreign_tables
|
||||
```
|
||||
|
||||
|
|
|
@ -226,6 +226,9 @@ incoming_email:
|
|||
|
||||
Example configuration for Gmail/G Suite. Assumes mailbox `gitlab-incoming@gmail.com`.
|
||||
|
||||
NOTE: **Note:**
|
||||
`incoming_email_email` cannot be a Gmail alias account.
|
||||
|
||||
Example for Omnibus installs:
|
||||
|
||||
```ruby
|
||||
|
|
|
@ -716,7 +716,7 @@ built-in command:
|
|||
|
||||
If you did not change the default location of the configuration file, run:
|
||||
|
||||
```sh
|
||||
```shell
|
||||
sudo gitlab-ctl registry-garbage-collect
|
||||
```
|
||||
|
||||
|
@ -725,7 +725,7 @@ layers you have stored.
|
|||
|
||||
If you changed the location of the Container Registry `config.yml`:
|
||||
|
||||
```sh
|
||||
```shell
|
||||
sudo gitlab-ctl registry-garbage-collect /path/to/config.yml
|
||||
```
|
||||
|
||||
|
@ -749,7 +749,7 @@ referenced by the registry tag. The `registry-garbage-collect` command supports
|
|||
`-m` switch to allow you to remove all unreferenced manifests and layers that are
|
||||
not directly accessible via `tag`:
|
||||
|
||||
```sh
|
||||
```shell
|
||||
sudo gitlab-ctl registry-garbage-collect -m
|
||||
```
|
||||
|
||||
|
@ -787,7 +787,7 @@ To enable the read-only mode:
|
|||
|
||||
1. Save and reconfigure GitLab:
|
||||
|
||||
```sh
|
||||
```shell
|
||||
sudo gitlab-ctl reconfigure
|
||||
```
|
||||
|
||||
|
@ -795,7 +795,7 @@ To enable the read-only mode:
|
|||
|
||||
1. Next, trigger one of the garbage collect commands:
|
||||
|
||||
```sh
|
||||
```shell
|
||||
# Recycling unused tags
|
||||
sudo /opt/gitlab/embedded/bin/registry garbage-collect /var/opt/gitlab/registry/config.yml
|
||||
|
||||
|
@ -822,7 +822,7 @@ To enable the read-only mode:
|
|||
|
||||
1. Save and reconfigure GitLab:
|
||||
|
||||
```sh
|
||||
```shell
|
||||
sudo gitlab-ctl reconfigure
|
||||
```
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ other CDNs or Function as a Service (FaaS) systems should work using the same pr
|
|||
`pwgen -cn1 64` on a UNIX machine). Save this token for the admin panel, as
|
||||
described in the [configuring](#configuring) section.
|
||||
|
||||
```js
|
||||
```javascript
|
||||
const ORIGIN_HOSTNAME = 'gitlab.installation.com' // FIXME: SET CORRECT VALUE
|
||||
const STORAGE_TOKEN = 'very-secure-token' // FIXME: SET CORRECT VALUE
|
||||
const CACHE_PRIVATE_OBJECTS = false
|
||||
|
|
|
@ -16,19 +16,19 @@ include use cases targeted for parsing GitLab log files.
|
|||
|
||||
#### Pipe colorized `jq` output into `less`
|
||||
|
||||
```sh
|
||||
```shell
|
||||
jq . <FILE> -C | less -R
|
||||
```
|
||||
|
||||
#### Search for a term and pretty-print all matching lines
|
||||
|
||||
```sh
|
||||
```shell
|
||||
grep <TERM> <FILE> | jq .
|
||||
```
|
||||
|
||||
#### Skip invalid lines of JSON
|
||||
|
||||
```sh
|
||||
```shell
|
||||
jq -cR 'fromjson?' file.json | jq <COMMAND>
|
||||
```
|
||||
|
||||
|
@ -39,49 +39,49 @@ This skips over all invalid lines and parses the rest.
|
|||
|
||||
#### Find all requests with a 5XX status code
|
||||
|
||||
```sh
|
||||
```shell
|
||||
jq 'select(status >= 500)' <FILE>
|
||||
```
|
||||
|
||||
#### Top 10 slowest requests
|
||||
|
||||
```sh
|
||||
```shell
|
||||
jq -s 'sort_by(-.duration) | limit(10; .[])' <FILE>
|
||||
```
|
||||
|
||||
#### Find and pretty print all requests related to a project
|
||||
|
||||
```sh
|
||||
```shell
|
||||
grep <PROJECT_NAME> <FILE> | jq .
|
||||
```
|
||||
|
||||
#### Find all requests with a total duration > 5 seconds
|
||||
|
||||
```sh
|
||||
```shell
|
||||
jq 'select(.duration > 5000)' <FILE>
|
||||
```
|
||||
|
||||
#### Find all project requests with more than 5 rugged calls
|
||||
|
||||
```sh
|
||||
```shell
|
||||
grep <PROJECT_NAME> <FILE> | jq 'select(.rugged_calls > 5)'
|
||||
```
|
||||
|
||||
#### Find all requests with a Gitaly duration > 10 seconds
|
||||
|
||||
```sh
|
||||
```shell
|
||||
jq 'select(.gitaly_duration > 10000)' <FILE>
|
||||
```
|
||||
|
||||
#### Find all requests with a queue duration > 10 seconds
|
||||
|
||||
```sh
|
||||
```shell
|
||||
jq 'select(.queue_duration > 10000)' <FILE>
|
||||
```
|
||||
|
||||
#### Top 10 requests by # of Gitaly calls
|
||||
|
||||
```sh
|
||||
```shell
|
||||
jq -s 'map(select(.gitaly_calls != null)) | sort_by(-.gitaly_calls) | limit(10; .[])' <FILE>
|
||||
```
|
||||
|
||||
|
@ -89,7 +89,7 @@ jq -s 'map(select(.gitaly_calls != null)) | sort_by(-.gitaly_calls) | limit(10;
|
|||
|
||||
#### Print the top three controller methods by request volume and their three longest durations
|
||||
|
||||
```sh
|
||||
```shell
|
||||
jq -s -r 'group_by(.controller+.action) | sort_by(-length) | limit(3; .[]) | sort_by(-.duration) | "CT: \(length)\tMETHOD: \(.[0].controller)#\(.[0].action)\tDURS: \(.[0].duration), \(.[1].duration), \(.[2].duration)"' production_json.log
|
||||
```
|
||||
|
||||
|
@ -105,7 +105,7 @@ CT: 1328 METHOD: Projects::NotesController#index DURS: 403.99, 386.29, 384.3
|
|||
|
||||
#### Print top three routes with request count and their three longest durations
|
||||
|
||||
```sh
|
||||
```shell
|
||||
jq -s -r 'group_by(.route) | sort_by(-length) | limit(3; .[]) | sort_by(-.duration) | "CT: \(length)\tROUTE: \(.[0].route)\tDURS: \(.[0].duration), \(.[1].duration), \(.[2].duration)"' api_json.log
|
||||
```
|
||||
|
||||
|
@ -121,25 +121,25 @@ CT: 190 ROUTE: /api/:version/projects/:id/repository/commits DURS: 1079.02,
|
|||
|
||||
#### Find all Gitaly requests sent from web UI
|
||||
|
||||
```sh
|
||||
```shell
|
||||
jq 'select(."grpc.meta.client_name" == "gitlab-web")' current
|
||||
```
|
||||
|
||||
#### Find all failed Gitaly requests
|
||||
|
||||
```sh
|
||||
```shell
|
||||
jq 'select(."grpc.code" != null and ."grpc.code" != "OK")' current
|
||||
```
|
||||
|
||||
#### Find all requests that took longer than 30 seconds
|
||||
|
||||
```sh
|
||||
```shell
|
||||
jq 'select(."grpc.time_ms" > 30000)' current
|
||||
```
|
||||
|
||||
#### Print top three projects by request volume and their three longest durations
|
||||
|
||||
```sh
|
||||
```shell
|
||||
jq -s -r 'map(select(."grpc.request.glProjectPath" != null and ."grpc.request.glProjectPath" != "" and ."grpc.time_ms" != null)) | group_by(."grpc.request.glProjectPath") | sort_by(-length) | limit(3; .[]) | sort_by(-."grpc.time_ms") | "CT: \(length)\tPROJECT: \(.[0]."grpc.request.glProjectPath")\tDURS: \(.[0]."grpc.time_ms"), \(.[1]."grpc.time_ms"), \(.[2]."grpc.time_ms")"' current
|
||||
```
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ interact with the Freeze Period API endpoints.
|
|||
|
||||
## List Freeze Periods
|
||||
|
||||
Paginated list of Freeze Periods, sorted by `created_at`.
|
||||
Paginated list of Freeze Periods, sorted by `created_at` in ascending order.
|
||||
|
||||
```plaintext
|
||||
GET /projects/:id/freeze_periods
|
||||
|
|
|
@ -297,7 +297,7 @@ POST /projects/:id/pipeline_schedules/:pipeline_schedule_id/play
|
|||
|
||||
Example request:
|
||||
|
||||
```sh
|
||||
```shell
|
||||
curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" 'https://gitlab.example.com/api/v4/projects/42/pipeline_schedules/1/play
|
||||
```
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ GET /projects/:id/remote_mirrors
|
|||
|
||||
Example request:
|
||||
|
||||
```sh
|
||||
```shell
|
||||
curl --header "PRIVATE-TOKEN: <your_access_token>" 'https://gitlab.example.com/api/v4/projects/42/remote_mirrors'
|
||||
```
|
||||
|
||||
|
@ -63,7 +63,7 @@ POST /projects/:id/remote_mirrors
|
|||
|
||||
Example request:
|
||||
|
||||
```sh
|
||||
```shell
|
||||
curl --request POST --data "url=https://username:token@example.com/gitlab/example.git" --header "PRIVATE-TOKEN: <your_access_token>" 'https://gitlab.example.com/api/v4/projects/42/remote_mirrors'
|
||||
```
|
||||
|
||||
|
@ -104,7 +104,7 @@ PUT /projects/:id/remote_mirrors/:mirror_id
|
|||
|
||||
Example request:
|
||||
|
||||
```sh
|
||||
```shell
|
||||
curl --request PUT --data "enabled=false" --header "PRIVATE-TOKEN: <your_access_token>" 'https://gitlab.example.com/api/v4/projects/42/remote_mirrors/101486'
|
||||
```
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ For feature flags disabled by default, if they can be used by end users:
|
|||
For example, for a feature disabled by default, disabled on GitLab.com, and
|
||||
not ready for production use:
|
||||
|
||||
````md
|
||||
````markdown
|
||||
# Feature Name
|
||||
|
||||
> - [Introduced](link-to-issue) in GitLab 12.0.
|
||||
|
@ -93,7 +93,7 @@ For features that became enabled by default:
|
|||
|
||||
For example, for a feature initially deployed disabled by default, that became enabled by default, that is enabled on GitLab.com, and ready for production use:
|
||||
|
||||
````md
|
||||
````markdown
|
||||
# Feature Name
|
||||
|
||||
> - [Introduced](link-to-issue) in GitLab 12.0.
|
||||
|
@ -138,7 +138,7 @@ For features enabled by default:
|
|||
|
||||
For example, for a feature enabled by default, enabled on GitLab.com, and ready for production use:
|
||||
|
||||
````md
|
||||
````markdown
|
||||
# Feature Name
|
||||
|
||||
> - [Introduced](link-to-issue) in GitLab 12.0.
|
||||
|
@ -177,7 +177,7 @@ Once the feature is ready and the flag has been removed, clean up the
|
|||
documentation. Remove the feature flag mention keeping only a note that
|
||||
mentions the flag in the version history notes:
|
||||
|
||||
````md
|
||||
````markdown
|
||||
# Feature Name
|
||||
|
||||
> - [Introduced](link-to-issue) in GitLab 12.0.
|
||||
|
|
|
@ -79,7 +79,7 @@ change prior to merging.
|
|||
If you indeed need to change a document's location, do not remove the old
|
||||
document, but instead replace all of its content with the following:
|
||||
|
||||
```md
|
||||
```markdown
|
||||
---
|
||||
redirect_to: '../path/to/file/index.md'
|
||||
---
|
||||
|
@ -93,7 +93,7 @@ The `redirect_to` variable supports both full and relative URLs, for example
|
|||
`https://docs.gitlab.com/ee/path/to/file.html`, `../path/to/file.html`, `path/to/file.md`.
|
||||
It ensures that the redirect will work for <https://docs.gitlab.com> and any `*.md` paths
|
||||
will be compiled to `*.html`.
|
||||
The new line underneath the frontmatter informs the user that the document
|
||||
The new line underneath the front matter informs the user that the document
|
||||
changed location and is useful for someone that browses that file from the repository.
|
||||
|
||||
For example, if you move `doc/workflow/lfs/index.md` to
|
||||
|
@ -102,7 +102,7 @@ For example, if you move `doc/workflow/lfs/index.md` to
|
|||
1. Copy `doc/workflow/lfs/index.md` to `doc/administration/lfs.md`
|
||||
1. Replace the contents of `doc/workflow/lfs/index.md` with:
|
||||
|
||||
```md
|
||||
```markdown
|
||||
---
|
||||
redirect_to: '../../administration/lfs.md'
|
||||
---
|
||||
|
@ -148,12 +148,12 @@ Disqus uses an identifier per page, and for <https://docs.gitlab.com>, the page
|
|||
is configured to be the page URL. Therefore, when we change the document location,
|
||||
we need to preserve the old URL as the same Disqus identifier.
|
||||
|
||||
To do that, add to the frontmatter the variable `disqus_identifier`,
|
||||
using the old URL as value. For example, let's say I moved the document
|
||||
To do that, add to the front matter the variable `disqus_identifier`,
|
||||
using the old URL as value. For example, let's say we moved the document
|
||||
available under `https://docs.gitlab.com/my-old-location/README.html` to a new location,
|
||||
`https://docs.gitlab.com/my-new-location/index.html`.
|
||||
|
||||
Into the **new document** frontmatter add the following:
|
||||
Into the **new document** front matter, we add the following:
|
||||
|
||||
```yaml
|
||||
---
|
||||
|
@ -298,8 +298,8 @@ To preview your changes to documentation locally, follow this
|
|||
|
||||
The live preview is currently enabled for the following projects:
|
||||
|
||||
- <https://gitlab.com/gitlab-org/gitlab>
|
||||
- <https://gitlab.com/gitlab-org/gitlab-runner>
|
||||
- [`gitlab`](https://gitlab.com/gitlab-org/gitlab)
|
||||
- [`gitlab-runner`](https://gitlab.com/gitlab-org/gitlab-runner)
|
||||
|
||||
If your merge request has docs changes, you can use the manual `review-docs-deploy` job
|
||||
to deploy the docs review app for your merge request.
|
||||
|
@ -485,14 +485,14 @@ markdownlint can be used [on the command line](https://github.com/igorshubovych/
|
|||
either on a single Markdown file or on all Markdown files in a project. For example, to run
|
||||
markdownlint on all documentation in the [`gitlab` project](https://gitlab.com/gitlab-org/gitlab),
|
||||
run the following commands from within your `gitlab` project root directory, which will
|
||||
automatically detect the [`.markdownlint.json`](#markdownlint-configuration) config
|
||||
automatically detect the [`.markdownlint.json`](#markdownlint-configuration) configuration
|
||||
file in the root of the project, and test all files in `/doc` and its subdirectories:
|
||||
|
||||
```shell
|
||||
markdownlint 'doc/**/*.md'
|
||||
```
|
||||
|
||||
If you wish to use a different config file, use the `-c` flag:
|
||||
If you wish to use a different configuration file, use the `-c` flag:
|
||||
|
||||
```shell
|
||||
markdownlint -c <config-file-name> 'doc/**/*.md'
|
||||
|
@ -506,7 +506,7 @@ such as:
|
|||
- [Atom](https://atom.io/packages/linter-node-markdownlint)
|
||||
|
||||
It is best to use the [same configuration file](#markdownlint-configuration) as what
|
||||
is in use in the four repos that are the sources for <https://docs.gitlab.com>. Each
|
||||
is in use in the four repositories that are the sources for <https://docs.gitlab.com>. Each
|
||||
plugin/extension has different requirements regarding the configuration file, which
|
||||
is explained in each editor's docs.
|
||||
|
||||
|
@ -515,12 +515,12 @@ is explained in each editor's docs.
|
|||
Each formatting issue that markdownlint checks has an associated
|
||||
[rule](https://github.com/DavidAnson/markdownlint/blob/master/doc/Rules.md#rules).
|
||||
These rules are configured in the `.markdownlint.json` files located in the root of
|
||||
four repos that are the sources for <https://docs.gitlab.com>:
|
||||
four repositories that are the sources for <https://docs.gitlab.com>:
|
||||
|
||||
- <https://gitlab.com/gitlab-org/gitlab/blob/master/.markdownlint.json>
|
||||
- <https://gitlab.com/gitlab-org/gitlab-runner/blob/master/.markdownlint.json>
|
||||
- <https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/.markdownlint.json>
|
||||
- <https://gitlab.com/charts/gitlab/blob/master/.markdownlint.json>
|
||||
- [`gitlab`](https://gitlab.com/gitlab-org/gitlab/blob/master/.markdownlint.json)
|
||||
- [`gitlab-runner`](https://gitlab.com/gitlab-org/gitlab-runner/blob/master/.markdownlint.json)
|
||||
- [`omnibus-gitlab`](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/.markdownlint.json)
|
||||
- [`charts`](https://gitlab.com/charts/gitlab/blob/master/.markdownlint.json)
|
||||
|
||||
By default all rules are enabled, so the configuration file is used to disable unwanted
|
||||
rules, and also to configure optional parameters for enabled rules as needed. You can
|
||||
|
@ -550,7 +550,7 @@ You can also
|
|||
[configure the text editor of your choice](https://errata-ai.github.io/vale/#local-use-by-a-single-writer)
|
||||
to display the results.
|
||||
|
||||
Vale's test results are not currently displayed in CI, but may be displayed in the future.
|
||||
Vale's test results [are displayed](#testing) in CI pipelines.
|
||||
|
||||
##### Disable a Vale test
|
||||
|
||||
|
@ -573,5 +573,5 @@ For more information, see [Vale's documentation](https://errata-ai.gitbook.io/va
|
|||
GitLab uses [Danger](https://github.com/danger/danger) for some elements in
|
||||
code review. For docs changes in merge requests, whenever a change to files under `/doc`
|
||||
is made, Danger Bot leaves a comment with further instructions about the documentation
|
||||
process. This is configured in the Dangerfile in the GitLab repo under
|
||||
process. This is configured in the `Dangerfile` in the GitLab repository under
|
||||
[/danger/documentation/](https://gitlab.com/gitlab-org/gitlab/tree/master/danger/documentation).
|
||||
|
|
|
@ -20,7 +20,7 @@ Every feature or use case document should include the following content in the f
|
|||
with exceptions and details noted below and in the template included on this page.
|
||||
|
||||
- **Title**: Top-level heading with the feature name, or a use case name, which would start with
|
||||
a verb, like Configuring, Enabling, etc.
|
||||
a verb, like Configuring, Enabling, and so on.
|
||||
- **Introduction**: A couple sentences about the subject matter and what's to be found
|
||||
on this page. Describe what the feature or topic is, what it does, and in what context it should
|
||||
be used. There is no need to add a title called "Introduction" or "Overview," because people rarely
|
||||
|
@ -41,7 +41,7 @@ and other logical divisions such as pre- and post-deployment steps.
|
|||
To start a new document, respect the file tree and file name guidelines,
|
||||
as well as the style guidelines. Use the following template:
|
||||
|
||||
```md
|
||||
```markdown
|
||||
<!--Follow the Style Guide when working on this document. https://docs.gitlab.com/ee/development/documentation/styleguide.html
|
||||
When done, remove all of this commented-out text, except a commented-out Troubleshooting section,
|
||||
which, if empty, can be left in place to encourage future use.-->
|
||||
|
@ -130,7 +130,7 @@ Notes:
|
|||
## Help and feedback section
|
||||
|
||||
The "help and feedback" section (introduced by [!319](https://gitlab.com/gitlab-org/gitlab-docs/-/merge_requests/319)) displayed at the end of each document
|
||||
can be omitted from the doc by adding a key into the its frontmatter:
|
||||
can be omitted from the doc by adding a key into the its front matter:
|
||||
|
||||
```yaml
|
||||
---
|
||||
|
@ -148,7 +148,7 @@ We also have integrated the docs site with Disqus (introduced by
|
|||
allowing our users to post comments.
|
||||
|
||||
To omit only the comments from the feedback section, use the following
|
||||
key on the frontmatter:
|
||||
key on the front matter:
|
||||
|
||||
```yaml
|
||||
---
|
||||
|
@ -159,7 +159,7 @@ comments: false
|
|||
We are only hiding comments in main index pages, such as [the main documentation index](../../README.md), since its content is too broad to comment on. Before omitting Disqus,
|
||||
you must check with a technical writer.
|
||||
|
||||
Note that once `feedback: false` is added to the frontmatter, it will automatically omit
|
||||
Note that once `feedback: false` is added to the front matter, it will automatically omit
|
||||
Disqus, therefore, don't add both keys to the same document.
|
||||
|
||||
The click events in the feedback section are tracked with Google Tag Manager. The
|
||||
|
|
|
@ -390,7 +390,7 @@ tenses, words, and phrases:
|
|||
- Insert an empty line for new paragraphs.
|
||||
- Insert an empty line between different markups (for example, after every paragraph, header, list, and so on). Example:
|
||||
|
||||
```md
|
||||
```markdown
|
||||
## Header
|
||||
|
||||
Paragraph.
|
||||
|
@ -447,7 +447,7 @@ Only use ordered lists when their items describe a sequence of steps to follow.
|
|||
|
||||
Do:
|
||||
|
||||
```md
|
||||
```markdown
|
||||
These are the steps to do something:
|
||||
|
||||
1. First, do the first step.
|
||||
|
@ -457,7 +457,7 @@ These are the steps to do something:
|
|||
|
||||
Don't:
|
||||
|
||||
```md
|
||||
```markdown
|
||||
This is a list of available features:
|
||||
|
||||
1. Feature 1
|
||||
|
@ -483,7 +483,7 @@ This is a list of available features:
|
|||
all with a period.
|
||||
- Separate list items from explanatory text with a colon (`:`). For example:
|
||||
|
||||
```md
|
||||
```markdown
|
||||
The list is as follows:
|
||||
|
||||
- First item: this explains the first item.
|
||||
|
@ -630,7 +630,7 @@ page), use the following phrases (based on the SVG icons):
|
|||
|
||||
## Quotes
|
||||
|
||||
Valid for Markdown content only, not for frontmatter entries:
|
||||
Valid for Markdown content only, not for front matter entries:
|
||||
|
||||
- Standard quotes: double quotes (`"`). Example: "This is wrapped in double quotes".
|
||||
- Quote within a quote: double quotes (`"`) wrap single quotes (`'`). Example: "I am 'quoting' something within a quote".
|
||||
|
@ -792,7 +792,7 @@ Instead:
|
|||
|
||||
Example:
|
||||
|
||||
```md
|
||||
```markdown
|
||||
For more information, see the [confidential issue](../../user/project/issues/confidential_issues.md) `https://gitlab.com/gitlab-org/gitlab-foss/issues/<issue_number>`.
|
||||
```
|
||||
|
||||
|
@ -908,7 +908,7 @@ Do not upload videos to the product repositories. [Link](#link-to-video) or [emb
|
|||
To link out to a video, include a YouTube icon so that readers can
|
||||
quickly and easily scan the page for videos before reading:
|
||||
|
||||
```md
|
||||
```markdown
|
||||
<i class="fa fa-youtube-play youtube" aria-hidden="true"></i>
|
||||
For an overview, see [Video Title](link-to-video).
|
||||
```
|
||||
|
@ -1082,7 +1082,7 @@ This will ensure that the source Markdown remains readable and should help with
|
|||
|
||||
The following are examples of source Markdown for menu items with their published output:
|
||||
|
||||
```md
|
||||
```markdown
|
||||
1. Go to **{home}** **Project overview > Details**
|
||||
1. Go to **{doc-text}** **Repository > Branches**
|
||||
1. Go to **{issues}** **Issues > List**
|
||||
|
@ -1143,7 +1143,7 @@ of users.
|
|||
Weigh the costs of distracting users to whom the content is not relevant against
|
||||
the cost of users missing the content if it were not expressed as a note.
|
||||
|
||||
```md
|
||||
```markdown
|
||||
NOTE: **Note:**
|
||||
This is something to note.
|
||||
```
|
||||
|
@ -1155,7 +1155,7 @@ This is something to note.
|
|||
|
||||
### Tip
|
||||
|
||||
```md
|
||||
```markdown
|
||||
TIP: **Tip:**
|
||||
This is a tip.
|
||||
```
|
||||
|
@ -1167,7 +1167,7 @@ This is a tip.
|
|||
|
||||
### Caution
|
||||
|
||||
```md
|
||||
```markdown
|
||||
CAUTION: **Caution:**
|
||||
This is something to be cautious about.
|
||||
```
|
||||
|
@ -1179,7 +1179,7 @@ This is something to be cautious about.
|
|||
|
||||
### Danger
|
||||
|
||||
```md
|
||||
```markdown
|
||||
DANGER: **Danger:**
|
||||
This is a breaking change, a bug, or something very important to note.
|
||||
```
|
||||
|
@ -1193,7 +1193,7 @@ This is a breaking change, a bug, or something very important to note.
|
|||
|
||||
For highlighting a text within a blue blockquote, use this format:
|
||||
|
||||
```md
|
||||
```markdown
|
||||
> This is a blockquote.
|
||||
```
|
||||
|
||||
|
@ -1205,7 +1205,7 @@ If the text spans across multiple lines it's OK to split the line.
|
|||
|
||||
For multiple paragraphs, use the symbol `>` before every line:
|
||||
|
||||
```md
|
||||
```markdown
|
||||
> This is the first paragraph.
|
||||
>
|
||||
> This is the second paragraph.
|
||||
|
@ -1298,14 +1298,14 @@ a helpful link back to how the feature was developed.
|
|||
- If listing information for multiple version as a feature evolves, add the information to a
|
||||
block-quoted bullet list. For example:
|
||||
|
||||
```md
|
||||
```markdown
|
||||
> - [Introduced](<link-to-issue>) in GitLab 11.3.
|
||||
> - Enabled by default in GitLab 11.4.
|
||||
```
|
||||
|
||||
- If a feature is moved to another tier:
|
||||
|
||||
```md
|
||||
```markdown
|
||||
> - [Introduced](<link-to-issue>) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.5.
|
||||
> - [Moved](<link-to-issue>) to [GitLab Starter](https://about.gitlab.com/pricing/) in 11.8.
|
||||
> - [Moved](<link-to-issue>) to GitLab Core in 12.0.
|
||||
|
@ -1417,7 +1417,7 @@ avoid duplication, link to the special document that can be found in
|
|||
[`doc/administration/restart_gitlab.md`](../../administration/restart_gitlab.md).
|
||||
Usually the text will read like:
|
||||
|
||||
```md
|
||||
```markdown
|
||||
Save the file and [reconfigure GitLab](../../administration/restart_gitlab.md)
|
||||
for the changes to take effect.
|
||||
```
|
||||
|
@ -1453,7 +1453,7 @@ When there is a list of steps to perform, usually that entails editing the
|
|||
configuration file and reconfiguring/restarting GitLab. In such case, follow
|
||||
the style below as a guide:
|
||||
|
||||
````md
|
||||
````markdown
|
||||
**For Omnibus installations**
|
||||
|
||||
1. Edit `/etc/gitlab/gitlab.rb`:
|
||||
|
@ -1591,7 +1591,7 @@ You can use the following fake tokens as examples.
|
|||
Use the following table headers to describe the methods. Attributes should
|
||||
always be in code blocks using backticks (`` ` ``).
|
||||
|
||||
```md
|
||||
```markdown
|
||||
| Attribute | Type | Required | Description |
|
||||
|:----------|:-----|:---------|:------------|
|
||||
```
|
||||
|
|
|
@ -26,7 +26,7 @@ If you do not provide any arguments, it will globally query and instantiate all
|
|||
<ul>
|
||||
```
|
||||
|
||||
```js
|
||||
```javascript
|
||||
const droplab = new DropLab();
|
||||
droplab.init();
|
||||
```
|
||||
|
@ -47,7 +47,7 @@ You can add static list items.
|
|||
<ul>
|
||||
```
|
||||
|
||||
```js
|
||||
```javascript
|
||||
const droplab = new DropLab();
|
||||
droplab.init();
|
||||
```
|
||||
|
@ -65,7 +65,7 @@ a non-global instance of DropLab using the `DropLab.prototype.init` method.
|
|||
<ul>
|
||||
```
|
||||
|
||||
```js
|
||||
```javascript
|
||||
const trigger = document.getElementById('trigger');
|
||||
const list = document.getElementById('list');
|
||||
|
||||
|
@ -83,7 +83,7 @@ You can also add hooks to an existing DropLab instance using `DropLab.prototype.
|
|||
<ul id="list" data-dropdown><!-- ... --><ul>
|
||||
```
|
||||
|
||||
```js
|
||||
```javascript
|
||||
const droplab = new DropLab();
|
||||
|
||||
droplab.init();
|
||||
|
@ -114,7 +114,7 @@ for all `data-dynamic` dropdown lists tracked by that DropLab instance.
|
|||
</ul>
|
||||
```
|
||||
|
||||
```js
|
||||
```javascript
|
||||
const droplab = new DropLab();
|
||||
|
||||
droplab.init().addData([{
|
||||
|
@ -137,7 +137,7 @@ the data as the second argument and the `id` of the trigger element as the first
|
|||
</ul>
|
||||
```
|
||||
|
||||
```js
|
||||
```javascript
|
||||
const droplab = new DropLab();
|
||||
|
||||
droplab.init().addData('trigger', [{
|
||||
|
@ -167,7 +167,7 @@ dropdown lists, one of which is dynamic.
|
|||
</div>
|
||||
```
|
||||
|
||||
```js
|
||||
```javascript
|
||||
const droplab = new DropLab();
|
||||
|
||||
droplab.init().addData('trigger', [{
|
||||
|
@ -224,7 +224,7 @@ Some plugins require configuration values, the config object can be passed as th
|
|||
<ul id="list" data-dropdown><!-- ... --><ul>
|
||||
```
|
||||
|
||||
```js
|
||||
```javascript
|
||||
const droplab = new DropLab();
|
||||
|
||||
const trigger = document.getElementById('trigger');
|
||||
|
@ -249,7 +249,7 @@ droplab.init(trigger, list, [droplabAjax], {
|
|||
When plugins are initialised for a droplab trigger+dropdown, DropLab will
|
||||
call the plugins `init` function, so this must be implemented in the plugin.
|
||||
|
||||
```js
|
||||
```javascript
|
||||
class MyPlugin {
|
||||
static init() {
|
||||
this.someProp = 'someProp';
|
||||
|
|
|
@ -18,7 +18,7 @@ Add the `Ajax` object to the plugins array of a `DropLab.prototype.init` or `Dro
|
|||
<ul id="list" data-dropdown><!-- ... --><ul>
|
||||
```
|
||||
|
||||
```js
|
||||
```javascript
|
||||
const droplab = new DropLab();
|
||||
|
||||
const trigger = document.getElementById('trigger');
|
||||
|
|
|
@ -18,7 +18,7 @@ Add the `Filter` object to the plugins array of a `DropLab.prototype.init` or `D
|
|||
<ul>
|
||||
```
|
||||
|
||||
```js
|
||||
```javascript
|
||||
const droplab = new DropLab();
|
||||
|
||||
const trigger = document.getElementById('trigger');
|
||||
|
|
|
@ -23,7 +23,7 @@ You can also set the `InputSetter` config to an array of objects, which will all
|
|||
<ul>
|
||||
```
|
||||
|
||||
```js
|
||||
```javascript
|
||||
const droplab = new DropLab();
|
||||
|
||||
const trigger = document.getElementById('trigger');
|
||||
|
|
|
@ -212,7 +212,7 @@ Read more about local state management with Apollo in the [Vue Apollo documentat
|
|||
|
||||
When Apollo Client is used within Vuex and fetched data is stored in the Vuex store, there is no need in keeping Apollo Client cache enabled. Otherwise we would have data from the API stored in two places - Vuex store and Apollo Client cache. More to say, with Apollo default settings, a subsequent fetch from the GraphQL API could result in fetching data from Apollo cache (in the case where we have the same query and variables). To prevent this behavior, we need to disable Apollo Client cache passing a valid `fetchPolicy` option to its constructor:
|
||||
|
||||
```js
|
||||
```javascript
|
||||
import fetchPolicies from '~/graphql_shared/fetch_policy_constants';
|
||||
|
||||
export const gqClient = createGqClient(
|
||||
|
|
|
@ -111,7 +111,7 @@ export default {
|
|||
</template>
|
||||
```
|
||||
|
||||
```js
|
||||
```javascript
|
||||
// MyAwesomeComponent.spec.js
|
||||
|
||||
import SomeChildComponent from '~/some_child_component.vue'
|
||||
|
|
|
@ -131,7 +131,7 @@ You can mark that content for translation with:
|
|||
In JavaScript we added the `__()` (double underscore parenthesis) function that
|
||||
you can import from the `~/locale` file. For instance:
|
||||
|
||||
```js
|
||||
```javascript
|
||||
import { __ } from '~/locale';
|
||||
const label = __('Subscribe');
|
||||
```
|
||||
|
@ -167,7 +167,7 @@ For example use `%{created_at}` in Ruby but `%{createdAt}` in JavaScript. Make s
|
|||
|
||||
- In JavaScript (when Vue cannot be used):
|
||||
|
||||
```js
|
||||
```javascript
|
||||
import { __, sprintf } from '~/locale';
|
||||
|
||||
sprintf(__('Hello %{username}'), { username: 'Joe' }); // => 'Hello Joe'
|
||||
|
@ -180,7 +180,7 @@ For example use `%{created_at}` in Ruby but `%{createdAt}` in JavaScript. Make s
|
|||
escape any interpolated dynamic values yourself, for instance using
|
||||
`escape` from `lodash`.
|
||||
|
||||
```js
|
||||
```javascript
|
||||
import { escape } from 'lodash';
|
||||
import { __, sprintf } from '~/locale';
|
||||
|
||||
|
@ -220,14 +220,14 @@ For example use `%{created_at}` in Ruby but `%{createdAt}` in JavaScript. Make s
|
|||
|
||||
- In JavaScript:
|
||||
|
||||
```js
|
||||
```javascript
|
||||
n__('Apple', 'Apples', 3)
|
||||
// => 'Apples'
|
||||
```
|
||||
|
||||
Using interpolation:
|
||||
|
||||
```js
|
||||
```javascript
|
||||
n__('Last day', 'Last %d days', x)
|
||||
// => When x == 1: 'Last day'
|
||||
// => When x == 2: 'Last 2 days'
|
||||
|
@ -274,7 +274,7 @@ Namespaces should be PascalCase.
|
|||
|
||||
- In JavaScript:
|
||||
|
||||
```js
|
||||
```javascript
|
||||
s__('OpenedNDaysAgo|Opened')
|
||||
```
|
||||
|
||||
|
@ -285,7 +285,7 @@ guidelines for more details](translation.md#namespaced-strings).
|
|||
|
||||
- In JavaScript:
|
||||
|
||||
```js
|
||||
```javascript
|
||||
import { createDateTimeFormat } from '~/locale';
|
||||
|
||||
const dateFormat = createDateTimeFormat({ year: 'numeric', month: 'long', day: 'numeric' });
|
||||
|
@ -372,7 +372,7 @@ structure is the same in all languages.
|
|||
|
||||
For instance, the following:
|
||||
|
||||
```js
|
||||
```javascript
|
||||
{{ s__("mrWidget|Set by") }}
|
||||
{{ author.name }}
|
||||
{{ s__("mrWidget|to be merged automatically when the pipeline succeeds") }}
|
||||
|
@ -380,7 +380,7 @@ For instance, the following:
|
|||
|
||||
should be externalized as follows:
|
||||
|
||||
```js
|
||||
```javascript
|
||||
{{ sprintf(s__("mrWidget|Set by %{author} to be merged automatically when the pipeline succeeds"), { author: author.name }) }}
|
||||
```
|
||||
|
||||
|
@ -439,7 +439,7 @@ This also applies when using links in between translated sentences, otherwise th
|
|||
|
||||
- In JavaScript (when Vue cannot be used), instead of:
|
||||
|
||||
```js
|
||||
```javascript
|
||||
{{
|
||||
sprintf(s__("ClusterIntegration|Learn more about %{link}"), {
|
||||
link: '<a href="https://cloud.google.com/compute/docs/regions-zones/regions-zones" target="_blank" rel="noopener noreferrer">zones</a>'
|
||||
|
@ -449,7 +449,7 @@ This also applies when using links in between translated sentences, otherwise th
|
|||
|
||||
Set the link starting and ending HTML fragments as placeholders like so:
|
||||
|
||||
```js
|
||||
```javascript
|
||||
{{
|
||||
sprintf(s__("ClusterIntegration|Learn more about %{linkStart}zones%{linkEnd}"), {
|
||||
linkStart: '<a href="https://cloud.google.com/compute/docs/regions-zones/regions-zones" target="_blank" rel="noopener noreferrer">',
|
||||
|
|
|
@ -51,7 +51,7 @@ or `db/post_migrate`, so if there are any migrations you don't want to
|
|||
commit to the schema, rename or remove them. If your branch is not
|
||||
targetting `master` you can set the `TARGET` environment variable.
|
||||
|
||||
```sh
|
||||
```shell
|
||||
# Regenerate schema against `master`
|
||||
scripts/regenerate-schema
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ within the GitLab project.
|
|||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
```javascript
|
||||
import dirtySubmitFactory from './dirty_submit/dirty_submit_form';
|
||||
|
||||
new DirtySubmitForm(document.querySelector('form'));
|
||||
|
|
|
@ -184,7 +184,7 @@ Reference pipeline: <https://gitlab.com/gitlab-org/gitlab/pipelines/135236627>
|
|||
```mermaid
|
||||
graph LR
|
||||
subgraph "No needed jobs";
|
||||
1-1["danger-review (5.3 minutes)"];
|
||||
1-1["danger-review (3.5 minutes)"];
|
||||
click 1-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=8100542&udv=0"
|
||||
1-50["docs lint (6.75 minutes)"];
|
||||
click 1-50 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=8356757&udv=0"
|
||||
|
@ -200,9 +200,9 @@ graph RL;
|
|||
classDef criticalPath fill:#f66;
|
||||
|
||||
subgraph "No needed jobs";
|
||||
1-1["danger-review (5.3 minutes)"];
|
||||
1-1["danger-review (3.5 minutes)"];
|
||||
click 1-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=8100542&udv=0"
|
||||
1-2["build-qa-image (4.4 minutes)"];
|
||||
1-2["build-qa-image (3.4 minutes)"];
|
||||
click 1-2 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914325&udv=0"
|
||||
1-3["compile-assets pull-cache (9.06 minutes)"];
|
||||
click 1-3 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914317&udv=0"
|
||||
|
@ -210,7 +210,7 @@ graph RL;
|
|||
click 1-4 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=8356616&udv=0"
|
||||
1-5["gitlab:assets:compile pull-cache (22 minutes)"];
|
||||
click 1-5 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914312&udv=0"
|
||||
1-6["setup-test-env (9.6 minutes)"];
|
||||
1-6["setup-test-env (8.22 minutes)"];
|
||||
click 1-6 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914315&udv=0"
|
||||
1-7["review-stop-failed-deployment"];
|
||||
1-8["dependency_scanning"];
|
||||
|
@ -250,7 +250,7 @@ graph RL;
|
|||
click 2_2-3 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=7910154&udv=0"
|
||||
2_2-4["memory-on-boot (7.19 minutes)"];
|
||||
click 2_2-4 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=8356727&udv=0"
|
||||
2_2-5["webpack-dev-server (7.62 minutes)"];
|
||||
2_2-5["webpack-dev-server (6.1 minutes)"];
|
||||
click 2_2-5 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=8404303&udv=0"
|
||||
subgraph "Needs `setup-test-env` & `compile-assets`";
|
||||
2_2-1 & 2_2-2 & 2_2-4 & 2_2-5 --> 1-6 & 1-3;
|
||||
|
@ -275,28 +275,28 @@ graph RL;
|
|||
click 2_5-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations"
|
||||
end
|
||||
|
||||
3_1-1["jest (11.2 minutes)"];
|
||||
3_1-1["jest (15 minutes)"];
|
||||
class 3_1-1 criticalPath;
|
||||
click 3_1-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914204&udv=0"
|
||||
3_1-2["karma (9.18 minutes)"];
|
||||
3_1-2["karma (8 minutes)"];
|
||||
click 3_1-3 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914200&udv=0"
|
||||
3_1-3["jest-as-if-foss (14.8 minutes)"];
|
||||
3_1-3["jest-as-if-foss (19.7 minutes)"];
|
||||
click 3_1-3 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914205&udv=0"
|
||||
3_1-4["karma-as-if-foss (8.25 minutes)"];
|
||||
3_1-4["karma-as-if-foss (7.5 minutes)"];
|
||||
click 3_1-4 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914203&udv=0"
|
||||
subgraph "Needs `frontend-fixtures`";
|
||||
3_1-1 & 3_1-2 --> 2_2-2;
|
||||
3_1-3 & 3_1-4 --> 2_2-3;
|
||||
end
|
||||
|
||||
3_2-1["rspec:coverage (7.67 minutes)"];
|
||||
3_2-1["rspec:coverage (6.5 minutes)"];
|
||||
subgraph "Depends on `rspec` jobs";
|
||||
3_2-1 -.->|"(don't use needs because of limitations)"| 2_5-1;
|
||||
class 3_2-1 criticalPath;
|
||||
click 3_2-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=7248745&udv=0"
|
||||
end
|
||||
|
||||
4_1-1["coverage-frontend (5.39 minutes)"];
|
||||
4_1-1["coverage-frontend (3.6 minutes)"];
|
||||
subgraph "Needs `jest`";
|
||||
4_1-1 --> 3_1-1;
|
||||
class 4_1-1 criticalPath;
|
||||
|
@ -313,9 +313,9 @@ graph RL;
|
|||
classDef criticalPath fill:#f66;
|
||||
|
||||
subgraph "No needed jobs";
|
||||
1-1["danger-review (5.3 minutes)"];
|
||||
1-1["danger-review (3.5 minutes)"];
|
||||
click 1-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=8100542&udv=0"
|
||||
1-2["build-qa-image (4.4 minutes)"];
|
||||
1-2["build-qa-image (3.4 minutes)"];
|
||||
click 1-2 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914325&udv=0"
|
||||
1-3["compile-assets pull-cache (9.06 minutes)"];
|
||||
click 1-3 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914317&udv=0"
|
||||
|
@ -323,7 +323,7 @@ graph RL;
|
|||
click 1-4 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=8356616&udv=0"
|
||||
1-5["gitlab:assets:compile pull-cache (22 minutes)"];
|
||||
click 1-5 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914312&udv=0"
|
||||
1-6["setup-test-env (9.6 minutes)"];
|
||||
1-6["setup-test-env (8.22 minutes)"];
|
||||
click 1-6 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914315&udv=0"
|
||||
1-7["review-stop-failed-deployment"];
|
||||
1-8["dependency_scanning"];
|
||||
|
@ -364,7 +364,7 @@ graph RL;
|
|||
click 2_2-3 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=7910154&udv=0"
|
||||
2_2-4["memory-on-boot (7.19 minutes)"];
|
||||
click 2_2-4 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=8356727&udv=0"
|
||||
2_2-5["webpack-dev-server (7.62 minutes)"];
|
||||
2_2-5["webpack-dev-server (6.1 minutes)"];
|
||||
click 2_2-5 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=8404303&udv=0"
|
||||
subgraph "Needs `setup-test-env` & `compile-assets`";
|
||||
2_2-1 & 2_2-2 & 2_2-4 & 2_2-5 --> 1-6 & 1-3;
|
||||
|
@ -397,28 +397,28 @@ graph RL;
|
|||
click 2_6-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914314&udv=0"
|
||||
end
|
||||
|
||||
3_1-1["jest (11.2 minutes)"];
|
||||
3_1-1["jest (15 minutes)"];
|
||||
class 3_1-1 criticalPath;
|
||||
click 3_1-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914204&udv=0"
|
||||
3_1-2["karma (9.18 minutes)"];
|
||||
3_1-2["karma (8 minutes)"];
|
||||
click 3_1-3 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914200&udv=0"
|
||||
3_1-3["jest-as-if-foss (14.8 minutes)"];
|
||||
3_1-3["jest-as-if-foss (19.7 minutes)"];
|
||||
click 3_1-3 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914205&udv=0"
|
||||
3_1-4["karma-as-if-foss (8.25 minutes)"];
|
||||
3_1-4["karma-as-if-foss (7.5 minutes)"];
|
||||
click 3_1-4 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914203&udv=0"
|
||||
subgraph "Needs `frontend-fixtures`";
|
||||
3_1-1 & 3_1-3 --> 2_2-2;
|
||||
3_1-2 & 3_1-4 --> 2_2-3;
|
||||
end
|
||||
|
||||
3_2-1["rspec:coverage (7.67 minutes)"];
|
||||
3_2-1["rspec:coverage (6.5 minutes)"];
|
||||
subgraph "Depends on `rspec` jobs";
|
||||
3_2-1 -.->|"(don't use needs because of limitations)"| 2_5-1;
|
||||
class 3_2-1 criticalPath;
|
||||
click 3_2-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=7248745&udv=0"
|
||||
end
|
||||
|
||||
4_1-1["coverage-frontend (5.39 minutes)"];
|
||||
4_1-1["coverage-frontend (3.6 minutes)"];
|
||||
subgraph "Needs `jest`";
|
||||
4_1-1 --> 3_1-1;
|
||||
class 4_1-1 criticalPath;
|
||||
|
@ -432,9 +432,9 @@ graph RL;
|
|||
click 3_3-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6721130&udv=0"
|
||||
end
|
||||
|
||||
4_2-1["review-qa-smoke (7.29 minutes)"];
|
||||
4_2-1["review-qa-smoke (8 minutes)"];
|
||||
click 4_2-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6729805&udv=0"
|
||||
4_2-2["review-performance (3.83 minutes)"];
|
||||
4_2-2["review-performance (4 minutes)"];
|
||||
click 4_2-2 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=8356817&udv=0"
|
||||
4_2-3["dast (18 minutes)"];
|
||||
click 4_2-3 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=8356819&udv=0"
|
||||
|
@ -453,9 +453,9 @@ graph RL;
|
|||
classDef criticalPath fill:#f66;
|
||||
|
||||
subgraph "No needed jobs";
|
||||
1-1["danger-review (5.3 minutes)"];
|
||||
1-1["danger-review (3.5 minutes)"];
|
||||
click 1-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=8100542&udv=0"
|
||||
1-2["build-qa-image (4.4 minutes)"];
|
||||
1-2["build-qa-image (3.4 minutes)"];
|
||||
click 1-2 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914325&udv=0"
|
||||
1-3["compile-assets pull-cache (9.06 minutes)"];
|
||||
click 1-3 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914317&udv=0"
|
||||
|
@ -463,7 +463,7 @@ graph RL;
|
|||
click 1-4 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=8356616&udv=0"
|
||||
1-5["gitlab:assets:compile pull-cache (22 minutes)"];
|
||||
click 1-5 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914312&udv=0"
|
||||
1-6["setup-test-env (9.6 minutes)"];
|
||||
1-6["setup-test-env (8.22 minutes)"];
|
||||
click 1-6 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914315&udv=0"
|
||||
1-7["review-stop-failed-deployment"];
|
||||
1-8["dependency_scanning"];
|
||||
|
|
|
@ -98,7 +98,7 @@ If it's not possible to follow the above method, the images can be transferred m
|
|||
|
||||
#### Example image packager script
|
||||
|
||||
```sh
|
||||
```shell
|
||||
#!/bin/bash
|
||||
set -ux
|
||||
|
||||
|
@ -120,7 +120,7 @@ done
|
|||
This example loads the images from a bastion host to an offline host. In certain configurations,
|
||||
physical media may be needed for such a transfer:
|
||||
|
||||
```sh
|
||||
```shell
|
||||
#!/bin/bash
|
||||
set -ux
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ being modified after the database dump is created.
|
|||
1. Get the Kubernetes namespace for the environment. It typically looks like `<project-name>-<project-id>-<environment>`.
|
||||
In our example, the namespace is called `minimal-ruby-app-4349298-production`.
|
||||
|
||||
```sh
|
||||
```shell
|
||||
$ kubectl get ns
|
||||
|
||||
NAME STATUS AGE
|
||||
|
@ -48,13 +48,13 @@ being modified after the database dump is created.
|
|||
|
||||
1. For ease of use, export the namespace name:
|
||||
|
||||
```sh
|
||||
```shell
|
||||
export APP_NAMESPACE=minimal-ruby-app-4349298-production
|
||||
```
|
||||
|
||||
1. Get the deployment name for your application with the following command. In our example, the deployment name is `production`.
|
||||
|
||||
```sh
|
||||
```shell
|
||||
$ kubectl get deployment --namespace "$APP_NAMESPACE"
|
||||
NAME READY UP-TO-DATE AVAILABLE AGE
|
||||
production 2/2 2 2 7d21h
|
||||
|
@ -64,7 +64,7 @@ being modified after the database dump is created.
|
|||
1. To prevent the database from being modified, set replicas to 0 for the deployment with the following command.
|
||||
We use the deployment name from the previous step (`deployments/<DEPLOYMENT_NAME>`).
|
||||
|
||||
```sh
|
||||
```shell
|
||||
$ kubectl scale --replicas=0 deployments/production --namespace "$APP_NAMESPACE"
|
||||
deployment.extensions/production scaled
|
||||
```
|
||||
|
@ -75,7 +75,7 @@ being modified after the database dump is created.
|
|||
|
||||
1. Get the service name for PostgreSQL. The name of the service should end with `-postgres`. In our example the service name is `production-postgres`.
|
||||
|
||||
```sh
|
||||
```shell
|
||||
$ kubectl get svc --namespace "$APP_NAMESPACE"
|
||||
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||
production-auto-deploy ClusterIP 10.30.13.90 <none> 5000/TCP 7d14h
|
||||
|
@ -84,7 +84,7 @@ being modified after the database dump is created.
|
|||
|
||||
1. Get the pod name for PostgreSQL with the following command. In our example, the pod name is `production-postgres-5db86568d7-qxlxv`.
|
||||
|
||||
```sh
|
||||
```shell
|
||||
$ kubectl get pod --namespace "$APP_NAMESPACE" -l app=production-postgres
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
production-postgres-5db86568d7-qxlxv 1/1 Running 0 7d14h
|
||||
|
@ -92,7 +92,7 @@ being modified after the database dump is created.
|
|||
|
||||
1. Connect to the pod with:
|
||||
|
||||
```sh
|
||||
```shell
|
||||
kubectl exec -it production-postgres-5db86568d7-qxlxv --namespace "$APP_NAMESPACE" bash
|
||||
```
|
||||
|
||||
|
@ -104,7 +104,7 @@ being modified after the database dump is created.
|
|||
|
||||
- You will be asked for the database password, the default is `testing-password`.
|
||||
|
||||
```sh
|
||||
```shell
|
||||
## Format is:
|
||||
# pg_dump -h SERVICE_NAME -U USERNAME DATABASE_NAME > /tmp/backup.sql
|
||||
|
||||
|
@ -115,7 +115,7 @@ being modified after the database dump is created.
|
|||
|
||||
1. Download the dump file with the following command:
|
||||
|
||||
```sh
|
||||
```shell
|
||||
kubectl cp --namespace "$APP_NAMESPACE" production-postgres-5db86568d7-qxlxv:/tmp/backup.sql backup.sql
|
||||
```
|
||||
|
||||
|
@ -131,7 +131,7 @@ deleted causing the persistent volumes to be deleted as well.
|
|||
|
||||
You can verify this by using the following command:
|
||||
|
||||
```sh
|
||||
```shell
|
||||
$ kubectl get pv
|
||||
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
|
||||
pvc-0da80c08-5239-11ea-9c8d-42010a8e0096 8Gi RWO Delete Bound minimal-ruby-app-4349298-staging/staging-postgres standard 7d22h
|
||||
|
@ -145,7 +145,7 @@ interested in keeping the volumes for the staging and production of the
|
|||
`minimal-ruby-app-4349298` application, the volume names here are
|
||||
`pvc-0da80c08-5239-11ea-9c8d-42010a8e0096` and `pvc-9085e3d3-5239-11ea-9c8d-42010a8e0096`:
|
||||
|
||||
```sh
|
||||
```shell
|
||||
$ kubectl patch pv pvc-0da80c08-5239-11ea-9c8d-42010a8e0096 -p '{"spec":{"persistentVolumeReclaimPolicy":"Retain"}}'
|
||||
persistentvolume/pvc-0da80c08-5239-11ea-9c8d-42010a8e0096 patched
|
||||
$ kubectl patch pv pvc-9085e3d3-5239-11ea-9c8d-42010a8e0096 -p '{"spec":{"persistentVolumeReclaimPolicy":"Retain"}}'
|
||||
|
@ -192,7 +192,7 @@ TIP: **Tip:** You can also
|
|||
1. Get the pod name for the new PostgreSQL, in our example, the pod name is
|
||||
`production-postgresql-0`:
|
||||
|
||||
```sh
|
||||
```shell
|
||||
$ kubectl get pod --namespace "$APP_NAMESPACE" -l app=postgresql
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
production-postgresql-0 1/1 Running 0 19m
|
||||
|
@ -200,13 +200,13 @@ TIP: **Tip:** You can also
|
|||
|
||||
1. Copy the dump file from the backup steps to the pod:
|
||||
|
||||
```sh
|
||||
```shell
|
||||
kubectl cp --namespace "$APP_NAMESPACE" backup.sql production-postgresql-0:/tmp/backup.sql
|
||||
```
|
||||
|
||||
1. Connect to the pod:
|
||||
|
||||
```sh
|
||||
```shell
|
||||
kubectl exec -it production-postgresql-0 --namespace "$APP_NAMESPACE" bash
|
||||
```
|
||||
|
||||
|
@ -216,7 +216,7 @@ TIP: **Tip:** You can also
|
|||
- `USERNAME` is the username you have configured for PostgreSQL. The default is `user`.
|
||||
- `DATABASE_NAME` is usually the environment name.
|
||||
|
||||
```sh
|
||||
```shell
|
||||
## Format is:
|
||||
# psql -U USERNAME -d DATABASE_NAME < /tmp/backup.sql
|
||||
|
||||
|
|
|
@ -228,7 +228,7 @@ To make PlantUML available in GitLab, a GitLab administrator needs to enable it
|
|||
|
||||
> If this is not rendered correctly, [view it in GitLab itself](https://gitlab.com/gitlab-org/gitlab/blob/master/doc/user/markdown.md#emoji).
|
||||
|
||||
```md
|
||||
```markdown
|
||||
Sometimes you want to :monkey: around a bit and add some :star2: to your :speech_balloon:. Well we have a gift for you:
|
||||
|
||||
:zap: You can use emoji anywhere GFM is supported. :v:
|
||||
|
@ -804,7 +804,7 @@ but_emphasis is_desired _here_
|
|||
|
||||
If you wish to emphasize only a part of a word, it can still be done with asterisks:
|
||||
|
||||
```md
|
||||
```markdown
|
||||
perform*complicated*task
|
||||
|
||||
do*this*and*do*that*and*another thing
|
||||
|
@ -976,7 +976,7 @@ Do not change to a reference style link.
|
|||
Image tags that link to files with a video extension are automatically converted to
|
||||
a video player. The valid video extensions are `.mp4`, `.m4v`, `.mov`, `.webm`, and `.ogv`:
|
||||
|
||||
```md
|
||||
```markdown
|
||||
Here's a sample video:
|
||||
|
||||
![Sample Video](img/markdown_video.mp4)
|
||||
|
@ -993,7 +993,7 @@ Here's a sample video:
|
|||
Similar to videos, link tags for files with an audio extension are automatically converted to
|
||||
an audio player. The valid audio extensions are `.mp3`, `.oga`, `.ogg`, `.spx`, and `.wav`:
|
||||
|
||||
```md
|
||||
```markdown
|
||||
Here's a sample audio clip:
|
||||
|
||||
![Sample Audio](img/markdown_audio.mp3)
|
||||
|
@ -1275,7 +1275,7 @@ number, and count up from there.
|
|||
|
||||
Examples:
|
||||
|
||||
```md
|
||||
```markdown
|
||||
1. First ordered list item
|
||||
2. Another item
|
||||
- Unordered sub-list.
|
||||
|
@ -1302,7 +1302,7 @@ See https://docs.gitlab.com/ee/development/documentation/styleguide.html#lists
|
|||
For an unordered list, add a `-`, `*` or `+`, followed by a space, at the start of
|
||||
each line for unordered lists, but you should not use a mix of them.
|
||||
|
||||
```md
|
||||
```markdown
|
||||
Unordered lists can:
|
||||
|
||||
- use
|
||||
|
|
|
@ -137,7 +137,7 @@ The minimum scope needed for both of them is `read_registry`.
|
|||
|
||||
Example of using a token:
|
||||
|
||||
```sh
|
||||
```shell
|
||||
docker login registry.example.com -u <username> -p <token>
|
||||
```
|
||||
|
||||
|
@ -206,7 +206,7 @@ Available for all projects, though more suitable for public ones:
|
|||
your Docker images and has read/write access to the Registry. This is ephemeral,
|
||||
so it's only valid for one job. You can use the following example as-is:
|
||||
|
||||
```sh
|
||||
```shell
|
||||
docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
|
||||
```
|
||||
|
||||
|
@ -221,7 +221,7 @@ For private and internal projects:
|
|||
|
||||
Replace the `<username>` and `<access_token>` in the following example:
|
||||
|
||||
```sh
|
||||
```shell
|
||||
docker login -u <username> -p <access_token> $CI_REGISTRY
|
||||
```
|
||||
|
||||
|
@ -231,7 +231,7 @@ For private and internal projects:
|
|||
Once created, you can use the special environment variables, and GitLab CI/CD
|
||||
will fill them in for you. You can use the following example as-is:
|
||||
|
||||
```sh
|
||||
```shell
|
||||
docker login -u $CI_DEPLOY_USER -p $CI_DEPLOY_PASSWORD $CI_REGISTRY
|
||||
```
|
||||
|
||||
|
|
|
@ -39,6 +39,26 @@ templates of the default branch will be taken into account.
|
|||
Create a new Markdown (`.md`) file inside the `.gitlab/issue_templates/`
|
||||
directory in your repository. Commit and push to your default branch.
|
||||
|
||||
To create a Markdown file:
|
||||
|
||||
1. Click the `+` button next to `master` and click **New file**.
|
||||
1. Add the name of your issue template to the **File name** text field next to `master`.
|
||||
Make sure words are separated with underscores and that your file has the `.md` extension, for
|
||||
example `feature_request.md`.
|
||||
1. Commit and push to your default branch.
|
||||
|
||||
If you don't have a `.gitlab/issue_templates` directory in your repository, you'll need to create it.
|
||||
|
||||
To create the `.gitlab/issue_templates` directory:
|
||||
|
||||
1. Click the `+` button next to `master` and select **New directory**.
|
||||
1. Name this new directory `.gitlab` and commit to your default branch.
|
||||
1. Click the `+` button next to `master` again and select **New directory**.This time, n
|
||||
1. Name your directory `issue_templates` and commit to your default branch.
|
||||
|
||||
To check if this has worked correctly, [create a new issue](./issues/managing_issues.md#create-a-new-issue)
|
||||
and see if you can choose a description template.
|
||||
|
||||
## Creating merge request templates
|
||||
|
||||
Similarly to issue templates, create a new Markdown (`.md`) file inside the
|
||||
|
|
|
@ -183,7 +183,7 @@ but it will not close automatically.
|
|||
|
||||
If the issue is in a different repository than the MR, add the full URL for the issue(s):
|
||||
|
||||
```md
|
||||
```markdown
|
||||
Closes #4, #6, and https://gitlab.com/<username>/<projectname>/issues/<xxx>
|
||||
```
|
||||
|
||||
|
|
|
@ -252,6 +252,9 @@ generate Release Evidence for an existing release. Because of this, [each releas
|
|||
can have multiple Release Evidence snapshots. You can view the Release Evidence and
|
||||
its details on the Release page.
|
||||
|
||||
NOTE: **Note:**
|
||||
When the issue tracker is disabled, release evidence [is not collected](https://gitlab.com/gitlab-org/gitlab/-/issues/208397).
|
||||
|
||||
Release Evidence is stored as a JSON object, so you can compare evidence by using
|
||||
commonly-available tools.
|
||||
|
||||
|
@ -371,7 +374,7 @@ freeze periods, all will apply, and should they overlap, the freeze covers the
|
|||
complete overlapped period.
|
||||
|
||||
During pipeline processing, GitLab CI creates an environment variable named
|
||||
`$CI_ENVIRONMENT_FROZEN` if the currently executing job is within a
|
||||
`$CI_DEPLOY_FREEZE` if the currently executing job is within a
|
||||
Freeze Period.
|
||||
|
||||
To take advantage of this variable, create a `rules` entry in your
|
||||
|
@ -384,7 +387,7 @@ deploy_to_production:
|
|||
stage: deploy
|
||||
script: deploy_to_prod.sh
|
||||
rules:
|
||||
- if: $CI_ENVIRONMENT_FROZEN == null
|
||||
- if: $CI_DEPLOY_FREEZE == null
|
||||
```
|
||||
|
||||
<!-- ## Troubleshooting
|
||||
|
|
|
@ -47,7 +47,7 @@ and some of them generate keys for free.
|
|||
To take advantage of X.509 signing, you will need Git 2.19.0 or later. You can
|
||||
check your Git version with:
|
||||
|
||||
```sh
|
||||
```shell
|
||||
git --version
|
||||
```
|
||||
|
||||
|
@ -57,7 +57,7 @@ If you have the correct version, you can proceed to configure Git.
|
|||
|
||||
Configure Git to use your key for signing:
|
||||
|
||||
```sh
|
||||
```shell
|
||||
signingkey = $( gpgsm --list-secret-keys | egrep '(key usage|ID)' | grep -B 1 digitalSignature | awk '/ID/ {print $2}' )
|
||||
git config --global user.signingkey $signingkey
|
||||
git config --global gpg.format x509
|
||||
|
@ -71,7 +71,7 @@ installer or via `brew install smimesign` on MacOS.
|
|||
Get the ID of your certificate with `smimesign --list-keys` and set your
|
||||
signingkey `git config --global user.signingkey ID`, then configure X.509:
|
||||
|
||||
```sh
|
||||
```shell
|
||||
git config --global gpg.x509.program smimesign
|
||||
git config --global gpg.format x509
|
||||
```
|
||||
|
@ -83,7 +83,7 @@ can start signing your commits:
|
|||
|
||||
1. Commit like you used to, the only difference is the addition of the `-S` flag:
|
||||
|
||||
```sh
|
||||
```shell
|
||||
git commit -S -m "feat: x509 signed commits"
|
||||
```
|
||||
|
||||
|
@ -92,7 +92,7 @@ can start signing your commits:
|
|||
If you don't want to type the `-S` flag every time you commit, you can tell Git
|
||||
to sign your commits automatically:
|
||||
|
||||
```sh
|
||||
```shell
|
||||
git config --global commit.gpgsign true
|
||||
```
|
||||
|
||||
|
@ -100,7 +100,7 @@ git config --global commit.gpgsign true
|
|||
|
||||
To verify that a commit is signed, you can use the `--show-signature` flag:
|
||||
|
||||
```sh
|
||||
```shell
|
||||
git log --show-signature
|
||||
```
|
||||
|
||||
|
@ -111,7 +111,7 @@ can start signing your tags:
|
|||
|
||||
1. Tag like you used to, the only difference is the addition of the `-s` flag:
|
||||
|
||||
```sh
|
||||
```shell
|
||||
git tag -s v1.1.1 -m "My signed tag"
|
||||
```
|
||||
|
||||
|
@ -120,7 +120,7 @@ can start signing your tags:
|
|||
If you don't want to type the `-s` flag every time you tag, you can tell Git
|
||||
to sign your tags automatically:
|
||||
|
||||
```sh
|
||||
```shell
|
||||
git config --global tag.gpgsign true
|
||||
```
|
||||
|
||||
|
@ -128,6 +128,6 @@ git config --global tag.gpgsign true
|
|||
|
||||
To verify that a tag is signed, you can use the `--verify` flag:
|
||||
|
||||
```sh
|
||||
```shell
|
||||
git tag --verify v1.1.1
|
||||
```
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe Admin::Ci::VariablesController do
|
||||
let_it_be(:variable) { create(:ci_instance_variable) }
|
||||
|
||||
before do
|
||||
sign_in(user)
|
||||
end
|
||||
|
||||
describe 'GET #show' do
|
||||
subject do
|
||||
get :show, params: {}, format: :json
|
||||
end
|
||||
|
||||
context 'when signed in as admin' do
|
||||
let(:user) { create(:admin) }
|
||||
|
||||
include_examples 'GET #show lists all variables'
|
||||
end
|
||||
|
||||
context 'when signed in as regular user' do
|
||||
let(:user) { create(:user) }
|
||||
|
||||
it 'returns 404' do
|
||||
subject
|
||||
|
||||
expect(response).to have_gitlab_http_status(:not_found)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'PATCH #update' do
|
||||
subject do
|
||||
patch :update,
|
||||
params: {
|
||||
variables_attributes: variables_attributes
|
||||
},
|
||||
format: :json
|
||||
end
|
||||
|
||||
context 'when signed in as admin' do
|
||||
let(:user) { create(:admin) }
|
||||
|
||||
include_examples 'PATCH #update updates variables' do
|
||||
let(:variables_scope) { Ci::InstanceVariable.all }
|
||||
let(:file_variables_scope) { variables_scope.file }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when signed in as regular user' do
|
||||
let(:user) { create(:user) }
|
||||
|
||||
let(:variables_attributes) do
|
||||
[{
|
||||
id: variable.id,
|
||||
key: variable.key,
|
||||
secret_value: 'new value'
|
||||
}]
|
||||
end
|
||||
|
||||
it 'returns 404' do
|
||||
subject
|
||||
|
||||
expect(response).to have_gitlab_http_status(:not_found)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -111,26 +111,6 @@ RSpec.describe Release do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#notify_new_release' do
|
||||
context 'when a release is created' do
|
||||
it 'instantiates NewReleaseWorker to send notifications' do
|
||||
expect(NewReleaseWorker).to receive(:perform_async)
|
||||
|
||||
create(:release)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when a release is updated' do
|
||||
let!(:release) { create(:release) }
|
||||
|
||||
it 'does not send any new notification' do
|
||||
expect(NewReleaseWorker).not_to receive(:perform_async)
|
||||
|
||||
release.update!(description: 'new description')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#name' do
|
||||
context 'name is nil' do
|
||||
before do
|
||||
|
|
|
@ -0,0 +1,230 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe Ci::UpdateInstanceVariablesService do
|
||||
let(:params) { { variables_attributes: variables_attributes } }
|
||||
|
||||
subject { described_class.new(params) }
|
||||
|
||||
describe '#execute' do
|
||||
context 'without variables' do
|
||||
let(:variables_attributes) { [] }
|
||||
|
||||
it { expect(subject.execute).to be_truthy }
|
||||
end
|
||||
|
||||
context 'with insert only variables' do
|
||||
let(:variables_attributes) do
|
||||
[
|
||||
{ key: 'var_a', secret_value: 'dummy_value_for_a', protected: true },
|
||||
{ key: 'var_b', secret_value: 'dummy_value_for_b', protected: false }
|
||||
]
|
||||
end
|
||||
|
||||
it { expect(subject.execute).to be_truthy }
|
||||
|
||||
it 'persists all the records' do
|
||||
expect { subject.execute }
|
||||
.to change { Ci::InstanceVariable.count }
|
||||
.by variables_attributes.size
|
||||
end
|
||||
|
||||
it 'persists attributes' do
|
||||
subject.execute
|
||||
|
||||
expect(Ci::InstanceVariable.all).to contain_exactly(
|
||||
have_attributes(key: 'var_a', secret_value: 'dummy_value_for_a', protected: true),
|
||||
have_attributes(key: 'var_b', secret_value: 'dummy_value_for_b', protected: false)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with update only variables' do
|
||||
let!(:var_a) { create(:ci_instance_variable) }
|
||||
let!(:var_b) { create(:ci_instance_variable, protected: false) }
|
||||
|
||||
let(:variables_attributes) do
|
||||
[
|
||||
{
|
||||
id: var_a.id,
|
||||
key: var_a.key,
|
||||
secret_value: 'new_dummy_value_for_a',
|
||||
protected: var_a.protected?.to_s
|
||||
},
|
||||
{
|
||||
id: var_b.id,
|
||||
key: 'var_b_key',
|
||||
secret_value: 'new_dummy_value_for_b',
|
||||
protected: 'true'
|
||||
}
|
||||
]
|
||||
end
|
||||
|
||||
it { expect(subject.execute).to be_truthy }
|
||||
|
||||
it 'does not change the count' do
|
||||
expect { subject.execute }
|
||||
.not_to change { Ci::InstanceVariable.count }
|
||||
end
|
||||
|
||||
it 'updates the records in place', :aggregate_failures do
|
||||
subject.execute
|
||||
|
||||
expect(var_a.reload).to have_attributes(secret_value: 'new_dummy_value_for_a')
|
||||
|
||||
expect(var_b.reload).to have_attributes(
|
||||
key: 'var_b_key', secret_value: 'new_dummy_value_for_b', protected: true)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with insert and update variables' do
|
||||
let!(:var_a) { create(:ci_instance_variable) }
|
||||
|
||||
let(:variables_attributes) do
|
||||
[
|
||||
{
|
||||
id: var_a.id,
|
||||
key: var_a.key,
|
||||
secret_value: 'new_dummy_value_for_a',
|
||||
protected: var_a.protected?.to_s
|
||||
},
|
||||
{
|
||||
key: 'var_b',
|
||||
secret_value: 'dummy_value_for_b',
|
||||
protected: true
|
||||
}
|
||||
]
|
||||
end
|
||||
|
||||
it { expect(subject.execute).to be_truthy }
|
||||
|
||||
it 'inserts only one record' do
|
||||
expect { subject.execute }
|
||||
.to change { Ci::InstanceVariable.count }.by 1
|
||||
end
|
||||
|
||||
it 'persists all the records', :aggregate_failures do
|
||||
subject.execute
|
||||
var_b = Ci::InstanceVariable.find_by(key: 'var_b')
|
||||
|
||||
expect(var_a.reload.secret_value).to eq('new_dummy_value_for_a')
|
||||
expect(var_b.secret_value).to eq('dummy_value_for_b')
|
||||
end
|
||||
end
|
||||
|
||||
context 'with insert, update, and destroy variables' do
|
||||
let!(:var_a) { create(:ci_instance_variable) }
|
||||
let!(:var_b) { create(:ci_instance_variable) }
|
||||
|
||||
let(:variables_attributes) do
|
||||
[
|
||||
{
|
||||
id: var_a.id,
|
||||
key: var_a.key,
|
||||
secret_value: 'new_dummy_value_for_a',
|
||||
protected: var_a.protected?.to_s
|
||||
},
|
||||
{
|
||||
id: var_b.id,
|
||||
key: var_b.key,
|
||||
secret_value: 'dummy_value_for_b',
|
||||
protected: var_b.protected?.to_s,
|
||||
'_destroy' => 'true'
|
||||
},
|
||||
{
|
||||
key: 'var_c',
|
||||
secret_value: 'dummy_value_for_c',
|
||||
protected: true
|
||||
}
|
||||
]
|
||||
end
|
||||
|
||||
it { expect(subject.execute).to be_truthy }
|
||||
|
||||
it 'persists all the records', :aggregate_failures do
|
||||
subject.execute
|
||||
var_c = Ci::InstanceVariable.find_by(key: 'var_c')
|
||||
|
||||
expect(var_a.reload.secret_value).to eq('new_dummy_value_for_a')
|
||||
expect { var_b.reload }.to raise_error(ActiveRecord::RecordNotFound)
|
||||
expect(var_c.secret_value).to eq('dummy_value_for_c')
|
||||
end
|
||||
end
|
||||
|
||||
context 'with invalid variables' do
|
||||
let!(:var_a) { create(:ci_instance_variable, secret_value: 'dummy_value_for_a') }
|
||||
|
||||
let(:variables_attributes) do
|
||||
[
|
||||
{
|
||||
key: '...?',
|
||||
secret_value: 'nice_value'
|
||||
},
|
||||
{
|
||||
id: var_a.id,
|
||||
key: var_a.key,
|
||||
secret_value: 'new_dummy_value_for_a',
|
||||
protected: var_a.protected?.to_s
|
||||
},
|
||||
{
|
||||
key: var_a.key,
|
||||
secret_value: 'other_value'
|
||||
}
|
||||
]
|
||||
end
|
||||
|
||||
it { expect(subject.execute).to be_falsey }
|
||||
|
||||
it 'does not insert any records' do
|
||||
expect { subject.execute }
|
||||
.not_to change { Ci::InstanceVariable.count }
|
||||
end
|
||||
|
||||
it 'does not update existing records' do
|
||||
subject.execute
|
||||
|
||||
expect(var_a.reload.secret_value).to eq('dummy_value_for_a')
|
||||
end
|
||||
|
||||
it 'returns errors' do
|
||||
subject.execute
|
||||
|
||||
expect(subject.errors).to match_array(
|
||||
[
|
||||
"Key (#{var_a.key}) has already been taken",
|
||||
"Key can contain only letters, digits and '_'."
|
||||
])
|
||||
end
|
||||
end
|
||||
|
||||
context 'when deleting non existing variables' do
|
||||
let(:variables_attributes) do
|
||||
[
|
||||
{
|
||||
id: 'some-id',
|
||||
key: 'some_key',
|
||||
secret_value: 'other_value',
|
||||
'_destroy' => 'true'
|
||||
}
|
||||
]
|
||||
end
|
||||
|
||||
it { expect { subject.execute }.to raise_error(ActiveRecord::RecordNotFound) }
|
||||
end
|
||||
|
||||
context 'when updating non existing variables' do
|
||||
let(:variables_attributes) do
|
||||
[
|
||||
{
|
||||
id: 'some-id',
|
||||
key: 'some_key',
|
||||
secret_value: 'other_value'
|
||||
}
|
||||
]
|
||||
end
|
||||
|
||||
it { expect { subject.execute }.to raise_error(ActiveRecord::RecordNotFound) }
|
||||
end
|
||||
end
|
||||
end
|
|
@ -762,7 +762,7 @@ describe NotificationService, :mailer do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#send_new_release_notifications', :deliver_mails_inline, :sidekiq_inline do
|
||||
describe '#send_new_release_notifications', :deliver_mails_inline do
|
||||
context 'when recipients for a new release exist' do
|
||||
let(:release) { create(:release) }
|
||||
|
||||
|
@ -774,7 +774,7 @@ describe NotificationService, :mailer do
|
|||
recipient_2 = NotificationRecipient.new(user_2, :custom, custom_action: :new_release)
|
||||
allow(NotificationRecipients::BuildService).to receive(:build_new_release_recipients).and_return([recipient_1, recipient_2])
|
||||
|
||||
release
|
||||
notification.send_new_release_notifications(release)
|
||||
|
||||
should_email(user_1)
|
||||
should_email(user_2)
|
||||
|
|
|
@ -20,6 +20,8 @@ describe Releases::CreateService do
|
|||
describe '#execute' do
|
||||
shared_examples 'a successful release creation' do
|
||||
it 'creates a new release' do
|
||||
expected_job_count = MailScheduler::NotificationServiceWorker.jobs.size + 1
|
||||
|
||||
result = service.execute
|
||||
|
||||
expect(project.releases.count).to eq(1)
|
||||
|
@ -30,6 +32,7 @@ describe Releases::CreateService do
|
|||
expect(result[:release].name).to eq(name)
|
||||
expect(result[:release].author).to eq(user)
|
||||
expect(result[:release].sha).to eq(tag_sha)
|
||||
expect(MailScheduler::NotificationServiceWorker.jobs.size).to eq(expected_job_count)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -27,6 +27,9 @@ RSpec.shared_examples 'PATCH #update updates variables' do
|
|||
protected: 'false' }
|
||||
end
|
||||
|
||||
let(:variables_scope) { owner.variables }
|
||||
let(:file_variables_scope) { owner.variables.file }
|
||||
|
||||
context 'with invalid new variable parameters' do
|
||||
let(:variables_attributes) do
|
||||
[
|
||||
|
@ -40,7 +43,7 @@ RSpec.shared_examples 'PATCH #update updates variables' do
|
|||
end
|
||||
|
||||
it 'does not create the new variable' do
|
||||
expect { subject }.not_to change { owner.variables.count }
|
||||
expect { subject }.not_to change { variables_scope.count }
|
||||
end
|
||||
|
||||
it 'returns a bad request response' do
|
||||
|
@ -63,7 +66,7 @@ RSpec.shared_examples 'PATCH #update updates variables' do
|
|||
end
|
||||
|
||||
it 'does not create the new variable' do
|
||||
expect { subject }.not_to change { owner.variables.count }
|
||||
expect { subject }.not_to change { variables_scope.count }
|
||||
end
|
||||
|
||||
it 'returns a bad request response' do
|
||||
|
@ -86,7 +89,7 @@ RSpec.shared_examples 'PATCH #update updates variables' do
|
|||
end
|
||||
|
||||
it 'creates the new variable' do
|
||||
expect { subject }.to change { owner.variables.count }.by(1)
|
||||
expect { subject }.to change { variables_scope.count }.by(1)
|
||||
end
|
||||
|
||||
it 'returns a successful response' do
|
||||
|
@ -106,7 +109,7 @@ RSpec.shared_examples 'PATCH #update updates variables' do
|
|||
let(:variables_attributes) { [variable_attributes.merge(_destroy: 'true')] }
|
||||
|
||||
it 'destroys the variable' do
|
||||
expect { subject }.to change { owner.variables.count }.by(-1)
|
||||
expect { subject }.to change { variables_scope.count }.by(-1)
|
||||
expect { variable.reload }.to raise_error ActiveRecord::RecordNotFound
|
||||
end
|
||||
|
||||
|
@ -123,6 +126,18 @@ RSpec.shared_examples 'PATCH #update updates variables' do
|
|||
end
|
||||
end
|
||||
|
||||
context 'with missing variable' do
|
||||
let(:variables_attributes) do
|
||||
[variable_attributes.merge(_destroy: 'true', id: 'some-id')]
|
||||
end
|
||||
|
||||
it 'returns not found response' do
|
||||
subject
|
||||
|
||||
expect(response).to have_gitlab_http_status(:not_found)
|
||||
end
|
||||
end
|
||||
|
||||
context 'for variables of type file' do
|
||||
let(:variables_attributes) do
|
||||
[
|
||||
|
@ -131,7 +146,7 @@ RSpec.shared_examples 'PATCH #update updates variables' do
|
|||
end
|
||||
|
||||
it 'creates new variable of type file' do
|
||||
expect { subject }.to change { owner.variables.file.count }.by(1)
|
||||
expect { subject }.to change { file_variables_scope.count }.by(1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# TODO: Worker can be removed in 13.2:
|
||||
# https://gitlab.com/gitlab-org/gitlab/-/issues/218231
|
||||
require 'spec_helper'
|
||||
|
||||
describe NewReleaseWorker do
|
||||
|
|
Loading…
Reference in New Issue