Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-09-22 06:10:15 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-09-22 06:10:15 +0300
commit1e69e818f0f6d3598efb67104c39ec9408570b0f (patch)
tree1dbb70f80d2a63e1a1aa2f282e8ab8e08edaee89
parent0bdb61ade7f12067dd524463af4f83994f1baa37 (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--app/assets/javascripts/repository/index.js2
-rw-r--r--app/assets/javascripts/repository/router.js3
-rw-r--r--app/models/repository.rb2
-rw-r--r--app/views/projects/blob/show.html.haml2
-rw-r--r--app/views/projects/buttons/_compare.html.haml8
-rw-r--r--app/views/projects/tree/_tree_header.html.haml1
-rw-r--r--doc/api/lint.md10
-rw-r--r--doc/user/application_security/dependency_scanning/index.md4
-rw-r--r--doc/user/packages/terraform_module_registry/index.md2
-rw-r--r--lib/api/lint.rb17
-rw-r--r--lib/extracts_ref.rb4
-rw-r--r--locale/gitlab.pot3
-rw-r--r--spec/features/projects/project_overview_spec.rb59
-rw-r--r--spec/lib/extracts_ref_spec.rb6
-rw-r--r--spec/presenters/tree_entry_presenter_spec.rb15
-rw-r--r--spec/requests/api/lint_spec.rb99
-rw-r--r--spec/views/projects/tree/show.html.haml_spec.rb22
17 files changed, 234 insertions, 25 deletions
diff --git a/app/assets/javascripts/repository/index.js b/app/assets/javascripts/repository/index.js
index 9753173ac30..74ef678c558 100644
--- a/app/assets/javascripts/repository/index.js
+++ b/app/assets/javascripts/repository/index.js
@@ -122,7 +122,7 @@ export default function setupVueRepositoryList() {
return h(LastCommit, {
props: {
currentPath: this.$route.params.path,
- refType: this.$route.query.ref_type,
+ refType: this.$route.meta.refType || this.$route.query.ref_type,
},
});
},
diff --git a/app/assets/javascripts/repository/router.js b/app/assets/javascripts/repository/router.js
index 5f73912ed2b..31bafab742d 100644
--- a/app/assets/javascripts/repository/router.js
+++ b/app/assets/javascripts/repository/router.js
@@ -63,6 +63,9 @@ export default function createRouter(base, baseRef) {
props: {
refType: 'HEADS',
},
+ meta: {
+ refType: 'HEADS',
+ },
},
],
});
diff --git a/app/models/repository.rb b/app/models/repository.rb
index 1c27a7a64cf..18dcc7fb840 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -688,7 +688,7 @@ class Repository
def head_tree(skip_flat_paths: true)
return if empty? || root_ref.nil?
- @head_tree ||= Tree.new(self, root_ref, nil, skip_flat_paths: skip_flat_paths)
+ @head_tree ||= Tree.new(self, root_ref, nil, skip_flat_paths: skip_flat_paths, ref_type: 'heads')
end
def tree(sha = :head, path = nil, recursive: false, skip_flat_paths: true, pagination_params: nil, ref_type: nil, rescue_not_found: true)
diff --git a/app/views/projects/blob/show.html.haml b/app/views/projects/blob/show.html.haml
index 9ec824f64d4..82f517e8a84 100644
--- a/app/views/projects/blob/show.html.haml
+++ b/app/views/projects/blob/show.html.haml
@@ -4,7 +4,7 @@
- signatures_path = namespace_project_signatures_path(namespace_id: @project.namespace.full_path, project_id: @project.path, id: @last_commit, limit: 1)
- content_for :prefetch_asset_tags do
- webpack_preload_asset_tag('monaco', prefetch: true)
-- add_page_startup_graphql_call('repository/blob_info', { projectPath: @project.full_path, ref: current_ref, refType: @ref_type.to_s, filePath: @blob.path, shouldFetchRawText: @blob.rendered_as_text? && !@blob.rich_viewer })
+- add_page_startup_graphql_call('repository/blob_info', { projectPath: @project.full_path, ref: current_ref, refType: @ref_type.to_s.upcase, filePath: @blob.path, shouldFetchRawText: @blob.rendered_as_text? && !@blob.rich_viewer })
.js-signature-container{ data: { 'signatures-path': signatures_path } }
diff --git a/app/views/projects/buttons/_compare.html.haml b/app/views/projects/buttons/_compare.html.haml
new file mode 100644
index 00000000000..82b1b837fbb
--- /dev/null
+++ b/app/views/projects/buttons/_compare.html.haml
@@ -0,0 +1,8 @@
+- project = local_assigns.fetch(:project)
+- ref = local_assigns.fetch(:ref, nil)
+- root_ref = local_assigns.fetch(:root_ref, nil)
+- unless ref.blank? || root_ref == ref
+ - compare_path = project_compare_index_path(project, from: root_ref, to: ref)
+
+ = link_button_to compare_path, class: 'shortcuts-compare', rel: 'nofollow' do
+ = _('Compare')
diff --git a/app/views/projects/tree/_tree_header.html.haml b/app/views/projects/tree/_tree_header.html.haml
index a4ed19c2fc9..dad6480706d 100644
--- a/app/views/projects/tree/_tree_header.html.haml
+++ b/app/views/projects/tree/_tree_header.html.haml
@@ -10,6 +10,7 @@
= render_if_exists 'projects/tree/lock_link'
#js-tree-history-link{ data: { history_link: project_commits_path(@project, @ref) } }
+ = render 'projects/buttons/compare', project: @project, ref: @ref, root_ref: @repository&.root_ref
= render 'projects/find_file_link'
= render 'shared/web_ide_button', blob: nil
= render 'projects/buttons/download', project: @project, ref: @ref
diff --git a/doc/api/lint.md b/doc/api/lint.md
index 9e29e8dccb4..7b288c34343 100644
--- a/doc/api/lint.md
+++ b/doc/api/lint.md
@@ -56,9 +56,12 @@ Example responses:
## Validate a project's CI configuration
-Checks if a project's latest (`HEAD` of the project's default branch)
-`.gitlab-ci.yml` configuration is valid. This endpoint uses all namespace
-specific data available, including variables and local includes.
+> `sha` attribute [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/369212) in GitLab 16.5.
+
+Checks if a project’s `.gitlab-ci.yml` configuration in a given commit
+(by default `HEAD` of the project’s default branch) is valid. This
+endpoint uses all namespace specific data available, including variables
+and local includes.
```plaintext
GET /projects/:id/ci/lint
@@ -69,6 +72,7 @@ GET /projects/:id/ci/lint
| `dry_run` | boolean | No | Run pipeline creation simulation, or only do static check. |
| `include_jobs` | boolean | No | If the list of jobs that would exist in a static check or pipeline simulation should be included in the response. Default: `false`. |
| `ref` | string | No | When `dry_run` is `true`, sets the branch or tag to use. Defaults to the project's default branch when not set. |
+| `sha` | string | No | The commit SHA of a branch or tag. Defaults to the SHA of the head of the project's default branch when not set. |
Example request:
diff --git a/doc/user/application_security/dependency_scanning/index.md b/doc/user/application_security/dependency_scanning/index.md
index f8bd5b99cb6..532d9506270 100644
--- a/doc/user/application_security/dependency_scanning/index.md
+++ b/doc/user/application_security/dependency_scanning/index.md
@@ -126,7 +126,7 @@ table.supported-languages ul {
8 LTS,
11 LTS,
17 LTS,
- or 21 EA<sup><b><a href="#notes-regarding-supported-languages-and-package-managers-2">2</a></b></sup>
+ or 21 LTS<sup><b><a href="#notes-regarding-supported-languages-and-package-managers-2">2</a></b></sup>
</td>
<td><a href="https://gradle.org/">Gradle</a><sup><b><a href="#notes-regarding-supported-languages-and-package-managers-3">3</a></b></sup></td>
<td>
@@ -236,7 +236,7 @@ table.supported-languages ul {
<li>
<a id="notes-regarding-supported-languages-and-package-managers-2"></a>
<p>
- Java 21 EA is only available when using <a href="https://maven.apache.org/">Maven</a> and is not supported when
+ Java 21 LTS is only available when using <a href="https://maven.apache.org/">Maven</a> and is not supported when
<a href="https://docs.gitlab.com/ee/development/fips_compliance.html#enable-fips-mode">FIPS mode</a> is enabled.
</p>
</li>
diff --git a/doc/user/packages/terraform_module_registry/index.md b/doc/user/packages/terraform_module_registry/index.md
index cb0516bdc4a..5c4105f8e00 100644
--- a/doc/user/packages/terraform_module_registry/index.md
+++ b/doc/user/packages/terraform_module_registry/index.md
@@ -204,7 +204,7 @@ For example, if:
- The project is `gitlab.example.com/parent-group/sub-group/my-project`.
- The Terraform module is `my-infra-package`.
-The project name must be unique in all projects in all groups under `parent-group`.
+The module name must be unique in all projects in all groups under `parent-group`.
## Delete a Terraform module
diff --git a/lib/api/lint.rb b/lib/api/lint.rb
index 71965fc05c9..26619e6924f 100644
--- a/lib/api/lint.rb
+++ b/lib/api/lint.rb
@@ -6,12 +6,16 @@ module API
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
desc 'Validates a CI YAML configuration with a namespace' do
- detail 'Checks if a project’s latest (HEAD of the project’s default branch) .gitlab-ci.yml configuration is
- valid'
+ detail 'Checks if a project’s .gitlab-ci.yml configuration in a given commit (by default HEAD of the
+ project’s default branch) is valid'
success Entities::Ci::Lint::Result
tags %w[ci_lint]
+ failure [
+ { code: 404, message: 'Not found' }
+ ]
end
params do
+ optional :sha, type: String, desc: 'The commit hash or name of a repository branch or tag. Defaults to the HEAD of the project’s default branch'
optional :dry_run, type: Boolean, default: false, desc: 'Run pipeline creation simulation, or only do static check. This is false by default'
optional :include_jobs, type: Boolean, desc: 'If the list of jobs that would exist in a static check or pipeline
simulation should be included in the response. This is false by default'
@@ -21,12 +25,13 @@ module API
get ':id/ci/lint', urgency: :low do
authorize_read_code!
- if user_project.commit.present?
- content = user_project.repository.gitlab_ci_yml_for(user_project.commit.id, user_project.ci_config_path_or_default)
- end
+ sha = params[:sha] || user_project.repository.root_ref_sha
+ not_found! 'Commit' unless user_project.commit(sha).present?
+
+ content = user_project.repository.gitlab_ci_yml_for(sha, user_project.ci_config_path_or_default)
result = Gitlab::Ci::Lint
- .new(project: user_project, current_user: current_user)
+ .new(project: user_project, current_user: current_user, sha: sha)
.validate(content, dry_run: params[:dry_run], ref: params[:ref] || user_project.default_branch)
present result, with: Entities::Ci::Lint::Result, current_user: current_user, include_jobs: params[:include_jobs]
diff --git a/lib/extracts_ref.rb b/lib/extracts_ref.rb
index 49ec564eb8d..fa3c1fe7307 100644
--- a/lib/extracts_ref.rb
+++ b/lib/extracts_ref.rb
@@ -10,9 +10,9 @@ module ExtractsRef
REF_TYPES = [BRANCH_REF_TYPE, TAG_REF_TYPE].freeze
def self.ref_type(type)
- return unless REF_TYPES.include?(type)
+ return unless REF_TYPES.include?(type&.downcase)
- type
+ type.downcase
end
def self.qualify_ref(ref, type)
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index f98cb46dd78..6dfb78db9ba 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -42622,6 +42622,9 @@ msgstr ""
msgid "SecurityOrchestration|This is a project-level policy"
msgstr ""
+msgid "SecurityOrchestration|This policy is inherited"
+msgstr ""
+
msgid "SecurityOrchestration|This policy is inherited from %{namespace}"
msgstr ""
diff --git a/spec/features/projects/project_overview_spec.rb b/spec/features/projects/project_overview_spec.rb
new file mode 100644
index 00000000000..e563b03c22a
--- /dev/null
+++ b/spec/features/projects/project_overview_spec.rb
@@ -0,0 +1,59 @@
+# frozen_string_literal: true
+
+require "spec_helper"
+
+RSpec.describe "Project overview when default branch collides with tag", :js, feature_category: :source_code_management do
+ let_it_be(:project) { create(:project, :empty_repo) }
+ let(:user) { project.first_owner }
+
+ before_all do
+ # Create a branch called main that does not contain a readme (this will be the default branch)
+ project.repository.create_file(
+ project.creator,
+ 'NOTREADME.md',
+ '',
+ message: "Initial commit",
+ branch_name: 'main'
+ )
+
+ # Create a branch called readme_branch that contains a readme
+ project.repository.create_file(
+ project.creator,
+ 'README.md',
+ 'readme',
+ message: "Add README.md",
+ branch_name: 'readme_branch'
+ )
+
+ # Create a tag called main pointing to readme_branch
+ project.repository.add_tag(
+ project.creator,
+ 'main',
+ 'readme_branch'
+ )
+ end
+
+ before do
+ sign_in(user)
+ visit project_path(project)
+ end
+
+ it "shows last commit" do
+ page.within(".commit-detail") do
+ expect(page).to have_content('Initial commit')
+ end
+
+ page.execute_script(%{
+ document.getElementsByClassName('tree-content-holder')[0].scrollIntoView()}
+ )
+ wait_for_all_requests
+
+ page.within(".tree-content-holder") do
+ expect(page).to have_content('Initial commit')
+ end
+ end
+
+ it 'has a button to button to add readme' do
+ expect(page).to have_link 'Add README'
+ end
+end
diff --git a/spec/lib/extracts_ref_spec.rb b/spec/lib/extracts_ref_spec.rb
index ac403ad642a..bf33c8b95f1 100644
--- a/spec/lib/extracts_ref_spec.rb
+++ b/spec/lib/extracts_ref_spec.rb
@@ -87,6 +87,12 @@ RSpec.describe ExtractsRef do
it { is_expected.to eq('tags') }
end
+ context 'when case does not match' do
+ let(:ref_type) { 'tAgS' }
+
+ it { is_expected.to(eq('tags')) }
+ end
+
context 'when ref_type is invalid' do
let(:ref_type) { 'invalid' }
diff --git a/spec/presenters/tree_entry_presenter_spec.rb b/spec/presenters/tree_entry_presenter_spec.rb
index 0abf372b704..359ffbcb140 100644
--- a/spec/presenters/tree_entry_presenter_spec.rb
+++ b/spec/presenters/tree_entry_presenter_spec.rb
@@ -7,29 +7,32 @@ RSpec.describe TreeEntryPresenter do
let(:project) { create(:project, :repository) }
let(:repository) { project.repository }
- let(:tree) { Gitlab::Graphql::Representation::TreeEntry.new(repository.tree.trees.first, repository) }
+ let(:tree) { Gitlab::Graphql::Representation::TreeEntry.new(repository.tree(ref).trees.first, repository) }
let(:presenter) { described_class.new(tree) }
+ let(:ref) { 'master' }
describe '.web_url' do
- it { expect(presenter.web_url).to eq("http://localhost/#{project.full_path}/-/tree/#{tree.commit_id}/#{tree.path}") }
+ it {
+ expect(presenter.web_url).to eq("http://localhost/#{project.full_path}/-/tree/#{ref}/#{tree.path}")
+ }
end
describe '#web_path' do
- it { expect(presenter.web_path).to eq("/#{project.full_path}/-/tree/#{tree.commit_id}/#{tree.path}") }
+ it { expect(presenter.web_path).to eq("/#{project.full_path}/-/tree/#{ref}/#{tree.path}") }
end
- context 'when blob has ref_type' do
+ context 'when tree has ref_type' do
before do
tree.ref_type = 'heads'
end
describe '.web_url' do
- it { expect(presenter.web_url).to eq("http://localhost/#{project.full_path}/-/tree/#{tree.commit_id}/#{tree.path}?ref_type=heads") }
+ it { expect(presenter.web_url).to eq("http://localhost/#{project.full_path}/-/tree/#{ref}/#{tree.path}?ref_type=heads") }
end
describe '#web_path' do
it {
- expect(presenter.web_path).to eq("/#{project.full_path}/-/tree/#{tree.commit_id}/#{tree.path}?ref_type=heads")
+ expect(presenter.web_path).to eq("/#{project.full_path}/-/tree/#{ref}/#{tree.path}?ref_type=heads")
}
end
end
diff --git a/spec/requests/api/lint_spec.rb b/spec/requests/api/lint_spec.rb
index 7fe17760220..5842bd1c716 100644
--- a/spec/requests/api/lint_spec.rb
+++ b/spec/requests/api/lint_spec.rb
@@ -4,9 +4,10 @@ require 'spec_helper'
RSpec.describe API::Lint, feature_category: :pipeline_composition do
describe 'GET /projects/:id/ci/lint' do
- subject(:ci_lint) { get api("/projects/#{project.id}/ci/lint", api_user), params: { dry_run: dry_run, include_jobs: include_jobs } }
+ subject(:ci_lint) { get api("/projects/#{project.id}/ci/lint", api_user), params: { sha: sha, dry_run: dry_run, include_jobs: include_jobs } }
let(:project) { create(:project, :repository) }
+ let(:sha) { nil }
let(:dry_run) { nil }
let(:include_jobs) { nil }
@@ -291,6 +292,102 @@ RSpec.describe API::Lint, feature_category: :pipeline_composition do
end
end
end
+
+ context 'with different sha values' do
+ let(:original_content) do
+ { test: { stage: 'test', script: 'echo 1' } }.deep_stringify_keys.to_yaml
+ end
+
+ let(:first_edit) do
+ { image: 'image:1.0', services: ['postgres'] }.deep_stringify_keys.to_yaml
+ end
+
+ let(:second_edit) do
+ { new_test: { stage: 'test', script: 'echo 0' } }.deep_stringify_keys.to_yaml
+ end
+
+ before do
+ project.repository.create_file(
+ project.creator,
+ '.gitlab-ci.yml',
+ original_content,
+ message: 'Automatically created .gitlab-ci.yml',
+ branch_name: 'master'
+ )
+
+ project.repository.update_file(
+ project.creator,
+ '.gitlab-ci.yml',
+ first_edit,
+ message: 'Automatically edited .gitlab-ci.yml',
+ branch_name: 'master'
+ )
+
+ project.repository.update_file(
+ project.creator,
+ '.gitlab-ci.yml',
+ second_edit,
+ message: 'Automatically edited .gitlab-ci.yml again',
+ branch_name: 'master'
+ )
+ end
+
+ context 'when latest .gitlab-ci.yml is valid' do
+ # check with explicit sha
+ let(:sha) { project.repository.commit.sha }
+
+ it 'passes validation' do
+ ci_lint
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response).to be_an Hash
+ expect(json_response['merged_yaml']).to eq(second_edit)
+ expect(json_response['valid']).to eq(true)
+ expect(json_response['warnings']).to eq([])
+ expect(json_response['errors']).to eq([])
+ end
+ end
+
+ context 'when previous .gitlab-ci.yml is invalid' do
+ let(:sha) { project.repository.commit.parent.sha }
+
+ it 'fails validation' do
+ ci_lint
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response).to be_an Hash
+ expect(json_response['merged_yaml']).to eq(first_edit)
+ expect(json_response['valid']).to eq(false)
+ expect(json_response['warnings']).to eq([])
+ expect(json_response['errors']).to eq(["jobs config should contain at least one visible job"])
+ end
+ end
+
+ context 'when first .gitlab-ci.yml is valid' do
+ let(:sha) { project.repository.commit.parent.parent.sha }
+
+ it 'passes validation' do
+ ci_lint
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response).to be_an Hash
+ expect(json_response['merged_yaml']).to eq(original_content)
+ expect(json_response['valid']).to eq(true)
+ expect(json_response['warnings']).to eq([])
+ expect(json_response['errors']).to eq([])
+ end
+ end
+
+ context 'when sha is not found' do
+ let(:sha) { "unknown" }
+
+ it 'returns 404 response' do
+ ci_lint
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+ end
end
end
diff --git a/spec/views/projects/tree/show.html.haml_spec.rb b/spec/views/projects/tree/show.html.haml_spec.rb
index 5a1ae715f8f..942c352c6b6 100644
--- a/spec/views/projects/tree/show.html.haml_spec.rb
+++ b/spec/views/projects/tree/show.html.haml_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
RSpec.describe 'projects/tree/show' do
include Devise::Test::ControllerHelpers
- let(:project) { create(:project, :repository) }
+ let_it_be(:project) { create(:project, :repository, create_branch: 'bar') }
let(:repository) { project.repository }
let(:ref) { 'master' }
let(:commit) { repository.commit(ref) }
@@ -38,4 +38,24 @@ RSpec.describe 'projects/tree/show' do
expect(rendered).to have_css('#js-tree-ref-switcher')
end
end
+
+ context 'when on root ref' do
+ let(:ref) { repository.root_ref }
+
+ it 'hides compare button' do
+ render
+
+ expect(rendered).not_to include('Compare')
+ end
+ end
+
+ context 'when not on root ref' do
+ let(:ref) { 'bar' }
+
+ it 'shows a compare button' do
+ render
+
+ expect(rendered).to include('Compare')
+ end
+ end
end