diff options
38 files changed, 702 insertions, 128 deletions
diff --git a/.rubocop.yml b/.rubocop.yml index 741403af009..004449210e5 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -174,3 +174,9 @@ GitlabSecurity/PublicSend: - 'ee/db/**/*' - 'ee/lib/**/*.rake' - 'ee/spec/**/*' + +Cop/InjectEnterpriseEditionModule: + Enabled: true + Exclude: + - 'spec/**/*' + - 'ee/spec/**/*' diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 3ab76965287..847a0f74aa2 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -149,17 +149,6 @@ RSpec/ExpectChange: RSpec/ExpectInHook: Enabled: false -# Offense count: 7 -# Configuration parameters: EnforcedStyle. -# SupportedStyles: implicit, each, example -RSpec/HookArgument: - Exclude: - - 'spec/spec_helper.rb' - - 'spec/support/carrierwave.rb' - - 'spec/support/db_cleaner.rb' - - 'spec/support/gitaly.rb' - - 'spec/support/setup_builds_storage.rb' - # Offense count: 19 # Configuration parameters: EnforcedStyle. # SupportedStyles: it_behaves_like, it_should_behave_like diff --git a/app/assets/javascripts/diffs/components/diff_content.vue b/app/assets/javascripts/diffs/components/diff_content.vue index ac963f2971e..42d09e44768 100644 --- a/app/assets/javascripts/diffs/components/diff_content.vue +++ b/app/assets/javascripts/diffs/components/diff_content.vue @@ -1,6 +1,7 @@ <script> import { mapActions, mapGetters, mapState } from 'vuex'; import DiffViewer from '~/vue_shared/components/diff_viewer/diff_viewer.vue'; +import EmptyFileViewer from '~/vue_shared/components/diff_viewer/viewers/empty_file.vue'; import InlineDiffView from './inline_diff_view.vue'; import ParallelDiffView from './parallel_diff_view.vue'; import NoteForm from '../../notes/components/note_form.vue'; @@ -17,6 +18,7 @@ export default { NoteForm, DiffDiscussions, ImageDiffOverlay, + EmptyFileViewer, }, props: { diffFile: { @@ -75,14 +77,15 @@ export default { <div class="diff-content"> <div class="diff-viewer"> <template v-if="isTextFile"> + <empty-file-viewer v-if="diffFile.empty" /> <inline-diff-view - v-if="isInlineView" + v-else-if="isInlineView" :diff-file="diffFile" :diff-lines="diffFile.highlighted_diff_lines || []" :help-page-path="helpPagePath" /> <parallel-diff-view - v-if="isParallelView" + v-else-if="isParallelView" :diff-file="diffFile" :diff-lines="diffFile.parallel_diff_lines || []" :help-page-path="helpPagePath" diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_rebase.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_rebase.vue index adfbcd18588..0bcccc50eb2 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_rebase.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_rebase.vue @@ -72,7 +72,7 @@ export default { Flash('Something went wrong. Please try again.'); } - eventHub.$emit('MRWidgetUpdateRequested'); + eventHub.$emit('MRWidgetRebaseSuccess'); stopPolling(); } }) diff --git a/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue b/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue index 3c3e3efcc36..d8a75388e84 100644 --- a/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue +++ b/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue @@ -155,13 +155,13 @@ export default { }; return new MRWidgetService(endpoints); }, - checkStatus(cb) { + checkStatus(cb, isRebased) { return this.service .checkStatus() .then(res => res.data) .then(data => { this.handleNotification(data); - this.mr.setData(data); + this.mr.setData(data, isRebased); this.setFaviconHelper(); if (cb) { @@ -263,6 +263,10 @@ export default { this.checkStatus(cb); }); + eventHub.$on('MRWidgetRebaseSuccess', cb => { + this.checkStatus(cb, true); + }); + // `params` should be an Array contains a Boolean, like `[true]` // Passing parameter as Boolean didn't work. eventHub.$on('SetBranchRemoveFlag', params => { diff --git a/app/assets/javascripts/vue_merge_request_widget/stores/get_state_key.js b/app/assets/javascripts/vue_merge_request_widget/stores/get_state_key.js index f7f0c1b6cb7..066a3b833d7 100644 --- a/app/assets/javascripts/vue_merge_request_widget/stores/get_state_key.js +++ b/app/assets/javascripts/vue_merge_request_widget/stores/get_state_key.js @@ -19,7 +19,7 @@ export default function deviseState(data) { return stateKey.unresolvedDiscussions; } else if (this.isPipelineBlocked) { return stateKey.pipelineBlocked; - } else if (this.hasSHAChanged) { + } else if (this.isSHAMismatch) { return stateKey.shaMismatch; } else if (this.mergeWhenPipelineSucceeds) { return this.mergeError ? stateKey.autoMergeFailed : stateKey.mergeWhenPipelineSucceeds; diff --git a/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js b/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js index 5c9a7133a6e..c777bcca0fa 100644 --- a/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js +++ b/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js @@ -11,7 +11,11 @@ export default class MergeRequestStore { this.setData(data); } - setData(data) { + setData(data, isRebased) { + if (isRebased) { + this.sha = data.diff_head_sha; + } + const currentUser = data.current_user; const pipelineStatus = data.pipeline ? data.pipeline.details.status : null; @@ -84,7 +88,7 @@ export default class MergeRequestStore { this.canMerge = !!data.merge_path; this.canCreateIssue = currentUser.can_create_issue || false; this.canCancelAutomaticMerge = !!data.cancel_merge_when_pipeline_succeeds_path; - this.hasSHAChanged = this.sha !== data.diff_head_sha; + this.isSHAMismatch = this.sha !== data.diff_head_sha; this.canBeMerged = data.can_be_merged || false; this.isMergeAllowed = data.mergeable || false; this.mergeOngoing = data.merge_ongoing; diff --git a/app/assets/javascripts/vue_shared/components/diff_viewer/viewers/empty_file.vue b/app/assets/javascripts/vue_shared/components/diff_viewer/viewers/empty_file.vue new file mode 100644 index 00000000000..53210cbcc93 --- /dev/null +++ b/app/assets/javascripts/vue_shared/components/diff_viewer/viewers/empty_file.vue @@ -0,0 +1,3 @@ +<template> + <div class="nothing-here-block">{{ __('Empty file') }}</div> +</template> diff --git a/app/helpers/version_check_helper.rb b/app/helpers/version_check_helper.rb index ab77b149072..5e519cf5c19 100644 --- a/app/helpers/version_check_helper.rb +++ b/app/helpers/version_check_helper.rb @@ -6,8 +6,7 @@ module VersionCheckHelper return unless Gitlab::CurrentSettings.version_check_enabled return if User.single_user&.requires_usage_stats_consent? - image_url = VersionCheck.new.url - image_tag image_url, class: 'js-version-status-badge' + image_tag VersionCheck.url, class: 'js-version-status-badge' end def link_to_version diff --git a/app/serializers/diff_file_entity.rb b/app/serializers/diff_file_entity.rb index f0881829efd..b0aaec3326d 100644 --- a/app/serializers/diff_file_entity.rb +++ b/app/serializers/diff_file_entity.rb @@ -5,6 +5,7 @@ class DiffFileEntity < DiffFileBaseEntity include IconsHelper expose :too_large?, as: :too_large + expose :empty?, as: :empty expose :added_lines expose :removed_lines diff --git a/changelogs/unreleased/47052-merge-button-does-not-appear-after-rebase-ing.yml b/changelogs/unreleased/47052-merge-button-does-not-appear-after-rebase-ing.yml new file mode 100644 index 00000000000..fd1e4605f2d --- /dev/null +++ b/changelogs/unreleased/47052-merge-button-does-not-appear-after-rebase-ing.yml @@ -0,0 +1,5 @@ +--- +title: Allow merge after rebase without page refresh on FF repositories +merge_request: 23572 +author: +type: fixed diff --git a/changelogs/unreleased/54786-mr-empty-file-display.yml b/changelogs/unreleased/54786-mr-empty-file-display.yml new file mode 100644 index 00000000000..5adf5744755 --- /dev/null +++ b/changelogs/unreleased/54786-mr-empty-file-display.yml @@ -0,0 +1,5 @@ +--- +title: Display empty files properly on MR diffs +merge_request: 23671 +author: Sean Nichols +type: fixed diff --git a/changelogs/unreleased/55402-broken-master-karma-test-failing-in-spec-javascripts-boards-components-issue_due_date_spec-js.yml b/changelogs/unreleased/55402-broken-master-karma-test-failing-in-spec-javascripts-boards-components-issue_due_date_spec-js.yml new file mode 100644 index 00000000000..d2ff095ce55 --- /dev/null +++ b/changelogs/unreleased/55402-broken-master-karma-test-failing-in-spec-javascripts-boards-components-issue_due_date_spec-js.yml @@ -0,0 +1,5 @@ +--- +title: Fix due date test +merge_request: 23845 +author: +type: other diff --git a/doc/administration/container_registry.md b/doc/administration/container_registry.md index cfe7b0e05e3..5b7a61ef8ff 100644 --- a/doc/administration/container_registry.md +++ b/doc/administration/container_registry.md @@ -604,6 +604,52 @@ Registry out of the box, it is possible to make it work if you follow [Docker's documentation][docker-insecure-self-signed]. You may find some additional information in [issue 18239][ce-18239]. +## Troubleshooting + +When using AWS S3 with the GitLab registry, an error may occur when pushing +large images. Look in the Registry log for the following error: + +``` +level=error msg="response completed with error" err.code=unknown err.detail="unexpected EOF" err.message="unknown error" +``` + +To resolve the error specify a `chunksize` value in the Registry configuration. +Start with a value between `25000000` (25MB) and `50000000` (50MB). + +**For Omnibus installations** + +1. Edit `/etc/gitlab/gitlab.rb`: + + ```ruby + registry['storage'] = { + 's3' => { + 'accesskey' => 'AKIAKIAKI', + 'secretkey' => 'secret123', + 'bucket' => 'gitlab-registry-bucket-AKIAKIAKI', + 'chunksize' => 25000000 + } + } + ``` + +1. Save the file and [reconfigure GitLab][] for the changes to take effect. + +--- + +**For installations from source** + +1. Edit `config/gitlab.yml`: + + ```yaml + storage: + s3: + accesskey: 'AKIAKIAKI' + secretkey: 'secret123' + bucket: 'gitlab-registry-bucket-AKIAKIAKI' + chunksize: 25000000 + ``` + +1. Save the file and [restart GitLab][] for the changes to take effect. + [ce-18239]: https://gitlab.com/gitlab-org/gitlab-ce/issues/18239 [docker-insecure-self-signed]: https://docs.docker.com/registry/insecure/#use-self-signed-certificates [reconfigure gitlab]: restart_gitlab.md#omnibus-gitlab-reconfigure diff --git a/doc/ci/yaml/README.md b/doc/ci/yaml/README.md index 01f4b023234..acfcd05624d 100644 --- a/doc/ci/yaml/README.md +++ b/doc/ci/yaml/README.md @@ -402,7 +402,7 @@ job: script: echo 'test' ``` -is translated to +is translated to: ```yaml job: @@ -412,49 +412,64 @@ job: ## `only` and `except` (complex) -> `refs` and `kubernetes` policies introduced in GitLab 10.0 -> -> `variables` policy introduced in 10.7 -> -> `changes` policy [introduced](https://gitlab.com/gitlab-org/gitlab-ce/issues/19232) in 11.4 +> - `refs` and `kubernetes` policies introduced in GitLab 10.0. +> - `variables` policy introduced in GitLab 10.7. +> - `changes` policy [introduced](https://gitlab.com/gitlab-org/gitlab-ce/issues/19232) in GitLab 11.4. CAUTION: **Warning:** This an _alpha_ feature, and it is subject to change at any time without prior notice! -Since GitLab 10.0 it is possible to define a more elaborate only/except job -policy configuration. +GitLab supports both simple and complex strategies, so it's possible to use an +array and a hash configuration scheme. -GitLab now supports both, simple and complex strategies, so it is possible to -use an array and a hash configuration scheme. +Four keys are available: -Four keys are now available: `refs`, `kubernetes` and `variables` and `changes`. +- `refs` +- `variables` +- `changes` +- `kubernetes` -### `refs` and `kubernetes` +If you use multiple keys under `only` or `except`, they act as an AND. The logic is: -Refs strategy equals to simplified only/except configuration, whereas -kubernetes strategy accepts only `active` keyword. +> (any of refs) AND (any of variables) AND (any of changes) AND (if kubernetes is active) -### `only:variables` +### `only:refs` and `except:refs` -`variables` keyword is used to define variables expressions. In other words -you can use predefined variables / project / group or -environment-scoped variables to define an expression GitLab is going to -evaluate in order to decide whether a job should be created or not. +The `refs` strategy can take the same values as the +[simplified only/except configuration](#only-and-except-simplified). -See the example below. Job is going to be created only when pipeline has been -scheduled or runs for a `master` branch, and only if kubernetes service is -active in the project. +In the example below, the `deploy` job is going to be created only when the +pipeline has been [scheduled][schedules] or runs for the `master` branch: ```yaml -job: +deploy: only: refs: - master - schedules +``` + +### `only:kubernetes` and `except:kubernetes` + +The `kubernetes` strategy accepts only the `active` keyword. + +In the example below, the `deploy` job is going to be created only when the +Kubernetes service is active in the project: + +```yaml +deploy: + only: kubernetes: active ``` +### `only:variables` and `except:variables` + +The `variables` keyword is used to define variables expressions. In other words, +you can use predefined variables / project / group or +environment-scoped variables to define an expression GitLab is going to +evaluate in order to decide whether a job should be created or not. + Examples of using variables expressions: ```yaml @@ -468,7 +483,7 @@ deploy: - $STAGING ``` -Another use case is exluding jobs depending on a commit message _(added in 11.0)_: +Another use case is excluding jobs depending on a commit message: ```yaml end-to-end: @@ -478,11 +493,11 @@ end-to-end: - $CI_COMMIT_MESSAGE =~ /skip-end-to-end-tests/ ``` -Learn more about variables expressions on [a separate page][variables-expressions]. +Learn more about [variables expressions](../variables/README.md#variables-expressions). -### `only:changes` +### `only:changes` and `except:changes` -Using `changes` keyword with `only` or `except` makes it possible to define if +Using the `changes` keyword with `only` or `except`, makes it possible to define if a job should be created based on files modified by a git push event. For example: @@ -499,13 +514,13 @@ docker build: ``` In the scenario above, if you are pushing multiple commits to GitLab to an -existing branch, GitLab creates and triggers `docker build` job, provided that +existing branch, GitLab creates and triggers the `docker build` job, provided that one of the commits contains changes to either: - The `Dockerfile` file. - Any of the files inside `docker/scripts/` directory. -- Any of the files and subfolders inside `dockerfiles` directory. -- Any of the files with `rb`, `py`, `sh` extensions inside `more_scripts` directory. +- Any of the files and subdirectories inside the `dockerfiles` directory. +- Any of the files with `rb`, `py`, `sh` extensions inside the `more_scripts` directory. CAUTION: **Warning:** There are some caveats when using this feature with new branches and tags. See @@ -614,7 +629,7 @@ failure. fails. 1. `always` - execute job regardless of the status of jobs from prior stages. 1. `manual` - execute job manually (added in GitLab 8.10). Read about - [manual actions](#when-manual) below. + [manual actions](#whenmanual) below. For example: @@ -674,7 +689,7 @@ Manual actions are a special type of job that are not executed automatically, they need to be explicitly started by a user. An example usage of manual actions would be a deployment to a production environment. Manual actions can be started from the pipeline, job, environment, and deployment views. Read more at the -[environments documentation][env-manual]. +[environments documentation](../environments.md#manually-deploying-to-environments). Manual actions can be either optional or blocking. Blocking manual actions will block the execution of the pipeline at the stage this action is defined in. It's @@ -1323,7 +1338,7 @@ The test reports are collected regardless of the job results (success or failure You can use [`artifacts:expire_in`](#artifacts-expire_in) to set up an expiration date for their artifacts. -NOTE: **Note:** +NOTE: **Note:** If you also want the ability to browse the report output files, include the [`artifacts:paths`](#artifactspaths) keyword. @@ -1657,7 +1672,7 @@ rspec: ``` NOTE: **Note:** -`include` requires the external YAML files to have the extensions `.yml` or `.yaml`. +`include` requires the external YAML files to have the extensions `.yml` or `.yaml`. The external file will not be included if the extension is missing. You can define it either as a single string, or, in case you want to include @@ -1709,7 +1724,7 @@ include: The remote file must be publicly accessible through a simple GET request, as we don't support authentication schemas in the remote URL. NOTE: **Note:** - In order to include files from another repository inside your local network, + In order to include files from another repository inside your local network, you may need to enable the **Allow requests to the local network from hooks and services** checkbox located in the **Settings > Network > Outbound requests** section within the **Admin area**. @@ -2195,19 +2210,14 @@ try to quote them, or change them to a different form (e.g., `/bin/true`). ## Examples -Visit the [examples README][examples] to see a list of examples using GitLab -CI with various languages. +See a [list of examples](../examples/README.md "CI/CD examples") for using +GitLab CI/CD with various languages. -[env-manual]: ../environments.md#manually-deploying-to-environments -[examples]: ../examples/README.md [ce-6323]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/6323 -[environment]: ../environments.md [ce-6669]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/6669 -[variables]: ../variables/README.md [ce-7983]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/7983 [ce-7447]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/7447 [ce-12909]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/12909 -[schedules]: ../../user/project/pipelines/schedules.md -[variables-expressions]: ../variables/README.md#variables-expressions -[ee]: https://about.gitlab.com/gitlab-ee/ -[gitlab-versions]: https://about.gitlab.com/products/ +[environment]: ../environments.md "CI/CD environments" +[schedules]: ../../user/project/pipelines/schedules.md "Pipelines schedules" +[variables]: ../variables/README.md "CI/CD variables" diff --git a/doc/user/project/pages/getting_started_part_three.md b/doc/user/project/pages/getting_started_part_three.md index 247e8d2a6a0..cea9628966d 100644 --- a/doc/user/project/pages/getting_started_part_three.md +++ b/doc/user/project/pages/getting_started_part_three.md @@ -234,26 +234,25 @@ reiterating the importance of HTTPS. ## Issuing Certificates -GitLab Pages accepts [PEM](https://support.quovadisglobal.com/kb/a37/what-is-pem-format.aspx) certificates issued by -[Certificate Authorities (CA)](https://en.wikipedia.org/wiki/Certificate_authority) -and self-signed certificates. Of course, -[you'd rather issue a certificate than generate a self-signed](https://en.wikipedia.org/wiki/Self-signed_certificate), -for security reasons and for having browsers trusting your -site's certificate. - -There are several different kinds of certificates, each one -with certain security level. A static personal website will +GitLab Pages accepts certificates provided in the [PEM](https://support.quovadisglobal.com/kb/a37/what-is-pem-format.aspx) format, issued by +[Certificate Authorities (CAs)](https://en.wikipedia.org/wiki/Certificate_authority) or as +[self-signed certificates](https://en.wikipedia.org/wiki/Self-signed_certificate). Note that [self-signed certificates are typically not used](https://securingtomorrow.mcafee.com/other-blogs/mcafee-labs/self-signed-certificates-secure-so-why-ban/) +for public websites for security reasons and to ensure that browsers trust your site's certificate. + +There are various kinds of certificates, each one +with a certain security level. A static personal website will not require the same security level as an online banking web app, -for instance. There are a couple Certificate Authorities that +for instance. + +There are some certificate authorities that offer free certificates, aiming to make the internet more secure to everyone. The most popular is [Let's Encrypt](https://letsencrypt.org/), which issues certificates trusted by most of browsers, it's open -source, and free to use. Please read through this tutorial to -understand [how to secure your GitLab Pages website with Let's Encrypt](https://about.gitlab.com/2016/04/11/tutorial-securing-your-gitlab-pages-with-tls-and-letsencrypt/). +source, and free to use. See our tutorial on [how to secure your GitLab Pages website with Let's Encrypt](lets_encrypt_for_gitlab_pages.md). -With the same popularity, there are [certificates issued by CloudFlare](https://www.cloudflare.com/ssl/), +Similarly popular are [certificates issued by CloudFlare](https://www.cloudflare.com/ssl/), which also offers a [free CDN service](https://blog.cloudflare.com/cloudflares-free-cdn-and-you/). -Their certs are valid up to 15 years. Read through the tutorial on +Their certs are valid up to 15 years. See the tutorial on [how to add a CloudFlare Certificate to your GitLab Pages website](https://about.gitlab.com/2017/02/07/setting-up-gitlab-pages-with-cloudflare-certificates/). ### Adding certificates to your project diff --git a/doc/user/project/pages/index.md b/doc/user/project/pages/index.md index 7de9ae0caea..ce4fccdaff3 100644 --- a/doc/user/project/pages/index.md +++ b/doc/user/project/pages/index.md @@ -170,7 +170,7 @@ optionally secure it with SSL/TLS certificates. You can read the following tutorials to learn how to use these third-party certificates with GitLab Pages: - [CloudFlare](https://about.gitlab.com/2017/02/07/setting-up-gitlab-pages-with-cloudflare-certificates/) -- [Let's Encrypt](https://about.gitlab.com/2016/04/11/tutorial-securing-your-gitlab-pages-with-tls-and-letsencrypt/) (mind that although this article is out-of-date, it can still be useful to guide you through the basic steps) +- [Let's Encrypt](lets_encrypt_for_gitlab_pages.md) ## Advanced use diff --git a/doc/user/project/pages/lets_encrypt_for_gitlab_pages.md b/doc/user/project/pages/lets_encrypt_for_gitlab_pages.md new file mode 100644 index 00000000000..f639188684b --- /dev/null +++ b/doc/user/project/pages/lets_encrypt_for_gitlab_pages.md @@ -0,0 +1,158 @@ +--- +description: "How to secure GitLab Pages websites with Let's Encrypt." +--- + +# Let's Encrypt for GitLab Pages + +If you have a GitLab Pages website served under your own domain, +you might want to secure it with a SSL/TSL certificate. + +[Let's Encrypt](https://letsencrypt.org) is a free, automated, and +open source Certificate Authority. + +## Requirements + +To follow along with this tutorial, we assume you already have: + +- Created a [project](getting_started_part_two.md) in GitLab which + contains your website's source code. +- Acquired a domain (`example.com`) and added a [DNS entry](getting_started_part_three.md#dns-records) + pointing it to your Pages website. +- [Added your domain to your Pages project](getting_started_part_three.md#add-your-custom-domain-to-gitlab-pages-settings) + and verified your ownership. +- Cloned your project into your computer. +- Your website up and running, served under HTTP protocol at `http://example.com`. + +## Obtaining a Let's Encrypt certificate + +Once you have the requirements addressed, follow the instructions +below to learn how to obtain the certificate. + +NOTE: **Note:** +The instructions below were tested on macOS Mojave. For other +operating systems the steps might be slightly different. Follow the +[CertBot instructions](https://certbot.eff.org/) according to your OS. + +1. On your computer, open a terminal and navigate to your repository's + root directory: + + ```bash + cd path/to/dir + ``` + +1. Install CertBot (the tool Let's Encrypt uses to issue certificates): + + ```bash + brew install certbot + ``` + +1. Request a certificate for your domain (`example.com`) and + provide an email account (`your@email.com`) to receive notifications: + + ```bash + sudo certbot certonly -a manual -d example.com --email your@email.com + ``` + + Alternatively, you can register without adding an e-mail account, + but you won't be notified about the certificate expiration's date: + + ```bash + sudo certbot certonly -a manual -d example.com --register-unsafely-without-email + ``` + + TIP: **Tip:** + Read through CertBot's documentation on their + [command line options](https://certbot.eff.org/docs/using.html#certbot-command-line-options). + +1. You'll be prompted with a message to agree with their terms. + Press `A` to agree and `Y` to let they log your IP. + + CertBot will then prompt you with the following message: + + ```bash + Create a file containing just this data: + + Rxnv6WKo95hsuLVX3osmT6LgmzsJKSaK9htlPToohOP.HUGNKk82jlsmOOfphlt8Jy69iuglsn095nxOMH9j3Yb + + And make it available on your web server at this URL: + + http://example.com/.well-known/acme-challenge/Rxnv6WKo95hsuLVX3osmT6LgmzsJKSaK9htlPToohOP + + Press Enter to Continue + ``` + +1. **Do not press Enter yet.** Let's Encrypt will need to verify your + domain ownership before issuing the certificate. To do so, create 3 + consecutive directories under your website's root: + `/.well-known/acme-challenge/Rxnv6WKo95hsuLVX3osmT6LgmzsJKSaK9htlPToohOP/` + and add to the last folder an `index.html` file containing the content + referred on the previous prompt message: + + ```bash + Rxnv6WKo95hsuLVX3osmT6LgmzsJKSaK9htlPToohOP.HUGNKk82jlsmOOfphlt8Jy69iuglsn095nxOMH9j3Yb + ``` + + Note that this file needs to be accessed under + `http://example.com/.well-known/acme-challenge/Rxnv6WKo95hsuLVX3osmT6LgmzsJKSaK9htlPToohOP` + to allow Let's Encrypt to verify the ownership of your domain, + therefore, it needs to be part of the website content under the + repo's [`public`](index.md#how-it-works) folder. + +1. Add, commit, and push the file into your repo in GitLab. Once the pipeline + passes, press **Enter** on your terminal to continue issuing your + certificate. CertBot will then prompt you with the following message: + + ```bash + Waiting for verification... + Cleaning up challenges + + IMPORTANT NOTES: + - Congratulations! Your certificate and chain have been saved at: + /etc/letsencrypt/live/example.com/fullchain.pem + Your key file has been saved at: + /etc/letsencrypt/live/example.com/privkey.pem + Your cert will expire on 2019-03-12. To obtain a new or tweaked + version of this certificate in the future, simply run certbot + again. To non-interactively renew *all* of your certificates, run + "certbot renew" + - If you like Certbot, please consider supporting our work by: + + Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate + Donating to EFF: https://eff.org/donate-le + ``` + +## Add your certificate to GitLab Pages + +Now that your certificate has been issued, let's add it to your Pages site: + +1. Back at GitLab, navigate to your project's **Settings > Pages**, + find your domain and click **Details** and **Edit** to add your certificate. +1. From your terminal, copy and paste the certificate into the first field + **Certificate (PEM)**: + + ```bash + sudo cat /etc/letsencrypt/live/example.com/fullchain.pem | pbcopy + ``` + +1. Copy and paste the public key into the second field **Key (PEM)**: + + ```bash + sudo cat /etc/letsencrypt/live/example.com/privkey.pem | pbcopy + ``` + +1. Click **Save changes** to apply them to your website. +1. Wait a few minutes for DNS propagation. +1. Visit your website at `https://example.com`. + +To force `https` connections on your site, navigate to your +project's **Settings > Pages** and check **Force domains with SSL +certificates to use HTTPS**. + +## Renewal + +Let's Encrypt certificates expire every 90 days and you'll have to +renew them periodically. To renew all your certificates at once, run: + +```bash +sudo certbot renew +``` diff --git a/lib/gitlab/diff/file.rb b/lib/gitlab/diff/file.rb index a85c5386d98..b5fc8d364c8 100644 --- a/lib/gitlab/diff/file.rb +++ b/lib/gitlab/diff/file.rb @@ -255,6 +255,10 @@ module Gitlab end # rubocop: enable CodeReuse/ActiveRecord + def empty? + valid_blobs.map(&:empty?).all? + end + def raw_binary? try_blobs(:raw_binary?) end diff --git a/lib/version_check.rb b/lib/version_check.rb index ccf7bb493db..c9f102f6b19 100644 --- a/lib/version_check.rb +++ b/lib/version_check.rb @@ -5,16 +5,17 @@ require "base64" # This class is used to build image URL to # check if it is a new version for update class VersionCheck - def data + def self.data { version: Gitlab::VERSION } end - def url + def self.url encoded_data = Base64.urlsafe_encode64(data.to_json) + "#{host}?gitlab_info=#{encoded_data}" end - def host + def self.host 'https://version.gitlab.com/check.svg' end end diff --git a/locale/gitlab.pot b/locale/gitlab.pot index e47f1433b8a..0584d2006f7 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -2668,6 +2668,9 @@ msgstr "" msgid "Embed" msgstr "" +msgid "Empty file" +msgstr "" + msgid "Enable" msgstr "" diff --git a/rubocop/cop/inject_enterprise_edition_module.rb b/rubocop/cop/inject_enterprise_edition_module.rb new file mode 100644 index 00000000000..c8b8aca51ab --- /dev/null +++ b/rubocop/cop/inject_enterprise_edition_module.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + # Cop that blacklists the injecting of EE specific modules anywhere but on + # the last line of a file. Injecting a module in the middle of a file will + # cause merge conflicts, while placing it on the last line will not. + class InjectEnterpriseEditionModule < RuboCop::Cop::Cop + MSG = 'Injecting EE modules must be done on the last line of this file' \ + ', outside of any class or module definitions' + + METHODS = Set.new(%i[include extend prepend]).freeze + + def_node_matcher :ee_const?, <<~PATTERN + (const (const _ :EE) _) + PATTERN + + def on_send(node) + return unless METHODS.include?(node.children[1]) + return unless ee_const?(node.children[2]) + + line = node.location.line + buffer = node.location.expression.source_buffer + last_line = buffer.last_line + + # Parser treats the final newline (if present) as a separate line, + # meaning that a simple `line < last_line` would yield true even though + # the expression is the last line _of code_. + last_line -= 1 if buffer.source.end_with?("\n") + + add_offense(node) if line < last_line + end + + # Automatically correcting these offenses is not always possible, as + # sometimes code needs to be refactored to make this work. As such, we + # only allow developers to easily blacklist existing offenses. + def autocorrect(node) + lambda do |corrector| + corrector.insert_after( + node.source_range, + " # rubocop: disable #{cop_name}" + ) + end + end + end + end +end diff --git a/rubocop/rubocop.rb b/rubocop/rubocop.rb index 4489159f422..3e33419eb2e 100644 --- a/rubocop/rubocop.rb +++ b/rubocop/rubocop.rb @@ -41,3 +41,4 @@ require_relative 'cop/code_reuse/presenter' require_relative 'cop/code_reuse/serializer' require_relative 'cop/code_reuse/active_record' require_relative 'cop/group_public_or_visible_to_user' +require_relative 'cop/inject_enterprise_edition_module' diff --git a/scripts/prepare_build.sh b/scripts/prepare_build.sh index 2e8fec166a3..d85c53090a4 100644 --- a/scripts/prepare_build.sh +++ b/scripts/prepare_build.sh @@ -5,7 +5,7 @@ export USE_BUNDLE_INSTALL=${USE_BUNDLE_INSTALL:-true} export BUNDLE_INSTALL_FLAGS="--without=production --jobs=$(nproc) --path=vendor --retry=3 --quiet" if [ "$USE_BUNDLE_INSTALL" != "false" ]; then - bundle install --clean $BUNDLE_INSTALL_FLAGS && bundle check + bundle install --clean $BUNDLE_INSTALL_FLAGS && bundle check fi # Only install knapsack after bundle install! Otherwise oddly some native @@ -22,18 +22,30 @@ export GITLAB_DATABASE=$(echo $CI_JOB_NAME | cut -f1 -d' ' | cut -f2 -d-) # This would make the default database postgresql, and we could also use # pg to mean postgresql. if [ "$GITLAB_DATABASE" != 'mysql' ]; then - export GITLAB_DATABASE='postgresql' + export GITLAB_DATABASE='postgresql' fi cp config/database.yml.$GITLAB_DATABASE config/database.yml +if [ -f config/database_geo.yml.$GITLAB_DATABASE ]; then + cp config/database_geo.yml.$GITLAB_DATABASE config/database_geo.yml +fi + # Set user to a non-superuser to ensure we test permissions sed -i 's/username: root/username: gitlab/g' config/database.yml if [ "$GITLAB_DATABASE" = 'postgresql' ]; then - sed -i 's/localhost/postgres/g' config/database.yml + sed -i 's/localhost/postgres/g' config/database.yml + + if [ -f config/database_geo.yml ]; then + sed -i 's/localhost/postgres/g' config/database_geo.yml + fi else # Assume it's mysql - sed -i 's/localhost/mysql/g' config/database.yml + sed -i 's/localhost/mysql/g' config/database.yml + + if [ -f config/database_geo.yml ]; then + sed -i 's/localhost/mysql/g' config/database_geo.yml + fi fi cp config/resque.yml.example config/resque.yml @@ -49,7 +61,7 @@ cp config/redis.shared_state.yml.example config/redis.shared_state.yml sed -i 's/localhost/redis/g' config/redis.shared_state.yml if [ "$SETUP_DB" != "false" ]; then - setup_db + setup_db elif getent hosts postgres || getent hosts mysql; then - setup_db_user_only + setup_db_user_only fi diff --git a/spec/features/help_pages_spec.rb b/spec/features/help_pages_spec.rb index c29dfb01381..e24b1f4349d 100644 --- a/spec/features/help_pages_spec.rb +++ b/spec/features/help_pages_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'Help Pages' do @@ -52,23 +54,21 @@ describe 'Help Pages' do end end - context 'in a production environment with version check enabled', :js do + context 'in a production environment with version check enabled' do before do - allow(Rails.env).to receive(:production?) { true } stub_application_setting(version_check_enabled: true) - allow_any_instance_of(VersionCheck).to receive(:url) { '/version-check-url' } + + allow(Rails.env).to receive(:production?).and_return(true) + allow(VersionCheck).to receive(:url).and_return('/version-check-url') sign_in(create(:user)) visit help_path end it 'has a version check image' do - expect(find('.js-version-status-badge', visible: false)['src']).to end_with('/version-check-url') - end - - it 'hides the version check image if the image request fails' do - # We use '--load-images=yes' with poltergeist so the image fails to load - expect(page).to have_selector('.js-version-status-badge', visible: false) + # Check `data-src` due to lazy image loading + expect(find('.js-version-status-badge', visible: false)['data-src']) + .to end_with('/version-check-url') end end diff --git a/spec/helpers/version_check_helper_spec.rb b/spec/helpers/version_check_helper_spec.rb index 9d4e34abef5..bfec7ad4bba 100644 --- a/spec/helpers/version_check_helper_spec.rb +++ b/spec/helpers/version_check_helper_spec.rb @@ -13,21 +13,21 @@ describe VersionCheckHelper do before do allow(Rails.env).to receive(:production?) { true } allow(Gitlab::CurrentSettings.current_application_settings).to receive(:version_check_enabled) { true } - allow_any_instance_of(VersionCheck).to receive(:url) { 'https://version.host.com/check.svg?gitlab_info=xxx' } - - @image_tag = helper.version_status_badge + allow(VersionCheck).to receive(:url) { 'https://version.host.com/check.svg?gitlab_info=xxx' } end it 'should return an image tag' do - expect(@image_tag).to match(/^<img/) + expect(helper.version_status_badge).to start_with('<img') end it 'should have a js prefixed css class' do - expect(@image_tag).to match(/class="js-version-status-badge lazy"/) + expect(helper.version_status_badge) + .to match(/class="js-version-status-badge lazy"/) end it 'should have a VersionCheck url as the src' do - expect(@image_tag).to match(%r{src="https://version\.host\.com/check\.svg\?gitlab_info=xxx"}) + expect(helper.version_status_badge) + .to include(%{src="https://version.host.com/check.svg?gitlab_info=xxx"}) end end end diff --git a/spec/javascripts/boards/components/issue_due_date_spec.js b/spec/javascripts/boards/components/issue_due_date_spec.js index 9e49330c052..054cf8c5b7d 100644 --- a/spec/javascripts/boards/components/issue_due_date_spec.js +++ b/spec/javascripts/boards/components/issue_due_date_spec.js @@ -49,10 +49,11 @@ describe('Issue Due Date component', () => { it('should render month and day for other dates', () => { date.setDate(date.getDate() + 17); vm = createComponent(date); + const today = new Date(); + const isDueInCurrentYear = today.getFullYear() === date.getFullYear(); + const format = isDueInCurrentYear ? 'mmm d' : 'mmm d, yyyy'; - expect(vm.$el.querySelector('time').textContent.trim()).toEqual( - dateFormat(date, 'mmm d', true), - ); + expect(vm.$el.querySelector('time').textContent.trim()).toEqual(dateFormat(date, format, true)); }); it('should contain the correct `.text-danger` css class for overdue issue', () => { diff --git a/spec/javascripts/diffs/components/diff_content_spec.js b/spec/javascripts/diffs/components/diff_content_spec.js index d688560a260..9e158327a77 100644 --- a/spec/javascripts/diffs/components/diff_content_spec.js +++ b/spec/javascripts/diffs/components/diff_content_spec.js @@ -50,6 +50,45 @@ describe('DiffContent', () => { }); }); + describe('empty files', () => { + beforeEach(() => { + vm.diffFile.empty = true; + vm.diffFile.highlighted_diff_lines = []; + vm.diffFile.parallel_diff_lines = []; + }); + + it('should render a message', done => { + vm.$nextTick(() => { + const block = vm.$el.querySelector('.diff-viewer .nothing-here-block'); + + expect(block).not.toBe(null); + expect(block.textContent.trim()).toContain('Empty file'); + + done(); + }); + }); + + it('should not render multiple messages', done => { + vm.diffFile.mode_changed = true; + vm.diffFile.b_mode = '100755'; + vm.diffFile.viewer.name = 'mode_changed'; + + vm.$nextTick(() => { + expect(vm.$el.querySelectorAll('.nothing-here-block').length).toBe(1); + + done(); + }); + }); + + it('should not render diff table', done => { + vm.$nextTick(() => { + expect(vm.$el.querySelector('table')).toBe(null); + + done(); + }); + }); + }); + describe('Non-Text diffs', () => { beforeEach(() => { vm.diffFile.viewer.name = 'image'; diff --git a/spec/javascripts/vue_mr_widget/components/mr_widget_rebase_spec.js b/spec/javascripts/vue_mr_widget/components/mr_widget_rebase_spec.js index 300133dc602..212519743aa 100644 --- a/spec/javascripts/vue_mr_widget/components/mr_widget_rebase_spec.js +++ b/spec/javascripts/vue_mr_widget/components/mr_widget_rebase_spec.js @@ -114,7 +114,7 @@ describe('Merge request widget rebase component', () => { // Wait for the eventHub to be called .then(vm.$nextTick()) .then(() => { - expect(eventHub.$emit).toHaveBeenCalledWith('MRWidgetUpdateRequested'); + expect(eventHub.$emit).toHaveBeenCalledWith('MRWidgetRebaseSuccess'); }) .then(done) .catch(done.fail); diff --git a/spec/javascripts/vue_mr_widget/stores/get_state_key_spec.js b/spec/javascripts/vue_mr_widget/stores/get_state_key_spec.js index 9d34bdd1084..61ef26cd080 100644 --- a/spec/javascripts/vue_mr_widget/stores/get_state_key_spec.js +++ b/spec/javascripts/vue_mr_widget/stores/get_state_key_spec.js @@ -35,7 +35,7 @@ describe('getStateKey', () => { expect(bound()).toEqual('mergeWhenPipelineSucceeds'); - context.hasSHAChanged = true; + context.isSHAMismatch = true; expect(bound()).toEqual('shaMismatch'); diff --git a/spec/javascripts/vue_mr_widget/stores/mr_widget_store_spec.js b/spec/javascripts/vue_mr_widget/stores/mr_widget_store_spec.js index f5079147f60..c226704694c 100644 --- a/spec/javascripts/vue_mr_widget/stores/mr_widget_store_spec.js +++ b/spec/javascripts/vue_mr_widget/stores/mr_widget_store_spec.js @@ -3,23 +3,30 @@ import { stateKey } from '~/vue_merge_request_widget/stores/state_maps'; import mockData from '../mock_data'; describe('MergeRequestStore', () => { - describe('setData', () => { - let store; + let store; - beforeEach(() => { - store = new MergeRequestStore(mockData); - }); + beforeEach(() => { + store = new MergeRequestStore(mockData); + }); - it('should set hasSHAChanged when the diff SHA changes', () => { + describe('setData', () => { + it('should set isSHAMismatch when the diff SHA changes', () => { store.setData({ ...mockData, diff_head_sha: 'a-different-string' }); - expect(store.hasSHAChanged).toBe(true); + expect(store.isSHAMismatch).toBe(true); }); - it('should not set hasSHAChanged when other data changes', () => { + it('should not set isSHAMismatch when other data changes', () => { store.setData({ ...mockData, work_in_progress: !mockData.work_in_progress }); - expect(store.hasSHAChanged).toBe(false); + expect(store.isSHAMismatch).toBe(false); + }); + + it('should update cached sha after rebasing', () => { + store.setData({ ...mockData, diff_head_sha: 'abc123' }, true); + + expect(store.isSHAMismatch).toBe(false); + expect(store.sha).toBe('abc123'); }); describe('isPipelinePassing', () => { diff --git a/spec/lib/gitlab/diff/file_spec.rb b/spec/lib/gitlab/diff/file_spec.rb index 3417896e259..b15d22c634a 100644 --- a/spec/lib/gitlab/diff/file_spec.rb +++ b/spec/lib/gitlab/diff/file_spec.rb @@ -583,6 +583,12 @@ describe Gitlab::Diff::File do end end + describe '#empty?' do + it 'returns true' do + expect(diff_file.empty?).to be_truthy + end + end + describe '#different_type?' do it 'returns false' do expect(diff_file).not_to be_different_type @@ -662,4 +668,87 @@ describe Gitlab::Diff::File do end end end + + describe '#empty?' do + let(:project) do + create(:project, :custom_repo, files: {}) + end + let(:branch_name) { 'master' } + + def create_file(file_name, content) + Files::CreateService.new( + project, + project.owner, + commit_message: 'Update', + start_branch: branch_name, + branch_name: branch_name, + file_path: file_name, + file_content: content + ).execute + + project.commit(branch_name).diffs.diff_files.first + end + + def update_file(file_name, content) + Files::UpdateService.new( + project, + project.owner, + commit_message: 'Update', + start_branch: branch_name, + branch_name: branch_name, + file_path: file_name, + file_content: content + ).execute + + project.commit(branch_name).diffs.diff_files.first + end + + def delete_file(file_name) + Files::DeleteService.new( + project, + project.owner, + commit_message: 'Update', + start_branch: branch_name, + branch_name: branch_name, + file_path: file_name + ).execute + + project.commit(branch_name).diffs.diff_files.first + end + + context 'when empty file is created' do + it 'returns true' do + diff_file = create_file('empty.md', '') + + expect(diff_file.empty?).to be_truthy + end + end + + context 'when empty file is deleted' do + it 'returns true' do + create_file('empty.md', '') + diff_file = delete_file('empty.md') + + expect(diff_file.empty?).to be_truthy + end + end + + context 'when file with content is truncated' do + it 'returns false' do + create_file('with-content.md', 'file content') + diff_file = update_file('with-content.md', '') + + expect(diff_file.empty?).to be_falsey + end + end + + context 'when empty file has content added' do + it 'returns false' do + create_file('empty.md', '') + diff_file = update_file('empty.md', 'new content') + + expect(diff_file.empty?).to be_falsey + end + end + end end diff --git a/spec/rubocop/cop/inject_enterprise_edition_module_spec.rb b/spec/rubocop/cop/inject_enterprise_edition_module_spec.rb new file mode 100644 index 00000000000..08ffc3c3a53 --- /dev/null +++ b/spec/rubocop/cop/inject_enterprise_edition_module_spec.rb @@ -0,0 +1,133 @@ +# frozen_string_literal: true + +require 'spec_helper' +require 'rubocop' +require 'rubocop/rspec/support' +require_relative '../../../rubocop/cop/inject_enterprise_edition_module' + +describe RuboCop::Cop::InjectEnterpriseEditionModule do + include CopHelper + + subject(:cop) { described_class.new } + + it 'flags the use of `prepend EE` in the middle of a file' do + expect_offense(<<~SOURCE) + class Foo + prepend EE::Foo + ^^^^^^^^^^^^^^^ Injecting EE modules must be done on the last line of this file, outside of any class or module definitions + end + SOURCE + end + + it 'flags the use of `prepend ::EE` in the middle of a file' do + expect_offense(<<~SOURCE) + class Foo + prepend ::EE::Foo + ^^^^^^^^^^^^^^^^^ Injecting EE modules must be done on the last line of this file, outside of any class or module definitions + end + SOURCE + end + + it 'flags the use of `include EE` in the middle of a file' do + expect_offense(<<~SOURCE) + class Foo + include EE::Foo + ^^^^^^^^^^^^^^^ Injecting EE modules must be done on the last line of this file, outside of any class or module definitions + end + SOURCE + end + + it 'flags the use of `include ::EE` in the middle of a file' do + expect_offense(<<~SOURCE) + class Foo + include ::EE::Foo + ^^^^^^^^^^^^^^^^^ Injecting EE modules must be done on the last line of this file, outside of any class or module definitions + end + SOURCE + end + + it 'flags the use of `extend EE` in the middle of a file' do + expect_offense(<<~SOURCE) + class Foo + extend EE::Foo + ^^^^^^^^^^^^^^ Injecting EE modules must be done on the last line of this file, outside of any class or module definitions + end + SOURCE + end + + it 'flags the use of `extend ::EE` in the middle of a file' do + expect_offense(<<~SOURCE) + class Foo + extend ::EE::Foo + ^^^^^^^^^^^^^^^^ Injecting EE modules must be done on the last line of this file, outside of any class or module definitions + end + SOURCE + end + + it 'does not flag prepending of regular modules' do + expect_no_offenses(<<~SOURCE) + class Foo + prepend Foo + end + SOURCE + end + + it 'does not flag including of regular modules' do + expect_no_offenses(<<~SOURCE) + class Foo + include Foo + end + SOURCE + end + + it 'does not flag extending using regular modules' do + expect_no_offenses(<<~SOURCE) + class Foo + extend Foo + end + SOURCE + end + + it 'does not flag the use of `prepend EE` on the last line' do + expect_no_offenses(<<~SOURCE) + class Foo + end + + Foo.prepend(EE::Foo) + SOURCE + end + + it 'does not flag the use of `include EE` on the last line' do + expect_no_offenses(<<~SOURCE) + class Foo + end + + Foo.include(EE::Foo) + SOURCE + end + + it 'does not flag the use of `extend EE` on the last line' do + expect_no_offenses(<<~SOURCE) + class Foo + end + + Foo.extend(EE::Foo) + SOURCE + end + + it 'autocorrects offenses by just disabling the Cop' do + source = <<~SOURCE + class Foo + prepend EE::Foo + include Bar + end + SOURCE + + expect(autocorrect_source(source)).to eq(<<~SOURCE) + class Foo + prepend EE::Foo # rubocop: disable Cop/InjectEnterpriseEditionModule + include Bar + end + SOURCE + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index cd69160be10..fb3421b61d3 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -115,7 +115,7 @@ RSpec.configure do |config| TestEnv.clean_test_path end - config.before(:example) do + config.before do # Enable all features by default for testing allow(Feature).to receive(:enabled?) { true } @@ -136,11 +136,11 @@ RSpec.configure do |config| RequestStore.clear! end - config.after(:example) do + config.after do Fog.unmock! if Fog.mock? end - config.after(:example) do + config.after do Gitlab::CurrentSettings.clear_in_memory_application_settings! end diff --git a/spec/support/carrierwave.rb b/spec/support/carrierwave.rb index b4b016e408f..b376822d530 100644 --- a/spec/support/carrierwave.rb +++ b/spec/support/carrierwave.rb @@ -1,7 +1,7 @@ CarrierWave.root = File.expand_path('tmp/tests/public', Rails.root) RSpec.configure do |config| - config.after(:each) do + config.after do FileUtils.rm_rf(CarrierWave.root) end end diff --git a/spec/support/db_cleaner.rb b/spec/support/db_cleaner.rb index 5edc5de2a09..34b9efaaecd 100644 --- a/spec/support/db_cleaner.rb +++ b/spec/support/db_cleaner.rb @@ -23,7 +23,7 @@ RSpec.configure do |config| DatabaseCleaner.clean_with(:deletion, cache_tables: false) end - config.before(:each) do + config.before do DatabaseCleaner.strategy = :transaction end @@ -39,11 +39,11 @@ RSpec.configure do |config| DatabaseCleaner.strategy = :deletion, { cache_tables: false } end - config.before(:each) do + config.before do DatabaseCleaner.start end - config.append_after(:each) do + config.append_after do DatabaseCleaner.clean end end diff --git a/spec/support/setup_builds_storage.rb b/spec/support/setup_builds_storage.rb index 2e7c88bfc09..1d2a4856724 100644 --- a/spec/support/setup_builds_storage.rb +++ b/spec/support/setup_builds_storage.rb @@ -11,7 +11,7 @@ RSpec.configure do |config| FileUtils.mkdir_p(builds_path) end - config.before(:each) do + config.before do FileUtils.rm_rf(builds_path) FileUtils.mkdir_p(builds_path) end diff --git a/spec/support/shared_examples/serializers/diff_file_entity_examples.rb b/spec/support/shared_examples/serializers/diff_file_entity_examples.rb index b8065886c42..1770308f789 100644 --- a/spec/support/shared_examples/serializers/diff_file_entity_examples.rb +++ b/spec/support/shared_examples/serializers/diff_file_entity_examples.rb @@ -32,7 +32,7 @@ shared_examples 'diff file entity' do it 'exposes correct attributes' do expect(subject).to include(:too_large, :added_lines, :removed_lines, :context_lines_path, :highlighted_diff_lines, - :parallel_diff_lines) + :parallel_diff_lines, :empty) end it 'includes viewer' do |