diff --git a/GITLAB_KAS_VERSION b/GITLAB_KAS_VERSION
index 0f2d03f58cd..6517900b5fc 100644
--- a/GITLAB_KAS_VERSION
+++ b/GITLAB_KAS_VERSION
@@ -1 +1 @@
-70acd17ccd04ef784f793b1b00a84873e798b1dd
+2e27a8a56fb51a7359742453a6102e0cf20711de
diff --git a/db/docs/arkose_sessions.yml b/db/docs/arkose_sessions.yml
new file mode 100644
index 00000000000..fd3307dd8ee
--- /dev/null
+++ b/db/docs/arkose_sessions.yml
@@ -0,0 +1,13 @@
+---
+table_name: arkose_sessions
+classes:
+- Users::ArkoseSession
+feature_categories:
+- instance_resiliency
+description: Stores the session data received when verifying an Arkose Labs session for a user
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/194590
+milestone: '18.2'
+gitlab_schema: gitlab_main_user
+sharding_key:
+ user_id: users
+table_size: small
diff --git a/db/integer_ids_not_yet_initialized_to_bigint.yml b/db/integer_ids_not_yet_initialized_to_bigint.yml
index b0b67631f1c..2b96a80c6f5 100644
--- a/db/integer_ids_not_yet_initialized_to_bigint.yml
+++ b/db/integer_ids_not_yet_initialized_to_bigint.yml
@@ -1,7 +1,7 @@
# -- DON'T MANUALLY EDIT --
# Contains the list of integer IDs which were converted to bigint for new installations in
# https://gitlab.com/gitlab-org/gitlab/-/issues/438124, but they are still integers for existing instances.
-# On initialize_conversion_of_integer_to_bigint those integer IDs will be removed automatically from here.
+# On cleanup_conversion_of_integer_to_bigint those integer IDs will be removed automatically from here.
---
alert_management_alert_user_mentions:
- mentioned_groups_ids
diff --git a/db/migrate/20250616064108_create_arkose_sessions.rb b/db/migrate/20250616064108_create_arkose_sessions.rb
new file mode 100644
index 00000000000..6e8f332fa83
--- /dev/null
+++ b/db/migrate/20250616064108_create_arkose_sessions.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+class CreateArkoseSessions < Gitlab::Database::Migration[2.3]
+ milestone '18.2'
+
+ def change
+ create_table :arkose_sessions do |t|
+ t.timestamptz :session_created_at, null: true
+ t.timestamptz :checked_answer_at, null: true
+ t.timestamptz :verified_at, null: false, index: true
+ t.references :user, null: false, foreign_key: { on_delete: :cascade }, index: true
+ t.integer :global_score, null: true
+ t.integer :custom_score, null: true
+ t.boolean :challenge_shown, null: false, default: false
+ t.boolean :challenge_solved, null: false, default: false
+ t.boolean :session_is_legit, null: false, default: true
+ t.boolean :is_tor, null: false, default: false
+ t.boolean :is_vpn, null: false, default: false
+ t.boolean :is_proxy, null: false, default: false
+ t.boolean :is_bot, null: false, default: false
+ t.text :session_xid, limit: 64, null: false, index: true
+ t.text :telltale_user, null: true, limit: 128
+ t.text :user_agent, null: true, limit: 255
+ t.text :user_language_shown, null: true, limit: 64
+ t.text :device_xid, null: true, limit: 64
+ t.text :telltale_list, null: false, array: true, default: []
+ t.text :user_ip, null: true, limit: 64
+ t.text :country, null: true, limit: 64
+ t.text :region, null: true, limit: 64
+ t.text :city, null: true, limit: 64
+ t.text :isp, null: true, limit: 128
+ t.text :connection_type, null: true, limit: 64
+ t.text :risk_band, null: true, limit: 64
+ t.text :risk_category, null: true, limit: 64
+ end
+ end
+end
diff --git a/db/schema_migrations/20250616064108 b/db/schema_migrations/20250616064108
new file mode 100644
index 00000000000..f7f3304379a
--- /dev/null
+++ b/db/schema_migrations/20250616064108
@@ -0,0 +1 @@
+5f079f283cdc1757efb2f480d4979f4874ebf2619d88dc6c6778f6c8130b643e
\ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index 0df9c3445d4..5f7d03ae302 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -10003,6 +10003,59 @@ CREATE TABLE ar_internal_metadata (
updated_at timestamp(6) without time zone NOT NULL
);
+CREATE TABLE arkose_sessions (
+ id bigint NOT NULL,
+ session_created_at timestamp with time zone,
+ checked_answer_at timestamp with time zone,
+ verified_at timestamp with time zone NOT NULL,
+ user_id bigint NOT NULL,
+ global_score integer,
+ custom_score integer,
+ challenge_shown boolean DEFAULT false NOT NULL,
+ challenge_solved boolean DEFAULT false NOT NULL,
+ session_is_legit boolean DEFAULT true NOT NULL,
+ is_tor boolean DEFAULT false NOT NULL,
+ is_vpn boolean DEFAULT false NOT NULL,
+ is_proxy boolean DEFAULT false NOT NULL,
+ is_bot boolean DEFAULT false NOT NULL,
+ session_xid text NOT NULL,
+ telltale_user text,
+ user_agent text,
+ user_language_shown text,
+ device_xid text,
+ telltale_list text[] DEFAULT '{}'::text[] NOT NULL,
+ user_ip text,
+ country text,
+ region text,
+ city text,
+ isp text,
+ connection_type text,
+ risk_band text,
+ risk_category text,
+ CONSTRAINT check_1a6f4682be CHECK ((char_length(user_agent) <= 255)),
+ CONSTRAINT check_1ccf4778d0 CHECK ((char_length(telltale_user) <= 128)),
+ CONSTRAINT check_20eae4e360 CHECK ((char_length(risk_band) <= 64)),
+ CONSTRAINT check_394c3c0153 CHECK ((char_length(session_xid) <= 64)),
+ CONSTRAINT check_5a92894aa9 CHECK ((char_length(device_xid) <= 64)),
+ CONSTRAINT check_8d83d12f95 CHECK ((char_length(user_ip) <= 64)),
+ CONSTRAINT check_940ffc498d CHECK ((char_length(risk_category) <= 64)),
+ CONSTRAINT check_9b4c7551e7 CHECK ((char_length(city) <= 64)),
+ CONSTRAINT check_b81756eb85 CHECK ((char_length(isp) <= 128)),
+ CONSTRAINT check_ba409cc401 CHECK ((char_length(region) <= 64)),
+ CONSTRAINT check_c745f5db92 CHECK ((char_length(country) <= 64)),
+ CONSTRAINT check_cd4cc1f7dc CHECK ((char_length(user_language_shown) <= 64)),
+ CONSTRAINT check_d4fd1df18c CHECK ((char_length(connection_type) <= 64))
+);
+
+CREATE SEQUENCE arkose_sessions_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+ALTER SEQUENCE arkose_sessions_id_seq OWNED BY arkose_sessions.id;
+
CREATE TABLE atlassian_identities (
user_id bigint NOT NULL,
created_at timestamp with time zone NOT NULL,
@@ -27415,6 +27468,8 @@ ALTER TABLE ONLY approver_groups ALTER COLUMN id SET DEFAULT nextval('approver_g
ALTER TABLE ONLY approvers ALTER COLUMN id SET DEFAULT nextval('approvers_id_seq'::regclass);
+ALTER TABLE ONLY arkose_sessions ALTER COLUMN id SET DEFAULT nextval('arkose_sessions_id_seq'::regclass);
+
ALTER TABLE ONLY atlassian_identities ALTER COLUMN user_id SET DEFAULT nextval('atlassian_identities_user_id_seq'::regclass);
ALTER TABLE ONLY audit_events ALTER COLUMN id SET DEFAULT nextval('audit_events_id_seq'::regclass);
@@ -29532,6 +29587,9 @@ ALTER TABLE ONLY approvers
ALTER TABLE ONLY ar_internal_metadata
ADD CONSTRAINT ar_internal_metadata_pkey PRIMARY KEY (key);
+ALTER TABLE ONLY arkose_sessions
+ ADD CONSTRAINT arkose_sessions_pkey PRIMARY KEY (id);
+
ALTER TABLE ONLY atlassian_identities
ADD CONSTRAINT atlassian_identities_pkey PRIMARY KEY (user_id);
@@ -34594,6 +34652,12 @@ CREATE INDEX index_approvers_on_target_id_and_target_type ON approvers USING btr
CREATE INDEX index_approvers_on_user_id ON approvers USING btree (user_id);
+CREATE INDEX index_arkose_sessions_on_session_xid ON arkose_sessions USING btree (session_xid);
+
+CREATE INDEX index_arkose_sessions_on_user_id ON arkose_sessions USING btree (user_id);
+
+CREATE INDEX index_arkose_sessions_on_verified_at ON arkose_sessions USING btree (verified_at);
+
CREATE UNIQUE INDEX index_atlassian_identities_on_extern_uid ON atlassian_identities USING btree (extern_uid);
CREATE UNIQUE INDEX index_audit_events_external_audit_on_verification_token ON audit_events_external_audit_event_destinations USING btree (verification_token);
@@ -45738,6 +45802,9 @@ ALTER TABLE ONLY service_desk_custom_email_credentials
ALTER TABLE ONLY software_license_policies
ADD CONSTRAINT fk_rails_87b2247ce5 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
+ALTER TABLE ONLY arkose_sessions
+ ADD CONSTRAINT fk_rails_87ceb2456f FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY achievements
ADD CONSTRAINT fk_rails_87e990f752 FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;
diff --git a/doc/api/graphql/reference/_index.md b/doc/api/graphql/reference/_index.md
index 39bcb0b4a9c..3286d4cdf95 100644
--- a/doc/api/graphql/reference/_index.md
+++ b/doc/api/graphql/reference/_index.md
@@ -6596,6 +6596,7 @@ Input type: `GroupAuditEventStreamingDestinationsUpdateInput`
| Name | Type | Description |
| ---- | ---- | ----------- |
+| `active` | [`Boolean`](#boolean) | Active status of the destination. |
| `category` | [`String`](#string) | Destination category. |
| `clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| `config` | [`JSON`](#json) | Destination config. |
@@ -7029,6 +7030,7 @@ Input type: `InstanceAuditEventStreamingDestinationsUpdateInput`
| Name | Type | Description |
| ---- | ---- | ----------- |
+| `active` | [`Boolean`](#boolean) | Active status of the destination. |
| `category` | [`String`](#string) | Destination category. |
| `clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| `config` | [`JSON`](#json) | Destination config. |
@@ -30439,6 +30441,7 @@ Represents an external destination to stream group level audit events.
| Name | Type | Description |
| ---- | ---- | ----------- |
+| `active` | [`Boolean!`](#boolean) | Active status of the destination. |
| `category` | [`String!`](#string) | Category of the external destination to send audit events to. |
| `config` | [`JSON!`](#json) | Config of the external destination. |
| `eventTypeFilters` | [`[String!]!`](#string) | List of event type filters added for streaming. |
@@ -31034,6 +31037,7 @@ Represents an external destination to stream instance level audit events.
| Name | Type | Description |
| ---- | ---- | ----------- |
+| `active` | [`Boolean!`](#boolean) | Active status of the destination. |
| `category` | [`String!`](#string) | Category of the external destination to send audit events to. |
| `config` | [`JSON!`](#json) | Config of the external destination. |
| `eventTypeFilters` | [`[String!]!`](#string) | List of event type filters added for streaming. |
@@ -49589,6 +49593,7 @@ Implementations:
| Name | Type | Description |
| ---- | ---- | ----------- |
+| `active` | [`Boolean!`](#boolean) | Active status of the destination. |
| `category` | [`String!`](#string) | Category of the external destination to send audit events to. |
| `config` | [`JSON!`](#json) | Config of the external destination. |
| `eventTypeFilters` | [`[String!]!`](#string) | List of event type filters added for streaming. |
diff --git a/doc/development/database/avoiding_downtime_in_migrations.md b/doc/development/database/avoiding_downtime_in_migrations.md
index 1d263a894a4..3bd55b2a607 100644
--- a/doc/development/database/avoiding_downtime_in_migrations.md
+++ b/doc/development/database/avoiding_downtime_in_migrations.md
@@ -655,7 +655,7 @@ end
{{< alert type="note" >}}
- With [Issue#438124](https://gitlab.com/gitlab-org/gitlab/-/issues/438124) new instances have all ID columns in bigint.
- The list of IDs yet to be converted to bigint in old instances (includes `Gitlab.com` SaaS) is maintained in `db/integer_ids_not_yet_initialized_to_bigint.yml`.
+ The list of IDs yet to be converted to bigint in old instances (includes `Gitlab.com` SaaS) is maintained in `db/integer_ids_not_yet_initialized_to_bigint.yml`. **Do not edit this file manually** - it gets automatically updated during the [cleanup process](https://gitlab.com/gitlab-org/gitlab/-/blob/c6f4ea1bf1d693f1a0379964dd83a4bfec3e2f8d/lib/gitlab/database/migrations/conversions/bigint_converter.rb#L17-23).
- Since the schema file already has all IDs in `bigint`, don't push any changes to `db/structure.sql`.
{{< /alert >}}
diff --git a/doc/install/package/_index.md b/doc/install/package/_index.md
index 4b2da199bd2..9ec032280b9 100644
--- a/doc/install/package/_index.md
+++ b/doc/install/package/_index.md
@@ -135,6 +135,7 @@ release for them can be found below:
| OpenSUSE 15.3 | [December 2022](https://en.opensuse.org/Lifetime#Discontinued_distributions) | [GitLab CE](https://packages.gitlab.com/app/gitlab/gitlab-ce/search?q=gitlab-ce-15.10&dist=opensuse%2F15.3) / [GitLab EE](https://packages.gitlab.com/app/gitlab/gitlab-ee/search?q=gitlab-ee-15.10&dist=opensuse%2F15.3) 15.10 |
| OpenSUSE 15.4 | [December 2023](https://en.opensuse.org/Lifetime#Discontinued_distributions) | [GitLab CE](https://packages.gitlab.com/app/gitlab/gitlab-ce/search?q=gitlab-ce-16.7&dist=opensuse%2F15.4) / [GitLab EE](https://packages.gitlab.com/app/gitlab/gitlab-ee/search?q=gitlab-ee-16.7&dist=opensuse%2F15.4) 16.7 |
| OpenSUSE 15.5 | [December 2024](https://en.opensuse.org/Lifetime#Discontinued_distributions) | [GitLab CE](https://packages.gitlab.com/app/gitlab/gitlab-ce/search?q=gitlab-ce-17.8&dist=opensuse%2F15.5) / [GitLab EE](https://packages.gitlab.com/app/gitlab/gitlab-ee/search?q=gitlab-ee-17.8&dist=opensuse%2F15.5) 17.8 |
+| SLES 15 SP2 | [December 2024](https://www.suse.com/lifecycle/#suse-linux-enterprise-server-15) | [GitLab EE](https://packages.gitlab.com/app/gitlab/gitlab-ee/search?q=gitlab-ee-18.1&filter=all&filter=all&dist=sles%2F15.2) |
| Raspbian Wheezy | [May 2015](https://downloads.raspberrypi.org/raspbian/images/raspbian-2015-05-07/) | [GitLab CE](https://packages.gitlab.com/app/gitlab/raspberry-pi2/search?q=gitlab-ce_8.17&dist=debian%2Fwheezy) 8.17 |
| Raspbian Jessie | [May 2017](https://downloads.raspberrypi.org/raspbian/images/raspbian-2017-07-05/) | [GitLab CE](https://packages.gitlab.com/app/gitlab/raspberry-pi2/search?q=gitlab-ce_11.7&dist=debian%2Fjessie) 11.7 |
| Raspbian Stretch | [June 2020](https://downloads.raspberrypi.org/raspbian/images/raspbian-2019-04-09/) | [GitLab CE](https://packages.gitlab.com/app/gitlab/raspberry-pi2/search?q=gitlab-ce_13.3&dist=raspbian%2Fstretch) 13.3 |
diff --git a/doc/install/package/suse.md b/doc/install/package/suse.md
index 50b7fdd63c1..f7fdc593794 100644
--- a/doc/install/package/suse.md
+++ b/doc/install/package/suse.md
@@ -25,7 +25,7 @@ supported distributions and architectures.
- OS requirements:
- OpenSUSE Leap 15.6
- SLES 12
- - SLES 15
+ - SLES 15 SP6
- See the [installation requirements](../requirements.md) to learn about the
minimum hardware requirements.
- Before you begin, make sure you have correctly
diff --git a/lib/gitlab/database/migrations/conversions/bigint_converter.rb b/lib/gitlab/database/migrations/conversions/bigint_converter.rb
index 4457c4df9c1..17ca815ed17 100644
--- a/lib/gitlab/database/migrations/conversions/bigint_converter.rb
+++ b/lib/gitlab/database/migrations/conversions/bigint_converter.rb
@@ -19,7 +19,7 @@ module Gitlab
# -- DON'T MANUALLY EDIT --
# Contains the list of integer IDs which were converted to bigint for new installations in
# https://gitlab.com/gitlab-org/gitlab/-/issues/438124, but they are still integers for existing instances.
- # On initialize_conversion_of_integer_to_bigint those integer IDs will be removed automatically from here.
+ # On cleanup_conversion_of_integer_to_bigint those integer IDs will be removed automatically from here.
MESSAGE
def initialize(migration, table, columns)
diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb
index a46867ff2d5..e1a29a0a4b6 100644
--- a/spec/models/ci/pipeline_spec.rb
+++ b/spec/models/ci/pipeline_spec.rb
@@ -6577,4 +6577,12 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep, feature_category:
expect(pipeline.queued_duration).to be_nil
end
end
+
+ describe "association dependent" do
+ it_behaves_like "cleanup by a loose foreign key", on_delete: :async_nullify do
+ let!(:lfk_column) { :trigger_id }
+ let!(:parent) { create(:ci_trigger) }
+ let!(:model) { create(:ci_pipeline, trigger: parent) }
+ end
+ end
end
diff --git a/spec/support/shared_examples/loose_foreign_keys/have_loose_foreign_key.rb b/spec/support/shared_examples/loose_foreign_keys/have_loose_foreign_key.rb
index 2045a1d3e14..9e2161b775f 100644
--- a/spec/support/shared_examples/loose_foreign_keys/have_loose_foreign_key.rb
+++ b/spec/support/shared_examples/loose_foreign_keys/have_loose_foreign_key.rb
@@ -59,10 +59,12 @@ RSpec.shared_examples 'it has loose foreign keys' do
end
end
-RSpec.shared_examples 'cleanup by a loose foreign key' do
+RSpec.shared_examples 'cleanup by a loose foreign key' do |on_delete: nil|
include_context 'for loose foreign keys'
it 'cleans up (delete or nullify) the model' do
+ expect(foreign_key_definition.on_delete).to eq(on_delete.to_sym) if on_delete.present?
+
puts("##+ Additional Debug Logs for LFK flakiness +##")
puts("## Parent: #{parent.inspect} ##")
parent.delete