Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
a6d9ec9567
commit
d75e21489f
|
|
@ -2,6 +2,7 @@
|
|||
# https://www.gitpod.io/docs/configure/workspaces/tasks
|
||||
|
||||
image: registry.gitlab.com/gitlab-org/gitlab-development-kit/gitpod-workspace:stable
|
||||
checkoutLocation: gitlab-development-kit/gitlab
|
||||
|
||||
tasks:
|
||||
|
||||
|
|
@ -24,8 +25,6 @@ tasks:
|
|||
echo "$(date) – Copying GDK" | tee -a /workspace/startup.log
|
||||
cp -r $HOME/gitlab-development-kit /workspace/
|
||||
cd /workspace/gitlab-development-kit
|
||||
# ensure GitLab directory is symlinked under the GDK
|
||||
ln -nfs "$GITPOD_REPO_ROOT" /workspace/gitlab-development-kit/gitlab
|
||||
mv -v /workspace/gitlab-development-kit/secrets.yml /workspace/gitlab-development-kit/gitlab/config
|
||||
# ensure gdk.yml has correct instance settings
|
||||
gdk config set gitlab.rails.port 443 |& tee -a /workspace/startup.log
|
||||
|
|
|
|||
|
|
@ -514,6 +514,7 @@ export const code = {
|
|||
open: generateCodeTag(),
|
||||
close: generateCodeTag(closeTag),
|
||||
mixable: true,
|
||||
escape: false,
|
||||
expelEnclosingWhitespace: true,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -238,7 +238,7 @@ export default {
|
|||
const container = document.createElement('div');
|
||||
// eslint-disable-next-line no-unsanitized/property
|
||||
container.innerHTML = `<svg class="drag-icon s14 gl-icon gl-cursor-grab gl-opacity-0" role="img" aria-hidden="true">
|
||||
<use href="${gon.sprite_icons}#drag-vertical"></use>
|
||||
<use href="${gon.sprite_icons}#grip"></use>
|
||||
</svg>`;
|
||||
return container.firstChild;
|
||||
},
|
||||
|
|
@ -259,7 +259,7 @@ export default {
|
|||
};
|
||||
|
||||
// We use pointerover/pointerout instead of CSS so that when we hover over a
|
||||
// list item with children, the drag icons of its children do not become visible.
|
||||
// list item with children, the grip icons of its children do not become visible.
|
||||
listItem.addEventListener('pointerover', pointeroverListener);
|
||||
listItem.addEventListener('pointerout', pointeroutListener);
|
||||
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ export default {
|
|||
|
||||
[types.UPDATE_RELEASE_TAG_NAME](state, tagName) {
|
||||
state.release.tagName = tagName;
|
||||
state.existingRelease = null;
|
||||
},
|
||||
[types.UPDATE_RELEASE_TAG_MESSAGE](state, tagMessage) {
|
||||
state.release.tagMessage = tagMessage;
|
||||
|
|
@ -118,6 +119,7 @@ export default {
|
|||
state.fetchError = error;
|
||||
state.isFetchingTagNotes = false;
|
||||
state.tagNotes = '';
|
||||
state.existingRelease = null;
|
||||
},
|
||||
[types.UPDATE_INCLUDE_TAG_NOTES](state, includeTagNotes) {
|
||||
state.includeTagNotes = includeTagNotes;
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ module Ci
|
|||
job.update_column(:artifacts_expire_at, artifact.expire_at)
|
||||
end
|
||||
|
||||
Gitlab::Ci::Artifacts::Logger.log_created(artifact)
|
||||
Gitlab::Ci::Artifacts::Logger.log_created([artifact, artifact_metadata].compact)
|
||||
|
||||
success(artifact: artifact)
|
||||
rescue ActiveRecord::RecordNotUnique => error
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
name: enable_new_sentry_clientside_integration
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/102650
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/344832
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/382570
|
||||
milestone: '15.6'
|
||||
type: development
|
||||
group: group::runner
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
name: use_primary_and_secondary_stores_for_rate_limiting
|
||||
introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/106123"
|
||||
rollout_issue_url: "https://gitlab.com/gitlab-org/gitlab/-/issues/385681"
|
||||
milestone: '15.9'
|
||||
type: development
|
||||
group: group::scalability
|
||||
default_enabled: false
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
name: use_primary_store_as_default_for_rate_limiting
|
||||
introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/106123"
|
||||
rollout_issue_url: "https://gitlab.com/gitlab-org/gitlab/-/issues/385681"
|
||||
milestone: '15.9'
|
||||
type: development
|
||||
group: group::scalability
|
||||
default_enabled: false
|
||||
|
|
@ -824,6 +824,9 @@ Gitlab.ee do
|
|||
Settings.cron_jobs['licenses_reset_submit_license_usage_data_banner'] ||= Settingslogic.new({})
|
||||
Settings.cron_jobs['licenses_reset_submit_license_usage_data_banner']['cron'] ||= "0 0 * * *"
|
||||
Settings.cron_jobs['licenses_reset_submit_license_usage_data_banner']['job_class'] = 'Licenses::ResetSubmitLicenseUsageDataBannerWorker'
|
||||
Settings.cron_jobs['abandoned_trial_emails'] ||= Settingslogic.new({})
|
||||
Settings.cron_jobs['abandoned_trial_emails']['cron'] ||= "0 1 * * *"
|
||||
Settings.cron_jobs['abandoned_trial_emails']['job_class'] = 'Emails::AbandonedTrialEmailsCronWorker'
|
||||
Gitlab.com do
|
||||
Settings.cron_jobs['disable_legacy_open_source_license_for_inactive_projects'] ||= Settingslogic.new({})
|
||||
Settings.cron_jobs['disable_legacy_open_source_license_for_inactive_projects']['cron'] ||= "30 5 * * 0"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
- title: 'Embedding Grafana panels in Markdown is deprecated'
|
||||
announcement_milestone: '15.9'
|
||||
removal_milestone: '16.0'
|
||||
breaking_change: true
|
||||
reporter: abellucci
|
||||
body: |
|
||||
The ability to add Grafana panels in GitLab Flavored Markdown is deprecated in 15.9 and will be removed in 16.0.
|
||||
We intend to replace this feature with the ability to [embed charts](https://gitlab.com/groups/gitlab-org/opstrace/-/epics/33) with the [GitLab Observability UI](https://gitlab.com/gitlab-org/opstrace/opstrace-ui).
|
||||
stage: monitor
|
||||
issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/389477
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddTrialDateIndexToGitlabSubscribtions < Gitlab::Database::Migration[2.1]
|
||||
disable_ddl_transaction!
|
||||
|
||||
INDEX_NAME = 'index_gitlab_subscriptions_on_trial_and_trial_starts_on'
|
||||
|
||||
def up
|
||||
add_concurrent_index :gitlab_subscriptions, [:trial, :trial_starts_on], name: INDEX_NAME
|
||||
end
|
||||
|
||||
def down
|
||||
remove_concurrent_index_by_name :gitlab_subscriptions, INDEX_NAME
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddProjectIdNameIdVersionIndexToInstallableNpmPackages < Gitlab::Database::Migration[2.1]
|
||||
disable_ddl_transaction!
|
||||
|
||||
INDEX_NAME = 'idx_packages_on_project_id_name_id_version_when_installable_npm'
|
||||
PACKAGE_TYPE_NPM = 2
|
||||
|
||||
def up
|
||||
add_concurrent_index(
|
||||
:packages_packages,
|
||||
[:project_id, :name, :id, :version],
|
||||
name: INDEX_NAME,
|
||||
where: "package_type = #{PACKAGE_TYPE_NPM} AND status IN (0, 1)"
|
||||
)
|
||||
end
|
||||
|
||||
def down
|
||||
remove_concurrent_index_by_name(:packages_packages, INDEX_NAME)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddFkIndexToCiBuildNeedsOnPartitionIdAndBuildId < Gitlab::Database::Migration[2.1]
|
||||
disable_ddl_transaction!
|
||||
|
||||
INDEX_NAME = :index_ci_build_needs_on_partition_id_build_id
|
||||
TABLE_NAME = :ci_build_needs
|
||||
COLUMNS = [:partition_id, :build_id]
|
||||
|
||||
def up
|
||||
add_concurrent_index(TABLE_NAME, COLUMNS, name: INDEX_NAME)
|
||||
end
|
||||
|
||||
def down
|
||||
remove_concurrent_index_by_name(TABLE_NAME, INDEX_NAME)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddFkToCiBuildNeedsOnPartitionIdAndBuildId < Gitlab::Database::Migration[2.1]
|
||||
disable_ddl_transaction!
|
||||
|
||||
SOURCE_TABLE_NAME = :ci_build_needs
|
||||
TARGET_TABLE_NAME = :ci_builds
|
||||
COLUMN = :build_id
|
||||
TARGET_COLUMN = :id
|
||||
FK_NAME = :fk_rails_3cf221d4ed_p
|
||||
PARTITION_COLUMN = :partition_id
|
||||
|
||||
def up
|
||||
add_concurrent_foreign_key(
|
||||
SOURCE_TABLE_NAME,
|
||||
TARGET_TABLE_NAME,
|
||||
column: [PARTITION_COLUMN, COLUMN],
|
||||
target_column: [PARTITION_COLUMN, TARGET_COLUMN],
|
||||
validate: false,
|
||||
reverse_lock_order: true,
|
||||
on_update: :cascade,
|
||||
on_delete: :cascade,
|
||||
name: FK_NAME
|
||||
)
|
||||
end
|
||||
|
||||
def down
|
||||
with_lock_retries do
|
||||
remove_foreign_key_if_exists(
|
||||
SOURCE_TABLE_NAME,
|
||||
TARGET_TABLE_NAME,
|
||||
name: FK_NAME,
|
||||
reverse_lock_order: true
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class FinalizeBackfillEnvironmentTierMigration < Gitlab::Database::Migration[2.1]
|
||||
MIGRATION = 'BackfillEnvironmentTiers'
|
||||
disable_ddl_transaction!
|
||||
|
||||
restrict_gitlab_migration gitlab_schema: :gitlab_main
|
||||
|
||||
def up
|
||||
ensure_batched_background_migration_is_finished(
|
||||
job_class_name: MIGRATION,
|
||||
table_name: :environments,
|
||||
column_name: :id,
|
||||
job_arguments: [],
|
||||
finalize: true
|
||||
)
|
||||
end
|
||||
|
||||
def down
|
||||
# no-op
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1 @@
|
|||
9eeead7484119ca0a9764104856970e5d78d484f4616552f8535f1eb047f4ae7
|
||||
|
|
@ -0,0 +1 @@
|
|||
17e3e3236ba71778e86a4df672ba2b7080a127658792b60669738fdad4fe2f36
|
||||
|
|
@ -0,0 +1 @@
|
|||
0678dd7f9e8ad7c7e5761b7b624340fdf7785688d41badfb4affc8a2e2181072
|
||||
|
|
@ -0,0 +1 @@
|
|||
ccf6031d207b41bfacbd671b9e320e0929e43d5c62744df49b073f5ee6a90885
|
||||
|
|
@ -0,0 +1 @@
|
|||
c63f9cf6abb67b2d2623b662cd9dd7c9684a972c0aa89ea43f59e6196dacb249
|
||||
|
|
@ -28624,6 +28624,8 @@ CREATE INDEX idx_packages_debian_group_component_files_on_architecture_id ON pac
|
|||
|
||||
CREATE INDEX idx_packages_debian_project_component_files_on_architecture_id ON packages_debian_project_component_files USING btree (architecture_id);
|
||||
|
||||
CREATE INDEX idx_packages_on_project_id_name_id_version_when_installable_npm ON packages_packages USING btree (project_id, name, id, version) WHERE ((package_type = 2) AND (status = ANY (ARRAY[0, 1])));
|
||||
|
||||
CREATE UNIQUE INDEX idx_packages_on_project_id_name_version_unique_when_generic ON packages_packages USING btree (project_id, name, version) WHERE ((package_type = 7) AND (status <> 4));
|
||||
|
||||
CREATE UNIQUE INDEX idx_packages_on_project_id_name_version_unique_when_golang ON packages_packages USING btree (project_id, name, version) WHERE ((package_type = 8) AND (status <> 4));
|
||||
|
|
@ -29002,6 +29004,8 @@ CREATE UNIQUE INDEX index_chat_teams_on_namespace_id ON chat_teams USING btree (
|
|||
|
||||
CREATE UNIQUE INDEX index_ci_build_needs_on_build_id_and_name ON ci_build_needs USING btree (build_id, name);
|
||||
|
||||
CREATE INDEX index_ci_build_needs_on_partition_id_build_id ON ci_build_needs USING btree (partition_id, build_id);
|
||||
|
||||
CREATE UNIQUE INDEX index_ci_build_pending_states_on_build_id ON ci_build_pending_states USING btree (build_id);
|
||||
|
||||
CREATE INDEX index_ci_build_pending_states_on_partition_id_build_id ON ci_build_pending_states USING btree (partition_id, build_id);
|
||||
|
|
@ -29900,6 +29904,8 @@ CREATE INDEX index_gitlab_subscriptions_on_max_seats_used_changed_at ON gitlab_s
|
|||
|
||||
CREATE UNIQUE INDEX index_gitlab_subscriptions_on_namespace_id ON gitlab_subscriptions USING btree (namespace_id);
|
||||
|
||||
CREATE INDEX index_gitlab_subscriptions_on_trial_and_trial_starts_on ON gitlab_subscriptions USING btree (trial, trial_starts_on);
|
||||
|
||||
CREATE UNIQUE INDEX index_gpg_key_subkeys_on_fingerprint ON gpg_key_subkeys USING btree (fingerprint);
|
||||
|
||||
CREATE INDEX index_gpg_key_subkeys_on_gpg_key_id ON gpg_key_subkeys USING btree (gpg_key_id);
|
||||
|
|
@ -34856,6 +34862,9 @@ ALTER TABLE ONLY chat_teams
|
|||
ALTER TABLE ONLY ci_build_needs
|
||||
ADD CONSTRAINT fk_rails_3cf221d4ed FOREIGN KEY (build_id) REFERENCES ci_builds(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY ci_build_needs
|
||||
ADD CONSTRAINT fk_rails_3cf221d4ed_p FOREIGN KEY (partition_id, build_id) REFERENCES ci_builds(partition_id, id) ON UPDATE CASCADE ON DELETE CASCADE NOT VALID;
|
||||
|
||||
ALTER TABLE ONLY cluster_groups
|
||||
ADD CONSTRAINT fk_rails_3d28377556 FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
|
||||
|
||||
|
|
|
|||
|
|
@ -479,25 +479,24 @@ changing Git remotes and API URLs.
|
|||
external_url 'https://<new_external_url>'
|
||||
```
|
||||
|
||||
If you provide GitLab with its certificate
|
||||
[manually](https://docs.gitlab.com/omnibus/settings/ssl/index.html#configure-https-manually),
|
||||
ensure:
|
||||
NOTE:
|
||||
Changing `external_url` does not prevent access via the old secondary URL, as
|
||||
long as the secondary DNS records are still intact.
|
||||
|
||||
- The new URL is one of the subject alternative names:
|
||||
1. Update the **secondary**'s SSL certificate:
|
||||
|
||||
- If you use the [Let's Encrypt integration](https://docs.gitlab.com/omnibus/settings/ssl/index.html#enable-the-lets-encrypt-integration),
|
||||
the certificate updates automatically.
|
||||
- If you had [manually set up](https://docs.gitlab.com/omnibus/settings/ssl/index.html#configure-https-manually),
|
||||
the **secondary**'s certificate, copy the certificate from the **primary** to the **secondary**.
|
||||
If you don't have access to the **primary**, issue a new certificate and make sure it contains
|
||||
both the **primary** and **secondary** URLs in the subject alternative names. You can check with:
|
||||
|
||||
```shell
|
||||
/opt/gitlab/embedded/bin/openssl x509 -noout -dates -subject -issuer \
|
||||
-nameopt multiline -ext subjectAltName -in /etc/gitlab/ssl/new-gitlab.new-example.com.crt
|
||||
```
|
||||
|
||||
- The certificate and key filenames match the new `external_url`,
|
||||
or those filenames are
|
||||
[specified in `/etc/gitlab/gitlab.rb`](https://docs.gitlab.com/omnibus/settings/ssl/index.html#change-the-default-ssl-certificate-location).
|
||||
|
||||
NOTE:
|
||||
Changing `external_url` does not prevent access via the old secondary URL, as
|
||||
long as the secondary DNS records are still intact.
|
||||
|
||||
1. Reconfigure the **secondary** site for the change to take effect:
|
||||
|
||||
```shell
|
||||
|
|
|
|||
|
|
@ -115,6 +115,9 @@ Configure DNS for an alternate SSH hostname such as `altssh.gitlab.example.com`.
|
|||
|
||||
It is strongly recommend that multi-node deployments configure load balancers to use the [readiness check](../user/admin_area/monitoring/health_check.md#readiness) to ensure a node is ready to accept traffic, before routing traffic to it. This is especially important when utilizing Puma, as there is a brief period during a restart where Puma doesn't accept requests.
|
||||
|
||||
WARNING:
|
||||
Using the `all=1` parameter with the readiness check in GitLab versions 15.4 to 15.8 may cause [increased Praefect memory usage](https://gitlab.com/gitlab-org/gitaly/-/issues/4751) and lead to memory errors.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### The health check is returning a `408` HTTP code via the load balancer
|
||||
|
|
|
|||
|
|
@ -914,6 +914,11 @@ When this is used, GitLab fetches temporary credentials each time an
|
|||
S3 bucket is accessed, so no hard-coded values are needed in the
|
||||
configuration.
|
||||
|
||||
To use an Amazon instance profile, GitLab must be able to connect to the
|
||||
[instance metadata endpoint](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-data-retrieval.html).
|
||||
If GitLab is [configured to use an Internet proxy](https://docs.gitlab.com/omnibus/settings/environment-variables.html), the endpoint IP
|
||||
address must be added to the `no_proxy` list.
|
||||
|
||||
#### Encrypted S3 buckets
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab-workhorse/-/merge_requests/466) in GitLab 13.1 for instance profiles only and [S3 default encryption](https://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-encryption.html).
|
||||
|
|
|
|||
|
|
@ -70,6 +70,22 @@ All Work Item types share the same pool of predefined widgets and are customized
|
|||
|
||||
\* status is not currently a widget, but a part of the root work item, similar to title
|
||||
|
||||
### Work item relationships
|
||||
|
||||
Work items can be related to other work items in a number of different ways:
|
||||
|
||||
- Parent: A direct ancestor to the current work item, whose completion relies on completing this work item.
|
||||
- Child: A direct descendant of the current work item, which contributes to this work item's completion.
|
||||
- Blocked by: A work item preventing the completion of the current work item.
|
||||
- Blocks: A work item whose completion is blocked by the current work item.
|
||||
- Related: A work item that is relevant to the subject of the current work item, but does not directly contribute to or block the completion of this work item.
|
||||
|
||||
#### Hierarchy
|
||||
|
||||
Parent-child relationships form the basis of **hierarchy** in work items. Each work item type has a defined set of types that can be parents or children of that type.
|
||||
|
||||
As types expand, and parent items have their own parent items, the hierarchy capability can grow exponentially.
|
||||
|
||||
### Work Item view
|
||||
|
||||
The new frontend view that renders Work Items of any type using global Work Item `id` as an identifier.
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ group: Pipeline Authoring
|
|||
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
|
||||
---
|
||||
|
||||
# Configure OpenID Connect in AWS to retrieve temporary credentials
|
||||
# Configure OpenID Connect in AWS to retrieve temporary credentials **(FREE)**
|
||||
|
||||
In this tutorial, we'll show you how to use a GitLab CI/CD job with a JSON web token (JWT) to retrieve temporary credentials from AWS without needing to store secrets.
|
||||
To do this, you must configure OpenID Connect (OIDC) for ID federation between GitLab and AWS. For background and requirements for integrating GitLab using OIDC, see [Connect to cloud services](../index.md).
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ group: Pipeline Authoring
|
|||
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
|
||||
---
|
||||
|
||||
# Configure OpenID Connect in Azure to retrieve temporary credentials
|
||||
# Configure OpenID Connect in Azure to retrieve temporary credentials **(FREE)**
|
||||
|
||||
This tutorial demonstrates how to use a JSON web token (JWT) in a GitLab CI/CD job
|
||||
to retrieve temporary credentials from Azure without needing to store secrets.
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ group: Pipeline Authoring
|
|||
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
|
||||
---
|
||||
|
||||
# Configure OpenID Connect with GCP Workload Identity Federation
|
||||
# Configure OpenID Connect with GCP Workload Identity Federation **(FREE)**
|
||||
|
||||
WARNING:
|
||||
The `CI_JOB_JWT_V2` variable is under development [(alpha)](../../../policy/alpha-beta-support.md#alpha-features) and is not yet suitable for production use.
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ group: Pipeline Authoring
|
|||
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
|
||||
---
|
||||
|
||||
# Connect to cloud services
|
||||
# Connect to cloud services **(FREE)**
|
||||
|
||||
> - `CI_JOB_JWT` variable for reading secrets from Vault [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/207125) in GitLab 12.10.
|
||||
> - `CI_JOB_JWT_V2` variable to support additional OIDC providers [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/346737) in GitLab 14.7.
|
||||
|
|
|
|||
|
|
@ -124,3 +124,14 @@ When you create a timeline event and select the tags, the event note
|
|||
is populated with a default message.
|
||||
This allows for a quick event creation. If a note has already been set, it isn't changed.
|
||||
Added tags are displayed next to the timestamp.
|
||||
|
||||
## Formatting rules
|
||||
|
||||
Incident timeline events support the following [GitLab Flavored Markdown](../../user/markdown.md) features.
|
||||
|
||||
- [Code](../../user/markdown.md#code-spans-and-blocks).
|
||||
- [Emojis](../../user/markdown.md#emojis).
|
||||
- [Emphasis](../../user/markdown.md#emphasis).
|
||||
- [GitLab-specific references](../../user/markdown.md#gitlab-specific-references).
|
||||
- [Images](../../user/markdown.md#images), rendered as a link to the uploaded image.
|
||||
- [Links](../../user/markdown.md#links).
|
||||
|
|
|
|||
|
|
@ -78,6 +78,21 @@ When using the native HashiCorp Vault integration, CI/CD jobs will fail when no
|
|||
|
||||
</div>
|
||||
|
||||
<div class="deprecation removal-160 breaking-change">
|
||||
|
||||
### Embedding Grafana panels in Markdown is deprecated
|
||||
|
||||
Planned removal: GitLab <span class="removal-milestone">16.0</span> <span class="removal-date"></span>
|
||||
|
||||
WARNING:
|
||||
This is a [breaking change](https://docs.gitlab.com/ee/development/deprecation_guidelines/).
|
||||
Review the details carefully before upgrading.
|
||||
|
||||
The ability to add Grafana panels in GitLab Flavored Markdown is deprecated in 15.9 and will be removed in 16.0.
|
||||
We intend to replace this feature with the ability to [embed charts](https://gitlab.com/groups/gitlab-org/opstrace/-/epics/33) with the [GitLab Observability UI](https://gitlab.com/gitlab-org/opstrace/opstrace-ui).
|
||||
|
||||
</div>
|
||||
|
||||
<div class="deprecation removal-170 breaking-change">
|
||||
|
||||
### GitLab Runner platforms and setup instructions in GraphQL API
|
||||
|
|
|
|||
|
|
@ -116,10 +116,10 @@ Prerequisites:
|
|||
|
||||
To reorder list items, when viewing an epic:
|
||||
|
||||
1. Hover over the list item row to make the drag icon (**{drag-vertical}**) visible.
|
||||
1. Select and hold the drag icon.
|
||||
1. Hover over the list item row to make the grip icon (**{grip}**) visible.
|
||||
1. Select and hold the grip icon.
|
||||
1. Drag the row to the new position in the list.
|
||||
1. Release the drag icon.
|
||||
1. Release the grip icon.
|
||||
|
||||
## Bulk edit epics
|
||||
|
||||
|
|
|
|||
|
|
@ -174,10 +174,10 @@ Prerequisites:
|
|||
|
||||
To reorder list items, when viewing an issue:
|
||||
|
||||
1. Hover over the list item row to make the drag icon (**{drag-vertical}**) visible.
|
||||
1. Select and hold the drag icon.
|
||||
1. Hover over the list item row to make the grip icon (**{grip}**) visible.
|
||||
1. Select and hold the grip icon.
|
||||
1. Drag the row to the new position in the list.
|
||||
1. Release the drag icon.
|
||||
1. Release the grip icon.
|
||||
|
||||
## Close an issue
|
||||
|
||||
|
|
|
|||
|
|
@ -29,17 +29,19 @@ module Gitlab
|
|||
)
|
||||
end
|
||||
|
||||
def self.log_created(artifact)
|
||||
payload = Gitlab::ApplicationContext.current.merge(
|
||||
message: 'Artifact created',
|
||||
job_artifact_id: artifact.id,
|
||||
size: artifact.size,
|
||||
type: artifact.file_type,
|
||||
build_id: artifact.job_id,
|
||||
project_id: artifact.project_id
|
||||
)
|
||||
def self.log_created(job_artifacts)
|
||||
Array(job_artifacts).each do |artifact|
|
||||
payload = Gitlab::ApplicationContext.current.merge(
|
||||
message: 'Artifact created',
|
||||
job_artifact_id: artifact.id,
|
||||
size: artifact.size,
|
||||
type: artifact.file_type,
|
||||
build_id: artifact.job_id,
|
||||
project_id: artifact.project_id
|
||||
)
|
||||
|
||||
Gitlab::AppLogger.info(payload)
|
||||
Gitlab::AppLogger.info(payload)
|
||||
end
|
||||
end
|
||||
|
||||
def self.log_deleted(job_artifacts, method)
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ module Gitlab
|
|||
Gitlab::Redis::Queues,
|
||||
Gitlab::Redis::RateLimiting,
|
||||
Gitlab::Redis::RepositoryCache,
|
||||
Gitlab::Redis::ClusterRateLimiting,
|
||||
Gitlab::Redis::Sessions,
|
||||
Gitlab::Redis::SharedState,
|
||||
Gitlab::Redis::TraceChunks
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module Redis
|
||||
class ClusterRateLimiting < ::Gitlab::Redis::Wrapper
|
||||
def self.config_fallback
|
||||
Cache
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -169,11 +169,15 @@ module Gitlab
|
|||
end
|
||||
|
||||
def use_primary_and_secondary_stores?
|
||||
feature_enabled?("use_primary_and_secondary_stores_for")
|
||||
feature_table_exists? &&
|
||||
Feature.enabled?("use_primary_and_secondary_stores_for_#{instance_name.underscore}") && # rubocop:disable Cop/FeatureFlagUsage
|
||||
!same_redis_store?
|
||||
end
|
||||
|
||||
def use_primary_store_as_default?
|
||||
feature_enabled?("use_primary_store_as_default_for")
|
||||
feature_table_exists? &&
|
||||
Feature.enabled?("use_primary_store_as_default_for_#{instance_name.underscore}") && # rubocop:disable Cop/FeatureFlagUsage
|
||||
!same_redis_store?
|
||||
end
|
||||
|
||||
def increment_pipelined_command_error_count(command_name)
|
||||
|
|
@ -213,15 +217,10 @@ module Gitlab
|
|||
|
||||
private
|
||||
|
||||
# @return [Boolean]
|
||||
def feature_enabled?(prefix)
|
||||
feature_table_exists? &&
|
||||
Feature.enabled?("#{prefix}_#{instance_name.underscore}") && # rubocop:disable Cop/FeatureFlagUsage
|
||||
!same_redis_store?
|
||||
end
|
||||
|
||||
# @return [Boolean]
|
||||
def feature_table_exists?
|
||||
# Use table_exists? (which uses ActiveRecord's schema cache) instead of Feature.feature_flags_available?
|
||||
# as the latter runs a ';' SQL query which causes a connection to be checked out.
|
||||
Feature::FlipperFeature.table_exists?
|
||||
rescue StandardError
|
||||
false
|
||||
|
|
|
|||
|
|
@ -3,13 +3,24 @@
|
|||
module Gitlab
|
||||
module Redis
|
||||
class RateLimiting < ::Gitlab::Redis::Wrapper
|
||||
# The data we store on RateLimiting used to be stored on Cache.
|
||||
def self.config_fallback
|
||||
Cache
|
||||
end
|
||||
class << self
|
||||
# The data we store on RateLimiting used to be stored on Cache.
|
||||
def config_fallback
|
||||
Cache
|
||||
end
|
||||
|
||||
def self.cache_store
|
||||
@cache_store ||= ActiveSupport::Cache::RedisCacheStore.new(redis: pool, namespace: Cache::CACHE_NAMESPACE)
|
||||
def cache_store
|
||||
@cache_store ||= ActiveSupport::Cache::RedisCacheStore.new(redis: pool, namespace: Cache::CACHE_NAMESPACE)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def redis
|
||||
primary_store = ::Redis.new(::Gitlab::Redis::ClusterRateLimiting.params)
|
||||
secondary_store = ::Redis.new(params)
|
||||
|
||||
MultiStore.new(primary_store, secondary_store, name.demodulize)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -36464,7 +36464,7 @@ msgstr ""
|
|||
msgid "Runners|Active"
|
||||
msgstr ""
|
||||
|
||||
msgid "Runners|Add notes, like who owns the runner or what it should be used for."
|
||||
msgid "Runners|Add notes such as the runner owner or what it should be used for."
|
||||
msgstr ""
|
||||
|
||||
msgid "Runners|Administrator"
|
||||
|
|
@ -36715,6 +36715,9 @@ msgstr ""
|
|||
msgid "Runners|Online:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Runners|Only administrators can view this."
|
||||
msgstr ""
|
||||
|
||||
msgid "Runners|Owner"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -38610,6 +38613,9 @@ msgstr ""
|
|||
msgid "SecurityReports|There was an error deleting the comment."
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityReports|There was an error dismissing the finding. Please try again."
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityReports|There was an error dismissing the vulnerabilities."
|
||||
msgstr ""
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import {
|
|||
} from 'jest/work_items/mock_data';
|
||||
import {
|
||||
descriptionProps as initialProps,
|
||||
descriptionHtmlWithList,
|
||||
descriptionHtmlWithCheckboxes,
|
||||
descriptionHtmlWithTask,
|
||||
} from '../mock_data/mock_data';
|
||||
|
|
@ -36,6 +37,7 @@ jest.mock('~/lib/utils/url_utility', () => ({
|
|||
jest.mock('~/task_list');
|
||||
jest.mock('~/behaviors/markdown/render_gfm');
|
||||
|
||||
const mockSpriteIcons = '/icons.svg';
|
||||
const showModal = jest.fn();
|
||||
const hideModal = jest.fn();
|
||||
const showDetailsModal = jest.fn();
|
||||
|
|
@ -57,11 +59,13 @@ const createWorkItemFromTaskSuccessHandler = jest
|
|||
|
||||
describe('Description component', () => {
|
||||
let wrapper;
|
||||
let originalGon;
|
||||
|
||||
Vue.use(VueApollo);
|
||||
|
||||
const findGfmContent = () => wrapper.find('[data-testid="gfm-content"]');
|
||||
const findTextarea = () => wrapper.find('[data-testid="textarea"]');
|
||||
const findListItems = () => findGfmContent().findAll('ul > li');
|
||||
const findTaskActionButtons = () => wrapper.findAll('.task-list-item-actions');
|
||||
const findTaskLink = () => wrapper.find('a.gfm-issue');
|
||||
const findModal = () => wrapper.findComponent(GlModal);
|
||||
|
|
@ -71,6 +75,7 @@ describe('Description component', () => {
|
|||
props = {},
|
||||
provide,
|
||||
createWorkItemFromTaskHandler = createWorkItemFromTaskSuccessHandler,
|
||||
...options
|
||||
} = {}) {
|
||||
wrapper = shallowMountExtended(Description, {
|
||||
propsData: {
|
||||
|
|
@ -103,10 +108,14 @@ describe('Description component', () => {
|
|||
},
|
||||
}),
|
||||
},
|
||||
...options,
|
||||
});
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
originalGon = window.gon;
|
||||
window.gon = { sprite_icons: mockSpriteIcons };
|
||||
|
||||
setWindowLocation(TEST_HOST);
|
||||
|
||||
if (!document.querySelector('.issuable-meta')) {
|
||||
|
|
@ -120,6 +129,8 @@ describe('Description component', () => {
|
|||
});
|
||||
|
||||
afterAll(() => {
|
||||
window.gon = originalGon;
|
||||
|
||||
$('.issuable-meta .flash-container').remove();
|
||||
});
|
||||
|
||||
|
|
@ -261,6 +272,37 @@ describe('Description component', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('with list', () => {
|
||||
beforeEach(async () => {
|
||||
createComponent({
|
||||
props: {
|
||||
descriptionHtml: descriptionHtmlWithList,
|
||||
},
|
||||
attachTo: document.body,
|
||||
});
|
||||
await nextTick();
|
||||
});
|
||||
|
||||
it('shows list items', () => {
|
||||
expect(findListItems()).toHaveLength(3);
|
||||
});
|
||||
|
||||
it('shows list items drag icons', () => {
|
||||
const dragIcon = findListItems().at(0).find('.drag-icon');
|
||||
|
||||
expect(dragIcon.classes()).toEqual(
|
||||
expect.arrayContaining(['s14', 'gl-icon', 'gl-cursor-grab', 'gl-opacity-0']),
|
||||
);
|
||||
expect(dragIcon.attributes()).toMatchObject({
|
||||
'aria-hidden': 'true',
|
||||
role: 'img',
|
||||
});
|
||||
expect(dragIcon.find('use').attributes()).toEqual({
|
||||
href: `${mockSpriteIcons}#grip`,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('with work_items_mvc_2 feature flag enabled', () => {
|
||||
describe('empty description', () => {
|
||||
beforeEach(() => {
|
||||
|
|
|
|||
|
|
@ -59,6 +59,14 @@ export const appProps = {
|
|||
publishedIncidentUrl,
|
||||
};
|
||||
|
||||
export const descriptionHtmlWithList = `
|
||||
<ul data-sourcepos="1:1-3:8" dir="auto">
|
||||
<li data-sourcepos="1:1-1:8">todo 1</li>
|
||||
<li data-sourcepos="2:1-2:8">todo 2</li>
|
||||
<li data-sourcepos="3:1-3:8">todo 3</li>
|
||||
</ul>
|
||||
`;
|
||||
|
||||
export const descriptionHtmlWithCheckboxes = `
|
||||
<ul dir="auto" class="task-list" data-sourcepos"3:1-5:12">
|
||||
<li class="task-list-item" data-sourcepos="3:1-3:11">
|
||||
|
|
|
|||
|
|
@ -89,6 +89,15 @@ describe('Release edit/new mutations', () => {
|
|||
|
||||
expect(state.release.tagName).toBe(newTag);
|
||||
});
|
||||
|
||||
it('nulls out existing release', () => {
|
||||
state.release = release;
|
||||
state.existingRelease = release;
|
||||
const newTag = 'updated-tag-name';
|
||||
mutations[types.UPDATE_RELEASE_TAG_NAME](state, newTag);
|
||||
|
||||
expect(state.existingRelease).toBe(null);
|
||||
});
|
||||
});
|
||||
|
||||
describe(`${types.UPDATE_RELEASE_TAG_MESSAGE}`, () => {
|
||||
|
|
@ -304,6 +313,17 @@ describe('Release edit/new mutations', () => {
|
|||
expect(state.tagNotes).toBe('');
|
||||
expect(state.isFetchingTagNotes).toBe(false);
|
||||
});
|
||||
|
||||
it('nulls out existing release', () => {
|
||||
state.existingRelease = release;
|
||||
const message = 'there was an error';
|
||||
state.isFetchingTagNotes = true;
|
||||
state.tagNotes = 'tag notes';
|
||||
|
||||
mutations[types.RECEIVE_TAG_NOTES_ERROR](state, { message });
|
||||
|
||||
expect(state.existingRelease).toBe(null);
|
||||
});
|
||||
});
|
||||
describe(`${types.UPDATE_INCLUDE_TAG_NOTES}`, () => {
|
||||
it('sets whether or not to include the tag notes', () => {
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ RSpec.describe Gitlab::Auth::IpRateLimiter, :use_clean_rails_memory_store_cachin
|
|||
|
||||
before do
|
||||
stub_rack_attack_setting(options)
|
||||
Rack::Attack.reset!
|
||||
Gitlab::Redis::RateLimiting.with(&:flushdb)
|
||||
Rack::Attack.clear_configuration
|
||||
Gitlab::RackAttack.configure(Rack::Attack)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -9,23 +9,27 @@ RSpec.describe Gitlab::Ci::Artifacts::Logger do
|
|||
|
||||
describe '.log_created' do
|
||||
it 'logs information about created artifact' do
|
||||
artifact = create(:ci_job_artifact, :archive)
|
||||
artifact_1 = create(:ci_job_artifact, :archive)
|
||||
artifact_2 = create(:ci_job_artifact, :metadata)
|
||||
artifacts = [artifact_1, artifact_2]
|
||||
|
||||
expect(Gitlab::AppLogger).to receive(:info).with(
|
||||
hash_including(
|
||||
message: 'Artifact created',
|
||||
job_artifact_id: artifact.id,
|
||||
size: artifact.size,
|
||||
type: artifact.file_type,
|
||||
build_id: artifact.job_id,
|
||||
project_id: artifact.project_id,
|
||||
'correlation_id' => an_instance_of(String),
|
||||
'meta.feature_category' => 'test',
|
||||
'meta.caller_id' => 'caller'
|
||||
artifacts.each do |artifact|
|
||||
expect(Gitlab::AppLogger).to receive(:info).with(
|
||||
hash_including(
|
||||
message: 'Artifact created',
|
||||
job_artifact_id: artifact.id,
|
||||
size: artifact.size,
|
||||
type: artifact.file_type,
|
||||
build_id: artifact.job_id,
|
||||
project_id: artifact.project_id,
|
||||
'correlation_id' => an_instance_of(String),
|
||||
'meta.feature_category' => 'test',
|
||||
'meta.caller_id' => 'caller'
|
||||
)
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
described_class.log_created(artifact)
|
||||
described_class.log_created(artifacts)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::Ci::Config::External::File::Artifact do
|
||||
RSpec.describe Gitlab::Ci::Config::External::File::Artifact, feature_category: :pipeline_authoring do
|
||||
let(:parent_pipeline) { create(:ci_pipeline) }
|
||||
let(:variables) {}
|
||||
let(:context) do
|
||||
|
|
@ -31,7 +31,7 @@ RSpec.describe Gitlab::Ci::Config::External::File::Artifact do
|
|||
|
||||
describe '#valid?' do
|
||||
subject(:valid?) do
|
||||
external_file.validate!
|
||||
Gitlab::Ci::Config::External::Mapper::Verifier.new(context).process([external_file])
|
||||
external_file.valid?
|
||||
end
|
||||
|
||||
|
|
@ -162,7 +162,8 @@ RSpec.describe Gitlab::Ci::Config::External::File::Artifact do
|
|||
user: anything
|
||||
}
|
||||
expect(context).to receive(:mutate).with(expected_attrs).and_call_original
|
||||
external_file.validate!
|
||||
|
||||
expect(valid?).to be_truthy
|
||||
external_file.content
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::Ci::Config::External::File::Base do
|
||||
RSpec.describe Gitlab::Ci::Config::External::File::Base, feature_category: :pipeline_authoring do
|
||||
let(:variables) {}
|
||||
let(:context_params) { { sha: 'HEAD', variables: variables } }
|
||||
let(:context) { Gitlab::Ci::Config::External::Context.new(**context_params) }
|
||||
|
|
@ -51,7 +51,7 @@ RSpec.describe Gitlab::Ci::Config::External::File::Base do
|
|||
|
||||
describe '#valid?' do
|
||||
subject(:valid?) do
|
||||
file.validate!
|
||||
Gitlab::Ci::Config::External::Mapper::Verifier.new(context).process([file])
|
||||
file.valid?
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ RSpec.describe Gitlab::Ci::Config::External::File::Local, feature_category: :pip
|
|||
|
||||
describe '#valid?' do
|
||||
subject(:valid?) do
|
||||
local_file.validate!
|
||||
Gitlab::Ci::Config::External::Mapper::Verifier.new(context).process([local_file])
|
||||
local_file.valid?
|
||||
end
|
||||
|
||||
|
|
@ -142,9 +142,12 @@ RSpec.describe Gitlab::Ci::Config::External::File::Local, feature_category: :pip
|
|||
let(:variables) { Gitlab::Ci::Variables::Collection.new([{ 'key' => 'GITLAB_TOKEN', 'value' => 'secret', 'masked' => true }]) }
|
||||
let(:location) { '/lib/gitlab/ci/templates/secret/existent-file.yml' }
|
||||
|
||||
it 'returns false and adds an error message about an empty file' do
|
||||
before do
|
||||
allow_any_instance_of(described_class).to receive(:fetch_local_content).and_return("")
|
||||
local_file.validate!
|
||||
end
|
||||
|
||||
it 'returns false and adds an error message about an empty file' do
|
||||
expect(valid?).to be_falsy
|
||||
expect(local_file.errors).to include("Local file `lib/gitlab/ci/templates/xxxxxx/existent-file.yml` is empty!")
|
||||
end
|
||||
end
|
||||
|
|
@ -208,7 +211,7 @@ RSpec.describe Gitlab::Ci::Config::External::File::Local, feature_category: :pip
|
|||
let(:variables) { Gitlab::Ci::Variables::Collection.new([{ 'key' => 'GITLAB_TOKEN', 'value' => 'secret_file', 'masked' => true }]) }
|
||||
|
||||
before do
|
||||
local_file.validate!
|
||||
Gitlab::Ci::Config::External::Mapper::Verifier.new(context).process([local_file])
|
||||
end
|
||||
|
||||
it 'returns an error message' do
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ RSpec.describe Gitlab::Ci::Config::External::File::Project, feature_category: :p
|
|||
|
||||
describe '#valid?' do
|
||||
subject(:valid?) do
|
||||
project_file.validate!
|
||||
Gitlab::Ci::Config::External::Mapper::Verifier.new(context).process([project_file])
|
||||
project_file.valid?
|
||||
end
|
||||
|
||||
|
|
@ -79,7 +79,7 @@ RSpec.describe Gitlab::Ci::Config::External::File::Project, feature_category: :p
|
|||
{ project: project.full_path, file: '/file.yml' }
|
||||
end
|
||||
|
||||
around(:all) do |example|
|
||||
around do |example|
|
||||
create_and_delete_files(project, { '/file.yml' => 'image: image:1.0' }) do
|
||||
example.run
|
||||
end
|
||||
|
|
@ -102,7 +102,7 @@ RSpec.describe Gitlab::Ci::Config::External::File::Project, feature_category: :p
|
|||
{ project: project.full_path, ref: 'master', file: '/file.yml' }
|
||||
end
|
||||
|
||||
around(:all) do |example|
|
||||
around do |example|
|
||||
create_and_delete_files(project, { '/file.yml' => 'image: image:1.0' }) do
|
||||
example.run
|
||||
end
|
||||
|
|
@ -118,7 +118,7 @@ RSpec.describe Gitlab::Ci::Config::External::File::Project, feature_category: :p
|
|||
|
||||
let(:variables) { Gitlab::Ci::Variables::Collection.new([{ 'key' => 'GITLAB_TOKEN', 'value' => 'secret_file', 'masked' => true }]) }
|
||||
|
||||
around(:all) do |example|
|
||||
around do |example|
|
||||
create_and_delete_files(project, { '/secret_file.yml' => '' }) do
|
||||
example.run
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::Ci::Config::External::File::Remote do
|
||||
RSpec.describe Gitlab::Ci::Config::External::File::Remote, feature_category: :pipeline_authoring do
|
||||
include StubRequests
|
||||
|
||||
let(:variables) { Gitlab::Ci::Variables::Collection.new([{ 'key' => 'GITLAB_TOKEN', 'value' => 'secret_file', 'masked' => true }]) }
|
||||
|
|
@ -55,7 +55,7 @@ RSpec.describe Gitlab::Ci::Config::External::File::Remote do
|
|||
|
||||
describe "#valid?" do
|
||||
subject(:valid?) do
|
||||
remote_file.validate!
|
||||
Gitlab::Ci::Config::External::Mapper::Verifier.new(context).process([remote_file])
|
||||
remote_file.valid?
|
||||
end
|
||||
|
||||
|
|
@ -138,7 +138,7 @@ RSpec.describe Gitlab::Ci::Config::External::File::Remote do
|
|||
|
||||
describe "#error_message" do
|
||||
subject(:error_message) do
|
||||
remote_file.validate!
|
||||
Gitlab::Ci::Config::External::Mapper::Verifier.new(context).process([remote_file])
|
||||
remote_file.error_message
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::Ci::Config::External::File::Template do
|
||||
RSpec.describe Gitlab::Ci::Config::External::File::Template, feature_category: :pipeline_authoring do
|
||||
let_it_be(:project) { create(:project) }
|
||||
let_it_be(:user) { create(:user) }
|
||||
|
||||
|
|
@ -46,7 +46,7 @@ RSpec.describe Gitlab::Ci::Config::External::File::Template do
|
|||
|
||||
describe "#valid?" do
|
||||
subject(:valid?) do
|
||||
template_file.validate!
|
||||
Gitlab::Ci::Config::External::Mapper::Verifier.new(context).process([template_file])
|
||||
template_file.valid?
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::Redis::ClusterRateLimiting, feature_category: :redis do
|
||||
include_examples "redis_new_instance_shared_examples", 'cluster_rate_limiting', Gitlab::Redis::Cache
|
||||
end
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
require_migration!
|
||||
|
||||
RSpec.describe AddProjectIdNameIdVersionIndexToInstallableNpmPackages, feature_category: :package_registry do
|
||||
it 'schedules an index creation' do
|
||||
reversible_migration do |migration|
|
||||
migration.before -> {
|
||||
expect(ActiveRecord::Base.connection.indexes('packages_packages').map(&:name))
|
||||
.not_to include('idx_packages_on_project_id_name_id_version_when_installable_npm')
|
||||
}
|
||||
|
||||
migration.after -> {
|
||||
expect(ActiveRecord::Base.connection.indexes('packages_packages').map(&:name))
|
||||
.to include('idx_packages_on_project_id_name_id_version_when_installable_npm')
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
require_migration!
|
||||
|
||||
RSpec.describe FinalizeBackfillEnvironmentTierMigration, :migration, feature_category: :continuous_delivery do
|
||||
let(:batched_migrations) { table(:batched_background_migrations) }
|
||||
|
||||
let!(:migration) { described_class::MIGRATION }
|
||||
|
||||
describe '#up' do
|
||||
shared_examples 'finalizes the migration' do
|
||||
it 'finalizes the migration' do
|
||||
allow_next_instance_of(Gitlab::Database::BackgroundMigration::BatchedMigrationRunner) do |runner|
|
||||
expect(runner).to receive(:finalize).with('BackfillEnvironmentTiers', :environments, :id, [])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when migration is missing' do
|
||||
it 'warns migration not found' do
|
||||
expect(Gitlab::AppLogger)
|
||||
.to receive(:warn).with(/Could not find batched background migration for the given configuration:/)
|
||||
|
||||
migrate!
|
||||
end
|
||||
end
|
||||
|
||||
context 'with migration present' do
|
||||
let!(:group_member_namespace_id_backfill) do
|
||||
batched_migrations.create!(
|
||||
job_class_name: 'BackfillEnvironmentTiers',
|
||||
table_name: :environments,
|
||||
column_name: :id,
|
||||
job_arguments: [],
|
||||
interval: 2.minutes,
|
||||
min_value: 1,
|
||||
max_value: 2,
|
||||
batch_size: 1000,
|
||||
sub_batch_size: 200,
|
||||
gitlab_schema: :gitlab_main,
|
||||
status: 3 # finished
|
||||
)
|
||||
end
|
||||
|
||||
context 'when migration finished successfully' do
|
||||
it 'does not raise exception' do
|
||||
expect { migrate! }.not_to raise_error
|
||||
end
|
||||
end
|
||||
|
||||
context 'with different migration statuses' do
|
||||
using RSpec::Parameterized::TableSyntax
|
||||
|
||||
where(:status, :description) do
|
||||
0 | 'paused'
|
||||
1 | 'active'
|
||||
4 | 'failed'
|
||||
5 | 'finalizing'
|
||||
end
|
||||
|
||||
with_them do
|
||||
before do
|
||||
group_member_namespace_id_backfill.update!(status: status)
|
||||
end
|
||||
|
||||
it_behaves_like 'finalizes the migration'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -37,7 +37,7 @@ RSpec.describe Ci::JobArtifacts::CreateService do
|
|||
it 'logs the created artifact' do
|
||||
expect(Gitlab::Ci::Artifacts::Logger)
|
||||
.to receive(:log_created)
|
||||
.with(an_instance_of(Ci::JobArtifact))
|
||||
.with([an_instance_of(Ci::JobArtifact)])
|
||||
|
||||
subject
|
||||
end
|
||||
|
|
@ -132,6 +132,14 @@ RSpec.describe Ci::JobArtifacts::CreateService do
|
|||
expect(new_artifact).to be_public_accessibility
|
||||
end
|
||||
|
||||
it 'logs the created artifact and metadata' do
|
||||
expect(Gitlab::Ci::Artifacts::Logger)
|
||||
.to receive(:log_created)
|
||||
.with([an_instance_of(Ci::JobArtifact), an_instance_of(Ci::JobArtifact)])
|
||||
|
||||
subject
|
||||
end
|
||||
|
||||
context 'when accessibility level passed as private' do
|
||||
before do
|
||||
params.merge!('accessibility' => 'private')
|
||||
|
|
|
|||
|
|
@ -382,7 +382,7 @@ RSpec.shared_examples 'tracking when dry-run mode is set' do
|
|||
end
|
||||
|
||||
def reset_rack_attack
|
||||
Rack::Attack.reset!
|
||||
Gitlab::Redis::RateLimiting.with(&:flushdb)
|
||||
Rack::Attack.clear_configuration
|
||||
Gitlab::RackAttack.configure(Rack::Attack)
|
||||
end
|
||||
|
|
|
|||
Loading…
Reference in New Issue