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>2020-06-25 06:08:52 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-06-25 06:08:52 +0300
commit03c38e31112a7dc0de78325e5421e6bb08c508ed (patch)
tree945f4eb57701ea8887d9c9beca06c67d9d01ad8d
parent5d6119a1a4d31009ea7aee400c8462e897ddc26c (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--app/graphql/resolvers/release_resolver.rb2
-rw-r--r--app/graphql/resolvers/releases_resolver.rb2
-rw-r--r--app/graphql/types/project_type.rb4
-rw-r--r--changelogs/unreleased/nfriend-enable-graphql_release_data-feature-flag.yml5
-rw-r--r--doc/api/graphql/reference/gitlab_schema.graphql4
-rw-r--r--doc/api/graphql/reference/gitlab_schema.json4
-rw-r--r--doc/api/graphql/reference/index.md2
-rw-r--r--doc/api/group_wikis.md196
-rw-r--r--doc/development/documentation/index.md83
-rw-r--r--doc/development/documentation/styleguide.md18
-rw-r--r--doc/development/integrations/secure.md8
-rw-r--r--doc/user/application_security/container_scanning/index.md2
-rw-r--r--doc/user/application_security/dependency_scanning/index.md2
-rw-r--r--doc/user/application_security/sast/index.md8
-rw-r--r--doc/user/application_security/secret_detection/index.md2
-rw-r--r--doc/user/markdown.md2
-rw-r--r--doc/user/project/issue_board.md24
-rw-r--r--doc/user/project/issues/index.md2
-rw-r--r--lib/api/helpers.rb6
-rw-r--r--lib/api/helpers/wikis_helpers.rb35
-rw-r--r--lib/api/wikis.rb204
-rw-r--r--spec/requests/api/graphql/project/release_spec.rb17
-rw-r--r--spec/requests/api/graphql/project/releases_spec.rb17
-rw-r--r--spec/requests/api/wikis_spec.rb304
-rw-r--r--spec/support/shared_examples/lib/wikis_api_examples.rb174
25 files changed, 718 insertions, 409 deletions
diff --git a/app/graphql/resolvers/release_resolver.rb b/app/graphql/resolvers/release_resolver.rb
index 9bae8b8cd13..1edcc8c70b5 100644
--- a/app/graphql/resolvers/release_resolver.rb
+++ b/app/graphql/resolvers/release_resolver.rb
@@ -15,6 +15,8 @@ module Resolvers
end
def resolve(tag_name:)
+ return unless Feature.enabled?(:graphql_release_data, project, default_enabled: true)
+
ReleasesFinder.new(
project,
current_user,
diff --git a/app/graphql/resolvers/releases_resolver.rb b/app/graphql/resolvers/releases_resolver.rb
index b2afbb92684..85892c2abeb 100644
--- a/app/graphql/resolvers/releases_resolver.rb
+++ b/app/graphql/resolvers/releases_resolver.rb
@@ -12,6 +12,8 @@ module Resolvers
end
def resolve(**args)
+ return unless Feature.enabled?(:graphql_release_data, project, default_enabled: true)
+
ReleasesFinder.new(
project,
current_user
diff --git a/app/graphql/types/project_type.rb b/app/graphql/types/project_type.rb
index f83faa36396..cbc75b5770c 100644
--- a/app/graphql/types/project_type.rb
+++ b/app/graphql/types/project_type.rb
@@ -243,15 +243,13 @@ module Types
Types::ReleaseType.connection_type,
null: true,
description: 'Releases of the project',
- resolver: Resolvers::ReleasesResolver,
- feature_flag: :graphql_release_data
+ resolver: Resolvers::ReleasesResolver
field :release,
Types::ReleaseType,
null: true,
description: 'A single release of the project',
resolver: Resolvers::ReleasesResolver.single,
- feature_flag: :graphql_release_data,
authorize: :download_code
field :container_expiration_policy,
diff --git a/changelogs/unreleased/nfriend-enable-graphql_release_data-feature-flag.yml b/changelogs/unreleased/nfriend-enable-graphql_release_data-feature-flag.yml
new file mode 100644
index 00000000000..b56c2337149
--- /dev/null
+++ b/changelogs/unreleased/nfriend-enable-graphql_release_data-feature-flag.yml
@@ -0,0 +1,5 @@
+---
+title: Add release data to GraphQL endpoint
+merge_request: 34937
+author:
+type: added
diff --git a/doc/api/graphql/reference/gitlab_schema.graphql b/doc/api/graphql/reference/gitlab_schema.graphql
index 772f79c2204..502dac666ee 100644
--- a/doc/api/graphql/reference/gitlab_schema.graphql
+++ b/doc/api/graphql/reference/gitlab_schema.graphql
@@ -9289,7 +9289,7 @@ type Project {
publicJobs: Boolean
"""
- A single release of the project. Available only when feature flag `graphql_release_data` is enabled
+ A single release of the project
"""
release(
"""
@@ -9299,7 +9299,7 @@ type Project {
): Release
"""
- Releases of the project. Available only when feature flag `graphql_release_data` is enabled
+ Releases of the project
"""
releases(
"""
diff --git a/doc/api/graphql/reference/gitlab_schema.json b/doc/api/graphql/reference/gitlab_schema.json
index e041c5270ca..aecc533931e 100644
--- a/doc/api/graphql/reference/gitlab_schema.json
+++ b/doc/api/graphql/reference/gitlab_schema.json
@@ -27364,7 +27364,7 @@
},
{
"name": "release",
- "description": "A single release of the project. Available only when feature flag `graphql_release_data` is enabled",
+ "description": "A single release of the project",
"args": [
{
"name": "tagName",
@@ -27391,7 +27391,7 @@
},
{
"name": "releases",
- "description": "Releases of the project. Available only when feature flag `graphql_release_data` is enabled",
+ "description": "Releases of the project",
"args": [
{
"name": "after",
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index ab078c0697b..bba6cd98b27 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -1353,7 +1353,7 @@ Information about pagination in a connection.
| `pipeline` | Pipeline | Build pipeline of the project |
| `printingMergeRequestLinkEnabled` | Boolean | Indicates if a link to create or view a merge request should display after a push to Git repositories of the project from the command line |
| `publicJobs` | Boolean | Indicates if there is public access to pipelines and job details of the project, including output logs and artifacts |
-| `release` | Release | A single release of the project. Available only when feature flag `graphql_release_data` is enabled |
+| `release` | Release | A single release of the project |
| `removeSourceBranchAfterMerge` | Boolean | Indicates if `Delete source branch` option should be enabled by default for all new merge requests of the project |
| `repository` | Repository | Git repository of the project |
| `requestAccessEnabled` | Boolean | Indicates if users can request member access to the project |
diff --git a/doc/api/group_wikis.md b/doc/api/group_wikis.md
new file mode 100644
index 00000000000..62094ffc940
--- /dev/null
+++ b/doc/api/group_wikis.md
@@ -0,0 +1,196 @@
+# Wikis API
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/212199) in GitLab 13.2.
+
+Available only in APIv4.
+
+## List wiki pages
+
+List all wiki pages for a given group.
+
+```plaintext
+GET /groups/:id/wikis
+```
+
+| Attribute | Type | Required | Description |
+| --------- | ------- | -------- | --------------------- |
+| `id` | integer/string | yes | The ID or [URL-encoded path of the group](README.md#namespaced-path-encoding) |
+| `with_content` | boolean | no | Include pages' content |
+
+```shell
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/1/wikis?with_content=1"
+```
+
+Example response:
+
+```json
+[
+ {
+ "content" : "Here is an instruction how to deploy this project.",
+ "format" : "markdown",
+ "slug" : "deploy",
+ "title" : "deploy"
+ },
+ {
+ "content" : "Our development process is described here.",
+ "format" : "markdown",
+ "slug" : "development",
+ "title" : "development"
+ },{
+ "content" : "* [Deploy](deploy)\n* [Development](development)",
+ "format" : "markdown",
+ "slug" : "home",
+ "title" : "home"
+ }
+]
+```
+
+## Get a wiki page
+
+Get a wiki page for a given group.
+
+```plaintext
+GET /groups/:id/wikis/:slug
+```
+
+| Attribute | Type | Required | Description |
+| --------- | ------- | -------- | --------------------- |
+| `id` | integer/string | yes | The ID or [URL-encoded path of the group](README.md#namespaced-path-encoding) |
+| `slug` | string | yes | The slug (a unique string) of the wiki page |
+
+```shell
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/1/wikis/home"
+```
+
+Example response:
+
+```json
+{
+ "content" : "home page",
+ "format" : "markdown",
+ "slug" : "home",
+ "title" : "home"
+}
+```
+
+## Create a new wiki page
+
+Create a new wiki page for the given repository with the given title, slug, and content.
+
+```plaintext
+POST /projects/:id/wikis
+```
+
+| Attribute | Type | Required | Description |
+| ------------- | ------- | -------- | ---------------------------- |
+| `id` | integer/string | yes | The ID or [URL-encoded path of the group](README.md#namespaced-path-encoding) |
+| `content` | string | yes | The content of the wiki page |
+| `title` | string | yes | The title of the wiki page |
+| `format` | string | no | The format of the wiki page. Available formats are: `markdown` (default), `rdoc`, `asciidoc` and `org` |
+
+```shell
+curl --data "format=rdoc&title=Hello&content=Hello world" \
+ --header "PRIVATE-TOKEN: <your_access_token>" \
+ "https://gitlab.example.com/api/v4/groups/1/wikis"
+```
+
+Example response:
+
+```json
+{
+ "content" : "Hello world",
+ "format" : "markdown",
+ "slug" : "Hello",
+ "title" : "Hello"
+}
+```
+
+## Edit an existing wiki page
+
+Update an existing wiki page. At least one parameter is required to update the wiki page.
+
+```plaintext
+PUT /groups/:id/wikis/:slug
+```
+
+| Attribute | Type | Required | Description |
+| --------------- | ------- | --------------------------------- | ------------------------------- |
+| `id` | integer/string | yes | The ID or [URL-encoded path of the group](README.md#namespaced-path-encoding) |
+| `content` | string | yes if `title` is not provided | The content of the wiki page |
+| `title` | string | yes if `content` is not provided | The title of the wiki page |
+| `format` | string | no | The format of the wiki page. Available formats are: `markdown` (default), `rdoc`, `asciidoc` and `org` |
+| `slug` | string | yes | The slug (a unique identifier) of the wiki page |
+
+```shell
+curl --request PUT --data "format=rdoc&content=documentation&title=Docs" \
+ --header "PRIVATE-TOKEN: <your_access_token>" \
+ "https://gitlab.example.com/api/v4/groups/1/wikis/foo"
+```
+
+Example response:
+
+```json
+{
+ "content" : "documentation",
+ "format" : "markdown",
+ "slug" : "Docs",
+ "title" : "Docs"
+}
+```
+
+## Delete a wiki page
+
+Delete a wiki page with a given slug.
+
+```plaintext
+DELETE /groups/:id/wikis/:slug
+```
+
+| Attribute | Type | Required | Description |
+| --------- | ------- | -------- | --------------------- |
+| `id` | integer/string | yes | The ID or [URL-encoded path of the group](README.md#namespaced-path-encoding) |
+| `slug` | string | yes | The slug (a unique identifier) of the wiki page |
+
+```shell
+curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/1/wikis/foo"
+```
+
+On success the HTTP status code is `204` and no JSON response is expected.
+
+## Upload an attachment to the wiki repository
+
+Upload a file to the attachment folder inside the wiki's repository. The
+attachment folder is the `uploads` folder.
+
+```plaintext
+POST /groups/:id/wikis/attachments
+```
+
+| Attribute | Type | Required | Description |
+| ------------- | ------- | -------- | ---------------------------- |
+| `id` | integer/string | yes | The ID or [URL-encoded path of the group](README.md#namespaced-path-encoding) |
+| `file` | string | yes | The attachment to be uploaded |
+| `branch` | string | no | The name of the branch. Defaults to the wiki repository default branch |
+
+To upload a file from your filesystem, use the `--form` argument. This causes
+cURL to post data using the header `Content-Type: multipart/form-data`.
+The `file=` parameter must point to a file on your filesystem and be preceded
+by `@`. For example:
+
+```shell
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" --form "file=@dk.png" "https://gitlab.example.com/api/v4/groups/1/wikis/attachments"
+```
+
+Example response:
+
+```json
+{
+ "file_name" : "dk.png",
+ "file_path" : "uploads/6a061c4cf9f1c28cb22c384b4b8d4e3c/dk.png",
+ "branch" : "master",
+ "link" : {
+ "url" : "uploads/6a061c4cf9f1c28cb22c384b4b8d4e3c/dk.png",
+ "markdown" : "![dk](uploads/6a061c4cf9f1c28cb22c384b4b8d4e3c/dk.png)"
+ }
+}
+```
diff --git a/doc/development/documentation/index.md b/doc/development/documentation/index.md
index e2c042f9c2e..096e36ebf66 100644
--- a/doc/development/documentation/index.md
+++ b/doc/development/documentation/index.md
@@ -70,7 +70,28 @@ See the [Structure](styleguide.md#structure) section of the [Documentation Style
## Metadata
To provide additional directives or useful information, we add metadata in YAML
-format to the beginning of each product documentation page.
+format to the beginning of each product documentation page (YAML front matter).
+All values are treated as strings and are only used for the
+[docs website](site_architecture/index.md).
+
+### Stage and group metadata
+
+Each page should ideally have metadata related to the stage and group it
+belongs to, as well as an information block as described below:
+
+- `stage`: The [Stage](https://about.gitlab.com/handbook/product/categories/#devops-stages)
+ to which the majority of the page's content belongs.
+- `group`: The [Group](https://about.gitlab.com/company/team/structure/#product-groups)
+ to which the majority of the page's content belongs.
+- `info`: The following line, which provides direction to contributors regarding
+ how to contact the Technical Writer associated with the page's Stage and
+ Group:
+
+ ```plaintext
+ To determine the technical writer assigned to the Stage/Group
+ associated with this page, see
+ https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
+ ```
For example, the following metadata would be at the beginning of a product
documentation page whose content is primarily associated with the Audit Events
@@ -84,24 +105,64 @@ info: To determine the technical writer assigned to the Stage/Group associated w
---
```
-The following list describes the YAML parameters in use:
+### Page type metadata
+
+Originally discussed in [this epic](https://gitlab.com/groups/gitlab-org/-/epics/1280),
+each page should have a `type` metadata. It can be one or more of the following:
+
+- `index`: Index/overview pages. They serve as a list to other pages. Doesn't
+ necessarily mean the page should be named `index.md`. [Example page](../../install/README.md).
+- `concepts`: What you need to know before using product. Informational, not
+ instructional. For example, abstract ideas, explain meaning or benefit, support
+ understanding of tasks. They are read for background information, for example
+ "Why X is important". [Example page](../../topics/autodevops/index.md).
+- `howto`: Specific use case instructions. [Example page](../../ssh/README.md).
+- `tutorial`: Learn a process/concept by doing. [Example page](../../gitlab-basics/start-using-git.md).
+- `reference`: Covers what things are/do. Things like specific settings, facts
+ without too much explanation that are read for detailed information.
+ [Example page](../../ci/yaml/README.md).
+
+### Redirection metadata
+
+The following metadata should be added when a page is moved to another location:
- `redirect_to`: The relative path and filename (with an `.md` extension) of the
location to which visitors should be redirected for a moved page.
[Learn more](#changing-document-location).
-- `stage`: The [Stage](https://about.gitlab.com/handbook/product/categories/#devops-stages)
- to which the majority of the page's content belongs.
-- `group`: The [Group](https://about.gitlab.com/company/team/structure/#product-groups)
- to which the majority of the page's content belongs.
-- `info`: The following line, which provides direction to contributors regarding
- how to contact the Technical Writer associated with the page's Stage and
- Group: `To determine the technical writer assigned to the Stage/Group
- associated with this page, see
- https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers`
- `disqus_identifier`: Identifier for Disqus commenting system. Used to keep
comments with a page that's been moved to a new URL.
[Learn more](#redirections-for-pages-with-disqus-comments).
+### Comments metadata
+
+The [docs website](site_architecture/index.md) has comments (provided by Disqus)
+enabled by default. In case you want to disable them (for example in index pages),
+set it to `false`:
+
+```yaml
+---
+comments: false
+---
+```
+
+### Additional page metadata
+
+Each page can have additional (optional) metadata (set in the
+[default.html](https://gitlab.com/gitlab-org/gitlab-docs/-/blob/fc3577921343173d589dfa43d837b4307e4e620f/layouts/default.html#L30-52)
+Nanoc layout), which will be shown to the top of the page if defined:
+
+- `author`: The name of the author of a page, usually a tutorial. It requires `author_gitlab` in order to be shown.
+- `author_gitlab`: The username of the author on GitLab.com. It requires `author` in order to be shown.
+- `date`: The date the page was created, usually for tutorials.
+- `article_type`: The type of article. Can be either `tutorial` or `user guide`.
+- `level`: The level of complexity of a how-to or tutorial. Can be either `beginner`,
+ `advanced`, or `intermediate`.
+- `last_updated`: The date in ISO format when the page was last updated. For example `2020-02-14`.
+- `reading_time`: If you want to add an indication of the approximate reading
+ time of a page, you can set `reading_time` to `true`. This uses a simple
+ [algorithm](https://gitlab.com/gitlab-org/gitlab-docs/-/blob/master/lib/helpers/reading_time.rb)
+ to calculate the reading time based on the number of words.
+
## Changing document location
Changing a document's location requires specific steps to ensure that
diff --git a/doc/development/documentation/styleguide.md b/doc/development/documentation/styleguide.md
index abcd1afacb4..b10136a6ffe 100644
--- a/doc/development/documentation/styleguide.md
+++ b/doc/development/documentation/styleguide.md
@@ -876,8 +876,6 @@ Inside the document:
- Always use a proper description for what the image is about. That way, when a
browser fails to show the image, this text will be used as an alternative
description.
-- If a heading is placed right after an image, always add three dashes (`---`)
- between the image and the heading.
### Remove image shadow
@@ -1336,6 +1334,22 @@ a helpful link back to how the feature was developed.
> - [Moved](<link-to-issue>) to GitLab Core in 12.0.
```
+- If a feature is deprecated, include a link to a replacement (when available):
+
+ ```markdown
+ > - [Deprecated](<link-to-issue>) in GitLab 11.3. Replaced by [meaningful text](<link-to-appropriate-documentation>).
+ ```
+
+ It's also acceptable to describe the replacement in surrounding text, if available.
+
+ If the deprecation is not obvious in existing text, you may want to include a warning such as:
+
+ ```markdown
+ CAUTION: **Warning:**
+ This feature was [deprecated](link-to-issue) in GitLab 12.3
+ and replaced by [Feature name](link-to-feature-documentation).
+ ```
+
NOTE: **Note:**
Version text must be on its own line and surrounded by blank lines to render correctly.
diff --git a/doc/development/integrations/secure.md b/doc/development/integrations/secure.md
index 33fd468140f..d922bd85bd0 100644
--- a/doc/development/integrations/secure.md
+++ b/doc/development/integrations/secure.md
@@ -239,17 +239,15 @@ one set in the `SECURE_LOG_LEVEL` variable. For instance, `info` and `warn`
messages should be skipped when `SECURE_LOG_LEVEL` is set to `error`. Accepted
values are as follows, listed from highest to lowest:
-- `panic`
- `fatal`
- `error`
- `warn`
- `info`
- `debug`
-- `trace`
-It is recommended to use the `debug` and `trace` levels for verbose logging
-that could be useful when debugging. The default value for `SECURE_LOG_LEVEL`
-should be set to `info`.
+It is recommended to use the `debug` level for verbose logging that could be
+useful when debugging. The default value for `SECURE_LOG_LEVEL` should be set
+to `info`.
#### common logutil package
diff --git a/doc/user/application_security/container_scanning/index.md b/doc/user/application_security/container_scanning/index.md
index 4bf1c6ae1c6..99feacd821b 100644
--- a/doc/user/application_security/container_scanning/index.md
+++ b/doc/user/application_security/container_scanning/index.md
@@ -174,7 +174,7 @@ using environment variables.
| `CLAIR_DB_IMAGE_TAG` | (**DEPRECATED - use `CLAIR_DB_IMAGE` instead**) The Docker image tag for the [PostgreSQL server hosting the vulnerabilities definitions](https://hub.docker.com/r/arminc/clair-db). It can be useful to override this value with a specific version, for example, to provide a consistent set of vulnerabilities for integration testing purposes. | `latest` |
| `DOCKERFILE_PATH` | The path to the `Dockerfile` to be used for generating remediations. By default, the scanner will look for a file named `Dockerfile` in the root directory of the project, so this variable should only be configured if your `Dockerfile` is in a non-standard location, such as a subdirectory. See [Solutions for vulnerabilities](#solutions-for-vulnerabilities-auto-remediation) for more details. | `Dockerfile` |
| `ADDITIONAL_CA_CERT_BUNDLE` | Bundle of CA certs that you want to trust. | "" |
-| `SECURE_LOG_LEVEL` | The log levels available are: `panic`, `fatal`, `error`, `warn`, `info`, `debug`, `trace` | `info` |
+| `SECURE_LOG_LEVEL` | The log levels available are: `fatal`, `error`, `warn`, `info`, `debug` | `info` |
### Overriding the Container Scanning template
diff --git a/doc/user/application_security/dependency_scanning/index.md b/doc/user/application_security/dependency_scanning/index.md
index 65aa145da60..c462faf3a64 100644
--- a/doc/user/application_security/dependency_scanning/index.md
+++ b/doc/user/application_security/dependency_scanning/index.md
@@ -155,7 +155,7 @@ The following variables allow configuration of global dependency scanning settin
| `DS_DISABLE_DIND` | Disable Docker-in-Docker and run analyzers [individually](#enabling-docker-in-docker). This variable is `true` by default. |
| `ADDITIONAL_CA_CERT_BUNDLE` | Bundle of CA certs to trust. |
| `DS_EXCLUDED_PATHS` | Exclude vulnerabilities from output based on the paths. A comma-separated list of patterns. Patterns can be globs, or file or folder paths (for example, `doc,spec`). Parent directories also match patterns. Default: `"spec, test, tests, tmp"` |
-| `SECURE_LOG_LEVEL` | Default log level is `info`, you can set it to any of the following strings: `panic`, `fatal`, `error`, `warn`, `info`, `debug`, `trace`. |
+| `SECURE_LOG_LEVEL` | Default log level is `info`, you can set it to any of the following strings: `fatal`, `error`, `warn`, `info`, `debug`. |
#### Configuring Docker-in-Docker orchestrator
diff --git a/doc/user/application_security/sast/index.md b/doc/user/application_security/sast/index.md
index b70272515a7..d612850f650 100644
--- a/doc/user/application_security/sast/index.md
+++ b/doc/user/application_security/sast/index.md
@@ -289,13 +289,11 @@ SAST can be [configured](#customizing-the-sast-settings) using environment varia
You can control the verbosity of logs by setting the `SECURE_LOG_LEVEL` env var. The default is set to `info`, you can set it to any of the following levels:
-- `panic`
- `fatal`
- `error`
- `warn`
- `info`
- `debug`
-- `trace`
#### Custom Certificate Authority
@@ -320,13 +318,13 @@ Some analyzers make it possible to filter out vulnerabilities under a given thre
| Environment variable | Default value | Description |
|-------------------------|---------------|-------------|
| `SAST_EXCLUDED_PATHS` | `spec, test, tests, tmp` | Exclude vulnerabilities from output based on the paths. This is a comma-separated list of patterns. Patterns can be globs, or file or folder paths (for example, `doc,spec` ). Parent directories will also match patterns. |
-| `SAST_BANDIT_EXCLUDED_PATHS` | - | comma-separated list of paths to exclude from scan. Uses Python's [`fnmatch` syntax](https://docs.python.org/2/library/fnmatch.html); For example: `'*/tests/*'` |
+| `SAST_BANDIT_EXCLUDED_PATHS` | | comma-separated list of paths to exclude from scan. Uses Python's [`fnmatch` syntax](https://docs.python.org/2/library/fnmatch.html); For example: `'*/tests/*'` |
| `SAST_BRAKEMAN_LEVEL` | 1 | Ignore Brakeman vulnerabilities under given confidence level. Integer, 1=Low 3=High. |
| `SAST_FLAWFINDER_LEVEL` | 1 | Ignore Flawfinder vulnerabilities under given risk level. Integer, 0=No risk, 5=High risk. |
| `SAST_GITLEAKS_ENTROPY_LEVEL` | 8.0 | Minimum entropy for secret detection. Float, 0.0 = low, 8.0 = high. |
| `SAST_GOSEC_LEVEL` | 0 | Ignore Gosec vulnerabilities under given confidence level. Integer, 0=Undefined, 1=Low, 2=Medium, 3=High. |
-| `SAST_GITLEAKS_COMMIT_FROM` | - | The commit a Gitleaks scan starts at. |
-| `SAST_GITLEAKS_COMMIT_TO` | - | The commit a Gitleaks scan ends at. |
+| `SAST_GITLEAKS_COMMIT_FROM` | | The commit a Gitleaks scan starts at. |
+| `SAST_GITLEAKS_COMMIT_TO` | | The commit a Gitleaks scan ends at. |
| `SAST_GITLEAKS_HISTORIC_SCAN` | false | Flag to enable a historic Gitleaks scan. |
#### Docker-in-Docker orchestrator
diff --git a/doc/user/application_security/secret_detection/index.md b/doc/user/application_security/secret_detection/index.md
index c47d4ae9996..b0bac0095a6 100644
--- a/doc/user/application_security/secret_detection/index.md
+++ b/doc/user/application_security/secret_detection/index.md
@@ -150,13 +150,11 @@ Secret Detection can be customized by defining available variables:
You can control the verbosity of logs by setting the `SECURE_LOG_LEVEL` env var. The default is set to `info`, you can set it to any of the following levels:
-- `panic`
- `fatal`
- `error`
- `warn`
- `info`
- `debug`
-- `trace`
## Full History Secret Scan
diff --git a/doc/user/markdown.md b/doc/user/markdown.md
index 0d028cfe77a..999c49cbc3c 100644
--- a/doc/user/markdown.md
+++ b/doc/user/markdown.md
@@ -502,8 +502,6 @@ Second section content.
![Preview of an auto-generated TOC in a Wiki](img/markdown_toc_preview_v12_9.png)
----
-
### Wiki-specific Markdown
The following examples show how links inside wikis behave.
diff --git a/doc/user/project/issue_board.md b/doc/user/project/issue_board.md
index 89b17609698..1831563332f 100644
--- a/doc/user/project/issue_board.md
+++ b/doc/user/project/issue_board.md
@@ -42,8 +42,6 @@ Check all the [GitLab Enterprise features for issue boards](#gitlab-enterprise-f
![GitLab issue boards - Premium](img/issue_boards_premium.png)
----
-
## How it works
The Issue Board feature builds on GitLab's existing
@@ -98,8 +96,6 @@ If you have the labels "**backend**", "**frontend**", "**staging**", and
![issue card moving](img/issue_board_move_issue_card_list.png)
----
-
### Use cases for multiple issue boards
With [multiple issue boards](#multiple-issue-boards),
@@ -252,8 +248,6 @@ clicking **View scope**.
![Viewing board configuration](img/issue_board_view_scope.png)
----
-
### Focus mode
> - [Introduced]((https://about.gitlab.com/releases/2017/04/22/gitlab-9-1-released/#issue-boards-focus-mode-ees-eep)) in [GitLab Starter](https://about.gitlab.com/pricing/) 9.1.
@@ -275,8 +269,6 @@ especially in combination with [assignee lists](#assignee-lists-premium).
![issue board summed weights](img/issue_board_summed_weights.png)
----
-
### Group issue boards **(PREMIUM)**
> [Introduced](https://about.gitlab.com/releases/2017/09/22/gitlab-10-0-released/#group-issue-boards) in [GitLab Premium](https://about.gitlab.com/pricing/) 10.0.
@@ -292,8 +284,6 @@ Multiple group issue boards were originally [introduced](https://about.gitlab.co
![Group issue board](img/group_issue_board.png)
----
-
### Assignee lists **(PREMIUM)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/5784) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.0.
@@ -313,8 +303,6 @@ To remove an assignee list, just as with a label list, click the trash icon.
![Assignee lists](img/issue_board_assignee_lists.png)
----
-
### Milestone lists **(PREMIUM)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/6469) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.2.
@@ -332,8 +320,6 @@ As in other list types, click the trash icon to remove a list.
![Milestone lists](img/issue_board_milestone_lists.png)
----
-
## Work In Progress limits **(STARTER)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/11403) in GitLab 12.7
@@ -365,8 +351,6 @@ status.
![Blocked issues](img/issue_boards_blocked_icon_v12_8.png)
----
-
## Actions you can take on an issue board
- [Create a new list](#create-a-new-list).
@@ -437,8 +421,6 @@ the list by filtering by author, assignee, milestone, and label.
![Bulk adding issues to lists](img/issue_boards_add_issues_modal.png)
----
-
### Remove an issue from a list
Removing an issue from a list can be done by clicking the issue card and then
@@ -447,8 +429,6 @@ respective label is removed.
![Remove issue from list](img/issue_boards_remove_issue.png)
----
-
### Filter issues
You should be able to use the filters on top of your issue board to show only
@@ -492,8 +472,6 @@ to another list the label changes and a system not is recorded.
![issue board system notes](img/issue_board_system_notes.png)
----
-
### Drag issues between lists
When dragging issues between lists, different behavior occurs depending on the source list and the target list.
@@ -518,8 +496,6 @@ To select and move multiple cards:
![Multi-select Issue Cards](img/issue_boards_multi_select_v12_4.png)
----
-
### Issue ordering in a list
When visiting a board, issues appear ordered in any list. You're able to change
diff --git a/doc/user/project/issues/index.md b/doc/user/project/issues/index.md
index 06a80672769..9113f5344ba 100644
--- a/doc/user/project/issues/index.md
+++ b/doc/user/project/issues/index.md
@@ -175,8 +175,6 @@ requires [GraphQL](../../../api/graphql/index.md) to be enabled.
![Similar issues](img/similar_issues.png)
----
-
### Health status **(ULTIMATE)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/36427) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.10.
diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb
index b1bbc3cf0fd..d8569dea4f1 100644
--- a/lib/api/helpers.rb
+++ b/lib/api/helpers.rb
@@ -79,12 +79,6 @@ module API
@project ||= find_project!(params[:id])
end
- def wiki_page
- page = ProjectWiki.new(user_project, current_user).find_page(params[:slug])
-
- page || not_found!('Wiki Page')
- end
-
def available_labels_for(label_parent, include_ancestor_groups: true)
search_params = { include_ancestor_groups: include_ancestor_groups }
diff --git a/lib/api/helpers/wikis_helpers.rb b/lib/api/helpers/wikis_helpers.rb
new file mode 100644
index 00000000000..49da1e317ab
--- /dev/null
+++ b/lib/api/helpers/wikis_helpers.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+module API
+ module Helpers
+ module WikisHelpers
+ def self.wiki_resource_kinds
+ [:projects]
+ end
+
+ def find_container(kind)
+ return user_project if kind == :projects
+
+ raise "Unknown wiki container #{kind}"
+ end
+
+ def wiki_page
+ Wiki.for_container(container, current_user).find_page(params[:slug]) || not_found!('Wiki Page')
+ end
+
+ def commit_params(attrs)
+ base_params = { branch_name: attrs[:branch] }
+ file_details = case attrs[:file]
+ when Hash # legacy format: TODO remove when we drop support for non accelerated uploads
+ { file_name: attrs[:file][:filename], file_content: attrs[:file][:tempfile].read }
+ else
+ { file_name: attrs[:file].original_filename, file_content: attrs[:file].read }
+ end
+
+ base_params.merge(file_details)
+ end
+ end
+ end
+end
+
+API::Helpers::WikisHelpers.prepend_if_ee('EE::API::Helpers::WikisHelpers')
diff --git a/lib/api/wikis.rb b/lib/api/wikis.rb
index c1bf3a64923..006dc257fe1 100644
--- a/lib/api/wikis.rb
+++ b/lib/api/wikis.rb
@@ -2,24 +2,10 @@
module API
class Wikis < Grape::API
+ helpers ::API::Helpers::WikisHelpers
+
helpers do
- def commit_params(attrs)
- # In order to avoid service disruption this can work with an old workhorse without the acceleration
- # the first branch of this if must be removed when we drop support for non accelerated uploads
- if attrs[:file].is_a?(Hash)
- {
- file_name: attrs[:file][:filename],
- file_content: attrs[:file][:tempfile].read,
- branch_name: attrs[:branch]
- }
- else
- {
- file_name: attrs[:file].original_filename,
- file_content: attrs[:file].read,
- branch_name: attrs[:branch]
- }
- end
- end
+ attr_reader :container
params :common_wiki_page_params do
optional :format,
@@ -32,108 +18,118 @@ module API
WIKI_ENDPOINT_REQUIREMENTS = API::NAMESPACE_OR_PROJECT_REQUIREMENTS.merge(slug: API::NO_SLASH_URL_PART_REGEX)
- resource :projects, requirements: WIKI_ENDPOINT_REQUIREMENTS do
- desc 'Get a list of wiki pages' do
- success Entities::WikiPageBasic
- end
- params do
- optional :with_content, type: Boolean, default: false, desc: "Include pages' content"
- end
- get ':id/wikis' do
- authorize! :read_wiki, user_project
-
- entity = params[:with_content] ? Entities::WikiPage : Entities::WikiPageBasic
+ ::API::Helpers::WikisHelpers.wiki_resource_kinds.each do |container_resource|
+ resource container_resource, requirements: WIKI_ENDPOINT_REQUIREMENTS do
+ after_validation do
+ @container = Gitlab::Lazy.new { find_container(container_resource) }
+ end
- present user_project.wiki.list_pages(load_content: params[:with_content]), with: entity
- end
+ desc 'Get a list of wiki pages' do
+ success Entities::WikiPageBasic
+ end
+ params do
+ optional :with_content, type: Boolean, default: false, desc: "Include pages' content"
+ end
+ get ':id/wikis' do
+ authorize! :read_wiki, container
- desc 'Get a wiki page' do
- success Entities::WikiPage
- end
- params do
- requires :slug, type: String, desc: 'The slug of a wiki page'
- end
- get ':id/wikis/:slug' do
- authorize! :read_wiki, user_project
+ entity = params[:with_content] ? Entities::WikiPage : Entities::WikiPageBasic
- present wiki_page, with: Entities::WikiPage
- end
+ present container.wiki.list_pages(load_content: params[:with_content]), with: entity
+ end
- desc 'Create a wiki page' do
- success Entities::WikiPage
- end
- params do
- requires :title, type: String, desc: 'Title of a wiki page'
- requires :content, type: String, desc: 'Content of a wiki page'
- use :common_wiki_page_params
- end
- post ':id/wikis' do
- authorize! :create_wiki, user_project
+ desc 'Get a wiki page' do
+ success Entities::WikiPage
+ end
+ params do
+ requires :slug, type: String, desc: 'The slug of a wiki page'
+ end
+ get ':id/wikis/:slug' do
+ authorize! :read_wiki, container
- page = WikiPages::CreateService.new(container: user_project, current_user: current_user, params: params).execute
+ present wiki_page, with: Entities::WikiPage
+ end
- if page.valid?
- present page, with: Entities::WikiPage
- else
- render_validation_error!(page)
+ desc 'Create a wiki page' do
+ success Entities::WikiPage
end
- end
+ params do
+ requires :title, type: String, desc: 'Title of a wiki page'
+ requires :content, type: String, desc: 'Content of a wiki page'
+ use :common_wiki_page_params
+ end
+ post ':id/wikis' do
+ authorize! :create_wiki, container
- desc 'Update a wiki page' do
- success Entities::WikiPage
- end
- params do
- optional :title, type: String, desc: 'Title of a wiki page'
- optional :content, type: String, desc: 'Content of a wiki page'
- use :common_wiki_page_params
- at_least_one_of :content, :title, :format
- end
- put ':id/wikis/:slug' do
- authorize! :create_wiki, user_project
+ page = WikiPages::CreateService.new(container: container, current_user: current_user, params: params).execute
- page = WikiPages::UpdateService.new(container: user_project, current_user: current_user, params: params).execute(wiki_page)
+ if page.valid?
+ present page, with: Entities::WikiPage
+ else
+ render_validation_error!(page)
+ end
+ end
- if page.valid?
- present page, with: Entities::WikiPage
- else
- render_validation_error!(page)
+ desc 'Update a wiki page' do
+ success Entities::WikiPage
+ end
+ params do
+ optional :title, type: String, desc: 'Title of a wiki page'
+ optional :content, type: String, desc: 'Content of a wiki page'
+ use :common_wiki_page_params
+ at_least_one_of :content, :title, :format
+ end
+ put ':id/wikis/:slug' do
+ authorize! :create_wiki, container
+
+ page = WikiPages::UpdateService
+ .new(container: container, current_user: current_user, params: params)
+ .execute(wiki_page)
+
+ if page.valid?
+ present page, with: Entities::WikiPage
+ else
+ render_validation_error!(page)
+ end
end
- end
- desc 'Delete a wiki page'
- params do
- requires :slug, type: String, desc: 'The slug of a wiki page'
- end
- delete ':id/wikis/:slug' do
- authorize! :admin_wiki, user_project
+ desc 'Delete a wiki page'
+ params do
+ requires :slug, type: String, desc: 'The slug of a wiki page'
+ end
+ delete ':id/wikis/:slug' do
+ authorize! :admin_wiki, container
- WikiPages::DestroyService.new(container: user_project, current_user: current_user).execute(wiki_page)
+ WikiPages::DestroyService
+ .new(container: container, current_user: current_user)
+ .execute(wiki_page)
- no_content!
- end
+ no_content!
+ end
- desc 'Upload an attachment to the wiki repository' do
- detail 'This feature was introduced in GitLab 11.3.'
- success Entities::WikiAttachment
- end
- params do
- requires :file, types: [::API::Validations::Types::SafeFile, ::API::Validations::Types::WorkhorseFile], desc: 'The attachment file to be uploaded'
- optional :branch, type: String, desc: 'The name of the branch'
- end
- post ":id/wikis/attachments" do
- authorize! :create_wiki, user_project
-
- result = ::Wikis::CreateAttachmentService.new(
- container: user_project,
- current_user: current_user,
- params: commit_params(declared_params(include_missing: false))
- ).execute
-
- if result[:status] == :success
- status(201)
- present OpenStruct.new(result[:result]), with: Entities::WikiAttachment
- else
- render_api_error!(result[:message], 400)
+ desc 'Upload an attachment to the wiki repository' do
+ detail 'This feature was introduced in GitLab 11.3.'
+ success Entities::WikiAttachment
+ end
+ params do
+ requires :file, types: [::API::Validations::Types::SafeFile, ::API::Validations::Types::WorkhorseFile], desc: 'The attachment file to be uploaded'
+ optional :branch, type: String, desc: 'The name of the branch'
+ end
+ post ":id/wikis/attachments" do
+ authorize! :create_wiki, container
+
+ result = ::Wikis::CreateAttachmentService.new(
+ container: container,
+ current_user: current_user,
+ params: commit_params(declared_params(include_missing: false))
+ ).execute
+
+ if result[:status] == :success
+ status(201)
+ present OpenStruct.new(result[:result]), with: Entities::WikiAttachment
+ else
+ render_api_error!(result[:message], 400)
+ end
end
end
end
diff --git a/spec/requests/api/graphql/project/release_spec.rb b/spec/requests/api/graphql/project/release_spec.rb
index bd3e5b5c340..f9c19d9747d 100644
--- a/spec/requests/api/graphql/project/release_spec.rb
+++ b/spec/requests/api/graphql/project/release_spec.rb
@@ -354,4 +354,21 @@ RSpec.describe 'Query.project(fullPath).release(tagName)' do
end
end
end
+
+ describe 'ensures that the release data can be contolled by a feature flag' do
+ context 'when the graphql_release_data feature flag is disabled' do
+ let_it_be(:project) { create(:project, :repository, :public) }
+ let_it_be(:release) { create(:release, project: project) }
+
+ let(:current_user) { developer }
+
+ before do
+ stub_feature_flags(graphql_release_data: false)
+
+ project.add_developer(developer)
+ end
+
+ it_behaves_like 'no access to the release field'
+ end
+ end
end
diff --git a/spec/requests/api/graphql/project/releases_spec.rb b/spec/requests/api/graphql/project/releases_spec.rb
index 0d20acad279..9d0387e6469 100644
--- a/spec/requests/api/graphql/project/releases_spec.rb
+++ b/spec/requests/api/graphql/project/releases_spec.rb
@@ -264,4 +264,21 @@ describe 'Query.project(fullPath).releases()' do
end
end
end
+
+ describe 'ensures that the release data can be contolled by a feature flag' do
+ context 'when the graphql_release_data feature flag is disabled' do
+ let_it_be(:project) { create(:project, :repository, :public) }
+ let_it_be(:release) { create(:release, project: project) }
+
+ let(:current_user) { developer }
+
+ before do
+ stub_feature_flags(graphql_release_data: false)
+
+ project.add_developer(developer)
+ end
+
+ it_behaves_like 'no access to any release data'
+ end
+ end
end
diff --git a/spec/requests/api/wikis_spec.rb b/spec/requests/api/wikis_spec.rb
index ea22e442127..f271f8aa853 100644
--- a/spec/requests/api/wikis_spec.rb
+++ b/spec/requests/api/wikis_spec.rb
@@ -21,178 +21,10 @@ RSpec.describe API::Wikis do
let(:payload) { { content: 'content', format: 'rdoc', title: 'title' } }
let(:expected_keys_with_content) { %w(content format slug title) }
let(:expected_keys_without_content) { %w(format slug title) }
+ let(:wiki) { project_wiki }
- shared_examples_for 'returns list of wiki pages' do
- context 'when wiki has pages' do
- let!(:pages) do
- [create(:wiki_page, wiki: project_wiki, title: 'page1', content: 'content of page1'),
- create(:wiki_page, wiki: project_wiki, title: 'page2.with.dot', content: 'content of page2')]
- end
-
- it 'returns the list of wiki pages without content' do
- get api(url, user)
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(json_response.size).to eq(2)
-
- json_response.each_with_index do |page, index|
- expect(page.keys).to match_array(expected_keys_without_content)
- expect(page['slug']).to eq(pages[index].slug)
- expect(page['title']).to eq(pages[index].title)
- end
- end
-
- it 'returns the list of wiki pages with content' do
- get api(url, user), params: { with_content: 1 }
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(json_response.size).to eq(2)
-
- json_response.each_with_index do |page, index|
- expect(page.keys).to match_array(expected_keys_with_content)
- expect(page['content']).to eq(pages[index].content)
- expect(page['slug']).to eq(pages[index].slug)
- expect(page['title']).to eq(pages[index].title)
- end
- end
- end
-
- it 'return the empty list of wiki pages' do
- get api(url, user)
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(json_response.size).to eq(0)
- end
- end
-
- shared_examples_for 'returns wiki page' do
- it 'returns the wiki page' do
- expect(response).to have_gitlab_http_status(:ok)
- expect(json_response.size).to eq(4)
- expect(json_response.keys).to match_array(expected_keys_with_content)
- expect(json_response['content']).to eq(page.content)
- expect(json_response['slug']).to eq(page.slug)
- expect(json_response['title']).to eq(page.title)
- end
- end
-
- shared_examples_for 'creates wiki page' do
- it 'creates the wiki page' do
- post(api(url, user), params: payload)
-
- expect(response).to have_gitlab_http_status(:created)
- expect(json_response.size).to eq(4)
- expect(json_response.keys).to match_array(expected_keys_with_content)
- expect(json_response['content']).to eq(payload[:content])
- expect(json_response['slug']).to eq(payload[:title].tr(' ', '-'))
- expect(json_response['title']).to eq(payload[:title])
- expect(json_response['rdoc']).to eq(payload[:rdoc])
- end
-
- [:title, :content].each do |part|
- it "responds with validation error on empty #{part}" do
- payload.delete(part)
-
- post(api(url, user), params: payload)
-
- expect(response).to have_gitlab_http_status(:bad_request)
- expect(json_response.size).to eq(1)
- expect(json_response['error']).to eq("#{part} is missing")
- end
- end
- end
-
- shared_examples_for 'updates wiki page' do
- it 'updates the wiki page' do
- put(api(url, user), params: payload)
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(json_response.size).to eq(4)
- expect(json_response.keys).to match_array(expected_keys_with_content)
- expect(json_response['content']).to eq(payload[:content])
- expect(json_response['slug']).to eq(payload[:title].tr(' ', '-'))
- expect(json_response['title']).to eq(payload[:title])
- end
-
- [:title, :content, :format].each do |part|
- it "updates with wiki with missing #{part}" do
- payload.delete(part)
-
- put(api(url, user), params: payload)
-
- expect(response).to have_gitlab_http_status(:ok)
- end
- end
- end
-
- shared_examples_for '403 Forbidden' do
- it 'returns 403 Forbidden' do
- expect(response).to have_gitlab_http_status(:forbidden)
- expect(json_response.size).to eq(1)
- expect(json_response['message']).to eq('403 Forbidden')
- end
- end
-
- shared_examples_for '404 Wiki Page Not Found' do
- it 'returns 404 Wiki Page Not Found' do
- expect(response).to have_gitlab_http_status(:not_found)
- expect(json_response.size).to eq(1)
- expect(json_response['message']).to eq('404 Wiki Page Not Found')
- end
- end
-
- shared_examples_for '404 Project Not Found' do
- it 'returns 404 Project Not Found' do
- expect(response).to have_gitlab_http_status(:not_found)
- expect(json_response.size).to eq(1)
- expect(json_response['message']).to eq('404 Project Not Found')
- end
- end
-
- shared_examples_for '204 No Content' do
- it 'returns 204 No Content' do
- expect(response).to have_gitlab_http_status(:no_content)
- end
- end
-
- shared_examples_for 'uploads wiki attachment' do
- it 'pushes attachment to the wiki repository' do
- allow(SecureRandom).to receive(:hex).and_return('fixed_hex')
-
- workhorse_post_with_file(api(url, user), file_key: :file, params: payload)
-
- expect(response).to have_gitlab_http_status(:created)
- expect(json_response).to eq result_hash.deep_stringify_keys
- end
-
- it 'responds with validation error on empty file' do
- payload.delete(:file)
-
- post(api(url, user), params: payload)
-
- expect(response).to have_gitlab_http_status(:bad_request)
- expect(json_response.size).to eq(1)
- expect(json_response['error']).to eq('file is missing')
- end
-
- it 'responds with validation error on invalid temp file' do
- payload[:file] = { tempfile: '/etc/hosts' }
-
- post(api(url, user), params: payload)
-
- expect(response).to have_gitlab_http_status(:bad_request)
- expect(json_response.size).to eq(1)
- expect(json_response['error']).to eq('file is invalid')
- end
-
- it 'is backward compatible with regular multipart uploads' do
- allow(SecureRandom).to receive(:hex).and_return('fixed_hex')
-
- post(api(url, user), params: payload)
-
- expect(response).to have_gitlab_http_status(:created)
- expect(json_response).to eq result_hash.deep_stringify_keys
- end
+ shared_examples_for 'wiki API 404 Project Not Found' do
+ include_examples 'wiki API 404 Not Found', 'Project'
end
describe 'GET /projects/:id/wikis' do
@@ -206,7 +38,7 @@ RSpec.describe API::Wikis do
get api(url)
end
- include_examples '404 Project Not Found'
+ include_examples 'wiki API 404 Project Not Found'
end
context 'when user is developer' do
@@ -216,7 +48,7 @@ RSpec.describe API::Wikis do
get api(url, user)
end
- include_examples '403 Forbidden'
+ include_examples 'wiki API 403 Forbidden'
end
context 'when user is maintainer' do
@@ -226,7 +58,7 @@ RSpec.describe API::Wikis do
get api(url, user)
end
- include_examples '403 Forbidden'
+ include_examples 'wiki API 403 Forbidden'
end
end
@@ -238,7 +70,7 @@ RSpec.describe API::Wikis do
get api(url)
end
- include_examples '404 Project Not Found'
+ include_examples 'wiki API 404 Project Not Found'
end
context 'when user is developer' do
@@ -246,7 +78,7 @@ RSpec.describe API::Wikis do
project.add_developer(user)
end
- include_examples 'returns list of wiki pages'
+ include_examples 'wikis API returns list of wiki pages'
end
context 'when user is maintainer' do
@@ -254,7 +86,7 @@ RSpec.describe API::Wikis do
project.add_maintainer(user)
end
- include_examples 'returns list of wiki pages'
+ include_examples 'wikis API returns list of wiki pages'
end
end
@@ -266,7 +98,7 @@ RSpec.describe API::Wikis do
get api(url)
end
- include_examples '404 Project Not Found'
+ include_examples 'wiki API 404 Project Not Found'
end
context 'when user is developer' do
@@ -274,7 +106,7 @@ RSpec.describe API::Wikis do
project.add_developer(user)
end
- include_examples 'returns list of wiki pages'
+ include_examples 'wikis API returns list of wiki pages'
end
context 'when user is maintainer' do
@@ -282,7 +114,7 @@ RSpec.describe API::Wikis do
project.add_maintainer(user)
end
- include_examples 'returns list of wiki pages'
+ include_examples 'wikis API returns list of wiki pages'
end
end
end
@@ -299,7 +131,7 @@ RSpec.describe API::Wikis do
get api(url)
end
- include_examples '404 Project Not Found'
+ include_examples 'wiki API 404 Project Not Found'
end
context 'when user is developer' do
@@ -309,7 +141,7 @@ RSpec.describe API::Wikis do
get api(url, user)
end
- include_examples '403 Forbidden'
+ include_examples 'wiki API 403 Forbidden'
end
context 'when user is maintainer' do
@@ -319,7 +151,7 @@ RSpec.describe API::Wikis do
get api(url, user)
end
- include_examples '403 Forbidden'
+ include_examples 'wiki API 403 Forbidden'
end
end
@@ -331,7 +163,7 @@ RSpec.describe API::Wikis do
get api(url)
end
- include_examples '404 Project Not Found'
+ include_examples 'wiki API 404 Project Not Found'
end
context 'when user is developer' do
@@ -340,12 +172,12 @@ RSpec.describe API::Wikis do
get api(url, user)
end
- include_examples 'returns wiki page'
+ include_examples 'wikis API returns wiki page'
context 'when page is not existing' do
let(:url) { "/projects/#{project.id}/wikis/unknown" }
- include_examples '404 Wiki Page Not Found'
+ include_examples 'wiki API 404 Wiki Page Not Found'
end
end
@@ -356,12 +188,12 @@ RSpec.describe API::Wikis do
get api(url, user)
end
- include_examples 'returns wiki page'
+ include_examples 'wikis API returns wiki page'
context 'when page is not existing' do
let(:url) { "/projects/#{project.id}/wikis/unknown" }
- include_examples '404 Wiki Page Not Found'
+ include_examples 'wiki API 404 Wiki Page Not Found'
end
end
end
@@ -374,7 +206,7 @@ RSpec.describe API::Wikis do
get api(url)
end
- include_examples '404 Project Not Found'
+ include_examples 'wiki API 404 Project Not Found'
end
context 'when user is developer' do
@@ -384,12 +216,12 @@ RSpec.describe API::Wikis do
get api(url, user)
end
- include_examples 'returns wiki page'
+ include_examples 'wikis API returns wiki page'
context 'when page is not existing' do
let(:url) { "/projects/#{project.id}/wikis/unknown" }
- include_examples '404 Wiki Page Not Found'
+ include_examples 'wiki API 404 Wiki Page Not Found'
end
end
@@ -400,12 +232,12 @@ RSpec.describe API::Wikis do
get api(url, user)
end
- include_examples 'returns wiki page'
+ include_examples 'wikis API returns wiki page'
context 'when page is not existing' do
let(:url) { "/projects/#{project.id}/wikis/unknown" }
- include_examples '404 Wiki Page Not Found'
+ include_examples 'wiki API 404 Wiki Page Not Found'
end
end
end
@@ -423,7 +255,7 @@ RSpec.describe API::Wikis do
post(api(url), params: payload)
end
- include_examples '404 Project Not Found'
+ include_examples 'wiki API 404 Project Not Found'
end
context 'when user is developer' do
@@ -432,7 +264,7 @@ RSpec.describe API::Wikis do
post(api(url, user), params: payload)
end
- include_examples '403 Forbidden'
+ include_examples 'wiki API 403 Forbidden'
end
context 'when user is maintainer' do
@@ -441,7 +273,7 @@ RSpec.describe API::Wikis do
post(api(url, user), params: payload)
end
- include_examples '403 Forbidden'
+ include_examples 'wiki API 403 Forbidden'
end
end
@@ -453,7 +285,7 @@ RSpec.describe API::Wikis do
post(api(url), params: payload)
end
- include_examples '404 Project Not Found'
+ include_examples 'wiki API 404 Project Not Found'
end
context 'when user is developer' do
@@ -461,7 +293,7 @@ RSpec.describe API::Wikis do
project.add_developer(user)
end
- include_examples 'creates wiki page'
+ include_examples 'wikis API creates wiki page'
end
context 'when user is maintainer' do
@@ -469,7 +301,7 @@ RSpec.describe API::Wikis do
project.add_maintainer(user)
end
- include_examples 'creates wiki page'
+ include_examples 'wikis API creates wiki page'
end
end
@@ -481,7 +313,7 @@ RSpec.describe API::Wikis do
post(api(url), params: payload)
end
- include_examples '404 Project Not Found'
+ include_examples 'wiki API 404 Project Not Found'
end
context 'when user is developer' do
@@ -489,7 +321,7 @@ RSpec.describe API::Wikis do
project.add_developer(user)
end
- include_examples 'creates wiki page'
+ include_examples 'wikis API creates wiki page'
end
context 'when user is maintainer' do
@@ -497,7 +329,7 @@ RSpec.describe API::Wikis do
project.add_maintainer(user)
end
- include_examples 'creates wiki page'
+ include_examples 'wikis API creates wiki page'
end
end
end
@@ -515,7 +347,7 @@ RSpec.describe API::Wikis do
put(api(url), params: payload)
end
- include_examples '404 Project Not Found'
+ include_examples 'wiki API 404 Project Not Found'
end
context 'when user is developer' do
@@ -525,7 +357,7 @@ RSpec.describe API::Wikis do
put(api(url, user), params: payload)
end
- include_examples '403 Forbidden'
+ include_examples 'wiki API 403 Forbidden'
end
context 'when user is maintainer' do
@@ -535,7 +367,7 @@ RSpec.describe API::Wikis do
put(api(url, user), params: payload)
end
- include_examples '403 Forbidden'
+ include_examples 'wiki API 403 Forbidden'
end
end
@@ -547,7 +379,7 @@ RSpec.describe API::Wikis do
put(api(url), params: payload)
end
- include_examples '404 Project Not Found'
+ include_examples 'wiki API 404 Project Not Found'
end
context 'when user is developer' do
@@ -555,7 +387,7 @@ RSpec.describe API::Wikis do
project.add_developer(user)
end
- include_examples 'updates wiki page'
+ include_examples 'wikis API updates wiki page'
context 'when page is not existing' do
let(:url) { "/projects/#{project.id}/wikis/unknown" }
@@ -564,7 +396,7 @@ RSpec.describe API::Wikis do
put(api(url, user), params: payload)
end
- include_examples '404 Wiki Page Not Found'
+ include_examples 'wiki API 404 Wiki Page Not Found'
end
end
@@ -573,7 +405,7 @@ RSpec.describe API::Wikis do
project.add_maintainer(user)
end
- include_examples 'updates wiki page'
+ include_examples 'wikis API updates wiki page'
context 'when page is not existing' do
let(:url) { "/projects/#{project.id}/wikis/unknown" }
@@ -582,7 +414,7 @@ RSpec.describe API::Wikis do
put(api(url, user), params: payload)
end
- include_examples '404 Wiki Page Not Found'
+ include_examples 'wiki API 404 Wiki Page Not Found'
end
end
end
@@ -595,7 +427,7 @@ RSpec.describe API::Wikis do
put(api(url), params: payload)
end
- include_examples '404 Project Not Found'
+ include_examples 'wiki API 404 Project Not Found'
end
context 'when user is developer' do
@@ -603,7 +435,7 @@ RSpec.describe API::Wikis do
project.add_developer(user)
end
- include_examples 'updates wiki page'
+ include_examples 'wikis API updates wiki page'
context 'when page is not existing' do
let(:url) { "/projects/#{project.id}/wikis/unknown" }
@@ -612,7 +444,7 @@ RSpec.describe API::Wikis do
put(api(url, user), params: payload)
end
- include_examples '404 Wiki Page Not Found'
+ include_examples 'wiki API 404 Wiki Page Not Found'
end
end
@@ -621,7 +453,7 @@ RSpec.describe API::Wikis do
project.add_maintainer(user)
end
- include_examples 'updates wiki page'
+ include_examples 'wikis API updates wiki page'
context 'when page is not existing' do
let(:url) { "/projects/#{project.id}/wikis/unknown" }
@@ -630,7 +462,7 @@ RSpec.describe API::Wikis do
put(api(url, user), params: payload)
end
- include_examples '404 Wiki Page Not Found'
+ include_examples 'wiki API 404 Wiki Page Not Found'
end
end
end
@@ -638,7 +470,7 @@ RSpec.describe API::Wikis do
context 'when wiki belongs to a group project' do
let(:project) { create(:project, :wiki_repo, namespace: group) }
- include_examples 'updates wiki page'
+ include_examples 'wikis API updates wiki page'
end
end
@@ -654,7 +486,7 @@ RSpec.describe API::Wikis do
delete(api(url))
end
- include_examples '404 Project Not Found'
+ include_examples 'wiki API 404 Project Not Found'
end
context 'when user is developer' do
@@ -664,7 +496,7 @@ RSpec.describe API::Wikis do
delete(api(url, user))
end
- include_examples '403 Forbidden'
+ include_examples 'wiki API 403 Forbidden'
end
context 'when user is maintainer' do
@@ -674,7 +506,7 @@ RSpec.describe API::Wikis do
delete(api(url, user))
end
- include_examples '403 Forbidden'
+ include_examples 'wiki API 403 Forbidden'
end
end
@@ -686,7 +518,7 @@ RSpec.describe API::Wikis do
delete(api(url))
end
- include_examples '404 Project Not Found'
+ include_examples 'wiki API 404 Project Not Found'
end
context 'when user is developer' do
@@ -696,7 +528,7 @@ RSpec.describe API::Wikis do
delete(api(url, user))
end
- include_examples '403 Forbidden'
+ include_examples 'wiki API 403 Forbidden'
end
context 'when user is maintainer' do
@@ -706,7 +538,7 @@ RSpec.describe API::Wikis do
delete(api(url, user))
end
- include_examples '204 No Content'
+ include_examples 'wiki API 204 No Content'
end
end
@@ -718,7 +550,7 @@ RSpec.describe API::Wikis do
delete(api(url))
end
- include_examples '404 Project Not Found'
+ include_examples 'wiki API 404 Project Not Found'
end
context 'when user is developer' do
@@ -728,7 +560,7 @@ RSpec.describe API::Wikis do
delete(api(url, user))
end
- include_examples '403 Forbidden'
+ include_examples 'wiki API 403 Forbidden'
end
context 'when user is maintainer' do
@@ -738,12 +570,12 @@ RSpec.describe API::Wikis do
delete(api(url, user))
end
- include_examples '204 No Content'
+ include_examples 'wiki API 204 No Content'
context 'when page is not existing' do
let(:url) { "/projects/#{project.id}/wikis/unknown" }
- include_examples '404 Wiki Page Not Found'
+ include_examples 'wiki API 404 Wiki Page Not Found'
end
end
end
@@ -755,7 +587,7 @@ RSpec.describe API::Wikis do
delete(api(url, user))
end
- include_examples '204 No Content'
+ include_examples 'wiki API 204 No Content'
end
end
@@ -783,7 +615,7 @@ RSpec.describe API::Wikis do
post(api(url), params: payload)
end
- include_examples '404 Project Not Found'
+ include_examples 'wiki API 404 Project Not Found'
end
context 'when user is developer' do
@@ -792,7 +624,7 @@ RSpec.describe API::Wikis do
post(api(url, user), params: payload)
end
- include_examples '403 Forbidden'
+ include_examples 'wiki API 403 Forbidden'
end
context 'when user is maintainer' do
@@ -801,7 +633,7 @@ RSpec.describe API::Wikis do
post(api(url, user), params: payload)
end
- include_examples '403 Forbidden'
+ include_examples 'wiki API 403 Forbidden'
end
end
@@ -813,7 +645,7 @@ RSpec.describe API::Wikis do
post(api(url), params: payload)
end
- include_examples '404 Project Not Found'
+ include_examples 'wiki API 404 Project Not Found'
end
context 'when user is developer' do
@@ -821,7 +653,7 @@ RSpec.describe API::Wikis do
project.add_developer(user)
end
- include_examples 'uploads wiki attachment'
+ include_examples 'wiki API uploads wiki attachment'
end
context 'when user is maintainer' do
@@ -829,7 +661,7 @@ RSpec.describe API::Wikis do
project.add_maintainer(user)
end
- include_examples 'uploads wiki attachment'
+ include_examples 'wiki API uploads wiki attachment'
end
end
@@ -841,7 +673,7 @@ RSpec.describe API::Wikis do
post(api(url), params: payload)
end
- include_examples '404 Project Not Found'
+ include_examples 'wiki API 404 Project Not Found'
end
context 'when user is developer' do
@@ -849,7 +681,7 @@ RSpec.describe API::Wikis do
project.add_developer(user)
end
- include_examples 'uploads wiki attachment'
+ include_examples 'wiki API uploads wiki attachment'
end
context 'when user is maintainer' do
@@ -857,7 +689,7 @@ RSpec.describe API::Wikis do
project.add_maintainer(user)
end
- include_examples 'uploads wiki attachment'
+ include_examples 'wiki API uploads wiki attachment'
end
end
end
diff --git a/spec/support/shared_examples/lib/wikis_api_examples.rb b/spec/support/shared_examples/lib/wikis_api_examples.rb
new file mode 100644
index 00000000000..2e4c667d37e
--- /dev/null
+++ b/spec/support/shared_examples/lib/wikis_api_examples.rb
@@ -0,0 +1,174 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples_for 'wikis API returns list of wiki pages' do
+ context 'when wiki has pages' do
+ let!(:pages) do
+ [create(:wiki_page, wiki: wiki, title: 'page1', content: 'content of page1'),
+ create(:wiki_page, wiki: wiki, title: 'page2.with.dot', content: 'content of page2')]
+ end
+
+ it 'returns the list of wiki pages without content' do
+ get api(url, user)
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response.size).to eq(2)
+
+ json_response.each_with_index do |page, index|
+ expect(page.keys).to match_array(expected_keys_without_content)
+ expect(page['slug']).to eq(pages[index].slug)
+ expect(page['title']).to eq(pages[index].title)
+ end
+ end
+
+ it 'returns the list of wiki pages with content' do
+ get api(url, user), params: { with_content: 1 }
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response.size).to eq(2)
+
+ json_response.each_with_index do |page, index|
+ expect(page.keys).to match_array(expected_keys_with_content)
+ expect(page['content']).to eq(pages[index].content)
+ expect(page['slug']).to eq(pages[index].slug)
+ expect(page['title']).to eq(pages[index].title)
+ end
+ end
+ end
+
+ it 'return the empty list of wiki pages' do
+ get api(url, user)
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response.size).to eq(0)
+ end
+end
+
+RSpec.shared_examples_for 'wikis API returns wiki page' do
+ it 'returns the wiki page' do
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response.size).to eq(4)
+ expect(json_response.keys).to match_array(expected_keys_with_content)
+ expect(json_response['content']).to eq(page.content)
+ expect(json_response['slug']).to eq(page.slug)
+ expect(json_response['title']).to eq(page.title)
+ end
+end
+
+RSpec.shared_examples_for 'wikis API creates wiki page' do
+ it 'creates the wiki page' do
+ post(api(url, user), params: payload)
+
+ expect(response).to have_gitlab_http_status(:created)
+ expect(json_response.size).to eq(4)
+ expect(json_response.keys).to match_array(expected_keys_with_content)
+ expect(json_response['content']).to eq(payload[:content])
+ expect(json_response['slug']).to eq(payload[:title].tr(' ', '-'))
+ expect(json_response['title']).to eq(payload[:title])
+ expect(json_response['rdoc']).to eq(payload[:rdoc])
+ end
+
+ [:title, :content].each do |part|
+ it "responds with validation error on empty #{part}" do
+ payload.delete(part)
+
+ post(api(url, user), params: payload)
+
+ expect(response).to have_gitlab_http_status(:bad_request)
+ expect(json_response.size).to eq(1)
+ expect(json_response['error']).to eq("#{part} is missing")
+ end
+ end
+end
+
+RSpec.shared_examples_for 'wikis API updates wiki page' do
+ it 'updates the wiki page' do
+ put(api(url, user), params: payload)
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response.size).to eq(4)
+ expect(json_response.keys).to match_array(expected_keys_with_content)
+ expect(json_response['content']).to eq(payload[:content])
+ expect(json_response['slug']).to eq(payload[:title].tr(' ', '-'))
+ expect(json_response['title']).to eq(payload[:title])
+ end
+
+ [:title, :content, :format].each do |part|
+ it "updates with wiki with missing #{part}" do
+ payload.delete(part)
+
+ put(api(url, user), params: payload)
+
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
+end
+
+RSpec.shared_examples_for 'wiki API 403 Forbidden' do
+ it 'returns 403 Forbidden' do
+ expect(response).to have_gitlab_http_status(:forbidden)
+ expect(json_response.size).to eq(1)
+ expect(json_response['message']).to eq('403 Forbidden')
+ end
+end
+
+RSpec.shared_examples_for 'wiki API 404 Wiki Page Not Found' do
+ it 'returns 404 Wiki Page Not Found' do
+ expect(response).to have_gitlab_http_status(:not_found)
+ expect(json_response.size).to eq(1)
+ expect(json_response['message']).to eq('404 Wiki Page Not Found')
+ end
+end
+
+RSpec.shared_examples_for 'wiki API 404 Not Found' do |what|
+ it "returns 404 #{what} Not Found" do
+ expect(response).to have_gitlab_http_status(:not_found)
+ expect(json_response.size).to eq(1)
+ expect(json_response['message']).to eq("404 #{what} Not Found")
+ end
+end
+
+RSpec.shared_examples_for 'wiki API 204 No Content' do
+ it 'returns 204 No Content' do
+ expect(response).to have_gitlab_http_status(:no_content)
+ end
+end
+
+RSpec.shared_examples_for 'wiki API uploads wiki attachment' do
+ it 'pushes attachment to the wiki repository' do
+ allow(SecureRandom).to receive(:hex).and_return('fixed_hex')
+
+ workhorse_post_with_file(api(url, user), file_key: :file, params: payload)
+
+ expect(response).to have_gitlab_http_status(:created)
+ expect(json_response).to eq result_hash.deep_stringify_keys
+ end
+
+ it 'responds with validation error on empty file' do
+ payload.delete(:file)
+
+ post(api(url, user), params: payload)
+
+ expect(response).to have_gitlab_http_status(:bad_request)
+ expect(json_response.size).to eq(1)
+ expect(json_response['error']).to eq('file is missing')
+ end
+
+ it 'responds with validation error on invalid temp file' do
+ payload[:file] = { tempfile: '/etc/hosts' }
+
+ post(api(url, user), params: payload)
+
+ expect(response).to have_gitlab_http_status(:bad_request)
+ expect(json_response.size).to eq(1)
+ expect(json_response['error']).to eq('file is invalid')
+ end
+
+ it 'is backward compatible with regular multipart uploads' do
+ allow(SecureRandom).to receive(:hex).and_return('fixed_hex')
+
+ post(api(url, user), params: payload)
+
+ expect(response).to have_gitlab_http_status(:created)
+ expect(json_response).to eq result_hash.deep_stringify_keys
+ end
+end