Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
bc9a474793
commit
1dab074ef1
|
@ -380,6 +380,15 @@ ee:update-major:
|
|||
- if: $QA_SUITES =~ /Test::Instance::Smoke/
|
||||
- !reference [.rules:test:manual, rules]
|
||||
|
||||
ee:gitab-pages:
|
||||
extends: .qa
|
||||
variables:
|
||||
QA_SCENARIO: Test::Integration::GitlabPages
|
||||
rules:
|
||||
- !reference [.rules:test:qa, rules]
|
||||
- if: $QA_SUITES =~ /Test::Integration::GitlabPages/
|
||||
- !reference [.rules:test:manual, rules]
|
||||
|
||||
ee:gitaly-cluster:
|
||||
extends: .qa
|
||||
variables:
|
||||
|
|
|
@ -65,3 +65,4 @@ RSpec/FilePath:
|
|||
- 'spec/services/ci/create_pipeline_service/rate_limit_spec.rb'
|
||||
- 'spec/services/ci/create_pipeline_service/rules_spec.rb'
|
||||
- 'spec/services/ci/create_pipeline_service/tags_spec.rb'
|
||||
- 'spec/services/ci/create_pipeline_service/variables_spec.rb'
|
||||
|
|
|
@ -1 +1 @@
|
|||
061bcd50aa4e5bae26265f8f039e6786b059053d
|
||||
0f35939596221fc096d873473ef0d6fc3fd09440
|
||||
|
|
|
@ -7,6 +7,7 @@ import {
|
|||
GlLink,
|
||||
GlModal,
|
||||
GlModalDirective,
|
||||
GlTooltipDirective,
|
||||
} from '@gitlab/ui';
|
||||
import { mapActions, mapGetters, mapState } from 'vuex';
|
||||
import createFlash, { FLASH_TYPES } from '~/flash';
|
||||
|
@ -51,6 +52,7 @@ export default {
|
|||
},
|
||||
directives: {
|
||||
GlModal: GlModalDirective,
|
||||
GlTooltip: GlTooltipDirective,
|
||||
},
|
||||
mixins: [trackingMixin],
|
||||
inject: {
|
||||
|
@ -287,12 +289,15 @@ export default {
|
|||
|
||||
<gl-dropdown
|
||||
v-if="hasDesktopDropdown"
|
||||
v-gl-tooltip.hover
|
||||
class="gl-display-none gl-sm-display-inline-flex! gl-ml-3"
|
||||
icon="ellipsis_v"
|
||||
category="tertiary"
|
||||
data-qa-selector="issue_actions_ellipsis_dropdown"
|
||||
:text="dropdownText"
|
||||
:text-sr-only="true"
|
||||
:title="dropdownText"
|
||||
:aria-label="dropdownText"
|
||||
data-testid="desktop-dropdown"
|
||||
no-caret
|
||||
right
|
||||
|
|
|
@ -33,8 +33,13 @@ module Ci
|
|||
end
|
||||
|
||||
def runner_variables
|
||||
stop_expanding_raw_refs = ::Feature.enabled?(:ci_raw_variables_in_yaml_config, project)
|
||||
|
||||
variables
|
||||
.sort_and_expand_all(keep_undefined: true, expand_file_vars: false, project: project)
|
||||
.sort_and_expand_all(keep_undefined: true,
|
||||
expand_file_refs: false,
|
||||
expand_raw_refs: !stop_expanding_raw_refs,
|
||||
project: project)
|
||||
.to_runner_variables
|
||||
end
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
- display_issuable_type = issuable_display_type(@merge_request)
|
||||
|
||||
.btn-group.gl-md-ml-3.gl-display-flex.dropdown.gl-new-dropdown.gl-md-w-auto.gl-w-full
|
||||
= button_tag type: 'button', class: "btn dropdown-toggle btn-default btn-md gl-button gl-dropdown-toggle btn-default-tertiary dropdown-icon-only dropdown-toggle-no-caret has-tooltip gl-display-none! gl-md-display-inline-flex!", data: { toggle: 'dropdown', title: _('Merge request actions'), testid: 'merge-request-actions' } do
|
||||
= button_tag type: 'button', class: "btn dropdown-toggle btn-default btn-md gl-button gl-dropdown-toggle btn-default-tertiary dropdown-icon-only dropdown-toggle-no-caret has-tooltip gl-display-none! gl-md-display-inline-flex!", data: { toggle: 'dropdown', title: _('Merge request actions'), testid: 'merge-request-actions', 'aria-label': _('Merge request actions') } do
|
||||
= sprite_icon "ellipsis_v", size: 16, css_class: "dropdown-icon gl-icon"
|
||||
= button_tag type: 'button', class: "btn dropdown-toggle btn-default btn-md btn-block gl-button gl-dropdown-toggle gl-md-display-none!", data: { 'toggle' => 'dropdown' } do
|
||||
%span.gl-new-dropdown-button-text= _('Merge request actions')
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ChangeDefaultValueOnPasswordLastChangedAtToUserDetails < Gitlab::Database::Migration[2.0]
|
||||
enable_lock_retries!
|
||||
|
||||
# rubocop:disable Migration/RemoveColumn
|
||||
def change
|
||||
remove_column :user_details, :password_last_changed_at, :datetime_with_timezone
|
||||
add_column :user_details, :password_last_changed_at, :datetime_with_timezone,
|
||||
null: false, default: -> { 'NOW()' }, comment: 'JiHu-specific column'
|
||||
end
|
||||
# rubocop:enable Migration/RemoveColumn
|
||||
end
|
|
@ -0,0 +1,15 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddIndexOnPasswordLastChangedAtToUserDetails < Gitlab::Database::Migration[2.0]
|
||||
INDEX_NAME = 'index_user_details_on_password_last_changed_at'
|
||||
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
add_concurrent_index :user_details, :password_last_changed_at, name: INDEX_NAME, comment: 'JiHu-specific index'
|
||||
end
|
||||
|
||||
def down
|
||||
remove_concurrent_index_by_name :user_details, INDEX_NAME
|
||||
end
|
||||
end
|
|
@ -0,0 +1 @@
|
|||
6762034e2dff9d6e6d146f1ce3b281f8886895b056c5ed54767ceb0d6c18bd59
|
|
@ -0,0 +1 @@
|
|||
0305d0fa4d95b0a1553c9ba7984af2cb74099988dbc9983e1048b54ead39a76e
|
|
@ -22208,13 +22208,13 @@ CREATE TABLE user_details (
|
|||
registration_objective smallint,
|
||||
phone text,
|
||||
requires_credit_card_verification boolean DEFAULT false NOT NULL,
|
||||
password_last_changed_at timestamp with time zone,
|
||||
linkedin text DEFAULT ''::text NOT NULL,
|
||||
twitter text DEFAULT ''::text NOT NULL,
|
||||
skype text DEFAULT ''::text NOT NULL,
|
||||
website_url text DEFAULT ''::text NOT NULL,
|
||||
location text DEFAULT ''::text NOT NULL,
|
||||
organization text DEFAULT ''::text NOT NULL,
|
||||
password_last_changed_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
CONSTRAINT check_245664af82 CHECK ((char_length(webauthn_xid) <= 100)),
|
||||
CONSTRAINT check_444573ee52 CHECK ((char_length(skype) <= 500)),
|
||||
CONSTRAINT check_466a25be35 CHECK ((char_length(twitter) <= 500)),
|
||||
|
@ -30805,6 +30805,10 @@ CREATE INDEX index_user_custom_attributes_on_key_and_value ON user_custom_attrib
|
|||
|
||||
CREATE UNIQUE INDEX index_user_custom_attributes_on_user_id_and_key ON user_custom_attributes USING btree (user_id, key);
|
||||
|
||||
CREATE INDEX index_user_details_on_password_last_changed_at ON user_details USING btree (password_last_changed_at);
|
||||
|
||||
COMMENT ON INDEX index_user_details_on_password_last_changed_at IS 'JiHu-specific index';
|
||||
|
||||
CREATE UNIQUE INDEX index_user_details_on_phone ON user_details USING btree (phone) WHERE (phone IS NOT NULL);
|
||||
|
||||
COMMENT ON INDEX index_user_details_on_phone IS 'JiHu-specific index';
|
||||
|
|
|
@ -267,6 +267,24 @@ new routing tables. Depending on the chosen
|
|||
[partitioning strategy](#how-do-we-want-to-partition-cicd-data) for a given
|
||||
table, it is possible to have many logical partitions per one physical partition.
|
||||
|
||||
### Attaching first partition and acquiring locks
|
||||
|
||||
We learned when [partitioning](https://gitlab.com/gitlab-org/gitlab/-/issues/378644)
|
||||
the first table that `PostgreSQL` requires an `AccessExclusiveLock` on the table and
|
||||
all of the other tables that it references through foreign keys. This can cause a deadlock
|
||||
if the migration tries to acquire the locks in a different order from the application
|
||||
business logic.
|
||||
|
||||
To solve this problem, we introduced a **priority locking strategy** to avoid
|
||||
further deadlock errors. This allows us to define the locking order and
|
||||
then try keep retrying aggressively until we acquire the locks or run out of retries.
|
||||
This process can take up to 40 minutes.
|
||||
|
||||
With this strategy, we successfully acquired a lock on `ci_builds` table after 15 retries
|
||||
during a low traffic period([after `00:00 UTC`](https://dashboards.gitlab.net/d/web-main/web-overview?orgId=1&viewPanel=537181794&from=now-2d&to=now)).
|
||||
|
||||
See an example of this strategy in our [partition tooling](../../../development/database/table_partitioning.md#step-6---create-parent-table-and-attach-existing-table-as-the-initial-partition)).
|
||||
|
||||
## Storing partitions metadata in the database
|
||||
|
||||
To build an efficient mechanism that will be responsible for creating
|
||||
|
@ -652,7 +670,7 @@ application-wide outage.
|
|||
1. Make it possible to create partitions in an automatic way.
|
||||
1. Deliver the new architecture to self-managed instances.
|
||||
|
||||
The diagram below visualizes this plan on Gantt chart. Please note that dates
|
||||
The diagram below visualizes this plan on Gantt chart. The dates
|
||||
on the chart below are just estimates to visualize the plan better, these are
|
||||
not deadlines and can change at any time.
|
||||
|
||||
|
|
|
@ -1068,8 +1068,8 @@ To fix this, use one of the following solutions:
|
|||
- Remove `environment` keyword from the deployment job. GitLab has already been
|
||||
ignoring the invalid keyword, therefore your deployment pipelines stay intact
|
||||
even after the keyword removal.
|
||||
- Ensure the variable exists in the pipeline. Please note that there is
|
||||
[a limitation on supported variables](../variables/where_variables_can_be_used.md#gitlab-ciyml-file).
|
||||
- Ensure the variable exists in the pipeline. Review the
|
||||
[limitation on supported variables](../variables/where_variables_can_be_used.md#gitlab-ciyml-file).
|
||||
|
||||
#### If you get this error on Review Apps
|
||||
|
||||
|
@ -1112,6 +1112,6 @@ to execute the following command on Rails console:
|
|||
Project.find_by_full_path(<your-project-full-path>).deployments.where(archived: true).each(&:create_ref)
|
||||
```
|
||||
|
||||
Please note that GitLab could drop this support in the future for the performance concern.
|
||||
GitLab might drop this support in the future for the performance concern.
|
||||
You can open an issue in [GitLab Issue Tracker](https://gitlab.com/gitlab-org/gitlab/-/issues/new)
|
||||
to discuss the behavior of this feature.
|
||||
|
|
|
@ -360,7 +360,7 @@ The following [`.gitlab-ci.yml`](../yaml/index.md) example for Go uses:
|
|||
- [`gocover-cobertura`](https://github.com/boumenot/gocover-cobertura) to convert Go's coverage profile into the Cobertura XML format.
|
||||
|
||||
This example assumes that [Go modules](https://go.dev/ref/mod)
|
||||
are being used. Please note that the `-covermode count` option does not work with the `-race` flag.
|
||||
are being used. The `-covermode count` option does not work with the `-race` flag.
|
||||
If you want to generate code coverage while also using the `-race` flag, you must switch to
|
||||
`-covermode atomic` which is slower than `-covermode count`. See [this blog post](https://go.dev/blog/cover)
|
||||
for more details.
|
||||
|
|
|
@ -1003,7 +1003,7 @@ rspec:
|
|||
|
||||
- Combining reports in parent pipelines using [artifacts from child pipelines](#needspipelinejob) is
|
||||
not supported. Track progress on adding support in [this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/215725).
|
||||
- To be able to browse the report output files, include the [`artifacts:paths`](#artifactspaths) keyword. Please note that this will upload and store the artifact twice.
|
||||
- To be able to browse the report output files, include the [`artifacts:paths`](#artifactspaths) keyword. This will upload and store the artifact twice.
|
||||
- The test reports are collected regardless of the job results (success or failure).
|
||||
You can use [`artifacts:expire_in`](#artifactsexpire_in) to set up an expiration
|
||||
date for artifacts reports.
|
||||
|
|
|
@ -447,6 +447,7 @@ class ConvertTableToListPartitioning < Gitlab::Database::Migration[2.0]
|
|||
disable_ddl_transaction!
|
||||
|
||||
TABLE_NAME = :table_name
|
||||
TABLE_FK = :table_references_by_fk
|
||||
PARENT_TABLE_NAME = :p_table_name
|
||||
FIRST_PARTITION = 100
|
||||
PARTITION_COLUMN = :partition_id
|
||||
|
@ -457,6 +458,7 @@ class ConvertTableToListPartitioning < Gitlab::Database::Migration[2.0]
|
|||
partitioning_column: PARTITION_COLUMN,
|
||||
parent_table_name: PARENT_TABLE_NAME,
|
||||
initial_partitioning_value: FIRST_PARTITION
|
||||
lock_tables: [TABLE_FK, TABLE_NAME]
|
||||
)
|
||||
end
|
||||
|
||||
|
|
|
@ -170,26 +170,17 @@ Hard-coded HTML is valid, although it's discouraged from being used. HTML is per
|
|||
- Special styling is required.
|
||||
- Reviewed and approved by a technical writer.
|
||||
|
||||
### Headings in Markdown
|
||||
### Heading levels in Markdown
|
||||
|
||||
Each documentation page begins with a level 1 heading (`#`). This becomes the `h1` element when
|
||||
the page is rendered to HTML. There can be only **one** level 1 heading per page.
|
||||
|
||||
- For each subsection, increment the heading level. In other words, increment the number of `#` characters
|
||||
in front of the heading.
|
||||
- Avoid headings greater than `H5` (`#####`). If you need more than five heading levels, move the topics to a new page instead.
|
||||
Headings greater than `H5` do not display in the right sidebar navigation.
|
||||
in front of the topic title.
|
||||
- Avoid heading levels greater than `H5` (`#####`). If you need more than five heading levels, move the topics to a new page instead.
|
||||
Heading levels greater than `H5` do not display in the right sidebar navigation.
|
||||
- Do not skip a level. For example: `##` > `####`.
|
||||
- Leave one blank line before and after the heading.
|
||||
|
||||
When you change heading text, the anchor link changes. To avoid broken links:
|
||||
|
||||
- Do not use step numbers in headings.
|
||||
- When possible, do not use words that might change in the future.
|
||||
|
||||
Also, do not use links as part of heading text.
|
||||
|
||||
See also [heading guidelines for specific topic types](../structure.md).
|
||||
- Leave one blank line before and after the topic title.
|
||||
|
||||
### Backticks in Markdown
|
||||
|
||||
|
@ -248,9 +239,9 @@ GitLab documentation should be clear and easy to understand.
|
|||
|
||||
As a company, we tend toward lowercase.
|
||||
|
||||
#### Headings
|
||||
#### Topic titles
|
||||
|
||||
Use sentence case. For example:
|
||||
Use sentence case for topic titles. For example:
|
||||
|
||||
- `# Use variables to configure pipelines`
|
||||
- `## Use the To-Do List`
|
||||
|
@ -356,7 +347,7 @@ Some contractions, however, should be avoided:
|
|||
### Acronyms
|
||||
|
||||
If you use an acronym, spell it out on first use on a page. You do not need to spell it out more than once on a page.
|
||||
When possible, try to avoid acronyms in headings.
|
||||
When possible, try to avoid acronyms in topic titles.
|
||||
|
||||
### Numbers
|
||||
|
||||
|
@ -713,22 +704,27 @@ use a URL like `https://docs.gitlab.com/charts/`.
|
|||
|
||||
### Anchor links
|
||||
|
||||
Each heading has an anchor link. For example, a topic with the title
|
||||
Each topic title has an anchor link. For example, a topic with the title
|
||||
`## This is an example` has the anchor `#this-is-an-example`.
|
||||
|
||||
The first topic on a page (the `h1`) has an anchor link,
|
||||
The first topic title on a page (the `h1`) has an anchor link,
|
||||
but do not use it. Link to the page instead.
|
||||
|
||||
If a heading has a [product tier badge](#product-tier-badges),
|
||||
do not include it in the anchor link. For example, for the heading
|
||||
If a topic title has a [product tier badge](#product-tier-badges),
|
||||
do not include it in the anchor link. For example, for the topic
|
||||
`## This is an example **(FREE)**`, use the anchor `#this-is-an-example`.
|
||||
|
||||
With Kramdown, you can add a custom ID to an HTML element, but these IDs
|
||||
don't work in `/help`, so you should not use them.
|
||||
|
||||
When you change topic title text, the anchor link changes. To avoid broken links:
|
||||
|
||||
- Do not use step numbers in topic titles.
|
||||
- When possible, do not use words that might change in the future.
|
||||
|
||||
#### Changing links and titles
|
||||
|
||||
When you change a heading, the anchor link changes. To ensure you update
|
||||
When you change a topic title, the anchor link changes. To ensure you update
|
||||
any related links, search these directories:
|
||||
|
||||
- `doc/*`
|
||||
|
@ -1231,7 +1227,7 @@ Instead of adding a note:
|
|||
|
||||
- Re-write the sentence as part of a paragraph.
|
||||
- Put the information into its own paragraph.
|
||||
- Put the content under a new subheading.
|
||||
- Put the content under a new topic title.
|
||||
|
||||
If you must use a note, use this format:
|
||||
|
||||
|
@ -1416,25 +1412,25 @@ When names change, it is more complicated to search or grep text that has line b
|
|||
|
||||
### Product tier badges
|
||||
|
||||
Tier badges are displayed as orange text next to a heading. These badges link to the GitLab
|
||||
Tier badges are displayed as orange text next to a topic title. These badges link to the GitLab
|
||||
pricing page. For example:
|
||||
|
||||
![Tier badge](img/tier_badge.png)
|
||||
|
||||
You must assign a tier badge:
|
||||
|
||||
- To all H1 topic headings, except the pages under `doc/development/*`.
|
||||
- To topic headings that don't apply to the same tier as the H1.
|
||||
- To all H1 topic titles, except the pages under `doc/development/*`.
|
||||
- To topic titles that don't apply to the same tier as the H1.
|
||||
|
||||
To add a tier badge to a heading, add the relevant tier badge
|
||||
after the heading text. For example:
|
||||
To add a tier badge to a topic title, add the relevant tier badge
|
||||
after the title text. For example:
|
||||
|
||||
```markdown
|
||||
# Heading title **(FREE)**
|
||||
# Topic title **(FREE)**
|
||||
```
|
||||
|
||||
Do not add tier badges inline with other text, except for [API attributes](../restful_api_styleguide.md).
|
||||
The single source of truth for a feature should be the heading where the
|
||||
The single source of truth for a feature should be the topic where the
|
||||
functionality is described.
|
||||
|
||||
#### Available product tier badges
|
||||
|
|
|
@ -35,7 +35,7 @@ Don't use backticks.
|
|||
|
||||
## 2FA, two-factor authentication
|
||||
|
||||
Spell out **two-factor authentication** in sentence case for the first use and in section headings, and **2FA**
|
||||
Spell out **two-factor authentication** in sentence case for the first use and in topic titles, and **2FA**
|
||||
thereafter. If the first word in a sentence, do not capitalize `factor` or `authentication`. For example:
|
||||
|
||||
- Two-factor authentication (2FA) helps secure your account. Set up 2FA when you first log in.
|
||||
|
|
|
@ -86,7 +86,7 @@ job, which runs two types of link checks. In both cases, links with destinations
|
|||
that begin with `http` or `https` are considered external links, and skipped:
|
||||
|
||||
- `bundle exec nanoc check internal_links`: Tests links to internal pages.
|
||||
- `bundle exec nanoc check internal_anchors`: Tests links to subheadings (anchors) on internal pages.
|
||||
- `bundle exec nanoc check internal_anchors`: Tests links to topic title anchors on internal pages.
|
||||
|
||||
Failures from these tests are displayed at the end of the test results in the **Issues found!** area.
|
||||
For example, failures in the `internal_anchors` test follow this format:
|
||||
|
@ -104,7 +104,7 @@ For example, failures in the `internal_anchors` test follow this format:
|
|||
- **Destination**: The full path to the file not found by the test. To find the
|
||||
file in the `gitlab` repository, replace `/tmp/gitlab-docs/public/ee` with `doc`, and `.html` with `.md`.
|
||||
- **Link**: The actual link the script attempted to find.
|
||||
- **Anchor**: If present, the subheading (anchor) the script attempted to find.
|
||||
- **Anchor**: If present, the topic title anchor the script attempted to find.
|
||||
|
||||
Check for multiple instances of the same broken link on each page reporting an error.
|
||||
Even if a specific broken link appears multiple times on a page, the test reports it only once.
|
||||
|
|
|
@ -32,13 +32,13 @@ Remember, if you start to describe about another concept, stop yourself.
|
|||
Each concept should be about one concept only.
|
||||
```
|
||||
|
||||
## Concept headings
|
||||
## Concept topic titles
|
||||
|
||||
For the heading text, use a noun. For example, `Widgets` or `GDK dependency management`.
|
||||
For the title text, use a noun. For example, `Widgets` or `GDK dependency management`.
|
||||
|
||||
If a noun is ambiguous, you can add a gerund. For example, `Documenting versions` instead of `Versions`.
|
||||
|
||||
Avoid these heading titles:
|
||||
Avoid these topic titles:
|
||||
|
||||
- `Overview` or `Introduction`. Instead, use a more specific
|
||||
noun or phrase that someone would search for.
|
||||
|
|
|
@ -66,14 +66,14 @@ Some pages are solely a list of links to other documentation.
|
|||
We do not encourage this page type. Lists of links can get out-of-date quickly
|
||||
and offer little value to users, who prefer to search to find information.
|
||||
|
||||
## Heading text guidelines
|
||||
## Topic text guidelines
|
||||
|
||||
In general, for heading text:
|
||||
In general, for topic text:
|
||||
|
||||
- Be clear and direct. Make every word count.
|
||||
- Use articles and prepositions.
|
||||
- Follow [capitalization](../styleguide/index.md#capitalization) guidelines.
|
||||
- Do not repeat text from earlier headings. For example, if the page is about merge requests,
|
||||
- Do not repeat text from earlier topic titles. For example, if the page is about merge requests,
|
||||
instead of `Troubleshooting merge requests`, use only `Troubleshooting`.
|
||||
|
||||
See also [guidelines for headings in Markdown](../styleguide/index.md#headings-in-markdown).
|
||||
See also [guidelines for heading levels in Markdown](../styleguide/index.md#heading-levels-in-markdown).
|
||||
|
|
|
@ -19,11 +19,11 @@ Introductory sentence.
|
|||
| **Name** | Descriptive sentence about the setting. |
|
||||
```
|
||||
|
||||
## Reference headings
|
||||
## Reference topic titles
|
||||
|
||||
Reference headings are usually nouns.
|
||||
Reference topic titles are usually nouns.
|
||||
|
||||
Avoid these heading titles:
|
||||
Avoid these topic titles:
|
||||
|
||||
- `Important notes`. Instead, incorporate this information
|
||||
closer to where it belongs. For example, this information might be a prerequisite
|
||||
|
|
|
@ -52,9 +52,9 @@ To create an issue:
|
|||
The issue is created. You can view it by going to **Issues > List**.
|
||||
```
|
||||
|
||||
## Task headings
|
||||
## Task topic titles
|
||||
|
||||
For the heading text, use the structure `active verb` + `noun`.
|
||||
For the title text, use the structure `active verb` + `noun`.
|
||||
For example, `Create an issue`.
|
||||
|
||||
If you have several tasks on a page that share prerequisites, you can use the title
|
||||
|
|
|
@ -46,12 +46,13 @@ The workaround is...
|
|||
If multiple causes or workarounds exist, consider putting them into a table format.
|
||||
If you use the exact error message, surround it in backticks so it's styled as code.
|
||||
|
||||
## Troubleshooting headings
|
||||
## Troubleshooting topic titles
|
||||
|
||||
For the heading of a **Troubleshooting reference** topic:
|
||||
For the title of a **Troubleshooting reference** topic:
|
||||
|
||||
- Consider including at least a partial error message.
|
||||
- Use fewer than 70 characters.
|
||||
- Do not use links in the title.
|
||||
|
||||
If you do not put the full error in the title, include it in the body text.
|
||||
|
||||
|
|
|
@ -54,9 +54,9 @@ To do step 2:
|
|||
1. Another step.
|
||||
```
|
||||
|
||||
## Tutorial headings
|
||||
## Tutorial page title
|
||||
|
||||
Start with `Tutorial:` followed by an active verb, like `Tutorial: Create a website`.
|
||||
Start the page title with `Tutorial:` followed by an active verb, like `Tutorial: Create a website`.
|
||||
|
||||
## Screenshots
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ You do not need to add version information on the pages in the `/development` di
|
|||
|
||||
### Add a **Version history** item
|
||||
|
||||
If all content in a topic is related, add a version history item after the topic heading.
|
||||
If all content in a topic is related, add a version history item after the topic title.
|
||||
For example:
|
||||
|
||||
```markdown
|
||||
|
|
|
@ -153,7 +153,7 @@ Ensure the following if skipping an initial Technical Writer review:
|
|||
- [Product badges](styleguide/index.md#product-tier-badges) are applied.
|
||||
- The GitLab [version](versions.md) that
|
||||
introduced the feature is included.
|
||||
- Changes to headings don't affect in-app hyperlinks.
|
||||
- Changes to topic titles don't affect in-app hyperlinks.
|
||||
- Specific [user permissions](../../user/permissions.md) are documented.
|
||||
- New documents are linked from higher-level indexes, for discoverability.
|
||||
- The style guide is followed:
|
||||
|
|
|
@ -156,7 +156,7 @@ You can use Redis metrics to track events not kept in the database, for example,
|
|||
|
||||
[Example of a merge request that adds a `Redis` metric](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/97009).
|
||||
|
||||
Please note that `RedisMetric` class can only be used as the `instrumentation_class` for Redis metrics with simple counters classes (classes that only inherit `BaseCounter` and set `PREFIX` and `KNOWN_EVENTS` constants). In case the counter class has additional logic included in it, a new `instrumentation_class`, inheriting from `RedisMetric`, needs to be created. This new class needs to include the additional logic from the counter class.
|
||||
The `RedisMetric` class can only be used as the `instrumentation_class` for Redis metrics with simple counters classes (classes that only inherit `BaseCounter` and set `PREFIX` and `KNOWN_EVENTS` constants). In case the counter class has additional logic included in it, a new `instrumentation_class`, inheriting from `RedisMetric`, needs to be created. This new class needs to include the additional logic from the counter class.
|
||||
|
||||
Count unique values for `source_code_pushes` event.
|
||||
|
||||
|
|
|
@ -422,7 +422,7 @@ At the moment, the feature flag API falls into **Unauthenticated traffic (from a
|
|||
in the [GitLab.com specific limits](../user/gitlab_com/index.md),
|
||||
so it's **500 requests per minute**.
|
||||
|
||||
Please note that the polling rate is configurable in SDKs. Provided that all clients are requesting from the same IP:
|
||||
The polling rate is configurable in SDKs. Provided that all clients are requesting from the same IP:
|
||||
|
||||
- Request once per minute ... 500 clients can be supported.
|
||||
- Request once per 15 sec ... 125 clients can be supported.
|
||||
|
|
|
@ -104,7 +104,7 @@ The **Overview** dashboard shows the following key metrics that measure team per
|
|||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/355304) time to restore service tile in GitLab 15.0.
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/357071) change failure rate tile in GitLab 15.0.
|
||||
|
||||
The value stream analytics **Overview** dashboard displays the following [DORA](../../../user/analytics/index.md) metrics:
|
||||
The value stream analytics **Overview** dashboard displays the following [DORA](../../../user/analytics/dora_metrics.md) metrics:
|
||||
|
||||
- Deployment Frequency.
|
||||
- Lead time for changes.
|
||||
|
|
|
@ -172,36 +172,37 @@ module API
|
|||
# Keep in alphabetical order
|
||||
mount ::API::AccessRequests
|
||||
mount ::API::Appearance
|
||||
mount ::API::Applications
|
||||
mount ::API::BroadcastMessages
|
||||
mount ::API::BulkImports
|
||||
mount ::API::Ci::ResourceGroups
|
||||
mount ::API::Ci::Runner
|
||||
mount ::API::Ci::Runners
|
||||
mount ::API::Clusters::Agents
|
||||
mount ::API::Clusters::AgentTokens
|
||||
mount ::API::Clusters::Agents
|
||||
mount ::API::DeployKeys
|
||||
mount ::API::DeployTokens
|
||||
mount ::API::Deployments
|
||||
mount ::API::Environments
|
||||
mount ::API::FeatureFlagsUserLists
|
||||
mount ::API::FeatureFlags
|
||||
mount ::API::FeatureFlagsUserLists
|
||||
mount ::API::Features
|
||||
mount ::API::FreezePeriods
|
||||
mount ::API::Keys
|
||||
mount ::API::ImportBitbucketServer
|
||||
mount ::API::ImportGithub
|
||||
mount ::API::Metadata
|
||||
mount ::API::Keys
|
||||
mount ::API::MergeRequestDiffs
|
||||
mount ::API::Metadata
|
||||
mount ::API::PersonalAccessTokens::SelfInformation
|
||||
mount ::API::ProjectExport
|
||||
mount ::API::ProjectHooks
|
||||
mount ::API::ProjectRepositoryStorageMoves
|
||||
mount ::API::Releases
|
||||
mount ::API::Release::Links
|
||||
mount ::API::ResourceAccessTokens
|
||||
mount ::API::ProjectSnapshots
|
||||
mount ::API::ProtectedTags
|
||||
mount ::API::ProtectedBranches
|
||||
mount ::API::ProtectedTags
|
||||
mount ::API::Release::Links
|
||||
mount ::API::Releases
|
||||
mount ::API::ResourceAccessTokens
|
||||
mount ::API::SnippetRepositoryStorageMoves
|
||||
mount ::API::Statistics
|
||||
mount ::API::Submodules
|
||||
|
@ -221,7 +222,6 @@ module API
|
|||
mount ::API::Admin::PlanLimits
|
||||
mount ::API::Admin::Sidekiq
|
||||
mount ::API::AlertManagementAlerts
|
||||
mount ::API::Applications
|
||||
mount ::API::Avatar
|
||||
mount ::API::AwardEmoji
|
||||
mount ::API::Badges
|
||||
|
|
|
@ -10,17 +10,21 @@ module API
|
|||
resource :applications do
|
||||
desc 'Create a new application' do
|
||||
detail 'This feature was introduced in GitLab 10.5'
|
||||
success Entities::ApplicationWithSecret
|
||||
success code: 200, model: Entities::ApplicationWithSecret
|
||||
end
|
||||
params do
|
||||
requires :name, type: String, desc: 'Application name'
|
||||
requires :redirect_uri, type: String, desc: 'Application redirect URI'
|
||||
requires :scopes, type: String, desc: 'Application scopes', allow_blank: false
|
||||
requires :name, type: String, desc: 'Name of the application.', documentation: { example: 'MyApplication' }
|
||||
requires :redirect_uri, type: String, desc: 'Redirect URI of the application.', documentation: { example: 'https://redirect.uri' }
|
||||
requires :scopes, type: String,
|
||||
desc: 'Scopes of the application. You can specify multiple scopes by separating\
|
||||
each scope using a space',
|
||||
allow_blank: false
|
||||
|
||||
optional :confidential,
|
||||
type: Boolean,
|
||||
default: true,
|
||||
desc: 'Application will be used where the client secret is confidential'
|
||||
desc: 'The application is used where the client secret can be kept confidential. Native mobile apps \
|
||||
and Single Page Apps are considered non-confidential. Defaults to true if not supplied'
|
||||
end
|
||||
post do
|
||||
application = Doorkeeper::Application.new(declared_params)
|
||||
|
@ -33,14 +37,19 @@ module API
|
|||
end
|
||||
|
||||
desc 'Get applications' do
|
||||
detail 'List all registered applications'
|
||||
success Entities::Application
|
||||
is_array true
|
||||
end
|
||||
get do
|
||||
applications = ApplicationsFinder.new.execute
|
||||
present applications, with: Entities::Application
|
||||
end
|
||||
|
||||
desc 'Delete an application'
|
||||
desc 'Delete an application' do
|
||||
detail 'Delete a specific application'
|
||||
success code: 204
|
||||
end
|
||||
params do
|
||||
requires :id, type: Integer, desc: 'The ID of the application (not the application_id)'
|
||||
end
|
||||
|
|
|
@ -4,10 +4,12 @@ module API
|
|||
module Entities
|
||||
class Application < Grape::Entity
|
||||
expose :id
|
||||
expose :uid, as: :application_id
|
||||
expose :name, as: :application_name
|
||||
expose :redirect_uri, as: :callback_url
|
||||
expose :confidential
|
||||
expose :uid, as: :application_id,
|
||||
documentation: { type: 'string',
|
||||
example: '5832fc6e14300a0d962240a8144466eef4ee93ef0d218477e55f11cf12fc3737' }
|
||||
expose :name, as: :application_name, documentation: { type: 'string', example: 'MyApplication' }
|
||||
expose :redirect_uri, as: :callback_url, documentation: { type: 'string', example: 'https://redirect.uri' }
|
||||
expose :confidential, documentation: { type: 'boolean', example: true }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,7 +4,8 @@ module API
|
|||
module Entities
|
||||
# Use with care, this exposes the secret
|
||||
class ApplicationWithSecret < Entities::Application
|
||||
expose :secret
|
||||
expose :secret, documentation: { type: 'string',
|
||||
example: 'ee1dd64b6adc89cf7e2c23099301ccc2c61b441064e9324d963c46902a85ec34' }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -72,7 +72,8 @@ module Gitlab
|
|||
Collection.new(@variables.reject(&block))
|
||||
end
|
||||
|
||||
def expand_value(value, keep_undefined: false, expand_file_vars: true, project: nil)
|
||||
# `expand_raw_refs` will be deleted with the FF `ci_raw_variables_in_yaml_config`.
|
||||
def expand_value(value, keep_undefined: false, expand_file_refs: true, expand_raw_refs: true, project: nil)
|
||||
value.gsub(Item::VARIABLES_REGEXP) do
|
||||
match = Regexp.last_match # it is either a valid variable definition or a ($$ / %%)
|
||||
full_match = match[0]
|
||||
|
@ -86,20 +87,26 @@ module Gitlab
|
|||
variable = self[variable_name]
|
||||
|
||||
if variable # VARIABLE_NAME is an existing variable
|
||||
next variable.value unless variable.file?
|
||||
if variable.file?
|
||||
# Will be cleaned up with https://gitlab.com/gitlab-org/gitlab/-/issues/378266
|
||||
if project
|
||||
# We only log if `project` exists to make sure it is called from `Ci::BuildRunnerPresenter`
|
||||
# when the variables are sent to Runner.
|
||||
Gitlab::AppJsonLogger.info(event: 'file_variable_is_referenced_in_another_variable',
|
||||
project_id: project.id,
|
||||
variable: variable_name)
|
||||
end
|
||||
|
||||
# Will be cleaned up with https://gitlab.com/gitlab-org/gitlab/-/issues/378266
|
||||
if project
|
||||
# We only log if `project` exists to make sure it is called from `Ci::BuildRunnerPresenter`
|
||||
# when the variables are sent to Runner.
|
||||
Gitlab::AppJsonLogger.info(
|
||||
event: 'file_variable_is_referenced_in_another_variable',
|
||||
project_id: project.id,
|
||||
variable: variable_name
|
||||
)
|
||||
expand_file_refs ? variable.value : full_match
|
||||
elsif variable.raw?
|
||||
# With `full_match`, we defer the expansion of raw variables to the runner. If we expand them here,
|
||||
# the runner will not know the expanded value is a raw variable and it tries to expand it again.
|
||||
# Discussion: https://gitlab.com/gitlab-org/gitlab/-/issues/353991#note_1103274951
|
||||
expand_raw_refs ? variable.value : full_match
|
||||
else
|
||||
variable.value
|
||||
end
|
||||
|
||||
expand_file_vars ? variable.value : full_match
|
||||
elsif keep_undefined
|
||||
full_match # we do not touch the variable definition
|
||||
else
|
||||
|
@ -108,7 +115,8 @@ module Gitlab
|
|||
end
|
||||
end
|
||||
|
||||
def sort_and_expand_all(keep_undefined: false, expand_file_vars: true, project: nil)
|
||||
# `expand_raw_refs` will be deleted with the FF `ci_raw_variables_in_yaml_config`.
|
||||
def sort_and_expand_all(keep_undefined: false, expand_file_refs: true, expand_raw_refs: true, project: nil)
|
||||
sorted = Sort.new(self)
|
||||
return self.class.new(self, sorted.errors) unless sorted.valid?
|
||||
|
||||
|
@ -123,7 +131,8 @@ module Gitlab
|
|||
# expand variables as they are added
|
||||
variable = item.to_runner_variable
|
||||
variable[:value] = new_collection.expand_value(variable[:value], keep_undefined: keep_undefined,
|
||||
expand_file_vars: expand_file_vars,
|
||||
expand_file_refs: expand_file_refs,
|
||||
expand_raw_refs: expand_raw_refs,
|
||||
project: project)
|
||||
new_collection.append(variable)
|
||||
end
|
||||
|
|
|
@ -21,9 +21,10 @@ module Gitlab
|
|||
@variable.fetch(:value)
|
||||
end
|
||||
|
||||
def raw
|
||||
def raw?
|
||||
@variable.fetch(:raw)
|
||||
end
|
||||
alias_method :raw, :raw?
|
||||
|
||||
def file?
|
||||
@variable.fetch(:file)
|
||||
|
@ -39,7 +40,7 @@ module Gitlab
|
|||
|
||||
def depends_on
|
||||
strong_memoize(:depends_on) do
|
||||
next if raw
|
||||
next if raw?
|
||||
|
||||
next unless self.class.possible_var_reference?(value)
|
||||
|
||||
|
|
|
@ -36531,6 +36531,9 @@ msgstr ""
|
|||
msgid "SecurityOrchestration|vulnerability"
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityPolicies|Invalid or empty policy"
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityReports|%{count} Selected"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module QA
|
||||
module Scenario
|
||||
module Test
|
||||
module Instance
|
||||
class GitlabPages < All
|
||||
tags :gitlab_pages
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,8 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module QA
|
||||
RSpec.describe 'Create', :runner, only: { subdomain: :staging }, product_group: :editor do
|
||||
RSpec.describe 'Create', :gitlab_pages, :orchestrated, except: { job: 'review-qa-*', subdomain: :production } do
|
||||
# TODO: Convert back to :smoke once proved to be stable. Related issue: https://gitlab.com/gitlab-org/gitlab/-/issues/300906
|
||||
describe 'Pages' do
|
||||
describe 'Pages', product_group: :editor do
|
||||
let!(:project) do
|
||||
Resource::Project.fabricate_via_api! do |project|
|
||||
project.name = 'jekyll-pages-project'
|
||||
|
@ -21,7 +22,6 @@ module QA
|
|||
|
||||
before do
|
||||
Flow::Login.sign_in
|
||||
|
||||
Resource::Runner.fabricate_via_api! do |runner|
|
||||
runner.project = project
|
||||
runner.executor = :docker
|
||||
|
|
|
@ -197,11 +197,11 @@ RSpec.describe Gitlab::Ci::Variables::Collection::Item do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#raw' do
|
||||
describe '#raw?' do
|
||||
it 'returns false when :raw is not specified' do
|
||||
item = described_class.new(**variable)
|
||||
|
||||
expect(item.raw).to eq false
|
||||
expect(item.raw?).to eq false
|
||||
end
|
||||
|
||||
context 'when :raw is specified as true' do
|
||||
|
@ -212,7 +212,7 @@ RSpec.describe Gitlab::Ci::Variables::Collection::Item do
|
|||
it 'returns true' do
|
||||
item = described_class.new(**variable)
|
||||
|
||||
expect(item.raw).to eq true
|
||||
expect(item.raw?).to eq true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -300,7 +300,6 @@ RSpec.describe Gitlab::Ci::Variables::Collection do
|
|||
Gitlab::Ci::Variables::Collection.new
|
||||
.append(key: 'CI_JOB_NAME', value: 'test-1')
|
||||
.append(key: 'CI_BUILD_ID', value: '1')
|
||||
.append(key: 'RAW_VAR', value: '$TEST1', raw: true)
|
||||
.append(key: 'TEST1', value: 'test-3')
|
||||
.append(key: 'FILEVAR1', value: 'file value 1', file: true)
|
||||
end
|
||||
|
@ -322,10 +321,6 @@ RSpec.describe Gitlab::Ci::Variables::Collection do
|
|||
value: 'key${TEST1}-${CI_JOB_NAME}',
|
||||
result: 'keytest-3-test-1'
|
||||
},
|
||||
"complex expansions with raw variable": {
|
||||
value: 'key${RAW_VAR}-${CI_JOB_NAME}',
|
||||
result: 'key$TEST1-test-1'
|
||||
},
|
||||
"missing variable not keeping original": {
|
||||
value: 'key${MISSING_VAR}-${CI_JOB_NAME}',
|
||||
result: 'key-test-1'
|
||||
|
@ -339,22 +334,22 @@ RSpec.describe Gitlab::Ci::Variables::Collection do
|
|||
value: 'key-$TEST1-%%HOME%%-$${HOME}',
|
||||
result: 'key-test-3-%%HOME%%-$${HOME}'
|
||||
},
|
||||
"file variable with expand_file_vars: true": {
|
||||
"file variable with expand_file_refs: true": {
|
||||
value: 'key-$FILEVAR1-$TEST1',
|
||||
result: 'key-file value 1-test-3'
|
||||
},
|
||||
"file variable with expand_file_vars: false": {
|
||||
"file variable with expand_file_refs: false": {
|
||||
value: 'key-$FILEVAR1-$TEST1',
|
||||
result: 'key-$FILEVAR1-test-3',
|
||||
expand_file_vars: false
|
||||
expand_file_refs: false
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
with_them do
|
||||
let(:options) { { keep_undefined: keep_undefined, expand_file_vars: expand_file_vars }.compact }
|
||||
let(:options) { { keep_undefined: keep_undefined, expand_file_refs: expand_file_refs }.compact }
|
||||
|
||||
subject(:result) { collection.expand_value(value, **options) }
|
||||
subject(:expanded_result) { collection.expand_value(value, **options) }
|
||||
|
||||
it 'matches expected expansion' do
|
||||
is_expected.to eq(result)
|
||||
|
@ -509,17 +504,35 @@ RSpec.describe Gitlab::Ci::Variables::Collection do
|
|||
{ key: 'variable4', value: 'keyvalue${variable2}value3' }
|
||||
]
|
||||
},
|
||||
"complex expansions with raw variable": {
|
||||
"complex expansions with raw variable with expand_raw_refs: true (default)": {
|
||||
variables: [
|
||||
{ key: 'variable3', value: 'key_${variable}_${variable2}' },
|
||||
{ key: 'variable', value: '$variable2', raw: true },
|
||||
{ key: 'variable2', value: 'value2' }
|
||||
{ key: 'variable1', value: 'value1' },
|
||||
{ key: 'raw_var', value: 'raw-$variable1', raw: true },
|
||||
{ key: 'nonraw_var', value: 'nonraw-$variable1' },
|
||||
{ key: 'variable2', value: '$raw_var and $nonraw_var' }
|
||||
],
|
||||
keep_undefined: false,
|
||||
result: [
|
||||
{ key: 'variable', value: '$variable2', raw: true },
|
||||
{ key: 'variable2', value: 'value2' },
|
||||
{ key: 'variable3', value: 'key_$variable2_value2' }
|
||||
{ key: 'variable1', value: 'value1' },
|
||||
{ key: 'raw_var', value: 'raw-$variable1', raw: true },
|
||||
{ key: 'nonraw_var', value: 'nonraw-value1' },
|
||||
{ key: 'variable2', value: 'raw-$variable1 and nonraw-value1' }
|
||||
]
|
||||
},
|
||||
"complex expansions with raw variable with expand_raw_refs: false": {
|
||||
variables: [
|
||||
{ key: 'variable1', value: 'value1' },
|
||||
{ key: 'raw_var', value: 'raw-$variable1', raw: true },
|
||||
{ key: 'nonraw_var', value: 'nonraw-$variable1' },
|
||||
{ key: 'variable2', value: '$raw_var and $nonraw_var' }
|
||||
],
|
||||
keep_undefined: false,
|
||||
expand_raw_refs: false,
|
||||
result: [
|
||||
{ key: 'variable1', value: 'value1' },
|
||||
{ key: 'raw_var', value: 'raw-$variable1', raw: true },
|
||||
{ key: 'nonraw_var', value: 'nonraw-value1' },
|
||||
{ key: 'variable2', value: '$raw_var and nonraw-value1' }
|
||||
]
|
||||
},
|
||||
"variable value referencing password with special characters": {
|
||||
|
@ -553,8 +566,9 @@ RSpec.describe Gitlab::Ci::Variables::Collection do
|
|||
|
||||
with_them do
|
||||
let(:collection) { Gitlab::Ci::Variables::Collection.new(variables) }
|
||||
let(:options) { { keep_undefined: keep_undefined, expand_raw_refs: expand_raw_refs }.compact }
|
||||
|
||||
subject { collection.sort_and_expand_all(keep_undefined: keep_undefined) }
|
||||
subject(:expanded_result) { collection.sort_and_expand_all(**options) }
|
||||
|
||||
it 'returns Collection' do
|
||||
is_expected.to be_an_instance_of(Gitlab::Ci::Variables::Collection)
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
require_migration!
|
||||
|
||||
RSpec.describe ChangeDefaultValueOnPasswordLastChangedAtToUserDetails, :migration do
|
||||
let(:namespace) { table(:namespaces).create!(name: 'user', path: 'user') }
|
||||
let(:users) { table(:users) }
|
||||
let(:user_details) { table(:user_details) }
|
||||
|
||||
it 'correctly migrates up and down' do
|
||||
user = create_user!(email: '1234@abc')
|
||||
user_details.create!(user_id: user.id, provisioned_by_group_id: namespace.id)
|
||||
|
||||
expect(UserDetail.find_by(user_id: user.id).password_last_changed_at).to be_nil
|
||||
|
||||
migrate!
|
||||
|
||||
user = create_user!(email: 'abc@1234')
|
||||
user_details.create!(user_id: user.id, provisioned_by_group_id: namespace.id)
|
||||
|
||||
expect(UserDetail.find_by(user_id: user.id).password_last_changed_at).not_to be_nil
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def create_user!(name: "Example User", email: "user@example.com", user_type: nil)
|
||||
users.create!(
|
||||
name: name,
|
||||
email: email,
|
||||
username: name,
|
||||
projects_limit: 0,
|
||||
user_type: user_type,
|
||||
confirmed_at: Time.current
|
||||
)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,16 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
require_migration!
|
||||
|
||||
RSpec.describe AddIndexOnPasswordLastChangedAtToUserDetails, :migration do
|
||||
let(:index_name) { 'index_user_details_on_password_last_changed_at' }
|
||||
|
||||
it 'correctly migrates up and down' do
|
||||
expect(subject).not_to be_index_exists_by_name(:user_details, index_name)
|
||||
|
||||
migrate!
|
||||
|
||||
expect(subject).to be_index_exists_by_name(:user_details, index_name)
|
||||
end
|
||||
end
|
|
@ -325,7 +325,7 @@ RSpec.describe Ci::BuildRunnerPresenter do
|
|||
is_expected.to eq(presenter.variables.to_runner_variables)
|
||||
end
|
||||
|
||||
context 'when there are variables to expand' do
|
||||
context 'when there is a file variable to expand' do
|
||||
before_all do
|
||||
create(:ci_variable, project: project,
|
||||
key: 'regular_var',
|
||||
|
@ -360,6 +360,49 @@ RSpec.describe Ci::BuildRunnerPresenter do
|
|||
runner_variables
|
||||
end
|
||||
end
|
||||
|
||||
context 'when there is a raw variable to expand' do
|
||||
before_all do
|
||||
create(:ci_variable, project: project,
|
||||
key: 'regular_var',
|
||||
value: 'value 1')
|
||||
create(:ci_variable, project: project,
|
||||
key: 'raw_var',
|
||||
value: 'value 2',
|
||||
raw: true)
|
||||
create(:ci_variable, project: project,
|
||||
key: 'var_with_variables',
|
||||
value: 'value 3 and $regular_var and $raw_var and $undefined_var')
|
||||
end
|
||||
|
||||
it 'returns expanded variables without expanding raws' do
|
||||
expect(runner_variables).to include(
|
||||
{ key: 'regular_var', value: 'value 1',
|
||||
public: false, masked: false },
|
||||
{ key: 'raw_var', value: 'value 2',
|
||||
public: false, masked: false, raw: true },
|
||||
{ key: 'var_with_variables', value: 'value 3 and value 1 and $raw_var and $undefined_var',
|
||||
public: false, masked: false }
|
||||
)
|
||||
end
|
||||
|
||||
context 'when the FF ci_raw_variables_in_yaml_config is disabled' do
|
||||
before do
|
||||
stub_feature_flags(ci_raw_variables_in_yaml_config: false)
|
||||
end
|
||||
|
||||
it 'returns expanded variables' do
|
||||
expect(runner_variables).to include(
|
||||
{ key: 'regular_var', value: 'value 1',
|
||||
public: false, masked: false },
|
||||
{ key: 'raw_var', value: 'value 2',
|
||||
public: false, masked: false, raw: true },
|
||||
{ key: 'var_with_variables', value: 'value 3 and value 1 and value 2 and $undefined_var',
|
||||
public: false, masked: false }
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#runner_variables subset' do
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Ci::CreatePipelineService, :yaml_processor_feature_flag_corectness do
|
||||
let_it_be(:project) { create(:project, :repository) }
|
||||
let_it_be(:user) { project.first_owner }
|
||||
|
||||
let(:service) { described_class.new(project, user, { ref: 'master' }) }
|
||||
let(:pipeline) { service.execute(:push).payload }
|
||||
|
||||
before do
|
||||
stub_ci_pipeline_yaml_file(config)
|
||||
end
|
||||
|
||||
context 'when using variables' do
|
||||
context 'when variables have expand: true/false' do
|
||||
let(:config) do
|
||||
<<-YAML
|
||||
variables:
|
||||
VAR7:
|
||||
value: "value 7 $CI_PIPELINE_ID"
|
||||
expand: false
|
||||
VAR8:
|
||||
value: "value 8 $CI_PIPELINE_ID"
|
||||
expand: false
|
||||
|
||||
rspec:
|
||||
script: rspec
|
||||
variables:
|
||||
VAR1: "JOBID-$CI_JOB_ID"
|
||||
VAR2: "PIPELINEID-$CI_PIPELINE_ID and $VAR1"
|
||||
VAR3:
|
||||
value: "PIPELINEID-$CI_PIPELINE_ID and $VAR1"
|
||||
expand: false
|
||||
VAR4:
|
||||
value: "JOBID-$CI_JOB_ID"
|
||||
expand: false
|
||||
VAR5: "PIPELINEID-$CI_PIPELINE_ID and $VAR4"
|
||||
VAR6:
|
||||
value: "PIPELINEID-$CI_PIPELINE_ID and $VAR4"
|
||||
expand: false
|
||||
VAR7: "overridden value 7 $CI_PIPELINE_ID"
|
||||
YAML
|
||||
end
|
||||
|
||||
let(:rspec) { find_job('rspec') }
|
||||
|
||||
it 'creates the pipeline with a job that has variable expanded according to "expand"' do
|
||||
expect(pipeline).to be_created_successfully
|
||||
|
||||
expect(Ci::BuildRunnerPresenter.new(rspec).runner_variables).to include(
|
||||
{ key: 'VAR1', value: "JOBID-#{rspec.id}", public: true, masked: false },
|
||||
{ key: 'VAR2', value: "PIPELINEID-#{pipeline.id} and JOBID-#{rspec.id}", public: true, masked: false },
|
||||
{ key: 'VAR3', value: "PIPELINEID-$CI_PIPELINE_ID and $VAR1", public: true, masked: false, raw: true },
|
||||
{ key: 'VAR4', value: "JOBID-$CI_JOB_ID", public: true, masked: false, raw: true },
|
||||
{ key: 'VAR5', value: "PIPELINEID-#{pipeline.id} and $VAR4", public: true, masked: false },
|
||||
{ key: 'VAR6', value: "PIPELINEID-$CI_PIPELINE_ID and $VAR4", public: true, masked: false, raw: true },
|
||||
{ key: 'VAR7', value: "overridden value 7 #{pipeline.id}", public: true, masked: false },
|
||||
{ key: 'VAR8', value: "value 8 $CI_PIPELINE_ID", public: true, masked: false, raw: true }
|
||||
)
|
||||
end
|
||||
|
||||
context 'when the FF ci_raw_variables_in_yaml_config is disabled' do
|
||||
before do
|
||||
stub_feature_flags(ci_raw_variables_in_yaml_config: false)
|
||||
end
|
||||
|
||||
it 'creates the pipeline with a job that has all variables expanded' do
|
||||
expect(pipeline).to be_created_successfully
|
||||
|
||||
expect(Ci::BuildRunnerPresenter.new(rspec).runner_variables).to include(
|
||||
{ key: 'VAR1', value: "JOBID-#{rspec.id}", public: true, masked: false },
|
||||
{ key: 'VAR2', value: "PIPELINEID-#{pipeline.id} and JOBID-#{rspec.id}", public: true, masked: false },
|
||||
{ key: 'VAR3', value: "PIPELINEID-#{pipeline.id} and JOBID-#{rspec.id}", public: true, masked: false },
|
||||
{ key: 'VAR4', value: "JOBID-#{rspec.id}", public: true, masked: false },
|
||||
{ key: 'VAR5', value: "PIPELINEID-#{pipeline.id} and JOBID-#{rspec.id}", public: true, masked: false },
|
||||
{ key: 'VAR6', value: "PIPELINEID-#{pipeline.id} and JOBID-#{rspec.id}", public: true, masked: false },
|
||||
{ key: 'VAR7', value: "overridden value 7 #{pipeline.id}", public: true, masked: false },
|
||||
{ key: 'VAR8', value: "value 8 #{pipeline.id}", public: true, masked: false }
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_job(name)
|
||||
pipeline.processables.find { |job| job.name == name }
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue