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:
-rw-r--r--.gitlab/ci/review-apps/main.gitlab-ci.yml1
-rw-r--r--.gitlab/ci/rules.gitlab-ci.yml4
-rw-r--r--.gitlab/ci/test-metadata.gitlab-ci.yml2
-rw-r--r--app/assets/javascripts/packages_and_registries/dependency_proxy/app.vue3
-rw-r--r--app/models/integrations/microsoft_teams.rb37
-rw-r--r--app/views/layouts/_img_loader.html.haml2
-rw-r--r--doc/administration/audit_events.md7
-rw-r--r--doc/development/ai_features.md8
-rw-r--r--doc/tutorials/protected_workflow/img/approval_rules_v16_2.pngbin0 -> 9312 bytes
-rw-r--r--doc/tutorials/protected_workflow/img/branch_is_protected_v16_2.pngbin0 -> 8894 bytes
-rw-r--r--doc/tutorials/protected_workflow/img/branch_list_v16_1.pngbin0 -> 11202 bytes
-rw-r--r--doc/tutorials/protected_workflow/img/new_file_v16_2.pngbin0 -> 9452 bytes
-rw-r--r--doc/tutorials/protected_workflow/img/new_project_v16_2.pngbin0 -> 21608 bytes
-rw-r--r--doc/tutorials/protected_workflow/img/protections_in_place_v16_2.pngbin0 -> 22111 bytes
-rw-r--r--doc/tutorials/protected_workflow/img/search_engineering_v16_2.pngbin0 -> 6244 bytes
-rw-r--r--doc/tutorials/protected_workflow/img/subgroup_structure_v16_1.pngbin0 -> 16992 bytes
-rw-r--r--doc/tutorials/protected_workflow/index.md290
-rw-r--r--doc/user/project/ml/experiment_tracking/img/candidate_detail_ci_v16_12.pngbin0 -> 53241 bytes
-rw-r--r--doc/user/project/ml/experiment_tracking/index.md12
-rw-r--r--doc/user/project/ml/experiment_tracking/mlflow_client.md (renamed from doc/user/project/integrations/mlflow_client.md)43
-rw-r--r--gems/rspec_flaky/lib/rspec_flaky/report.rb1
-rw-r--r--lib/gitlab/i18n.rb18
-rw-r--r--locale/gitlab.pot3
-rwxr-xr-xscripts/remote_development/run-smoke-test-suite.sh1
-rwxr-xr-xscripts/review_apps/review-apps.sh5
-rw-r--r--spec/frontend/packages_and_registries/dependency_proxy/app_spec.js73
-rw-r--r--spec/models/integrations/microsoft_teams_spec.rb2
-rw-r--r--workhorse/.tool-versions2
28 files changed, 440 insertions, 74 deletions
diff --git a/.gitlab/ci/review-apps/main.gitlab-ci.yml b/.gitlab/ci/review-apps/main.gitlab-ci.yml
index 065a654eab2..f11cba97f63 100644
--- a/.gitlab/ci/review-apps/main.gitlab-ci.yml
+++ b/.gitlab/ci/review-apps/main.gitlab-ci.yml
@@ -49,7 +49,6 @@ review-build-cng:
GITLAB_REPO_URL: ${CI_PROJECT_URL}
GITLAB_IMAGE_REPOSITORY: "registry.gitlab.com/gitlab-org/build/cng-mirror"
GITLAB_IMAGE_SUFFIX: "ee"
- GITLAB_VERIFY_DEPLOY_TIMEOUT_MINUTES: 5
GITLAB_HELM_CHART_REF: "75b1486a9aec212d0f49ef1251526d8e51004bbc" # 7.0.1: https://gitlab.com/gitlab-org/charts/gitlab/-/commit/75b1486a9aec212d0f49ef1251526d8e51004bbc
environment:
name: review/${CI_COMMIT_REF_SLUG}${SCHEDULE_TYPE} # No separator for SCHEDULE_TYPE so it's compatible as before and looks nice without it
diff --git a/.gitlab/ci/rules.gitlab-ci.yml b/.gitlab/ci/rules.gitlab-ci.yml
index d0ce284fcef..28467dca3d5 100644
--- a/.gitlab/ci/rules.gitlab-ci.yml
+++ b/.gitlab/ci/rules.gitlab-ci.yml
@@ -2527,6 +2527,10 @@
changes:
- ".gitlab/ci/test-metadata.gitlab-ci.yml"
- "scripts/rspec_helpers.sh"
+ - <<: *if-merge-request
+ changes:
+ - "gems/gitlab-rspec"
+ - "gems/rspec_flaky"
###################
# workhorse rules #
diff --git a/.gitlab/ci/test-metadata.gitlab-ci.yml b/.gitlab/ci/test-metadata.gitlab-ci.yml
index 85d3ea11ac6..c890fb15a59 100644
--- a/.gitlab/ci/test-metadata.gitlab-ci.yml
+++ b/.gitlab/ci/test-metadata.gitlab-ci.yml
@@ -45,7 +45,7 @@ update-tests-metadata:
- rspec-ee system pg14
- rspec-ee background_migration pg14
script:
- - run_timed_command "retry gem install fog-aws mime-types activesupport rspec_profiling postgres-copy --no-document"
+ - run_timed_command "retry gem install fog-aws mime-types activesupport rspec rspec_profiling postgres-copy --no-document"
- source ./scripts/rspec_helpers.sh
- test -f "${FLAKY_RSPEC_SUITE_REPORT_PATH}" || echo -e "\e[31m" 'Consider add ~"pipeline:run-all-rspec" to run full rspec jobs' "\e[0m"
- update_tests_metadata
diff --git a/app/assets/javascripts/packages_and_registries/dependency_proxy/app.vue b/app/assets/javascripts/packages_and_registries/dependency_proxy/app.vue
index c4675c25df4..87a2eb362d5 100644
--- a/app/assets/javascripts/packages_and_registries/dependency_proxy/app.vue
+++ b/app/assets/javascripts/packages_and_registries/dependency_proxy/app.vue
@@ -194,8 +194,6 @@ export default {
</template>
</title-area>
- <gl-skeleton-loader v-if="$apollo.queries.group.loading" />
-
<gl-form-group
v-if="showDependencyProxyImagePrefix"
:label="$options.i18n.proxyImagePrefix"
@@ -225,6 +223,7 @@ export default {
</span>
</template>
</gl-form-group>
+ <gl-skeleton-loader v-else-if="$apollo.queries.group.loading" />
<manifests-list
:dependency-proxy-image-prefix="dependencyProxyImagePrefix"
diff --git a/app/models/integrations/microsoft_teams.rb b/app/models/integrations/microsoft_teams.rb
index d6cbe5760e8..a9ed0bd3da1 100644
--- a/app/models/integrations/microsoft_teams.rb
+++ b/app/models/integrations/microsoft_teams.rb
@@ -2,6 +2,24 @@
module Integrations
class MicrosoftTeams < BaseChatNotification
+ undef :notify_only_broken_pipelines
+
+ field :webhook,
+ section: SECTION_TYPE_CONNECTION,
+ help: 'https://outlook.office.com/webhook/…',
+ required: true
+
+ field :notify_only_broken_pipelines,
+ type: 'checkbox',
+ section: SECTION_TYPE_CONFIGURATION,
+ help: 'If selected, successful pipelines do not trigger a notification event.'
+
+ field :branches_to_be_notified,
+ type: 'select',
+ section: SECTION_TYPE_CONFIGURATION,
+ title: -> { s_('Integrations|Branches for which notifications are to be sent') },
+ choices: -> { branch_choices }
+
def title
'Microsoft Teams notifications'
end
@@ -26,23 +44,8 @@ module Integrations
pipeline wiki_page]
end
- def default_fields
- [
- { type: 'text', section: SECTION_TYPE_CONNECTION, name: 'webhook', help: 'https://outlook.office.com/webhook/…', required: true },
- {
- type: 'checkbox',
- section: SECTION_TYPE_CONFIGURATION,
- name: 'notify_only_broken_pipelines',
- help: 'If selected, successful pipelines do not trigger a notification event.'
- },
- {
- type: 'select',
- section: SECTION_TYPE_CONFIGURATION,
- name: 'branches_to_be_notified',
- title: s_('Integrations|Branches for which notifications are to be sent'),
- choices: self.class.branch_choices
- }
- ]
+ def fields
+ self.class.fields + build_event_channels
end
def sections
diff --git a/app/views/layouts/_img_loader.html.haml b/app/views/layouts/_img_loader.html.haml
index 979ebeb0a02..c1fe3ae0924 100644
--- a/app/views/layouts/_img_loader.html.haml
+++ b/app/views/layouts/_img_loader.html.haml
@@ -13,6 +13,6 @@
img.removeAttribute('data-src');
img.classList.remove('lazy');
img.classList.add('js-lazy-loaded');
- img.dataset.qa_selector = 'js_lazy_loaded_content';
+ img.dataset.testid = 'js_lazy_loaded_content';
});
}
diff --git a/doc/administration/audit_events.md b/doc/administration/audit_events.md
index 3ea94f5e4be..69c97982562 100644
--- a/doc/administration/audit_events.md
+++ b/doc/administration/audit_events.md
@@ -405,6 +405,13 @@ The following user actions on a GitLab instance generate instance audit events:
Instance events can also be accessed using the [Instance Audit Events API](../api/audit_events.md#instance-audit-events).
+#### Application settings **(PREMIUM)**
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/282428) in GitLab 16.2.
+
+When a user changes an application setting in an instance, project, or group,
+that change and the user that made the change are recorded in the audit log.
+
### GitLab Runner events
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/335509) in GitLab 14.8, audit events for when a runner is registered.
diff --git a/doc/development/ai_features.md b/doc/development/ai_features.md
index 7c4035fc6e9..52dc37caec3 100644
--- a/doc/development/ai_features.md
+++ b/doc/development/ai_features.md
@@ -43,7 +43,7 @@ See the [feature flag tracker](https://gitlab.com/gitlab-org/gitlab/-/issues/405
## Implement a new AI action
-To implement a new AI action, connect to the OpenAI API. You can connect to this API using either the:
+To implement a new AI action, connect to the preferred AI provider. You can connect to this API using either the:
- Experimental REST API.
- Abstraction layer.
@@ -208,7 +208,7 @@ The experimental endpoint is only available to GitLab team members on production
### GraphQL API
-To connect to the OpenAI API using the Abstraction Layer, use an extendable GraphQL API called
+To connect to the AI provider API using the Abstraction Layer, use an extendable GraphQL API called
[`aiAction`](https://gitlab.com/gitlab-org/gitlab/blob/master/ee/app/graphql/mutations/ai/action.rb).
The `input` accepts key/value pairs, where the `key` is the action that needs to be performed.
We only allow one AI action per mutation request.
@@ -237,6 +237,8 @@ mutation {
The GraphQL API then uses the [OpenAI Client](https://gitlab.com/gitlab-org/gitlab/blob/master/ee/lib/gitlab/llm/open_ai/client.rb)
to send the response.
+Remember that other clients are available and you should not use OpenAI.
+
#### How to receive a response
As the OpenAI API requests are handled in a background job, we do not keep the request alive and
@@ -256,6 +258,8 @@ You should only subscribe to the subscription once the mutation is sent. If mult
#### Current abstraction layer flow
+The following graph uses OpenAI as an example. You can use different providers.
+
```mermaid
flowchart TD
A[GitLab frontend] -->B[AiAction GraphQL mutation]
diff --git a/doc/tutorials/protected_workflow/img/approval_rules_v16_2.png b/doc/tutorials/protected_workflow/img/approval_rules_v16_2.png
new file mode 100644
index 00000000000..a7db9488bad
--- /dev/null
+++ b/doc/tutorials/protected_workflow/img/approval_rules_v16_2.png
Binary files differ
diff --git a/doc/tutorials/protected_workflow/img/branch_is_protected_v16_2.png b/doc/tutorials/protected_workflow/img/branch_is_protected_v16_2.png
new file mode 100644
index 00000000000..c4ea048a41e
--- /dev/null
+++ b/doc/tutorials/protected_workflow/img/branch_is_protected_v16_2.png
Binary files differ
diff --git a/doc/tutorials/protected_workflow/img/branch_list_v16_1.png b/doc/tutorials/protected_workflow/img/branch_list_v16_1.png
new file mode 100644
index 00000000000..d557c4a9350
--- /dev/null
+++ b/doc/tutorials/protected_workflow/img/branch_list_v16_1.png
Binary files differ
diff --git a/doc/tutorials/protected_workflow/img/new_file_v16_2.png b/doc/tutorials/protected_workflow/img/new_file_v16_2.png
new file mode 100644
index 00000000000..d42b461f9c5
--- /dev/null
+++ b/doc/tutorials/protected_workflow/img/new_file_v16_2.png
Binary files differ
diff --git a/doc/tutorials/protected_workflow/img/new_project_v16_2.png b/doc/tutorials/protected_workflow/img/new_project_v16_2.png
new file mode 100644
index 00000000000..00effb87856
--- /dev/null
+++ b/doc/tutorials/protected_workflow/img/new_project_v16_2.png
Binary files differ
diff --git a/doc/tutorials/protected_workflow/img/protections_in_place_v16_2.png b/doc/tutorials/protected_workflow/img/protections_in_place_v16_2.png
new file mode 100644
index 00000000000..b21a714562e
--- /dev/null
+++ b/doc/tutorials/protected_workflow/img/protections_in_place_v16_2.png
Binary files differ
diff --git a/doc/tutorials/protected_workflow/img/search_engineering_v16_2.png b/doc/tutorials/protected_workflow/img/search_engineering_v16_2.png
new file mode 100644
index 00000000000..ae69b41a665
--- /dev/null
+++ b/doc/tutorials/protected_workflow/img/search_engineering_v16_2.png
Binary files differ
diff --git a/doc/tutorials/protected_workflow/img/subgroup_structure_v16_1.png b/doc/tutorials/protected_workflow/img/subgroup_structure_v16_1.png
new file mode 100644
index 00000000000..3c4ee02d0f4
--- /dev/null
+++ b/doc/tutorials/protected_workflow/img/subgroup_structure_v16_1.png
Binary files differ
diff --git a/doc/tutorials/protected_workflow/index.md b/doc/tutorials/protected_workflow/index.md
new file mode 100644
index 00000000000..5245bdc5ba9
--- /dev/null
+++ b/doc/tutorials/protected_workflow/index.md
@@ -0,0 +1,290 @@
+---
+stage: Create
+group: Code Review
+info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments"
+---
+
+<!-- vale gitlab.FutureTense = NO -->
+
+# Tutorial: Build a protected workflow for your project **(FREE)**
+
+When your team starts a new project, they need a workflow that balances efficiency
+with appropriate reviews. In GitLab, you can create user groups, combine those
+groups with branch protections, and then enforce those protections with approval rules.
+
+This tutorial sets up protections for Excelsior Project's `1.x` and `1.x.x`
+release branches, and creates a minimal approval workflow for the project:
+
+1. [Create the `engineering` group](#create-the-engineering-group)
+1. [Create subgroups in `engineering`](#create-subgroups-in-engineering)
+1. [Add users to the subgroups](#add-users-to-the-subgroups)
+1. [Create the Excelsior project](#create-the-excelsior-project)
+1. [Add a basic CODEOWNERS file](#add-a-basic-codeowners-file)
+1. [Configure approval rules](#configure-approval-rules)
+1. [Enforce CODEOWNER approval on branches](#enforce-codeowner-approval-on-branches)
+1. [Create the release branches](#create-the-release-branches)
+
+## Prerequisites
+
+- You must have the Maintainer or Owner role.
+- You need a list of managers and their email addresses.
+- You need a list of your backend and frontend engineers, and their email addresses.
+- You understand [semantic versioning](https://semver.org/) for branch names.
+
+## Create the `engineering` group
+
+Before setting up Excelsior Project, you should create a group to own
+the project. Here, you'll set up the Engineering group:
+
+1. On the left sidebar, at the top, select **Create new...** (**{plus}**) and **New group**.
+1. Select **Create group**.
+1. For **Group name**, enter `Engineering`.
+1. For the **Group URL**, enter `engineering`.
+1. Set the **Visibility level** to **Private**.
+1. Personalize your experience so GitLab shows the most helpful information to you:
+ - For **Role**, select **System administrator**.
+ - For **Who will be using this group?** select **My company or team**.
+ - For **What will you use this group for?** select **I want to store my code**.
+1. Skip inviting members to the group. You'll add users in a later section of this tutorial.
+1. Select **Create group**.
+
+Next, you'll add subgroups to this `engineering` group for more granular control.
+
+## Create subgroups in `engineering`
+
+The `engineering` group is a good start, but Excelsior Project's
+backend engineers, frontend engineers, and managers
+have different tasks, and different areas of specialty.
+
+Here, you'll create three more granular subgroups in the Engineering group to
+segment users by the type of work they do: `managers`, `frontend`, and `backend`.
+Then you'll add these new groups as members of the `engineering` group.
+
+First, create the new subgroup:
+
+1. On the left sidebar, at the top, select **Search GitLab** (**{search}**)
+ and search for `engineering`. Select the group named `Engineering`:
+
+ ![The engineering group in search results](img/search_engineering_v16_2.png)
+
+1. On the overview page for the `engineering` group, in the upper-right corner,
+ select **New subgroup**.
+1. For the **Subgroup name**, enter `Managers`.
+1. Set the **Visibility level** to **Private**.
+1. Select **Create subgroup**.
+
+Next, add the subgroup as a member of the `engineering` group:
+
+1. On the left sidebar, at the top, select **Search GitLab** (**{search}**)
+ and search for `engineering`. Select the group named `Engineering`.
+1. On the left sidebar, select **Manage > Members**.
+1. On the top right, select **Invite a group**.
+1. For **Select a group to invite**, select `Engineering / Managers`.
+1. When adding the subgroups select the role **Maintainer**.
+ This configures the highest role a member of the subgroup can inherit when accessing the `engineering` group and its projects.
+1. Optional. Select an expiration date.
+1. Select **Invite**.
+
+Repeat this process to create subgroups for `backend` and `frontend`. When you're done,
+search for the `engineering` group one more time. Its overview page should show
+three subgroups, like this:
+
+![The engineering group has three subgroups](img/subgroup_structure_v16_1.png)
+
+## Add users to the subgroups
+
+In the previous step, when you added your subgroups to the parent group (`engineering`), you limited
+members of the subgroups to the Maintainer role. This is the highest role they can inherit
+for projects owned by `engineering`. As a result:
+
+- User 1 is added to the `manager` subgroup with the Guest role, and receives
+ the Guest role on `engineering` projects.
+- User 2 is added to the `manager` group with the Owner role. This role is higher
+ than the maximum role (Maintainer) you set, so User 2 receives the Maintainer
+ role instead of Owner.
+
+To add a user to the `frontend` subgroup:
+
+1. On the left sidebar, at the top, select **Search GitLab** (**{search}**)
+ and search for `frontend`. Select the `Frontend` group.
+1. Select **Manage > Members**.
+1. Select **Invite members**.
+1. Fill in the fields. Select the **Developer** role by default, increasing it
+ to **Maintainer** if this user reviews the work of others.
+1. Select **Invite**.
+1. Repeat these steps until you've added all of the frontend engineers into the
+ `frontend` subgroup.
+
+Now do the same with the `backend` and `managers` groups. The same user can be a
+member of multiple subgroups.
+
+## Create the Excelsior project
+
+Now that your group structure is in place, create the `excelsior` project
+for the teams to work in. Because both frontend and backend engineers
+are involved, `excelsior` should belong to `engineering` instead of any of the
+smaller subgroups you just created.
+
+To create the new `excelsior` project:
+
+1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) and
+ search for `engineering`. Select the group named `Engineering`.
+1. On the overview page for the `engineering` group, on the left sidebar, at the top,
+ select **Create new...** (**{plus}**) and **In this group > New project/repository**.
+1. Select **Create blank project**.
+1. Enter the project details:
+ - In the **Project name** field, enter `Excelsior`. The **Project slug** should
+ auto-populate with `excelsior`.
+ - For **Visibility Level**, select **Public**.
+ - Select **Initialize repository with a README** to add an initial file to the repository.
+1. Select **Create project**.
+
+GitLab creates the `excelsior` project for you, and redirects you to its homepage.
+It should look like this:
+
+![Your new, almost-empty excelsior project](img/new_project_v16_2.png)
+
+You'll use a feature on this page in the next step.
+
+## Add a basic CODEOWNERS file
+
+Add a CODEOWNERS file to the root directory of your project to route reviews to
+the right subgroup. This example sets up four rules:
+
+- All changes should be reviewed by someone in the `engineering` group.
+- A manager should review any change to the CODEOWNERS file itself.
+- Frontend engineers should review changes to frontend files.
+- Backend engineers should review changes to backend files.
+
+NOTE:
+GitLab Free supports only optional reviews. To make reviews required, you need
+GitLab Premium or Ultimate.
+
+To add a CODEOWNERS file to your `excelsior` project:
+
+1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) and
+ search for `Excelsior`. Select the project named `Excelsior`.
+1. Next to the branch name, select the plus icon (**{plus}**), then **New file**:
+ ![Create a new file in the project](img/new_file_v16_2.png)
+1. For **Filename**, enter `CODEOWNERS`. This will create a file named `CODEOWNERS`
+ in the root directory of your project.
+1. Paste this example into the editing area, changing `@engineering/` if it
+ does not match your group structure:
+
+ ```plaintext
+ # All changes should be reviewed by someone in the engineering group
+ * @engineering
+
+ # A manager should review any changes to this file
+ CODEOWNERS @engineering/managers
+
+ # Frontend files should be reviewed by FE engineers
+ [Frontend] @engineering/frontend
+ *.scss
+ *.js
+
+ # Backend files should be reviewed by BE engineers
+ [Backend] @engineering/backend
+ *.rb
+ ```
+
+1. For a **Commit message**, paste in:
+
+ ```plaintext
+ Adds a new CODEOWNERS file
+
+ Creates a small CODEOWNERS file to:
+ - Route backend and frontend changes to the right teams
+ - Route CODEOWNERS file changes to managers
+ - Request all changes be reviewed
+ ```
+
+1. Select **Commit changes**.
+
+The CODEOWNERS file is now in place in the `main` branch of your project, and
+available for all future branches created in this project.
+
+## Configure approval rules
+
+The CODEOWNERS file describes the appropriate reviewers for directories and
+file types. Approval rules direct merge requests to those reviewers.
+Here, you will set up an approval rule that uses the information in your new CODEOWNERS
+file and adds protection for release branches:
+
+1. On the left sidebar, select **Settings > Merge requests**.
+1. In the **Merge request approvals** section, scroll to **Approval rules**.
+1. Select **Add approval rule**.
+1. Create a rule named `Enforce CODEOWNERS`.
+1. Select **All protected branches**.
+1. To make the rule required in GitLab Premium and GitLab Ultimate,
+ set the **Approvals required** to `1`.
+1. Add the `managers` group as approvers.
+1. Select **Add approval rule**.
+1. Scroll to **Approval settings** and make sure
+ **Prevent editing approval rules in merge requests** is selected.
+1. Select **Save changes**.
+
+When added, the `Enforce CODEOWNERS` rule looks like this:
+
+![New approval rule in place](img/approval_rules_v16_2.png)
+
+## Enforce CODEOWNER approval on branches
+
+You've configured several protections for your project, and you're now ready to
+combine those protections together to safeguard your project's important branches:
+
+- Your users are sorted into logical groups and subgroups.
+- Your CODEOWNERS file describes the subject matter experts for file types and directories.
+- Your approval rule encourages (in GitLab Free) or requires (in GitLab Premium and GitLab Ultimate)
+ the subject matter experts to review changes.
+
+Your `excelsior` project uses [semantic versioning](https://semver.org/) for
+release branch names, so you know the release branches follow the pattern `1.x`
+and `1.x.x`. You want all code added to these branches to be reviewed by subject
+matter experts, and for managers to make the final decision on what work is merged
+into the release branch.
+
+Rather than create protections for a branch at a time, configure wildcard branch rules
+to protect multiple branches:
+
+1. On the left sidebar, select **Settings > Repository**.
+1. Expand **Protected branches**.
+1. From the **Branch** dropdown list, type `1.*`, and then select **Create wildcard `1.*`**.
+1. To require everyone to submit merge requests, rather than pushing commits directly:
+ 1. Set **Allowed to merge** to **Maintainers**.
+ 1. Set **Allowed to push and merge** to **No one**.
+ 1. Leave **Allowed to force push** disabled.
+1. In GitLab Premium and GitLab Ultimate, to require Code Owners to review changes
+ to files they work on, toggle **Require approval from code owners**.
+1. Select **Protect**.
+1. In the table of branches, find the rule marked as `Default`. (Depending on
+ your version of GitLab, this branch may be named `main` or `master`.) Set the
+ values for this branch to match the settings you used for the `1.*` rule.
+
+Your rules are now in place, even though no `1.*` branches exist yet:
+
+![main and 1.x are now protected](img/branch_list_v16_1.png)
+
+## Create the release branches
+
+Now that all branch protections in place, you're ready to create your 1.0.0 release branch:
+
+1. On the left sidebar, select **Code > Branches**.
+1. On the top right, select **New branch**. Name it `1.0.0`.
+1. Select **Create branch**.
+
+The branch protections are now visible in the UI:
+
+- On the left sidebar, select **Code > Branches**. In the list of branches,
+ branch `1.0.0` should be show that it is protected:
+
+ ![List of branches, showing 1.0.0 is protected](img/branch_is_protected_v16_2.png)
+
+- On the left sidebar, select **Settings > Repository**, then expand **Branch rules**
+ to see details about all protected branches:
+
+ ![List of protected branches and their protections](img/protections_in_place_v16_2.png)
+
+Congratulations! Your engineers can work independently in their feature branches,
+and all code submitted for consideration for the 1.0.0 release branch will
+be reviewed by subject matter experts.
diff --git a/doc/user/project/ml/experiment_tracking/img/candidate_detail_ci_v16_12.png b/doc/user/project/ml/experiment_tracking/img/candidate_detail_ci_v16_12.png
new file mode 100644
index 00000000000..fb4f8d5dc66
--- /dev/null
+++ b/doc/user/project/ml/experiment_tracking/img/candidate_detail_ci_v16_12.png
Binary files differ
diff --git a/doc/user/project/ml/experiment_tracking/index.md b/doc/user/project/ml/experiment_tracking/index.md
index 584a6c0df59..7fda6ef03a0 100644
--- a/doc/user/project/ml/experiment_tracking/index.md
+++ b/doc/user/project/ml/experiment_tracking/index.md
@@ -58,8 +58,8 @@ Some example parameters:
## Track new experiments and candidates
Experiment and trials can only be tracked through the
-[MLflow](https://www.mlflow.org/docs/latest/tracking.html) client integration.
-See [MLflow client integration](../../integrations/mlflow_client.md) for more information
+[MLflow](https://www.mlflow.org/docs/latest/tracking.html) client compatibility.
+See [MLflow client compatibility](mlflow_client.md) for more information
on how to use GitLab as a backend for the MLflow Client.
## Explore model candidates
@@ -82,6 +82,14 @@ limitations. After an artifact is logged for a candidate, all artifacts logged f
package registry. The package name for a candidate is `ml_experiment_<experiment_id>`, where the version is the candidate
IID. The link to the artifacts can also be accessed from the **Experiment Candidates** list or **Candidate detail**.
+## View CI information
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/119788) in 16.1
+
+Candidates can be associated to the CI job that created them, allowing quick links to the merge request, pipeline, and user that triggered the pipeline:
+
+![CI information in candidate detail](img/candidate_detail_ci_v16_12.png)
+
## Related topics
- Development details in [epic 8560](https://gitlab.com/groups/gitlab-org/-/epics/8560).
diff --git a/doc/user/project/integrations/mlflow_client.md b/doc/user/project/ml/experiment_tracking/mlflow_client.md
index 9d354c9a2d9..7fd5c7cca92 100644
--- a/doc/user/project/integrations/mlflow_client.md
+++ b/doc/user/project/ml/experiment_tracking/mlflow_client.md
@@ -4,17 +4,17 @@ group: Incubation
info: Machine Learning Experiment Tracking is a GitLab Incubation Engineering program. No technical writer assigned to this group.
---
-# MLflow client integration **(FREE)**
+# MLflow client compatibility **(FREE)**
-> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/8560) in GitLab 15.11 as an [Experiment](../../../policy/experiment-beta-support.md#experiment) release [with a flag](../../../administration/feature_flags.md) named `ml_experiment_tracking`. Disabled by default.
+> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/8560) in GitLab 15.11 as an [Experiment](../../../../policy/experiment-beta-support.md#experiment) release [with a flag](../../../../administration/feature_flags.md) named `ml_experiment_tracking`. Disabled by default.
NOTE:
-Model experiment tracking is an [experimental feature](../../../policy/experiment-beta-support.md).
+Model experiment tracking is an [experimental feature](../../../../policy/experiment-beta-support.md).
Refer to <https://gitlab.com/gitlab-org/gitlab/-/issues/381660> for feedback and feature requests.
[MLflow](https://mlflow.org/) is a popular open source tool for Machine Learning Experiment Tracking.
-GitLab works as a backend to the MLflow Client, [logging experiments](../ml/experiment_tracking/index.md).
-Setting up your integrations requires minimal changes to existing code.
+GitLab [Model experiment tracking](index.md) is compatible with MLflow Client,
+[logging experiments](index.md). The setup requires minimal changes to existing code.
GitLab plays the role of a MLflow server. Running `mlflow server` is not necessary.
@@ -22,12 +22,12 @@ GitLab plays the role of a MLflow server. Running `mlflow server` is not necessa
Prerequisites:
-- A [personal](../../../user/profile/personal_access_tokens.md), [project](../../../user/project/settings/project_access_tokens.md), or [group](../../../user/group/settings/group_access_tokens.md) access token with at least the Developer role and the `api` permission.
+- A [personal](../../../../user/profile/personal_access_tokens.md), [project](../../../../user/project/settings/project_access_tokens.md), or [group](../../../../user/group/settings/group_access_tokens.md) access token with at least the Developer role and the `api` permission.
- The project ID. To find the project ID:
1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
1. Select **Settings > General**.
-To enable MLflow client integration:
+To use MLflow client compatibility from a local environment:
1. Set the tracking URI and token environment variables on the host that runs the code.
This can be your local environment, CI pipeline, or remote host. For example:
@@ -53,18 +53,23 @@ Runs are registered as:
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/119454) in GitLab 16.1.
If your training code is being run from a CI/CD job, GitLab can use that information to enhance
-candidate metadata. To do so, add the following snippet to your training code within the run
-execution context:
-
-```python
-with mlflow.start_run(run_name=f"Candidate {index}"):
- # Your training code
-
- # Start of snippet to be included
- if os.getenv('GITLAB_CI'):
- mlflow.set_tag('gitlab.CI_JOB_ID', os.getenv('CI_JOB_ID'))
- # End of snippet to be included
-```
+candidate metadata. To associate a candidate to a CI/CD job:
+
+1. In the [Project CI variables](../../../../ci/variables/index.md), include the following variables:
+ - `MLFLOW_TRACKING_URI`: `"<your gitlab endpoint>/api/v4/projects/<your project id>/ml/mlflow"`
+ - `MLFLOW_TRACKING_TOKEN`: `<your_access_token>`
+
+1. In your training code within the run execution context, add the following code snippet:
+
+ ```python
+ with mlflow.start_run(run_name=f"Candidate {index}"):
+ # Your training code
+
+ # Start of snippet to be included
+ if os.getenv('GITLAB_CI'):
+ mlflow.set_tag('gitlab.CI_JOB_ID', os.getenv('CI_JOB_ID'))
+ # End of snippet to be included
+ ```
## Supported MLflow client methods and caveats
diff --git a/gems/rspec_flaky/lib/rspec_flaky/report.rb b/gems/rspec_flaky/lib/rspec_flaky/report.rb
index 3c8e1c933e1..cc213d336ae 100644
--- a/gems/rspec_flaky/lib/rspec_flaky/report.rb
+++ b/gems/rspec_flaky/lib/rspec_flaky/report.rb
@@ -2,6 +2,7 @@
require 'json'
require 'time'
+require 'fileutils'
require_relative 'config'
require_relative 'flaky_examples_collection'
diff --git a/lib/gitlab/i18n.rb b/lib/gitlab/i18n.rb
index 180ccf21264..fabc02af70a 100644
--- a/lib/gitlab/i18n.rb
+++ b/lib/gitlab/i18n.rb
@@ -44,30 +44,30 @@ module Gitlab
TRANSLATION_LEVELS = {
'bg' => 0,
'cs_CZ' => 0,
- 'da_DK' => 31,
- 'de' => 97,
+ 'da_DK' => 30,
+ 'de' => 99,
'en' => 100,
'eo' => 0,
- 'es' => 30,
+ 'es' => 29,
'fil_PH' => 0,
- 'fr' => 98,
+ 'fr' => 99,
'gl_ES' => 0,
'id_ID' => 0,
'it' => 1,
- 'ja' => 98,
- 'ko' => 18,
+ 'ja' => 99,
+ 'ko' => 17,
'nb_NO' => 22,
'nl_NL' => 0,
'pl_PL' => 3,
- 'pt_BR' => 56,
- 'ro_RO' => 82,
+ 'pt_BR' => 57,
+ 'ro_RO' => 80,
'ru' => 23,
'si_LK' => 10,
'tr_TR' => 9,
'uk' => 53,
'zh_CN' => 98,
'zh_HK' => 1,
- 'zh_TW' => 99
+ 'zh_TW' => 100
}.freeze
private_constant :TRANSLATION_LEVELS
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 4cdc81b693a..2f0b9362ab9 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -53796,6 +53796,9 @@ msgstr ""
msgid "ciReport|%{sameNum} same"
msgstr ""
+msgid "ciReport|%{scanner} detected %{atleastStart}at least%{atleastEnd} %{number} new potential %{vulnStr}"
+msgstr ""
+
msgid "ciReport|%{scanner} detected %{number} new potential %{vulnStr}"
msgstr ""
diff --git a/scripts/remote_development/run-smoke-test-suite.sh b/scripts/remote_development/run-smoke-test-suite.sh
index a48b66d31ab..0db57e04317 100755
--- a/scripts/remote_development/run-smoke-test-suite.sh
+++ b/scripts/remote_development/run-smoke-test-suite.sh
@@ -42,6 +42,7 @@ ee/spec/finders/remote_development/workspaces_finder_spec.rb \
ee/spec/graphql/types/query_type_spec.rb \
ee/spec/graphql/types/remote_development/workspace_type_spec.rb \
ee/spec/graphql/types/subscription_type_spec.rb \
+ee/spec/lib/remote_development/agent_config/main_integration_spec.rb \
ee/spec/lib/remote_development/unmatched_result_error_spec.rb \
ee/spec/lib/remote_development/workspaces/create/create_processor_spec.rb \
ee/spec/lib/remote_development/workspaces/create/devfile_processor_spec.rb \
diff --git a/scripts/review_apps/review-apps.sh b/scripts/review_apps/review-apps.sh
index 7ba63a4464a..af6c2ec5383 100755
--- a/scripts/review_apps/review-apps.sh
+++ b/scripts/review_apps/review-apps.sh
@@ -395,8 +395,9 @@ function verify_deploy() {
mkdir -p curl-logs/
- local max_try_times=${GITLAB_VERIFY_DEPLOY_TIMEOUT_MINUTES} * 60 / 5
- for i in {1..max_try_times}; do # try for GITLAB_VERIFY_DEPLOY_TIMEOUT_MINUTES minutes, default 5 minutes
+ # By default, try for 5 minutes, with 5 of sleep between attempts
+ local max_try_times=$((${GITLAB_VERIFY_DEPLOY_TIMEOUT_MINUTES:-5} * 60 / 5))
+ for i in {1..$max_try_times}; do
local now=$(date '+%H:%M:%S')
echo "[${now}] Verifying deployment at ${CI_ENVIRONMENT_URL}/users/sign_in"
log_name="curl-logs/${now}.log"
diff --git a/spec/frontend/packages_and_registries/dependency_proxy/app_spec.js b/spec/frontend/packages_and_registries/dependency_proxy/app_spec.js
index fd2220a20d2..f590cff0312 100644
--- a/spec/frontend/packages_and_registries/dependency_proxy/app_spec.js
+++ b/spec/frontend/packages_and_registries/dependency_proxy/app_spec.js
@@ -6,6 +6,7 @@ import {
GlFormGroup,
GlModal,
GlSprintf,
+ GlSkeletonLoader,
} from '@gitlab/ui';
import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
@@ -77,6 +78,7 @@ describe('DependencyProxyApp', () => {
const findFormInputGroup = () => wrapper.findComponent(GlFormInputGroup);
const findProxyCountText = () => wrapper.findByTestId('proxy-count');
const findManifestList = () => wrapper.findComponent(ManifestsList);
+ const findLoader = () => wrapper.findComponent(GlSkeletonLoader);
const findClearCacheDropdownList = () => wrapper.findComponent(GlDropdown);
const findClearCacheModal = () => wrapper.findComponent(GlModal);
const findClearCacheAlert = () => wrapper.findComponent(GlAlert);
@@ -100,9 +102,16 @@ describe('DependencyProxyApp', () => {
describe('when the dependency proxy is available', () => {
describe('when is loading', () => {
- it('does not render a form group with label', () => {
+ beforeEach(() => {
createComponent();
+ });
+
+ it('renders loading component & sets loading prop', () => {
+ expect(findLoader().exists()).toBe(true);
+ expect(findManifestList().props('loading')).toBe(true);
+ });
+ it('does not render a form group with label', () => {
expect(findFormGroup().exists()).toBe(false);
});
});
@@ -191,26 +200,58 @@ describe('DependencyProxyApp', () => {
});
});
- it('prev-page event on list fetches the previous page', async () => {
- findManifestList().vm.$emit('prev-page');
- await waitForPromises();
+ describe('prev-page event on list', () => {
+ beforeEach(() => {
+ findManifestList().vm.$emit('prev-page');
+ });
+
+ describe('while loading', () => {
+ it('does not render loading component & sets loading prop', () => {
+ expect(findLoader().exists()).toBe(false);
+ expect(findManifestList().props('loading')).toBe(true);
+ });
+
+ it('renders form group with label', () => {
+ expect(findFormGroup().exists()).toBe(true);
+ });
+ });
- expect(resolver).toHaveBeenCalledWith({
- before: pagination().startCursor,
- first: null,
- fullPath: provideDefaults.groupPath,
- last: GRAPHQL_PAGE_SIZE,
+ it('list fetches the previous page', async () => {
+ await waitForPromises();
+
+ expect(resolver).toHaveBeenCalledWith({
+ before: pagination().startCursor,
+ first: null,
+ fullPath: provideDefaults.groupPath,
+ last: GRAPHQL_PAGE_SIZE,
+ });
});
});
- it('next-page event on list fetches the next page', async () => {
- findManifestList().vm.$emit('next-page');
- await waitForPromises();
+ describe('next-page event on list', () => {
+ beforeEach(() => {
+ findManifestList().vm.$emit('next-page');
+ });
- expect(resolver).toHaveBeenCalledWith({
- after: pagination().endCursor,
- first: GRAPHQL_PAGE_SIZE,
- fullPath: provideDefaults.groupPath,
+ describe('while loading', () => {
+ it('does not render loading component & sets loading prop', () => {
+ expect(findLoader().exists()).toBe(false);
+ expect(findManifestList().props('loading')).toBe(true);
+ });
+
+ it('renders form group with label', () => {
+ expect(findFormGroup().exists()).toBe(true);
+ });
+ });
+
+ it('fetches the next page', async () => {
+ await waitForPromises();
+
+ expect(resolver).toHaveBeenCalledWith({
+ after: pagination().endCursor,
+ first: GRAPHQL_PAGE_SIZE,
+ fullPath: provideDefaults.groupPath,
+ });
});
});
diff --git a/spec/models/integrations/microsoft_teams_spec.rb b/spec/models/integrations/microsoft_teams_spec.rb
index f1d9071d232..4f5b4daad42 100644
--- a/spec/models/integrations/microsoft_teams_spec.rb
+++ b/spec/models/integrations/microsoft_teams_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Integrations::MicrosoftTeams do
+RSpec.describe Integrations::MicrosoftTeams, feature_category: :integrations do
it_behaves_like "chat integration", "Microsoft Teams" do
let(:client) { ::MicrosoftTeams::Notifier }
let(:client_arguments) { webhook_url }
diff --git a/workhorse/.tool-versions b/workhorse/.tool-versions
index e8249f49e4f..bf7f6cc9184 100644
--- a/workhorse/.tool-versions
+++ b/workhorse/.tool-versions
@@ -1 +1 @@
-golang 1.20.5
+golang 1.20.6