Commit 7bc6b3ba authored by GitLab Bot's avatar GitLab Bot

Automatic merge of gitlab-org/gitlab master

parents a9f87077 1711cbd5
c35fba1c073deed91d1a1f9f11dd668856841d80
1e442ff0382ed147e7bc4682cd9c278a56163a42
......@@ -5,6 +5,9 @@ class Projects::BuildsController < Projects::ApplicationController
feature_category :continuous_integration
urgency :high, [:index, :show]
urgency :low, [:raw]
def index
redirect_to project_jobs_path(project)
end
......
......@@ -4,6 +4,8 @@ class Projects::JobsController < Projects::ApplicationController
include SendFileUpload
include ContinueParams
urgency :low, [:index, :show, :trace, :retry, :play, :cancel, :unschedule, :status, :erase, :raw]
before_action :find_job_as_build, except: [:index, :play, :show]
before_action :find_job_as_processable, only: [:play, :show]
before_action :authorize_read_build_trace!, only: [:trace, :raw]
......
......@@ -87,7 +87,8 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
:ci_environments_status,
:destroy,
:rebase,
:discussions
:discussions,
:pipelines
]
def index
......
......@@ -5,6 +5,10 @@ module Projects
class StagesController < Projects::Pipelines::ApplicationController
before_action :authorize_update_pipeline!
urgency :low, [
:play_manual
]
def play_manual
::Ci::PlayManualStageService
.new(@project, current_user, pipeline: pipeline)
......
......@@ -4,6 +4,9 @@ class Projects::PipelinesController < Projects::ApplicationController
include ::Gitlab::Utils::StrongMemoize
include RedisTracking
urgency :default, [:status]
urgency :low, [:index, :new, :builds, :show, :failures, :create, :stage, :retry, :dag, :cancel]
before_action :disable_query_limiting, only: [:create, :retry]
before_action :pipeline, except: [:index, :new, :create, :charts, :config_variables]
before_action :set_pipeline_path, only: [:show]
......
......@@ -7,4 +7,12 @@ class WorkItem < Issue
def noteable_target_type_name
'issue'
end
private
def record_create_action
super
Gitlab::UsageDataCounters::WorkItemActivityUniqueCounter.track_work_item_created_action(author: author)
end
end
......@@ -31,51 +31,47 @@
%p
= _('You can also upload existing files from your computer using the instructions below.')
.git-empty.js-git-empty
%fieldset
%h5= _('Git global setup')
%pre.bg-light
:preserve
git config --global user.name "#{h git_user_name}"
git config --global user.email "#{h git_user_email}"
%h5= _('Git global setup')
%pre.bg-light
:preserve
git config --global user.name "#{h git_user_name}"
git config --global user.email "#{h git_user_email}"
%fieldset
%h5= _('Create a new repository')
%pre.bg-light
:preserve
git clone #{ content_tag(:span, default_url_to_repo, class: 'js-clone')}
cd #{h @project.path}
git switch -c #{h default_branch_name}
touch README.md
git add README.md
git commit -m "add README"
- if @project.can_current_user_push_to_default_branch?
%span><
git push -u origin #{h default_branch_name }
%h5= _('Create a new repository')
%pre.bg-light
:preserve
git clone #{ content_tag(:span, default_url_to_repo, class: 'js-clone')}
cd #{h @project.path}
git switch -c #{h default_branch_name}
touch README.md
git add README.md
git commit -m "add README"
- if @project.can_current_user_push_to_default_branch?
%span><
git push -u origin #{h default_branch_name }
%fieldset
%h5= _('Push an existing folder')
%pre.bg-light
:preserve
cd existing_folder
git init --initial-branch=#{h default_branch_name}
git remote add origin #{ content_tag(:span, default_url_to_repo, class: 'js-clone')}
git add .
git commit -m "Initial commit"
- if @project.can_current_user_push_to_default_branch?
%span><
git push -u origin #{h default_branch_name }
%h5= _('Push an existing folder')
%pre.bg-light
:preserve
cd existing_folder
git init --initial-branch=#{h default_branch_name}
git remote add origin #{ content_tag(:span, default_url_to_repo, class: 'js-clone')}
git add .
git commit -m "Initial commit"
- if @project.can_current_user_push_to_default_branch?
%span><
git push -u origin #{h default_branch_name }
%fieldset
%h5= _('Push an existing Git repository')
%pre.bg-light
:preserve
cd existing_repo
git remote rename origin old-origin
git remote add origin #{ content_tag(:span, default_url_to_repo, class: 'js-clone')}
- if @project.can_current_user_push_to_default_branch?
%span><
git push -u origin --all
git push -u origin --tags
%h5= _('Push an existing Git repository')
%pre.bg-light
:preserve
cd existing_repo
git remote rename origin old-origin
git remote add origin #{ content_tag(:span, default_url_to_repo, class: 'js-clone')}
- if @project.can_current_user_push_to_default_branch?
%span><
git push -u origin --all
git push -u origin --tags
- if @project.upload_anchor_data.present?
= render 'projects/blob/upload', title: _('Upload New File'), placeholder: _('Upload New File'), button_title: _('Upload file'), form_path: project_create_blob_path(@project, default_branch_name), ref: default_branch_name, method: :post
---
key_path: redis_hll_counters.work_items.users_creating_work_items_monthly
description: Unique users creating work items
product_category: team planning
product_section: dev
product_stage: plan
product_group: group::project management
value_type: number
status: active
milestone: '14.9'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81201
time_frame: 28d
data_source: redis_hll
data_category: optional
instrumentation_class: RedisHLLMetric
options:
events:
- users_creating_work_items
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate
---
key_path: redis_hll_counters.work_items.users_creating_work_items_weekly
description: Unique users creating work items
product_category: team planning
product_section: dev
product_stage: plan
product_group: group::project management
value_type: number
status: active
milestone: '14.9'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81201
time_frame: 7d
data_source: redis_hll
data_category: optional
instrumentation_class: RedisHLLMetric
options:
events:
- users_creating_work_items
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate
......@@ -7,7 +7,8 @@ type: reference, api
# Group wikis API **(PREMIUM)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/212199) in GitLab 13.5.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/212199) in GitLab 13.5.
> - The `encoding` field was [added](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81150) in GitLab 14.9.
The [group wikis](../user/project/wiki/group.md) API is available only in APIv4.
An API for [project wikis](wikis.md) is also available.
......@@ -37,18 +38,21 @@ Example response:
"content" : "Here is an instruction how to deploy this project.",
"format" : "markdown",
"slug" : "deploy",
"title" : "deploy"
"title" : "deploy",
"encoding": "UTF-8"
},
{
"content" : "Our development process is described here.",
"format" : "markdown",
"slug" : "development",
"title" : "development"
"title" : "development",
"encoding": "UTF-8"
},{
"content" : "* [Deploy](deploy)\n* [Development](development)",
"format" : "markdown",
"slug" : "home",
"title" : "home"
"title" : "home",
"encoding": "UTF-8"
}
]
```
......@@ -77,7 +81,8 @@ Example response:
"content" : "home page",
"format" : "markdown",
"slug" : "home",
"title" : "home"
"title" : "home",
"encoding": "UTF-8"
}
```
......@@ -109,7 +114,8 @@ Example response:
"content" : "Hello world",
"format" : "markdown",
"slug" : "Hello",
"title" : "Hello"
"title" : "Hello",
"encoding": "UTF-8"
}
```
......@@ -142,7 +148,8 @@ Example response:
"content" : "documentation",
"format" : "markdown",
"slug" : "Docs",
"title" : "Docs"
"title" : "Docs",
"encoding": "UTF-8"
}
```
......
......@@ -6,6 +6,8 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Project wikis API **(FREE)**
> The `encoding` field was [added](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81150) in GitLab 14.9.
The project [wikis](../user/project/wiki/index.md) API is available only in APIv4.
An API for [group wikis](group_wikis.md) is also available.
......@@ -34,18 +36,21 @@ Example response:
"content" : "Here is an instruction how to deploy this project.",
"format" : "markdown",
"slug" : "deploy",
"title" : "deploy"
"title" : "deploy",
"encoding": "UTF-8"
},
{
"content" : "Our development process is described here.",
"format" : "markdown",
"slug" : "development",
"title" : "development"
"title" : "development",
"encoding": "UTF-8"
},{
"content" : "* [Deploy](deploy)\n* [Development](development)",
"format" : "markdown",
"slug" : "home",
"title" : "home"
"title" : "home",
"encoding": "UTF-8"
}
]
```
......@@ -74,7 +79,8 @@ Example response:
"content" : "home page",
"format" : "markdown",
"slug" : "home",
"title" : "home"
"title" : "home",
"encoding": "UTF-8"
}
```
......@@ -105,7 +111,8 @@ Example response:
"content" : "Hello world",
"format" : "markdown",
"slug" : "Hello",
"title" : "Hello"
"title" : "Hello",
"encoding": "UTF-8"
}
```
......@@ -137,7 +144,8 @@ Example response:
"content" : "documentation",
"format" : "markdown",
"slug" : "Docs",
"title" : "Docs"
"title" : "Docs",
"encoding": "UTF-8"
}
```
......
......@@ -21,7 +21,7 @@ RSpec.describe API::Wikis do
let(:group) { create(:group, :internal, :wiki_repo) }
let(:wiki) { create(:group_wiki, container: group, user: user) }
let(:payload) { { content: 'content', format: 'rdoc', title: 'title' } }
let(:expected_keys_with_content) { %w(content format slug title) }
let(:expected_keys_with_content) { %w(content format slug title encoding) }
let(:expected_keys_without_content) { %w(format slug title) }
before do
......
......@@ -38,7 +38,7 @@ module API
use :pagination
end
# rubocop: disable CodeReuse/ActiveRecord
get ':id/jobs', feature_category: :continuous_integration do
get ':id/jobs', urgency: :low, feature_category: :continuous_integration do
authorize_read_builds!
builds = user_project.builds.order('id DESC')
......@@ -55,7 +55,7 @@ module API
params do
requires :job_id, type: Integer, desc: 'The ID of a job'
end
get ':id/jobs/:job_id', feature_category: :continuous_integration do
get ':id/jobs/:job_id', urgency: :low, feature_category: :continuous_integration do
authorize_read_builds!
build = find_build!(params[:job_id])
......@@ -70,7 +70,7 @@ module API
params do
requires :job_id, type: Integer, desc: 'The ID of a job'
end
get ':id/jobs/:job_id/trace', feature_category: :continuous_integration do
get ':id/jobs/:job_id/trace', urgency: :low, feature_category: :continuous_integration do
authorize_read_builds!
build = find_build!(params[:job_id])
......@@ -92,7 +92,7 @@ module API
params do
requires :job_id, type: Integer, desc: 'The ID of a job'
end
post ':id/jobs/:job_id/cancel', feature_category: :continuous_integration do
post ':id/jobs/:job_id/cancel', urgency: :low, feature_category: :continuous_integration do
authorize_update_builds!
build = find_build!(params[:job_id])
......@@ -109,7 +109,7 @@ module API
params do
requires :job_id, type: Integer, desc: 'The ID of a build'
end
post ':id/jobs/:job_id/retry', feature_category: :continuous_integration do
post ':id/jobs/:job_id/retry', urgency: :low, feature_category: :continuous_integration do
authorize_update_builds!
build = find_build!(params[:job_id])
......@@ -127,7 +127,7 @@ module API
params do
requires :job_id, type: Integer, desc: 'The ID of a build'
end
post ':id/jobs/:job_id/erase', feature_category: :continuous_integration do
post ':id/jobs/:job_id/erase', urgency: :low, feature_category: :continuous_integration do
authorize_update_builds!
build = find_build!(params[:job_id])
......@@ -146,7 +146,7 @@ module API
requires :job_id, type: Integer, desc: 'The ID of a Job'
end
post ":id/jobs/:job_id/play", feature_category: :continuous_integration do
post ':id/jobs/:job_id/play', urgency: :low, feature_category: :continuous_integration do
authorize_read_builds!
job = find_job!(params[:job_id])
......@@ -168,11 +168,11 @@ module API
end
resource :job do
desc 'Get current project using job token' do
desc 'Get current job using job token' do
success Entities::Ci::Job
end
route_setting :authentication, job_token_allowed: true
get '', feature_category: :continuous_integration do
get '', feature_category: :continuous_integration, urgency: :low do
validate_current_authenticated_job
present current_authenticated_job, with: Entities::Ci::Job
......
......@@ -123,7 +123,7 @@ module API
use :pagination
end
get ':id/pipelines/:pipeline_id/jobs', feature_category: :continuous_integration do
get ':id/pipelines/:pipeline_id/jobs', urgency: :low, feature_category: :continuous_integration do
authorize!(:read_pipeline, user_project)
pipeline = user_project.all_pipelines.find(params[:pipeline_id])
......
......@@ -131,7 +131,7 @@ module API
formatter :build_json, ->(object, _) { object }
parser :build_json, ::Grape::Parser::Json
post '/request', feature_category: :continuous_integration do
post '/request', urgency: :low, feature_category: :continuous_integration do
authenticate_runner!
unless current_runner.active?
......@@ -185,7 +185,7 @@ module API
end
optional :exit_code, type: Integer, desc: %q(Job's exit code)
end
put '/:id', feature_category: :continuous_integration do
put '/:id', urgency: :low, feature_category: :continuous_integration do
job = authenticate_job!(heartbeat_runner: true)
Gitlab::Metrics.add_event(:update_build)
......@@ -212,7 +212,7 @@ module API
requires :id, type: Integer, desc: %q(Job's ID)
optional :token, type: String, desc: %q(Job's authentication token)
end
patch '/:id/trace', feature_category: :continuous_integration do
patch '/:id/trace', urgency: :default, feature_category: :continuous_integration do
job = authenticate_job!(heartbeat_runner: true)
error!('400 Missing header Content-Range', 400) unless request.headers.key?('Content-Range')
......
......@@ -4,6 +4,10 @@ module API
module Entities
class WikiPage < WikiPageBasic
expose :content
expose :encoding do |wiki_page|
wiki_page.content.encoding.name
end
end
end
end
......@@ -4,3 +4,8 @@
redis_slot: users
aggregation: weekly
feature_flag: track_work_items_activity
- name: users_creating_work_items
category: work_items
redis_slot: users
aggregation: weekly
feature_flag: track_work_items_activity
......@@ -3,9 +3,14 @@
module Gitlab
module UsageDataCounters
module WorkItemActivityUniqueCounter
WORK_ITEM_CREATED = 'users_creating_work_items'
WORK_ITEM_TITLE_CHANGED = 'users_updating_work_item_title'
class << self
def track_work_item_created_action(author:)
track_unique_action(WORK_ITEM_CREATED, author)
end
def track_work_item_title_changed_action(author:)
track_unique_action(WORK_ITEM_TITLE_CHANGED, author)
end
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe API::Entities::WikiPage do
let_it_be_with_reload(:wiki_page) { create(:wiki_page) }
let(:entity) { described_class.new(wiki_page) }
it 'returns the proper encoding for the wiki page content' do
expect(entity.as_json[:encoding]).to eq 'UTF-8'
wiki_page.update_attributes(content: 'new_content'.encode('ISO-8859-1')) # rubocop:disable Rails/ActiveRecordAliases, Rails/SaveBang
expect(entity.as_json[:encoding]).to eq 'ISO-8859-1'
end
end
......@@ -17,16 +17,12 @@ RSpec.describe Gitlab::UsageDataCounters::WorkItemActivityUniqueCounter, :clean_
end
end
describe '.track_work_item_title_changed_action' do
subject(:track_event) { described_class.track_work_item_title_changed_action(author: user) }
let(:event_name) { described_class::WORK_ITEM_TITLE_CHANGED }
shared_examples 'work item unique counter' do
context 'when track_work_items_activity FF is enabled' do
it 'tracks a unique event only once' do
expect { 3.times { track_event } }.to change {
Gitlab::UsageDataCounters::HLLRedisCounter.unique_events(
event_names: described_class::WORK_ITEM_TITLE_CHANGED,
event_names: event_name,
start_date: 2.weeks.ago,
end_date: 2.weeks.from_now
)
......@@ -48,4 +44,20 @@ RSpec.describe Gitlab::UsageDataCounters::WorkItemActivityUniqueCounter, :clean_
it_behaves_like 'counter that does not track the event'
end
end
describe '.track_work_item_created_action' do
subject(:track_event) { described_class.track_work_item_created_action(author: user) }
let(:event_name) { described_class::WORK_ITEM_CREATED }
it_behaves_like 'work item unique counter'
end
describe '.track_work_item_title_changed_action' do
subject(:track_event) { described_class.track_work_item_title_changed_action(author: user) }
let(:event_name) { described_class::WORK_ITEM_TITLE_CHANGED }
it_behaves_like 'work item unique counter'
end
end
......@@ -10,4 +10,16 @@ RSpec.describe WorkItem do
expect(work_item.noteable_target_type_name).to eq('issue')
end
end
describe 'callbacks' do
describe 'record_create_action' do
it 'records the creation action after saving' do
expect(Gitlab::UsageDataCounters::WorkItemActivityUniqueCounter).to receive(:track_work_item_created_action)
# During the work item transition we also want to track work items as issues
expect(Gitlab::UsageDataCounters::IssueActivityUniqueCounter).to receive(:track_issue_created_action)
create(:work_item)
end
end
end
end
......@@ -31,7 +31,7 @@ RSpec.describe API::Wikis do
let(:project_wiki) { create(:project_wiki, project: project, user: user) }
let(:payload) { { content: 'content', format: 'rdoc', title: 'title' } }
let(:expected_keys_with_content) { %w(content format slug title) }
let(:expected_keys_with_content) { %w(content format slug title encoding) }
let(:expected_keys_without_content) { %w(format slug title) }
let(:wiki) { project_wiki }
......
......@@ -46,11 +46,12 @@ end
RSpec.shared_examples_for 'wikis API returns wiki page' do
it 'returns the wiki page' do
expect(response).to have_gitlab_http_status(:ok)
expect(json_response.size).to eq(4)
expect(json_response.size).to eq(5)
expect(json_response.keys).to match_array(expected_keys_with_content)
expect(json_response['content']).to eq(page.content)
expect(json_response['slug']).to eq(page.slug)
expect(json_response['title']).to eq(page.title)
expect(json_response['encoding']).to eq('UTF-8')
end
end
......@@ -59,12 +60,13 @@ RSpec.shared_examples_for 'wikis API creates wiki page' do
post(api(url, user), params: payload)
expect(response).to have_gitlab_http_status(:created)
expect(json_response.size).to eq(4)
expect(json_response.size).to eq(5)
expect(json_response.keys).to match_array(expected_keys_with_content)
expect(json_response['content']).to eq(payload[:content])
expect(json_response['slug']).to eq(payload[:title].tr(' ', '-'))
expect(json_response['title']).to eq(payload[:title])
expect(json_response['rdoc']).to eq(payload[:rdoc])
expect(json_response['encoding']).to eq('UTF-8')
end
[:title, :content].each do |part|
......@@ -85,7 +87,7 @@ RSpec.shared_examples_for 'wikis API updates wiki page' do
put(api(url, user), params: payload)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response.size).to eq(4)
expect(json_response.size).to eq(5)
expect(json_response.keys).to match_array(expected_keys_with_content)
expect(json_response['content']).to eq(payload[:content])
expect(json_response['slug']).to eq(payload[:title].tr(' ', '-'))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment