Commit 1b4e0a1e authored by Igor Drozdov's avatar Igor Drozdov

Merge branch '28827-download-subfolders-api' into 'master'

Support path parameter for repository download via API

See merge request gitlab-org/gitlab!71431
parents 73eda3ea ddf22f7e
...@@ -126,6 +126,7 @@ Supported attributes: ...@@ -126,6 +126,7 @@ Supported attributes:
## Get file archive ## Get file archive
> Support for [including Git LFS blobs](../topics/git/lfs/index.md#lfs-objects-in-project-archives) was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15079) in GitLab 13.5. > Support for [including Git LFS blobs](../topics/git/lfs/index.md#lfs-objects-in-project-archives) was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15079) in GitLab 13.5.
> Support for downloading a subfolder was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/28827) in GitLab 14.4.
Get an archive of the repository. This endpoint can be accessed without Get an archive of the repository. This endpoint can be accessed without
authentication if the repository is publicly accessible. authentication if the repository is publicly accessible.
...@@ -147,11 +148,12 @@ Supported attributes: ...@@ -147,11 +148,12 @@ Supported attributes:
|:------------|:---------------|:---------|:----------------------| |:------------|:---------------|:---------|:----------------------|
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
| `sha` | string | no | The commit SHA to download. A tag, branch reference, or SHA can be used. This defaults to the tip of the default branch if not specified. | | `sha` | string | no | The commit SHA to download. A tag, branch reference, or SHA can be used. This defaults to the tip of the default branch if not specified. |
| `path` | string | no | The subpath of the repository to download. This defaults to the whole repository (empty string). |
Example request: Example request:
```shell ```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.com/api/v4/projects/<project_id>/repository/archive?sha=<commit_sha>" curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.com/api/v4/projects/<project_id>/repository/archive?sha=<commit_sha>&path=<path>"
``` ```
## Compare branches, tags or commits ## Compare branches, tags or commits
......
...@@ -101,6 +101,7 @@ module API ...@@ -101,6 +101,7 @@ module API
params do params do
optional :sha, type: String, desc: 'The commit sha of the archive to be downloaded' optional :sha, type: String, desc: 'The commit sha of the archive to be downloaded'
optional :format, type: String, desc: 'The archive format' optional :format, type: String, desc: 'The archive format'
optional :path, type: String, desc: 'Subfolder of the repository to be downloaded'
end end
get ':id/repository/archive', requirements: { format: Gitlab::PathRegex.archive_formats_regex } do get ':id/repository/archive', requirements: { format: Gitlab::PathRegex.archive_formats_regex } do
if archive_rate_limit_reached?(current_user, user_project) if archive_rate_limit_reached?(current_user, user_project)
...@@ -109,7 +110,7 @@ module API ...@@ -109,7 +110,7 @@ module API
not_acceptable! if Gitlab::HotlinkingDetector.intercept_hotlinking?(request) not_acceptable! if Gitlab::HotlinkingDetector.intercept_hotlinking?(request)
send_git_archive user_project.repository, ref: params[:sha], format: params[:format], append_sha: true send_git_archive user_project.repository, ref: params[:sha], format: params[:format], append_sha: true, path: params[:path]
rescue StandardError rescue StandardError
not_found!('File') not_found!('File')
end end
......
...@@ -305,6 +305,18 @@ RSpec.describe API::Repositories do ...@@ -305,6 +305,18 @@ RSpec.describe API::Repositories do
end end
end end
it 'returns only a part of the repository with path set' do
path = 'bar'
get api("#{route}?path=#{path}", current_user)
expect(response).to have_gitlab_http_status(:ok)
type, params = workhorse_send_data
expect(type).to eq('git-archive')
expect(params['ArchivePath']).to match(/#{project.path}\-[^\.]+\-#{path}\.tar.gz/)
end
it 'rate limits user when thresholds hit' do it 'rate limits user when thresholds hit' do
allow(::Gitlab::ApplicationRateLimiter).to receive(:throttled?).and_return(true) allow(::Gitlab::ApplicationRateLimiter).to receive(:throttled?).and_return(true)
......
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