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/build-images.gitlab-ci.yml11
-rw-r--r--.gitlab/ci/frontend.gitlab-ci.yml5
-rw-r--r--.gitlab/ci/package-and-test/main.gitlab-ci.yml41
-rw-r--r--.gitlab/ci/qa.gitlab-ci.yml2
-rw-r--r--.gitlab/ci/review-apps/main.gitlab-ci.yml5
-rw-r--r--.gitlab/ci/review.gitlab-ci.yml2
-rw-r--r--Dockerfile.assets2
-rw-r--r--app/assets/javascripts/boards/graphql.js15
-rw-r--r--app/assets/javascripts/boards/index.js4
-rw-r--r--app/assets/javascripts/boards/stores/actions.js5
-rw-r--r--app/assets/javascripts/graphql_shared/issuable_client.js11
-rw-r--r--app/assets/javascripts/ml/experiment_tracking/components/experiment.vue36
-rw-r--r--app/assets/javascripts/ml/experiment_tracking/components/incubation_alert.vue48
-rw-r--r--app/assets/javascripts/pages/projects/ml/experiments/show/index.js31
-rw-r--r--app/assets/javascripts/pipelines/components/pipeline_mini_graph/pipeline_stage.vue14
-rw-r--r--app/assets/stylesheets/_page_specific_files.scss1
-rw-r--r--app/assets/stylesheets/pages/ml_experiment_tracking.scss16
-rw-r--r--app/assets/stylesheets/pages/search.scss7
-rw-r--r--app/controllers/projects/ml/experiments_controller.rb32
-rw-r--r--app/helpers/markup_helper.rb93
-rw-r--r--app/helpers/projects/ml/experiments_helper.rb24
-rw-r--r--app/models/ml/candidate.rb3
-rw-r--r--app/models/ml/candidate_metric.rb2
-rw-r--r--app/models/ml/experiment.rb2
-rw-r--r--app/services/markup/rendering_service.rb79
-rw-r--r--app/services/packages/rpm/parse_package_service.rb3
-rw-r--r--app/services/packages/rpm/repository_metadata/build_filelist_xml_service.rb39
-rw-r--r--app/services/packages/rpm/repository_metadata/build_other_xml_service.rb12
-rw-r--r--app/services/packages/rpm/repository_metadata/build_primary_xml_service.rb12
-rw-r--r--app/services/packages/rpm/repository_metadata/build_repomd_xml_service.rb12
-rw-r--r--app/services/packages/rpm/repository_metadata/build_xml_base_service.rb22
-rw-r--r--app/services/packages/rpm/repository_metadata/update_xml_service.rb3
-rw-r--r--app/views/projects/ml/experiments/_experiment.html.haml3
-rw-r--r--app/views/projects/ml/experiments/_experiment_list.html.haml7
-rw-r--r--app/views/projects/ml/experiments/_incubation_banner.html.haml8
-rw-r--r--app/views/projects/ml/experiments/index.html.haml11
-rw-r--r--app/views/projects/ml/experiments/show.html.haml14
-rw-r--r--config/open_api.yml4
-rw-r--r--config/routes/project.rb4
-rw-r--r--db/structure.sql20
-rw-r--r--doc/administration/consul.md2
-rw-r--r--doc/administration/geo/replication/docker_registry.md11
-rw-r--r--doc/administration/geo/replication/faq.md10
-rw-r--r--doc/administration/geo/replication/security_review.md10
-rw-r--r--doc/administration/geo/replication/troubleshooting.md3
-rw-r--r--doc/administration/geo/setup/external_database.md2
-rw-r--r--doc/administration/gitaly/configure_gitaly.md4
-rw-r--r--doc/administration/logs.md11
-rw-r--r--doc/administration/maintenance_mode/index.md2
-rw-r--r--doc/administration/monitoring/performance/index.md2
-rw-r--r--doc/administration/monitoring/prometheus/gitlab_metrics.md2
-rw-r--r--doc/administration/nfs.md4
-rw-r--r--doc/administration/object_storage.md6
-rw-r--r--doc/administration/package_information/omnibus_packages.md2
-rw-r--r--doc/administration/pages/index.md4
-rw-r--r--doc/administration/polling.md4
-rw-r--r--doc/administration/redis/troubleshooting.md4
-rw-r--r--doc/administration/reference_architectures/2k_users.md4
-rw-r--r--doc/administration/reference_architectures/index.md4
-rw-r--r--doc/administration/reference_architectures/troubleshooting.md11
-rw-r--r--doc/administration/troubleshooting/debug.md11
-rw-r--r--doc/administration/troubleshooting/defcon.md11
-rw-r--r--doc/administration/troubleshooting/group_saml_scim.md11
-rw-r--r--doc/administration/troubleshooting/kubernetes_cheat_sheet.md11
-rw-r--r--doc/administration/troubleshooting/log_parsing.md11
-rw-r--r--doc/administration/troubleshooting/navigating_gitlab_via_rails_console.md11
-rw-r--r--doc/api/issues.md4
-rw-r--r--doc/api/lint.md2
-rw-r--r--doc/ci/cloud_deployment/index.md2
-rw-r--r--doc/ci/cloud_services/azure/index.md20
-rw-r--r--doc/ci/environments/environments_dashboard.md2
-rw-r--r--doc/ci/examples/authenticating-with-hashicorp-vault/index.md32
-rw-r--r--doc/ci/examples/deployment/composer-npm-deploy.md2
-rw-r--r--doc/ci/jobs/ci_job_token.md4
-rw-r--r--doc/ci/jobs/job_control.md4
-rw-r--r--doc/ci/migration/jenkins.md8
-rw-r--r--doc/ci/pipelines/cicd_minutes.md2
-rw-r--r--doc/ci/pipelines/index.md4
-rw-r--r--doc/ci/pipelines/pipeline_architectures.md2
-rw-r--r--doc/ci/pipelines/pipeline_efficiency.md2
-rw-r--r--doc/ci/secrets/index.md12
-rw-r--r--doc/ci/yaml/index.md2
-rw-r--r--doc/development/audit_event_guide/index.md2
-rw-r--r--doc/development/code_review.md6
-rw-r--r--doc/development/contributing/design.md2
-rw-r--r--doc/development/development_processes.md2
-rw-r--r--doc/development/fips_compliance.md2
-rw-r--r--doc/development/gemfile.md2
-rw-r--r--doc/development/licensed_feature_availability.md11
-rw-r--r--doc/development/merge_request_concepts/widget_extensions.md11
-rw-r--r--doc/development/secure_coding_guidelines.md4
-rw-r--r--doc/development/service_ping/index.md2
-rw-r--r--doc/development/snowplow/implementation.md10
-rw-r--r--doc/development/snowplow/index.md11
-rw-r--r--doc/development/snowplow/schemas.md19
-rw-r--r--doc/development/testing_guide/end_to_end/rspec_metadata_tests.md2
-rw-r--r--doc/development/work_items.md16
-rw-r--r--doc/install/migrate/compare_sm_to_saas.md4
-rw-r--r--doc/install/requirements.md2
-rw-r--r--doc/integration/jenkins_deprecated.md13
-rw-r--r--doc/integration/vault.md10
-rw-r--r--doc/operations/incident_management/incident_timeline_events.md4
-rw-r--r--doc/subscriptions/gitlab_com/index.md2
-rw-r--r--doc/subscriptions/gitlab_dedicated/index.md2
-rw-r--r--doc/subscriptions/index.md4
-rw-r--r--doc/subscriptions/self_managed/index.md2
-rw-r--r--doc/user/admin_area/geo_nodes.md11
-rw-r--r--doc/user/admin_area/license.md2
-rw-r--r--doc/user/application_security/api_fuzzing/index.md33
-rw-r--r--doc/user/feature_highlight.md11
-rw-r--r--doc/user/infrastructure/clusters/manage/management_project_applications/vault.md12
-rw-r--r--doc/user/project/clusters/kubernetes_pod_logs.md12
-rw-r--r--doc/user/project/import/tfvc.md2
-rw-r--r--doc/user/project/pages/getting_started/pages_from_scratch.md2
-rw-r--r--doc/user/project/pages/index.md2
-rw-r--r--doc/user/usage_quotas.md2
-rw-r--r--lib/api/api.rb4
-rw-r--r--lib/api/deploy_tokens.rb58
-rw-r--r--lib/api/entities/freeze_period.rb8
-rw-r--r--lib/api/freeze_periods.rb45
-rw-r--r--lib/gitlab/content_security_policy/config_loader.rb2
-rw-r--r--locale/gitlab.pot27
-rw-r--r--rubocop/cop/gitlab/rspec/avoid_setup.rb2
-rwxr-xr-xscripts/build_assets_image66
-rw-r--r--scripts/rspec_helpers.sh3
-rwxr-xr-xscripts/trigger-build.rb15
-rw-r--r--scripts/utils.sh16
-rw-r--r--spec/fixtures/packages/rpm/payload.json3
-rw-r--r--spec/frontend/boards/stores/actions_spec.js18
-rw-r--r--spec/frontend/ml/experiment_tracking/components/__snapshots__/experiment_spec.js.snap223
-rw-r--r--spec/frontend/ml/experiment_tracking/components/experiment_spec.js44
-rw-r--r--spec/frontend/ml/experiment_tracking/components/incubation_alert_spec.js27
-rw-r--r--spec/frontend/work_items/components/work_item_assignees_spec.js4
-rw-r--r--spec/frontend/work_items/components/work_item_detail_spec.js4
-rw-r--r--spec/frontend/work_items/components/work_item_milestone_spec.js4
-rw-r--r--spec/helpers/markup_helper_spec.rb149
-rw-r--r--spec/helpers/projects/ml/experiments_helper_spec.rb49
-rw-r--r--spec/lib/gitlab/content_security_policy/config_loader_spec.rb12
-rw-r--r--spec/models/ml/candidate_metric_spec.rb13
-rw-r--r--spec/models/ml/candidate_spec.rb22
-rw-r--r--spec/requests/projects/ml/experiments_controller_spec.rb86
-rw-r--r--spec/scripts/trigger-build_spec.rb23
-rw-r--r--spec/services/markup/rendering_service_spec.rb163
-rw-r--r--spec/services/packages/rpm/repository_metadata/build_filelist_xml_service_spec.rb54
-rw-r--r--spec/services/packages/rpm/repository_metadata/build_other_xml_service_spec.rb24
-rw-r--r--spec/services/packages/rpm/repository_metadata/build_primary_xml_service_spec.rb20
-rw-r--r--spec/services/packages/rpm/repository_metadata/update_xml_service_spec.rb22
-rw-r--r--spec/tooling/rspec_flaky/flaky_example_spec.rb79
-rw-r--r--tooling/rspec_flaky/flaky_example.rb7
-rw-r--r--tooling/rspec_flaky/listener.rb2
150 files changed, 1673 insertions, 796 deletions
diff --git a/.gitlab/ci/build-images.gitlab-ci.yml b/.gitlab/ci/build-images.gitlab-ci.yml
index 3c7056a92c1..bb18ba12c4b 100644
--- a/.gitlab/ci/build-images.gitlab-ci.yml
+++ b/.gitlab/ci/build-images.gitlab-ci.yml
@@ -18,7 +18,7 @@ build-qa-image:
- ./scripts/build_qa_image
# This image is used by:
-# - The `CNG` pipelines (via the `review-build-cng` job): https://gitlab.com/gitlab-org/build/CNG/-/blob/cfc67136d711e1c8c409bf8e57427a644393da2f/.gitlab-ci.yml#L335
+# - The `CNG` downstream pipelines (we pass the image tag via the `review-build-cng` job): https://gitlab.com/gitlab-org/gitlab/-/blob/c34e0834b01cd45c1f69a01b5e38dd6bc505f903/.gitlab/ci/review-apps/main.gitlab-ci.yml#L69
# - The `omnibus-gitlab` pipelines (via the `e2e:package-and-test` job): https://gitlab.com/gitlab-org/omnibus-gitlab/-/blob/dfd1ad475868fc84e91ab7b5706aa03e46dc3a86/.gitlab-ci.yml#L130
build-assets-image:
extends:
@@ -27,7 +27,10 @@ build-assets-image:
stage: build-images
needs: ["compile-production-assets"]
script:
- # TODO: Change the image tag to be the MD5 of assets files and skip image building if the image exists
- # We'll also need to pass GITLAB_ASSETS_TAG to the trigerred omnibus-gitlab pipeline similarly to how we do it for trigerred CNG pipelines
- # https://gitlab.com/gitlab-org/gitlab/issues/208389
- run_timed_command "scripts/build_assets_image"
+ artifacts:
+ expire_in: 7 days
+ paths:
+ # The `cached-assets-hash.txt` file is used in `review-build-cng-env` (`.gitlab/ci/review-apps/main.gitlab-ci.yml`)
+ # to pass the assets image tag to the CNG downstream pipeline.
+ - cached-assets-hash.txt
diff --git a/.gitlab/ci/frontend.gitlab-ci.yml b/.gitlab/ci/frontend.gitlab-ci.yml
index 085c0aa890d..fdc53ac6218 100644
--- a/.gitlab/ci/frontend.gitlab-ci.yml
+++ b/.gitlab/ci/frontend.gitlab-ci.yml
@@ -23,6 +23,7 @@
gitlab_assets_archive_doesnt_exist || run_timed_command "download_and_extract_gitlab_assets"
fi
- assets_compile_script
+ - echo -n "${GITLAB_ASSETS_HASH}" > "cached-assets-hash.txt"
compile-production-assets:
extends:
@@ -38,6 +39,7 @@ compile-production-assets:
# These assets are used in multiple locations:
# - in `build-assets-image` job to create assets image for packaging systems
# - GitLab UI for integration tests: https://gitlab.com/gitlab-org/gitlab-ui/-/blob/e88493b3c855aea30bf60baee692a64606b0eb1e/.storybook/preview-head.pug#L1
+ - cached-assets-hash.txt
- public/assets/
- "${WEBPACK_COMPILE_LOG_PATH}"
when: always
@@ -68,9 +70,6 @@ update-assets-compile-production-cache:
- .assets-compile-cache-push
- .shared:rules:update-cache
stage: prepare
- script:
- - !reference [compile-production-assets, script]
- - echo -n "${GITLAB_ASSETS_HASH}" > "cached-assets-hash.txt"
artifacts: {} # This job's purpose is only to update the cache.
update-assets-compile-test-cache:
diff --git a/.gitlab/ci/package-and-test/main.gitlab-ci.yml b/.gitlab/ci/package-and-test/main.gitlab-ci.yml
index 50b0b3531c7..64408838472 100644
--- a/.gitlab/ci/package-and-test/main.gitlab-ci.yml
+++ b/.gitlab/ci/package-and-test/main.gitlab-ci.yml
@@ -4,6 +4,7 @@ default:
interruptible: true
include:
+ - local: .gitlab/ci/global.gitlab-ci.yml
- local: .gitlab/ci/package-and-test/rules.gitlab-ci.yml
- local: .gitlab/ci/package-and-test/variables.gitlab-ci.yml
- project: gitlab-org/quality/pipeline-common
@@ -38,23 +39,6 @@ stages:
extends:
- .gitlab-qa-install
-.omnibus-env:
- variables:
- BUILD_ENV: build.env
- script:
- - |
- SECURITY_SOURCES=$([[ ! "$CI_PROJECT_NAMESPACE" =~ ^gitlab-org\/security ]] || echo "true")
- echo "SECURITY_SOURCES=${SECURITY_SOURCES:-false}" > $BUILD_ENV
- echo "OMNIBUS_GITLAB_CACHE_UPDATE=${OMNIBUS_GITLAB_CACHE_UPDATE:-false}" >> $BUILD_ENV
- for version_file in *_VERSION; do echo "$version_file=$(cat $version_file)" >> $BUILD_ENV; done
- echo "OMNIBUS_GITLAB_RUBY3_BUILD=${OMNIBUS_GITLAB_RUBY3_BUILD:-false}" >> $BUILD_ENV
- echo "OMNIBUS_GITLAB_CACHE_EDITION=${OMNIBUS_GITLAB_CACHE_EDITION:-GITLAB}" >> $BUILD_ENV
- echo "Built environment file for omnibus build:"
- cat $BUILD_ENV
- artifacts:
- reports:
- dotenv: $BUILD_ENV
-
.update-script:
script:
- export QA_COMMAND="bundle exec gitlab-qa Test::Omnibus::UpdateFromPrevious $RELEASE $GITLAB_VERSION $UPDATE_TYPE -- $QA_RSPEC_TAGS $RSPEC_REPORT_OPTS"
@@ -108,9 +92,29 @@ dont-interrupt-me:
trigger-omnibus-env:
extends:
- - .omnibus-env
+ - .default-utils-before_script
- .rules:omnibus-build
stage: .pre
+ needs:
+ # We need this job because we need its `cached-assets-hash.txt` artifact, so that we can pass the assets image tag to the downstream omnibus-gitlab pipeline.
+ - pipeline: $PARENT_PIPELINE_ID
+ job: build-assets-image
+ variables:
+ BUILD_ENV: build.env
+ script:
+ - |
+ SECURITY_SOURCES=$([[ ! "$CI_PROJECT_NAMESPACE" =~ ^gitlab-org\/security ]] || echo "true")
+ echo "SECURITY_SOURCES=${SECURITY_SOURCES:-false}" > $BUILD_ENV
+ echo "OMNIBUS_GITLAB_CACHE_UPDATE=${OMNIBUS_GITLAB_CACHE_UPDATE:-false}" >> $BUILD_ENV
+ for version_file in *_VERSION; do echo "$version_file=$(cat $version_file)" >> $BUILD_ENV; done
+ echo "OMNIBUS_GITLAB_RUBY3_BUILD=${OMNIBUS_GITLAB_RUBY3_BUILD:-false}" >> $BUILD_ENV
+ echo "OMNIBUS_GITLAB_CACHE_EDITION=${OMNIBUS_GITLAB_CACHE_EDITION:-GITLAB}" >> $BUILD_ENV
+ echo "GITLAB_ASSETS_TAG=$(assets_image_tag)" >> $BUILD_ENV
+ echo "Built environment file for omnibus build:"
+ cat $BUILD_ENV
+ artifacts:
+ reports:
+ dotenv: $BUILD_ENV
trigger-omnibus:
extends: .rules:omnibus-build
@@ -128,6 +132,7 @@ trigger-omnibus:
GITLAB_SHELL_VERSION: $GITLAB_SHELL_VERSION
GITLAB_WORKHORSE_VERSION: $GITLAB_WORKHORSE_VERSION
GITLAB_VERSION: $CI_COMMIT_SHA
+ GITLAB_ASSETS_TAG: $GITLAB_ASSETS_TAG
IMAGE_TAG: $CI_COMMIT_SHA
TOP_UPSTREAM_SOURCE_PROJECT: $CI_PROJECT_PATH
SECURITY_SOURCES: $SECURITY_SOURCES
diff --git a/.gitlab/ci/qa.gitlab-ci.yml b/.gitlab/ci/qa.gitlab-ci.yml
index bd587cb4418..b365827b1c3 100644
--- a/.gitlab/ci/qa.gitlab-ci.yml
+++ b/.gitlab/ci/qa.gitlab-ci.yml
@@ -75,6 +75,8 @@ e2e:package-and-test:
- build-qa-image
- e2e-test-pipeline-generate
variables:
+ # This is needed by `trigger-omnibus-env` (`.gitlab/ci/package-and-test/main.gitlab-ci.yml`).
+ PARENT_PIPELINE_ID: $CI_PIPELINE_ID
SKIP_MESSAGE: Skipping package-and-test due to mr containing only quarantine changes!
RELEASE: "${REGISTRY_HOST}/${REGISTRY_GROUP}/build/omnibus-gitlab-mirror/gitlab-ee:${CI_COMMIT_SHA}"
GITLAB_QA_IMAGE: "${CI_REGISTRY_IMAGE}/gitlab-ee-qa:${CI_COMMIT_SHA}"
diff --git a/.gitlab/ci/review-apps/main.gitlab-ci.yml b/.gitlab/ci/review-apps/main.gitlab-ci.yml
index 1f801e0d803..01725d04c7b 100644
--- a/.gitlab/ci/review-apps/main.gitlab-ci.yml
+++ b/.gitlab/ci/review-apps/main.gitlab-ci.yml
@@ -34,7 +34,10 @@ review-build-cng-env:
- .review:rules:review-build-cng
image: ${GITLAB_DEPENDENCY_PROXY_ADDRESS}ruby:3.0-alpine3.13
stage: prepare
- needs: []
+ needs:
+ # We need this job because we need its `cached-assets-hash.txt` artifact, so that we can pass the assets image tag to the downstream CNG pipeline.
+ - pipeline: $PARENT_PIPELINE_ID
+ job: build-assets-image
before_script:
- source ./scripts/utils.sh
- install_gitlab_gem
diff --git a/.gitlab/ci/review.gitlab-ci.yml b/.gitlab/ci/review.gitlab-ci.yml
index aefa96da159..199f564464d 100644
--- a/.gitlab/ci/review.gitlab-ci.yml
+++ b/.gitlab/ci/review.gitlab-ci.yml
@@ -33,6 +33,8 @@ start-review-app-pipeline:
# They need to be explicitly passed on to the child pipeline.
# https://docs.gitlab.com/ee/ci/pipelines/multi_project_pipelines.html#pass-cicd-variables-to-a-downstream-pipeline-by-using-the-variables-keyword
variables:
+ # This is needed by `review-build-cng-env` (`.gitlab/ci/review-apps/main.gitlab-ci.yml`).
+ PARENT_PIPELINE_ID: $CI_PIPELINE_ID
SCHEDULE_TYPE: $SCHEDULE_TYPE
DAST_RUN: $DAST_RUN
SKIP_MESSAGE: Skipping review-app due to mr containing only quarantine changes!
diff --git a/Dockerfile.assets b/Dockerfile.assets
index 403d16cc4ab..ba69a614e88 100644
--- a/Dockerfile.assets
+++ b/Dockerfile.assets
@@ -1,4 +1,4 @@
# Simple container to store assets for later use
FROM scratch
-ADD public/assets /assets/
+COPY public/assets /assets/
CMD /bin/true
diff --git a/app/assets/javascripts/boards/graphql.js b/app/assets/javascripts/boards/graphql.js
deleted file mode 100644
index d066a5d002e..00000000000
--- a/app/assets/javascripts/boards/graphql.js
+++ /dev/null
@@ -1,15 +0,0 @@
-import { defaultDataIdFromObject } from '@apollo/client/core';
-import createDefaultClient from '~/lib/graphql';
-
-export const gqlClient = createDefaultClient(
- {},
- {
- cacheConfig: {
- dataIdFromObject: (object) => {
- // eslint-disable-next-line no-underscore-dangle
- return object.__typename === 'BoardList' ? object.iid : defaultDataIdFromObject(object);
- },
- },
- batchMax: 2,
- },
-);
diff --git a/app/assets/javascripts/boards/index.js b/app/assets/javascripts/boards/index.js
index a7003edba47..49be7c06cc2 100644
--- a/app/assets/javascripts/boards/index.js
+++ b/app/assets/javascripts/boards/index.js
@@ -12,14 +12,14 @@ import {
convertObjectPropsToCamelCase,
} from '~/lib/utils/common_utils';
import { queryToObject } from '~/lib/utils/url_utility';
+import { defaultClient } from '~/graphql_shared/issuable_client';
import { fullBoardId } from './boards_util';
-import { gqlClient } from './graphql';
Vue.use(VueApollo);
Vue.use(PortalVue);
const apolloProvider = new VueApollo({
- defaultClient: gqlClient,
+ defaultClient,
});
function mountBoardApp(el) {
diff --git a/app/assets/javascripts/boards/stores/actions.js b/app/assets/javascripts/boards/stores/actions.js
index c2e346da606..e5437690fd4 100644
--- a/app/assets/javascripts/boards/stores/actions.js
+++ b/app/assets/javascripts/boards/stores/actions.js
@@ -34,11 +34,11 @@ import issueMoveListMutation from 'ee_else_ce/boards/graphql/issue_move_list.mut
import totalCountAndWeightQuery from 'ee_else_ce/boards/graphql/board_lists_deferred.query.graphql';
import { fetchPolicies } from '~/lib/graphql';
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
+import { defaultClient as gqlClient } from '~/graphql_shared/issuable_client';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import { queryToObject } from '~/lib/utils/url_utility';
import { s__ } from '~/locale';
import eventHub from '../eventhub';
-import { gqlClient } from '../graphql';
import projectBoardQuery from '../graphql/project_board.query.graphql';
import groupBoardQuery from '../graphql/group_board.query.graphql';
import boardLabelsQuery from '../graphql/board_labels.query.graphql';
@@ -149,6 +149,9 @@ export default {
query: listsQuery[issuableType].query,
variables,
...(resetLists ? { fetchPolicy: fetchPolicies.NO_CACHE } : {}),
+ context: {
+ isSingleRequest: true,
+ },
})
.then(({ data }) => {
const { lists, hideBacklogList } = data[boardType].board;
diff --git a/app/assets/javascripts/graphql_shared/issuable_client.js b/app/assets/javascripts/graphql_shared/issuable_client.js
index 3b737dfff33..04a6e555bea 100644
--- a/app/assets/javascripts/graphql_shared/issuable_client.js
+++ b/app/assets/javascripts/graphql_shared/issuable_client.js
@@ -1,14 +1,21 @@
import produce from 'immer';
import VueApollo from 'vue-apollo';
+import { defaultDataIdFromObject } from '@apollo/client/core';
import { concatPagination } from '@apollo/client/utilities';
import getIssueStateQuery from '~/issues/show/queries/get_issue_state.query.graphql';
import createDefaultClient from '~/lib/graphql';
import typeDefs from '~/work_items/graphql/typedefs.graphql';
import { WIDGET_TYPE_MILESTONE } from '~/work_items/constants';
-export const temporaryConfig = {
+export const config = {
typeDefs,
cacheConfig: {
+ // included temporarily until Vuex is removed from boards app
+ dataIdFromObject: (object) => {
+ // eslint-disable-next-line no-underscore-dangle
+ return object.__typename === 'BoardList' ? object.iid : defaultDataIdFromObject(object);
+ },
+
possibleTypes: {
LocalWorkItemWidget: ['LocalWorkItemMilestone'],
},
@@ -78,7 +85,7 @@ export const resolvers = {
},
};
-export const defaultClient = createDefaultClient(resolvers, temporaryConfig);
+export const defaultClient = createDefaultClient(resolvers, config);
export const apolloProvider = new VueApollo({
defaultClient,
diff --git a/app/assets/javascripts/ml/experiment_tracking/components/experiment.vue b/app/assets/javascripts/ml/experiment_tracking/components/experiment.vue
new file mode 100644
index 00000000000..73cdfbc44b0
--- /dev/null
+++ b/app/assets/javascripts/ml/experiment_tracking/components/experiment.vue
@@ -0,0 +1,36 @@
+<script>
+import { GlTable } from '@gitlab/ui';
+import IncubationAlert from './incubation_alert.vue';
+
+export default {
+ name: 'ShowMlExperiment',
+ components: {
+ GlTable,
+ IncubationAlert,
+ },
+ inject: ['candidates', 'metricNames', 'paramNames'],
+ computed: {
+ fields() {
+ return [...this.paramNames, ...this.metricNames];
+ },
+ },
+};
+</script>
+
+<template>
+ <div>
+ <incubation-alert />
+
+ <h3>
+ {{ __('Experiment Candidates') }}
+ </h3>
+
+ <gl-table
+ :fields="fields"
+ :items="candidates"
+ :empty-text="__('This Experiment has no logged Candidates')"
+ show-empty
+ class="gl-mt-0!"
+ />
+ </div>
+</template>
diff --git a/app/assets/javascripts/ml/experiment_tracking/components/incubation_alert.vue b/app/assets/javascripts/ml/experiment_tracking/components/incubation_alert.vue
new file mode 100644
index 00000000000..51c1e935677
--- /dev/null
+++ b/app/assets/javascripts/ml/experiment_tracking/components/incubation_alert.vue
@@ -0,0 +1,48 @@
+<script>
+import { GlAlert, GlLink } from '@gitlab/ui';
+import { __ } from '~/locale';
+
+export default {
+ i18n: {
+ titleLabel: __('Machine Learning Experiment Tracking is in Incubating Phase'),
+ contentLabel: __(
+ 'GitLab incubates features to explore new use cases. These features are updated regularly, and support is limited',
+ ),
+ learnMoreLabel: __('Learn More'),
+ feedbackLabel: __('Feedback and Updates'),
+ },
+ name: 'MlopsIncubationAlert',
+ components: { GlAlert, GlLink },
+ data() {
+ return {
+ isAlertDismissed: false,
+ };
+ },
+ computed: {
+ shouldShowAlert() {
+ return !this.isAlertDismissed;
+ },
+ },
+ methods: {
+ dismissAlert() {
+ this.isAlertDismissed = true;
+ },
+ },
+};
+</script>
+
+<template>
+ <gl-alert
+ v-if="shouldShowAlert"
+ :title="$options.i18n.titleLabel"
+ variant="warning"
+ :primary-button-text="$options.i18n.feedbackLabel"
+ primary-button-link="https://gitlab.com/groups/gitlab-org/-/epics/8560"
+ @dismiss="dismissAlert"
+ >
+ {{ $options.i18n.contentLabel }}
+ <gl-link href="https://about.gitlab.com/handbook/engineering/incubation/" target="_blank">{{
+ $options.i18n.learnMoreLabel
+ }}</gl-link>
+ </gl-alert>
+</template>
diff --git a/app/assets/javascripts/pages/projects/ml/experiments/show/index.js b/app/assets/javascripts/pages/projects/ml/experiments/show/index.js
new file mode 100644
index 00000000000..0a9d9f4c987
--- /dev/null
+++ b/app/assets/javascripts/pages/projects/ml/experiments/show/index.js
@@ -0,0 +1,31 @@
+import Vue from 'vue';
+import ShowExperiment from '~/ml/experiment_tracking/components/experiment.vue';
+
+const initShowExperiment = () => {
+ const element = document.querySelector('#js-show-ml-experiment');
+ if (!element) {
+ return;
+ }
+
+ const container = document.createElement('div');
+ element.appendChild(container);
+
+ const candidates = JSON.parse(element.dataset.candidates);
+ const metricNames = JSON.parse(element.dataset.metrics);
+ const paramNames = JSON.parse(element.dataset.params);
+
+ // eslint-disable-next-line no-new
+ new Vue({
+ el: container,
+ provide: {
+ candidates,
+ metricNames,
+ paramNames,
+ },
+ render(h) {
+ return h(ShowExperiment);
+ },
+ });
+};
+
+initShowExperiment();
diff --git a/app/assets/javascripts/pipelines/components/pipeline_mini_graph/pipeline_stage.vue b/app/assets/javascripts/pipelines/components/pipeline_mini_graph/pipeline_stage.vue
index 10a48c83716..ba150919e58 100644
--- a/app/assets/javascripts/pipelines/components/pipeline_mini_graph/pipeline_stage.vue
+++ b/app/assets/javascripts/pipelines/components/pipeline_mini_graph/pipeline_stage.vue
@@ -137,25 +137,19 @@ export default {
:is-active="isDropdownOpen"
:size="24"
:status="stage.status"
- class="gl-align-items-center gl-border gl-display-inline-flex gl-z-index-1"
+ class="gl-display-inline-flex gl-align-items-center gl-border gl-z-index-1"
/>
</template>
- <div
- v-if="isLoading"
- class="gl-display-flex gl-justify-content-center gl-p-2"
- data-testid="pipeline-stage-loading-state"
- >
+ <div v-if="isLoading" class="gl--flex-center gl-p-2" data-testid="pipeline-stage-loading-state">
<gl-loading-icon size="sm" class="gl-mr-3" />
- <p class="gl-mb-0">{{ $options.i18n.loadingText }}</p>
+ <p class="gl-line-height-normal gl-mb-0">{{ $options.i18n.loadingText }}</p>
</div>
<ul
v-else
class="js-builds-dropdown-list scrollable-menu"
data-testid="mini-pipeline-graph-dropdown-menu-list"
>
- <div
- class="gl-align-items-center gl-border-b gl-display-flex gl-font-weight-bold gl-justify-content-center gl-pb-3"
- >
+ <div class="gl--flex-center gl-border-b gl-font-weight-bold gl-pb-3">
<span class="gl-mr-1">{{ $options.i18n.stage }}</span>
<span data-testid="pipeline-stage-dropdown-menu-title">{{ stageName }}</span>
</div>
diff --git a/app/assets/stylesheets/_page_specific_files.scss b/app/assets/stylesheets/_page_specific_files.scss
index 65d27aad4a2..6878e9a10d7 100644
--- a/app/assets/stylesheets/_page_specific_files.scss
+++ b/app/assets/stylesheets/_page_specific_files.scss
@@ -8,6 +8,7 @@
@import './pages/issues';
@import './pages/labels';
@import './pages/login';
+@import './pages/ml_experiment_tracking';
@import './pages/merge_requests';
@import './pages/monitor';
@import './pages/note_form';
diff --git a/app/assets/stylesheets/pages/ml_experiment_tracking.scss b/app/assets/stylesheets/pages/ml_experiment_tracking.scss
new file mode 100644
index 00000000000..2dff51cff92
--- /dev/null
+++ b/app/assets/stylesheets/pages/ml_experiment_tracking.scss
@@ -0,0 +1,16 @@
+@import '../page_bundles/mixins_and_variables_and_functions';
+
+.ml-experiment-row {
+ .title {
+ margin-bottom: $gl-spacing-scale-1;
+ font-weight: $gl-font-weight-bold;
+ }
+
+ .ml-experiment-info {
+ color: $gl-text-color-secondary;
+ }
+
+ a {
+ color: $gl-text-color;
+ }
+}
diff --git a/app/assets/stylesheets/pages/search.scss b/app/assets/stylesheets/pages/search.scss
index a8027d2a5f5..1bca04e5eb1 100644
--- a/app/assets/stylesheets/pages/search.scss
+++ b/app/assets/stylesheets/pages/search.scss
@@ -52,13 +52,6 @@ input[type='checkbox']:hover {
.global-search-container {
flex-grow: 1;
}
-
- @include media-breakpoint-down(lg) {
- .title-container {
- flex: 0;
- overflow: hidden;
- }
- }
}
}
diff --git a/app/controllers/projects/ml/experiments_controller.rb b/app/controllers/projects/ml/experiments_controller.rb
new file mode 100644
index 00000000000..d19cc93aedd
--- /dev/null
+++ b/app/controllers/projects/ml/experiments_controller.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+module Projects
+ module Ml
+ class ExperimentsController < ::Projects::ApplicationController
+ include Projects::Ml::ExperimentsHelper
+ before_action :check_feature_flag
+
+ feature_category :mlops
+
+ MAX_PER_PAGE = 20
+
+ def index
+ @experiments = ::Ml::Experiment.by_project_id(@project.id).page(params[:page]).per(MAX_PER_PAGE)
+ end
+
+ def show
+ @experiment = ::Ml::Experiment.by_project_id_and_iid(@project.id, params[:id])
+
+ return redirect_to project_ml_experiments_path(@project) unless @experiment.present?
+
+ @candidates = @experiment.candidates&.including_metrics_and_params
+ end
+
+ private
+
+ def check_feature_flag
+ render_404 unless Feature.enabled?(:ml_experiment_tracking)
+ end
+ end
+ end
+end
diff --git a/app/helpers/markup_helper.rb b/app/helpers/markup_helper.rb
index 866399f3021..9baea43b77d 100644
--- a/app/helpers/markup_helper.rb
+++ b/app/helpers/markup_helper.rb
@@ -6,12 +6,6 @@ module MarkupHelper
include ActionView::Helpers::TextHelper
include ActionView::Context
- # Let's increase the render timeout
- # For a smaller one, a test that renders the blob content statically fails
- # We can consider removing this custom timeout when markup_rendering_timeout FF is removed:
- # https://gitlab.com/gitlab-org/gitlab/-/issues/365358
- RENDER_TIMEOUT = 5.seconds
-
# Use this in places where you would normally use link_to(gfm(...), ...).
def link_to_markdown(body, url, html_options = {})
return '' if body.blank?
@@ -97,8 +91,9 @@ module MarkupHelper
context[:project] ||= @project
context[:group] ||= @group
- html = markdown_unsafe(text, context)
- prepare_for_rendering(html, context)
+ html = Markup::RenderingService.new(text, context: context, postprocess_context: postprocess_context).execute
+
+ Hamlit::RailsHelpers.preserve(html)
end
def markdown_field(object, field, context = {})
@@ -114,8 +109,13 @@ module MarkupHelper
def markup(file_name, text, context = {})
context[:project] ||= @project
context[:text_source] ||= :blob
- html = context.delete(:rendered) || markup_unsafe(file_name, text, context)
- prepare_for_rendering(html, context)
+ prepare_asciidoc_context(file_name, context)
+
+ html = Markup::RenderingService
+ .new(text, file_name: file_name, context: context, postprocess_context: postprocess_context)
+ .execute
+
+ Hamlit::RailsHelpers.preserve(html)
end
def render_wiki_content(wiki_page, context = {})
@@ -123,35 +123,13 @@ module MarkupHelper
return '' unless text.present?
context = render_wiki_content_context(wiki_page.wiki, wiki_page, context)
- html = markup_unsafe(wiki_page.path, text, context)
-
- prepare_for_rendering(html, context)
- end
-
- def markup_unsafe(file_name, text, context = {})
- return '' unless text.present?
+ prepare_asciidoc_context(wiki_page.path, context)
- markup = proc do
- if Gitlab::MarkupHelper.gitlab_markdown?(file_name)
- markdown_unsafe(text, context)
- elsif Gitlab::MarkupHelper.asciidoc?(file_name)
- asciidoc_unsafe(text, context)
- elsif Gitlab::MarkupHelper.plain?(file_name)
- plain_unsafe(text)
- else
- other_markup_unsafe(file_name, text, context)
- end
- end
-
- if Feature.enabled?(:markup_rendering_timeout, @project)
- Gitlab::RenderTimeout.timeout(foreground: RENDER_TIMEOUT, &markup)
- else
- markup.call
- end
- rescue StandardError => e
- Gitlab::ErrorTracking.track_exception(e, project_id: @project&.id, file_name: file_name)
+ html = Markup::RenderingService
+ .new(text, file_name: wiki_page.path, context: context, postprocess_context: postprocess_context)
+ .execute
- simple_format(text)
+ Hamlit::RailsHelpers.preserve(html)
end
# Returns the text necessary to reference `entity` across projects
@@ -214,29 +192,6 @@ module MarkupHelper
end
end
- def markdown_unsafe(text, context = {})
- Banzai.render(text, context)
- end
-
- def asciidoc_unsafe(text, context = {})
- context.reverse_merge!(
- commit: @commit,
- ref: @ref,
- requested_path: @path
- )
- Gitlab::Asciidoc.render(text, context)
- end
-
- def plain_unsafe(text)
- content_tag :pre, class: 'plain-readme' do
- text
- end
- end
-
- def other_markup_unsafe(file_name, text, context = {})
- Gitlab::OtherMarkup.render(file_name, text, context)
- end
-
def render_markdown_field(object, field, context = {})
post_process = context.delete(:post_process)
post_process = true if post_process.nil?
@@ -257,7 +212,15 @@ module MarkupHelper
def prepare_for_rendering(html, context = {})
return '' unless html.present?
- context.reverse_merge!(
+ context.reverse_merge!(postprocess_context)
+
+ html = Banzai.post_process(html, context)
+
+ Hamlit::RailsHelpers.preserve(html)
+ end
+
+ def postprocess_context
+ {
current_user: (current_user if defined?(current_user)),
# RepositoryLinkFilter and UploadLinkFilter
@@ -265,11 +228,13 @@ module MarkupHelper
wiki: @wiki,
ref: @ref,
requested_path: @path
- )
+ }
+ end
- html = Banzai.post_process(html, context)
+ def prepare_asciidoc_context(file_name, context)
+ return unless Gitlab::MarkupHelper.asciidoc?(file_name)
- Hamlit::RailsHelpers.preserve(html)
+ context.reverse_merge!(commit: @commit, ref: @ref, requested_path: @path)
end
extend self
diff --git a/app/helpers/projects/ml/experiments_helper.rb b/app/helpers/projects/ml/experiments_helper.rb
new file mode 100644
index 00000000000..29bd879859e
--- /dev/null
+++ b/app/helpers/projects/ml/experiments_helper.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+module Projects
+ module Ml
+ module ExperimentsHelper
+ require 'json'
+ include ActionView::Helpers::NumberHelper
+
+ def candidates_table_items(candidates)
+ items = candidates.map do |candidate|
+ {
+ **candidate.params.to_h { |p| [p.name, p.value] },
+ **candidate.latest_metrics.to_h { |m| [m.name, number_with_precision(m.value, precision: 4)] }
+ }
+ end
+
+ Gitlab::Json.generate(items)
+ end
+
+ def unique_logged_names(candidates, &selector)
+ Gitlab::Json.generate(candidates.flat_map(&selector).map(&:name).uniq)
+ end
+ end
+ end
+end
diff --git a/app/models/ml/candidate.rb b/app/models/ml/candidate.rb
index 62e2e75db2a..9b00aefa5f2 100644
--- a/app/models/ml/candidate.rb
+++ b/app/models/ml/candidate.rb
@@ -11,9 +11,12 @@ module Ml
belongs_to :user
has_many :metrics, class_name: 'Ml::CandidateMetric'
has_many :params, class_name: 'Ml::CandidateParam'
+ has_many :latest_metrics, -> { latest }, class_name: 'Ml::CandidateMetric', inverse_of: :candidate
default_value_for(:iid) { SecureRandom.uuid }
+ scope :including_metrics_and_params, -> { includes(:latest_metrics, :params) }
+
def artifact_root
"/ml_candidate_#{iid}/-/"
end
diff --git a/app/models/ml/candidate_metric.rb b/app/models/ml/candidate_metric.rb
index e03a8b83ee6..8e13a46d6b4 100644
--- a/app/models/ml/candidate_metric.rb
+++ b/app/models/ml/candidate_metric.rb
@@ -6,5 +6,7 @@ module Ml
validates :name, length: { maximum: 250 }, presence: true
belongs_to :candidate, class_name: 'Ml::Candidate'
+
+ scope :latest, -> { select('DISTINCT ON (candidate_id, name) *').order('candidate_id, name, id DESC') }
end
end
diff --git a/app/models/ml/experiment.rb b/app/models/ml/experiment.rb
index a32099e8a0c..05b238b960d 100644
--- a/app/models/ml/experiment.rb
+++ b/app/models/ml/experiment.rb
@@ -23,7 +23,7 @@ module Ml
end
def by_project_id(project_id)
- where(project_id: project_id)
+ where(project_id: project_id).order(id: :desc)
end
end
end
diff --git a/app/services/markup/rendering_service.rb b/app/services/markup/rendering_service.rb
new file mode 100644
index 00000000000..0142d600522
--- /dev/null
+++ b/app/services/markup/rendering_service.rb
@@ -0,0 +1,79 @@
+# frozen_string_literal: true
+
+module Markup
+ class RenderingService
+ include ActionView::Helpers::TextHelper
+
+ # Let's increase the render timeout
+ # For a smaller one, a test that renders the blob content statically fails
+ # We can consider removing this custom timeout when markup_rendering_timeout FF is removed:
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/365358
+ RENDER_TIMEOUT = 5.seconds
+
+ def initialize(text, file_name: nil, context: {}, postprocess_context: {})
+ @text = text
+ @file_name = file_name
+ @context = context
+ @postprocess_context = postprocess_context
+ end
+
+ def execute
+ return '' unless text.present?
+ return context.delete(:rendered) if context.has_key?(:rendered)
+
+ html = file_name ? markup_unsafe : markdown_unsafe
+
+ return '' unless html.present?
+
+ postprocess_context ? postprocess(html) : html
+ end
+
+ private
+
+ def markup_unsafe
+ markup = proc do
+ if Gitlab::MarkupHelper.gitlab_markdown?(file_name)
+ markdown_unsafe
+ elsif Gitlab::MarkupHelper.asciidoc?(file_name)
+ asciidoc_unsafe
+ elsif Gitlab::MarkupHelper.plain?(file_name)
+ plain_unsafe
+ else
+ other_markup_unsafe
+ end
+ end
+
+ if Feature.enabled?(:markup_rendering_timeout, context[:project])
+ Gitlab::RenderTimeout.timeout(foreground: RENDER_TIMEOUT, &markup)
+ else
+ markup.call
+ end
+ rescue StandardError => e
+ Gitlab::ErrorTracking.track_exception(e, project_id: context[:project]&.id, file_name: file_name)
+
+ simple_format(text)
+ end
+
+ def markdown_unsafe
+ Banzai.render(text, context)
+ end
+
+ def asciidoc_unsafe
+ Gitlab::Asciidoc.render(text, context)
+ end
+
+ def plain_unsafe
+ "<pre class=\"plain-readme\">#{text}</pre>"
+ end
+
+ def other_markup_unsafe
+ Gitlab::OtherMarkup.render(file_name, text, context)
+ end
+
+ def postprocess(html)
+ Banzai.post_process(html, context.reverse_merge(postprocess_context))
+ end
+
+ attr_reader :text, :file_name, :context, :postprocess_context
+ end
+end
diff --git a/app/services/packages/rpm/parse_package_service.rb b/app/services/packages/rpm/parse_package_service.rb
index 689a161a81a..18b916a9d8b 100644
--- a/app/services/packages/rpm/parse_package_service.rb
+++ b/app/services/packages/rpm/parse_package_service.rb
@@ -25,7 +25,8 @@ module Packages
epoch: package_tags[:epoch] || '0',
changelogs: build_changelogs,
requirements: build_requirements,
- provides: build_provides
+ provides: build_provides,
+ directories: package_tags[:dirnames]
}.merge(extract_static_attributes)
end
diff --git a/app/services/packages/rpm/repository_metadata/build_filelist_xml_service.rb b/app/services/packages/rpm/repository_metadata/build_filelist_xml_service.rb
new file mode 100644
index 00000000000..47cbba76fa4
--- /dev/null
+++ b/app/services/packages/rpm/repository_metadata/build_filelist_xml_service.rb
@@ -0,0 +1,39 @@
+# frozen_string_literal: true
+module Packages
+ module Rpm
+ module RepositoryMetadata
+ class BuildFilelistXmlService < BuildXmlBaseService
+ ROOT_TAG = 'filelists'
+ ROOT_ATTRIBUTES = {
+ xmlns: 'http://linux.duke.edu/metadata/filelists',
+ packages: '0'
+ }.freeze
+
+ def execute
+ super do |xml|
+ xml.package(pkgid: data[:pkgid], name: data[:name], arch: data[:arch]) do
+ xml.version epoch: data[:epoch], ver: data[:version], rel: data[:release]
+ build_file_nodes(xml)
+ end
+ end
+ end
+
+ private
+
+ def build_file_nodes(xml)
+ data[:files].each do |path|
+ attributes = dir?(path) ? { type: 'dir' } : {}
+
+ xml.file path, **attributes
+ end
+ end
+
+ def dir?(path)
+ # Add trailing slash to path to check
+ # if it exists in directories list
+ data[:directories].include? File.join(path, '')
+ end
+ end
+ end
+ end
+end
diff --git a/app/services/packages/rpm/repository_metadata/build_other_xml_service.rb b/app/services/packages/rpm/repository_metadata/build_other_xml_service.rb
index 853bdf7da63..00e88f4f548 100644
--- a/app/services/packages/rpm/repository_metadata/build_other_xml_service.rb
+++ b/app/services/packages/rpm/repository_metadata/build_other_xml_service.rb
@@ -2,32 +2,24 @@
module Packages
module Rpm
module RepositoryMetadata
- class BuildOtherXmlService
+ class BuildOtherXmlService < BuildXmlBaseService
ROOT_TAG = 'otherdata'
ROOT_ATTRIBUTES = {
xmlns: 'http://linux.duke.edu/metadata/other',
packages: '0'
}.freeze
- def initialize(data)
- @data = data
- end
-
def execute
- builder = Nokogiri::XML::Builder.new do |xml|
+ super do |xml|
xml.package(pkgid: data[:pkgid], name: data[:name], arch: data[:arch]) do
xml.version epoch: data[:epoch], ver: data[:version], rel: data[:release]
build_changelog_nodes(xml)
end
end
-
- Nokogiri::XML(builder.to_xml).at('package')
end
private
- attr_reader :data
-
def build_changelog_nodes(xml)
data[:changelogs].each do |changelog|
xml.changelog changelog[:changelogtext], date: changelog[:changelogtime]
diff --git a/app/services/packages/rpm/repository_metadata/build_primary_xml_service.rb b/app/services/packages/rpm/repository_metadata/build_primary_xml_service.rb
index f7de4ac3eee..1044ab3997a 100644
--- a/app/services/packages/rpm/repository_metadata/build_primary_xml_service.rb
+++ b/app/services/packages/rpm/repository_metadata/build_primary_xml_service.rb
@@ -2,7 +2,7 @@
module Packages
module Rpm
module RepositoryMetadata
- class BuildPrimaryXmlService
+ class BuildPrimaryXmlService < BuildXmlBaseService
ROOT_TAG = 'metadata'
ROOT_ATTRIBUTES = {
xmlns: 'http://linux.duke.edu/metadata/common',
@@ -14,12 +14,8 @@ module Packages
BASE_ATTRIBUTES = %i[name arch summary description url packager].freeze
FORMAT_NODE_BASE_ATTRIBUTES = %i[license vendor group buildhost sourcerpm].freeze
- def initialize(data)
- @data = data
- end
-
def execute
- builder = Nokogiri::XML::Builder.new do |xml|
+ super do |xml|
xml.package(type: :rpm, 'xmlns:rpm': 'http://linux.duke.edu/metadata/rpm') do
build_base_attributes(xml)
xml.version epoch: data[:epoch], ver: data[:version], rel: data[:release]
@@ -30,14 +26,10 @@ module Packages
build_format_node(xml)
end
end
-
- Nokogiri::XML(builder.to_xml).at('package')
end
private
- attr_reader :data
-
def build_base_attributes(xml)
BASE_ATTRIBUTES.each do |attribute|
xml.method_missing(attribute, data[attribute]) if data[attribute].present?
diff --git a/app/services/packages/rpm/repository_metadata/build_repomd_xml_service.rb b/app/services/packages/rpm/repository_metadata/build_repomd_xml_service.rb
index 9fa7aac3202..cb80faa12c0 100644
--- a/app/services/packages/rpm/repository_metadata/build_repomd_xml_service.rb
+++ b/app/services/packages/rpm/repository_metadata/build_repomd_xml_service.rb
@@ -3,8 +3,6 @@ module Packages
module Rpm
module RepositoryMetadata
class BuildRepomdXmlService
- attr_reader :data
-
ROOT_ATTRIBUTES = {
xmlns: 'http://linux.duke.edu/metadata/repo',
'xmlns:rpm': 'http://linux.duke.edu/metadata/rpm'
@@ -26,12 +24,6 @@ module Packages
end
def execute
- build_repomd
- end
-
- private
-
- def build_repomd
Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |xml|
xml.repomd(ROOT_ATTRIBUTES) do
xml.revision Time.now.to_i
@@ -40,6 +32,10 @@ module Packages
end.to_xml
end
+ private
+
+ attr_reader :data
+
def build_data_info(xml)
data.each do |filename, info|
xml.data(type: filename) do
diff --git a/app/services/packages/rpm/repository_metadata/build_xml_base_service.rb b/app/services/packages/rpm/repository_metadata/build_xml_base_service.rb
new file mode 100644
index 00000000000..4dfb4087f1b
--- /dev/null
+++ b/app/services/packages/rpm/repository_metadata/build_xml_base_service.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+module Packages
+ module Rpm
+ module RepositoryMetadata
+ class BuildXmlBaseService
+ def initialize(data)
+ @data = data
+ end
+
+ def execute
+ builder = Nokogiri::XML::Builder.new { |xml| yield xml } # rubocop:disable Style/ExplicitBlockArgument
+
+ Nokogiri::XML(builder.to_xml).at('package')
+ end
+
+ private
+
+ attr_reader :data
+ end
+ end
+ end
+end
diff --git a/app/services/packages/rpm/repository_metadata/update_xml_service.rb b/app/services/packages/rpm/repository_metadata/update_xml_service.rb
index 3fe93b7a623..8fef425195f 100644
--- a/app/services/packages/rpm/repository_metadata/update_xml_service.rb
+++ b/app/services/packages/rpm/repository_metadata/update_xml_service.rb
@@ -5,7 +5,8 @@ module Packages
class UpdateXmlService
BUILDERS = {
other: ::Packages::Rpm::RepositoryMetadata::BuildOtherXmlService,
- primary: ::Packages::Rpm::RepositoryMetadata::BuildPrimaryXmlService
+ primary: ::Packages::Rpm::RepositoryMetadata::BuildPrimaryXmlService,
+ filelist: ::Packages::Rpm::RepositoryMetadata::BuildFilelistXmlService
}.freeze
def initialize(filename:, xml: nil, data: {})
diff --git a/app/views/projects/ml/experiments/_experiment.html.haml b/app/views/projects/ml/experiments/_experiment.html.haml
new file mode 100644
index 00000000000..42823f47469
--- /dev/null
+++ b/app/views/projects/ml/experiments/_experiment.html.haml
@@ -0,0 +1,3 @@
+%li.ml-experiment-row.py-3
+ = link_to project_ml_experiment_path(@project, experiment.iid), class: "title" do
+ = experiment.name
diff --git a/app/views/projects/ml/experiments/_experiment_list.html.haml b/app/views/projects/ml/experiments/_experiment_list.html.haml
new file mode 100644
index 00000000000..a25e814b2b5
--- /dev/null
+++ b/app/views/projects/ml/experiments/_experiment_list.html.haml
@@ -0,0 +1,7 @@
+- if experiments.blank?
+ .nothing-here-block= s_('MlExperimentsEmptyState|No Experiments to Show')
+- else
+ .ml-experiments-list-holder
+ %ul.content-list
+ = render partial: 'experiment', collection: experiments, as: :experiment
+ = paginate_collection @experiments
diff --git a/app/views/projects/ml/experiments/_incubation_banner.html.haml b/app/views/projects/ml/experiments/_incubation_banner.html.haml
new file mode 100644
index 00000000000..e34f3fd2d2f
--- /dev/null
+++ b/app/views/projects/ml/experiments/_incubation_banner.html.haml
@@ -0,0 +1,8 @@
+= render Pajamas::AlertComponent.new(variant: :warning,
+ title: _('Machine Learning Experiment Tracking is in Incubating Phase'),
+ alert_options: { class: 'gl-my-3' }) do |c|
+ = c.body do
+ = _('GitLab incubates features to explore new use cases. These features are updated regularly, and support is limited')
+ = link_to _('Learn more.'), 'https://about.gitlab.com/handbook/engineering/incubation/', target: "_blank"
+ = c.actions do
+ = link_to _('Feedback and Updates'), 'https://gitlab.com/groups/gitlab-org/-/epics/8560', target: "_blank"
diff --git a/app/views/projects/ml/experiments/index.html.haml b/app/views/projects/ml/experiments/index.html.haml
new file mode 100644
index 00000000000..a84cb15d940
--- /dev/null
+++ b/app/views/projects/ml/experiments/index.html.haml
@@ -0,0 +1,11 @@
+- breadcrumb_title _('ML Experiments')
+- page_title _('ML Experiments')
+
+.page-title-holder.d-flex.align-items-center
+ %h1.page-title.gl-font-size-h-display= _('Machine Learning Experiments')
+
+= render "incubation_banner"
+
+%div{ class: container_class }
+ .content-list.builds-content-list
+ = render "experiment_list", experiments: @experiments, project: @project
diff --git a/app/views/projects/ml/experiments/show.html.haml b/app/views/projects/ml/experiments/show.html.haml
new file mode 100644
index 00000000000..2c350439762
--- /dev/null
+++ b/app/views/projects/ml/experiments/show.html.haml
@@ -0,0 +1,14 @@
+- add_to_breadcrumbs _("Experiments"), project_ml_experiments_path(@project)
+- breadcrumb_title @experiment.name
+- page_title @experiment.name
+- items = candidates_table_items(@candidates)
+- metrics = unique_logged_names(@candidates, &:latest_metrics)
+- params = unique_logged_names(@candidates, &:params)
+
+.page-title-holder.d-flex.align-items-center
+ %h1.page-title.gl-font-size-h-display= @experiment.name
+
+#js-show-ml-experiment{ data: {
+ candidates: items,
+ metrics: metrics,
+ params: params } }
diff --git a/config/open_api.yml b/config/open_api.yml
index b4c3df13f1e..29b2b622aaf 100644
--- a/config/open_api.yml
+++ b/config/open_api.yml
@@ -22,9 +22,13 @@ metadata:
description: Operations related to merge requests
- name: deploy_keys
description: Operations related to deploy keys
+ - name: deploy_tokens
+ description: Operations related to deploy tokens
- name: deployments
description: Operations related to deployments
- name: features
description: Operations related to managing Flipper-based feature flags
+ - name: freeze_periods
+ description: Operations related to deploy freeze periods
- name: release_links
description: Operations related to release assets (links)
diff --git a/config/routes/project.rb b/config/routes/project.rb
index f75d338dad4..56fd52db3b0 100644
--- a/config/routes/project.rb
+++ b/config/routes/project.rb
@@ -471,6 +471,10 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
end
end
end
+
+ namespace :ml do
+ resources :experiments, only: [:index, :show], controller: 'experiments'
+ end
end
# End of the /-/ scope.
diff --git a/db/structure.sql b/db/structure.sql
index c06dedf9115..41c45918fb5 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -11434,7 +11434,6 @@ CREATE TABLE application_settings (
inactive_projects_min_size_mb integer DEFAULT 0 NOT NULL,
inactive_projects_send_warning_email_after_months integer DEFAULT 1 NOT NULL,
delayed_group_deletion boolean DEFAULT true NOT NULL,
- maven_package_requests_forwarding boolean DEFAULT true NOT NULL,
arkose_labs_namespace text DEFAULT 'client'::text NOT NULL,
max_export_size integer DEFAULT 0,
encrypted_slack_app_signing_secret bytea,
@@ -11473,17 +11472,18 @@ CREATE TABLE application_settings (
cube_api_base_url text,
encrypted_cube_api_key bytea,
encrypted_cube_api_key_iv bytea,
+ maven_package_requests_forwarding boolean DEFAULT true NOT NULL,
+ dashboard_limit_enabled boolean DEFAULT false NOT NULL,
+ dashboard_limit integer DEFAULT 0 NOT NULL,
+ dashboard_notification_limit integer DEFAULT 0 NOT NULL,
+ dashboard_enforcement_limit integer DEFAULT 0 NOT NULL,
+ dashboard_limit_new_namespace_creation_enforcement_date date,
jitsu_host text,
jitsu_project_xid text,
clickhouse_connection_string text,
jitsu_administrator_email text,
encrypted_jitsu_administrator_password bytea,
encrypted_jitsu_administrator_password_iv bytea,
- dashboard_limit_enabled boolean DEFAULT false NOT NULL,
- dashboard_limit integer DEFAULT 0 NOT NULL,
- dashboard_notification_limit integer DEFAULT 0 NOT NULL,
- dashboard_enforcement_limit integer DEFAULT 0 NOT NULL,
- dashboard_limit_new_namespace_creation_enforcement_date date,
can_create_group boolean DEFAULT true NOT NULL,
lock_maven_package_requests_forwarding boolean DEFAULT false NOT NULL,
lock_pypi_package_requests_forwarding boolean DEFAULT false NOT NULL,
@@ -20192,8 +20192,8 @@ CREATE TABLE project_settings (
selective_code_owner_removals boolean DEFAULT false NOT NULL,
issue_branch_template text,
show_diff_preview_in_email boolean DEFAULT true NOT NULL,
- jitsu_key text,
suggested_reviewers_enabled boolean DEFAULT false NOT NULL,
+ jitsu_key text,
only_allow_merge_if_all_status_checks_passed boolean DEFAULT false NOT NULL,
CONSTRAINT check_2981f15877 CHECK ((char_length(jitsu_key) <= 100)),
CONSTRAINT check_3a03e7557a CHECK ((char_length(previous_default_branch) <= 4096)),
@@ -28242,10 +28242,6 @@ CREATE UNIQUE INDEX p_ci_builds_metadata_build_id_partition_id_idx ON ONLY p_ci_
CREATE UNIQUE INDEX index_ci_builds_metadata_on_build_id_partition_id_unique ON ci_builds_metadata USING btree (build_id, partition_id);
-CREATE UNIQUE INDEX p_ci_builds_metadata_id_partition_id_idx ON ONLY p_ci_builds_metadata USING btree (id, partition_id);
-
-CREATE UNIQUE INDEX index_ci_builds_metadata_on_id_partition_id_unique ON ci_builds_metadata USING btree (id, partition_id);
-
CREATE INDEX p_ci_builds_metadata_project_id_idx ON ONLY p_ci_builds_metadata USING btree (project_id);
CREATE INDEX index_ci_builds_metadata_on_project_id ON ci_builds_metadata USING btree (project_id);
@@ -32484,8 +32480,6 @@ ALTER INDEX p_ci_builds_metadata_build_id_id_idx ATTACH PARTITION index_ci_build
ALTER INDEX p_ci_builds_metadata_build_id_partition_id_idx ATTACH PARTITION index_ci_builds_metadata_on_build_id_partition_id_unique;
-ALTER INDEX p_ci_builds_metadata_id_partition_id_idx ATTACH PARTITION index_ci_builds_metadata_on_id_partition_id_unique;
-
ALTER INDEX p_ci_builds_metadata_project_id_idx ATTACH PARTITION index_ci_builds_metadata_on_project_id;
CREATE TRIGGER chat_names_loose_fk_trigger AFTER DELETE ON chat_names REFERENCING OLD TABLE AS old_table FOR EACH STATEMENT EXECUTE FUNCTION insert_into_loose_foreign_keys_deleted_records();
diff --git a/doc/administration/consul.md b/doc/administration/consul.md
index a6f76882c4d..f9e4e7d6d44 100644
--- a/doc/administration/consul.md
+++ b/doc/administration/consul.md
@@ -249,5 +249,5 @@ Shortly after that, the client agents should rejoin as well.
If you have taken advantage of Consul to store other data and want to restore
the failed node, follow the
-[Consul guide](https://learn.hashicorp.com/tutorials/consul/recovery-outage)
+[Consul guide](https://developer.hashicorp.com/consul/tutorials/datacenter-operations/recovery-outage)
to recover a failed cluster.
diff --git a/doc/administration/geo/replication/docker_registry.md b/doc/administration/geo/replication/docker_registry.md
deleted file mode 100644
index d0af6f2a66f..00000000000
--- a/doc/administration/geo/replication/docker_registry.md
+++ /dev/null
@@ -1,11 +0,0 @@
----
-redirect_to: 'container_registry.md'
-remove_date: '2022-10-29'
----
-
-This document was moved to [another location](container_registry.md).
-
-<!-- This redirect file can be deleted after <2022-10-29>. -->
-<!-- Redirects that point to other docs in the same project expire in three months. -->
-<!-- Redirects that point to docs in a different project or site (link is not relative and starts with `https:`) expire in one year. -->
-<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html --> \ No newline at end of file
diff --git a/doc/administration/geo/replication/faq.md b/doc/administration/geo/replication/faq.md
index 81afcc19bb1..311cdeee5b9 100644
--- a/doc/administration/geo/replication/faq.md
+++ b/doc/administration/geo/replication/faq.md
@@ -22,7 +22,7 @@ For each project to sync:
1. Geo issues a `git fetch geo --mirror` to get the latest information from the **primary** site.
If there are no changes, the sync is fast. Otherwise, it has to pull the latest commits.
-1. The **secondary** site updates the tracking database to store the fact that it has synced projects A, B, C, and so on.
+1. The **secondary** site updates the tracking database to store the fact that it has synced projects by name.
1. Repeat until all projects are synced.
When someone pushes a commit to the **primary** site, it generates an event in the GitLab database that the repository has changed.
@@ -45,8 +45,8 @@ Read the documentation for [Disaster Recovery](../disaster_recovery/index.md).
## What data is replicated to a **secondary** site?
We currently replicate project repositories, LFS objects, generated
-attachments and avatars, and the whole database. This means user accounts,
-issues, merge requests, groups, project data, and so on, are available for
+attachments and avatars, and the whole database. This means information such as user accounts,
+issues, merge requests, groups, and project data are available for
query.
For more details, see the [supported Geo data types](datatypes.md).
@@ -58,8 +58,8 @@ Pushing directly to a **secondary** site (for both HTTP and SSH, including Git L
## How long does it take to have a commit replicated to a **secondary** site?
All replication operations are asynchronous and are queued to be dispatched. Therefore, it depends on a lot of
-factors including the amount of traffic, how big your commit is, the
-connectivity between your sites, your hardware, and so on.
+factors such as the amount of traffic, how big your commit is, the
+connectivity between your sites, and your hardware.
## What if the SSH server runs at a different port?
diff --git a/doc/administration/geo/replication/security_review.md b/doc/administration/geo/replication/security_review.md
index 0231da53b9c..afe831dcb9c 100644
--- a/doc/administration/geo/replication/security_review.md
+++ b/doc/administration/geo/replication/security_review.md
@@ -25,8 +25,8 @@ from [owasp.org](https://owasp.org/).
### What data does the application receive, produce, and process?
- Geo streams almost all data held by a GitLab instance between sites. This
- includes full database replication, most files (user-uploaded attachments,
- and so on) and repository + wiki data. In a typical configuration, this will
+ includes full database replication, most files such as user-uploaded attachments,
+ and repository + wiki data. In a typical configuration, this will
happen across the public Internet, and be TLS-encrypted.
- PostgreSQL replication is TLS-encrypted.
- See also: [only TLSv1.2 should be supported](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/2948)
@@ -37,7 +37,7 @@ from [owasp.org](https://owasp.org/).
private projects. Geo replicates them all indiscriminately. "Selective sync"
exists for files and repositories (but not database content), which would permit
only less-sensitive projects to be replicated to a **secondary** site if desired.
-- See also: [GitLab data classification policy](https://about.gitlab.com/handbook/engineering/security/data-classification-standard.html).
+- See also: [GitLab data classification policy](https://about.gitlab.com/handbook/security/data-classification-standard.html).
### What data backup and retention requirements have been defined for the application?
@@ -59,8 +59,8 @@ from [owasp.org](https://owasp.org/).
(notably a HTTP/HTTPS web application, and HTTP/HTTPS or SSH Git repository
access), but is constrained to read-only activities. The principal use case is
envisioned to be cloning Git repositories from the **secondary** site in favor of the
- **primary** site, but end-users may use the GitLab web interface to view projects,
- issues, merge requests, snippets, and so on.
+ **primary** site, but end-users may use the GitLab web interface to view information like projects,
+ issues, merge requests, and snippets.
### What security expectations do the end‐users have?
diff --git a/doc/administration/geo/replication/troubleshooting.md b/doc/administration/geo/replication/troubleshooting.md
index e46f3b40046..efe012040ea 100644
--- a/doc/administration/geo/replication/troubleshooting.md
+++ b/doc/administration/geo/replication/troubleshooting.md
@@ -1218,7 +1218,8 @@ If you set up a new secondary from scratch, you must also [remove the old site f
The most common problems that prevent the database from replicating correctly are:
-- **Secondary** sites cannot reach the **primary** site. Check credentials, [firewall rules](../index.md#firewall-rules), and so on.
+- **Secondary** sites cannot reach the **primary** site. Check credentials and
+ [firewall rules](../index.md#firewall-rules).
- SSL certificate problems. Make sure you copied `/etc/gitlab/gitlab-secrets.json` from the **primary** site.
- Database storage disk is full.
- Database replication slot is misconfigured.
diff --git a/doc/administration/geo/setup/external_database.md b/doc/administration/geo/setup/external_database.md
index eabed7c10f3..ab73e5c65f5 100644
--- a/doc/administration/geo/setup/external_database.md
+++ b/doc/administration/geo/setup/external_database.md
@@ -62,7 +62,7 @@ developed and tested. We aim to be compatible with most external
To set up an external database, you can either:
-- Set up [streaming replication](https://www.postgresql.org/docs/12/warm-standby.html#STREAMING-REPLICATION-SLOTS) yourself (for example Amazon RDS, bare metal not managed by Omnibus, and so on).
+- Set up [streaming replication](https://www.postgresql.org/docs/12/warm-standby.html#STREAMING-REPLICATION-SLOTS) yourself (for example Amazon RDS, or bare metal not managed by Omnibus).
- Perform the Omnibus configuration manually as follows.
#### Leverage your cloud provider's tools to replicate the primary database
diff --git a/doc/administration/gitaly/configure_gitaly.md b/doc/administration/gitaly/configure_gitaly.md
index e4aef2db9a8..b59bce37b98 100644
--- a/doc/administration/gitaly/configure_gitaly.md
+++ b/doc/administration/gitaly/configure_gitaly.md
@@ -1100,8 +1100,8 @@ benefit from it. It is orthogonal to:
- The transport (HTTP or SSH).
- Git protocol version (v0 or v2).
-- The type of fetch (full clones, incremental fetches, shallow clones,
- partial clones, and so on).
+- The type of fetch, such as full clones, incremental fetches, shallow clones,
+ or partial clones.
The strength of this cache is its ability to deduplicate concurrent
identical fetches. It:
diff --git a/doc/administration/logs.md b/doc/administration/logs.md
deleted file mode 100644
index 7264cf6db98..00000000000
--- a/doc/administration/logs.md
+++ /dev/null
@@ -1,11 +0,0 @@
----
-redirect_to: 'logs/index.md'
-remove_date: '2022-10-23'
----
-
-This document was moved to [another location](logs/index.md).
-
-<!-- This redirect file can be deleted after <2022-10-23>. -->
-<!-- Redirects that point to other docs in the same project expire in three months. -->
-<!-- Redirects that point to docs in a different project or site (link is not relative and starts with `https:`) expire in one year. -->
-<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
diff --git a/doc/administration/maintenance_mode/index.md b/doc/administration/maintenance_mode/index.md
index 12f3c4c1cc3..d7e7f6d79bd 100644
--- a/doc/administration/maintenance_mode/index.md
+++ b/doc/administration/maintenance_mode/index.md
@@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/2149) in GitLab 13.9.
-Maintenance Mode allows administrators to reduce write operations to a minimum while maintenance tasks are performed. The main goal is to block all external actions that change the internal state, including the PostgreSQL database, but especially files, Git repositories, Container repositories, and so on.
+Maintenance Mode allows administrators to reduce write operations to a minimum while maintenance tasks are performed. The main goal is to block all external actions that change the internal state, including the PostgreSQL database, but especially files, Git repositories, and Container repositories.
Once Maintenance Mode is enabled, in-progress actions finish relatively quickly since no new actions are coming in, and internal state changes are minimal.
In that state, various maintenance tasks are easier, and services can be stopped completely or be
diff --git a/doc/administration/monitoring/performance/index.md b/doc/administration/monitoring/performance/index.md
index 0bea0836191..89f1270532a 100644
--- a/doc/administration/monitoring/performance/index.md
+++ b/doc/administration/monitoring/performance/index.md
@@ -41,7 +41,7 @@ Two types of metrics are collected:
Transaction metrics are metrics that can be associated with a single
transaction. This includes statistics such as the transaction duration, timings
-of any executed SQL queries, time spent rendering HAML views, and so on. These metrics
+of any executed SQL queries, and time spent rendering HAML views. These metrics
are collected for every Rack request and Sidekiq job processed.
### Sampled Metrics
diff --git a/doc/administration/monitoring/prometheus/gitlab_metrics.md b/doc/administration/monitoring/prometheus/gitlab_metrics.md
index 69277becc84..f6b040e60ee 100644
--- a/doc/administration/monitoring/prometheus/gitlab_metrics.md
+++ b/doc/administration/monitoring/prometheus/gitlab_metrics.md
@@ -401,7 +401,7 @@ These client metrics are meant to complement Redis server metrics.
These metrics are broken down per
[Redis instance](https://docs.gitlab.com/omnibus/settings/redis.html#running-with-multiple-redis-instances).
These metrics all have a `storage` label which indicates the Redis
-instance (`cache`, `shared_state`, and so on).
+instance. For example, `cache` or `shared_state`.
| Metric | Type | Since | Description |
|:--------------------------------- |:------- |:----- |:----------- |
diff --git a/doc/administration/nfs.md b/doc/administration/nfs.md
index b72bc57fd60..402d18fc9a7 100644
--- a/doc/administration/nfs.md
+++ b/doc/administration/nfs.md
@@ -10,7 +10,7 @@ type: reference
NFS can be used as an alternative for object storage but this isn't typically
recommended for performance reasons.
-For data objects such as LFS, Uploads, Artifacts, and so on, an [Object Storage service](object_storage.md)
+For data objects such as LFS, Uploads, and Artifacts, an [Object Storage service](object_storage.md)
is recommended over NFS where possible, due to better performance.
When eliminating the usage of NFS, there are [additional steps you need to take](object_storage.md#other-alternatives-to-file-system-storage)
in addition to moving to Object Storage.
@@ -338,7 +338,7 @@ following are the 4 locations need to be shared:
| -------- | ----------- | --------------------- |
| `/var/opt/gitlab/git-data` | Git repository data. This accounts for a large portion of your data | `git_data_dirs({"default" => { "path" => "/var/opt/gitlab/git-data"} })`
| `/var/opt/gitlab/gitlab-rails/uploads` | User uploaded attachments | `gitlab_rails['uploads_directory'] = '/var/opt/gitlab/gitlab-rails/uploads'`
-| `/var/opt/gitlab/gitlab-rails/shared` | Build artifacts, GitLab Pages, LFS objects, temp files, and so on. If you're using LFS this may also account for a large portion of your data | `gitlab_rails['shared_path'] = '/var/opt/gitlab/gitlab-rails/shared'`
+| `/var/opt/gitlab/gitlab-rails/shared` | Objects such as build artifacts, GitLab Pages, LFS objects, and temp files. If you're using LFS this may also account for a large portion of your data | `gitlab_rails['shared_path'] = '/var/opt/gitlab/gitlab-rails/shared'`
| `/var/opt/gitlab/gitlab-ci/builds` | GitLab CI/CD build traces | `gitlab_ci['builds_directory'] = '/var/opt/gitlab/gitlab-ci/builds'`
Other GitLab directories should not be shared between nodes. They contain
diff --git a/doc/administration/object_storage.md b/doc/administration/object_storage.md
index 0e85635b3d2..6233aa217bd 100644
--- a/doc/administration/object_storage.md
+++ b/doc/administration/object_storage.md
@@ -88,8 +88,8 @@ Object storage for <object type> must have a bucket specified
If you want to use local storage for specific object types, you can
[selectively disable object storages](#selectively-disabling-object-storage).
-Most types of objects, such as CI artifacts, LFS files, upload
-attachments, and so on can be saved in object storage by specifying a single
+Most types of objects, such as CI artifacts, LFS files, and upload
+attachments can be saved in object storage by specifying a single
credential for object storage with multiple buckets.
When the consolidated form is:
@@ -492,7 +492,7 @@ To migrate existing local data to object storage see the following guides:
Prior to GitLab 13.2:
- Object storage configuration for all types of objects such as CI/CD artifacts, LFS
- files, upload attachments, and so on had to be configured independently.
+ files, and upload attachments had to be configured independently.
- Object store connection parameters such as passwords and endpoint URLs had to be
duplicated for each type.
diff --git a/doc/administration/package_information/omnibus_packages.md b/doc/administration/package_information/omnibus_packages.md
index ec406f8b458..7b3892ace70 100644
--- a/doc/administration/package_information/omnibus_packages.md
+++ b/doc/administration/package_information/omnibus_packages.md
@@ -72,7 +72,7 @@ Some drawbacks of a package with bundled dependencies:
1. Duplication with possibly existing software.
1. Less flexibility in configuration.
-## Why would I install an omnibus package when I can use a system package?
+## Why would you install an omnibus package when you can use a system package?
The answer can be simplified to: less maintenance required. Instead of handling
multiple packages that *can* break existing functionality if the versions are
diff --git a/doc/administration/pages/index.md b/doc/administration/pages/index.md
index 922f9a27aad..0cfdcc3f4d9 100644
--- a/doc/administration/pages/index.md
+++ b/doc/administration/pages/index.md
@@ -820,8 +820,8 @@ database encryption. Proceed with caution.
It's possible to run GitLab Pages on multiple servers if you wish to distribute
the load. You can do this through standard load balancing practices such as
-configuring your DNS server to return multiple IPs for your Pages server,
-configuring a load balancer to work at the IP level, and so on. If you wish to
+configuring your DNS server to return multiple IPs for your Pages server, or
+configuring a load balancer to work at the IP level. If you wish to
set up GitLab Pages on multiple servers, perform the above procedure for each
Pages server.
diff --git a/doc/administration/polling.md b/doc/administration/polling.md
index 11f26f081cb..deb6e89183d 100644
--- a/doc/administration/polling.md
+++ b/doc/administration/polling.md
@@ -6,8 +6,8 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Polling interval multiplier **(FREE SELF)**
-The GitLab UI polls for updates for different resources (issue notes, issue titles, pipeline
-statuses, and so on) on a schedule appropriate to the resource.
+The GitLab UI polls for updates for different resources (such as issue notes, issue titles, and pipeline
+statuses) on a schedule appropriate to the resource.
Adjust the multiplier on these schedules to adjust how frequently the GitLab UI polls for updates. If
you set the multiplier to:
diff --git a/doc/administration/redis/troubleshooting.md b/doc/administration/redis/troubleshooting.md
index e568daed961..29407f65efd 100644
--- a/doc/administration/redis/troubleshooting.md
+++ b/doc/administration/redis/troubleshooting.md
@@ -26,8 +26,8 @@ Start Redis troubleshooting with a basic Redis activity check:
1. Open a terminal on your GitLab server.
1. Run `gitlab-redis-cli --stat` and observe the output while it runs.
-1. Go to your GitLab UI and browse to a handful of pages. Any page works, like
- group or project overviews, issues, files in repositories, and so on.
+1. Go to your GitLab UI and browse to a handful of pages. Any page works, such as
+ group or project overviews, issues, or files in repositories.
1. Check the `stat` output again and verify that the values for `keys`, `clients`,
`requests`, and `connections` increases as you browse. If the numbers go up,
basic Redis functionality is working and GitLab can connect to it.
diff --git a/doc/administration/reference_architectures/2k_users.md b/doc/administration/reference_architectures/2k_users.md
index 61ea435f63f..3f85fc5fd33 100644
--- a/doc/administration/reference_architectures/2k_users.md
+++ b/doc/administration/reference_architectures/2k_users.md
@@ -35,7 +35,7 @@ For a full list of reference architectures, see
1. Can be optionally run on reputable third-party external PaaS PostgreSQL solutions. See [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
- [Google Cloud SQL](https://cloud.google.com/sql/docs/postgres/high-availability#normal) and [Amazon RDS](https://aws.amazon.com/rds/) are known to work.
- [Google AlloyDB](https://cloud.google.com/alloydb) and [Amazon RDS Multi-AZ DB clusters](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/multi-az-db-clusters-concepts.html) have not been tested and are not recommended. Both solutions are specifically not expected to work with GitLab Geo.
- - [Amazon Aurora](https://aws.amazon.com/rds/aurora/) is **incompatible** with load balancing enabled by default in [14.4.0](../../update/index.md#1440), and [Azure Database for PostgreSQL](https://azure.microsoft.com/en-gb/services/postgresql/) is **not recommended** due to [performance issues](https://gitlab.com/gitlab-org/quality/reference-architectures/-/issues/61).
+ - [Amazon Aurora](https://aws.amazon.com/rds/aurora/) is **incompatible** with load balancing enabled by default in [14.4.0](../../update/index.md#1440), and [Azure Database for PostgreSQL](https://azure.microsoft.com/en-gb/products/postgresql/#overview) is **not recommended** due to [performance issues](https://gitlab.com/gitlab-org/quality/reference-architectures/-/issues/61).
- Consul is primarily used for Omnibus PostgreSQL high availability so can be ignored when using a PostgreSQL PaaS setup. However, Consul is also used optionally by Prometheus for Omnibus auto host discovery.
2. Can be optionally run on reputable third-party external PaaS Redis solutions. See [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
- [Google Memorystore](https://cloud.google.com/memorystore) and [Amazon ElastiCache](https://aws.amazon.com/elasticache/) are known to work.
@@ -1010,7 +1010,7 @@ services where applicable):
1. Can be optionally run on reputable third-party external PaaS PostgreSQL solutions. See [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
- [Google Cloud SQL](https://cloud.google.com/sql/docs/postgres/high-availability#normal) and [Amazon RDS](https://aws.amazon.com/rds/) are known to work.
- [Google AlloyDB](https://cloud.google.com/alloydb) and [Amazon RDS Multi-AZ DB clusters](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/multi-az-db-clusters-concepts.html) have not been tested and are not recommended. Both solutions are specifically not expected to work with GitLab Geo.
- - [Amazon Aurora](https://aws.amazon.com/rds/aurora/) is **incompatible** with load balancing enabled by default in [14.4.0](../../update/index.md#1440), and [Azure Database for PostgreSQL](https://azure.microsoft.com/en-gb/services/postgresql/) is **not recommended** due to [performance issues](https://gitlab.com/gitlab-org/quality/reference-architectures/-/issues/61).
+ - [Amazon Aurora](https://aws.amazon.com/rds/aurora/) is **incompatible** with load balancing enabled by default in [14.4.0](../../update/index.md#1440), and [Azure Database for PostgreSQL](https://azure.microsoft.com/en-gb/products/postgresql/#overview) is **not recommended** due to [performance issues](https://gitlab.com/gitlab-org/quality/reference-architectures/-/issues/61).
- Consul is primarily used for Omnibus PostgreSQL high availability so can be ignored when using a PostgreSQL PaaS setup. However, Consul is also used optionally by Prometheus for Omnibus auto host discovery.
2. Can be optionally run on reputable third-party external PaaS Redis solutions. See [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
- [Google Memorystore](https://cloud.google.com/memorystore) and [Amazon ElastiCache](https://aws.amazon.com/elasticache/) are known to work.
diff --git a/doc/administration/reference_architectures/index.md b/doc/administration/reference_architectures/index.md
index ca14426ae67..467cc332e25 100644
--- a/doc/administration/reference_architectures/index.md
+++ b/doc/administration/reference_architectures/index.md
@@ -206,7 +206,7 @@ When selecting a database service, it should run a standard, performant, and [su
Several cloud provider services are known not to support the above or have been found to have other issues and aren't recommended:
- [Amazon Aurora](https://aws.amazon.com/rds/aurora/) is incompatible and not supported. See [14.4.0](../../update/index.md#1440) for more details.
-- [Azure Database for PostgreSQL Single Server](https://azure.microsoft.com/en-gb/services/postgresql/#overview) (Single / Flexible) is **strongly not recommended** for use due to notable performance / stability issues or missing functionality. See [Recommendation Notes for Azure](#recommendation-notes-for-azure) for more details.
+- [Azure Database for PostgreSQL Single Server](https://azure.microsoft.com/en-gb/products/postgresql/#overview) (Single / Flexible) is **strongly not recommended** for use due to notable performance / stability issues or missing functionality. See [Recommendation Notes for Azure](#recommendation-notes-for-azure) for more details.
- [Google AlloyDB](https://cloud.google.com/alloydb) and [Amazon RDS Multi-AZ DB clusters](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/multi-az-db-clusters-concepts.html) have not been tested and are not recommended. Both solutions are specifically not expected to work with GitLab Geo.
### Recommendation notes for Azure
@@ -217,7 +217,7 @@ In addition to the above, you should be aware of the additional specific guidanc
- **We outright strongly do not recommend [Azure Database for PostgreSQL Single Server](https://learn.microsoft.com/en-us/azure/postgresql/single-server/overview-single-server)** specifically due to significant performance and stability issues found. **For GitLab 14.0 and higher the service is not supported** due to it only supporting up to PostgreSQL 11.
- A new service, [Azure Database for Postgres Flexible Server](https://learn.microsoft.com/en-us/azure/postgresql/flexible-server/) has been released but due to it missing some functionality we don't recommend it at this time.
-- [Azure Blob Storage](https://azure.microsoft.com/en-gb/services/storage/blobs/) has been found to have performance limits that can impact production use at certain times. However, this has only been seen in larger architectures.
+- [Azure Blob Storage](https://azure.microsoft.com/en-gb/products/storage/blobs/) has been found to have performance limits that can impact production use at certain times. However, this has only been seen in larger architectures.
## Validation and test results
diff --git a/doc/administration/reference_architectures/troubleshooting.md b/doc/administration/reference_architectures/troubleshooting.md
deleted file mode 100644
index a9bf035a528..00000000000
--- a/doc/administration/reference_architectures/troubleshooting.md
+++ /dev/null
@@ -1,11 +0,0 @@
----
-redirect_to: '../configure.md'
-remove_date: '2022-10-24'
----
-
-This document was moved to [another location](../configure.md).
-
-<!-- This redirect file can be deleted after <2022-10-24>. -->
-<!-- Redirects that point to other docs in the same project expire in three months. -->
-<!-- Redirects that point to docs in a different project or site (for example, link is not relative and starts with `https:`) expire in one year. -->
-<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html --> \ No newline at end of file
diff --git a/doc/administration/troubleshooting/debug.md b/doc/administration/troubleshooting/debug.md
deleted file mode 100644
index d5019f1aa4a..00000000000
--- a/doc/administration/troubleshooting/debug.md
+++ /dev/null
@@ -1,11 +0,0 @@
----
-redirect_to: '../reference_architectures/troubleshooting.md'
-remove_date: '2022-10-19'
----
-
-This document was moved to [another location](../reference_architectures/troubleshooting.md).
-
-<!-- This redirect file can be deleted after 2022-10-19. -->
-<!-- Redirects that point to other docs in the same project expire in three months. -->
-<!-- Redirects that point to docs in a different project or site (for example, link is not relative and starts with `https:`) expire in one year. -->
-<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
diff --git a/doc/administration/troubleshooting/defcon.md b/doc/administration/troubleshooting/defcon.md
deleted file mode 100644
index f2554f523f0..00000000000
--- a/doc/administration/troubleshooting/defcon.md
+++ /dev/null
@@ -1,11 +0,0 @@
----
-redirect_to: '../../ci/troubleshooting.md#disaster-recovery'
-remove_date: '2022-10-04'
----
-
-This document was moved to [another location](../../ci/troubleshooting.md#disaster-recovery).
-
-<!-- This redirect file can be deleted after <2022-10-04>. -->
-<!-- Redirects that point to other docs in the same project expire in three months. -->
-<!-- Redirects that point to docs in a different project or site (for example, link is not relative and starts with `https:`) expire in one year. -->
-<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
diff --git a/doc/administration/troubleshooting/group_saml_scim.md b/doc/administration/troubleshooting/group_saml_scim.md
deleted file mode 100644
index b5187504231..00000000000
--- a/doc/administration/troubleshooting/group_saml_scim.md
+++ /dev/null
@@ -1,11 +0,0 @@
----
-redirect_to: '../../user/group/saml_sso/example_saml_config.md'
-remove_date: '2022-10-29'
----
-
-This document was moved to [another location](../../user/group/saml_sso/example_saml_config.md).
-
-<!-- This redirect file can be deleted after <2022-10-29>. -->
-<!-- Redirects that point to other docs in the same project expire in three months. -->
-<!-- Redirects that point to docs in a different project or site (link is not relative and starts with `https:`) expire in one year. -->
-<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
diff --git a/doc/administration/troubleshooting/kubernetes_cheat_sheet.md b/doc/administration/troubleshooting/kubernetes_cheat_sheet.md
deleted file mode 100644
index 15ec8d5940b..00000000000
--- a/doc/administration/troubleshooting/kubernetes_cheat_sheet.md
+++ /dev/null
@@ -1,11 +0,0 @@
----
-redirect_to: 'https://docs.gitlab.com/charts/troubleshooting/kubernetes_cheat_sheet.html'
-remove_date: '2022-10-05'
----
-
-This document was moved to [another location](https://docs.gitlab.com/charts/troubleshooting/kubernetes_cheat_sheet.html).
-
-<!-- This redirect file can be deleted after 2022-10-05. -->
-<!-- Redirects that point to other docs in the same project expire in three months. -->
-<!-- Redirects that point to docs in a different project or site (for example, link is not relative and starts with `https:`) expire in one year. -->
-<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
diff --git a/doc/administration/troubleshooting/log_parsing.md b/doc/administration/troubleshooting/log_parsing.md
deleted file mode 100644
index 929a49494be..00000000000
--- a/doc/administration/troubleshooting/log_parsing.md
+++ /dev/null
@@ -1,11 +0,0 @@
----
-redirect_to: '../logs/log_parsing.md'
-remove_date: '2022-10-24'
----
-
-This document was moved to [another location](../logs/log_parsing.md).
-
-<!-- This redirect file can be deleted after <2022-10-24>. -->
-<!-- Redirects that point to other docs in the same project expire in three months. -->
-<!-- Redirects that point to docs in a different project or site (link is not relative and starts with `https:`) expire in one year. -->
-<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
diff --git a/doc/administration/troubleshooting/navigating_gitlab_via_rails_console.md b/doc/administration/troubleshooting/navigating_gitlab_via_rails_console.md
deleted file mode 100644
index 09a5cb8d185..00000000000
--- a/doc/administration/troubleshooting/navigating_gitlab_via_rails_console.md
+++ /dev/null
@@ -1,11 +0,0 @@
----
-redirect_to: '../operations/rails_console.md'
-remove_date: '2022-10-05'
----
-
-This document was moved to [another location](../operations/rails_console.md).
-
-<!-- This redirect file can be deleted after <2022-10-05>. -->
-<!-- Redirects that point to other docs in the same project expire in three months. -->
-<!-- Redirects that point to docs in a different project or site (link is not relative and starts with `https:`) expire in one year. -->
-<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
diff --git a/doc/api/issues.md b/doc/api/issues.md
index a0eb518f23e..dd5a1354a3a 100644
--- a/doc/api/issues.md
+++ b/doc/api/issues.md
@@ -1506,8 +1506,8 @@ Please use `iid` of the `epic` attribute instead.
Clone the issue to given project. If the user has insufficient permissions,
an error message with status code `400` is returned.
-Copies as much data as possible as long as the target project contains equivalent labels, milestones,
-and so on.
+Copies as much data as possible as long as the target project contains equivalent
+criteria such as labels or milestones.
```plaintext
POST /projects/:id/issues/:issue_iid/clone
diff --git a/doc/api/lint.md b/doc/api/lint.md
index c1d95f65a86..e50832a9528 100644
--- a/doc/api/lint.md
+++ b/doc/api/lint.md
@@ -210,7 +210,7 @@ Example responses:
Checks if a project's latest (`HEAD` of the project's default branch)
`.gitlab-ci.yml` configuration is valid. This endpoint uses all namespace
-specific data available, including variables, local includes, and so on.
+specific data available, including variables and local includes.
```plaintext
GET /projects/:id/ci/lint
diff --git a/doc/ci/cloud_deployment/index.md b/doc/ci/cloud_deployment/index.md
index 83774f63566..bd9276275a7 100644
--- a/doc/ci/cloud_deployment/index.md
+++ b/doc/ci/cloud_deployment/index.md
@@ -76,7 +76,7 @@ Prerequisites:
- [Authenticate AWS with GitLab](#authenticate-gitlab-with-aws).
- Create a cluster on Amazon ECS.
-- Create related components, like an ECS service, a database on Amazon RDS, and so on.
+- Create related components, like an ECS service or a database on Amazon RDS.
- Create an ECS task definition, where the value for the `containerDefinitions[].name` attribute is
the same as the `Container name` defined in your targeted ECS service. The task definition can be:
- An existing task definition in ECS.
diff --git a/doc/ci/cloud_services/azure/index.md b/doc/ci/cloud_services/azure/index.md
index 944f95c03e2..b2f78648be9 100644
--- a/doc/ci/cloud_services/azure/index.md
+++ b/doc/ci/cloud_services/azure/index.md
@@ -16,7 +16,7 @@ Prerequisites:
- Access to an existing Azure Subscription with `Owner` access level.
- Access to the corresponding Azure Active Directory Tenant with at least the `Application Developer` access level.
-- A local installation of the [Azure CLI](https://learn.microsoft.com/cli/azure/install-azure-cli).
+- A local installation of the [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli).
Alternatively, you can follow all the steps below with the [Azure Cloud Shell](https://shell.azure.com/).
- A GitLab project.
@@ -27,11 +27,11 @@ To complete this tutorial:
1. [Grant permissions for the service principal](#grant-permissions-for-the-service-principal).
1. [Retrieve a temporary credential](#retrieve-a-temporary-credential).
-For more information, review Azure's documentation on [Workload identity federation](https://learn.microsoft.com/azure/active-directory/develop/workload-identity-federation).
+For more information, review Azure's documentation on [Workload identity federation](https://learn.microsoft.com/en-us/azure/active-directory/develop/workload-identity-federation).
## Create Azure AD application and service principal
-To create an [Azure AD application](https://learn.microsoft.com/cli/azure/ad/app?view=azure-cli-latest#az-ad-app-create)
+To create an [Azure AD application](https://learn.microsoft.com/en-us/cli/azure/ad/app?view=azure-cli-latest#az-ad-app-create)
and service principal:
1. In the Azure CLI, create the AD application:
@@ -43,13 +43,13 @@ and service principal:
Save the `appId` (Application client ID) output, as you need it later
to configure your GitLab CI/CD pipeline.
-1. Create a corresponding [Service Principal](https://learn.microsoft.com/cli/azure/ad/sp?view=azure-cli-latest#az-ad-sp-create):
+1. Create a corresponding [Service Principal](https://learn.microsoft.com/en-us/cli/azure/ad/sp?view=azure-cli-latest#az-ad-sp-create):
```shell
az ad sp create --id $appId --query appId -otsv
```
-Instead of the Azure CLI, you can [use the Azure Portal to create these resources](https://learn.microsoft.com/azure/active-directory/develop/howto-create-service-principal-portal).
+Instead of the Azure CLI, you can [use the Azure Portal to create these resources](https://learn.microsoft.com/en-us/azure/active-directory/develop/howto-create-service-principal-portal).
## Create Azure AD federated identity credentials
@@ -88,7 +88,7 @@ identity credentials from the Azure Portal:
## Grant permissions for the service principal
-After you create the credentials, use [`role assignment`](https://learn.microsoft.com/cli/azure/role/assignment?view=azure-cli-latest#az-role-assignment-create)
+After you create the credentials, use [`role assignment`](https://learn.microsoft.com/en-us/cli/azure/role/assignment?view=azure-cli-latest#az-role-assignment-create)
to grant permissions to the above service principal to access to Azure resources:
```shell
@@ -97,13 +97,13 @@ az role assignment create --assignee $appId --role Reader --scope /subscriptions
You can find your subscription ID in:
-- The [Azure Portal](https://learn.microsoft.com/azure/azure-portal/get-subscription-tenant-id#find-your-azure-subscription).
-- The [Azure CLI](https://learn.microsoft.com/cli/azure/manage-azure-subscriptions-azure-cli#get-the-active-subscription).
+- The [Azure Portal](https://learn.microsoft.com/en-us/azure/azure-portal/get-subscription-tenant-id#find-your-azure-subscription).
+- The [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/manage-azure-subscriptions-azure-cli#get-the-active-subscription).
## Retrieve a temporary credential
After you configure the Azure AD application and federated identity credentials,
-the CI/CD job can retrieve a temporary credential by using the [Azure CLI](https://learn.microsoft.com/cli/azure/reference-index?view=azure-cli-latest#az-login):
+the CI/CD job can retrieve a temporary credential by using the [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/reference-index?view=azure-cli-latest#az-login):
```yaml
default:
@@ -123,7 +123,7 @@ The CI/CD variables are:
- `AZURE_CLIENT_ID`: The [application client ID you saved earlier](#create-azure-ad-application-and-service-principal).
- `AZURE_TENANT_ID`: Your Azure Active Directory. You can
- [find it by using the Azure CLI or Azure Portal](https://learn.microsoft.com/azure/active-directory/fundamentals/active-directory-how-to-find-tenant).
+ [find it by using the Azure CLI or Azure Portal](https://learn.microsoft.com/en-us/azure/active-directory/fundamentals/active-directory-how-to-find-tenant).
- `CI_JOB_JWT_V2`: The JSON web token is a [predefined CI/CD variable](../../variables/predefined_variables.md).
## Troubleshooting
diff --git a/doc/ci/environments/environments_dashboard.md b/doc/ci/environments/environments_dashboard.md
index f662c156f55..479b783202d 100644
--- a/doc/ci/environments/environments_dashboard.md
+++ b/doc/ci/environments/environments_dashboard.md
@@ -29,7 +29,7 @@ The Environments dashboard displays a paginated list of projects that includes
up to three environments per project.
The listed environments for each project are unique, such as
-"production", "staging", and so on. Review apps and other grouped
+"production" and "staging". Review apps and other grouped
environments are not displayed.
## Adding a project to the dashboard
diff --git a/doc/ci/examples/authenticating-with-hashicorp-vault/index.md b/doc/ci/examples/authenticating-with-hashicorp-vault/index.md
index 59e377dbb09..7208caaccae 100644
--- a/doc/ci/examples/authenticating-with-hashicorp-vault/index.md
+++ b/doc/ci/examples/authenticating-with-hashicorp-vault/index.md
@@ -29,7 +29,7 @@ You must replace the `vault.example.com` URL below with the URL of your Vault se
## How it works
-Each job has JSON Web Token (JWT) provided as CI/CD variable named `CI_JOB_JWT`. This JWT can be used to authenticate with Vault using the [JWT Auth](https://www.vaultproject.io/docs/auth/jwt#jwt-authentication) method.
+Each job has JSON Web Token (JWT) provided as CI/CD variable named `CI_JOB_JWT`. This JWT can be used to authenticate with Vault using the [JWT Auth](https://developer.hashicorp.com/vault/docs/auth/jwt#jwt-authentication) method.
The following fields are included in the JWT:
@@ -90,7 +90,7 @@ The JWT is encoded by using RS256 and signed with a dedicated private key. The e
You can use this JWT and your instance's JWKS endpoint (`https://gitlab.example.com/-/jwks`) to authenticate with a Vault server that is configured to allow the JWT Authentication method for authentication.
-When configuring roles in Vault, you can use [bound_claims](https://www.vaultproject.io/docs/auth/jwt#bound-claims) to match against the JWT's claims and restrict which secrets each CI job has access to.
+When configuring roles in Vault, you can use [bound_claims](https://developer.hashicorp.com/vault/docs/auth/jwt#bound-claims) to match against the JWT's claims and restrict which secrets each CI job has access to.
To communicate with Vault, you can use either its CLI client or perform API requests (using `curl` or another client).
@@ -109,7 +109,7 @@ $ vault kv get -field=password secret/myproject/production/db
real-pa$$w0rd
```
-To configure your Vault server, start by enabling the [JWT Auth](https://www.vaultproject.io/docs/auth/jwt) method:
+To configure your Vault server, start by enabling the [JWT Auth](https://developer.hashicorp.com/vault/docs/auth/jwt) method:
```shell
$ vault auth enable jwt
@@ -180,17 +180,17 @@ $ vault write auth/jwt/role/myproject-production - <<EOF
EOF
```
-This example uses [bound_claims](https://www.vaultproject.io/api-docs/auth/jwt#bound_claims) to specify that only a JWT with matching values for the specified claims is allowed to authenticate.
+This example uses [bound_claims](https://developer.hashicorp.com/vault/api-docs/auth/jwt#bound_claims) to specify that only a JWT with matching values for the specified claims is allowed to authenticate.
Combined with [protected branches](../../../user/project/protected_branches.md), you can restrict who is able to authenticate and read the secrets.
-[`token_explicit_max_ttl`](https://www.vaultproject.io/api-docs/auth/jwt#token_explicit_max_ttl) specifies that the token issued by Vault, upon successful authentication, has a hard lifetime limit of 60 seconds.
+[`token_explicit_max_ttl`](https://developer.hashicorp.com/vault/api-docs/auth/jwt#token_explicit_max_ttl) specifies that the token issued by Vault, upon successful authentication, has a hard lifetime limit of 60 seconds.
-[`user_claim`](https://www.vaultproject.io/api-docs/auth/jwt#user_claim) specifies the name for the Identity alias created by Vault upon a successful login.
+[`user_claim`](https://developer.hashicorp.com/vault/api-docs/auth/jwt#user_claim) specifies the name for the Identity alias created by Vault upon a successful login.
-[`bound_claims_type`](https://www.vaultproject.io/api-docs/auth/jwt#bound_claims_type) configures the interpretation of the `bound_claims` values. If set to `glob`, the values are interpreted as globs, with `*` matching any number of characters.
+[`bound_claims_type`](https://developer.hashicorp.com/vault/api-docs/auth/jwt#bound_claims_type) configures the interpretation of the `bound_claims` values. If set to `glob`, the values are interpreted as globs, with `*` matching any number of characters.
-The claim fields listed in [the table above](#how-it-works) can also be accessed for [Vault's policy path templating](https://learn.hashicorp.com/tutorials/vault/policy-templating?in=vault/policies) purposes by using the accessor name of the JWT auth within Vault. The [mount accessor name](https://learn.hashicorp.com/tutorials/vault/identity#step-1-create-an-entity-with-alias) (`ACCESSOR_NAME` in the example below) can be retrieved by running `vault auth list`.
+The claim fields listed in [the table above](#how-it-works) can also be accessed for [Vault's policy path templating](https://developer.hashicorp.com/vault/tutorials/policies/policy-templating?in=vault%2Fpolicies) purposes by using the accessor name of the JWT auth within Vault. The [mount accessor name](https://developer.hashicorp.com/vault/tutorials/auth-methods/identity#step-1-create-an-entity-with-alias) (`ACCESSOR_NAME` in the example below) can be retrieved by running `vault auth list`.
Policy template example making use of a named metadata field named `project_path`:
@@ -200,7 +200,7 @@ path "secret/data/{{identity.entity.aliases.ACCESSOR_NAME.metadata.project_path}
}
```
-Role example to support the templated policy above, mapping the claim field `project_path` as a metadata field through use of [`claim_mappings`](https://www.vaultproject.io/api-docs/auth/jwt#claim_mappings) configuration:
+Role example to support the templated policy above, mapping the claim field `project_path` as a metadata field through use of [`claim_mappings`](https://developer.hashicorp.com/vault/api-docs/auth/jwt#claim_mappings) configuration:
```plaintext
{
@@ -212,7 +212,7 @@ Role example to support the templated policy above, mapping the claim field `pro
}
```
-For the full list of options, see Vault's [Create Role documentation](https://www.vaultproject.io/api-docs/auth/jwt#create-role).
+For the full list of options, see Vault's [Create Role documentation](https://developer.hashicorp.com/vault/api-docs/auth/jwt#create-role).
WARNING:
Always restrict your roles to project or namespace by using one of the provided claims (for example, `project_id` or `namespace_id`). Otherwise any JWT generated by this instance may be allowed to authenticate using this role.
@@ -225,9 +225,9 @@ $ vault write auth/jwt/config \
bound_issuer="gitlab.example.com"
```
-[bound_issuer](https://www.vaultproject.io/api-docs/auth/jwt#bound_issuer) specifies that only a JWT with the issuer (that is, the `iss` claim) set to `gitlab.example.com` can use this method to authenticate, and that the JWKS endpoint (`https://gitlab.example.com/-/jwks`) should be used to validate the token.
+[bound_issuer](https://developer.hashicorp.com/vault/api-docs/auth/jwt#bound_issuer) specifies that only a JWT with the issuer (that is, the `iss` claim) set to `gitlab.example.com` can use this method to authenticate, and that the JWKS endpoint (`https://gitlab.example.com/-/jwks`) should be used to validate the token.
-For the full list of available configuration options, see Vault's [API documentation](https://www.vaultproject.io/api-docs/auth/jwt#configure).
+For the full list of available configuration options, see Vault's [API documentation](https://developer.hashicorp.com/vault/api-docs/auth/jwt#configure).
The following job, when run for the default branch, is able to read secrets under `secret/myproject/staging/`, but not the secrets under `secret/myproject/production/`:
@@ -242,7 +242,7 @@ read_secrets:
# Vault's address can be provided here or as CI/CD variable
- export VAULT_ADDR=http://vault.example.com:8200
# Authenticate and get token. Token expiry time and other properties can be configured
- # when configuring JWT Auth - https://www.vaultproject.io/api-docs/auth/jwt#parameters-1
+ # when configuring JWT Auth - https://developer.hashicorp.com/vault/api-docs/auth/jwt#parameters-1
- export VAULT_TOKEN="$(vault write -field=token auth/jwt/login role=myproject-staging jwt=$CI_JOB_JWT)"
# Now use the VAULT_TOKEN to read the secret and store it in an environment variable
- export PASSWORD="$(vault kv get -field=password secret/myproject/staging/db)"
@@ -271,7 +271,7 @@ read_secrets:
# Vault's address can be provided here or as CI/CD variable
- export VAULT_ADDR=http://vault.example.com:8200
# Authenticate and get token. Token expiry time and other properties can be configured
- # when configuring JWT Auth - https://www.vaultproject.io/api-docs/auth/jwt#parameters-1
+ # when configuring JWT Auth - https://developer.hashicorp.com/vault/api-docs/auth/jwt#parameters-1
- export VAULT_TOKEN="$(vault write -field=token auth/jwt/login role=myproject-production jwt=$CI_JOB_JWT)"
# Now use the VAULT_TOKEN to read the secret and store it in environment variable
- export PASSWORD="$(vault kv get -field=password secret/myproject/production/db)"
@@ -286,11 +286,11 @@ read_secrets:
You can control `CI_JOB_JWT` access to Vault secrets by using Vault protections
and GitLab features. For example, restrict the token by:
-- Using Vault [bound_claims](https://www.vaultproject.io/docs/auth/jwt#bound-claims)
+- Using Vault [bound_claims](https://developer.hashicorp.com/vault/docs/auth/jwt#bound-claims)
for specific groups using `group_claim`.
- Hard coding values for Vault bound claims based on the `user_login` and `user_email`
of specific users.
-- Setting Vault time limits for TTL of the token as specified in [`token_explicit_max_ttl`](https://www.vaultproject.io/api-docs/auth/jwt#token_explicit_max_ttl),
+- Setting Vault time limits for TTL of the token as specified in [`token_explicit_max_ttl`](https://developer.hashicorp.com/vault/api-docs/auth/jwt#token_explicit_max_ttl),
where the token expires after authentication.
- Scoping the JWT to [GitLab protected branches](../../../user/project/protected_branches.md)
that are restricted to a subset of project users.
diff --git a/doc/ci/examples/deployment/composer-npm-deploy.md b/doc/ci/examples/deployment/composer-npm-deploy.md
index f14372757a9..a603207aef7 100644
--- a/doc/ci/examples/deployment/composer-npm-deploy.md
+++ b/doc/ci/examples/deployment/composer-npm-deploy.md
@@ -47,7 +47,7 @@ All these operations put all files into a `build` folder, which is ready to be d
## How to transfer files to a live server
-You have multiple options: rsync, SCP, SFTP, and so on. For now, use SCP.
+You have multiple options such as rsync, SCP, or SFTP. For now, use SCP.
To make this work, you must add a GitLab CI/CD Variable (accessible on `gitlab.example/your-project-name/variables`). Name this variable `STAGING_PRIVATE_KEY` and set it to the **private** SSH key of your server.
diff --git a/doc/ci/jobs/ci_job_token.md b/doc/ci/jobs/ci_job_token.md
index 7282ebb0909..1e7b389c84a 100644
--- a/doc/ci/jobs/ci_job_token.md
+++ b/doc/ci/jobs/ci_job_token.md
@@ -26,8 +26,8 @@ You can use a GitLab CI/CD job token to authenticate with specific API endpoints
- [Terraform plan](../../user/infrastructure/index.md).
The token has the same permissions to access the API as the user that caused the
-job to run. A user can cause a job to run by pushing a commit, triggering a manual job,
-being the owner of a scheduled pipeline, and so on. Therefore, this user must be assigned to
+job to run. A user can cause a job to run by taking action like pushing a commit,
+triggering a manual job, or being the owner of a scheduled pipeline. Therefore, this user must be assigned to
[a role that has the required privileges](../../user/permissions.md#gitlab-cicd-permissions).
The token is valid only while the pipeline job runs. After the job finishes, you can't
diff --git a/doc/ci/jobs/job_control.md b/doc/ci/jobs/job_control.md
index 39ab0998291..fc3b106aa18 100644
--- a/doc/ci/jobs/job_control.md
+++ b/doc/ci/jobs/job_control.md
@@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
When a new pipeline starts, GitLab checks the pipeline configuration to determine
which jobs should run in that pipeline. You can configure jobs to run depending on
-the status of variables, the pipeline type, and so on.
+factors like the status of variables, or the pipeline type.
To configure a job to be included or excluded from certain pipelines, you can use:
@@ -1061,7 +1061,7 @@ docker_build:
When the `DOCKERFILES_DIR` variable is expanded in the `changes:` section, the full
path becomes `path/to/files//*`. The double slashes might cause unexpected behavior
-depending on the keyword used, shell and OS of the runner, and so on.
+depending on factors like the keyword used, or the shell and OS of the runner.
### `You are not allowed to download code from this project.` error message
diff --git a/doc/ci/migration/jenkins.md b/doc/ci/migration/jenkins.md
index 300de610aa7..4ba59e14811 100644
--- a/doc/ci/migration/jenkins.md
+++ b/doc/ci/migration/jenkins.md
@@ -49,8 +49,8 @@ things we have found that help this:
your users understand why the effort is worth it. The value is clear when
the work is done, but people need to be aware while it's in progress too.
- Sponsorship and alignment from the relevant leadership team helps with the point above.
-- Spending time educating your users on what's different, sharing this document with them,
- and so on helps ensure you are successful.
+- Spending time educating your users on what's different and sharing this document
+ with them helps ensure you are successful.
- Finding ways to sequence or delay parts of the migration can help a lot, but you
don't want to leave things in a non-migrated (or partially-migrated) state for too
long. To gain all the benefits of GitLab, moving your existing Jenkins setup over
@@ -67,7 +67,7 @@ of transition, by letting you delay the migration of less urgent pipelines for a
If you are interested in helping GitLab test the wrapper, join our [public testing issue](https://gitlab.com/gitlab-org/gitlab/-/issues/215675) for instructions and to provide your feedback.
NOTE:
-If you have a paid GitLab subscription, note that the JenkinsFile Wrapper is not packaged as part of GitLab, and falls outside of the scope of support. For more information, see the [Statement of Support](https://about.gitlab.com/support/statement-of-support.html).
+If you have a paid GitLab subscription, note that the JenkinsFile Wrapper is not packaged as part of GitLab, and falls outside of the scope of support. For more information, see the [Statement of Support](https://about.gitlab.com/support/statement-of-support/).
## Important product differences
@@ -197,7 +197,7 @@ can leverage. You can see the complete list of packaging features in the
## Integrated features
-Where you may have used plugins to get things like code quality, unit tests, security scanning, and so on working in Jenkins,
+Where you may have used plugins to get things like code quality, unit tests, and security scanning working in Jenkins,
GitLab takes advantage of our connected ecosystem to automatically pull these kinds of results into
your merge requests, pipeline details pages, and other locations. You may find that you actually don't
need to configure anything to have these appear.
diff --git a/doc/ci/pipelines/cicd_minutes.md b/doc/ci/pipelines/cicd_minutes.md
index a5484fcdf5a..bca2bea0156 100644
--- a/doc/ci/pipelines/cicd_minutes.md
+++ b/doc/ci/pipelines/cicd_minutes.md
@@ -232,7 +232,7 @@ For this reduced cost factor:
- The merge request source project must be a fork of a GitLab-maintained project,
such as [`gitlab-com/www-gitlab-com`](https://gitlab.com/gitlab-com/www-gitlab-com),
- [`gitlab-org/gitlab`](https://gitlab.com/gitlab-org/gitlab), and so on.
+ or [`gitlab-org/gitlab`](https://gitlab.com/gitlab-org/gitlab).
- The merge request target project must be the fork's parent project.
- The pipeline must be a merge request, merged results, or merge train pipeline.
diff --git a/doc/ci/pipelines/index.md b/doc/ci/pipelines/index.md
index 59310e7923f..f1ca8afa62c 100644
--- a/doc/ci/pipelines/index.md
+++ b/doc/ci/pipelines/index.md
@@ -80,7 +80,7 @@ You can also configure specific aspects of your pipelines through the GitLab UI.
### Ref specs for runners
When a runner picks a pipeline job, GitLab provides that job's metadata. This includes the [Git refspecs](https://git-scm.com/book/en/v2/Git-Internals-The-Refspec),
-which indicate which ref (branch, tag, and so on) and commit (SHA1) are checked out from your
+which indicate which ref (such as branch or tag) and commit (SHA1) are checked out from your
project repository.
This table lists the refspecs injected for each pipeline type:
@@ -158,7 +158,7 @@ The pipeline now executes the jobs as configured.
You can use the [`description` and `value`](../yaml/index.md#variablesdescription)
keywords to define [pipeline-level (global) variables](../variables/index.md#create-a-custom-cicd-variable-in-the-gitlab-ciyml-file)
that are prefilled when running a pipeline manually. Use the description to explain
-what the variable is used for, what the acceptable values are, and so on.
+information such as what the variable is used for, and what the acceptable values are.
Job-level variables cannot be pre-filled.
diff --git a/doc/ci/pipelines/pipeline_architectures.md b/doc/ci/pipelines/pipeline_architectures.md
index 3e348734f62..1e4d32fc331 100644
--- a/doc/ci/pipelines/pipeline_architectures.md
+++ b/doc/ci/pipelines/pipeline_architectures.md
@@ -34,7 +34,7 @@ own advantages. These methods can be mixed and matched if needed:
## Basic Pipelines
This is the simplest pipeline in GitLab. It runs everything in the build stage concurrently,
-and once all of those finish, it runs everything in the test stage the same way, and so on.
+and once all of those finish, it runs everything in the test and subsequent stages the same way.
It's not the most efficient, and if you have lots of steps it can grow quite complex, but it's
easier to maintain:
diff --git a/doc/ci/pipelines/pipeline_efficiency.md b/doc/ci/pipelines/pipeline_efficiency.md
index aa2f074693a..276a03cb480 100644
--- a/doc/ci/pipelines/pipeline_efficiency.md
+++ b/doc/ci/pipelines/pipeline_efficiency.md
@@ -225,7 +225,7 @@ has more information about building efficient Docker images.
Methods to reduce Docker image size:
- Use a small base image, for example `debian-slim`.
-- Do not install convenience tools like vim, curl, and so on, if they aren't strictly needed.
+- Do not install convenience tools such as vim or curl if they aren't strictly needed.
- Create a dedicated development image.
- Disable man pages and docs installed by packages to save space.
- Reduce the `RUN` layers and combine software installation steps.
diff --git a/doc/ci/secrets/index.md b/doc/ci/secrets/index.md
index 62350905bd4..a5082af89bc 100644
--- a/doc/ci/secrets/index.md
+++ b/doc/ci/secrets/index.md
@@ -20,11 +20,11 @@ required by a job. Read [GitLab CI/CD pipeline configuration reference](../yaml/
for more information about the syntax.
GitLab has selected [Vault by HashiCorp](https://www.vaultproject.io) as the
-first supported provider, and [KV-V2](https://www.vaultproject.io/docs/secrets/kv/kv-v2)
+first supported provider, and [KV-V2](https://developer.hashicorp.com/vault/docs/secrets/kv/kv-v2)
as the first supported secrets engine.
GitLab authenticates using Vault's
-[JSON Web Token (JWT) authentication method](https://www.vaultproject.io/docs/auth/jwt#jwt-authentication), using
+[JSON Web Token (JWT) authentication method](https://developer.hashicorp.com/vault/docs/auth/jwt#jwt-authentication), using
the [JSON Web Token](https://gitlab.com/gitlab-org/gitlab/-/issues/207125) (`CI_JOB_JWT`)
introduced in GitLab 12.10.
@@ -88,10 +88,10 @@ To configure your Vault server:
- `VAULT_SERVER_URL` - The URL of your Vault server, such as `https://vault.example.com:8200`.
Required.
- `VAULT_AUTH_ROLE` - Optional. The role to use when attempting to authenticate.
- If no role is specified, Vault uses the [default role](https://www.vaultproject.io/api-docs/auth/jwt#default_role)
+ If no role is specified, Vault uses the [default role](https://developer.hashicorp.com/vault/api-docs/auth/jwt#default_role)
specified when the authentication method was configured.
- `VAULT_AUTH_PATH` - Optional. The path where the authentication method is mounted, default is `jwt`.
- - `VAULT_NAMESPACE` - Optional. The [Vault Enterprise namespace](https://www.vaultproject.io/docs/enterprise/namespaces) to use for reading secrets and authentication.
+ - `VAULT_NAMESPACE` - Optional. The [Vault Enterprise namespace](https://developer.hashicorp.com/vault/docs/enterprise/namespaces) to use for reading secrets and authentication.
If no namespace is specified, Vault uses the `root` ("`/`") namespace.
The setting is ignored by Vault Open Source.
@@ -142,7 +142,7 @@ When a CI job attempts to authenticate, it specifies a role. You can use roles t
different policies together. If authentication is successful, these policies are
attached to the resulting Vault token.
-[Bound claims](https://www.vaultproject.io/docs/auth/jwt#bound-claims) are predefined
+[Bound claims](https://developer.hashicorp.com/vault/docs/auth/jwt#bound-claims) are predefined
values that are matched to the JWT's claims. With bounded claims, you can restrict access
to specific GitLab users, specific projects, or even jobs running for specific Git
references. You can have as many bounded claims you need, but they must *all* match
@@ -183,7 +183,7 @@ For a full list of `CI_JOB_JWT` claims, read the
You can also specify some attributes for the resulting Vault tokens, such as time-to-live,
IP address range, and number of uses. The full list of options is available in
-[Vault's documentation on creating roles](https://www.vaultproject.io/api-docs/auth/jwt#create-role)
+[Vault's documentation on creating roles](https://developer.hashicorp.com/vault/api-docs/auth/jwt#create-role)
for the JSON web token method.
## Using a self-signed Vault server
diff --git a/doc/ci/yaml/index.md b/doc/ci/yaml/index.md
index 4c7f18dbce5..1f67457ab54 100644
--- a/doc/ci/yaml/index.md
+++ b/doc/ci/yaml/index.md
@@ -3599,7 +3599,7 @@ Use `secrets:vault` to specify secrets provided by a [HashiCorp Vault](https://w
**Example of `secrets:vault`**:
-To specify all details explicitly and use the [KV-V2](https://www.vaultproject.io/docs/secrets/kv/kv-v2) secrets engine:
+To specify all details explicitly and use the [KV-V2](https://developer.hashicorp.com/vault/docs/secrets/kv/kv-v2) secrets engine:
```yaml
job:
diff --git a/doc/development/audit_event_guide/index.md b/doc/development/audit_event_guide/index.md
index 25d1d08be4a..2279ede7d54 100644
--- a/doc/development/audit_event_guide/index.md
+++ b/doc/development/audit_event_guide/index.md
@@ -21,7 +21,7 @@ While any events could trigger an Audit Event, not all events should. In general
- Not attributable to one specific user.
- Not of specific interest to an administrator or owner persona.
- Are tracking information for product feature adoption.
-- Are covered in the direction page's discussion on [what is not planned](https://about.gitlab.com/direction/manage/compliance/audit-events/#what-is-not-planned-right-now).
+- Are covered in the direction page's discussion on [what is not planned](https://about.gitlab.com/direction/govern/compliance/audit-events/#what-is-not-planned-right-now).
If you have any questions, please reach out to `@gitlab-org/govern/compliance` to see if an Audit Event, or some other approach, may be best for your event.
diff --git a/doc/development/code_review.md b/doc/development/code_review.md
index 280af21a864..978b89f4289 100644
--- a/doc/development/code_review.md
+++ b/doc/development/code_review.md
@@ -212,8 +212,8 @@ See the [test engineering process](https://about.gitlab.com/handbook/engineering
##### Security
-1. I have confirmed that if this MR contains changes to processing or storing of credentials or tokens, authorization, and authentication methods, or other items described in [the security review guidelines](https://about.gitlab.com/handbook/engineering/security/#when-to-request-a-security-review), I have added the `~security` label and I have `@`-mentioned `@gitlab-com/gl-security/appsec`.
-1. I have reviewed the documentation regarding [internal application security reviews](https://about.gitlab.com/handbook/engineering/security/#internal-application-security-reviews) for **when** and **how** to request a security review and requested a security review if this is warranted for this change.
+1. I have confirmed that if this MR contains changes to processing or storing of credentials or tokens, authorization, and authentication methods, or other items described in [the security review guidelines](https://about.gitlab.com/handbook/security/#when-to-request-a-security-review), I have added the `~security` label and I have `@`-mentioned `@gitlab-com/gl-security/appsec`.
+1. I have reviewed the documentation regarding [internal application security reviews](https://about.gitlab.com/handbook/security/#internal-application-security-reviews) for **when** and **how** to request a security review and requested a security review if this is warranted for this change.
##### Deployment
@@ -508,7 +508,7 @@ people who add commits to an MR are not authorized to approve the merge request,
so they must seek a maintainer who has not contributed to the MR to approve the MR before it can be merged.
This policy is in place to satisfy the CHG-04 control of the GitLab
-[Change Management Controls](https://about.gitlab.com/handbook/engineering/security/security-assurance/security-compliance/guidance/change-management.html).
+[Change Management Controls](https://about.gitlab.com/handbook/security/security-assurance/security-compliance/guidance/change-management.html).
To implement this policy in `gitlab-org/gitlab`, we have enabled the following
settings to ensure MRs get an approval from a top-level CODEOWNERS maintainer:
diff --git a/doc/development/contributing/design.md b/doc/development/contributing/design.md
index a1f9fa2e457..e6b6b56cf73 100644
--- a/doc/development/contributing/design.md
+++ b/doc/development/contributing/design.md
@@ -24,7 +24,7 @@ screenshots (or videos) of your changes in the description, as explained in our
[MR workflow](merge_request_workflow.md). These screenshots/videos are very helpful
for all reviewers and can speed up the review process, especially if the changes
are small.
-- Attach the ~UX label to any merge request that impacts the user experience. This will enable Product Designers to [review](https://about.gitlab.com/handbook/engineering/ux/product-designer/mr-reviews/#stage-group-mrs/) any user facing changes.
+- Attach the ~UX label to any merge request that impacts the user experience. This will enable Product Designers to [review](https://about.gitlab.com/handbook/product/ux/product-designer/mr-reviews/#stage-group-mrs/) any user facing changes.
- Assign the Product Designer suggested by Reviewer Roulette as the reviewer of your merge request. The reviewer does not have to be the domain expert unless this is a community contribution.
## Checklist
diff --git a/doc/development/development_processes.md b/doc/development/development_processes.md
index 10818b749ab..e1df3b55d06 100644
--- a/doc/development/development_processes.md
+++ b/doc/development/development_processes.md
@@ -80,7 +80,7 @@ In these cases, use the following workflow:
- [Backend](https://about.gitlab.com/handbook/engineering/)
- [Database](https://about.gitlab.com/handbook/engineering/development/database/)
- [User Experience (UX)](https://about.gitlab.com/handbook/product/ux/)
- - [Security](https://about.gitlab.com/handbook/engineering/security/)
+ - [Security](https://about.gitlab.com/handbook/security/)
- [Quality](https://about.gitlab.com/handbook/engineering/quality/)
- [Engineering Productivity](https://about.gitlab.com/handbook/engineering/quality/engineering-productivity/)
- [Infrastructure](https://about.gitlab.com/handbook/engineering/infrastructure/)
diff --git a/doc/development/fips_compliance.md b/doc/development/fips_compliance.md
index c976f057d02..c6208d45c77 100644
--- a/doc/development/fips_compliance.md
+++ b/doc/development/fips_compliance.md
@@ -203,7 +203,7 @@ This [GitHub pull request](https://github.com/awslabs/amazon-eks-ami/pull/898) m
it possible to create an Amazon Linux 2 EKS AMI with FIPS enabled for Kubernetes v1.21.
To build an image:
-1. [Install Packer](https://learn.hashicorp.com/tutorials/packer/get-started-install-cli).
+1. [Install Packer](https://developer.hashicorp.com/packer/tutorials/docker-get-started/get-started-install-cli).
1. Run the following:
```shell
diff --git a/doc/development/gemfile.md b/doc/development/gemfile.md
index 7d3531afb49..3c7dc19da8e 100644
--- a/doc/development/gemfile.md
+++ b/doc/development/gemfile.md
@@ -66,7 +66,7 @@ This means that new dependencies should, at a minimum, meet the following criter
When adding a new gem to our `Gemfile` or even changing versions in
`Gemfile.lock` it is strongly recommended that you
-[request a Security review](https://about.gitlab.com/handbook/engineering/security/#how-to-request-a-security-review).
+[request a Security review](https://about.gitlab.com/handbook/security/#how-to-request-a-security-review).
New gems add an extra security risk for GitLab, and it is important to
evaluate this risk before we ship this to production. Technically, just adding
a new gem and pushing to a branch in our main `gitlab` project is a security
diff --git a/doc/development/licensed_feature_availability.md b/doc/development/licensed_feature_availability.md
deleted file mode 100644
index b007df8f1da..00000000000
--- a/doc/development/licensed_feature_availability.md
+++ /dev/null
@@ -1,11 +0,0 @@
----
-redirect_to: 'ee_features.md'
-remove_date: '2022-10-08'
----
-
-This document was moved to [another location](ee_features.md).
-
-<!-- This redirect file can be deleted after <2022-10-08>. -->
-<!-- Redirects that point to other docs in the same project expire in three months. -->
-<!-- Redirects that point to docs in a different project or site (link is not relative and starts with `https:`) expire in one year. -->
-<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
diff --git a/doc/development/merge_request_concepts/widget_extensions.md b/doc/development/merge_request_concepts/widget_extensions.md
deleted file mode 100644
index 097e9155f2b..00000000000
--- a/doc/development/merge_request_concepts/widget_extensions.md
+++ /dev/null
@@ -1,11 +0,0 @@
----
-redirect_to: '../fe_guide/merge_request_widget_extensions.md'
-remove_date: '2022-10-27'
----
-
-This document was moved to [another location](../fe_guide/merge_request_widget_extensions.md).
-
-<!-- This redirect file can be deleted after <2022-10-27>. -->
-<!-- Redirects that point to other docs in the same project expire in three months. -->
-<!-- Redirects that point to docs in a different project or site (for example, link is not relative and starts with `https:`) expire in one year. -->
-<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
diff --git a/doc/development/secure_coding_guidelines.md b/doc/development/secure_coding_guidelines.md
index 59013c89687..7b787b67bca 100644
--- a/doc/development/secure_coding_guidelines.md
+++ b/doc/development/secure_coding_guidelines.md
@@ -1271,7 +1271,7 @@ This sensitive data must be handled carefully to avoid leaks which could lead to
- The [Gitleaks Git hook](https://gitlab.com/gitlab-com/gl-security/security-research/gitleaks-endpoint-installer) is recommended for preventing credentials from being committed.
- Never log credentials under any circumstance. Issue [#353857](https://gitlab.com/gitlab-org/gitlab/-/issues/353857) is an example of credential leaks through log file.
- When credentials are required in a CI/CD job, use [masked variables](../ci/variables/index.md#mask-a-cicd-variable) to help prevent accidental exposure in the job logs. Be aware that when [debug logging](../ci/variables/index.md#debug-logging) is enabled, all masked CI/CD variables are visible in job logs. Also consider using [protected variables](../ci/variables/index.md#protected-cicd-variables) when possible so that sensitive CI/CD variables are only available to pipelines running on protected branches or protected tags.
-- Proper scanners must be enabled depending on what data those credentials are protecting. See the [Application Security Inventory Policy](https://about.gitlab.com/handbook/engineering/security/security-engineering-and-research/application-security/inventory.html#policies) and our [Data Classification Standards](https://about.gitlab.com/handbook/engineering/security/data-classification-standard.html#data-classification-standards).
+- Proper scanners must be enabled depending on what data those credentials are protecting. See the [Application Security Inventory Policy](https://about.gitlab.com/handbook/security/security-engineering-and-research/application-security/inventory.html#policies) and our [Data Classification Standards](https://about.gitlab.com/handbook/security/data-classification-standard.html#data-classification-standards).
- To store and/or share credentials between teams, refer to [1Password for Teams](https://about.gitlab.com/handbook/security/#1password-for-teams) and follow [the 1Password Guidelines](https://about.gitlab.com/handbook/security/#1password-guidelines).
- If you need to share a secret with a team member, use 1Password. Do not share a secret over email, Slack, or other service on the Internet.
@@ -1281,7 +1281,7 @@ This sensitive data must be handled carefully to avoid leaks which could lead to
- Avoid including credentials as part of an HTTP response unless it is absolutely necessary as part of the workflow. For example, generating a PAT for users.
- Avoid sending credentials in URL parameters, as these can be more easily logged inadvertently during transit.
-In the event of credential leak through an MR, issue, or any other medium, [reach out to SIRT team](https://about.gitlab.com/handbook/engineering/security/security-operations/sirt/#-engaging-sirt).
+In the event of credential leak through an MR, issue, or any other medium, [reach out to SIRT team](https://about.gitlab.com/handbook/security/security-operations/sirt/#-engaging-sirt).
## Serialization
diff --git a/doc/development/service_ping/index.md b/doc/development/service_ping/index.md
index 5baf1a6d38d..37e0b753448 100644
--- a/doc/development/service_ping/index.md
+++ b/doc/development/service_ping/index.md
@@ -504,7 +504,7 @@ Service Ping reporting process state is monitored with [internal SiSense dashboa
- [Product Intelligence Guide](https://about.gitlab.com/handbook/product/product-intelligence-guide/)
- [Snowplow Guide](../snowplow/index.md)
-- [Product Intelligence Direction](https://about.gitlab.com/direction/product-intelligence/)
+- [Product Intelligence Direction](https://about.gitlab.com/direction/analytics/product-intelligence/)
- [Data Analysis Process](https://about.gitlab.com/handbook/business-technology/data-team/#data-analysis-process/)
- [Data for Product Managers](https://about.gitlab.com/handbook/business-technology/data-team/programs/data-for-product-managers/)
- [Data Infrastructure](https://about.gitlab.com/handbook/business-technology/data-team/platform/infrastructure/)
diff --git a/doc/development/snowplow/implementation.md b/doc/development/snowplow/implementation.md
index 659165cf18a..a80d6fe70ff 100644
--- a/doc/development/snowplow/implementation.md
+++ b/doc/development/snowplow/implementation.md
@@ -13,7 +13,7 @@ This page describes how to:
## Snowplow JavaScript frontend tracking
-GitLab provides a `Tracking` interface that wraps the [Snowplow JavaScript tracker](https://docs.snowplowanalytics.com/docs/collecting-data/collecting-from-own-applications/javascript-trackers/)
+GitLab provides a `Tracking` interface that wraps the [Snowplow JavaScript tracker](https://docs.snowplow.io/docs/collecting-data/collecting-from-own-applications/javascript-trackers/)
to track custom events.
For the recommended frontend tracking implementation, see [Usage recommendations](#usage-recommendations).
@@ -349,7 +349,7 @@ describe('MyTracking', () => {
### Form tracking
-To enable Snowplow automatic [form tracking](https://docs.snowplowanalytics.com/docs/collecting-data/collecting-from-own-applications/javascript-trackers/javascript-tracker/javascript-tracker-v2/tracking-specific-events/#form-tracking):
+To enable Snowplow automatic [form tracking](https://docs.snowplow.io/docs/collecting-data/collecting-from-own-applications/javascript-trackers/javascript-tracker/javascript-tracker-v2/tracking-specific-events/#form-tracking):
1. Call `Tracking.enableFormTracking` when the DOM is ready.
1. Provide a `config` object that includes at least one of the following elements:
@@ -389,7 +389,7 @@ describe('MyFormTracking', () => {
## Implement Ruby backend tracking
-`Gitlab::Tracking` is an interface that wraps the [Snowplow Ruby Tracker](https://docs.snowplowanalytics.com/docs/collecting-data/collecting-from-own-applications/ruby-tracker/) for tracking custom events.
+`Gitlab::Tracking` is an interface that wraps the [Snowplow Ruby Tracker](https://docs.snowplow.io/docs/collecting-data/collecting-from-own-applications/ruby-tracker/) for tracking custom events.
Backend tracking provides:
- User behavior tracking
@@ -451,7 +451,7 @@ Before you test frontend events in development, you must:
1. Turn off ad blockers that could prevent Snowplow JavaScript from loading in your environment.
1. Turn off "Do Not Track" (DNT) in your browser.
-All URLs are pseudonymized. The entity identifier [replaces](https://docs.snowplowanalytics.com/docs/collecting-data/collecting-from-own-applications/javascript-trackers/javascript-tracker/javascript-tracker-v2/tracker-setup/other-parameters-2/#Setting_a_custom_page_URL_and_referrer_URL) personally identifiable
+All URLs are pseudonymized. The entity identifier [replaces](https://docs.snowplow.io/docs/collecting-data/collecting-from-own-applications/javascript-trackers/javascript-tracker/javascript-tracker-v2/tracker-setup/other-parameters-2/#setting-a-custom-page-url-and-referrer-url) personally identifiable
information (PII). PII includes usernames, group, and project names.
Page titles are hardcoded as `GitLab` for the same reason.
@@ -477,7 +477,7 @@ For a video tutorial, see the [Snowplow plugin walk through](https://www.youtube
#### Snowplow Micro
-[Snowplow Micro](https://snowplowanalytics.com/blog/2019/07/17/introducing-snowplow-micro/) is a
+[Snowplow Micro](https://snowplow.io/blog/introducing-snowplow-micro/) is a
Docker-based solution for testing backend and frontend in a local development environment. Snowplow Micro
records the same events as the full Snowplow pipeline. To query events, use the Snowplow Micro API.
diff --git a/doc/development/snowplow/index.md b/doc/development/snowplow/index.md
index af253486861..7dec2740da2 100644
--- a/doc/development/snowplow/index.md
+++ b/doc/development/snowplow/index.md
@@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
Snowplow is an enterprise-grade marketing and Product Intelligence platform that tracks how users engage with our website and application.
-[Snowplow](https://snowplowanalytics.com) consists of several loosely-coupled sub-systems:
+[Snowplow](https://snowplow.io/) consists of several loosely-coupled sub-systems:
- **Trackers** fire Snowplow events. Snowplow has twelve trackers that cover web, mobile, desktop, server, and IoT.
- **Collectors** receive Snowplow events from trackers. We use different event collectors that synchronize events to Amazon S3, Apache Kafka, or Amazon Kinesis.
@@ -82,10 +82,10 @@ For more details about the architecture, see [Snowplow infrastructure](infrastru
## Event schema
-Click events must be consistent. If each feature captures events differently, it can be difficult
+All the events must be consistent. If each feature captures events differently, it can be difficult
to perform analysis.
-Each click event provides attributes that describe the event.
+Each event provides attributes that describe the event.
| Attribute | Type | Required | Description |
| --------- | ------- | -------- | ----------- |
@@ -94,6 +94,7 @@ Each click event provides attributes that describe the event.
| label | text | false | The specific element or object to act on. This can be one of the following: the label of the element, for example, a tab labeled 'Create from template' for `create_from_template`; a unique identifier if no text is available, for example, `groups_dropdown_close` for closing the Groups dropdown list in the top bar; or the name or title attribute of a record being created. For Service Ping metrics adapted to Snowplow events, this should be the full metric [key path](../service_ping/metrics_dictionary.md#metric-key_path) taken from its definition file. |
| property | text | false | Any additional property of the element, or object being acted on. For Service Ping metrics adapted to Snowplow events, this should be additional information or context that can help analyze the event. For example, in the case of `usage_activity_by_stage_monthly.create.merge_requests_users`, there are four different possible merge request actions: "create", "merge", "comment", and "close". Each of these would be a possible property value. |
| value | decimal | false | Describes a numeric value (decimal) directly related to the event. This could be the value of an input. For example, `10` when clicking `internal` visibility. |
+| context | vector | false | Additional data in the form of a [self-describing JSON](https://docs.snowplow.io/docs/pipeline-components-and-applications/iglu/common-architecture/self-describing-json-schemas/) to describe the event if the attributes are not sufficient. Each context must have its schema defined to assure data integrity. Refer to the list of GitLab-defined contexts for more details. |
### Examples
@@ -189,12 +190,12 @@ Snowplow JavaScript adds [web-specific parameters](https://docs.snowplowanalytic
## Related topics
-- [Snowplow data structure](https://docs.snowplowanalytics.com/docs/understanding-your-pipeline/canonical-event/)
+- [Snowplow data structure](https://docs.snowplow.io/docs/understanding-your-pipeline/canonical-event/)
- [Our Iglu schema registry](https://gitlab.com/gitlab-org/iglu)
- [List of events used in our codebase (Event Dictionary)](https://metrics.gitlab.com/snowplow/)
- [Product Intelligence Guide](https://about.gitlab.com/handbook/product/product-intelligence-guide/)
- [Service Ping Guide](../service_ping/index.md)
-- [Product Intelligence Direction](https://about.gitlab.com/direction/product-intelligence/)
+- [Product Intelligence Direction](https://about.gitlab.com/direction/analytics/product-intelligence/)
- [Data Analysis Process](https://about.gitlab.com/handbook/business-technology/data-team/#data-analysis-process/)
- [Data for Product Managers](https://about.gitlab.com/handbook/business-technology/data-team/programs/data-for-product-managers/)
- [Data Infrastructure](https://about.gitlab.com/handbook/business-technology/data-team/platform/infrastructure/)
diff --git a/doc/development/snowplow/schemas.md b/doc/development/snowplow/schemas.md
index 482c0e0105b..5a6cdea9fee 100644
--- a/doc/development/snowplow/schemas.md
+++ b/doc/development/snowplow/schemas.md
@@ -33,8 +33,8 @@ _\* Default value present for frontend events only_
## Default Schema
-Frontend events include a [web-specific schema](https://docs.snowplowanalytics.com/docs/understanding-your-pipeline/canonical-event/#Web-specific_fields) provided by Snowplow.
-All URLs are pseudonymized. The entity identifier [replaces](https://docs.snowplowanalytics.com/docs/collecting-data/collecting-from-own-applications/javascript-trackers/javascript-tracker/javascript-tracker-v2/tracker-setup/other-parameters-2/#Setting_a_custom_page_URL_and_referrer_URL) personally identifiable
+Frontend events include a [web-specific schema](https://docs.snowplow.io/docs/understanding-your-pipeline/canonical-event/#web-specific-fields) provided by Snowplow.
+All URLs are pseudonymized. The entity identifier [replaces](https://docs.snowplow.io/docs/collecting-data/collecting-from-own-applications/javascript-trackers/javascript-tracker/javascript-tracker-v2/tracker-setup/other-parameters-2/#setting-a-custom-page-url-and-referrer-url) personally identifiable
information (PII). PII includes usernames, group, and project names.
Page titles are hardcoded as `GitLab` for the same reason.
@@ -172,3 +172,18 @@ Page titles are hardcoded as `GitLab` for the same reason.
| `v_collector` | **{dotted-circle}** | string | Collector version |
| `v_etl` | **{dotted-circle}** | string | ETL version |
| `v_tracker` | **{dotted-circle}** | string | Identifier for Snowplow tracker |
+
+## `gitlab_service_ping`
+
+Backend events converted from ServicePing (`redis` and `redis_hll`) must include [ServicePing context](https://gitlab.com/gitlab-org/iglu/-/tree/master/public/schemas/com.gitlab/gitlab_service_ping/jsonschema)
+using the [helper class](https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/tracking/service_ping_context.rb).
+
+An example of converted `redis_hll` [event with context](https://gitlab.com/gitlab-org/gitlab/-/edit/master/app/controllers/concerns/product_analytics_tracking.rb#L58).
+
+| Field Name | Required | Type | Description |
+|---------------|:-------------------:|------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| `data_source` | **{check-circle}** | string (max 64 chars) | The `data_source` attribute from the metrics YAML definition. |
+| `event_name`* | **{dotted-circle}** | string (max 128 chars) | When there is a many-to-many relationship between events and metrics, this field contains the name of a Redis event that can be used for aggregations in downstream systems |
+| `key_path`* | **{dotted-circle}** | string (max 256 chars) | The `key_path` attribute from the metrics YAML definition |
+
+_\* Either `event_name` or `key_path` is required_
diff --git a/doc/development/testing_guide/end_to_end/rspec_metadata_tests.md b/doc/development/testing_guide/end_to_end/rspec_metadata_tests.md
index b12c6bd443a..a7d1ece77b2 100644
--- a/doc/development/testing_guide/end_to_end/rspec_metadata_tests.md
+++ b/doc/development/testing_guide/end_to_end/rspec_metadata_tests.md
@@ -36,7 +36,7 @@ This is a partial list of the [RSpec metadata](https://relishapp.com/rspec/rspec
| `:only` | The test is only to be run in specific execution contexts. See [test execution context selection](execution_context_selection.md) for more information. |
| `:orchestrated` | The GitLab instance under test may be [configured by `gitlab-qa`](https://gitlab.com/gitlab-org/gitlab-qa/-/blob/master/docs/what_tests_can_be_run.md#orchestrated-tests) to be different to the default GitLab configuration, or `gitlab-qa` may launch additional services in separate Docker containers, or both. Tests tagged with `:orchestrated` are excluded when testing environments where we can't dynamically modify the GitLab configuration (for example, Staging). |
| `:packages` | The test requires a GitLab instance that has the [Package Registry](../../../administration/packages/index.md#gitlab-package-registry-administration) enabled. |
-| `:product_group` | Specifies what product group the test belongs to. See [Product sections, stages, groups, and categories](https://about.gitlab.com/handbook/product/categories) for the comprehensive groups list. |
+| `:product_group` | Specifies what product group the test belongs to. See [Product sections, stages, groups, and categories](https://about.gitlab.com/handbook/product/categories/) for the comprehensive groups list. |
| `:quarantine` | The test has been [quarantined](https://about.gitlab.com/handbook/engineering/quality/quality-engineering/debugging-qa-test-failures/#quarantining-tests), runs in a separate job that only includes quarantined tests, and is allowed to fail. The test is skipped in its regular job so that if it fails it doesn't hold up the pipeline. Note that you can also [quarantine a test only when it runs in a specific context](execution_context_selection.md#quarantine-a-test-for-a-specific-environment). |
| `:relative_url` | The test requires a GitLab instance to be installed under a [relative URL](../../../install/relative_url.md). |
| `:reliable` | The test has been [promoted to a reliable test](https://about.gitlab.com/handbook/engineering/quality/quality-engineering/reliable-tests/#promoting-an-existing-test-to-reliable) meaning it passes consistently in all pipelines, including merge requests. |
diff --git a/doc/development/work_items.md b/doc/development/work_items.md
index eabad175bf7..b71f6e86033 100644
--- a/doc/development/work_items.md
+++ b/doc/development/work_items.md
@@ -164,13 +164,17 @@ define these various types in a very flexible manner. Having GitLab use
this system first (without introducing customer customization) allows us to
better build out the initial system.
-NOTE:
-Currently work item's `base_type` is used to define static mapping of what
+Work item's `base_type` is used to define static mapping of what
widgets are available for each type (current status), this definition should be
-rather stored in database table. The exact structure of the WIT widgets
-metadata is still to be defined. `base_type` was added to help converting other
-types of resources (requirements and incidents) into work items. Eventually (when
-these resources become regular work items), `base_type` will be removed.
+rather stored in a database table. The exact structure of the WIT widgets metadata
+is [still to be defined](https://gitlab.com/gitlab-org/gitlab/-/issues/370599).
+`base_type` was added to help convert other types of resources (requirements
+and incidents) into work items. Eventually (when these resources become regular
+work items), `base_type` will be removed.
+
+Until the architecture of WIT widgets is finalized, we are holding off on the creation of new work item
+types. If a new work item type is absolutely necessary, please reach out to a
+member of the [Project Management Engineering Team](https://gitlab.com/gitlab-org/gitlab/-/issues/370599).
### Custom work item types
diff --git a/doc/install/migrate/compare_sm_to_saas.md b/doc/install/migrate/compare_sm_to_saas.md
index e12861632b8..db5bb54386f 100644
--- a/doc/install/migrate/compare_sm_to_saas.md
+++ b/doc/install/migrate/compare_sm_to_saas.md
@@ -83,7 +83,7 @@ In a self-managed instance:
On GitLab SaaS:
-- You cannot use internal encryption key for the data store ([bring-your-own-key](https://about.gitlab.com/handbook/engineering/security/vulnerability_management/encryption-policy.html#rolling-your-own-crypto)).
+- You cannot use internal encryption key for the data store ([bring-your-own-key](https://about.gitlab.com/handbook/security/threat-management/vulnerability-management/encryption-policy.html#rolling-your-own-crypto)).
- You cannot view console logs.
- You cannot enforce jobs on every pipeline across the group or organization.
- You cannot configure or control data backups. You must use [group](../../api/group_import_export.md) and [project](../../api/project_import_export.md) export.
@@ -106,7 +106,7 @@ In a self-managed instance, you control the encryption type and configuration.
On GitLab SaaS:
-- An [Access Management Process](https://about.gitlab.com/handbook/engineering/security/#access-management-process) is in place.
+- An [Access Management Process](https://about.gitlab.com/handbook/security/#access-management-process) is in place.
- All data on GitLab.com is encrypted at rest by default. Access to encryption keys is strictly managed by GitLab.
- GitLab does not access your tenant data except as part of a verified service request from you.
diff --git a/doc/install/requirements.md b/doc/install/requirements.md
index 8a1533dc268..43d31212f03 100644
--- a/doc/install/requirements.md
+++ b/doc/install/requirements.md
@@ -299,7 +299,7 @@ GitLab supports the following web browsers:
- [Google Chrome](https://www.google.com/chrome/)
- [Chromium](https://www.chromium.org/getting-involved/dev-channel/)
- [Apple Safari](https://www.apple.com/safari/)
-- [Microsoft Edge](https://www.microsoft.com/en-us/edge)
+- [Microsoft Edge](https://www.microsoft.com/en-us/edge?form=MA13FJ)
For the listed web browsers, GitLab supports:
diff --git a/doc/integration/jenkins_deprecated.md b/doc/integration/jenkins_deprecated.md
deleted file mode 100644
index 53f7162402b..00000000000
--- a/doc/integration/jenkins_deprecated.md
+++ /dev/null
@@ -1,13 +0,0 @@
----
-stage: Manage
-group: Integrations
-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
-remove_date: '2022-10-29'
-redirect_to: 'jenkins.md'
----
-
-# Jenkins CI service (removed) **(FREE)**
-
-This feature was [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/1600)
-in GitLab 13.0.
-Use the [Jenkins integration](jenkins.md) instead.
diff --git a/doc/integration/vault.md b/doc/integration/vault.md
index ad807f9eb7a..2226dc4cfd4 100644
--- a/doc/integration/vault.md
+++ b/doc/integration/vault.md
@@ -18,7 +18,7 @@ GitLab by using our OpenID authentication feature.
## Prerequisites
-1. [Install Vault](https://www.vaultproject.io/docs/install).
+1. [Install Vault](https://developer.hashicorp.com/vault/docs/install).
1. Run Vault.
## Get the OpenID Connect client ID and secret from GitLab
@@ -29,7 +29,7 @@ for authenticating into Vault. To do this, sign in to GitLab and follow these st
1. In the top-right corner, select your avatar.
1. Select **Edit profile**.
1. On the left sidebar, select **Applications**.
-1. Fill out the application **Name** and [**Redirect URI**](https://www.vaultproject.io/docs/auth/jwt#redirect-uris).
+1. Fill out the application **Name** and [**Redirect URI**](https://developer.hashicorp.com/vault/docs/auth/jwt#redirect-uris).
1. Select the **OpenID** scope.
1. Select **Save application**.
1. Copy the **Client ID** and **Client Secret**, or keep the page open for reference.
@@ -78,7 +78,7 @@ Success! Data written to: auth/oidc/config
## Write the OIDC role configuration
-You must tell Vault the [**Redirect URIs**](https://www.vaultproject.io/docs/auth/jwt#redirect-uris)
+You must tell Vault the [**Redirect URIs**](https://developer.hashicorp.com/vault/docs/auth/jwt#redirect-uris)
and scopes given to GitLab when you created the application.
Run the following command in the terminal:
@@ -128,7 +128,7 @@ Otherwise, anyone with a public account can access your Vault instance.
## Sign in using the Vault CLI (optional)
-You can also sign into Vault using the [Vault CLI](https://www.vaultproject.io/docs/commands).
+You can also sign into Vault using the [Vault CLI](https://developer.hashicorp.com/vault/docs/commands).
1. To sign in with the role configuration you created in the previous example,
run the following command in your terminal:
@@ -143,7 +143,7 @@ You can also sign into Vault using the [Vault CLI](https://www.vaultproject.io/d
- `-method=oidc` to set Vault to use the `OIDC` sign-in method.
- `port=8250` to set the port that GitLab should redirect to. This port
number must match the port given to GitLab when listing
- [Redirect URIs](https://www.vaultproject.io/docs/auth/jwt#redirect-uris).
+ [Redirect URIs](https://developer.hashicorp.com/vault/docs/auth/jwt#redirect-uris).
After running this command, you should see a link in the terminal.
diff --git a/doc/operations/incident_management/incident_timeline_events.md b/doc/operations/incident_management/incident_timeline_events.md
index 7d31569b6a1..c35f53e1f2c 100644
--- a/doc/operations/incident_management/incident_timeline_events.md
+++ b/doc/operations/incident_management/incident_timeline_events.md
@@ -76,12 +76,12 @@ The comment is shown on the incident timeline as a timeline event.
### When incident severity changes
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/375280) in GitLab 15.6 [with a flag](../../administration/feature_flags.md) named `incident_timeline_events_for_severity`. Disabled by default.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/375280) in GitLab 15.6 [with a flag](../../administration/feature_flags.md) named `incident_timeline_events_for_severity`. Disabled by default. Enabled on GitLab.com.
FLAG:
On self-managed GitLab, by default this feature is unavailable. To show the feature per user,
ask an administrator to [enable the feature flag](../../administration/feature_flags.md) named `incident_timeline_events_for_severity`.
-On GitLab.com, this feature is not available.
+On GitLab.com, this feature is available.
This feature is not ready for production use.
A new timeline event is created when someone [changes the severity](incidents.md#change-severity)
diff --git a/doc/subscriptions/gitlab_com/index.md b/doc/subscriptions/gitlab_com/index.md
index 2ba365a237f..a1ae355a738 100644
--- a/doc/subscriptions/gitlab_com/index.md
+++ b/doc/subscriptions/gitlab_com/index.md
@@ -29,7 +29,7 @@ Members of every subgroup and project in the group:
To subscribe to GitLab SaaS:
-1. View the [GitLab SaaS feature comparison](https://about.gitlab.com/pricing/gitlab-com/feature-comparison/)
+1. View the [GitLab SaaS feature comparison](https://about.gitlab.com/pricing/feature-comparison/)
and decide which tier you want.
1. Create a user account for yourself by using the
[sign up page](https://gitlab.com/users/sign_up).
diff --git a/doc/subscriptions/gitlab_dedicated/index.md b/doc/subscriptions/gitlab_dedicated/index.md
index 441a4d2aa30..c503c501eeb 100644
--- a/doc/subscriptions/gitlab_dedicated/index.md
+++ b/doc/subscriptions/gitlab_dedicated/index.md
@@ -30,7 +30,7 @@ GitLab Dedicated enables you to offload the operational overhead of managing the
- Backups: Regular backups taken and tested.
- Choice of cloud region: Upon onboarding, choose the cloud region where you want to deploy your instance. Some AWS regions have limited features and as a result, we are not able to deploy production instances to those regions. See below for the [full list of regions](#aws-regions-not-supported) not currently supported.
- Security: Data encrypted at rest and in transit using latest encryption standards.
-- Application: Self-managed [Ultimate feature set](https://about.gitlab.com/pricing/self-managed/feature-comparison/) with the exception of the unsupported features [listed below](#features-that-are-not-available).
+- Application: Self-managed [Ultimate feature set](https://about.gitlab.com/pricing/feature-comparison/) with the exception of the unsupported features [listed below](#features-that-are-not-available).
## Features that are not available
diff --git a/doc/subscriptions/index.md b/doc/subscriptions/index.md
index 415245ee810..a571256ddea 100644
--- a/doc/subscriptions/index.md
+++ b/doc/subscriptions/index.md
@@ -177,7 +177,7 @@ For qualifying non-profit educational institutions, the [GitLab for Education Pr
### GitLab for Open Source
-For qualifying open source projects, the [GitLab for Open Source Program](https://about.gitlab.com/solutions/open-source/) provides GitLab Ultimate, plus 50,000 CI/CD minutes per month. For more information—including instructions for applying to the program and renewing program membership—see the [GitLab for Open Source Program page](https://about.gitlab.com/solutions/open-source/) and the [GitLab handbook](https://about.gitlab.com/handbook/marketing/community-relations/opensource-program/).
+For qualifying open source projects, the [GitLab for Open Source Program](https://about.gitlab.com/solutions/open-source/) provides GitLab Ultimate, plus 50,000 CI/CD minutes per month. For more information—including instructions for applying to the program and renewing program membership—see the [GitLab for Open Source Program page](https://about.gitlab.com/solutions/open-source/) and the [GitLab handbook](https://about.gitlab.com/handbook/marketing/community-relations/community-programs/opensource-program/).
#### Meeting GitLab for Open Source Program requirements
@@ -238,7 +238,7 @@ Exceptions to this public visibility requirement apply in select circumstances (
### GitLab for Startups
-For qualifying startups, the [GitLab for Startups](https://about.gitlab.com/solutions/startups/) program provides GitLab Ultimate, plus 50,000 CI/CD minutes per month for 12 months. For more information—including instructions for applying to the program and renewing program membership—see the [GitLab for Startups Program page](https://about.gitlab.com/solutions/startups/) and the [GitLab handbook](https://about.gitlab.com/handbook/marketing/community-relations/startups-program/).
+For qualifying startups, the [GitLab for Startups](https://about.gitlab.com/solutions/startups/) program provides GitLab Ultimate, plus 50,000 CI/CD minutes per month for 12 months. For more information—including instructions for applying to the program and renewing program membership—see the [GitLab for Startups Program page](https://about.gitlab.com/solutions/startups/) and the [GitLab handbook](https://about.gitlab.com/handbook/marketing/community-relations/community-programs/startups-program/).
## Contact Support
diff --git a/doc/subscriptions/self_managed/index.md b/doc/subscriptions/self_managed/index.md
index 4538e8587c9..6cfc7aee6fe 100644
--- a/doc/subscriptions/self_managed/index.md
+++ b/doc/subscriptions/self_managed/index.md
@@ -33,7 +33,7 @@ The cost of a GitLab self-managed subscription is determined by the following:
Pricing is [tier-based](https://about.gitlab.com/pricing/), so you can choose
the features that fit your budget. For information on the features available
for each tier, see the
-[GitLab self-managed feature comparison](https://about.gitlab.com/pricing/self-managed/feature-comparison/).
+[GitLab self-managed feature comparison](https://about.gitlab.com/pricing/feature-comparison/).
## Subscription seats
diff --git a/doc/user/admin_area/geo_nodes.md b/doc/user/admin_area/geo_nodes.md
deleted file mode 100644
index 710f37bb344..00000000000
--- a/doc/user/admin_area/geo_nodes.md
+++ /dev/null
@@ -1,11 +0,0 @@
----
-redirect_to: 'geo_sites.md'
-remove_date: '2022-10-05'
----
-
-This document was moved to [another location](geo_sites.md).
-
-<!-- This redirect file can be deleted after <2022-10-05>. -->
-<!-- Redirects that point to other docs in the same project expire in three months. -->
-<!-- Redirects that point to docs in a different project or site (link is not relative and starts with `https:`) expire in one year. -->
-<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
diff --git a/doc/user/admin_area/license.md b/doc/user/admin_area/license.md
index 5211a18201b..f2e2bd1a5f1 100644
--- a/doc/user/admin_area/license.md
+++ b/doc/user/admin_area/license.md
@@ -64,6 +64,6 @@ This error occurs when you use an activation code to activate your instance, but
You may have connectivity issues due to the following reasons:
-- **You have an offline environment**: Configure your setup to allow connection to GitLab servers. If connection to GitLab servers is not possible, contact [GitLab support](https://about.gitlab.com/support/#contact-support) to request a license key.
+- **You have an offline environment**: Configure your setup to allow connection to GitLab servers. If connection to GitLab servers is not possible, contact your Sales Representative to request a license key. You can also contact [GitLab support](https://about.gitlab.com/support/#contact-support) if you need help finding out your Sales Representative.
- **Firewall settings**: Enable an encrypted HTTPS connection from your GitLab instance to `customers.gitlab.com` (with IP addresses 104.18.26.123 and 104.18.27.123) on port 443.
- **Customers Portal is not operational**: To check for performance or service disruptions, check the Customers Portal [status](https://status.gitlab.com/).
diff --git a/doc/user/application_security/api_fuzzing/index.md b/doc/user/application_security/api_fuzzing/index.md
index a6ea20767db..03eed6fdbf8 100644
--- a/doc/user/application_security/api_fuzzing/index.md
+++ b/doc/user/application_security/api_fuzzing/index.md
@@ -1211,7 +1211,7 @@ Example usage for setting a `body-json` override:
}
```
-Note that each JSON property name in the object `body-json` is set to a [JSON Path](https://goessner.net/articles/JsonPath/)
+Each JSON property name in the object `body-json` is set to a [JSON Path](https://goessner.net/articles/JsonPath/)
expression. The JSON Path expression `$.credentials.access-token` identifies the node to be
overridden with the value `iddqd!42.$`. The override engine uses `body-json` when the request body
has only [JSON](https://www.json.org/json-en.html) content.
@@ -1250,7 +1250,7 @@ the second entry overrides an XML element:
}
```
-Note that each JSON property name in the object `body-xml` is set to an
+Each JSON property name in the object `body-xml` is set to an
[XPath v2](https://www.w3.org/TR/xpath20/)
expression. The XPath expression `/credentials/@isEnabled` identifies the attribute node to override
with the value `true`. The XPath expression `/credentials/access-token/text()` identifies the
@@ -1392,7 +1392,7 @@ It is also possible to write messages from your script to a log file that is col
Adding some basic logging to your overrides script is useful in case the script fails unexpectedly during normal running of the job. The log file is automatically included as an artifact of the job, allowing you to download it after the job has finished.
-Following our example, we provided `renew_token.py` in the environmental variable `FUZZAPI_OVERRIDES_CMD`. Please notice two things in the script:
+Following our example, we provided `renew_token.py` in the environmental variable `FUZZAPI_OVERRIDES_CMD`. Notice two things in the script:
- Log file is saved in the location indicated by the environment variable `CI_PROJECT_DIR`.
- Log filename should match `gl-*.log`.
@@ -1871,7 +1871,7 @@ variables:
##### Excluding two URLs and their child resources
-In order to exclude the URLs: `http://target/api/buy` and `http://target/api/sell`, and their child resources. To provide multiple URLs we use the `,` character as follows:
+To exclude the URLs: `http://target/api/buy` and `http://target/api/sell`, and their child resources. To provide multiple URLs we use the `,` character as follows:
```yaml
stages:
@@ -1888,7 +1888,11 @@ variables:
##### Excluding URL using regular expressions
-In order to exclude exactly `https://target/api/v1/user/create` and `https://target/api/v2/user/create` or any other version (`v3`,`v4`, and more). We could use `https://target/api/v.*/user/create$`, in the previous regular expression `.` indicates any character and `*` indicates zero or more times, additionally `$` indicates that the URL should end there.
+To exclude exactly `https://target/api/v1/user/create` and `https://target/api/v2/user/create` or any other version (`v3`,`v4`, and more), we could use `https://target/api/v.*/user/create$`. In the previous regular expression:
+
+- `.` indicates any character.
+- `*` indicates zero or more times.
+- `$` indicates that the URL should end there.
```yaml
stages:
@@ -2507,16 +2511,16 @@ For OpenAPI Specifications that are generated automatically validation errors ar
1. Identify the validation errors.
1. Use the [Swagger Editor](https://editor.swagger.io/) to identify validation problems in your specification. The visual nature of the Swagger Editor makes it easier to understand what needs to change.
- 1. Alternatively, you can check the log output and look for schema validation warnings. They are prefixed with messages such as `OpenAPI 2.0 schema validation error` or `OpenAPI 3.0.x schema validation error`. Each failed validation provides extra information about `location` and `description`. Note that JSON Schema validation messages might not be easy to understand. This is why we recommend the use of editors to validate schema documents.
+ 1. Alternatively, you can check the log output and look for schema validation warnings. They are prefixed with messages such as `OpenAPI 2.0 schema validation error` or `OpenAPI 3.0.x schema validation error`. Each failed validation provides extra information about `location` and `description`. JSON Schema validation messages can be complex, and editors can help you validate schema documents.
1. Review the documentation for the OpenAPI generation your framework/tech stack is using. Identify the changes needed to produce a correct OpenAPI document.
-1. Once the validation issues are resolved, re-run your pipeline.
+1. After the validation issues are resolved, re-run your pipeline.
**For manually created OpenAPI Specifications**
1. Identify the validation errors.
1. The simplest solution is to use a visual tool to edit and validate the OpenAPI document. For example the [Swagger Editor](https://editor.swagger.io/) highlights schema errors and possible solutions.
- 1. Alternatively, you can check the log output and look for schema validation warnings. They are prefixed with messages such as `OpenAPI 2.0 schema validation error` or `OpenAPI 3.0.x schema validation error`. Each failed validation provides extra information about `location` and `description`. Correct each of the validation failures and then resubmit the OpenAPI doc. Note that JSON Schema validation message might not be easy to understand. This is why we recommend the use of editors to validate document.
-1. Once the validation issues are resolved, re-run your pipeline.
+ 1. Alternatively, you can check the log output and look for schema validation warnings. They are prefixed with messages such as `OpenAPI 2.0 schema validation error` or `OpenAPI 3.0.x schema validation error`. Each failed validation provides extra information about `location` and `description`. Correct each of the validation failures and then resubmit the OpenAPI doc. JSON Schema validation messages can be complex, and editors can help you validate schema documents.
+1. After the validation issues are resolved, re-run your pipeline.
### `Failed to start scanner session (version header not found)`
@@ -2538,7 +2542,10 @@ The API Fuzzing analyzer outputs an error message when it cannot determine the t
There is an order of precedence in which the API Fuzzing analyzer tries to get the target API when checking the different sources. First, it will try to use the `FUZZAPI_TARGET_URL`. If the environment variable has not been set, then the API Fuzzing analyzer will attempt to use the `environment_url.txt` file. If there is no file `environment_url.txt`, the API Fuzzing analyzer will then use the OpenAPI document contents and the URL provided in `FUZZAPI_OPENAPI` (if a URL is provided) to try to compute the target API.
-The best-suited solution will depend on whether or not your target API changes for each deployment. In static environments, the target API is the same for each deployment, in this case please refer to the [static environment solution](#static-environment-solution). If the target API changes for each deployment a [dynamic environment solution](#dynamic-environment-solutions) should be applied.
+The best-suited solution depends on whether or not your target API changes for each deployment:
+
+- If the target API is the same for each deployment (a static environment), use the [static environment solution](#static-environment-solution).
+- If the target API changes for each deployment, use a [dynamic environment solution](#dynamic-environment-solutions).
#### Static environment solution
@@ -2643,10 +2650,10 @@ API Fuzzing uses the specified media types in the OpenAPI document to generate r
## Get support or request an improvement
-To get support for your particular problem please use the [getting help channels](https://about.gitlab.com/get-help/).
+To get support for your particular problem use the [getting help channels](https://about.gitlab.com/get-help/).
The [GitLab issue tracker on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/issues) is the right place for bugs and feature proposals about API Security and API Fuzzing.
-Please use `~"Category:API Security"` [label](../../../development/contributing/issue_workflow.md#labels) when opening a new issue regarding API fuzzing to ensure it is quickly reviewed by the right people. Please refer to our [review response SLO](https://about.gitlab.com/handbook/engineering/workflow/code-review/#review-response-slo) to understand when you should receive a response.
+Use `~"Category:API Security"` [label](../../../development/contributing/issue_workflow.md#labels) when opening a new issue regarding API fuzzing to ensure it is quickly reviewed by the right people. Refer to our [review response SLO](https://about.gitlab.com/handbook/engineering/workflow/code-review/#review-response-slo) to understand when you should receive a response.
[Search the issue tracker](https://gitlab.com/gitlab-org/gitlab/-/issues) for similar entries before submitting your own, there's a good chance somebody else had the same issue or feature proposal. Show your support with an award emoji and or join the discussion.
@@ -2658,7 +2665,7 @@ When experiencing a behavior not working as expected, consider providing context
- Scanner log file available as a job artifact named `gl-api-security-scanner.log`.
WARNING:
-**Sanitize data attached to a support issue**. Please remove sensitive information, including: credentials, passwords, tokens, keys, and secrets.
+**Sanitize data attached to a support issue**. Remove sensitive information, including: credentials, passwords, tokens, keys, and secrets.
## Glossary
diff --git a/doc/user/feature_highlight.md b/doc/user/feature_highlight.md
deleted file mode 100644
index ef96d2524a6..00000000000
--- a/doc/user/feature_highlight.md
+++ /dev/null
@@ -1,11 +0,0 @@
----
-redirect_to: 'index.md'
-remove_date: '2022-10-29'
----
-
-This document was moved to [another location](index.md).
-
-<!-- This redirect file can be deleted after <2022-10-29>. -->
-<!-- Redirects that point to other docs in the same project expire in three months. -->
-<!-- Redirects that point to docs in a different project or site (for example, link is not relative and starts with `https:`) expire in one year. -->
-<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
diff --git a/doc/user/infrastructure/clusters/manage/management_project_applications/vault.md b/doc/user/infrastructure/clusters/manage/management_project_applications/vault.md
index 72a44ef2a21..c2190ad7cfa 100644
--- a/doc/user/infrastructure/clusters/manage/management_project_applications/vault.md
+++ b/doc/user/infrastructure/clusters/manage/management_project_applications/vault.md
@@ -36,17 +36,17 @@ Vault application causes downtime.
To optimally use Vault in a production environment, it's ideal to have a good understanding
of the internals of Vault and how to configure it. This can be done by reading
the [Vault Configuration guide](../../../../../ci/secrets/index.md#configure-your-vault-server),
-the [Vault documentation](https://www.vaultproject.io/docs/internals) and
+the [Vault documentation](https://developer.hashicorp.com/vault/docs/internals) and
the Vault Helm chart [`values.yaml` file](https://github.com/hashicorp/vault-helm/blob/v0.3.3/values.yaml).
At a minimum, most users set up:
-- A [seal](https://www.vaultproject.io/docs/configuration/seal) for extra encryption
+- A [seal](https://developer.hashicorp.com/vault/docs/configuration/seal) for extra encryption
of the main key.
-- A [storage backend](https://www.vaultproject.io/docs/configuration/storage) that's
+- A [storage backend](https://developer.hashicorp.com/vault/docs/configuration/storage) that's
suitable for environment and storage security requirements.
-- [HA Mode](https://www.vaultproject.io/docs/concepts/ha).
-- The [Vault UI](https://www.vaultproject.io/docs/configuration/ui).
+- [HA Mode](https://developer.hashicorp.com/vault/docs/concepts/ha).
+- The [Vault UI](https://developer.hashicorp.com/vault/docs/configuration/ui).
The following is an example values file (`applications/vault/values.yaml`)
that configures Google Key Management Service for auto-unseal, using a Google Cloud Storage backend, enabling
@@ -86,7 +86,7 @@ server:
```
After you have successfully installed Vault, you must
-[initialize the Vault](https://learn.hashicorp.com/tutorials/vault/getting-started-deploy#initializing-the-vault)
+[initialize the Vault](https://developer.hashicorp.com/vault/tutorials/getting-started/getting-started-deploy#initializing-the-vault)
and obtain the initial root token. You need access to your Kubernetes cluster that
Vault has been deployed into to do this. To initialize the Vault, get a
shell to one of the Vault pods running inside Kubernetes (typically this is done
diff --git a/doc/user/project/clusters/kubernetes_pod_logs.md b/doc/user/project/clusters/kubernetes_pod_logs.md
deleted file mode 100644
index 51e4f1c2db2..00000000000
--- a/doc/user/project/clusters/kubernetes_pod_logs.md
+++ /dev/null
@@ -1,12 +0,0 @@
----
-stage: Monitor
-group: Respond
-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
-remove_date: '2022-10-18'
-redirect_to: '../../clusters/agent/index.md'
----
-
-# Kubernetes Logs (removed) **(FREE SELF)**
-
-This feature was [deprecated](https://gitlab.com/groups/gitlab-org/configure/-/epics/8) in GitLab 14.5
-and [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/360193) in GitLab 15.2.
diff --git a/doc/user/project/import/tfvc.md b/doc/user/project/import/tfvc.md
index 3625355340b..0a03513467e 100644
--- a/doc/user/project/import/tfvc.md
+++ b/doc/user/project/import/tfvc.md
@@ -7,7 +7,7 @@ type: concepts
# Migrate from TFVC to Git **(FREE)**
-Team Foundation Server (TFS), renamed [Azure DevOps Server](https://azure.microsoft.com/en-us/services/devops/server/)
+Team Foundation Server (TFS), renamed [Azure DevOps Server](https://azure.microsoft.com/en-us/products/devops/server/)
in 2019, is a set of tools developed by Microsoft which also includes
[Team Foundation Version Control](https://learn.microsoft.com/en-us/azure/devops/repos/tfvc/what-is-tfvc?view=azure-devops)
(TFVC), a centralized version control system similar to Git.
diff --git a/doc/user/project/pages/getting_started/pages_from_scratch.md b/doc/user/project/pages/getting_started/pages_from_scratch.md
index e34544c96f8..4825979c649 100644
--- a/doc/user/project/pages/getting_started/pages_from_scratch.md
+++ b/doc/user/project/pages/getting_started/pages_from_scratch.md
@@ -427,7 +427,7 @@ For more information, see the following blog posts.
- Use GitLab CI/CD `environments` to
[deploy your web app to staging and production](https://about.gitlab.com/blog/2021/02/05/ci-deployment-and-environments/).
- Learn how to run jobs
- [sequentially, in parallel, or build a custom pipeline](https://about.gitlab.com/blog/2016/07/29/the-basics-of-gitlab-ci/).
+ [sequentially, in parallel, or build a custom pipeline](https://about.gitlab.com/blog/2020/12/10/basics-of-gitlab-ci-updated/).
- Learn [how to pull specific directories from different projects](https://about.gitlab.com/blog/2016/12/07/building-a-new-gitlab-docs-site-with-nanoc-gitlab-ci-and-gitlab-pages/)
to deploy this website, <https://docs.gitlab.com>.
- Learn [how to use GitLab Pages to produce a code coverage report](https://about.gitlab.com/blog/2016/11/03/publish-code-coverage-report-with-gitlab-pages/).
diff --git a/doc/user/project/pages/index.md b/doc/user/project/pages/index.md
index 47c0885c26b..9305b92bf7d 100644
--- a/doc/user/project/pages/index.md
+++ b/doc/user/project/pages/index.md
@@ -107,7 +107,7 @@ These GitLab Pages website examples can teach you advanced techniques to use
and adapt for your own needs:
- [Posting to your GitLab Pages blog from iOS](https://about.gitlab.com/blog/2016/08/19/posting-to-your-gitlab-pages-blog-from-ios/).
-- [GitLab CI: Run jobs sequentially, in parallel, or build a custom pipeline](https://about.gitlab.com/blog/2016/07/29/the-basics-of-gitlab-ci/).
+- [GitLab CI: Run jobs sequentially, in parallel, or build a custom pipeline](https://about.gitlab.com/blog/2020/12/10/basics-of-gitlab-ci-updated/).
- [GitLab CI: Deployment & environments](https://about.gitlab.com/blog/2021/02/05/ci-deployment-and-environments/).
- [Building a new GitLab docs site with Nanoc, GitLab CI, and GitLab Pages](https://about.gitlab.com/blog/2016/12/07/building-a-new-gitlab-docs-site-with-nanoc-gitlab-ci-and-gitlab-pages/).
- [Publish code coverage reports with GitLab Pages](https://about.gitlab.com/blog/2016/11/03/publish-code-coverage-report-with-gitlab-pages/).
diff --git a/doc/user/usage_quotas.md b/doc/user/usage_quotas.md
index 1b265e86dd4..b2da663af4b 100644
--- a/doc/user/usage_quotas.md
+++ b/doc/user/usage_quotas.md
@@ -35,7 +35,7 @@ To prevent exceeding the namespace storage quota, you can:
- Apply for [GitLab for Education](https://about.gitlab.com/solutions/education/join/), [GitLab for Open Source](https://about.gitlab.com/solutions/open-source/join/), or [GitLab for Startups](https://about.gitlab.com/solutions/startups/) if you meet the eligibility requirements.
- Consider using a [self-managed instance](../subscriptions/self_managed/index.md) of GitLab which does not have these limits on the free tier.
- [Purchase additional storage](../subscriptions/gitlab_com/index.md#purchase-more-storage-and-transfer) units at $60/year for 10GB of storage.
-- [Start a trial](https://about.gitlab.com/free-trial/) or [upgrade to GitLab Premium or Ultimate](https://about.gitlab.com/pricing) which include higher limits and features that enable growing teams to ship faster without sacrificing on quality.
+- [Start a trial](https://about.gitlab.com/free-trial/) or [upgrade to GitLab Premium or Ultimate](https://about.gitlab.com/pricing/) which include higher limits and features that enable growing teams to ship faster without sacrificing on quality.
- [Talk to an expert](https://page.gitlab.com/usage_limits_help.html) to learn more about your options and ask questions.
### Namespace storage limit application schedule
diff --git a/lib/api/api.rb b/lib/api/api.rb
index a1868e592b6..851f4e83494 100644
--- a/lib/api/api.rb
+++ b/lib/api/api.rb
@@ -172,8 +172,10 @@ module API
mount ::API::AccessRequests
mount ::API::Appearance
mount ::API::DeployKeys
+ mount ::API::DeployTokens
mount ::API::Deployments
mount ::API::Features
+ mount ::API::FreezePeriods
mount ::API::Metadata
mount ::API::MergeRequestDiffs
mount ::API::UserCounts
@@ -222,7 +224,6 @@ module API
mount ::API::DebianGroupPackages
mount ::API::DebianProjectPackages
mount ::API::DependencyProxy
- mount ::API::DeployTokens
mount ::API::Discussions
mount ::API::Environments
mount ::API::ErrorTracking::ClientKeys
@@ -232,7 +233,6 @@ module API
mount ::API::FeatureFlags
mount ::API::FeatureFlagsUserLists
mount ::API::Files
- mount ::API::FreezePeriods
mount ::API::GenericPackages
mount ::API::Geo
mount ::API::GoProxy
diff --git a/lib/api/deploy_tokens.rb b/lib/api/deploy_tokens.rb
index 3955e29621f..37824ec7856 100644
--- a/lib/api/deploy_tokens.rb
+++ b/lib/api/deploy_tokens.rb
@@ -25,9 +25,11 @@ module API
end
end
- desc 'Return all deploy tokens' do
- detail 'This feature was introduced in GitLab 12.9.'
+ desc 'List all deploy tokens' do
+ detail 'Get a list of all deploy tokens across the GitLab instance. This endpoint requires administrator access. This feature was introduced in GitLab 12.9.'
success Entities::DeployToken
+ is_array true
+ tags %w[deploy_tokens]
end
params do
use :pagination
@@ -46,16 +48,18 @@ module API
end
params do
- requires :id, type: String, desc: 'The ID of a project'
+ requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project owned by the authenticated user'
end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
params do
use :pagination
use :filter_params
end
- desc 'List deploy tokens for a project' do
- detail 'This feature was introduced in GitLab 12.9'
+ desc 'List project deploy tokens' do
+ detail "Get a list of a project's deploy tokens. This feature was introduced in GitLab 12.9."
success Entities::DeployToken
+ is_array true
+ tags %w[deploy_tokens]
end
get ':id/deploy_tokens' do
authorize!(:read_deploy_token, user_project)
@@ -75,13 +79,14 @@ module API
type: Array[String],
coerce_with: ::API::Validations::Types::CommaSeparatedToArray.coerce,
values: ::DeployToken::AVAILABLE_SCOPES.map(&:to_s),
- desc: 'Indicates the deploy token scopes. Must be at least one of "read_repository", "read_registry", "write_registry", "read_package_registry", or "write_package_registry".'
- optional :expires_at, type: DateTime, desc: 'Expiration date for the deploy token. Does not expire if no value is provided.'
+ desc: 'Indicates the deploy token scopes. Must be at least one of `read_repository`, `read_registry`, `write_registry`, `read_package_registry`, or `write_package_registry`.'
+ optional :expires_at, type: DateTime, desc: 'Expiration date for the deploy token. Does not expire if no value is provided. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`).'
optional :username, type: String, desc: 'Username for deploy token. Default is `gitlab+deploy-token-{n}`'
end
desc 'Create a project deploy token' do
- detail 'This feature was introduced in GitLab 12.9'
+ detail 'Creates a new deploy token for a project. This feature was introduced in GitLab 12.9.'
success Entities::DeployTokenWithToken
+ tags %w[deploy_tokens]
end
post ':id/deploy_tokens' do
authorize!(:create_deploy_token, user_project)
@@ -98,11 +103,12 @@ module API
end
desc 'Get a project deploy token' do
- detail 'This feature was introduced in GitLab 14.9'
+ detail "Get a single project's deploy token by ID. This feature was introduced in GitLab 14.9."
success Entities::DeployToken
+ tags %w[deploy_tokens]
end
params do
- requires :token_id, type: Integer, desc: 'The deploy token ID'
+ requires :token_id, type: Integer, desc: 'The ID of the deploy token'
end
get ':id/deploy_tokens/:token_id' do
authorize!(:read_deploy_token, user_project)
@@ -113,10 +119,11 @@ module API
end
desc 'Delete a project deploy token' do
- detail 'This feature was introduced in GitLab 12.9'
+ detail 'This feature was introduced in GitLab 12.9.'
+ tags %w[deploy_tokens]
end
params do
- requires :token_id, type: Integer, desc: 'The deploy token ID'
+ requires :token_id, type: Integer, desc: 'The ID of the deploy token'
end
delete ':id/deploy_tokens/:token_id' do
authorize!(:destroy_deploy_token, user_project)
@@ -130,16 +137,18 @@ module API
end
params do
- requires :id, type: String, desc: 'The ID of a group'
+ requires :id, types: [Integer, String], desc: 'The ID or URL-encoded path of the group owned by the authenticated user'
end
resource :groups, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
params do
use :pagination
use :filter_params
end
- desc 'List deploy tokens for a group' do
- detail 'This feature was introduced in GitLab 12.9'
+ desc 'List group deploy tokens' do
+ detail "Get a list of a group's deploy tokens. This feature was introduced in GitLab 12.9."
success Entities::DeployToken
+ is_array true
+ tags %w[deploy_tokens]
end
get ':id/deploy_tokens' do
authorize!(:read_deploy_token, user_group)
@@ -154,18 +163,19 @@ module API
end
params do
- requires :name, type: String, desc: 'The name of the deploy token'
+ requires :name, type: String, desc: "New deploy token's name"
requires :scopes,
type: Array[String],
coerce_with: ::API::Validations::Types::CommaSeparatedToArray.coerce,
values: ::DeployToken::AVAILABLE_SCOPES.map(&:to_s),
- desc: 'Indicates the deploy token scopes. Must be at least one of "read_repository", "read_registry", "write_registry", "read_package_registry", or "write_package_registry".'
- optional :expires_at, type: DateTime, desc: 'Expiration date for the deploy token. Does not expire if no value is provided.'
+ desc: 'Indicates the deploy token scopes. Must be at least one of `read_repository`, `read_registry`, `write_registry`, `read_package_registry`, or `write_package_registry`'
+ optional :expires_at, type: DateTime, desc: 'Expiration date for the deploy token. Does not expire if no value is provided. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`)'
optional :username, type: String, desc: 'Username for deploy token. Default is `gitlab+deploy-token-{n}`'
end
desc 'Create a group deploy token' do
- detail 'This feature was introduced in GitLab 12.9'
+ detail 'Creates a new deploy token for a group. This feature was introduced in GitLab 12.9.'
success Entities::DeployTokenWithToken
+ tags %w[deploy_tokens]
end
post ':id/deploy_tokens' do
authorize!(:create_deploy_token, user_group)
@@ -182,11 +192,12 @@ module API
end
desc 'Get a group deploy token' do
- detail 'This feature was introduced in GitLab 14.9'
+ detail "Get a single group's deploy token by ID. This feature was introduced in GitLab 14.9. "
success Entities::DeployToken
+ tags %w[deploy_tokens]
end
params do
- requires :token_id, type: Integer, desc: 'The deploy token ID'
+ requires :token_id, type: Integer, desc: 'The ID of the deploy token'
end
get ':id/deploy_tokens/:token_id' do
authorize!(:read_deploy_token, user_group)
@@ -197,10 +208,11 @@ module API
end
desc 'Delete a group deploy token' do
- detail 'This feature was introduced in GitLab 12.9'
+ detail 'Removes a deploy token from the group. This feature was introduced in GitLab 12.9.'
+ tags %w[deploy_tokens]
end
params do
- requires :token_id, type: Integer, desc: 'The deploy token ID'
+ requires :token_id, type: Integer, desc: 'The ID of the deploy token'
end
delete ':id/deploy_tokens/:token_id' do
authorize!(:destroy_deploy_token, user_group)
diff --git a/lib/api/entities/freeze_period.rb b/lib/api/entities/freeze_period.rb
index 9b5f08925db..d6853c544a5 100644
--- a/lib/api/entities/freeze_period.rb
+++ b/lib/api/entities/freeze_period.rb
@@ -3,9 +3,11 @@
module API
module Entities
class FreezePeriod < Grape::Entity
- expose :id
- expose :freeze_start, :freeze_end, :cron_timezone
- expose :created_at, :updated_at
+ expose :id, documentation: { type: 'integer', example: 1 }
+ expose :freeze_start, documentation: { type: 'string', example: '0 23 * * 5' }
+ expose :freeze_end, documentation: { type: 'string', example: '0 8 * * 1' }
+ expose :cron_timezone, documentation: { type: 'string', example: 'UTC' }
+ expose :created_at, :updated_at, documentation: { type: 'dateTime', example: '2020-05-15T17:03:35.702Z' }
end
end
end
diff --git a/lib/api/freeze_periods.rb b/lib/api/freeze_periods.rb
index e69baeee97f..0e991b92901 100644
--- a/lib/api/freeze_periods.rb
+++ b/lib/api/freeze_periods.rb
@@ -4,19 +4,24 @@ module API
class FreezePeriods < ::API::Base
include PaginationParams
+ freeze_periods_tags = %w[freeze_periods]
+
before { authenticate! }
feature_category :continuous_delivery
urgency :low
params do
- requires :id, type: String, desc: 'The ID of a project'
+ requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
- desc 'Get project freeze periods' do
- detail 'This feature was introduced in GitLab 13.0.'
+ desc 'List freeze periods' do
+ detail 'Paginated list of Freeze Periods, sorted by created_at in ascending order. ' \
+ 'This feature was introduced in GitLab 13.0.'
success Entities::FreezePeriod
+ is_array true
+ tags freeze_periods_tags
end
params do
use :pagination
@@ -30,12 +35,13 @@ module API
present paginate(freeze_periods), with: Entities::FreezePeriod, current_user: current_user
end
- desc 'Get a single freeze period' do
- detail 'This feature was introduced in GitLab 13.0.'
+ desc 'Get a freeze period' do
+ detail 'Get a freeze period for the given `freeze_period_id`. This feature was introduced in GitLab 13.0.'
success Entities::FreezePeriod
+ tags freeze_periods_tags
end
params do
- requires :freeze_period_id, type: Integer, desc: 'The ID of a project freeze period'
+ requires :freeze_period_id, type: Integer, desc: 'The ID of the freeze period'
end
get ":id/freeze_periods/:freeze_period_id" do
authorize! :read_freeze_period, user_project
@@ -43,14 +49,17 @@ module API
present freeze_period, with: Entities::FreezePeriod, current_user: current_user
end
- desc 'Create a new freeze period' do
- detail 'This feature was introduced in GitLab 13.0.'
+ desc 'Create a freeze period' do
+ detail 'Creates a freeze period. This feature was introduced in GitLab 13.0.'
success Entities::FreezePeriod
+ tags freeze_periods_tags
end
params do
- requires :freeze_start, type: String, desc: 'Freeze Period start'
- requires :freeze_end, type: String, desc: 'Freeze Period end'
- optional :cron_timezone, type: String, desc: 'Timezone'
+ requires :freeze_start, type: String, desc: 'Start of the freeze period in cron format.'
+ requires :freeze_end, type: String, desc: 'End of the freeze period in cron format'
+ optional :cron_timezone,
+ type: String,
+ desc: 'The time zone for the cron fields, defaults to UTC if not provided'
end
post ':id/freeze_periods' do
authorize! :create_freeze_period, user_project
@@ -67,13 +76,14 @@ module API
end
desc 'Update a freeze period' do
- detail 'This feature was introduced in GitLab 13.0.'
+ detail 'Updates a freeze period for the given `freeze_period_id`. This feature was introduced in GitLab 13.0.'
success Entities::FreezePeriod
+ tags freeze_periods_tags
end
params do
- optional :freeze_start, type: String, desc: 'Freeze Period start'
- optional :freeze_end, type: String, desc: 'Freeze Period end'
- optional :cron_timezone, type: String, desc: 'Freeze Period Timezone'
+ optional :freeze_start, type: String, desc: 'Start of the freeze period in cron format'
+ optional :freeze_end, type: String, desc: 'End of the freeze period in cron format'
+ optional :cron_timezone, type: String, desc: 'The time zone for the cron fields'
end
put ':id/freeze_periods/:freeze_period_id' do
authorize! :update_freeze_period, user_project
@@ -88,11 +98,12 @@ module API
end
desc 'Delete a freeze period' do
- detail 'This feature was introduced in GitLab 13.0.'
+ detail 'Deletes a freeze period for the given `freeze_period_id`. This feature was introduced in GitLab 13.0.'
success Entities::FreezePeriod
+ tags freeze_periods_tags
end
params do
- requires :freeze_period_id, type: Integer, desc: 'Freeze Period ID'
+ requires :freeze_period_id, type: Integer, desc: 'The ID of the freeze period'
end
delete ':id/freeze_periods/:freeze_period_id' do
authorize! :destroy_freeze_period, user_project
diff --git a/lib/gitlab/content_security_policy/config_loader.rb b/lib/gitlab/content_security_policy/config_loader.rb
index 8648ffe5f49..2dcfd957bc6 100644
--- a/lib/gitlab/content_security_policy/config_loader.rb
+++ b/lib/gitlab/content_security_policy/config_loader.rb
@@ -24,7 +24,7 @@ module Gitlab
'frame_src' => ContentSecurityPolicy::Directives.frame_src,
'img_src' => "'self' data: blob: http: https:",
'manifest_src' => "'self'",
- 'media_src' => "'self' data:",
+ 'media_src' => "'self' data: http: https:",
'script_src' => ContentSecurityPolicy::Directives.script_src,
'style_src' => "'self' 'unsafe-inline'",
'worker_src' => "#{Gitlab::Utils.append_path(Gitlab.config.gitlab.url, 'assets/')} blob: data:",
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 5ae74752beb..f428b753f21 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -16125,9 +16125,15 @@ msgstr ""
msgid "Expected documents: %{expected_documents}"
msgstr ""
+msgid "Experiment Candidates"
+msgstr ""
+
msgid "ExperimentSubject|Must have exactly one of User, Namespace, or Project."
msgstr ""
+msgid "Experiments"
+msgstr ""
+
msgid "Expiration"
msgstr ""
@@ -16854,6 +16860,9 @@ msgstr ""
msgid "February"
msgstr ""
+msgid "Feedback and Updates"
+msgstr ""
+
msgid "Fetch and check out this merge request's feature branch:"
msgstr ""
@@ -18179,6 +18188,9 @@ msgstr ""
msgid "GitLab group: %{source_link}"
msgstr ""
+msgid "GitLab incubates features to explore new use cases. These features are updated regularly, and support is limited"
+msgstr ""
+
msgid "GitLab informs you if a new version is available. %{link_start}What information does GitLab Inc. collect?%{link_end}"
msgstr ""
@@ -24591,6 +24603,9 @@ msgstr ""
msgid "MERGED"
msgstr ""
+msgid "ML Experiments"
+msgstr ""
+
msgid "MR widget|Back to the merge request"
msgstr ""
@@ -24627,6 +24642,12 @@ msgstr ""
msgid "MRDiff|Show full file"
msgstr ""
+msgid "Machine Learning Experiment Tracking is in Incubating Phase"
+msgstr ""
+
+msgid "Machine Learning Experiments"
+msgstr ""
+
msgid "Made this %{type} confidential."
msgstr ""
@@ -26303,6 +26324,9 @@ msgstr ""
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push repositories via SSH until you add an SSH key to your profile"
msgstr ""
+msgid "MlExperimentsEmptyState|No Experiments to Show"
+msgstr ""
+
msgid "ModalButton|Add projects"
msgstr ""
@@ -41162,6 +41186,9 @@ msgstr ""
msgid "This Cron pattern is invalid"
msgstr ""
+msgid "This Experiment has no logged Candidates"
+msgstr ""
+
msgid "This GitLab instance does not provide any shared runners yet. Instance administrators can register shared runners in the admin area."
msgstr ""
diff --git a/rubocop/cop/gitlab/rspec/avoid_setup.rb b/rubocop/cop/gitlab/rspec/avoid_setup.rb
index 3b2bf079b99..fd2ed3b7e34 100644
--- a/rubocop/cop/gitlab/rspec/avoid_setup.rb
+++ b/rubocop/cop/gitlab/rspec/avoid_setup.rb
@@ -68,7 +68,7 @@ module RuboCop
NOT_ALLOWED = %i[let_it_be let_it_be_with_refind let_it_be_with_reload let let!
before after around it_behaves_like shared_examples shared_examples_for
- shared_context include_context].freeze
+ shared_context include_context subject].freeze
RESTRICT_ON_SEND = NOT_ALLOWED
diff --git a/scripts/build_assets_image b/scripts/build_assets_image
index 8aa6526061a..f480cae9a7b 100755
--- a/scripts/build_assets_image
+++ b/scripts/build_assets_image
@@ -1,36 +1,70 @@
+#!/bin/sh
+
+. scripts/utils.sh
+
# Exit early if we don't want to build the image
-if [[ "${BUILD_ASSETS_IMAGE}" != "true" ]]
+if [ "${BUILD_ASSETS_IMAGE}" != "true" ]
then
exit 0
fi
+get_repository_id() {
+ repository_name="${1}"
+ repositories_url="${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/registry/repositories"
+
+ curl --header "PRIVATE-TOKEN: ${PROJECT_TOKEN_FOR_CI_SCRIPTS_API_USAGE}" "${repositories_url}" | jq "map(select(.name == \"${repository_name}\")) | .[0].id"
+}
+
# Generate the image name based on the project this is being run in
ASSETS_IMAGE_NAME="gitlab-assets-ce"
+
# `dev.gitlab-org` still has gitlab-ee.
-if [[ "${CI_PROJECT_NAME}" == "gitlab" ]] || [[ "${CI_PROJECT_NAME}" == "gitlab-ee" ]]
+if [ "${CI_PROJECT_NAME}" = "gitlab" ] || [ "${CI_PROJECT_NAME}" = "gitlab-ee" ]
then
ASSETS_IMAGE_NAME="gitlab-assets-ee"
fi
-ASSETS_IMAGE_PATH=${CI_REGISTRY}/${CI_PROJECT_PATH}/${ASSETS_IMAGE_NAME}
-
-mkdir -p assets_container.build/public
-cp -r public/assets assets_container.build/public/
-cp Dockerfile.assets assets_container.build/
+ASSETS_IMAGE_PATH="${CI_REGISTRY}/${CI_PROJECT_PATH}/${ASSETS_IMAGE_NAME}"
+COMMIT_ASSETS_HASH_TAG="$(assets_image_tag)"
+COMMIT_ASSETS_HASH_DESTINATION="${ASSETS_IMAGE_PATH}:${COMMIT_ASSETS_HASH_TAG}"
-COMMIT_REF_SLUG_DESTINATION=${ASSETS_IMAGE_PATH}:${CI_COMMIT_REF_SLUG}
-
-COMMIT_SHA_DESTINATION=${ASSETS_IMAGE_PATH}:${CI_COMMIT_SHA}
-COMMIT_REF_NAME_DESTINATION=${ASSETS_IMAGE_PATH}:${CI_COMMIT_REF_NAME}
-
-DESTINATIONS="--destination=$COMMIT_REF_SLUG_DESTINATION --destination=$COMMIT_SHA_DESTINATION"
+DESTINATIONS="--destination=${COMMIT_ASSETS_HASH_DESTINATION}"
# Also tag the image with GitLab version, if running on a tag pipeline, so
# other projects can simply use that instead of computing the slug.
-if [ -n "$CI_COMMIT_TAG" ]; then
+if [ -n "${CI_COMMIT_TAG}" ]; then
+ COMMIT_REF_NAME_DESTINATION="${ASSETS_IMAGE_PATH}:${CI_COMMIT_REF_NAME}"
DESTINATIONS="$DESTINATIONS --destination=$COMMIT_REF_NAME_DESTINATION"
+else
+ if [ -n "${PROJECT_TOKEN_FOR_CI_SCRIPTS_API_USAGE}" ]; then
+ echoinfo "Checking if the ${COMMIT_ASSETS_HASH_DESTINATION} image exists..."
+ repository_id=$(get_repository_id "${ASSETS_IMAGE_NAME}")
+
+ if [ -n "${repository_id}" ]; then
+ api_image_url="${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/registry/repositories/${repository_id}/tags/${COMMIT_ASSETS_HASH_TAG}"
+ echoinfo "api_image_url: ${api_image_url}"
+
+ if test_url "${api_image_url}" "--header \"PRIVATE-TOKEN: ${PROJECT_TOKEN_FOR_CI_SCRIPTS_API_USAGE}\""; then
+ echosuccess "Image ${COMMIT_ASSETS_HASH_DESTINATION} already exists, no need to rebuild it."
+ exit 0
+ else
+ echoinfo "Image ${COMMIT_ASSETS_HASH_DESTINATION} doesn't exist, we'll need to build it."
+ fi
+ else
+ echoerr "Repository ID couldn't be found for the '${ASSETS_IMAGE_NAME}' image!"
+ fi
+ else
+ echoinfo "The 'PROJECT_TOKEN_FOR_CI_SCRIPTS_API_USAGE' variable is not present, so we cannot check if the image already exists."
+ fi
fi
-echo "building assets image for destinations: $DESTINATIONS"
+mkdir -p assets_container.build/public
+cp -r public/assets assets_container.build/public/
+cp Dockerfile.assets assets_container.build/
+
+echo "Building assets image for destinations: ${DESTINATIONS}"
-/kaniko/executor --context=assets_container.build --dockerfile=assets_container.build/Dockerfile.assets $DESTINATIONS
+/kaniko/executor \
+ --context="assets_container.build" \
+ --dockerfile="assets_container.build/Dockerfile.assets" \
+ ${DESTINATIONS}
diff --git a/scripts/rspec_helpers.sh b/scripts/rspec_helpers.sh
index 73030d2ad6c..3c96635896e 100644
--- a/scripts/rspec_helpers.sh
+++ b/scripts/rspec_helpers.sh
@@ -61,6 +61,9 @@ function update_tests_metadata() {
export FLAKY_RSPEC_GENERATE_REPORT="true"
scripts/merge-reports "${FLAKY_RSPEC_SUITE_REPORT_PATH}" ${rspec_flaky_folder_path}all_*.json
+
+ # Prune flaky tests that weren't flaky in the last 7 days, *after* updating the flaky tests detected
+ # in this pipeline, so that first_flaky_at for tests that are still flaky is maintained.
scripts/flaky_examples/prune-old-flaky-examples "${FLAKY_RSPEC_SUITE_REPORT_PATH}"
if [[ "$CI_PIPELINE_SOURCE" == "schedule" ]]; then
diff --git a/scripts/trigger-build.rb b/scripts/trigger-build.rb
index 897ca9f473e..1167774f500 100755
--- a/scripts/trigger-build.rb
+++ b/scripts/trigger-build.rb
@@ -160,6 +160,8 @@ module Trigger
end
class CNG < Base
+ ASSETS_HASH = "cached-assets-hash.txt"
+
def variables
# Delete variables that aren't useful when using native triggers.
super.tap do |hash|
@@ -187,7 +189,7 @@ module Trigger
"TRIGGER_BRANCH" => ref,
"GITLAB_VERSION" => ENV['CI_COMMIT_SHA'],
"GITLAB_TAG" => ENV['CI_COMMIT_TAG'], # Always set a value, even an empty string, so that the downstream pipeline can correctly check it.
- "GITLAB_ASSETS_TAG" => ENV['CI_COMMIT_TAG'] ? ENV['CI_COMMIT_REF_NAME'] : ENV['CI_COMMIT_SHA'],
+ "GITLAB_ASSETS_TAG" => assets_image_tag,
"FORCE_RAILS_IMAGE_BUILDS" => 'true',
"CE_PIPELINE" => Trigger.ee? ? nil : "true", # Always set a value, even an empty string, so that the downstream pipeline can correctly check it.
"EE_PIPELINE" => Trigger.ee? ? "true" : nil # Always set a value, even an empty string, so that the downstream pipeline can correctly check it.
@@ -204,6 +206,17 @@ module Trigger
raw_version
end
end
+
+ # We're doing the same operation in `scripts/utils.sh` in the `assets_image_tag` function.
+ def assets_image_tag
+ if ENV['CI_COMMIT_TAG']
+ ENV['CI_COMMIT_REF_NAME']
+ elsif File.exist?(ASSETS_HASH)
+ "assets-hash-#{File.read(ASSETS_HASH).strip[0...10]}"
+ else
+ ENV['CI_COMMIT_SHA']
+ end
+ end
end
class Docs < Base
diff --git a/scripts/utils.sh b/scripts/utils.sh
index ea2b390f249..5d18e724e5d 100644
--- a/scripts/utils.sh
+++ b/scripts/utils.sh
@@ -15,9 +15,11 @@ function retry() {
function test_url() {
local url="${1}"
+ local curl_args="${2}"
local status
+ local cmd="curl ${curl_args} --output /dev/null -L -s -w ''%{http_code}'' \"${url}\""
- status=$(curl --output /dev/null -L -s -w ''%{http_code}'' "${url}")
+ status=$(eval "${cmd}")
if [[ $status == "200" ]]; then
return 0
@@ -203,3 +205,15 @@ function danger_as_local() {
# We need to base SHA to help danger determine the base commit for this shallow clone.
bundle exec danger dry_run --fail-on-errors=true --verbose --base="${CI_MERGE_REQUEST_DIFF_BASE_SHA}" --head="${CI_MERGE_REQUEST_SOURCE_BRANCH_SHA:-$CI_COMMIT_SHA}" --dangerfile="${DANGER_DANGERFILE:-Dangerfile}"
}
+
+# We're doing the same operation in `scripts/trigger-build.rb` in the `assets_image_tag` method.
+function assets_image_tag() {
+ local cache_assets_hash_file="cached-assets-hash.txt"
+
+ if [[ ! -f "${cache_assets_hash_file}" ]]; then
+ echoerr "The ${cache_assets_hash_file} is missing!"
+ exit 1
+ else
+ echo -n "assets-hash-$(cat ${cache_assets_hash_file} | cut -c1-10)"
+ fi
+}
diff --git a/spec/fixtures/packages/rpm/payload.json b/spec/fixtures/packages/rpm/payload.json
index 36f8e904437..ef948c0bb6f 100644
--- a/spec/fixtures/packages/rpm/payload.json
+++ b/spec/fixtures/packages/rpm/payload.json
@@ -3,6 +3,9 @@
"/usr/bin/test",
"/usr/bin/test/hello.sh"
],
+ "directories": [
+ "/usr/bin/test/"
+ ],
"changelogs": [
{
"changelogtext": "First build",
diff --git a/spec/frontend/boards/stores/actions_spec.js b/spec/frontend/boards/stores/actions_spec.js
index 78859525a63..b3e90e34161 100644
--- a/spec/frontend/boards/stores/actions_spec.js
+++ b/spec/frontend/boards/stores/actions_spec.js
@@ -8,7 +8,6 @@ import {
ListType,
issuableTypes,
BoardType,
- listsQuery,
DraggableItemTypes,
} from 'ee_else_ce/boards/constants';
import issueMoveListMutation from 'ee_else_ce/boards/graphql/issue_move_list.mutation.graphql';
@@ -21,7 +20,7 @@ import {
getMoveData,
updateListPosition,
} from 'ee_else_ce/boards/boards_util';
-import { gqlClient } from '~/boards/graphql';
+import { defaultClient as gqlClient } from '~/graphql_shared/issuable_client';
import destroyBoardListMutation from '~/boards/graphql/board_list_destroy.mutation.graphql';
import issueCreateMutation from '~/boards/graphql/issue_create.mutation.graphql';
import actions from '~/boards/stores/actions';
@@ -318,21 +317,18 @@ describe('fetchLists', () => {
};
const variables = {
- query: listsQuery[issuableType].query,
- variables: {
- fullPath: 'gitlab-org',
- boardId: fullBoardId,
- filters: {},
- isGroup,
- isProject,
- },
+ fullPath: 'gitlab-org',
+ boardId: fullBoardId,
+ filters: {},
+ isGroup,
+ isProject,
};
jest.spyOn(gqlClient, 'query').mockResolvedValue(queryResponse);
await actions.fetchLists({ commit, state, dispatch });
- expect(gqlClient.query).toHaveBeenCalledWith(variables);
+ expect(gqlClient.query).toHaveBeenCalledWith(expect.objectContaining({ variables }));
},
);
});
diff --git a/spec/frontend/ml/experiment_tracking/components/__snapshots__/experiment_spec.js.snap b/spec/frontend/ml/experiment_tracking/components/__snapshots__/experiment_spec.js.snap
new file mode 100644
index 00000000000..2eba8869535
--- /dev/null
+++ b/spec/frontend/ml/experiment_tracking/components/__snapshots__/experiment_spec.js.snap
@@ -0,0 +1,223 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`ShowExperiment with candidates renders correctly 1`] = `
+<div>
+ <div
+ class="gl-alert gl-alert-warning"
+ >
+ <svg
+ aria-hidden="true"
+ class="gl-icon s16 gl-alert-icon"
+ data-testid="warning-icon"
+ role="img"
+ >
+ <use
+ href="#warning"
+ />
+ </svg>
+
+ <div
+ aria-live="assertive"
+ class="gl-alert-content"
+ role="alert"
+ >
+ <h2
+ class="gl-alert-title"
+ >
+ Machine Learning Experiment Tracking is in Incubating Phase
+ </h2>
+
+ <div
+ class="gl-alert-body"
+ >
+
+ GitLab incubates features to explore new use cases. These features are updated regularly, and support is limited
+
+ <a
+ class="gl-link"
+ href="https://about.gitlab.com/handbook/engineering/incubation/"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ Learn More
+ </a>
+ </div>
+
+ <div
+ class="gl-alert-actions"
+ >
+ <a
+ class="btn gl-alert-action btn-confirm btn-md gl-button"
+ href="https://gitlab.com/groups/gitlab-org/-/epics/8560"
+ >
+ <!---->
+
+ <!---->
+
+ <span
+ class="gl-button-text"
+ >
+
+ Feedback and Updates
+
+ </span>
+ </a>
+ </div>
+ </div>
+
+ <button
+ aria-label="Dismiss"
+ class="btn gl-dismiss-btn btn-default btn-sm gl-button btn-default-tertiary btn-icon"
+ type="button"
+ >
+ <!---->
+
+ <svg
+ aria-hidden="true"
+ class="gl-button-icon gl-icon s16"
+ data-testid="close-icon"
+ role="img"
+ >
+ <use
+ href="#close"
+ />
+ </svg>
+
+ <!---->
+ </button>
+ </div>
+
+ <h3>
+
+ Experiment Candidates
+
+ </h3>
+
+ <table
+ aria-busy="false"
+ aria-colcount="4"
+ class="table b-table gl-table gl-mt-0!"
+ role="table"
+ >
+ <!---->
+ <!---->
+ <thead
+ class=""
+ role="rowgroup"
+ >
+ <!---->
+ <tr
+ class=""
+ role="row"
+ >
+ <th
+ aria-colindex="1"
+ class=""
+ role="columnheader"
+ scope="col"
+ >
+ <div>
+ L1 Ratio
+ </div>
+ </th>
+ <th
+ aria-colindex="2"
+ class=""
+ role="columnheader"
+ scope="col"
+ >
+ <div>
+ Rmse
+ </div>
+ </th>
+ <th
+ aria-colindex="3"
+ class=""
+ role="columnheader"
+ scope="col"
+ >
+ <div>
+ Auc
+ </div>
+ </th>
+ <th
+ aria-colindex="4"
+ class=""
+ role="columnheader"
+ scope="col"
+ >
+ <div>
+ Mae
+ </div>
+ </th>
+ </tr>
+ </thead>
+ <tbody
+ role="rowgroup"
+ >
+ <!---->
+ <tr
+ class=""
+ role="row"
+ >
+ <td
+ aria-colindex="1"
+ class=""
+ role="cell"
+ >
+ 0.4
+ </td>
+ <td
+ aria-colindex="2"
+ class=""
+ role="cell"
+ >
+ 1
+ </td>
+ <td
+ aria-colindex="3"
+ class=""
+ role="cell"
+ />
+ <td
+ aria-colindex="4"
+ class=""
+ role="cell"
+ />
+ </tr>
+ <tr
+ class=""
+ role="row"
+ >
+ <td
+ aria-colindex="1"
+ class=""
+ role="cell"
+ >
+ 0.5
+ </td>
+ <td
+ aria-colindex="2"
+ class=""
+ role="cell"
+ />
+ <td
+ aria-colindex="3"
+ class=""
+ role="cell"
+ >
+ 0.3
+ </td>
+ <td
+ aria-colindex="4"
+ class=""
+ role="cell"
+ />
+ </tr>
+ <!---->
+ <!---->
+ </tbody>
+ <!---->
+ </table>
+</div>
+`;
diff --git a/spec/frontend/ml/experiment_tracking/components/experiment_spec.js b/spec/frontend/ml/experiment_tracking/components/experiment_spec.js
new file mode 100644
index 00000000000..af722d77532
--- /dev/null
+++ b/spec/frontend/ml/experiment_tracking/components/experiment_spec.js
@@ -0,0 +1,44 @@
+import { GlAlert } from '@gitlab/ui';
+import { mountExtended } from 'helpers/vue_test_utils_helper';
+import ShowExperiment from '~/ml/experiment_tracking/components/experiment.vue';
+
+describe('ShowExperiment', () => {
+ let wrapper;
+
+ const createWrapper = (candidates = [], metricNames = [], paramNames = []) => {
+ return mountExtended(ShowExperiment, { provide: { candidates, metricNames, paramNames } });
+ };
+
+ const findAlert = () => wrapper.findComponent(GlAlert);
+
+ const findEmptyState = () => wrapper.findByText('This Experiment has no logged Candidates');
+
+ it('shows incubation warning', () => {
+ wrapper = createWrapper();
+
+ expect(findAlert().exists()).toBe(true);
+ });
+
+ describe('no candidates', () => {
+ it('shows empty state', () => {
+ wrapper = createWrapper();
+
+ expect(findEmptyState().exists()).toBe(true);
+ });
+ });
+
+ describe('with candidates', () => {
+ it('renders correctly', () => {
+ wrapper = createWrapper(
+ [
+ { rmse: 1, l1_ratio: 0.4 },
+ { auc: 0.3, l1_ratio: 0.5 },
+ ],
+ ['rmse', 'auc', 'mae'],
+ ['l1_ratio'],
+ );
+
+ expect(wrapper.element).toMatchSnapshot();
+ });
+ });
+});
diff --git a/spec/frontend/ml/experiment_tracking/components/incubation_alert_spec.js b/spec/frontend/ml/experiment_tracking/components/incubation_alert_spec.js
new file mode 100644
index 00000000000..e07a4ed816b
--- /dev/null
+++ b/spec/frontend/ml/experiment_tracking/components/incubation_alert_spec.js
@@ -0,0 +1,27 @@
+import { mount } from '@vue/test-utils';
+import { GlAlert, GlButton } from '@gitlab/ui';
+import IncubationAlert from '~/ml/experiment_tracking/components/incubation_alert.vue';
+
+describe('IncubationAlert', () => {
+ let wrapper;
+
+ const findAlert = () => wrapper.findComponent(GlAlert);
+
+ const findButton = () => wrapper.findComponent(GlButton);
+
+ beforeEach(() => {
+ wrapper = mount(IncubationAlert);
+ });
+
+ it('displays link to issue', () => {
+ expect(findButton().attributes().href).toBe(
+ 'https://gitlab.com/groups/gitlab-org/-/epics/8560',
+ );
+ });
+
+ it('is removed if dismissed', async () => {
+ await wrapper.find('[aria-label="Dismiss"]').trigger('click');
+
+ expect(findAlert().exists()).toBe(false);
+ });
+});
diff --git a/spec/frontend/work_items/components/work_item_assignees_spec.js b/spec/frontend/work_items/components/work_item_assignees_spec.js
index 1b204b6fd60..7367212e49f 100644
--- a/spec/frontend/work_items/components/work_item_assignees_spec.js
+++ b/spec/frontend/work_items/components/work_item_assignees_spec.js
@@ -8,7 +8,7 @@ import { mockTracking } from 'helpers/tracking_helper';
import { DEFAULT_DEBOUNCE_AND_THROTTLE_MS } from '~/lib/utils/constants';
import userSearchQuery from '~/graphql_shared/queries/users_search.query.graphql';
import currentUserQuery from '~/graphql_shared/queries/current_user.query.graphql';
-import { temporaryConfig } from '~/graphql_shared/issuable_client';
+import { config } from '~/graphql_shared/issuable_client';
import InviteMembersTrigger from '~/invite_members/components/invite_members_trigger.vue';
import workItemQuery from '~/work_items/graphql/work_item.query.graphql';
import updateWorkItemMutation from '~/work_items/graphql/update_work_item.mutation.graphql';
@@ -86,7 +86,7 @@ describe('WorkItemAssignees component', () => {
],
{},
{
- typePolicies: temporaryConfig.cacheConfig.typePolicies,
+ typePolicies: config.cacheConfig.typePolicies,
},
);
diff --git a/spec/frontend/work_items/components/work_item_detail_spec.js b/spec/frontend/work_items/components/work_item_detail_spec.js
index aae61b11196..1e22fb42a83 100644
--- a/spec/frontend/work_items/components/work_item_detail_spec.js
+++ b/spec/frontend/work_items/components/work_item_detail_spec.js
@@ -29,7 +29,7 @@ import workItemTitleSubscription from '~/work_items/graphql/work_item_title.subs
import workItemAssigneesSubscription from '~/work_items/graphql/work_item_assignees.subscription.graphql';
import updateWorkItemMutation from '~/work_items/graphql/update_work_item.mutation.graphql';
import updateWorkItemTaskMutation from '~/work_items/graphql/update_work_item_task.mutation.graphql';
-import { temporaryConfig } from '~/graphql_shared/issuable_client';
+import { config } from '~/graphql_shared/issuable_client';
import { useLocalStorageSpy } from 'helpers/local_storage_helper';
import {
mockParent,
@@ -101,7 +101,7 @@ describe('WorkItemDetail component', () => {
handlers,
{},
{
- typePolicies: includeWidgets ? temporaryConfig.cacheConfig.typePolicies : {},
+ typePolicies: includeWidgets ? config.cacheConfig.typePolicies : {},
},
),
propsData: { isModal, workItemId },
diff --git a/spec/frontend/work_items/components/work_item_milestone_spec.js b/spec/frontend/work_items/components/work_item_milestone_spec.js
index 08cdf62ae52..e5713efdbec 100644
--- a/spec/frontend/work_items/components/work_item_milestone_spec.js
+++ b/spec/frontend/work_items/components/work_item_milestone_spec.js
@@ -9,7 +9,7 @@ import {
import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
import WorkItemMilestone from '~/work_items/components/work_item_milestone.vue';
-import { resolvers, temporaryConfig } from '~/graphql_shared/issuable_client';
+import { resolvers, config } from '~/graphql_shared/issuable_client';
import createMockApollo from 'helpers/mock_apollo_helper';
import { mockTracking } from 'helpers/tracking_helper';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
@@ -72,7 +72,7 @@ describe('WorkItemMilestone component', () => {
[[projectMilestonesQuery, searchQueryHandler]],
resolvers,
{
- typePolicies: temporaryConfig.cacheConfig.typePolicies,
+ typePolicies: config.cacheConfig.typePolicies,
},
);
diff --git a/spec/helpers/markup_helper_spec.rb b/spec/helpers/markup_helper_spec.rb
index a2e34471324..0b3d400041c 100644
--- a/spec/helpers/markup_helper_spec.rb
+++ b/spec/helpers/markup_helper_spec.rb
@@ -332,8 +332,8 @@ RSpec.describe MarkupHelper do
context 'when file is Markdown' do
let(:extension) { 'md' }
- it 'renders using #markdown_unsafe helper method' do
- expect(helper).to receive(:markdown_unsafe).with('wiki content', context)
+ it 'renders using CommonMark method' do
+ expect(Banzai).to receive(:render).with('wiki content', context)
helper.render_wiki_content(wiki_page)
end
@@ -377,24 +377,16 @@ RSpec.describe MarkupHelper do
end
end
- context 'when file is Kramdown' do
+ context 'when file is R Markdown' do
let(:extension) { 'rmd' }
- let(:content) do
- <<-EOF
-{::options parse_block_html="true" /}
-
-<div>
-FooBar
-</div>
- EOF
- end
+ let(:content) { '## Header' }
- it 'renders using #markdown_unsafe helper method' do
- expect(helper).to receive(:markdown_unsafe).with(content, context)
+ it 'renders using CommonMark method' do
+ expect(Markup::RenderingService).to receive(:new).and_call_original
result = helper.render_wiki_content(wiki_page)
- expect(result).to be_empty
+ expect(result).to include('Header</h2>')
end
end
@@ -424,23 +416,9 @@ FooBar
expect(helper.markup('foo.rst', content).encoding.name).to eq('UTF-8')
end
- it 'delegates to #markdown_unsafe when file name corresponds to Markdown' do
- expect(Gitlab::MarkupHelper).to receive(:gitlab_markdown?).with('foo.md').and_return(true)
- expect(helper).to receive(:markdown_unsafe).and_return('NOEL')
-
- expect(helper.markup('foo.md', content)).to eq('NOEL')
- end
-
- it 'delegates to #asciidoc_unsafe when file name corresponds to AsciiDoc' do
- expect(Gitlab::MarkupHelper).to receive(:asciidoc?).with('foo.adoc').and_return(true)
- expect(helper).to receive(:asciidoc_unsafe).and_return('NOEL')
-
- expect(helper.markup('foo.adoc', content)).to eq('NOEL')
- end
-
it 'uses passed in rendered content' do
expect(Gitlab::MarkupHelper).not_to receive(:gitlab_markdown?)
- expect(helper).not_to receive(:markdown_unsafe)
+ expect(Markup::RenderingService).not_to receive(:execute)
expect(helper.markup('foo.md', content, rendered: '<p>NOEL</p>')).to eq('<p>NOEL</p>')
end
@@ -448,113 +426,18 @@ FooBar
it 'defaults to CommonMark' do
expect(helper.markup('foo.md', 'x^2')).to include('x^2')
end
- end
-
- describe '#markup_unsafe' do
- subject { helper.markup_unsafe(file_name, text, context) }
-
- let_it_be(:project_base) { create(:project, :repository) }
- let_it_be(:context) { { project: project_base } }
-
- let(:file_name) { 'foo.bar' }
- let(:text) { 'Noël' }
-
- context 'when text is missing' do
- let(:text) { nil }
-
- it 'returns an empty string' do
- is_expected.to eq('')
- end
- end
-
- context 'when rendering takes too long' do
- before do
- stub_const("MarkupHelper::RENDER_TIMEOUT", 0.1)
- allow(Gitlab::OtherMarkup).to receive(:render) { sleep(0.2) }
- end
-
- it 'times out' do
- expect(Gitlab::RenderTimeout).to receive(:timeout).and_call_original
- expect(Gitlab::ErrorTracking).to receive(:track_exception).with(
- instance_of(Timeout::Error),
- project_id: project.id, file_name: file_name
- )
-
- subject
- end
-
- context 'when markup_rendering_timeout is disabled' do
- it 'waits until the execution completes' do
- stub_feature_flags(markup_rendering_timeout: false)
-
- expect(Gitlab::RenderTimeout).not_to receive(:timeout)
-
- subject
- end
- end
- end
-
- context 'when file is a markdown file' do
- let(:file_name) { 'foo.md' }
- it 'returns html (rendered by Banzai)' do
- expected_html = '<p data-sourcepos="1:1-1:5" dir="auto">Noël</p>'
-
- expect(Banzai).to receive(:render).with(text, context) { expected_html }
-
- is_expected.to eq(expected_html)
- end
-
- context 'when renderer returns an error' do
- before do
- allow(Banzai).to receive(:render).and_raise(StandardError, "An error")
- end
-
- it 'returns html (rendered by ActionView:TextHelper)' do
- is_expected.to eq('<p>Noël</p>')
- end
-
- it 'logs the error' do
- expect(Gitlab::ErrorTracking).to receive(:track_exception).with(
- instance_of(StandardError),
- project_id: project.id, file_name: 'foo.md'
- )
-
- subject
- end
- end
- end
-
- context 'when file is asciidoc file' do
- let(:file_name) { 'foo.adoc' }
-
- it 'returns html (rendered by Gitlab::Asciidoc)' do
- expected_html = "<div>\n<p>Noël</p>\n</div>"
-
- expect(Gitlab::Asciidoc).to receive(:render).with(text, context) { expected_html }
-
- is_expected.to eq(expected_html)
- end
- end
-
- context 'when file is a regular text file' do
- let(:file_name) { 'foo.txt' }
-
- it 'returns html (rendered by ActionView::TagHelper)' do
- is_expected.to eq('<pre class="plain-readme">Noël</pre>')
- end
- end
-
- context 'when file has an unknown type' do
- let(:file_name) { 'foo.tex' }
+ it 'sets additional context for Asciidoc' do
+ context = {}
+ assign(:commit, commit)
+ assign(:ref, 'ref')
+ assign(:path, 'path')
- it 'returns html (rendered by Gitlab::OtherMarkup)' do
- expected_html = 'Noël'
+ expect(Gitlab::Asciidoc).to receive(:render)
- expect(Gitlab::OtherMarkup).to receive(:render).with(file_name, text, context) { expected_html }
+ helper.markup('foo.adoc', content, context)
- is_expected.to eq(expected_html)
- end
+ expect(context).to include(commit: commit, ref: 'ref', requested_path: 'path')
end
end
diff --git a/spec/helpers/projects/ml/experiments_helper_spec.rb b/spec/helpers/projects/ml/experiments_helper_spec.rb
new file mode 100644
index 00000000000..e4421ff7606
--- /dev/null
+++ b/spec/helpers/projects/ml/experiments_helper_spec.rb
@@ -0,0 +1,49 @@
+# frozen_string_literal: true
+
+require 'rspec'
+
+require 'spec_helper'
+require 'mime/types'
+
+RSpec.describe Projects::Ml::ExperimentsHelper do
+ let_it_be(:project) { build(:project, :private) }
+ let_it_be(:experiment) { build(:ml_experiments, user_id: project.creator, project: project) }
+ let_it_be(:candidates) do
+ create_list(:ml_candidates, 2, experiment: experiment, user: project.creator).tap do |c|
+ c[0].params.create!([{ name: 'param1', value: 'p1' }, { name: 'param2', value: 'p2' }])
+ c[0].metrics.create!(
+ [{ name: 'metric1', value: 0.1 }, { name: 'metric2', value: 0.2 }, { name: 'metric3', value: 0.3 }]
+ )
+
+ c[1].params.create!([{ name: 'param2', value: 'p3' }, { name: 'param3', value: 'p4' }])
+ c[1].metrics.create!(name: 'metric3', value: 0.4)
+ end
+ end
+
+ describe '#candidates_table_items' do
+ subject { helper.candidates_table_items(candidates) }
+
+ it 'creates the correct model for the table' do
+ expected_value = [
+ { 'param1' => 'p1', 'param2' => 'p2', 'metric1' => '0.1000', 'metric2' => '0.2000', 'metric3' => '0.3000' },
+ { 'param2' => 'p3', 'param3' => 'p4', 'metric3' => '0.4000' }
+ ]
+
+ expect(Gitlab::Json.parse(subject)).to match_array(expected_value)
+ end
+ end
+
+ describe '#unique_logged_names' do
+ context 'when for params' do
+ subject { Gitlab::Json.parse(helper.unique_logged_names(candidates, &:params)) }
+
+ it { is_expected.to match_array(%w[param1 param2 param3]) }
+ end
+
+ context 'when latest_metrics is passed' do
+ subject { Gitlab::Json.parse(helper.unique_logged_names(candidates, &:latest_metrics)) }
+
+ it { is_expected.to match_array(%w[metric1 metric2 metric3]) }
+ end
+ end
+end
diff --git a/spec/lib/gitlab/content_security_policy/config_loader_spec.rb b/spec/lib/gitlab/content_security_policy/config_loader_spec.rb
index 616fe15c1a6..47745eaa4af 100644
--- a/spec/lib/gitlab/content_security_policy/config_loader_spec.rb
+++ b/spec/lib/gitlab/content_security_policy/config_loader_spec.rb
@@ -53,6 +53,18 @@ RSpec.describe Gitlab::ContentSecurityPolicy::ConfigLoader do
expect(directives['child_src']).to eq("#{directives['frame_src']} #{directives['worker_src']}")
end
+ describe 'the images-src directive' do
+ it 'can be loaded from anywhere' do
+ expect(directives['img_src']).to include('http: https:')
+ end
+ end
+
+ describe 'the media-src directive' do
+ it 'can be loaded from anywhere' do
+ expect(directives['media_src']).to include('http: https:')
+ end
+ end
+
context 'adds all websocket origins to support Safari' do
it 'with insecure domain' do
stub_config_setting(host: 'example.com', https: false)
diff --git a/spec/models/ml/candidate_metric_spec.rb b/spec/models/ml/candidate_metric_spec.rb
index 5ee6030fb8e..9f9a6e8e3ba 100644
--- a/spec/models/ml/candidate_metric_spec.rb
+++ b/spec/models/ml/candidate_metric_spec.rb
@@ -6,4 +6,17 @@ RSpec.describe Ml::CandidateMetric do
describe 'associations' do
it { is_expected.to belong_to(:candidate) }
end
+
+ describe 'scope :latest' do
+ let_it_be(:candidate) { create(:ml_candidates) }
+ let!(:metric1) { create(:ml_candidate_metrics, candidate: candidate) }
+ let!(:metric2) { create(:ml_candidate_metrics, candidate: candidate ) }
+ let!(:metric3) { create(:ml_candidate_metrics, name: metric1.name, candidate: candidate) }
+
+ subject { described_class.latest }
+
+ it 'fetches only the last metric for the name' do
+ expect(subject).to match_array([metric2, metric3] )
+ end
+ end
end
diff --git a/spec/models/ml/candidate_spec.rb b/spec/models/ml/candidate_spec.rb
index 84e0e6be199..d08dc35b358 100644
--- a/spec/models/ml/candidate_spec.rb
+++ b/spec/models/ml/candidate_spec.rb
@@ -46,4 +46,26 @@ RSpec.describe Ml::Candidate, factory_default: :keep do
it { is_expected.to be_nil }
end
end
+
+ describe "#latest_metrics" do
+ let_it_be(:candidate2) { create(:ml_candidates, experiment: candidate.experiment) }
+ let!(:metric1) { create(:ml_candidate_metrics, candidate: candidate2) }
+ let!(:metric2) { create(:ml_candidate_metrics, candidate: candidate2 ) }
+ let!(:metric3) { create(:ml_candidate_metrics, name: metric1.name, candidate: candidate2) }
+
+ subject { candidate2.latest_metrics }
+
+ it 'fetches only the last metric for the name' do
+ expect(subject).to match_array([metric2, metric3] )
+ end
+ end
+
+ describe "#including_metrics_and_params" do
+ subject { described_class.including_metrics_and_params.find_by(id: candidate.id) }
+
+ it 'loads latest metrics and params', :aggregate_failures do
+ expect(subject.association_cached?(:latest_metrics)).to be(true)
+ expect(subject.association_cached?(:params)).to be(true)
+ end
+ end
end
diff --git a/spec/requests/projects/ml/experiments_controller_spec.rb b/spec/requests/projects/ml/experiments_controller_spec.rb
new file mode 100644
index 00000000000..7be5899fcbe
--- /dev/null
+++ b/spec/requests/projects/ml/experiments_controller_spec.rb
@@ -0,0 +1,86 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Projects::Ml::ExperimentsController do
+ let_it_be(:project) { create(:project, :repository) }
+ let_it_be(:user) { project.first_owner }
+ let_it_be(:basic_params) { { namespace_id: project.namespace.to_param, project_id: project } }
+ let_it_be(:experiment) do
+ create(:ml_experiments, project: project, user: user).tap do |e|
+ create(:ml_candidates, experiment: e, user: user)
+ end
+ end
+
+ let(:params) { basic_params }
+ let(:ff_value) { true }
+ let(:threshold) { 4 }
+
+ before do
+ stub_feature_flags(ml_experiment_tracking: ff_value)
+
+ sign_in(user)
+ end
+
+ shared_examples '404 if feature flag disabled' do
+ context 'when :ml_experiment_tracking disabled' do
+ let(:ff_value) { false }
+
+ it 'is 404' do
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+ end
+
+ describe 'GET index' do
+ before do
+ list_experiments
+ end
+
+ it 'renders the template' do
+ expect(response).to render_template('projects/ml/experiments/index')
+ end
+
+ it 'does not perform N+1 sql queries' do
+ control_count = ActiveRecord::QueryRecorder.new { list_experiments }
+
+ create_list(:ml_experiments, 2, project: project, user: user)
+
+ expect { list_experiments }.not_to exceed_all_query_limit(control_count).with_threshold(threshold)
+ end
+
+ it_behaves_like '404 if feature flag disabled'
+ end
+
+ describe 'GET show' do
+ let(:params) { basic_params.merge(id: experiment.iid) }
+
+ before do
+ show_experiment
+ end
+
+ it 'renders the template' do
+ expect(response).to render_template('projects/ml/experiments/show')
+ end
+
+ it 'does not perform N+1 sql queries' do
+ control_count = ActiveRecord::QueryRecorder.new { show_experiment }
+
+ create_list(:ml_candidates, 2, :with_metrics_and_params, experiment: experiment)
+
+ expect { show_experiment }.not_to exceed_all_query_limit(control_count).with_threshold(threshold)
+ end
+
+ it_behaves_like '404 if feature flag disabled'
+ end
+
+ private
+
+ def show_experiment
+ get project_ml_experiment_path(project, experiment.iid), params: params
+ end
+
+ def list_experiments
+ get project_ml_experiments_path(project), params: params
+ end
+end
diff --git a/spec/scripts/trigger-build_spec.rb b/spec/scripts/trigger-build_spec.rb
index ac8e3c7797c..758336d251d 100644
--- a/spec/scripts/trigger-build_spec.rb
+++ b/spec/scripts/trigger-build_spec.rb
@@ -337,6 +337,29 @@ RSpec.describe Trigger do
it 'sets GITLAB_ASSETS_TAG to CI_COMMIT_SHA' do
expect(subject.variables['GITLAB_ASSETS_TAG']).to eq(env['CI_COMMIT_SHA'])
end
+
+ context 'when cached-assets-hash.txt does not exist' do
+ before do
+ expect(File).to receive(:exist?).with('cached-assets-hash.txt').and_return(false)
+ end
+
+ it 'sets GITLAB_ASSETS_TAG to CI_COMMIT_SHA' do
+ expect(subject.variables['GITLAB_ASSETS_TAG']).to eq(env['CI_COMMIT_SHA'])
+ end
+ end
+
+ context 'when cached-assets-hash.txt exists' do
+ before do
+ allow(File).to receive(:exist?).and_call_original
+ allow(File).to receive(:read).and_call_original
+ expect(File).to receive(:exist?).with('cached-assets-hash.txt').and_return(true)
+ expect(File).to receive(:read).with('cached-assets-hash.txt').and_return("42")
+ end
+
+ it 'sets GITLAB_ASSETS_TAG to CI_COMMIT_SHA' do
+ expect(subject.variables['GITLAB_ASSETS_TAG']).to eq("assets-hash-42")
+ end
+ end
end
end
diff --git a/spec/services/markup/rendering_service_spec.rb b/spec/services/markup/rendering_service_spec.rb
new file mode 100644
index 00000000000..a5711a8cbc4
--- /dev/null
+++ b/spec/services/markup/rendering_service_spec.rb
@@ -0,0 +1,163 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Markup::RenderingService do
+ describe '#execute' do
+ let_it_be(:project) { create(:project, :repository) }
+ let_it_be(:user) do
+ user = create(:user, username: 'gfm')
+ project.add_maintainer(user)
+ user
+ end
+
+ let_it_be(:context) { { project: project } }
+ let_it_be(:postprocess_context) { { current_user: user } }
+
+ let(:file_name) { nil }
+ let(:text) { 'Noël' }
+
+ subject do
+ described_class
+ .new(text, file_name: file_name, context: context, postprocess_context: postprocess_context)
+ .execute
+ end
+
+ context 'when text is missing' do
+ let(:text) { nil }
+
+ it 'returns an empty string' do
+ is_expected.to eq('')
+ end
+ end
+
+ context 'when file_name is missing' do
+ it 'returns html (rendered by Banzai)' do
+ expected_html = '<p data-sourcepos="1:1-1:5" dir="auto">Noël</p>'
+
+ expect(Banzai).to receive(:render).with(text, context) { expected_html }
+
+ is_expected.to eq(expected_html)
+ end
+ end
+
+ context 'when postprocess_context is missing' do
+ let(:file_name) { 'foo.txt' }
+ let(:postprocess_context) { nil }
+
+ it 'returns html (rendered by Banzai)' do
+ expected_html = '<pre class="plain-readme">Noël</pre>'
+
+ expect(Banzai).not_to receive(:post_process) { expected_html }
+
+ is_expected.to eq(expected_html)
+ end
+ end
+
+ context 'when rendered context is present' do
+ let(:rendered) { 'rendered text' }
+ let(:file_name) { 'foo.md' }
+
+ it 'returns an empty string' do
+ context[:rendered] = rendered
+
+ is_expected.to eq(rendered)
+ end
+ end
+
+ context 'when file is a markdown file' do
+ let(:file_name) { 'foo.md' }
+
+ it 'returns html (rendered by Banzai)' do
+ expected_html = '<p data-sourcepos="1:1-1:5" dir="auto">Noël</p>'
+
+ expect(Banzai).to receive(:render).with(text, context) { expected_html }
+
+ is_expected.to eq(expected_html)
+ end
+
+ context 'when renderer returns an error' do
+ before do
+ allow(Banzai).to receive(:render).and_raise(StandardError, "An error")
+ end
+
+ it 'returns html (rendered by ActionView:TextHelper)' do
+ is_expected.to eq('<p>Noël</p>')
+ end
+
+ it 'logs the error' do
+ expect(Gitlab::ErrorTracking).to receive(:track_exception).with(
+ instance_of(StandardError),
+ project_id: context[:project].id, file_name: 'foo.md'
+ )
+
+ subject
+ end
+ end
+ end
+
+ context 'when file is asciidoc file' do
+ let(:file_name) { 'foo.adoc' }
+
+ it 'returns html (rendered by Gitlab::Asciidoc)' do
+ expected_html = "<div>\n<p>Noël</p>\n</div>"
+
+ expect(Gitlab::Asciidoc).to receive(:render).with(text, context) { expected_html }
+
+ is_expected.to eq(expected_html)
+ end
+ end
+
+ context 'when file is a regular text file' do
+ let(:file_name) { 'foo.txt' }
+
+ it 'returns html (rendered by ActionView::TagHelper)' do
+ is_expected.to eq('<pre class="plain-readme">Noël</pre>')
+ end
+ end
+
+ context 'when file has an unknown type' do
+ let(:file_name) { 'foo.tex' }
+
+ it 'returns html (rendered by Gitlab::OtherMarkup)' do
+ expected_html = 'Noël'
+
+ expect(Gitlab::OtherMarkup).to receive(:render).with(file_name, text, context) { expected_html }
+
+ is_expected.to eq(expected_html)
+ end
+ end
+
+ context 'when rendering takes too long' do
+ let(:file_name) { 'foo.bar' }
+
+ before do
+ stub_const("Markup::RenderingService::RENDER_TIMEOUT", 0.1)
+ allow(Gitlab::OtherMarkup).to receive(:render) do
+ sleep(0.2)
+ text
+ end
+ end
+
+ it 'times out' do
+ expect(Gitlab::RenderTimeout).to receive(:timeout).and_call_original
+ expect(Gitlab::ErrorTracking).to receive(:track_exception).with(
+ instance_of(Timeout::Error),
+ project_id: context[:project].id, file_name: file_name
+ )
+
+ is_expected.to eq("<p>#{text}</p>")
+ end
+
+ context 'when markup_rendering_timeout is disabled' do
+ it 'waits until the execution completes' do
+ stub_feature_flags(markup_rendering_timeout: false)
+
+ expect(Gitlab::RenderTimeout).not_to receive(:timeout)
+
+ is_expected.to eq(text)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/services/packages/rpm/repository_metadata/build_filelist_xml_service_spec.rb b/spec/services/packages/rpm/repository_metadata/build_filelist_xml_service_spec.rb
new file mode 100644
index 00000000000..d93d6ab9fcb
--- /dev/null
+++ b/spec/services/packages/rpm/repository_metadata/build_filelist_xml_service_spec.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+RSpec.describe Packages::Rpm::RepositoryMetadata::BuildFilelistXmlService do
+ describe '#execute' do
+ subject { described_class.new(data).execute }
+
+ include_context 'with rpm package data'
+
+ let(:data) { xml_update_params }
+ let(:file_xpath) { "//package/file" }
+
+ it 'adds all file nodes' do
+ result = subject
+
+ expect(result.xpath(file_xpath).count).to eq(data[:files].count)
+ end
+
+ describe 'setting type attribute' do
+ context 'when all files are directories' do
+ let(:dirs) do
+ 3.times.map { generate_directory } # rubocop:disable Performance/TimesMap
+ end
+
+ let(:files) do
+ 5.times.map { FFaker::Filesystem.file_name(dirs.sample) } # rubocop:disable Performance/TimesMap
+ end
+
+ let(:data) do
+ {
+ directories: dirs.map { "#{_1}/" }, # Add trailing slash as in original package
+ files: dirs + files
+ }
+ end
+
+ it 'set dir type attribute for directories only' do
+ result = subject
+
+ result.xpath(file_xpath).each do |tag|
+ if dirs.include?(tag.content)
+ expect(tag.attributes['type']&.value).to eq('dir')
+ else
+ expect(tag.attributes['type']).to be_nil
+ end
+ end
+ end
+ end
+
+ def generate_directory
+ FFaker::Lorem.words(3).join('/')
+ end
+ end
+ end
+end
diff --git a/spec/services/packages/rpm/repository_metadata/build_other_xml_service_spec.rb b/spec/services/packages/rpm/repository_metadata/build_other_xml_service_spec.rb
index 19080b8dfd0..201f9e67ce9 100644
--- a/spec/services/packages/rpm/repository_metadata/build_other_xml_service_spec.rb
+++ b/spec/services/packages/rpm/repository_metadata/build_other_xml_service_spec.rb
@@ -5,24 +5,22 @@ RSpec.describe Packages::Rpm::RepositoryMetadata::BuildOtherXmlService do
describe '#execute' do
subject { described_class.new(data).execute }
- context 'when updating existing xml' do
- include_context 'with rpm package data'
+ include_context 'with rpm package data'
- let(:data) { xml_update_params }
- let(:changelog_xpath) { "//package/changelog" }
+ let(:data) { xml_update_params }
+ let(:changelog_xpath) { "//package/changelog" }
- it 'adds all changelog nodes' do
- result = subject
+ it 'adds all changelog nodes' do
+ result = subject
- expect(result.xpath(changelog_xpath).count).to eq(data[:changelogs].count)
- end
+ expect(result.xpath(changelog_xpath).count).to eq(data[:changelogs].count)
+ end
- it 'set required date attribute' do
- result = subject
+ it 'set required date attribute' do
+ result = subject
- data[:changelogs].each do |changelog|
- expect(result.at("#{changelog_xpath}[@date=\"#{changelog[:changelogtime]}\"]")).not_to be_nil
- end
+ data[:changelogs].each do |changelog|
+ expect(result.at("#{changelog_xpath}[@date=\"#{changelog[:changelogtime]}\"]")).not_to be_nil
end
end
end
diff --git a/spec/services/packages/rpm/repository_metadata/build_primary_xml_service_spec.rb b/spec/services/packages/rpm/repository_metadata/build_primary_xml_service_spec.rb
index 902844c196a..9bbfa5c9863 100644
--- a/spec/services/packages/rpm/repository_metadata/build_primary_xml_service_spec.rb
+++ b/spec/services/packages/rpm/repository_metadata/build_primary_xml_service_spec.rb
@@ -5,20 +5,18 @@ RSpec.describe Packages::Rpm::RepositoryMetadata::BuildPrimaryXmlService do
describe '#execute' do
subject { described_class.new(data).execute }
- context 'when updating existing xml' do
- include_context 'with rpm package data'
+ include_context 'with rpm package data'
- let(:data) { xml_update_params }
- let(:required_text_only_attributes) { %i[description summary arch name] }
+ let(:data) { xml_update_params }
+ let(:required_text_only_attributes) { %i[description summary arch name] }
- it 'adds node with required_text_only_attributes' do
- result = subject
+ it 'adds node with required_text_only_attributes' do
+ result = subject
- required_text_only_attributes.each do |attribute|
- expect(
- result.at("//package/#{attribute}").text
- ).to eq(data[attribute])
- end
+ required_text_only_attributes.each do |attribute|
+ expect(
+ result.at("//package/#{attribute}").text
+ ).to eq(data[attribute])
end
end
end
diff --git a/spec/services/packages/rpm/repository_metadata/update_xml_service_spec.rb b/spec/services/packages/rpm/repository_metadata/update_xml_service_spec.rb
index 01991e3928f..e351392ba1c 100644
--- a/spec/services/packages/rpm/repository_metadata/update_xml_service_spec.rb
+++ b/spec/services/packages/rpm/repository_metadata/update_xml_service_spec.rb
@@ -37,6 +37,16 @@ RSpec.describe Packages::Rpm::RepositoryMetadata::UpdateXmlService do
end
end
+ shared_context 'with filelist xml file data' do
+ let(:filename) { :filelist }
+ let(:empty_xml) do
+ <<~XML
+ <?xml version="1.0" encoding="UTF-8"?>
+ <filelists xmlns="http://linux.duke.edu/metadata/filelists" packages="0"/>
+ XML
+ end
+ end
+
context 'when building empty xml' do
shared_examples 'generating empty xml' do
it 'generate expected xml' do
@@ -57,6 +67,12 @@ RSpec.describe Packages::Rpm::RepositoryMetadata::UpdateXmlService do
it_behaves_like 'generating empty xml'
end
+
+ context "for 'filelist' xml file" do
+ include_context 'with filelist xml file data'
+
+ it_behaves_like 'generating empty xml'
+ end
end
context 'when updating xml file' do
@@ -150,6 +166,12 @@ RSpec.describe Packages::Rpm::RepositoryMetadata::UpdateXmlService do
it_behaves_like 'updating rpm xml file'
end
+
+ context "for 'filelist' xml file" do
+ include_context 'with filelist xml file data'
+
+ it_behaves_like 'updating rpm xml file'
+ end
end
end
end
diff --git a/spec/tooling/rspec_flaky/flaky_example_spec.rb b/spec/tooling/rspec_flaky/flaky_example_spec.rb
index 03436ee1cbd..c83af7e4909 100644
--- a/spec/tooling/rspec_flaky/flaky_example_spec.rb
+++ b/spec/tooling/rspec_flaky/flaky_example_spec.rb
@@ -9,30 +9,13 @@ RSpec.describe RspecFlaky::FlakyExample, :aggregate_failures do
include ActiveSupport::Testing::TimeHelpers
include StubENV
- let(:flaky_example_attrs) do
+ let(:example_attrs) do
{
example_id: 'spec/foo/bar_spec.rb:2',
file: 'spec/foo/bar_spec.rb',
line: 2,
description: 'hello world',
- first_flaky_at: 1234,
- last_flaky_at: 2345,
- last_flaky_job: 'https://gitlab.com/gitlab-org/gitlab-foss/-/jobs/12',
- last_attempts_count: 2,
- flaky_reports: 1
- }
- end
-
- let(:example_attrs) do
- {
- uid: 'abc123',
- example_id: flaky_example_attrs[:example_id],
- file: flaky_example_attrs[:file],
- line: flaky_example_attrs[:line],
- description: flaky_example_attrs[:description],
- status: 'passed',
- exception: 'BOOM!',
- attempts: flaky_example_attrs[:last_attempts_count]
+ last_attempts_count: 2
}
end
@@ -48,18 +31,18 @@ RSpec.describe RspecFlaky::FlakyExample, :aggregate_failures do
it 'returns valid attributes' do
attrs = flaky_example.to_h
- expect(attrs[:uid]).to eq(flaky_example_attrs[:uid])
- expect(attrs[:file]).to eq(flaky_example_attrs[:file])
- expect(attrs[:line]).to eq(flaky_example_attrs[:line])
- expect(attrs[:description]).to eq(flaky_example_attrs[:description])
+ expect(attrs[:uid]).to eq(example_attrs[:uid])
+ expect(attrs[:file]).to eq(example_attrs[:file])
+ expect(attrs[:line]).to eq(example_attrs[:line])
+ expect(attrs[:description]).to eq(example_attrs[:description])
expect(attrs[:first_flaky_at]).to eq(expected_first_flaky_at)
expect(attrs[:last_flaky_at]).to eq(expected_last_flaky_at)
- expect(attrs[:last_attempts_count]).to eq(flaky_example_attrs[:last_attempts_count])
+ expect(attrs[:last_attempts_count]).to eq(example_attrs[:last_attempts_count])
expect(attrs[:flaky_reports]).to eq(expected_flaky_reports)
end
end
- context 'when given an Example hash' do
+ context 'when given an Example.to_h' do
it_behaves_like 'a valid FlakyExample instance' do
let(:args) { example_attrs }
let(:expected_first_flaky_at) { Time.now }
@@ -67,18 +50,9 @@ RSpec.describe RspecFlaky::FlakyExample, :aggregate_failures do
let(:expected_flaky_reports) { 0 }
end
end
-
- context 'when given a FlakyExample hash' do
- it_behaves_like 'a valid FlakyExample instance' do
- let(:args) { flaky_example_attrs }
- let(:expected_flaky_reports) { flaky_example_attrs[:flaky_reports] }
- let(:expected_first_flaky_at) { flaky_example_attrs[:first_flaky_at] }
- let(:expected_last_flaky_at) { flaky_example_attrs[:last_flaky_at] }
- end
- end
end
- describe '#update_flakiness!' do
+ describe '#update!' do
shared_examples 'an up-to-date FlakyExample instance' do
let(:flaky_example) { described_class.new(args) }
@@ -86,18 +60,18 @@ RSpec.describe RspecFlaky::FlakyExample, :aggregate_failures do
args[:first_flaky_at] = nil
freeze_time do
- flaky_example.update_flakiness!
+ flaky_example.update!(example_attrs)
expect(flaky_example.to_h[:first_flaky_at]).to eq(Time.now)
end
end
it 'maintains the first_flaky_at if exists' do
- flaky_example.update_flakiness!
+ flaky_example.update!(example_attrs)
expected_first_flaky_at = flaky_example.to_h[:first_flaky_at]
travel_to(Time.now + 42) do
- flaky_example.update_flakiness!
+ flaky_example.update!(example_attrs)
expect(flaky_example.to_h[:first_flaky_at]).to eq(expected_first_flaky_at)
end
end
@@ -105,7 +79,7 @@ RSpec.describe RspecFlaky::FlakyExample, :aggregate_failures do
it 'updates the last_flaky_at' do
travel_to(Time.now + 42) do
the_future = Time.now
- flaky_example.update_flakiness!
+ flaky_example.update!(example_attrs)
expect(flaky_example.to_h[:last_flaky_at]).to eq(the_future)
end
@@ -114,16 +88,15 @@ RSpec.describe RspecFlaky::FlakyExample, :aggregate_failures do
it 'updates the flaky_reports' do
expected_flaky_reports = flaky_example.to_h[:first_flaky_at] ? flaky_example.to_h[:flaky_reports] + 1 : 1
- expect { flaky_example.update_flakiness! }.to change { flaky_example.to_h[:flaky_reports] }.by(1)
+ expect { flaky_example.update!(example_attrs) }.to change { flaky_example.to_h[:flaky_reports] }.by(1)
expect(flaky_example.to_h[:flaky_reports]).to eq(expected_flaky_reports)
end
- context 'when passed a :last_attempts_count' do
- it 'updates the last_attempts_count' do
- flaky_example.update_flakiness!(last_attempts_count: 42)
+ it 'updates the last_attempts_count' do
+ example_attrs[:last_attempts_count] = 42
+ flaky_example.update!(example_attrs)
- expect(flaky_example.to_h[:last_attempts_count]).to eq(42)
- end
+ expect(flaky_example.to_h[:last_attempts_count]).to eq(42)
end
context 'when run on the CI' do
@@ -134,7 +107,7 @@ RSpec.describe RspecFlaky::FlakyExample, :aggregate_failures do
end
it 'updates the last_flaky_job' do
- flaky_example.update_flakiness!
+ flaky_example.update!(example_attrs)
expect(flaky_example.to_h[:last_flaky_job]).to eq(job_url)
end
@@ -146,12 +119,6 @@ RSpec.describe RspecFlaky::FlakyExample, :aggregate_failures do
let(:args) { example_attrs }
end
end
-
- context 'when given a FlakyExample hash' do
- it_behaves_like 'an up-to-date FlakyExample instance' do
- let(:args) { flaky_example_attrs }
- end
- end
end
describe '#to_h', :freeze_time do
@@ -160,7 +127,7 @@ RSpec.describe RspecFlaky::FlakyExample, :aggregate_failures do
it 'returns a valid hash' do
flaky_example = described_class.new(args)
- final_hash = flaky_example_attrs.merge(additional_attrs)
+ final_hash = example_attrs.merge(additional_attrs)
expect(flaky_example.to_h).to eq(final_hash)
end
@@ -175,11 +142,5 @@ RSpec.describe RspecFlaky::FlakyExample, :aggregate_failures do
end
end
end
-
- context 'when given a FlakyExample hash' do
- let(:args) { flaky_example_attrs }
-
- it_behaves_like 'a valid FlakyExample hash'
- end
end
end
diff --git a/tooling/rspec_flaky/flaky_example.rb b/tooling/rspec_flaky/flaky_example.rb
index 299fcb567fc..5736cc74810 100644
--- a/tooling/rspec_flaky/flaky_example.rb
+++ b/tooling/rspec_flaky/flaky_example.rb
@@ -31,11 +31,14 @@ module RspecFlaky
end
end
- def update_flakiness!(last_attempts_count: nil)
+ def update!(example_hash)
+ attributes[:file] = example_hash[:file]
+ attributes[:line] = example_hash[:line]
+ attributes[:description] = example_hash[:description]
attributes[:first_flaky_at] ||= Time.now
attributes[:last_flaky_at] = Time.now
attributes[:flaky_reports] += 1
- attributes[:last_attempts_count] = last_attempts_count if last_attempts_count
+ attributes[:last_attempts_count] = example_hash[:last_attempts_count] if example_hash[:last_attempts_count]
if ENV['CI_JOB_URL']
attributes[:last_flaky_job] = "#{ENV['CI_JOB_URL']}"
diff --git a/tooling/rspec_flaky/listener.rb b/tooling/rspec_flaky/listener.rb
index 9b20eefc2f0..3431d814a8a 100644
--- a/tooling/rspec_flaky/listener.rb
+++ b/tooling/rspec_flaky/listener.rb
@@ -27,7 +27,7 @@ module RspecFlaky
return unless current_example.attempts > 1
flaky_example = suite_flaky_examples.fetch(current_example.uid) { RspecFlaky::FlakyExample.new(current_example.to_h) }
- flaky_example.update_flakiness!(last_attempts_count: current_example.attempts)
+ flaky_example.update!(current_example.to_h)
flaky_examples[current_example.uid] = flaky_example
end