Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
f77969819a
commit
028d8ac9fd
|
|
@ -999,9 +999,6 @@ class Project < ApplicationRecord
|
|||
job_id =
|
||||
if forked?
|
||||
RepositoryForkWorker.perform_async(id)
|
||||
elsif gitlab_project_import?
|
||||
# Do not retry on Import/Export until https://gitlab.com/gitlab-org/gitlab-foss/issues/26189 is solved.
|
||||
RepositoryImportWorker.set(retry: false).perform_async(self.id)
|
||||
else
|
||||
RepositoryImportWorker.perform_async(self.id)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ module Ci
|
|||
def test_case_hashes(build, test_suite)
|
||||
[].tap do |hashes|
|
||||
test_suite.each_test_case do |test_case|
|
||||
key = "#{build.project_id}-#{test_suite.name}-#{test_case.key}"
|
||||
key = "#{build.project_id}-#{test_case.key}"
|
||||
hashes << Digest::SHA256.hexdigest(key)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -39,6 +39,13 @@ module Ci
|
|||
return false if artifacts.empty?
|
||||
|
||||
artifacts.each(&:destroy!)
|
||||
run_after_destroy(artifacts)
|
||||
|
||||
true # This is required because of the design of `loop_until` method.
|
||||
end
|
||||
|
||||
def run_after_destroy(artifacts); end
|
||||
end
|
||||
end
|
||||
|
||||
Ci::DestroyExpiredJobArtifactsService.prepend_if_ee('EE::Ci::DestroyExpiredJobArtifactsService')
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ class RepositoryImportWorker # rubocop:disable Scalability/IdempotentWorker
|
|||
|
||||
feature_category :importers
|
||||
worker_has_external_dependencies!
|
||||
# Do not retry on Import/Export until https://gitlab.com/gitlab-org/gitlab/-/issues/16812 is solved.
|
||||
sidekiq_options retry: false
|
||||
sidekiq_options status_expiration: Gitlab::Import::StuckImportJob::IMPORT_JOBS_EXPIRATION
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Fix Auto Deploy scale subcommand unintentionally recreates legacy PostgreSQL
|
||||
merge_request: 44535
|
||||
author:
|
||||
type: fixed
|
||||
|
|
@ -17,13 +17,13 @@ kaniko solves two problems with using the
|
|||
build](using_docker_build.md#use-docker-in-docker-workflow-with-docker-executor) method:
|
||||
|
||||
- Docker-in-Docker requires [privileged mode](https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities)
|
||||
in order to function, which is a significant security concern.
|
||||
to function, which is a significant security concern.
|
||||
- Docker-in-Docker generally incurs a performance penalty and can be quite slow.
|
||||
|
||||
## Requirements
|
||||
|
||||
In order to utilize kaniko with GitLab, [a runner](https://docs.gitlab.com/runner/)
|
||||
with one of the following executors is required:
|
||||
To use kaniko with GitLab, [a runner](https://docs.gitlab.com/runner/) with one
|
||||
of the following executors is required:
|
||||
|
||||
- [Kubernetes](https://docs.gitlab.com/runner/executors/kubernetes.html).
|
||||
- [Docker](https://docs.gitlab.com/runner/executors/docker.html).
|
||||
|
|
|
|||
|
|
@ -23,10 +23,10 @@ We also assume that an Artifactory instance is available and reachable from the
|
|||
|
||||
## Create the simple Maven dependency
|
||||
|
||||
First of all, you need an application to work with: in this specific case we will
|
||||
use a simple one, but it could be any Maven application. This will be the
|
||||
dependency you want to package and deploy to Artifactory, in order to be
|
||||
available to other projects.
|
||||
First, you need an application to work with: in this specific case we'll use a
|
||||
simple one, but it could be any Maven application. This will be the dependency
|
||||
you want to package and deploy to Artifactory, to be available to other
|
||||
projects.
|
||||
|
||||
### Prepare the dependency application
|
||||
|
||||
|
|
@ -58,7 +58,7 @@ The application is ready to use, but you need some additional steps to deploy it
|
|||
1. Log in to Artifactory with your user's credentials.
|
||||
1. From the main screen, click on the `libs-release-local` item in the **Set Me Up** panel.
|
||||
1. Copy to clipboard the configuration snippet under the **Deploy** paragraph.
|
||||
1. Change the `url` value in order to have it configurable via variables.
|
||||
1. Change the `url` value to have it configurable by using variables.
|
||||
1. Copy the snippet in the `pom.xml` file for your project, just after the
|
||||
`dependencies` section. The snippet should look like this:
|
||||
|
||||
|
|
@ -146,8 +146,9 @@ deploy:
|
|||
- master
|
||||
```
|
||||
|
||||
The runner will use the latest [Maven Docker image](https://hub.docker.com/_/maven/), which already contains all the tools and the dependencies you need to manage the project,
|
||||
in order to run the jobs.
|
||||
The runner uses the latest [Maven Docker image](https://hub.docker.com/_/maven/),
|
||||
which contains all of the tools and dependencies needed to manage the project
|
||||
and to run the jobs.
|
||||
|
||||
Environment variables are set to instruct Maven to use the `homedir` of the repository instead of the user's home when searching for configuration and dependencies.
|
||||
|
||||
|
|
|
|||
|
|
@ -95,9 +95,10 @@ dependency upgrade did not break anything without even having to look at your we
|
|||
|
||||
## Running locally
|
||||
|
||||
We'll get to running the above test in CI/CD in a moment. When writing tests, however, it helps if
|
||||
you do not have to wait for your pipelines to succeed in order to check whether they do what you
|
||||
expect them to do. In other words, let's get it to run locally.
|
||||
We'll get to running the above test in CI/CD in a moment. When writing tests,
|
||||
however, it helps if you don't have to wait for your pipelines to succeed to
|
||||
determine whether they do what you expect them to do. In other words, let's get
|
||||
it to run locally.
|
||||
|
||||
Make sure that your app is running locally. If you use Webpack,
|
||||
you can use [the Webpack Dev Server WebdriverIO plugin](https://www.npmjs.com/package/wdio-webpack-dev-server-service)
|
||||
|
|
|
|||
|
|
@ -141,12 +141,11 @@ Of course, `my_php.ini` must be present in the root directory of your repository
|
|||
|
||||
## Test PHP projects using the Shell executor
|
||||
|
||||
The shell executor runs your job in a terminal session on your server.
|
||||
Thus, in order to test your projects you first need to make sure that all
|
||||
dependencies are installed.
|
||||
The shell executor runs your job in a terminal session on your server. To test
|
||||
your projects, you must first ensure that all dependencies are installed.
|
||||
|
||||
For example, in a VM running Debian 8 we first update the cache, then we
|
||||
install `phpunit` and `php5-mysql`:
|
||||
For example, in a VM running Debian 8, first update the cache, and then install
|
||||
`phpunit` and `php5-mysql`:
|
||||
|
||||
```shell
|
||||
sudo apt-get update -y
|
||||
|
|
@ -219,8 +218,8 @@ test:atoum:
|
|||
### Using Composer
|
||||
|
||||
The majority of the PHP projects use Composer for managing their PHP packages.
|
||||
In order to execute Composer before running your tests, simply add the
|
||||
following in your `.gitlab-ci.yml`:
|
||||
To execute Composer before running your tests, add the following to your
|
||||
`.gitlab-ci.yml`:
|
||||
|
||||
```yaml
|
||||
# Composer stores all downloaded packages in the vendor/ directory.
|
||||
|
|
@ -243,14 +242,14 @@ before_script:
|
|||
## Access private packages or dependencies
|
||||
|
||||
If your test suite needs to access a private repository, you need to configure
|
||||
[the SSH keys](../ssh_keys/README.md) in order to be able to clone it.
|
||||
the [SSH keys](../ssh_keys/README.md) to be able to clone it.
|
||||
|
||||
## Use databases or other services
|
||||
|
||||
Most of the time you will need a running database in order for your tests to
|
||||
run. If you are using the Docker executor you can leverage Docker's ability to
|
||||
link to other containers. With GitLab Runner, this can be achieved by
|
||||
defining a `service`.
|
||||
Most of the time, you need a running database for your tests to be able to
|
||||
run. If you're using the Docker executor, you can leverage Docker's ability to
|
||||
link to other containers. With GitLab Runner, this can be achieved by defining
|
||||
a `service`.
|
||||
|
||||
This functionality is covered in [the CI services](../services/README.md)
|
||||
documentation.
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ First install [Docker Engine](https://docs.docker.com/installation/).
|
|||
|
||||
To build this project you also need to have [GitLab Runner](https://docs.gitlab.com/runner/).
|
||||
You can use public runners available on `gitlab.com` or register your own. Start by
|
||||
creating a template configuration file in order to pass complex configuration:
|
||||
creating a template configuration file to pass complex configuration:
|
||||
|
||||
```shell
|
||||
cat > /tmp/test-config.template.toml << EOF
|
||||
|
|
|
|||
|
|
@ -125,8 +125,9 @@ Therefore:
|
|||
- Since `C` specifies that it should only run for merge requests, it will not run for any pipeline
|
||||
except a merge request pipeline.
|
||||
|
||||
This helps you avoid having to add the `only:` rule to all of your jobs
|
||||
in order to make them always run. You can use this format to set up a Review App, helping to save resources.
|
||||
This helps you avoid having to add the `only:` rule to all of your jobs to make
|
||||
them always run. You can use this format to set up a Review App, helping to
|
||||
save resources.
|
||||
|
||||
#### Excluding certain branches
|
||||
|
||||
|
|
|
|||
|
|
@ -80,8 +80,8 @@ For more information, read the [documentation on Merge Trains](merge_trains/inde
|
|||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/12996) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.3.
|
||||
|
||||
GitLab CI/CD can detect the presence of redundant pipelines,
|
||||
and will cancel them automatically in order to conserve CI resources.
|
||||
GitLab CI/CD can detect the presence of redundant pipelines, and cancels them
|
||||
to conserve CI resources.
|
||||
|
||||
When a user merges a merge request immediately within an ongoing merge
|
||||
train, the train will be reconstructed, as it will recreate the expected
|
||||
|
|
|
|||
|
|
@ -37,8 +37,8 @@ pdf:
|
|||
expire_in: 1 week
|
||||
```
|
||||
|
||||
A job named `pdf` calls the `xelatex` command in order to build a PDF file from
|
||||
the latex source file `mycv.tex`. We then define the `artifacts` paths which in
|
||||
A job named `pdf` calls the `xelatex` command to build a PDF file from the
|
||||
latex source file `mycv.tex`. We then define the `artifacts` paths which in
|
||||
turn are defined with the `paths` keyword. All paths to files and directories
|
||||
are relative to the repository that was cloned during the build.
|
||||
|
||||
|
|
@ -429,7 +429,9 @@ To erase a job:
|
|||
|
||||
## Retrieve artifacts of private projects when using GitLab CI
|
||||
|
||||
In order to retrieve a job artifact of a different project, you might need to use a private token in order to [authenticate and download](../../api/job_artifacts.md#get-job-artifacts) the artifacts.
|
||||
To retrieve a job artifact from a different project, you might need to use a
|
||||
private token to [authenticate and download](../../api/job_artifacts.md#get-job-artifacts)
|
||||
the artifact.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
|
|
|
|||
|
|
@ -134,7 +134,8 @@ on, and use that key for all projects that are run on this machine.
|
|||
If you are accessing a private GitLab repository you need to add it as a
|
||||
[deploy key](../../ssh/README.md#deploy-keys).
|
||||
|
||||
Once done, try to log in to the remote server in order to accept the fingerprint:
|
||||
After generating the key, try to sign in to the remote server to accept the
|
||||
fingerprint:
|
||||
|
||||
```shell
|
||||
ssh example.com
|
||||
|
|
|
|||
|
|
@ -183,9 +183,9 @@ webhook URL for Push and Tag events (change the project ID, ref and token):
|
|||
https://gitlab.example.com/api/v4/projects/9/ref/master/trigger/pipeline?token=TOKEN
|
||||
```
|
||||
|
||||
`ref` should be passed as part of the URL in order to take precedence over
|
||||
`ref` from the webhook body that designates the branch ref that fired the
|
||||
trigger in the source repository. `ref` should be URL-encoded if it contains slashes.
|
||||
You should pass `ref` as part of the URL, to take precedence over `ref` from
|
||||
the webhook body that designates the branch ref that fired the trigger in the
|
||||
source repository. Be sure to URL-encode `ref` if it contains slashes.
|
||||
|
||||
## Making use of trigger variables
|
||||
|
||||
|
|
|
|||
|
|
@ -1979,15 +1979,17 @@ docker build service one:
|
|||
- service-one/**/*
|
||||
```
|
||||
|
||||
In the example above, a pipeline could fail due to changes to a file in `service-one/**/*`.
|
||||
A later commit could then be pushed that does not include any changes to this file,
|
||||
but includes changes to the `Dockerfile`, and this pipeline could pass because it's only
|
||||
testing the changes to the `Dockerfile`. GitLab checks the **most recent pipeline**,
|
||||
that **passed**, and shows the merge request as mergeable, despite the earlier
|
||||
failed pipeline caused by a change that was not yet corrected.
|
||||
In the example above, the pipeline might fail because of changes to a file in `service-one/**/*`.
|
||||
|
||||
With this configuration, care must be taken to check that the most recent pipeline
|
||||
properly corrected any failures from previous pipelines.
|
||||
A later commit that doesn't have changes in `service-one/**/*`
|
||||
but does have changes to the `Dockerfile` can pass. The job
|
||||
only tests the changes to the `Dockerfile`.
|
||||
|
||||
GitLab checks the **most recent pipeline** that **passed**. If the merge request is mergeable,
|
||||
it doesn't matter that an earlier pipeline failed because of a change that has not been corrected.
|
||||
|
||||
When you use this configuration, ensure that the most recent pipeline
|
||||
properly corrects any failures from previous pipelines.
|
||||
|
||||
##### Using `only:changes` without pipelines for merge requests
|
||||
|
||||
|
|
@ -2093,8 +2095,7 @@ can choose a custom limit. For example, to set the limit to 100:
|
|||
Plan.default.actual_limits.update!(ci_needs_size_limit: 100)
|
||||
```
|
||||
|
||||
NOTE: **Note:**
|
||||
To disable the ability to use DAG, set the limit to `0`.
|
||||
To disable directed acyclic graphs (DAG), set the limit to `0`.
|
||||
|
||||
#### Artifact downloads with `needs`
|
||||
|
||||
|
|
@ -2130,7 +2131,7 @@ rubocop:
|
|||
```
|
||||
|
||||
Additionally, in the three syntax examples below, the `rspec` job downloads the artifacts
|
||||
from all three `build_jobs`, as `artifacts` is true for `build_job_1`, and
|
||||
from all three `build_jobs`. `artifacts` is true for `build_job_1` and
|
||||
**defaults** to true for both `build_job_2` and `build_job_3`.
|
||||
|
||||
```yaml
|
||||
|
|
@ -2146,9 +2147,10 @@ rspec:
|
|||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/14311) in GitLab v12.7.
|
||||
|
||||
`needs` can be used to download artifacts from up to five jobs in pipelines on
|
||||
[other refs in the same project](#artifact-downloads-between-pipelines-in-the-same-project),
|
||||
or pipelines in different projects, groups and namespaces:
|
||||
Use `needs` to download artifacts from up to five jobs in pipelines:
|
||||
|
||||
- [On other refs in the same project](#artifact-downloads-between-pipelines-in-the-same-project).
|
||||
- In different projects, groups and namespaces.
|
||||
|
||||
```yaml
|
||||
build_job:
|
||||
|
|
@ -2171,9 +2173,10 @@ The user running the pipeline must have at least `reporter` access to the group
|
|||
|
||||
##### Artifact downloads between pipelines in the same project
|
||||
|
||||
`needs` can be used to download artifacts from different pipelines in the current project
|
||||
by setting the `project` keyword as the current project's name, and specifying a ref.
|
||||
In the example below, `build_job` downloads the artifacts for the latest successful
|
||||
Use `needs` to download artifacts from different pipelines in the current project.
|
||||
Set the `project` keyword as the current project's name, and specify a ref.
|
||||
|
||||
In this example, `build_job` downloads the artifacts for the latest successful
|
||||
`build-1` job with the `other-ref` ref:
|
||||
|
||||
```yaml
|
||||
|
|
@ -2205,7 +2208,6 @@ build_job:
|
|||
artifacts: true
|
||||
```
|
||||
|
||||
NOTE: **Note:**
|
||||
Downloading artifacts from jobs that are run in [`parallel:`](#parallel) is not supported.
|
||||
|
||||
### `tags`
|
||||
|
|
@ -2217,7 +2219,7 @@ When you register a runner, you can specify the runner's tags, for
|
|||
example `ruby`, `postgres`, `development`.
|
||||
|
||||
In this example, the job is run by a runner that
|
||||
has both `ruby` AND `postgres` tags defined.
|
||||
has both `ruby` and `postgres` tags defined.
|
||||
|
||||
```yaml
|
||||
job:
|
||||
|
|
@ -2562,9 +2564,9 @@ deploy to production:
|
|||
> defined, GitLab automatically triggers a stop action when the associated
|
||||
> branch is deleted.
|
||||
|
||||
Closing (stopping) environments can be achieved with the `on_stop` keyword defined under
|
||||
`environment`. It declares a different job that runs in order to close
|
||||
the environment.
|
||||
Closing (stopping) environments can be achieved with the `on_stop` keyword
|
||||
defined under `environment`. It declares a different job that runs to close the
|
||||
environment.
|
||||
|
||||
Read the `environment:action` section for an example.
|
||||
|
||||
|
|
@ -2602,21 +2604,20 @@ stop_review_app:
|
|||
action: stop
|
||||
```
|
||||
|
||||
In the above example we set up the `review_app` job to deploy to the `review`
|
||||
environment, and we also defined a new `stop_review_app` job under `on_stop`.
|
||||
In the above example, the `review_app` job deploys to the `review`
|
||||
environment. A new `stop_review_app` job is listed under `on_stop`.
|
||||
After the `review_app` job is finished, it triggers the
|
||||
`stop_review_app` job based on what is defined under `when`. In this case we
|
||||
set it up to `manual` so it needs a [manual action](#whenmanual) from
|
||||
`stop_review_app` job based on what is defined under `when`. In this case,
|
||||
it is set to `manual`, so it needs a [manual action](#whenmanual) from
|
||||
GitLab's user interface to run.
|
||||
|
||||
Also in the example, `GIT_STRATEGY` is set to `none` so that GitLab Runner won’t
|
||||
try to check out the code after the branch is deleted when the `stop_review_app`
|
||||
job is [automatically triggered](../environments/index.md#automatically-stopping-an-environment).
|
||||
Also in the example, `GIT_STRATEGY` is set to `none`. If the
|
||||
`stop_review_app` job is [automatically triggered](../environments/index.md#automatically-stopping-an-environment),
|
||||
the runner won’t try to check out the code after the branch is deleted.
|
||||
|
||||
NOTE: **Note:**
|
||||
The above example overwrites global variables. If your stop environment job depends
|
||||
on global variables, you can use [anchor variables](#yaml-anchors-for-variables) when setting the `GIT_STRATEGY`
|
||||
to change it without overriding the global variables.
|
||||
The example also overwrites global variables. If your `stop` `environment` job depends
|
||||
on global variables, you can use [anchor variables](#yaml-anchors-for-variables) when you set the `GIT_STRATEGY`.
|
||||
This changes the job without overriding the global variables.
|
||||
|
||||
The `stop_review_app` job is **required** to have the following keywords defined:
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ module Gitlab
|
|||
root = Hash.from_xml(xml_data)
|
||||
|
||||
all_cases(root) do |test_case|
|
||||
test_case = create_test_case(test_case, args)
|
||||
test_case = create_test_case(test_case, test_suite, args)
|
||||
test_suite.add_test_case(test_case)
|
||||
end
|
||||
rescue Nokogiri::XML::SyntaxError => e
|
||||
|
|
@ -33,20 +33,24 @@ module Gitlab
|
|||
all_cases(node['testsuites'], root, &blk) unless parent
|
||||
|
||||
# we require at least one level of testsuites or testsuite
|
||||
each_case(node['testcase'], &blk) if parent
|
||||
each_case(node['testcase'], node['name'], &blk) if parent
|
||||
|
||||
# we allow multiple nested 'testsuite' (eg. PHPUnit)
|
||||
all_cases(node['testsuite'], root, &blk)
|
||||
end
|
||||
end
|
||||
|
||||
def each_case(testcase, &blk)
|
||||
def each_case(testcase, testsuite_name, &blk)
|
||||
return unless testcase.present?
|
||||
|
||||
[testcase].flatten.compact.map(&blk)
|
||||
[testcase].flatten.compact.each do |tc|
|
||||
tc['suite_name'] = testsuite_name
|
||||
|
||||
yield(tc)
|
||||
end
|
||||
end
|
||||
|
||||
def create_test_case(data, args)
|
||||
def create_test_case(data, test_suite, args)
|
||||
if data.key?('failure')
|
||||
status = ::Gitlab::Ci::Reports::TestCase::STATUS_FAILED
|
||||
system_output = data['failure']
|
||||
|
|
@ -63,6 +67,7 @@ module Gitlab
|
|||
end
|
||||
|
||||
::Gitlab::Ci::Reports::TestCase.new(
|
||||
suite_name: data['suite_name'] || test_suite.name,
|
||||
classname: data['classname'],
|
||||
name: data['name'],
|
||||
file: data['file'],
|
||||
|
|
@ -74,6 +79,10 @@ module Gitlab
|
|||
)
|
||||
end
|
||||
|
||||
def suite_name(parent, test_suite)
|
||||
parent.dig('testsuite', 'name') || test_suite.name
|
||||
end
|
||||
|
||||
def attachment_path(data)
|
||||
return unless data
|
||||
|
||||
|
|
|
|||
|
|
@ -10,9 +10,10 @@ module Gitlab
|
|||
STATUS_ERROR = 'error'
|
||||
STATUS_TYPES = [STATUS_ERROR, STATUS_FAILED, STATUS_SUCCESS, STATUS_SKIPPED].freeze
|
||||
|
||||
attr_reader :name, :classname, :execution_time, :status, :file, :system_output, :stack_trace, :key, :attachment, :job
|
||||
attr_reader :suite_name, :name, :classname, :execution_time, :status, :file, :system_output, :stack_trace, :key, :attachment, :job
|
||||
|
||||
def initialize(params)
|
||||
@suite_name = params.fetch(:suite_name)
|
||||
@name = params.fetch(:name)
|
||||
@classname = params.fetch(:classname)
|
||||
@file = params.fetch(:file, nil)
|
||||
|
|
@ -23,7 +24,7 @@ module Gitlab
|
|||
@attachment = params.fetch(:attachment, nil)
|
||||
@job = params.fetch(:job, nil)
|
||||
|
||||
@key = hash_key("#{classname}_#{name}")
|
||||
@key = hash_key("#{suite_name}_#{classname}_#{name}")
|
||||
end
|
||||
|
||||
def has_attachment?
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
.dast-auto-deploy:
|
||||
image: "registry.gitlab.com/gitlab-org/cluster-integration/auto-deploy-image:v1.0.3"
|
||||
image: "registry.gitlab.com/gitlab-org/cluster-integration/auto-deploy-image:v1.0.5"
|
||||
|
||||
dast_environment_deploy:
|
||||
extends: .dast-auto-deploy
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
.auto-deploy:
|
||||
image: "registry.gitlab.com/gitlab-org/cluster-integration/auto-deploy-image:v1.0.3"
|
||||
image: "registry.gitlab.com/gitlab-org/cluster-integration/auto-deploy-image:v1.0.5"
|
||||
dependencies: []
|
||||
|
||||
review:
|
||||
|
|
|
|||
|
|
@ -22835,10 +22835,10 @@ msgstr ""
|
|||
msgid "SecurityApprovals|One or more of the security scanners must be enabled. %{linkStart}More information%{linkEnd}"
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}More information%{linkEnd}"
|
||||
msgid "SecurityApprovals|Requires approval for Denied licenses. %{linkStart}More information%{linkEnd}"
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityApprovals|Requires license policy rules for licenses of Allowed, or Denied. %{linkStart}More information%{linkEnd}"
|
||||
msgid "SecurityApprovals|Requires approval for vulnerabilities of Critical, High, or Unknown severity. %{linkStart}More information%{linkEnd}"
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityConfiguration|An error occurred while creating the merge request."
|
||||
|
|
|
|||
|
|
@ -26,6 +26,10 @@ module QA
|
|||
within_element(:ci_variable_key_field) { find('input').set key }
|
||||
fill_element :ci_variable_value_field, value
|
||||
click_ci_variable_save_button
|
||||
|
||||
wait_until(reload: false) do
|
||||
within_element(:ci_variable_table_content) { has_element?(:edit_ci_variable_button) }
|
||||
end
|
||||
end
|
||||
|
||||
def click_add_variable
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
module QA
|
||||
RSpec.describe 'Verify' do
|
||||
describe 'Add or Remove CI variable via UI', :smoke do
|
||||
let!(:project) do
|
||||
let(:project) do
|
||||
Resource::Project.fabricate_via_api! do |project|
|
||||
project.name = 'project-with-ci-variables'
|
||||
project.description = 'project with CI variables'
|
||||
|
|
@ -12,31 +12,27 @@ module QA
|
|||
|
||||
before do
|
||||
Flow::Login.sign_in
|
||||
project.visit!
|
||||
add_ci_variable
|
||||
open_ci_cd_settings
|
||||
end
|
||||
|
||||
it 'user adds a CI variable', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/395' do
|
||||
Page::Project::Settings::CICD.perform do |settings|
|
||||
settings.expand_ci_variables do |page|
|
||||
expect(page).to have_text('VARIABLE_KEY')
|
||||
expect(page).not_to have_text('some_CI_variable')
|
||||
Page::Project::Settings::CiVariables.perform do |ci_variable|
|
||||
expect(ci_variable).to have_text('VARIABLE_KEY')
|
||||
expect(ci_variable).to have_no_text('some_CI_variable')
|
||||
|
||||
page.click_reveal_ci_variable_value_button
|
||||
ci_variable.click_reveal_ci_variable_value_button
|
||||
|
||||
expect(page).to have_text('some_CI_variable')
|
||||
end
|
||||
expect(ci_variable).to have_text('some_CI_variable')
|
||||
end
|
||||
end
|
||||
|
||||
it 'user removes a CI variable', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/394' do
|
||||
Page::Project::Settings::CICD.perform do |settings|
|
||||
settings.expand_ci_variables do |page|
|
||||
page.click_edit_ci_variable
|
||||
page.click_ci_variable_delete_button
|
||||
Page::Project::Settings::CiVariables.perform do |ci_variable|
|
||||
ci_variable.click_edit_ci_variable
|
||||
ci_variable.click_ci_variable_delete_button
|
||||
|
||||
expect(page).not_to have_text('VARIABLE_KEY')
|
||||
end
|
||||
expect(ci_variable).to have_text('There are no variables yet', wait: 60)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -50,11 +46,6 @@ module QA
|
|||
ci_variable.masked = false
|
||||
end
|
||||
end
|
||||
|
||||
def open_ci_cd_settings
|
||||
project.visit!
|
||||
Page::Project::Menu.perform(&:go_to_ci_cd_settings)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
FactoryBot.define do
|
||||
factory :test_case, class: 'Gitlab::Ci::Reports::TestCase' do
|
||||
suite_name { "rspec" }
|
||||
name { "test-1" }
|
||||
classname { "trace" }
|
||||
file { "spec/trace_spec.rb" }
|
||||
|
|
@ -25,6 +26,7 @@ FactoryBot.define do
|
|||
|
||||
initialize_with do
|
||||
new(
|
||||
suite_name: suite_name,
|
||||
name: name,
|
||||
classname: classname,
|
||||
file: file,
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ RSpec.describe Gitlab::Ci::Parsers::Test::Junit do
|
|||
let(:junit) do
|
||||
<<-EOF.strip_heredoc
|
||||
<testsuites>
|
||||
<testsuite>
|
||||
<testsuite name='Math'>
|
||||
<testcase classname='Calculator' name='sumTest1' time='0.01'></testcase>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
|
@ -53,6 +53,7 @@ RSpec.describe Gitlab::Ci::Parsers::Test::Junit do
|
|||
it 'parses XML and adds a test case to a suite' do
|
||||
expect { subject }.not_to raise_error
|
||||
|
||||
expect(test_cases[0].suite_name).to eq('Math')
|
||||
expect(test_cases[0].classname).to eq('Calculator')
|
||||
expect(test_cases[0].name).to eq('sumTest1')
|
||||
expect(test_cases[0].execution_time).to eq(0.01)
|
||||
|
|
@ -62,7 +63,7 @@ RSpec.describe Gitlab::Ci::Parsers::Test::Junit do
|
|||
context 'when there is <testcase>' do
|
||||
let(:junit) do
|
||||
<<-EOF.strip_heredoc
|
||||
<testsuite>
|
||||
<testsuite name='Math'>
|
||||
<testcase classname='Calculator' name='sumTest1' time='0.01'>
|
||||
#{testcase_content}
|
||||
</testcase>
|
||||
|
|
@ -79,6 +80,7 @@ RSpec.describe Gitlab::Ci::Parsers::Test::Junit do
|
|||
shared_examples_for '<testcase> XML parser' do |status, output|
|
||||
it 'parses XML and adds a test case to the suite' do
|
||||
aggregate_failures do
|
||||
expect(test_case.suite_name).to eq('Math')
|
||||
expect(test_case.classname).to eq('Calculator')
|
||||
expect(test_case.name).to eq('sumTest1')
|
||||
expect(test_case.execution_time).to eq(0.01)
|
||||
|
|
@ -152,13 +154,15 @@ RSpec.describe Gitlab::Ci::Parsers::Test::Junit do
|
|||
expect { subject }.not_to raise_error
|
||||
|
||||
expect(test_cases.count).to eq(1)
|
||||
expect(test_cases.first.suite_name).to eq("XXX\\FrontEnd\\WebBundle\\Tests\\Controller\\LogControllerTest")
|
||||
expect(test_cases.first.name).to eq("testIndexAction")
|
||||
end
|
||||
end
|
||||
|
||||
context 'when there are two test cases' do
|
||||
let(:junit) do
|
||||
<<-EOF.strip_heredoc
|
||||
<testsuite>
|
||||
<testsuite name='Math'>
|
||||
<testcase classname='Calculator' name='sumTest1' time='0.01'></testcase>
|
||||
<testcase classname='Calculator' name='sumTest2' time='0.02'></testcase>
|
||||
</testsuite>
|
||||
|
|
@ -168,9 +172,11 @@ RSpec.describe Gitlab::Ci::Parsers::Test::Junit do
|
|||
it 'parses XML and adds test cases to a suite' do
|
||||
expect { subject }.not_to raise_error
|
||||
|
||||
expect(test_cases[0].suite_name).to eq('Math')
|
||||
expect(test_cases[0].classname).to eq('Calculator')
|
||||
expect(test_cases[0].name).to eq('sumTest1')
|
||||
expect(test_cases[0].execution_time).to eq(0.01)
|
||||
expect(test_cases[1].suite_name).to eq('Math')
|
||||
expect(test_cases[1].classname).to eq('Calculator')
|
||||
expect(test_cases[1].name).to eq('sumTest2')
|
||||
expect(test_cases[1].execution_time).to eq(0.02)
|
||||
|
|
@ -181,7 +187,7 @@ RSpec.describe Gitlab::Ci::Parsers::Test::Junit do
|
|||
let(:junit) do
|
||||
<<-EOF.strip_heredoc
|
||||
<testsuites>
|
||||
<testsuite>
|
||||
<testsuite name='Math'>
|
||||
<testcase classname='Calculator' name='sumTest1' time='0.01'></testcase>
|
||||
<testcase classname='Calculator' name='sumTest2' time='0.02'></testcase>
|
||||
</testsuite>
|
||||
|
|
@ -196,18 +202,32 @@ RSpec.describe Gitlab::Ci::Parsers::Test::Junit do
|
|||
it 'parses XML and adds test cases to a suite' do
|
||||
expect { subject }.not_to raise_error
|
||||
|
||||
expect(test_cases[0].classname).to eq('Calculator')
|
||||
expect(test_cases[0].name).to eq('sumTest1')
|
||||
expect(test_cases[0].execution_time).to eq(0.01)
|
||||
expect(test_cases[1].classname).to eq('Calculator')
|
||||
expect(test_cases[1].name).to eq('sumTest2')
|
||||
expect(test_cases[1].execution_time).to eq(0.02)
|
||||
expect(test_cases[2].classname).to eq('Statemachine')
|
||||
expect(test_cases[2].name).to eq('happy path')
|
||||
expect(test_cases[2].execution_time).to eq(100)
|
||||
expect(test_cases[3].classname).to eq('Statemachine')
|
||||
expect(test_cases[3].name).to eq('unhappy path')
|
||||
expect(test_cases[3].execution_time).to eq(200)
|
||||
expect(test_cases).to contain_exactly(
|
||||
have_attributes(
|
||||
suite_name: 'Math',
|
||||
classname: 'Calculator',
|
||||
name: 'sumTest1',
|
||||
execution_time: 0.01
|
||||
),
|
||||
have_attributes(
|
||||
suite_name: 'Math',
|
||||
classname: 'Calculator',
|
||||
name: 'sumTest2',
|
||||
execution_time: 0.02
|
||||
),
|
||||
have_attributes(
|
||||
suite_name: test_suite.name, # Defaults to test suite instance's name
|
||||
classname: 'Statemachine',
|
||||
name: 'happy path',
|
||||
execution_time: 100
|
||||
),
|
||||
have_attributes(
|
||||
suite_name: test_suite.name, # Defaults to test suite instance's name
|
||||
classname: 'Statemachine',
|
||||
name: 'unhappy path',
|
||||
execution_time: 200
|
||||
)
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -6,39 +6,26 @@ RSpec.describe Gitlab::Ci::Reports::TestCase do
|
|||
describe '#initialize' do
|
||||
let(:test_case) { described_class.new(params) }
|
||||
|
||||
context 'when both classname and name are given' do
|
||||
context 'when test case is passed' do
|
||||
let(:job) { build(:ci_build) }
|
||||
let(:params) { attributes_for(:test_case).merge!(job: job) }
|
||||
context 'when required params are given' do
|
||||
let(:job) { build(:ci_build) }
|
||||
let(:params) { attributes_for(:test_case).merge!(job: job) }
|
||||
|
||||
it 'initializes an instance' do
|
||||
expect { test_case }.not_to raise_error
|
||||
it 'initializes an instance', :aggregate_failures do
|
||||
expect { test_case }.not_to raise_error
|
||||
|
||||
expect(test_case.name).to eq('test-1')
|
||||
expect(test_case.classname).to eq('trace')
|
||||
expect(test_case.file).to eq('spec/trace_spec.rb')
|
||||
expect(test_case.execution_time).to eq(1.23)
|
||||
expect(test_case.status).to eq(described_class::STATUS_SUCCESS)
|
||||
expect(test_case.system_output).to be_nil
|
||||
expect(test_case.job).to be_present
|
||||
end
|
||||
end
|
||||
expect(test_case).to have_attributes(
|
||||
suite_name: params[:suite_name],
|
||||
name: params[:name],
|
||||
classname: params[:classname],
|
||||
file: params[:file],
|
||||
execution_time: params[:execution_time],
|
||||
status: params[:status],
|
||||
system_output: params[:system_output],
|
||||
job: params[:job]
|
||||
)
|
||||
|
||||
context 'when test case is failed' do
|
||||
let(:job) { build(:ci_build) }
|
||||
let(:params) { attributes_for(:test_case, :failed).merge!(job: job) }
|
||||
|
||||
it 'initializes an instance' do
|
||||
expect { test_case }.not_to raise_error
|
||||
|
||||
expect(test_case.name).to eq('test-1')
|
||||
expect(test_case.classname).to eq('trace')
|
||||
expect(test_case.file).to eq('spec/trace_spec.rb')
|
||||
expect(test_case.execution_time).to eq(1.23)
|
||||
expect(test_case.status).to eq(described_class::STATUS_FAILED)
|
||||
expect(test_case.system_output)
|
||||
.to eq('Failure/Error: is_expected.to eq(300) expected: 300 got: -100')
|
||||
end
|
||||
key = "#{test_case.suite_name}_#{test_case.classname}_#{test_case.name}"
|
||||
expect(test_case.key).to eq(Digest::SHA256.hexdigest(key))
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -53,6 +40,10 @@ RSpec.describe Gitlab::Ci::Reports::TestCase do
|
|||
end
|
||||
end
|
||||
|
||||
context 'when suite_name is missing' do
|
||||
it_behaves_like 'param is missing', :suite_name
|
||||
end
|
||||
|
||||
context 'when classname is missing' do
|
||||
it_behaves_like 'param is missing', :classname
|
||||
end
|
||||
|
|
|
|||
|
|
@ -9,9 +9,10 @@ RSpec.describe Ci::DestroyExpiredJobArtifactsService, :clean_gitlab_redis_shared
|
|||
subject { service.execute }
|
||||
|
||||
let(:service) { described_class.new }
|
||||
let!(:artifact) { create(:ci_job_artifact, expire_at: 1.day.ago) }
|
||||
|
||||
before do
|
||||
let_it_be(:artifact) { create(:ci_job_artifact, expire_at: 1.day.ago) }
|
||||
|
||||
before(:all) do
|
||||
artifact.job.pipeline.unlocked!
|
||||
end
|
||||
|
||||
|
|
@ -38,7 +39,9 @@ RSpec.describe Ci::DestroyExpiredJobArtifactsService, :clean_gitlab_redis_shared
|
|||
end
|
||||
|
||||
context 'when artifact is not expired' do
|
||||
let!(:artifact) { create(:ci_job_artifact, expire_at: 1.day.since) }
|
||||
before do
|
||||
artifact.update_column(:expire_at, 1.day.since)
|
||||
end
|
||||
|
||||
it 'does not destroy expired job artifacts' do
|
||||
expect { subject }.not_to change { Ci::JobArtifact.count }
|
||||
|
|
@ -46,7 +49,9 @@ RSpec.describe Ci::DestroyExpiredJobArtifactsService, :clean_gitlab_redis_shared
|
|||
end
|
||||
|
||||
context 'when artifact is permanent' do
|
||||
let!(:artifact) { create(:ci_job_artifact, expire_at: nil) }
|
||||
before do
|
||||
artifact.update_column(:expire_at, nil)
|
||||
end
|
||||
|
||||
it 'does not destroy expired job artifacts' do
|
||||
expect { subject }.not_to change { Ci::JobArtifact.count }
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
module TestReportsHelper
|
||||
def create_test_case_rspec_success(name = 'test_spec')
|
||||
Gitlab::Ci::Reports::TestCase.new(
|
||||
suite_name: 'rspec',
|
||||
name: 'Test#sum when a is 1 and b is 3 returns summary',
|
||||
classname: "spec.#{name}",
|
||||
file: './spec/test_spec.rb',
|
||||
|
|
@ -12,6 +13,7 @@ module TestReportsHelper
|
|||
|
||||
def create_test_case_rspec_failed(name = 'test_spec', execution_time = 2.22)
|
||||
Gitlab::Ci::Reports::TestCase.new(
|
||||
suite_name: 'rspec',
|
||||
name: 'Test#sum when a is 1 and b is 3 returns summary',
|
||||
classname: "spec.#{name}",
|
||||
file: './spec/test_spec.rb',
|
||||
|
|
@ -22,6 +24,7 @@ module TestReportsHelper
|
|||
|
||||
def create_test_case_rspec_skipped(name = 'test_spec')
|
||||
Gitlab::Ci::Reports::TestCase.new(
|
||||
suite_name: 'rspec',
|
||||
name: 'Test#sum when a is 3 and b is 3 returns summary',
|
||||
classname: "spec.#{name}",
|
||||
file: './spec/test_spec.rb',
|
||||
|
|
@ -31,6 +34,7 @@ module TestReportsHelper
|
|||
|
||||
def create_test_case_rspec_error(name = 'test_spec')
|
||||
Gitlab::Ci::Reports::TestCase.new(
|
||||
suite_name: 'rspec',
|
||||
name: 'Test#sum when a is 4 and b is 4 returns summary',
|
||||
classname: "spec.#{name}",
|
||||
file: './spec/test_spec.rb',
|
||||
|
|
@ -52,6 +56,7 @@ module TestReportsHelper
|
|||
|
||||
def create_test_case_java_success(name = 'addTest')
|
||||
Gitlab::Ci::Reports::TestCase.new(
|
||||
suite_name: 'java',
|
||||
name: name,
|
||||
classname: 'CalculatorTest',
|
||||
execution_time: 5.55,
|
||||
|
|
@ -60,6 +65,7 @@ module TestReportsHelper
|
|||
|
||||
def create_test_case_java_failed(name = 'addTest')
|
||||
Gitlab::Ci::Reports::TestCase.new(
|
||||
suite_name: 'java',
|
||||
name: name,
|
||||
classname: 'CalculatorTest',
|
||||
execution_time: 6.66,
|
||||
|
|
@ -69,6 +75,7 @@ module TestReportsHelper
|
|||
|
||||
def create_test_case_java_skipped(name = 'addTest')
|
||||
Gitlab::Ci::Reports::TestCase.new(
|
||||
suite_name: 'java',
|
||||
name: name,
|
||||
classname: 'CalculatorTest',
|
||||
execution_time: 7.77,
|
||||
|
|
@ -77,6 +84,7 @@ module TestReportsHelper
|
|||
|
||||
def create_test_case_java_error(name = 'addTest')
|
||||
Gitlab::Ci::Reports::TestCase.new(
|
||||
suite_name: 'java',
|
||||
name: name,
|
||||
classname: 'CalculatorTest',
|
||||
execution_time: 8.88,
|
||||
|
|
|
|||
Loading…
Reference in New Issue