提交 bc692af9 编写于 作者: G GitLab Bot

Add latest changes from gitlab-org/gitlab@master

上级 66108e3b
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
### Tasks to Evaluate ### Tasks to Evaluate
<!-- Outline the tasks with issues that you need evaluate as a part of the implementation issue --> <!-- Outline the tasks with issues that you need to evaluate as a part of the implementation issue -->
- [ ] Determine feasibility of the feature - [ ] Determine feasibility of the feature
- [ ] Create issue for implementation or update existing implementation issue description with implementation proposal - [ ] Create issue for implementation or update existing implementation issue description with implementation proposal
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
### Risks and Implementation Considerations ### Risks and Implementation Considerations
<!-- Idenitfy any risks found in the research, whether this is performance, impacts to other functionality or other bugs --> <!-- Identify any risks found in the research, whether this is performance, impacts to other functionality or other bugs -->
### Team ### Team
......
# frozen_string_literal: true
module Ci
class FreezePeriod < ApplicationRecord
include StripAttribute
self.table_name = 'ci_freeze_periods'
belongs_to :project, inverse_of: :freeze_periods
strip_attributes :freeze_start, :freeze_end
validates :freeze_start, cron: true, presence: true
validates :freeze_end, cron: true, presence: true
validates :cron_timezone, cron_freeze_period_timezone: true, presence: true
end
end
...@@ -302,6 +302,7 @@ class Project < ApplicationRecord ...@@ -302,6 +302,7 @@ class Project < ApplicationRecord
has_many :project_deploy_tokens has_many :project_deploy_tokens
has_many :deploy_tokens, through: :project_deploy_tokens has_many :deploy_tokens, through: :project_deploy_tokens
has_many :resource_groups, class_name: 'Ci::ResourceGroup', inverse_of: :project has_many :resource_groups, class_name: 'Ci::ResourceGroup', inverse_of: :project
has_many :freeze_periods, class_name: 'Ci::FreezePeriod', inverse_of: :project
has_one :auto_devops, class_name: 'ProjectAutoDevops', inverse_of: :project, autosave: true has_one :auto_devops, class_name: 'ProjectAutoDevops', inverse_of: :project, autosave: true
has_many :custom_attributes, class_name: 'ProjectCustomAttribute' has_many :custom_attributes, class_name: 'ProjectCustomAttribute'
......
# frozen_string_literal: true
module Ci
class CompareAccessibilityReportsService < CompareReportsBaseService
def comparer_class
Gitlab::Ci::Reports::AccessibilityReportsComparer
end
def serializer_class
AccessibilityReportsComparerSerializer
end
def get_report(pipeline)
pipeline&.accessibility_reports
end
end
end
# frozen_string_literal: true
# CronTimezoneValidator
#
# Custom validator for CronTimezone.
class CronFreezePeriodTimezoneValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
freeze_start_parser = Gitlab::Ci::CronParser.new(record.freeze_start, record.cron_timezone)
freeze_end_parser = Gitlab::Ci::CronParser.new(record.freeze_end, record.cron_timezone)
record.errors.add(attribute, " is invalid syntax") unless freeze_start_parser.cron_timezone_valid? && freeze_end_parser.cron_timezone_valid?
end
end
# frozen_string_literal: true # frozen_string_literal: true
# CronValidator
#
# Custom validator for Cron.
class CronValidator < ActiveModel::EachValidator class CronValidator < ActiveModel::EachValidator
ATTRIBUTE_WHITELIST = %i[cron freeze_start freeze_end].freeze
NonWhitelistedAttributeError = Class.new(StandardError)
def validate_each(record, attribute, value) def validate_each(record, attribute, value)
cron_parser = Gitlab::Ci::CronParser.new(record.cron, record.cron_timezone) if ATTRIBUTE_WHITELIST.include?(attribute)
record.errors.add(attribute, " is invalid syntax") unless cron_parser.cron_valid? cron_parser = Gitlab::Ci::CronParser.new(record.public_send(attribute), record.cron_timezone) # rubocop:disable GitlabSecurity/PublicSend
record.errors.add(attribute, " is invalid syntax") unless cron_parser.cron_valid?
else
raise NonWhitelistedAttributeError.new "Non-whitelisted attribute"
end
end end
end end
---
title: Add freeze period model
merge_request: 29162
author:
type: added
---
title: Organize package models by package type
merge_request: 31346
author: Sashi Kumar
type: other
# frozen_string_literal: true
class CreateCiFreezePeriods < ActiveRecord::Migration[6.0]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
def up
unless table_exists?(:ci_freeze_periods)
create_table :ci_freeze_periods do |t|
t.references :project, foreign_key: true, null: false
t.text :freeze_start, null: false
t.text :freeze_end, null: false
t.text :cron_timezone, null: false
t.timestamps_with_timezone null: false
end
end
add_text_limit :ci_freeze_periods, :freeze_start, 998
add_text_limit :ci_freeze_periods, :freeze_end, 998
add_text_limit :ci_freeze_periods, :cron_timezone, 255
end
def down
drop_table :ci_freeze_periods
end
end
...@@ -1069,6 +1069,25 @@ CREATE SEQUENCE public.ci_daily_report_results_id_seq ...@@ -1069,6 +1069,25 @@ CREATE SEQUENCE public.ci_daily_report_results_id_seq
ALTER SEQUENCE public.ci_daily_report_results_id_seq OWNED BY public.ci_daily_report_results.id; ALTER SEQUENCE public.ci_daily_report_results_id_seq OWNED BY public.ci_daily_report_results.id;
CREATE TABLE public.ci_freeze_periods (
id bigint NOT NULL,
project_id bigint NOT NULL,
freeze_start character varying(998) NOT NULL,
freeze_end character varying(998) NOT NULL,
cron_timezone character varying(255) NOT NULL,
created_at timestamp with time zone NOT NULL,
updated_at timestamp with time zone NOT NULL
);
CREATE SEQUENCE public.ci_freeze_periods_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
ALTER SEQUENCE public.ci_freeze_periods_id_seq OWNED BY public.ci_freeze_periods.id;
CREATE TABLE public.ci_group_variables ( CREATE TABLE public.ci_group_variables (
id integer NOT NULL, id integer NOT NULL,
key character varying NOT NULL, key character varying NOT NULL,
...@@ -7319,6 +7338,8 @@ ALTER TABLE ONLY public.ci_daily_build_group_report_results ALTER COLUMN id SET ...@@ -7319,6 +7338,8 @@ ALTER TABLE ONLY public.ci_daily_build_group_report_results ALTER COLUMN id SET
ALTER TABLE ONLY public.ci_daily_report_results ALTER COLUMN id SET DEFAULT nextval('public.ci_daily_report_results_id_seq'::regclass); ALTER TABLE ONLY public.ci_daily_report_results ALTER COLUMN id SET DEFAULT nextval('public.ci_daily_report_results_id_seq'::regclass);
ALTER TABLE ONLY public.ci_freeze_periods ALTER COLUMN id SET DEFAULT nextval('public.ci_freeze_periods_id_seq'::regclass);
ALTER TABLE ONLY public.ci_group_variables ALTER COLUMN id SET DEFAULT nextval('public.ci_group_variables_id_seq'::regclass); ALTER TABLE ONLY public.ci_group_variables ALTER COLUMN id SET DEFAULT nextval('public.ci_group_variables_id_seq'::regclass);
ALTER TABLE ONLY public.ci_instance_variables ALTER COLUMN id SET DEFAULT nextval('public.ci_instance_variables_id_seq'::regclass); ALTER TABLE ONLY public.ci_instance_variables ALTER COLUMN id SET DEFAULT nextval('public.ci_instance_variables_id_seq'::regclass);
...@@ -7992,6 +8013,9 @@ ALTER TABLE ONLY public.ci_daily_build_group_report_results ...@@ -7992,6 +8013,9 @@ ALTER TABLE ONLY public.ci_daily_build_group_report_results
ALTER TABLE ONLY public.ci_daily_report_results ALTER TABLE ONLY public.ci_daily_report_results
ADD CONSTRAINT ci_daily_report_results_pkey PRIMARY KEY (id); ADD CONSTRAINT ci_daily_report_results_pkey PRIMARY KEY (id);
ALTER TABLE ONLY public.ci_freeze_periods
ADD CONSTRAINT ci_freeze_periods_pkey PRIMARY KEY (id);
ALTER TABLE ONLY public.ci_group_variables ALTER TABLE ONLY public.ci_group_variables
ADD CONSTRAINT ci_group_variables_pkey PRIMARY KEY (id); ADD CONSTRAINT ci_group_variables_pkey PRIMARY KEY (id);
...@@ -9190,6 +9214,8 @@ CREATE INDEX index_ci_daily_build_group_report_results_on_last_pipeline_id ON pu ...@@ -9190,6 +9214,8 @@ CREATE INDEX index_ci_daily_build_group_report_results_on_last_pipeline_id ON pu
CREATE INDEX index_ci_daily_report_results_on_last_pipeline_id ON public.ci_daily_report_results USING btree (last_pipeline_id); CREATE INDEX index_ci_daily_report_results_on_last_pipeline_id ON public.ci_daily_report_results USING btree (last_pipeline_id);
CREATE INDEX index_ci_freeze_periods_on_project_id ON public.ci_freeze_periods USING btree (project_id);
CREATE UNIQUE INDEX index_ci_group_variables_on_group_id_and_key ON public.ci_group_variables USING btree (group_id, key); CREATE UNIQUE INDEX index_ci_group_variables_on_group_id_and_key ON public.ci_group_variables USING btree (group_id, key);
CREATE UNIQUE INDEX index_ci_instance_variables_on_key ON public.ci_instance_variables USING btree (key); CREATE UNIQUE INDEX index_ci_instance_variables_on_key ON public.ci_instance_variables USING btree (key);
...@@ -11670,6 +11696,9 @@ ALTER TABLE ONLY public.geo_repository_updated_events ...@@ -11670,6 +11696,9 @@ ALTER TABLE ONLY public.geo_repository_updated_events
ALTER TABLE ONLY public.protected_branch_unprotect_access_levels ALTER TABLE ONLY public.protected_branch_unprotect_access_levels
ADD CONSTRAINT fk_rails_2d2aba21ef FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE; ADD CONSTRAINT fk_rails_2d2aba21ef FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE;
ALTER TABLE ONLY public.ci_freeze_periods
ADD CONSTRAINT fk_rails_2e02bbd1a6 FOREIGN KEY (project_id) REFERENCES public.projects(id);
ALTER TABLE ONLY public.saml_providers ALTER TABLE ONLY public.saml_providers
ADD CONSTRAINT fk_rails_306d459be7 FOREIGN KEY (group_id) REFERENCES public.namespaces(id) ON DELETE CASCADE; ADD CONSTRAINT fk_rails_306d459be7 FOREIGN KEY (group_id) REFERENCES public.namespaces(id) ON DELETE CASCADE;
...@@ -13659,6 +13688,7 @@ COPY "schema_migrations" (version) FROM STDIN; ...@@ -13659,6 +13688,7 @@ COPY "schema_migrations" (version) FROM STDIN;
20200407182205 20200407182205
20200407222647 20200407222647
20200408110856 20200408110856
20200408125046
20200408133211 20200408133211
20200408153842 20200408153842
20200408154331 20200408154331
......
...@@ -31,9 +31,6 @@ by [installing GitLab](../../install/README.md) on a single machine to minimize ...@@ -31,9 +31,6 @@ by [installing GitLab](../../install/README.md) on a single machine to minimize
If your organization has more than 2,000 users, the recommendation is to scale GitLab's components to multiple If your organization has more than 2,000 users, the recommendation is to scale GitLab's components to multiple
machine nodes. The machine nodes are grouped by component(s). The addition of these machine nodes. The machine nodes are grouped by component(s). The addition of these
nodes increases the performance and scalability of to your GitLab instance. nodes increases the performance and scalability of to your GitLab instance.
As long as there is at least one of each component online and capable of handling
the instance's usage load, your team's productivity will not be interrupted.
Scaling GitLab in this manner also enables you to perform [zero-downtime updates](https://docs.gitlab.com/omnibus/update/#zero-downtime-updates).
When scaling GitLab, there are several factors to consider: When scaling GitLab, there are several factors to consider:
...@@ -60,13 +57,14 @@ The following reference architectures are available: ...@@ -60,13 +57,14 @@ The following reference architectures are available:
- [Up to 25,000 users](25k_users.md) - [Up to 25,000 users](25k_users.md)
- [Up to 50,000 users](50k_users.md) - [Up to 50,000 users](50k_users.md)
## Availability complexity ## Availability components
GitLab comes with the following availability complexity for your use, listed from GitLab comes with the following availability components for your use, listed from
least to most complex: least to most complex:
1. [Automated backups](#automated-backups-core-only) 1. [Automated backups](#automated-backups-core-only)
1. [Traffic Load Balancer](#Traffic-load-balancer-starter-only) 1. [Traffic load balancer](#traffic-load-balancer-starter-only)
1. [Zero downtime updates](#zero-downtime-updates-starter-only)
1. [Automated database failover](#automated-database-failover-premium-only) 1. [Automated database failover](#automated-database-failover-premium-only)
1. [Instance level replication with GitLab Geo](#instance-level-replication-with-gitlab-geo-premium-only) 1. [Instance level replication with GitLab Geo](#instance-level-replication-with-gitlab-geo-premium-only)
...@@ -109,6 +107,16 @@ to the default installation: ...@@ -109,6 +107,16 @@ to the default installation:
- Enable zero-downtime upgrades. - Enable zero-downtime upgrades.
- Increase availability. - Increase availability.
### Zero downtime updates **(STARTER ONLY)**
> - Level of complexity: **Medium**
> - Required domain knowledge: PostgreSQL, HAProxy, shared storage, distributed systems
> - Supported tiers: [GitLab Starter, Premium, and Ultimate](https://about.gitlab.com/pricing/)
GitLab supports [zero-downtime updates](https://docs.gitlab.com/omnibus/update/#zero-downtime-updates).
Although you can perform zero-downtime updates with a single GitLab node, the recommendation is to separate GitLab into several application nodes.
As long as at least one of each component is online and capable of handling the instance's usage load, your team's productivity will not be interrupted during the update.
### Automated database failover **(PREMIUM ONLY)** ### Automated database failover **(PREMIUM ONLY)**
> - Level of complexity: **High** > - Level of complexity: **High**
......
...@@ -77,10 +77,11 @@ authentication is not provided. For ...@@ -77,10 +77,11 @@ authentication is not provided. For
those cases where it is not required, this will be mentioned in the documentation those cases where it is not required, this will be mentioned in the documentation
for each individual endpoint. For example, the [`/projects/:id` endpoint](projects.md). for each individual endpoint. For example, the [`/projects/:id` endpoint](projects.md).
There are four ways to authenticate with the GitLab API: There are several ways to authenticate with the GitLab API:
1. [OAuth2 tokens](#oauth2-tokens) 1. [OAuth2 tokens](#oauth2-tokens)
1. [Personal access tokens](#personal-access-tokens) 1. [Personal access tokens](../user/profile/personal_access_tokens.md)
1. [Project access tokens](../user/project/settings/project_access_tokens.md) **(CORE ONLY)**
1. [Session cookie](#session-cookie) 1. [Session cookie](#session-cookie)
1. [GitLab CI/CD job token](#gitlab-ci-job-token) **(Specific endpoints only)** 1. [GitLab CI/CD job token](#gitlab-ci-job-token) **(Specific endpoints only)**
...@@ -117,31 +118,29 @@ curl --header "Authorization: Bearer OAUTH-TOKEN" https://gitlab.example.com/api ...@@ -117,31 +118,29 @@ curl --header "Authorization: Bearer OAUTH-TOKEN" https://gitlab.example.com/api
Read more about [GitLab as an OAuth2 provider](oauth2.md). Read more about [GitLab as an OAuth2 provider](oauth2.md).
### Personal access tokens ### Personal/project access tokens
You can use a [personal access token](../user/profile/personal_access_tokens.md) to authenticate with the API by passing it in either the Access tokens can be used to authenticate with the API by passing it in either the `private_token` parameter
`private_token` parameter or the `Private-Token` header. or the `Private-Token` header.
Example of using the personal access token in a parameter: Example of using the personal/project access token in a parameter:
```shell ```shell
curl https://gitlab.example.com/api/v4/projects?private_token=<your_access_token> curl https://gitlab.example.com/api/v4/projects?private_token=<your_access_token>
``` ```
Example of using the personal access token in a header: Example of using the personal/project access token in a header:
```shell ```shell
curl --header "Private-Token: <your_access_token>" https://gitlab.example.com/api/v4/projects curl --header "Private-Token: <your_access_token>" https://gitlab.example.com/api/v4/projects
``` ```
You can also use personal access tokens with OAuth-compliant headers: You can also use personal/project access tokens with OAuth-compliant headers:
```shell ```shell
curl --header "Authorization: Bearer <your_access_token>" https://gitlab.example.com/api/v4/projects curl --header "Authorization: Bearer <your_access_token>" https://gitlab.example.com/api/v4/projects
``` ```
Read more about [personal access tokens](../user/profile/personal_access_tokens.md).
### Session cookie ### Session cookie
When signing in to the main GitLab application, a `_gitlab_session` cookie is When signing in to the main GitLab application, a `_gitlab_session` cookie is
......
...@@ -196,8 +196,8 @@ information like the file `name`, `side`, `sha1`, etc. ...@@ -196,8 +196,8 @@ information like the file `name`, `side`, `sha1`, etc.
If there is specific data necessary to be stored for only one package system support, If there is specific data necessary to be stored for only one package system support,
consider creating a separate metadata model. See `packages_maven_metadata` table consider creating a separate metadata model. See `packages_maven_metadata` table
and `Packages::MavenMetadatum` model as an example for package specific data, and `packages_conan_file_metadata` table and `Packages::Maven::Metadatum` model as an example for package specific data, and `packages_conan_file_metadata` table
and `Packages::ConanFileMetadatum` model as an example for package file specific data. and `Packages::Conan::FileMetadatum` model as an example for package file specific data.
If there is package specific behavior for a given package manager, add those methods to the metadata models and If there is package specific behavior for a given package manager, add those methods to the metadata models and
delegate from the package model. delegate from the package model.
......
...@@ -38,7 +38,8 @@ This page gathers all the resources for the topic **Authentication** within GitL ...@@ -38,7 +38,8 @@ This page gathers all the resources for the topic **Authentication** within GitL
## API ## API
- [OAuth 2 Tokens](../../api/README.md#oauth2-tokens) - [OAuth 2 Tokens](../../api/README.md#oauth2-tokens)
- [Personal access tokens](../../api/README.md#personal-access-tokens) - [Personal access tokens](../../api/README.md#personalproject-access-tokens)
- [Project access tokens](../../api/README.md#personalproject-access-tokens) **(CORE ONLY)**
- [Impersonation tokens](../../api/README.md#impersonation-tokens) - [Impersonation tokens](../../api/README.md#impersonation-tokens)
- [GitLab as an OAuth2 provider](../../api/oauth2.md#gitlab-as-an-oauth2-provider) - [GitLab as an OAuth2 provider](../../api/oauth2.md#gitlab-as-an-oauth2-provider)
......
...@@ -227,6 +227,8 @@ If your `.gitlab-ci.yml` extends these Auto DevOps templates and override the `o ...@@ -227,6 +227,8 @@ If your `.gitlab-ci.yml` extends these Auto DevOps templates and override the `o
`except` keywords, you must migrate your templates to use the `except` keywords, you must migrate your templates to use the
[`rules`](../../ci/yaml/README.md#rules) syntax after the [`rules`](../../ci/yaml/README.md#rules) syntax after the
base template is migrated to use the `rules` syntax. base template is migrated to use the `rules` syntax.
For users who cannot migrate just yet, you can alternatively pin your templates to
the [GitLab 12.10 based templates](https://gitlab.com/gitlab-org/auto-devops-v12-10).
## PostgreSQL database support ## PostgreSQL database support
......
...@@ -462,6 +462,22 @@ The following are possible reasons: ...@@ -462,6 +462,22 @@ The following are possible reasons:
Auto Test may fail because of a mismatch between testing frameworks. In this Auto Test may fail because of a mismatch between testing frameworks. In this
case, you may need to customize your `.gitlab-ci.yml` with your test commands. case, you may need to customize your `.gitlab-ci.yml` with your test commands.
### Pipeline that extends Auto DevOps with only / except fails
If your pipeline fails with the following message:
```plaintext
Found errors in your .gitlab-ci.yml:
jobs:test config key may not be used with `rules`: only
```
This error appears when the included job’s rules configuration has been overridden with the `only` or `except` syntax.
To fix this issue, you must either:
- Transition your `only/except` syntax to rules.
- (Temporarily) Pin your templates to the [GitLab 12.10 based templates](https://gitlab.com/gitlab-org/auto-devops-v12-10).
### Failure to create a Kubernetes namespace ### Failure to create a Kubernetes namespace
Auto Deploy will fail if GitLab can't create a Kubernetes namespace and Auto Deploy will fail if GitLab can't create a Kubernetes namespace and
......
...@@ -148,6 +148,7 @@ The following table depicts the various user permission levels in a project. ...@@ -148,6 +148,7 @@ The following table depicts the various user permission levels in a project.
| Delete wiki pages | | | | ✓ | ✓ | | Delete wiki pages | | | | ✓ | ✓ |
| View project Audit Events | | | | ✓ | ✓ | | View project Audit Events | | | | ✓ | ✓ |
| Manage [push rules](../push_rules/push_rules.md) | | | | ✓ | ✓ | | Manage [push rules](../push_rules/push_rules.md) | | | | ✓ | ✓ |
| Manage [project access tokens](./project/settings/project_access_tokens.md) **(CORE ONLY)** | | | | ✓ | ✓ |
| Switch visibility level | | | | | ✓ | | Switch visibility level | | | | | ✓ |
| Transfer project to another namespace | | | | | ✓ | | Transfer project to another namespace | | | | | ✓ |
| Remove fork relationship | | | | | ✓ | | Remove fork relationship | | | | | ✓ |
......
...@@ -8,7 +8,7 @@ type: concepts, howto ...@@ -8,7 +8,7 @@ type: concepts, howto
> - [Notifications about expiring tokens](https://gitlab.com/gitlab-org/gitlab/-/issues/3649) added in GitLab 12.6. > - [Notifications about expiring tokens](https://gitlab.com/gitlab-org/gitlab/-/issues/3649) added in GitLab 12.6.
> - [Token lifetime limits](https://gitlab.com/gitlab-org/gitlab/-/issues/3649) added in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.6. > - [Token lifetime limits](https://gitlab.com/gitlab-org/gitlab/-/issues/3649) added in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.6.
If you're unable to use [OAuth2](../../api/oauth2.md), you can use a personal access token to authenticate with the [GitLab API](../../api/README.md#personal-access-tokens). If you're unable to use [OAuth2](../../api/oauth2.md), you can use a personal access token to authenticate with the [GitLab API](../../api/README.md#personalproject-access-tokens).
You can also use personal access tokens with Git to authenticate over HTTP or SSH. Personal access tokens are required when [Two-Factor Authentication (2FA)](../account/two_factor_authentication.md) is enabled. In both cases, you can authenticate with a token in place of your password. You can also use personal access tokens with Git to authenticate over HTTP or SSH. Personal access tokens are required when [Two-Factor Authentication (2FA)](../account/two_factor_authentication.md) is enabled. In both cases, you can authenticate with a token in place of your password.
...@@ -17,7 +17,7 @@ Personal access tokens expire on the date you define, at midnight UTC. ...@@ -17,7 +17,7 @@ Personal access tokens expire on the date you define, at midnight UTC.
- GitLab runs a check at 01:00 AM UTC every day to identify personal access tokens that will expire in under seven days. The owners of these tokens are notified by email. - GitLab runs a check at 01:00 AM UTC every day to identify personal access tokens that will expire in under seven days. The owners of these tokens are notified by email.
- In GitLab Ultimate, administrators may [limit the lifetime of personal access tokens](../admin_area/settings/account_and_limit_settings.md#limiting-lifetime-of-personal-access-tokens-ultimate-only). - In GitLab Ultimate, administrators may [limit the lifetime of personal access tokens](../admin_area/settings/account_and_limit_settings.md#limiting-lifetime-of-personal-access-tokens-ultimate-only).
For examples of how you can use a personal access token to authenticate with the API, see the following section from our [API Docs](../../api/README.md#personal-access-tokens). For examples of how you can use a personal access token to authenticate with the API, see the following section from our [API Docs](../../api/README.md#personalproject-access-tokens).
GitLab also offers [impersonation tokens](../../api/README.md#impersonation-tokens) which are created by administrators via the API. They're a great fit for automated authentication as a specific user. GitLab also offers [impersonation tokens](../../api/README.md#impersonation-tokens) which are created by administrators via the API. They're a great fit for automated authentication as a specific user.
......
# Project access tokens **(CORE ONLY)**
> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/2587) in GitLab 13.0.
Project access tokens are scoped to a project and can be used to authenticate with the [GitLab API](../../../api/README.md#personalproject-access-tokens).
You can also use project access tokens with Git to authenticate over HTTP or SSH.
Project access tokens expire on the date you define, at midnight UTC.
For examples of how you can use a project access token to authenticate with the API, see the following section from our [API Docs](../../../api/README.md#personalproject-access-tokens).
## Creating a project access token
1. Log in to GitLab.
1. Navigate to the project you would like to create an access token for.
1. In the **{settings}** **Settings** menu choose **Access Tokens**.
1. Choose a name and optional expiry date for the token.
1. Choose the [desired scopes](#limiting-scopes-of-a-project-access-token).
1. Click the **Create project access token** button.
1. Save the project access token somewhere safe. Once you leave or refresh
the page, you won't be able to access it again.
## Project bot users
For each project access token created, a bot user will also be created and added to the project with
["Maintainer" level permissions](../../permissions.md#project-members-permissions). API calls made with a
project access token will be associated to the corresponding bot user.
These users will appear in **{settings}** **Settings > Members** but can not be modified.
Furthermore, the bot user can not be added to any other project.
When the project access token is [revoked](#revoking-a-project-access-token) the bot user will be deleted and all
records will be moved to a system-wide user with the username "Ghost User". For more information,
see [Associated Records](../../profile/account/delete_account.md#associated-records).
## Revoking a project access token
At any time, you can revoke any project access token by clicking the
respective **Revoke** button in **{settings}** **Settings > Access Tokens**.
## Limiting scopes of a project access token
Project access tokens can be created with one or more scopes that allow various
actions that a given token can perform. The available scopes are depicted in
the following table.
| Scope | Description |
| ------------------ | ----------- |
| `api` | Grants complete read/write access to scoped project API. |
| `read_api` | Grants read access to the scoped project API. |
| `read_registry` | Allows read-access (pull) to [container registry](../../packages/container_registry/index.md) images if a project is private and authorization is required. |
| `write_registry` | Allows write-access (push) to [container registry](../../packages/container_registry/index.md). |
| `read_repository` | Allows read-only access (pull) to the repository. |
| `write_repository` | Allows read-write access (pull, push) to the repository. |
...@@ -29,7 +29,7 @@ module Gitlab ...@@ -29,7 +29,7 @@ module Gitlab
return if Gitlab::Metrics::System.real_time < request_deadline return if Gitlab::Metrics::System.real_time < request_deadline
raise RequestDeadlineExceeded, raise RequestDeadlineExceeded,
"Request takes longer than #{max_request_duration_seconds}" "Request takes longer than #{max_request_duration_seconds} seconds"
end end
private private
......
...@@ -8,7 +8,7 @@ module Gitlab ...@@ -8,7 +8,7 @@ module Gitlab
# If enabled then it injects a job field that persists through the job execution # If enabled then it injects a job field that persists through the job execution
class Client class Client
def call(_worker_class, job, _queue, _redis_pool) def call(_worker_class, job, _queue, _redis_pool)
return yield unless Feature.enabled?(:user_mode_in_session) return yield unless ::Feature.enabled?(:user_mode_in_session)
# Admin mode enabled in the original request or in a nested sidekiq job # Admin mode enabled in the original request or in a nested sidekiq job
admin_mode_user_id = find_admin_user_id admin_mode_user_id = find_admin_user_id
...@@ -16,7 +16,7 @@ module Gitlab ...@@ -16,7 +16,7 @@ module Gitlab
if admin_mode_user_id if admin_mode_user_id
job['admin_mode_user_id'] ||= admin_mode_user_id job['admin_mode_user_id'] ||= admin_mode_user_id
Gitlab::AppLogger.debug("AdminMode::Client injected admin mode for job: #{job.inspect}") ::Gitlab::AppLogger.debug("AdminMode::Client injected admin mode for job: #{job.inspect}")
end end
yield yield
...@@ -25,8 +25,8 @@ module Gitlab ...@@ -25,8 +25,8 @@ module Gitlab
private private
def find_admin_user_id def find_admin_user_id
Gitlab::Auth::CurrentUserMode.current_admin&.id || ::Gitlab::Auth::CurrentUserMode.current_admin&.id ||
Gitlab::Auth::CurrentUserMode.bypass_session_admin_id ::Gitlab::Auth::CurrentUserMode.bypass_session_admin_id
end end
end end
end end
......
...@@ -15,8 +15,7 @@ Usage: rake "gitlab:gitaly:install[/installation/dir,/storage/path]") ...@@ -15,8 +15,7 @@ Usage: rake "gitlab:gitaly:install[/installation/dir,/storage/path]")
checkout_or_clone_version(version: version, repo: args.repo, target_dir: args.dir) checkout_or_clone_version(version: version, repo: args.repo, target_dir: args.dir)
command = %w[/usr/bin/env -u RUBYOPT -u BUNDLE_GEMFILE] command = []
_, status = Gitlab::Popen.popen(%w[which gmake]) _, status = Gitlab::Popen.popen(%w[which gmake])
command << (status.zero? ? 'gmake' : 'make') command << (status.zero? ? 'gmake' : 'make')
...@@ -31,7 +30,7 @@ Usage: rake "gitlab:gitaly:install[/installation/dir,/storage/path]") ...@@ -31,7 +30,7 @@ Usage: rake "gitlab:gitaly:install[/installation/dir,/storage/path]")
Dir.chdir(args.dir) do Dir.chdir(args.dir) do
# In CI we run scripts/gitaly-test-build instead of this command # In CI we run scripts/gitaly-test-build instead of this command
unless ENV['CI'].present? unless ENV['CI'].present?
Bundler.with_original_env { run_command!(command) } Bundler.with_original_env { Gitlab::Popen.popen(command, nil, { "RUBYOPT" => nil, "BUNDLE_GEMFILE" => nil }) }
end end
end end
end end
......
# frozen_string_literal: true
FactoryBot.define do
factory :ci_freeze_period, class: 'Ci::FreezePeriod' do
project
freeze_start { '0 23 * * 5' }
freeze_end { '0 7 * * 1' }
cron_timezone { 'UTC' }
end
end
...@@ -490,6 +490,7 @@ project: ...@@ -490,6 +490,7 @@ project:
- metrics_users_starred_dashboards - metrics_users_starred_dashboards
- alert_management_alerts - alert_management_alerts
- repository_storage_moves - repository_storage_moves
- freeze_periods
award_emoji: award_emoji:
- awardable - awardable
- user - user
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Ci::FreezePeriod, type: :model do
subject { build(:ci_freeze_period) }
it { is_expected.to belong_to(:project) }
it { is_expected.to respond_to(:freeze_start) }
it { is_expected.to respond_to(:freeze_end) }
it { is_expected.to respond_to(:cron_timezone) }
describe 'cron validations' do
it 'allows valid cron patterns' do
freeze_period = build(:ci_freeze_period, freeze_start: '0 23 * * 5')
expect(freeze_period).to be_valid
end
it 'does not allow invalid cron patterns' do
freeze_period = build(:ci_freeze_period, freeze_start: '0 0 0 * *')
expect(freeze_period).not_to be_valid
end
it 'does not allow non-cron strings' do
freeze_period = build(:ci_freeze_period, cron_timezone: 'invalid')
expect(freeze_period).not_to be_valid
end
context 'when cron contains trailing whitespaces' do
it 'strips the attribute' do
freeze_period = build(:ci_freeze_period, freeze_start: ' 0 0 * * * ')
expect(freeze_period).to be_valid
expect(freeze_period.freeze_start).to eq('0 0 * * *')
end
end
end
end
...@@ -22,13 +22,13 @@ describe Ci::PipelineSchedule do ...@@ -22,13 +22,13 @@ describe Ci::PipelineSchedule do
end end
describe 'validations' do describe 'validations' do
it 'does not allow invalid cron patters' do it 'does not allow invalid cron patterns' do
pipeline_schedule = build(:ci_pipeline_schedule, cron: '0 0 0 * *') pipeline_schedule = build(:ci_pipeline_schedule, cron: '0 0 0 * *')
expect(pipeline_schedule).not_to be_valid expect(pipeline_schedule).not_to be_valid
end end
it 'does not allow invalid cron patters' do it 'does not allow invalid cron patterns' do
pipeline_schedule = build(:ci_pipeline_schedule, cron_timezone: 'invalid') pipeline_schedule = build(:ci_pipeline_schedule, cron_timezone: 'invalid')
expect(pipeline_schedule).not_to be_valid expect(pipeline_schedule).not_to be_valid
......
...@@ -335,7 +335,7 @@ describe ApplicationSettings::UpdateService do ...@@ -335,7 +335,7 @@ describe ApplicationSettings::UpdateService do
end end
end end
context 'when issues_create_limit is passsed' do context 'when issues_create_limit is passed' do
let(:params) do let(:params) do
{ {
issues_create_limit: 600 issues_create_limit: 600
......
# frozen_string_literal: true
require 'spec_helper'
describe Ci::CompareAccessibilityReportsService do
let(:service) { described_class.new(project) }
let(:project) { create(:project, :repository) }
describe '#execute' do
subject { service.execute(base_pipeline, head_pipeline) }
context 'when head pipeline has accessibility reports' do
let(:base_pipeline) { nil }
let(:head_pipeline) { create(:ci_pipeline, :with_accessibility_reports, project: project) }
it 'returns status and data' do
expect(subject[:status]).to eq(:parsed)
expect(subject[:data]).to match_schema('entities/accessibility_reports_comparer')
end
end
context 'when base and head pipelines have accessibility reports' do
let(:base_pipeline) { create(:ci_pipeline, :with_accessibility_reports, project: project) }
let(:head_pipeline) { create(:ci_pipeline, :with_accessibility_reports, project: project) }
it 'returns status and data' do
expect(subject[:status]).to eq(:parsed)
expect(subject[:data]).to match_schema('entities/accessibility_reports_comparer')
end
end
end
describe '#latest?' do
subject { service.latest?(base_pipeline, head_pipeline, data) }
let!(:base_pipeline) { nil }
let!(:head_pipeline) { create(:ci_pipeline, :with_accessibility_reports, project: project) }
let!(:key) { service.send(:key, base_pipeline, head_pipeline) }
context 'when cache key is latest' do
let(:data) { { key: key } }
it { is_expected.to be_truthy }
end
context 'when cache key is outdated' do
before do
head_pipeline.update_column(:updated_at, 10.minutes.ago)
end
let(:data) { { key: key } }
it { is_expected.to be_falsy }
end
context 'when cache key is empty' do
let(:data) { { key: nil } }
it { is_expected.to be_falsy }
end
end
end
...@@ -53,8 +53,6 @@ describe 'gitlab:gitaly namespace rake task' do ...@@ -53,8 +53,6 @@ describe 'gitlab:gitaly namespace rake task' do
end end
describe 'gmake/make' do describe 'gmake/make' do
let(:command_preamble) { %w[/usr/bin/env -u RUBYOPT -u BUNDLE_GEMFILE] }
before do before do
stub_env('CI', false) stub_env('CI', false)
FileUtils.mkdir_p(clone_path) FileUtils.mkdir_p(clone_path)
...@@ -69,7 +67,7 @@ describe 'gitlab:gitaly namespace rake task' do ...@@ -69,7 +67,7 @@ describe 'gitlab:gitaly namespace rake task' do
it 'calls gmake in the gitaly directory' do it 'calls gmake in the gitaly directory' do
expect(Gitlab::Popen).to receive(:popen).with(%w[which gmake]).and_return(['/usr/bin/gmake', 0]) expect(Gitlab::Popen).to receive(:popen).with(%w[which gmake]).and_return(['/usr/bin/gmake', 0])
expect(main_object).to receive(:run_command!).with(command_preamble + %w[gmake]).and_return(true) expect(Gitlab::Popen).to receive(:popen).with(%w[gmake], nil, { "BUNDLE_GEMFILE" => nil, "RUBYOPT" => nil }).and_return(true)
subject subject
end end
...@@ -82,7 +80,7 @@ describe 'gitlab:gitaly namespace rake task' do ...@@ -82,7 +80,7 @@ describe 'gitlab:gitaly namespace rake task' do
end end
it 'calls make in the gitaly directory' do it 'calls make in the gitaly directory' do
expect(main_object).to receive(:run_command!).with(command_preamble + %w[make]).and_return(true) expect(Gitlab::Popen).to receive(:popen).with(%w[make], nil, { "BUNDLE_GEMFILE" => nil, "RUBYOPT" => nil }).and_return(true)
subject subject
end end
...@@ -99,7 +97,7 @@ describe 'gitlab:gitaly namespace rake task' do ...@@ -99,7 +97,7 @@ describe 'gitlab:gitaly namespace rake task' do
end end
it 'calls make in the gitaly directory with --no-deployment flag for bundle' do it 'calls make in the gitaly directory with --no-deployment flag for bundle' do
expect(main_object).to receive(:run_command!).with(command_preamble + command).and_return(true) expect(Gitlab::Popen).to receive(:popen).with(command, nil, { "BUNDLE_GEMFILE" => nil, "RUBYOPT" => nil }).and_return(true)
subject subject
end end
......
# frozen_string_literal: true
require 'spec_helper'
describe CronFreezePeriodTimezoneValidator do
using RSpec::Parameterized::TableSyntax
subject { create :ci_freeze_period }
where(:freeze_start, :freeze_end, :is_valid) do
'0 23 * * 5' | '0 7 * * 1' | true
'0 23 * * 5' | 'invalid' | false
'invalid' | '0 7 * * 1' | false
end
with_them do
it 'crontab validation' do
subject.freeze_start = freeze_start
subject.freeze_end = freeze_end
expect(subject.valid?).to eq(is_valid)
end
end
end
# frozen_string_literal: true
require 'spec_helper'
describe CronValidator do
subject do
Class.new do
include ActiveModel::Model
include ActiveModel::Validations
attr_accessor :cron
validates :cron, cron: true
def cron_timezone
'UTC'
end
end.new
end
it 'validates valid crontab' do
subject.cron = '0 23 * * 5'
expect(subject.valid?).to be_truthy
end
it 'validates invalid crontab' do
subject.cron = 'not a cron'
expect(subject.valid?).to be_falsy
end
context 'cron field is not whitelisted' do
subject do
Class.new do
include ActiveModel::Model
include ActiveModel::Validations
attr_accessor :cron_partytime
validates :cron_partytime, cron: true
end.new
end
it 'raises an error' do
subject.cron_partytime = '0 23 * * 5'
expect { subject.valid? }.to raise_error(StandardError, "Non-whitelisted attribute")
end
end
end
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册