diff --git a/app/assets/javascripts/pager.js b/app/assets/javascripts/pager.js index f78d2b0dbd3..bdb33a82b66 100644 --- a/app/assets/javascripts/pager.js +++ b/app/assets/javascripts/pager.js @@ -16,7 +16,6 @@ export default { callback = $.noop, container = '', ) { - this.url = $('.content_list').data('href') || removeParams(['limit', 'offset']); this.limit = limit; this.offset = parseInt(getParameterByName('offset'), 10) || this.limit; this.disable = disable; @@ -32,8 +31,10 @@ export default { getOld() { this.loading.show(); + const url = $('.content_list').data('href') || removeParams(['limit', 'offset']); + axios - .get(this.url, { + .get(url, { params: { limit: this.limit, offset: this.offset, diff --git a/app/services/ci/generate_coverage_reports_service.rb b/app/services/ci/generate_coverage_reports_service.rb index b3aa7b3091b..4e6fbc5462a 100644 --- a/app/services/ci/generate_coverage_reports_service.rb +++ b/app/services/ci/generate_coverage_reports_service.rb @@ -15,7 +15,13 @@ module Ci data: head_pipeline.pipeline_artifacts.find_by_file_type(:code_coverage).present.for_files(merge_request.new_paths) } rescue => e - Gitlab::ErrorTracking.track_exception(e, project_id: project.id) + Gitlab::ErrorTracking.track_exception( + e, + project_id: project.id, + base_pipeline_id: base_pipeline&.id, + head_pipeline_id: head_pipeline&.id + ) + { status: :error, key: key(base_pipeline, head_pipeline), diff --git a/app/services/members/invite_service.rb b/app/services/members/invite_service.rb index 140d8c35219..db29f41d5f6 100644 --- a/app/services/members/invite_service.rb +++ b/app/services/members/invite_service.rb @@ -84,7 +84,11 @@ module Members def add_member(email) new_member = source.add_user(email, params[:access_level], current_user: current_user, expires_at: params[:expires_at]) - errors[email] = new_member.errors.full_messages.to_sentence if new_member.invalid? + if new_member.invalid? + errors[email] = new_member.errors.full_messages.to_sentence + else + after_execute(member: new_member) + end end def result diff --git a/changelogs/unreleased/24551-keep-search-param-in-commit-scroll.yml b/changelogs/unreleased/24551-keep-search-param-in-commit-scroll.yml new file mode 100644 index 00000000000..bed12330a7c --- /dev/null +++ b/changelogs/unreleased/24551-keep-search-param-in-commit-scroll.yml @@ -0,0 +1,5 @@ +--- +title: Ensure search param is kept in scrolled commit +merge_request: 57307 +author: +type: fixed diff --git a/doc/api/packages/pypi.md b/doc/api/packages/pypi.md new file mode 100644 index 00000000000..531193e59e2 --- /dev/null +++ b/doc/api/packages/pypi.md @@ -0,0 +1,113 @@ +--- +stage: Package +group: Package +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments +--- + +# PyPI API + +This is the API documentation for [PyPI Packages](../../user/packages/pypi_repository/index.md). + +WARNING: +This API is used by the [PyPI package manager client](https://pypi.apache.org/) +and is generally not meant for manual consumption. + +For instructions on how to upload and install PyPI packages from the GitLab +package registry, see the [PyPI package registry documentation](../../user/packages/pypi_repository/index.md). + +NOTE: +These endpoints do not adhere to the standard API authentication methods. +See the [PyPI package registry documentation](../../user/packages/pypi_repository/index.md) +for details on which headers and token types are supported. + +## Download a package file + +> Introduced in GitLab 12.10. + +Download a PyPI package file. The [simple API](#simple-api-entry-point) +normally supplies this URL. + +```plaintext +GET projects/:id/packages/pypi/files/:sha256/:file_identifier +``` + +| Attribute | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `id` | string | yes | The ID or full path of the project. | +| `sha256` | string | yes | PyPI package file sha256 check sum. | +| `file_identifier` | string | yes | The PyPI package file name. | + +```shell +curl --user : "https://gitlab.example.com/api/v4/projects/1/packages/pypi/files/5y57017232013c8ac80647f4ca153k3726f6cba62d055cd747844ed95b3c65ff/my.pypi.package-0.0.1.tar.gz" +``` + +To write the output to a file: + +```shell +curl --user : "https://gitlab.example.com/api/v4/projects/1/packages/pypi/files/5y57017232013c8ac80647f4ca153k3726f6cba62d055cd747844ed95b3c65ff/my.pypi.package-0.0.1.tar.gz" >> my.pypi.package-0.0.1.tar.gz +``` + +This writes the downloaded file to `my.pypi.package-0.0.1.tar.gz` in the current directory. + +## Simple API entry point + +> Introduced in GitLab 12.10. + +Returns the package descriptor as an HTML file: + +```plaintext +GET projects/:id/packages/pypi/simple/:package_name +``` + +| Attribute | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `id` | string | yes | The ID or full path of the project. | +| `package_name` | string | yes | The name of the package. | + +```shell +curl --user : "https://gitlab.example.com/api/v4/projects/1/packages/pypi/simple/my.pypi.package" +``` + +Example response: + +```html + + + + Links for my.pypi.package + + +

Links for my.pypi.package

+ my.pypi.package-0.0.1-py3-none-any.whl
my.pypi.package-0.0.1.tar.gz
+ + +``` + +To write the output to a file: + +```shell +curl --user : "https://gitlab.example.com/api/v4/projects/1/packages/pypi/simple/my.pypi.package" >> simple.html +``` + +This writes the downloaded file to `simple.html` in the current directory. + +## Upload a package + +> Introduced in GitLab 11.3. + +Upload a PyPI package: + +```plaintext +PUT projects/:id/packages/pypi +``` + +| Attribute | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `id` | string | yes | The ID or full path of the project. | + +```shell +curl --request PUT \ + --upload-file path/to/my.pypi.package-0.0.1.tar.gz \ + --user : \ + "https://gitlab.example.com/api/v4/projects/1/packages/pypi" +``` diff --git a/doc/user/packages/pypi_repository/index.md b/doc/user/packages/pypi_repository/index.md index cf24c6c1dea..a08b7b65145 100644 --- a/doc/user/packages/pypi_repository/index.md +++ b/doc/user/packages/pypi_repository/index.md @@ -17,6 +17,9 @@ The Package Registry works with: - [pip](https://pypi.org/project/pip/) - [twine](https://pypi.org/project/twine/) +For documentation of the specific API endpoints that the `pip` and `twine` +clients use, see the [PyPI API documentation](../../../api/packages/pypi.md). + ## Build a PyPI package This section explains how to create a PyPI package. diff --git a/doc/user/project/integrations/hipchat.md b/doc/user/project/integrations/hipchat.md index 9c0eb571f66..5bb226b0efd 100644 --- a/doc/user/project/integrations/hipchat.md +++ b/doc/user/project/integrations/hipchat.md @@ -4,12 +4,12 @@ group: Ecosystem info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments --- -# Atlassian HipChat (Deprecated) **(FREE)** +# Atlassian HipChat **(FREE)** -As of [GitLab -13.11](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/57434), the -HipChat integration will not send any notifications to HipChat. This -integration is also deprecated. +WARNING: +This feature, and the integration for it, were +[deprecated](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/57434) in +GitLab 13.11. The HipChat integration no longer sends any notifications to HipChat. GitLab provides a way to send HipChat notifications upon a number of events, such as when a user pushes code, creates a branch or tag, adds a comment, and diff --git a/package.json b/package.json index 88655e42d78..d8ca7ae5011 100644 --- a/package.json +++ b/package.json @@ -5,10 +5,6 @@ "block-dependencies": "node scripts/frontend/block_dependencies.js", "clean": "rm -rf public/assets tmp/cache/*-loader", "dev-server": "NODE_OPTIONS=\"--max-old-space-size=3584\" node scripts/frontend/webpack_dev_server.js", - "eslint-fix": "echo 'Please use `yarn lint:eslint:all:fix` instead' && exit 1", - "eslint-staged": "echo 'Please use `yarn lint:eslint:staged` instead' && exit 1", - "eslint-staged-fix": "echo 'Please use `yarn lint:eslint:staged:fix` instead' && exit 1", - "eslint-report": "echo 'Please use `yarn lint:eslint:report` instead' && exit 1", "file-coverage": "scripts/frontend/file_test_coverage.js", "lint-docs": "scripts/lint-doc.sh", "internal:eslint": "eslint --cache --max-warnings 0 --report-unused-disable-directives --ext .js,.vue", @@ -39,10 +35,6 @@ "lint:stylelint:staged:fix": "yarn run lint:stylelint:staged --fix", "markdownlint": "markdownlint --config .markdownlint.json", "postinstall": "node ./scripts/frontend/postinstall.js", - "prettier-all": "echo 'Please use `yarn lint:prettier` instead' && exit 1", - "prettier-all-save": "echo 'Please use `yarn lint:prettier:fix` instead' && exit 1", - "prettier-staged": "echo 'Please use `yarn lint:prettier:staged` instead' && exit 1", - "prettier-staged-save": "echo 'Please use `yarn lint:prettier:staged:fix` instead' && exit 1", "stylelint-create-utility-map": "node scripts/frontend/stylelint/stylelint-utility-map.js", "webpack": "NODE_OPTIONS=\"--max-old-space-size=3584\" webpack --config config/webpack.config.js", "webpack-vendor": "NODE_OPTIONS=\"--max-old-space-size=3584\" webpack --config config/webpack.vendor.config.js", diff --git a/spec/frontend/pager_spec.js b/spec/frontend/pager_spec.js index ad4222e7cb2..95679a51c6d 100644 --- a/spec/frontend/pager_spec.js +++ b/spec/frontend/pager_spec.js @@ -32,38 +32,12 @@ describe('pager', () => { window.history.replaceState({}, null, originalHref); }); - it('should use data-href attribute from list element', () => { - const href = `${TEST_HOST}/some_list.json`; - setFixtures(`
`); - Pager.init(); - - expect(Pager.url).toBe(href); - }); - - it('should use current url if data-href attribute not provided', () => { - const href = `${TEST_HOST}/some_list`; - removeParams.mockReturnValue(href); - Pager.init(); - - expect(Pager.url).toBe(href); - }); - it('should get initial offset from query parameter', () => { window.history.replaceState({}, null, '?offset=100'); Pager.init(); expect(Pager.offset).toBe(100); }); - - it('keeps extra query parameters from url', () => { - window.history.replaceState({}, null, '?filter=test&offset=100'); - const href = `${TEST_HOST}/some_list?filter=test`; - removeParams.mockReturnValue(href); - Pager.init(); - - expect(removeParams).toHaveBeenCalledWith(['limit', 'offset']); - expect(Pager.url).toEqual(href); - }); }); describe('getOld', () => { @@ -164,5 +138,50 @@ describe('pager', () => { done(); }); }); + + describe('has data-href attribute from list element', () => { + const href = `${TEST_HOST}/some_list.json`; + + beforeEach(() => { + setFixtures(`
`); + }); + + it('should use data-href attribute', () => { + Pager.getOld(); + + expect(axios.get).toHaveBeenCalledWith(href, expect.any(Object)); + }); + + it('should not use current url', () => { + Pager.getOld(); + + expect(removeParams).not.toHaveBeenCalled(); + expect(removeParams).not.toHaveBeenCalledWith(href); + }); + }); + + describe('no data-href attribute attribute provided from list element', () => { + beforeEach(() => { + setFixtures(`
`); + }); + + it('should use current url', () => { + const href = `${TEST_HOST}/some_list`; + removeParams.mockReturnValue(href); + Pager.getOld(); + + expect(axios.get).toHaveBeenCalledWith(href, expect.any(Object)); + }); + + it('keeps extra query parameters from url', () => { + window.history.replaceState({}, null, '?filter=test&offset=100'); + const href = `${TEST_HOST}/some_list?filter=test`; + removeParams.mockReturnValue(href); + Pager.getOld(); + + expect(removeParams).toHaveBeenCalledWith(['limit', 'offset']); + expect(axios.get).toHaveBeenCalledWith(href, expect.any(Object)); + }); + }); }); });