Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2024-01-24 15:08:34 +00:00
parent af5193aa3c
commit 3d8ebbb15d
29 changed files with 326 additions and 39 deletions

View File

@ -3,3 +3,5 @@ export const getModifierKey = (removeSuffix = false) => {
const winKey = `Ctrl${removeSuffix ? '' : '+'}`;
return window.gl?.client?.isMac ? '⌘' : winKey;
};
export const PRELOAD_THROTTLE_TIMEOUT_MS = 4000;

View File

@ -5,6 +5,7 @@ import GfmAutoComplete, { defaultAutocompleteConfig } from 'ee_else_ce/gfm_auto_
import { disableButtonIfEmptyField } from '~/lib/utils/common_utils';
import dropzoneInput from './dropzone_input';
import { addMarkdownListeners, removeMarkdownListeners } from './lib/utils/text_markdown';
import { PRELOAD_THROTTLE_TIMEOUT_MS } from './constants';
export default class GLForm {
/**
@ -17,10 +18,11 @@ export default class GLForm {
* By default, the backend embeds these in the global object gl.GfmAutocomplete.dataSources.
* Use this param to override them.
*/
constructor(form, enableGFM = {}, forceNew = false, gfmDataSources = {}) {
constructor(form, enableGFM = {}, forceNew = false, gfmDataSources = {}, preloadMembers = false) {
this.form = form;
this.textarea = this.form.find('textarea.js-gfm-input');
this.enableGFM = { ...defaultAutocompleteConfig, ...enableGFM };
this.preloadMembers = preloadMembers;
// Disable autocomplete for keywords which do not have dataSources available
let dataSources = (gl.GfmAutoComplete && gl.GfmAutoComplete.dataSources) || {};
@ -68,6 +70,21 @@ export default class GLForm {
);
this.autoComplete = new GfmAutoComplete(dataSources);
this.autoComplete.setup(this.form.find('.js-gfm-input'), this.enableGFM);
if (this.preloadMembers && dataSources?.members) {
// for now the preload is only implemented for the members
// timeout helping to trottle the preloads in the case content_editor
// is set as main comment editor and support for rspec tests
// https://gitlab.com/gitlab-org/gitlab/-/issues/427437
requestIdleCallback(() =>
setTimeout(
() => this.autoComplete?.fetchData($('.js-gfm-input'), '@'),
PRELOAD_THROTTLE_TIMEOUT_MS,
),
);
}
this.formDropzone = dropzoneInput(this.form, { parallelUploads: 1 });
if (this.form.is(':not(.js-no-autosize)')) {

View File

@ -12,6 +12,7 @@ import discussionNavigator from '../notes/components/discussion_navigator.vue';
import NotesApp from '../notes/components/notes_app.vue';
import { getNotesFilterData } from '../notes/utils/get_notes_filter_data';
import initWidget from '../vue_merge_request_widget';
import { MERGE_REQUEST_NOTEABLE_TYPE } from '../notes/constants';
export default () => {
requestIdleCallback(
@ -45,6 +46,9 @@ export default () => {
newCommentTemplatePath: notesDataset.newCommentTemplatePath,
mrFilter: true,
newCustomEmojiPath: notesDataset.newCustomEmojiPath,
preloadMembers:
notesDataset?.noteableType === MERGE_REQUEST_NOTEABLE_TYPE &&
gon?.features?.preloadAutocompleteMembersIssuesMrs,
},
data() {
const noteableData = JSON.parse(notesDataset.noteableData);

View File

@ -7,6 +7,7 @@ import { getLocationHash } from '~/lib/utils/url_utility';
import NotesApp from './components/notes_app.vue';
import { store } from './stores';
import { getNotesFilterData } from './utils/get_notes_filter_data';
import { ISSUE_NOTEABLE_TYPE } from './constants';
export default ({ editorAiActions = [] } = {}) => {
const el = document.getElementById('js-vue-notes');
@ -63,6 +64,9 @@ export default ({ editorAiActions = [] } = {}) => {
resourceGlobalId: convertToGraphQLId(noteableData.noteableType, noteableData.id),
editorAiActions: editorAiActions.map((factory) => factory(noteableData)),
newCustomEmojiPath: notesDataset.newCustomEmojiPath,
preloadMembers:
notesDataset.noteableType === ISSUE_NOTEABLE_TYPE &&
gon?.features?.preloadAutocompleteMembersIssuesMrs,
},
data() {
return {

View File

@ -33,6 +33,13 @@ export default {
GlTooltip: GlTooltipDirective,
},
mixins: [glFeatureFlagsMixin()],
inject: {
preloadMembers: {
type: Boolean,
required: false,
default: false,
},
},
props: {
/**
* This prop should be bound to the value of the `<textarea>` element
@ -278,6 +285,7 @@ export default {
},
true,
this.autocompleteDataSources,
this.preloadMembers,
);
markdownEditorEventHub.$emit(MARKDOWN_EDITOR_READY_EVENT);

View File

@ -72,6 +72,7 @@ class Projects::IssuesController < Projects::ApplicationController
push_force_frontend_feature_flag(:linked_work_items, project.linked_work_items_feature_flag_enabled?)
push_frontend_feature_flag(:notifications_todos_buttons, current_user)
push_frontend_feature_flag(:mention_autocomplete_backend_filtering, project)
push_frontend_feature_flag(:preload_autocomplete_members_issues_mrs, current_user)
end
around_action :allow_gitaly_ref_name_caching, only: [:discussions]

View File

@ -49,6 +49,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
push_frontend_feature_flag(:mention_autocomplete_backend_filtering, project)
push_frontend_feature_flag(:pinned_file, project)
push_frontend_feature_flag(:merge_request_diff_generated_subscription, project)
push_frontend_feature_flag(:preload_autocomplete_members_issues_mrs, current_user)
end
around_action :allow_gitaly_ref_name_caching, only: [:index, :show, :diffs, :discussions]

View File

@ -0,0 +1,8 @@
---
name: preload_autocomplete_members_issues_mrs
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/139085
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/435698
milestone: '16.8'
type: development
group: group::global search
default_enabled: false

View File

@ -8,3 +8,5 @@ description: TODO
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/5b0954759cc24bdba97be89bb117c5440174f859
milestone: '9.4'
gitlab_schema: gitlab_ci
sharding_key:
group_id: namespaces

View File

@ -8,3 +8,5 @@ description: TODO
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/77886
milestone: '14.7'
gitlab_schema: gitlab_ci
sharding_key:
project_id: projects

View File

@ -8,3 +8,5 @@ description: TODO
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/046b28312704f3131e72dcd2dbdacc5264d4aa62
milestone: '8.0'
gitlab_schema: gitlab_ci
sharding_key:
project_id: projects

View File

@ -1 +1 @@
1383d7d49981bdb5fa5eeb54dd83520f4bd2de1e8f0cc227c1397d0bc48a66f4
f6e40be8eac5b255458e32b33755b9404ede064add99f0f13998647eea1dfbb7

View File

@ -178,12 +178,13 @@ including:
- Snippets
- [Group wikis](../../user/project/wiki/group.md)
- Project-level Secure Files ([introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/121142) in GitLab 16.1)
- Merge request diffs (Helm chart installation only)
Backups do not include:
- [Mattermost data](https://docs.mattermost.com/administration/config-settings.html#file-storage)
- [Mattermost data](../../integration/mattermost/index.md#back-up-gitlab-mattermost)
- Redis (and thus Sidekiq jobs)
- [Object storage](#object-storage)
- [Object storage](#object-storage) on Linux package (Omnibus) / Docker / Self-compiled installations
WARNING:
GitLab does not back up any configuration files (`/etc/gitlab`), TLS keys and certificates, or system
@ -208,7 +209,7 @@ system. If you installed GitLab:
### Backup command
WARNING:
The backup command does not back up items in [object storage](#object-storage).
The backup command does not back up items in [object storage](#object-storage) on Linux package (Omnibus) / Docker / Self-compiled installations.
WARNING:
The backup command requires [additional parameters](#back-up-and-restore-for-installations-using-pgbouncer) when
@ -239,8 +240,6 @@ Run the backup task by using `kubectl` to run the `backup-utility` script on the
Run the backup from the host.
- GitLab 12.2 or later:
```shell
docker exec -t <container name> gitlab-backup create
```
@ -439,28 +438,45 @@ on all distributions. To verify that it's available in your distribution, run
sudo gitlab-backup create BACKUP=dump GZIP_RSYNCABLE=yes
```
#### Excluding specific directories from the backup
#### Excluding specific data from the backup
You can exclude specific directories from the backup by adding the environment variable `SKIP`, whose values are a comma-separated list of the following options:
Depending on your installation type, slightly different components can be skipped on backup creation.
::Tabs
:::Tab Title Linux package (Omnibus) / Docker / Self-compiled
<!-- source: https://gitlab.com/gitlab-org/gitlab/-/blob/31c3df7ebb65768208772da3e20d32688a6c90ef/lib/backup/manager.rb#L126 -->
- `db` (database)
- `repositories` (Git repositories data, including wikis)
- `uploads` (attachments)
- `builds` (CI job output logs)
- `artifacts` (CI job artifacts)
- `pages` (Pages content)
- `lfs` (LFS objects)
- `terraform_state` (Terraform states)
- `registry` (Container registry images)
- `pages` (Pages content)
- `repositories` (Git repositories data)
- `packages` (Packages)
- `ci_secure_files` (Project-level Secure Files)
NOTE:
When [backing up and restoring Helm Charts](https://docs.gitlab.com/charts/architecture/backup-restore.html), there is an additional option `packages`, which refers to any packages managed by the GitLab [package registry](../../user/packages/package_registry/index.md).
For more information see [command line arguments](https://docs.gitlab.com/charts/architecture/backup-restore.html#command-line-arguments).
:::TabTitle Helm chart (Kubernetes)
All wikis are backed up as part of the `repositories` group. Non-existent
wikis are skipped during a backup.
<!-- source: https://gitlab.com/gitlab-org/build/CNG/-/blob/068e146db915efcd875414e04403410b71a2e70c/gitlab-toolbox/scripts/bin/backup-utility#L19 -->
- `db` (database)
- `repositories` (Git repositories data, including wikis)
- `uploads` (attachments)
- `artifacts` (CI job artifacts and output logs)
- `pages` (Pages content)
- `lfs` (LFS objects)
- `terraform_state` (Terraform states)
- `registry` (Container registry images)
- `packages` (Package registry)
- `ci_secure_files` (Project-level Secure Files)
- `external_diffs` (Merge request diffs)
::EndTabs
::Tabs
@ -470,6 +486,10 @@ wikis are skipped during a backup.
sudo gitlab-backup create SKIP=db,uploads
```
:::TabTitle Helm chart (Kubernetes)
See [Skipping components](https://docs.gitlab.com/charts/backup-restore/backup.html#skipping-components) in charts backup documentation.
:::TabTitle Self-compiled
```shell
@ -1341,7 +1361,7 @@ If you have a specific reason to change the path, it can be configured in the Li
Because every deployment may have different capabilities, you should first review [what data needs to be backed up](#what-data-needs-to-be-backed-up) to better understand if, and how, you can leverage them.
For example, if you use Amazon RDS, you might choose to use its built-in backup and restore features to handle your GitLab [PostgreSQL data](#postgresql-databases), and [exclude PostgreSQL data](#excluding-specific-directories-from-the-backup) when using the [backup command](#backup-command).
For example, if you use Amazon RDS, you might choose to use its built-in backup and restore features to handle your GitLab [PostgreSQL data](#postgresql-databases), and [exclude PostgreSQL data](#excluding-specific-data-from-the-backup) when using the [backup command](#backup-command).
In the following cases, consider using file system data transfer or snapshots as part of your backup strategy:
@ -1381,7 +1401,7 @@ practical use.
### Back up repository data separately
First, ensure you back up existing GitLab data while [skipping repositories](#excluding-specific-directories-from-the-backup):
First, ensure you back up existing GitLab data while [skipping repositories](#excluding-specific-data-from-the-backup):
::Tabs

View File

@ -60,7 +60,7 @@ the container registry on the primary site and restore it onto the secondary
site:
1. On your primary site, back up only the registry and
[exclude specific directories from the backup](../../../administration/backup_restore/backup_gitlab.md#excluding-specific-directories-from-the-backup):
[exclude specific directories from the backup](../../../administration/backup_restore/backup_gitlab.md#excluding-specific-data-from-the-backup):
```shell
# Create a backup in the /var/opt/gitlab/backups folder

View File

@ -985,3 +985,44 @@ to run the following command:
```ruby
Feature.disable(:s3_multithreaded_uploads)
```
### Manual testing through Rails Console
In some situations, it may be helpful to test object storage settings using the Rails Console. The following example tests a given set of connection settings, attempts to write a test object, and finally read it.
1. Start a [Rails console](operations/rails_console.md).
1. Set up the object storage connection, using the same parameters you set up in `/etc/gitlab/gitlab.rb`, in the following example format:
Example connection using access keys:
```ruby
connection = Fog::Storage.new(
{
provider: 'AWS',
region: `eu-central-1`,
aws_access_key_id: '<AWS_ACCESS_KEY_ID>',
aws_secret_access_key: '<AWS_SECRET_ACCESS_KEY>'
}
)
```
Example connection using AWS IAM Profiles:
```ruby
connection = Fog::Storage.new(
{
provider: 'AWS',
use_iam_profile: true,
region: 'us-east-1'
}
)
```
1. Specify the bucket name to test against, write, and finally read a test file.
```ruby
dir = connection.directories.new(key: '<bucket-name-here>')
f = dir.files.create(key: 'test.txt', body: 'test')
pp f
pp dir.files.head('test.txt')
```

View File

@ -195,7 +195,7 @@ can result from directly accessing and copying Gitaly files using tools like `rs
- From GitLab 13.3, backup performance can be improved by
[processing multiple repositories concurrently](../../administration/backup_restore/backup_gitlab.md#back-up-git-repositories-concurrently).
- Backups can be created of just the repositories using the
[skip feature](../../administration/backup_restore/backup_gitlab.md#excluding-specific-directories-from-the-backup).
[skip feature](../../administration/backup_restore/backup_gitlab.md#excluding-specific-data-from-the-backup).
No other method works for Gitaly Cluster targets.

View File

@ -307,6 +307,41 @@ Example response:
```
## Get the sequence of a commit
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/438151) in GitLab 16.9.
Get the sequence number of a commit in a project by following the parent links from the given commit.
This API provides essentially the same features as the `git rev-list --count` command for a given commit SHA.
```plaintext
GET /projects/:id/repository/commits/:sha/sequence
```
Parameters:
| Attribute | Type | Required | Description |
| -------------- | -------------- | -------- | ----------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding) owned by the authenticated user. |
| `sha` | string | yes | The commit hash. |
| `first_parent` | boolean | no | Follow only the first parent commit upon seeing a merge commit. |
Example request:
```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" \
--url "https://gitlab.example.com/api/v4/projects/5/repository/commits/5937ac0a7beb003549fc5fd26fc247adbce4a52e/sequence"
```
Example response:
```json
{
"count": 632
}
```
## Cherry-pick a commit
Cherry-picks a commit to a given branch.

View File

@ -804,6 +804,25 @@ Returns [`RunnerSetup`](#runnersetup).
| <a id="queryrunnersetupplatform"></a>`platform` | [`String!`](#string) | Platform to generate the instructions for. |
| <a id="queryrunnersetupprojectid"></a>`projectId` **{warning-solid}** | [`ProjectID`](#projectid) | **Deprecated** in 13.11. No longer used. |
### `Query.runnerUsageByProject`
Runner usage by project.
WARNING:
**Introduced** in 16.9.
This feature is an Experiment. It can be changed or removed at any time.
Returns [`[RunnerUsageByProject!]`](#runnerusagebyproject).
#### Arguments
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="queryrunnerusagebyprojectfromdate"></a>`fromDate` | [`Date`](#date) | Start of the requested date frame. Defaults to the start of the previous calendar month. |
| <a id="queryrunnerusagebyprojectprojectslimit"></a>`projectsLimit` | [`Int`](#int) | Maximum number of projects to return.Other projects will be aggregated to a `project: null` entry.Can not be larger than 500. Defaults to 5. |
| <a id="queryrunnerusagebyprojectrunnertype"></a>`runnerType` | [`CiRunnerType`](#cirunnertype) | Filter jobs by the type of runner that executed them. |
| <a id="queryrunnerusagebyprojecttodate"></a>`toDate` | [`Date`](#date) | End of the requested date frame. Defaults to the end of the previous calendar month. |
### `Query.runners`
Get all runners in the GitLab instance (project and shared). Access is restricted to users with administrator access.
@ -26845,6 +26864,18 @@ Counts of requirements by their state.
| <a id="runnersetupinstallinstructions"></a>`installInstructions` | [`String!`](#string) | Instructions for installing the runner on the specified architecture. |
| <a id="runnersetupregisterinstructions"></a>`registerInstructions` | [`String`](#string) | Instructions for registering the runner. The actual registration tokens are not included in the commands. Instead, a placeholder `$REGISTRATION_TOKEN` is shown. |
### `RunnerUsageByProject`
Runner usage in minutes by project.
#### Fields
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="runnerusagebyprojectcibuildcount"></a>`ciBuildCount` | [`Int!`](#int) | Amount of builds executed during the selected period. |
| <a id="runnerusagebyprojectciminutesused"></a>`ciMinutesUsed` | [`Int!`](#int) | Amount of minutes used during the selected period. |
| <a id="runnerusagebyprojectproject"></a>`project` | [`Project`](#project) | Project that the usage refers to. Null means "Other projects". |
### `SastCiConfiguration`
Represents a CI configuration of SAST.

View File

@ -766,7 +766,7 @@ Some important things to know:
must [configure this yourself](../../administration/backup_restore/backup_gitlab.md#storing-configuration-files).
- By default, the backup files are stored locally, but you can
[backup GitLab using S3](../../administration/backup_restore/backup_gitlab.md#using-amazon-s3).
- You can [exclude specific directories form the backup](../../administration/backup_restore/backup_gitlab.md#excluding-specific-directories-from-the-backup).
- You can [exclude specific directories form the backup](../../administration/backup_restore/backup_gitlab.md#excluding-specific-data-from-the-backup).
### Backing up GitLab

View File

@ -184,10 +184,7 @@ separation of duties is:
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/356791) in GitLab 16.4 [with a flag](../../../administration/feature_flags.md) named `compliance_violation_csv_export`. Disabled by default.
> - [Enabled on GitLab.com and self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/424447) in GitLab 16.5.
FLAG:
On self-managed GitLab, by default this feature is available. To hide the feature, an administrator can [disable the feature flag](../../../administration/feature_flags.md) named
`compliance_violation_csv_export`. On GitLab.com, this feature is available.
> - [Feature flag `compliance_violation_csv_export`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/142568) removed in GitLab 16.9.
Export a report of merge request compliance violations on merge requests belonging to projects in a group. Reports:

View File

@ -309,6 +309,27 @@ module API
present paginate(notes), with: Entities::CommitNote
end
desc 'Get the sequence count of a commit SHA' do
success code: 200, model: Entities::CommitSequence
tags %w[commits]
failure [
{ code: 404, message: 'Not found' }
]
end
params do
requires :sha, type: String, desc: 'A commit SHA'
optional :first_parent, type: Boolean, desc: 'Only include the first parent of merges', default: false
end
get ':id/repository/commits/:sha/sequence', requirements: API::COMMIT_ENDPOINT_REQUIREMENTS do
commit = user_project.commit(params[:sha])
not_found! 'Commit' unless commit
count = user_project.repository.count_commits(ref: params[:sha], first_parent: params[:first_parent])
count_hash = { count: count }
present count_hash, with: Entities::CommitSequence
end
desc 'Cherry pick commit into a branch' do
detail 'This feature was introduced in GitLab 8.15'
success code: 200, model: Entities::Commit

View File

@ -0,0 +1,9 @@
# frozen_string_literal: true
module API
module Entities
class CommitSequence < Grape::Entity
expose :count, documentation: { type: 'integer', example: 1 }
end
end
end

View File

@ -85,7 +85,7 @@ module QA
def click_boards_dropdown_button
# The dropdown button comes from the `GlDropdown` component of `@gitlab/ui`,
# so it wasn't possible to add a `data-qa-selector` to it.
# so it wasn't possible to add a `data-testid` to it.
find_element('boards-dropdown').find('button').click
end

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
# VSCode WebIDE is built off an iFrame application therefore we are unable to use `qa-selectors`
# VSCode WebIDE is built off an iFrame application therefore we are unable to use `testids`
module QA
module Page
module Project

View File

@ -92,7 +92,9 @@ RSpec.describe 'User comments on a merge request', :js, feature_category: :code_
end
wait_for_requests
expect(page.html).to include('Are you sure you want to cancel creating this comment?')
page.within('.modal-dialog') do
expect(page).to have_content('Are you sure you want to cancel creating this comment?')
end
end
it 'loads new comment' do

View File

@ -1,6 +1,7 @@
import autosize from 'autosize';
import $ from 'jquery';
import GLForm from '~/gl_form';
import GfmAutoComplete from 'ee_else_ce/gfm_auto_complete';
import '~/lib/utils/text_utility';
import '~/lib/utils/common_utils';
@ -46,6 +47,43 @@ describe('GLForm', () => {
expect(setupFormSpy).toHaveBeenCalledWith(customDataSources, false);
});
});
describe('GfmAutoComplete', () => {
let autocompleteDataFetchSpy;
const updatedMockGl = { ...mockGl };
updatedMockGl.GfmAutoComplete.dataSources = {
...updatedMockGl.GfmAutoComplete.dataSources,
members: '/group/projects/-/autocomplete_sources/members',
};
beforeEach(() => {
jest.spyOn(window, 'requestIdleCallback').mockImplementation((cb) => cb());
// We need to mock implement fetchData to prevent
// the axios call which is not subject of this test
autocompleteDataFetchSpy = jest
.spyOn(GfmAutoComplete.prototype, 'fetchData')
.mockImplementation(() => 'test');
testContext.form = $('<form class="gfm-form"><textarea class="js-gfm-input"></form>');
testContext.textarea = testContext.form.find('textarea');
});
afterEach(() => {
window.requestIdleCallback.mockRestore();
autocompleteDataFetchSpy.mockRestore();
});
it('will call fetchdata if preloadMembers is enabled', () => {
window.gl = { ...updatedMockGl };
testContext.glForm = new GLForm(testContext.form, {}, true, {}, true);
jest.runAllTimers();
expect(autocompleteDataFetchSpy).toHaveBeenCalledTimes(1);
expect(autocompleteDataFetchSpy).toHaveBeenCalledWith(expect.any(Object), '@');
});
});
});
describe('when instantiated', () => {

View File

@ -67,6 +67,9 @@ describe('Markdown field component', () => {
showContentEditorSwitcher,
supportsQuickActions: true,
},
provide: {
preloadMembers: true,
},
mocks: {
$apollo: {
queries: {
@ -93,6 +96,9 @@ describe('Markdown field component', () => {
showContentEditorSwitcher: false,
autocompleteDataSources,
},
provide: {
preloadMembers: true,
},
});
}
@ -131,6 +137,10 @@ describe('Markdown field component', () => {
commands: '/foobar/-/autocomplete_sources',
});
});
it('initializes GlForm with autocomplete data sources and preload memebers', () => {
expect(findGlForm().preloadMembers).toBe(true);
});
});
it('renders textarea inside backdrop', () => {

View File

@ -1864,6 +1864,46 @@ RSpec.describe API::Commits, feature_category: :source_code_management do
end
end
describe 'GET /projects/:id/repository/commits/:sha/sequence' do
let(:current_user) { user }
let(:commit) { project.repository.commit }
let(:commit_id) { commit.id }
let(:route) { "/projects/#{project_id}/repository/commits/#{commit_id}/sequence" }
context 'when commit does not exist' do
let(:commit_id) { 'unknown' }
it_behaves_like '404 response' do
let(:request) { get api(route, current_user) }
let(:message) { '404 Commit Not Found' }
end
end
context 'when commit exists' do
it 'returns correct JSON' do
expected_count = project.repository.count_commits(ref: commit_id, first_parent: false)
get api(route, current_user)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['count']).to eq(expected_count)
end
end
context 'when commit exists first-parent' do
let(:route) { "/projects/#{project_id}/repository/commits/#{commit_id}/sequence?first_parent=true" }
it 'returns correct JSON' do
expected_count = project.repository.count_commits(ref: commit_id, first_parent: true)
get api(route, current_user)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['count']).to eq(expected_count)
end
end
end
describe 'POST :id/repository/commits/:sha/cherry_pick' do
let(:project) { create(:project, :repository, creator: user, path: 'my.project') }
let(:commit) { project.commit('7d3b0f7cff5f37573aea97cebfd5692ea1689924') }

View File

@ -125,7 +125,6 @@ type testServer struct {
writer *multipart.Writer
buffer *bytes.Buffer
fileWriter io.Writer
cleanup func()
}
func setupWithTmpPath(t *testing.T, filename string, includeFormat bool, format string, authResponse *api.Response, bodyProcessor func(w http.ResponseWriter, r *http.Request)) *testServer {
@ -143,10 +142,10 @@ func setupWithTmpPath(t *testing.T, filename string, includeFormat bool, format
require.NotNil(t, fileWriter)
require.NoError(t, err)
cleanup := func() {
t.Cleanup(func() {
ts.Close()
require.NoError(t, writer.Close())
}
})
qs := ""
@ -154,7 +153,7 @@ func setupWithTmpPath(t *testing.T, filename string, includeFormat bool, format
qs = fmt.Sprintf("?%s=%s", ArtifactFormatKey, format)
}
return &testServer{url: ts.URL + Path + qs, writer: writer, buffer: &buffer, fileWriter: fileWriter, cleanup: cleanup}
return &testServer{url: ts.URL + Path + qs, writer: writer, buffer: &buffer, fileWriter: fileWriter}
}
func testUploadArtifacts(t *testing.T, contentType, url string, body io.Reader) *httptest.ResponseRecorder {
@ -211,7 +210,6 @@ func TestUploadHandlerAddingMetadata(t *testing.T) {
require.Contains(t, r.PostForm, "metadata.gitlab-workhorse-upload")
},
)
defer s.cleanup()
archive := zip.NewWriter(s.fileWriter)
file, err := archive.Create("test.file")
@ -241,7 +239,6 @@ func TestUploadHandlerTarArtifact(t *testing.T) {
require.Contains(t, r.PostForm, "file.gitlab-workhorse-upload")
},
)
defer s.cleanup()
file, err := os.Open("../../testdata/tarfile.tar")
require.NoError(t, err)
@ -258,7 +255,6 @@ func TestUploadHandlerTarArtifact(t *testing.T) {
func TestUploadHandlerForUnsupportedArchive(t *testing.T) {
s := setupWithTmpPath(t, "file", true, "other", nil, nil)
defer s.cleanup()
require.NoError(t, s.writer.Close())
response := testUploadArtifacts(t, s.writer.FormDataContentType(), s.url, s.buffer)
@ -268,7 +264,6 @@ func TestUploadHandlerForUnsupportedArchive(t *testing.T) {
func TestUploadHandlerForMultipleFiles(t *testing.T) {
s := setupWithTmpPath(t, "file", true, "", nil, nil)
defer s.cleanup()
file, err := s.writer.CreateFormFile("file", "my.file")
require.NotNil(t, file)
@ -281,7 +276,6 @@ func TestUploadHandlerForMultipleFiles(t *testing.T) {
func TestUploadFormProcessing(t *testing.T) {
s := setupWithTmpPath(t, "metadata", true, "", nil, nil)
defer s.cleanup()
require.NoError(t, s.writer.Close())
response := testUploadArtifacts(t, s.writer.FormDataContentType(), s.url, s.buffer)
@ -292,7 +286,6 @@ func TestLsifFileProcessing(t *testing.T) {
tempPath := t.TempDir()
s := setupWithTmpPath(t, "file", true, "zip", &api.Response{TempPath: tempPath, ProcessLsif: true}, nil)
defer s.cleanup()
file, err := os.Open("../../testdata/lsif/valid.lsif.zip")
require.NoError(t, err)
@ -311,7 +304,6 @@ func TestInvalidLsifFileProcessing(t *testing.T) {
tempPath := t.TempDir()
s := setupWithTmpPath(t, "file", true, "zip", &api.Response{TempPath: tempPath, ProcessLsif: true}, nil)
defer s.cleanup()
file, err := os.Open("../../testdata/lsif/invalid.lsif.zip")
require.NoError(t, err)