mirror of
https://gitlab.com/gitlab-org/gitlab-foss.git
synced 2025-08-15 21:39:00 +00:00
Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
@ -1 +1 @@
|
||||
3.2.3
|
||||
3.2.4
|
||||
|
@ -61,14 +61,24 @@ class Projects::TreeController < Projects::ApplicationController
|
||||
end
|
||||
|
||||
def assign_dir_vars
|
||||
@branch_name = params[:branch_name]
|
||||
params.require(create_dir_params_attributes)
|
||||
|
||||
@dir_name = File.join(@path, params[:dir_name])
|
||||
@branch_name = permitted_params[:branch_name]
|
||||
|
||||
@dir_name = File.join(@path, permitted_params[:dir_name])
|
||||
@commit_params = {
|
||||
file_path: @dir_name,
|
||||
commit_message: params[:commit_message]
|
||||
commit_message: permitted_params[:commit_message]
|
||||
}
|
||||
end
|
||||
|
||||
def permitted_params
|
||||
params.permit(*create_dir_params_attributes)
|
||||
end
|
||||
|
||||
def create_dir_params_attributes
|
||||
[:branch_name, :dir_name, :commit_message]
|
||||
end
|
||||
end
|
||||
|
||||
Projects::TreeController.prepend_mod
|
||||
|
@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/433324
|
||||
milestone: '16.7'
|
||||
type: development
|
||||
group: group::ide
|
||||
default_enabled: true
|
||||
default_enabled: false
|
||||
|
@ -0,0 +1,39 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class UpdatePostgresSequencesView < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.3'
|
||||
|
||||
def up
|
||||
execute(<<~SQL)
|
||||
CREATE OR REPLACE VIEW postgres_sequences
|
||||
AS
|
||||
SELECT seq_pg_class.relname AS seq_name,
|
||||
dep_pg_class.relname AS table_name,
|
||||
pg_attribute.attname AS col_name
|
||||
FROM pg_class seq_pg_class
|
||||
INNER JOIN pg_depend ON seq_pg_class.oid = pg_depend.objid
|
||||
INNER JOIN pg_class dep_pg_class ON pg_depend.refobjid = dep_pg_class.oid
|
||||
INNER JOIN pg_attribute ON dep_pg_class.oid = pg_attribute.attrelid
|
||||
AND pg_depend.refobjsubid = pg_attribute.attnum
|
||||
WHERE pg_depend.classid = 'pg_class'::regclass
|
||||
AND pg_depend.refclassid = 'pg_class'::regclass
|
||||
AND seq_pg_class.relkind = 'S'
|
||||
SQL
|
||||
end
|
||||
|
||||
def down
|
||||
execute(<<~SQL)
|
||||
CREATE OR REPLACE VIEW postgres_sequences
|
||||
AS
|
||||
SELECT seq_pg_class.relname AS seq_name,
|
||||
dep_pg_class.relname AS table_name,
|
||||
pg_attribute.attname AS col_name
|
||||
FROM pg_class seq_pg_class
|
||||
INNER JOIN pg_depend ON seq_pg_class.oid = pg_depend.objid
|
||||
INNER JOIN pg_class dep_pg_class ON pg_depend.refobjid = dep_pg_class.oid
|
||||
INNER JOIN pg_attribute ON dep_pg_class.oid = pg_attribute.attrelid
|
||||
AND pg_depend.refobjsubid = pg_attribute.attnum
|
||||
WHERE seq_pg_class.relkind = 'S'
|
||||
SQL
|
||||
end
|
||||
end
|
1
db/schema_migrations/20240724101535
Normal file
1
db/schema_migrations/20240724101535
Normal file
@ -0,0 +1 @@
|
||||
7d2eb2f8ca8038d63668edae062438c319e5f06fe1dc0c2bb6be67c16a24d2be
|
@ -15638,7 +15638,7 @@ CREATE VIEW postgres_sequences AS
|
||||
JOIN pg_depend ON ((seq_pg_class.oid = pg_depend.objid)))
|
||||
JOIN pg_class dep_pg_class ON ((pg_depend.refobjid = dep_pg_class.oid)))
|
||||
JOIN pg_attribute ON (((dep_pg_class.oid = pg_attribute.attrelid) AND (pg_depend.refobjsubid = pg_attribute.attnum))))
|
||||
WHERE (seq_pg_class.relkind = 'S'::"char");
|
||||
WHERE ((pg_depend.classid = ('pg_class'::regclass)::oid) AND (pg_depend.refclassid = ('pg_class'::regclass)::oid) AND (seq_pg_class.relkind = 'S'::"char"));
|
||||
|
||||
CREATE TABLE programming_languages (
|
||||
id integer NOT NULL,
|
||||
|
@ -184,7 +184,7 @@ the Gitaly CLI is used to:
|
||||
- Validate Gitaly configuration files.
|
||||
- Verify the internal Gitaly API is accessible.
|
||||
|
||||
For more information on the other subcommands, run `gitaly --help`.
|
||||
For more information on the other subcommands, run `/opt/gitlab/embedded/bin/gitaly --help`.
|
||||
|
||||
### Backing up repositories
|
||||
|
||||
|
@ -27,7 +27,7 @@ Scan execution policies are enforced for all applicable projects. For projects w
|
||||
static analysis, or other scanners that do not require a build in the project, are still able to
|
||||
run and be enforced.
|
||||
|
||||
This feature has some overlap with [compliance framework pipelines](../../group/compliance_pipelines.md),
|
||||
This feature has some overlap with [compliance pipelines](../../group/compliance_pipelines.md),
|
||||
as we have not [unified the user experience for these two features](https://gitlab.com/groups/gitlab-org/-/epics/7312).
|
||||
For details on the similarities and differences between these features, see
|
||||
[Enforce scan execution](../index.md#enforce-scan-execution).
|
||||
@ -295,7 +295,7 @@ projects in the group.
|
||||
|
||||
You can refine a security policy's scope to:
|
||||
|
||||
- _Include_ only projects containing a compliance framework label.
|
||||
- _Include_ only projects applied with a [compliance framework](../../group/compliance_frameworks.md).
|
||||
- _Include_ or _exclude_ selected projects from enforcement.
|
||||
|
||||
### Policy scope schema
|
||||
|
@ -20284,6 +20284,9 @@ msgstr ""
|
||||
msgid "Enabled OAuth authentication sources"
|
||||
msgstr ""
|
||||
|
||||
msgid "Enables a free GitLab Ultimate trial when you create a new project."
|
||||
msgstr ""
|
||||
|
||||
msgid "End Time"
|
||||
msgstr ""
|
||||
|
||||
@ -30274,7 +30277,7 @@ msgstr ""
|
||||
msgid "Join a project"
|
||||
msgstr ""
|
||||
|
||||
msgid "Join your team on GitLab and contribute to an existing project"
|
||||
msgid "Join your team on GitLab and contribute to an existing project."
|
||||
msgstr ""
|
||||
|
||||
msgid "Joined %{user_created_time}"
|
||||
|
@ -60,7 +60,8 @@ FROM base AS gitlab-gems
|
||||
COPY --chown=gdk:gdk Gemfile Gemfile.lock .tool-versions ./gitlab/
|
||||
COPY --chown=gdk:gdk vendor/gems/ ./gitlab/vendor/gems/
|
||||
COPY --chown=gdk:gdk gems/ ./gitlab/gems/
|
||||
RUN make .gitlab-bundle \
|
||||
RUN make gitlab-asdf-install \
|
||||
&& make .gitlab-bundle \
|
||||
&& cd gitlab \
|
||||
&& rm -rf /home/gdk/.asdf/installs/ruby/*/lib/ruby/gems/*/cache
|
||||
|
||||
|
@ -1,81 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'parser/current'
|
||||
require 'json'
|
||||
|
||||
load 'gems/gitlab-utils/lib/gitlab/version_info.rb'
|
||||
load 'lib/gitlab/database/migrations/version.rb'
|
||||
|
||||
# We need this as Gitlab::VersionInfo depends on #present?
|
||||
class Object
|
||||
def blank?
|
||||
respond_to?(:empty?) ? !!empty? : !self
|
||||
end
|
||||
|
||||
def present?
|
||||
!blank?
|
||||
end
|
||||
end
|
||||
|
||||
def evaluate_node(ast)
|
||||
return unless ast.is_a?(Parser::AST::Node)
|
||||
|
||||
if ast.type == :send
|
||||
_, method, *args = ast.children
|
||||
return args.first.children.first if method == :milestone && args.any?
|
||||
else
|
||||
ast.children.each do |child|
|
||||
result = evaluate_node(child)
|
||||
return result if result
|
||||
end
|
||||
end
|
||||
|
||||
nil
|
||||
end
|
||||
|
||||
def find_milestone(filename)
|
||||
code = File.read(filename)
|
||||
ast = Parser::CurrentRuby.parse(code)
|
||||
evaluate_node(ast)
|
||||
end
|
||||
|
||||
def grep_timestamp(filename)
|
||||
File.basename(filename).match(/(?<timestamp>\d+)_.*\.rb/)[:timestamp].to_i
|
||||
end
|
||||
|
||||
def grep_type(filename)
|
||||
filename.include?('/post_migrate/') ? :post : :regular
|
||||
end
|
||||
|
||||
def version_from_file(filename)
|
||||
timestamp = grep_timestamp(filename)
|
||||
milestone = find_milestone(filename)
|
||||
if milestone.present?
|
||||
type = grep_type(filename)
|
||||
|
||||
Gitlab::Database::Migrations::Version.new(timestamp, milestone, type)
|
||||
else
|
||||
timestamp
|
||||
end
|
||||
end
|
||||
|
||||
codebase_versions = Dir['db/migrate/*.rb', 'db/post_migrate/*.rb'].map do |filename|
|
||||
version_from_file(filename)
|
||||
end.sort.reverse
|
||||
|
||||
geo_codebase_versions = Dir['ee/db/geo/migrate/*.rb', 'ee/db/geo/post_migrate/*.rb'].map do |filename|
|
||||
version_from_file(filename)
|
||||
end.sort.reverse
|
||||
|
||||
result = {
|
||||
migrations: {
|
||||
regular: codebase_versions.find { |v| v.is_a?(Gitlab::Database::Migrations::Version) && v.type == :regular },
|
||||
all: codebase_versions.first
|
||||
},
|
||||
geo_migrations: {
|
||||
regular: geo_codebase_versions.find { |v| v.is_a?(Gitlab::Database::Migrations::Version) && v.type == :regular },
|
||||
all: geo_codebase_versions.first
|
||||
}
|
||||
}
|
||||
|
||||
print(result.to_json)
|
@ -209,12 +209,11 @@ RSpec.describe Projects::TreeController, feature_category: :source_code_manageme
|
||||
end
|
||||
|
||||
describe '#create_dir' do
|
||||
subject(:create_dir) { post :create_dir, params: params }
|
||||
|
||||
let(:create_merge_request) { nil }
|
||||
|
||||
render_views
|
||||
|
||||
before do
|
||||
post :create_dir, params: {
|
||||
let(:params) do
|
||||
{
|
||||
namespace_id: project.namespace.to_param,
|
||||
project_id: project,
|
||||
id: 'master',
|
||||
@ -225,6 +224,8 @@ RSpec.describe Projects::TreeController, feature_category: :source_code_manageme
|
||||
}
|
||||
end
|
||||
|
||||
render_views
|
||||
|
||||
context 'successful creation' do
|
||||
let(:path) { 'files/new_dir' }
|
||||
let(:branch_name) { "main-test-#{SecureRandom.hex}" }
|
||||
@ -233,7 +234,7 @@ RSpec.describe Projects::TreeController, feature_category: :source_code_manageme
|
||||
let(:create_merge_request) { 'false' }
|
||||
|
||||
it 'redirects to the new directory' do
|
||||
expect(subject)
|
||||
expect(create_dir)
|
||||
.to redirect_to("/#{project.full_path}/-/tree/#{branch_name}/#{path}")
|
||||
expect(flash[:notice]).to eq('The directory has been successfully created.')
|
||||
end
|
||||
@ -242,7 +243,7 @@ RSpec.describe Projects::TreeController, feature_category: :source_code_manageme
|
||||
context 'when creating a new MR' do
|
||||
shared_examples 'a new MR from branch redirection' do
|
||||
it 'redirects to the new MR page' do
|
||||
expect(subject)
|
||||
expect(create_dir)
|
||||
.to redirect_to("/#{project.full_path}/-/merge_requests/new?merge_request%5Bsource_branch%5D=#{branch_name}&merge_request%5Btarget_branch%5D=master&merge_request%5Btarget_project_id%5D=#{project.id}")
|
||||
expect(flash[:notice]).to eq('The directory has been successfully created. You can now submit a merge request to get this change into the original branch.')
|
||||
end
|
||||
@ -279,10 +280,28 @@ RSpec.describe Projects::TreeController, feature_category: :source_code_manageme
|
||||
let(:branch_name) { 'master' }
|
||||
|
||||
it 'does not allow overwriting of existing files' do
|
||||
expect(subject)
|
||||
expect(create_dir)
|
||||
.to redirect_to("/#{project.full_path}/-/tree/master")
|
||||
expect(flash[:alert]).to eq('A file with this name already exists')
|
||||
end
|
||||
|
||||
[:branch_name, :dir_name, :commit_message].each do |required_param|
|
||||
context "when #{required_param} is missing" do
|
||||
let(:params) { super().except(required_param) }
|
||||
|
||||
it 'raises a missing parameter exception' do
|
||||
expect { create_dir }.to raise_error(ActionController::ParameterMissing)
|
||||
end
|
||||
end
|
||||
|
||||
context "when #{required_param} is empty" do
|
||||
let(:params) { super().merge(required_param => nil) }
|
||||
|
||||
it 'raises a missing parameter exception' do
|
||||
expect { create_dir }.to raise_error(ActionController::ParameterMissing)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -6,25 +6,27 @@ RSpec.describe 'Triggers', :js, feature_category: :continuous_integration do
|
||||
include Spec::Support::Helpers::ModalHelpers
|
||||
|
||||
let(:trigger_title) { 'trigger desc' }
|
||||
let(:user) { create(:user) }
|
||||
let(:user2) { create(:user) }
|
||||
let(:guest_user) { create(:user) }
|
||||
let_it_be(:user) { create(:user) }
|
||||
let_it_be(:user2) { create(:user) }
|
||||
let_it_be(:guest_user) { create(:user) }
|
||||
let_it_be(:project) { create(:project) }
|
||||
|
||||
before do
|
||||
sign_in(user)
|
||||
|
||||
@project = create(:project)
|
||||
@project.add_maintainer(user)
|
||||
@project.add_maintainer(user2)
|
||||
@project.add_guest(guest_user)
|
||||
|
||||
visit project_settings_ci_cd_path(@project)
|
||||
|
||||
wait_for_requests
|
||||
before_all do
|
||||
project.add_maintainer(user)
|
||||
project.add_maintainer(user2)
|
||||
project.add_guest(guest_user)
|
||||
end
|
||||
|
||||
describe 'triggers page' do
|
||||
describe 'create trigger workflow' do
|
||||
before do
|
||||
sign_in(user)
|
||||
|
||||
visit project_settings_ci_cd_path(project)
|
||||
|
||||
wait_for_requests
|
||||
end
|
||||
|
||||
it 'prevents adding new trigger with no description' do
|
||||
click_button 'Add new token'
|
||||
fill_in 'trigger_description', with: ''
|
||||
@ -74,10 +76,17 @@ RSpec.describe 'Triggers', :js, feature_category: :continuous_integration do
|
||||
describe 'edit trigger workflow' do
|
||||
let(:new_trigger_title) { 'new trigger' }
|
||||
|
||||
it 'click on edit trigger opens edit trigger modal' do
|
||||
create(:ci_trigger, owner: user, project: @project, description: trigger_title)
|
||||
visit project_settings_ci_cd_path(@project)
|
||||
before do
|
||||
create(:ci_trigger, owner: user, project: project, description: trigger_title)
|
||||
|
||||
sign_in(user)
|
||||
|
||||
visit project_settings_ci_cd_path(project)
|
||||
|
||||
wait_for_requests
|
||||
end
|
||||
|
||||
it 'click on edit trigger opens edit trigger modal' do
|
||||
# See if edit modal has correct descrption
|
||||
find('button[title="Edit"]').send_keys(:return)
|
||||
page.within('[id="edit-trigger-modal"]') do
|
||||
@ -86,9 +95,6 @@ RSpec.describe 'Triggers', :js, feature_category: :continuous_integration do
|
||||
end
|
||||
|
||||
it 'edit trigger and save' do
|
||||
create(:ci_trigger, owner: user, project: @project, description: trigger_title)
|
||||
visit project_settings_ci_cd_path(@project)
|
||||
|
||||
# See if edit modal opens, then fill in new description and save
|
||||
find('button[title="Edit"]').send_keys(:return)
|
||||
page.within('[id="edit-trigger-modal"]') do
|
||||
@ -105,8 +111,13 @@ RSpec.describe 'Triggers', :js, feature_category: :continuous_integration do
|
||||
|
||||
describe 'trigger "Revoke" workflow' do
|
||||
before do
|
||||
create(:ci_trigger, owner: user2, project: @project, description: trigger_title)
|
||||
visit project_settings_ci_cd_path(@project)
|
||||
create(:ci_trigger, owner: user2, project: project, description: trigger_title)
|
||||
|
||||
sign_in(user)
|
||||
|
||||
visit project_settings_ci_cd_path(project)
|
||||
|
||||
wait_for_requests
|
||||
end
|
||||
|
||||
it 'button "Revoke" has correct alert' do
|
||||
@ -151,14 +162,22 @@ RSpec.describe 'Triggers', :js, feature_category: :continuous_integration do
|
||||
end
|
||||
|
||||
describe 'show triggers workflow' do
|
||||
before do
|
||||
sign_in(user)
|
||||
end
|
||||
|
||||
it 'contains trigger description placeholder' do
|
||||
visit project_settings_ci_cd_path(project)
|
||||
|
||||
wait_for_requests
|
||||
|
||||
click_button 'Add new token'
|
||||
expect(page.find('#trigger_description')['placeholder']).to eq 'Trigger description'
|
||||
end
|
||||
|
||||
it 'show "invalid" badge for trigger with owner having insufficient permissions' do
|
||||
create(:ci_trigger, owner: guest_user, project: @project, description: trigger_title)
|
||||
visit project_settings_ci_cd_path(@project)
|
||||
create(:ci_trigger, owner: guest_user, project: project, description: trigger_title)
|
||||
visit project_settings_ci_cd_path(project)
|
||||
|
||||
aggregate_failures 'has invalid badge and no edit link' do
|
||||
expect(page.find('.triggers-list')).to have_content 'invalid'
|
||||
@ -167,25 +186,25 @@ RSpec.describe 'Triggers', :js, feature_category: :continuous_integration do
|
||||
end
|
||||
|
||||
it 'hides the token value and reveals when clicking the "reveal values" button', :aggregate_failures do
|
||||
create(:ci_trigger, owner: user, project: @project, description: trigger_title)
|
||||
visit project_settings_ci_cd_path(@project)
|
||||
create(:ci_trigger, owner: user, project: project, description: trigger_title)
|
||||
visit project_settings_ci_cd_path(project)
|
||||
|
||||
expect(page.find('.triggers-list')).to have_content('*' * 47)
|
||||
|
||||
find_by_testid('reveal-hide-values-button').click
|
||||
|
||||
expect(page.find('.triggers-list')).to have_content(@project.triggers.first.token)
|
||||
expect(page.find('.triggers-list')).to have_content(project.triggers.first.token)
|
||||
end
|
||||
|
||||
it 'do not show "Edit" or full token for not owned trigger' do
|
||||
# Create trigger with user different from current_user
|
||||
create(:ci_trigger, owner: user2, project: @project, description: trigger_title)
|
||||
visit project_settings_ci_cd_path(@project)
|
||||
create(:ci_trigger, owner: user2, project: project, description: trigger_title)
|
||||
visit project_settings_ci_cd_path(project)
|
||||
|
||||
find_by_testid('reveal-hide-values-button').click
|
||||
|
||||
aggregate_failures 'shows truncated token, no clipboard button and no edit link' do
|
||||
expect(page.find('.triggers-list')).to have_content(@project.triggers.first.token[0..3])
|
||||
expect(page.find('.triggers-list')).to have_content(project.triggers.first.token[0..3])
|
||||
expect(page.find('.triggers-list')).not_to have_selector('[data-testid="clipboard-btn"]')
|
||||
expect(page.find('.triggers-list .trigger-owner')).not_to have_content user.name
|
||||
expect(page.find('.triggers-list')).not_to have_selector('a[title="Edit"]')
|
||||
@ -193,13 +212,13 @@ RSpec.describe 'Triggers', :js, feature_category: :continuous_integration do
|
||||
end
|
||||
|
||||
it 'show "Edit" and full token for owned trigger' do
|
||||
create(:ci_trigger, owner: user, project: @project, description: trigger_title)
|
||||
visit project_settings_ci_cd_path(@project)
|
||||
create(:ci_trigger, owner: user, project: project, description: trigger_title)
|
||||
visit project_settings_ci_cd_path(project)
|
||||
|
||||
find_by_testid('reveal-hide-values-button').click
|
||||
|
||||
aggregate_failures 'shows full token, clipboard button and edit link' do
|
||||
expect(page.find('.triggers-list')).to have_content @project.triggers.first.token
|
||||
expect(page.find('.triggers-list')).to have_content project.triggers.first.token
|
||||
expect(page.find('.triggers-list')).to have_selector('[data-testid="clipboard-btn"]')
|
||||
expect(page.find('.triggers-list .trigger-owner')).to have_content user.name
|
||||
expect(page.find('.triggers-list')).to have_selector('button[title="Edit"]')
|
||||
|
Reference in New Issue
Block a user