From ba537a9b5cf97308fd9fe099e0d022a9a76b66ad Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Tue, 29 Mar 2022 21:08:04 +0000 Subject: [PATCH] Add latest changes from gitlab-org/gitlab@master --- app/services/import/github_service.rb | 2 +- ...-runner-api-status-does-contain-paused.yml | 6 +- doc/tutorials/index.md | 2 +- doc/tutorials/make_your_first_git_commit.md | 2 +- doc/update/deprecations.md | 6 +- doc/user/admin_area/license.md | 18 +- jest.config.base.js | 3 +- lib/backup/manager.rb | 3 +- locale/gitlab.pot | 2 +- package.json | 2 + spec/frontend/__helpers__/matchers/index.js | 1 + .../matchers/to_validate_json_schema.js | 34 ++ .../matchers/to_validate_json_schema_spec.js | 65 ++++ spec/frontend/__helpers__/yaml_transformer.js | 11 + .../editor/schema/ci/ci_schema_spec.js | 90 +++++ .../default_no_additional_properties.json | 12 + ...erit_default_no_additional_properties.json | 8 + ...ob_variables_must_not_contain_objects.json | 12 + .../release_assets_links_empty.json | 13 + ...elease_assets_links_invalid_link_type.json | 24 ++ .../release_assets_links_missing.json | 11 + .../negative_tests/retry_unknown_when.json | 9 + .../positive_tests/allow_failure.json | 19 + .../positive_tests/environment.json | 75 ++++ .../gitlab-ci-dependencies.json | 68 ++++ .../json_tests/positive_tests/gitlab-ci.json | 350 ++++++++++++++++++ .../ci/json_tests/positive_tests/inherit.json | 54 +++ .../positive_tests/multiple-caches.json | 24 ++ .../ci/json_tests/positive_tests/retry.json | 60 +++ .../positive_tests/terraform_report.json | 50 +++ .../json_tests/positive_tests/variables.json | 22 ++ .../variables_mix_string_and_user_input.json | 10 + .../ci/yaml_tests/negative_tests/cache.yml | 15 + .../ci/yaml_tests/negative_tests/include.yml | 17 + .../ci/yaml_tests/positive_tests/cache.yml | 25 ++ .../ci/yaml_tests/positive_tests/filter.yml | 18 + .../ci/yaml_tests/positive_tests/include.yml | 32 ++ .../ci/yaml_tests/positive_tests/rules.yml | 13 + spec/lib/backup/manager_spec.rb | 14 + spec/services/import/github_service_spec.rb | 4 +- yarn.lock | 8 +- 41 files changed, 1193 insertions(+), 21 deletions(-) create mode 100644 spec/frontend/__helpers__/matchers/to_validate_json_schema.js create mode 100644 spec/frontend/__helpers__/matchers/to_validate_json_schema_spec.js create mode 100644 spec/frontend/__helpers__/yaml_transformer.js create mode 100644 spec/frontend/editor/schema/ci/ci_schema_spec.js create mode 100644 spec/frontend/editor/schema/ci/json_tests/negative_tests/default_no_additional_properties.json create mode 100644 spec/frontend/editor/schema/ci/json_tests/negative_tests/inherit_default_no_additional_properties.json create mode 100644 spec/frontend/editor/schema/ci/json_tests/negative_tests/job_variables_must_not_contain_objects.json create mode 100644 spec/frontend/editor/schema/ci/json_tests/negative_tests/release_assets_links_empty.json create mode 100644 spec/frontend/editor/schema/ci/json_tests/negative_tests/release_assets_links_invalid_link_type.json create mode 100644 spec/frontend/editor/schema/ci/json_tests/negative_tests/release_assets_links_missing.json create mode 100644 spec/frontend/editor/schema/ci/json_tests/negative_tests/retry_unknown_when.json create mode 100644 spec/frontend/editor/schema/ci/json_tests/positive_tests/allow_failure.json create mode 100644 spec/frontend/editor/schema/ci/json_tests/positive_tests/environment.json create mode 100644 spec/frontend/editor/schema/ci/json_tests/positive_tests/gitlab-ci-dependencies.json create mode 100644 spec/frontend/editor/schema/ci/json_tests/positive_tests/gitlab-ci.json create mode 100644 spec/frontend/editor/schema/ci/json_tests/positive_tests/inherit.json create mode 100644 spec/frontend/editor/schema/ci/json_tests/positive_tests/multiple-caches.json create mode 100644 spec/frontend/editor/schema/ci/json_tests/positive_tests/retry.json create mode 100644 spec/frontend/editor/schema/ci/json_tests/positive_tests/terraform_report.json create mode 100644 spec/frontend/editor/schema/ci/json_tests/positive_tests/variables.json create mode 100644 spec/frontend/editor/schema/ci/json_tests/positive_tests/variables_mix_string_and_user_input.json create mode 100644 spec/frontend/editor/schema/ci/yaml_tests/negative_tests/cache.yml create mode 100644 spec/frontend/editor/schema/ci/yaml_tests/negative_tests/include.yml create mode 100644 spec/frontend/editor/schema/ci/yaml_tests/positive_tests/cache.yml create mode 100644 spec/frontend/editor/schema/ci/yaml_tests/positive_tests/filter.yml create mode 100644 spec/frontend/editor/schema/ci/yaml_tests/positive_tests/include.yml create mode 100644 spec/frontend/editor/schema/ci/yaml_tests/positive_tests/rules.yml diff --git a/app/services/import/github_service.rb b/app/services/import/github_service.rb index 061543b5885..a891dcc11e3 100644 --- a/app/services/import/github_service.rb +++ b/app/services/import/github_service.rb @@ -117,7 +117,7 @@ module Import error: exception.response_body ) - error(_('Import failed due to a GitHub error: %{original}') % { original: exception.response_body }, :unprocessable_entity) + error(_('Import failed due to a GitHub error: %{original} (HTTP %{code})') % { original: exception.response_body, code: exception.response_status }, :unprocessable_entity) end def log_and_return_error(message, translated_message, http_status) diff --git a/data/deprecations/14-5-runner-api-status-does-contain-paused.yml b/data/deprecations/14-5-runner-api-status-does-contain-paused.yml index 46f1ef89b53..5acfac45ca2 100644 --- a/data/deprecations/14-5-runner-api-status-does-contain-paused.yml +++ b/data/deprecations/14-5-runner-api-status-does-contain-paused.yml @@ -1,11 +1,11 @@ - name: "REST and GraphQL API Runner status will not return `paused`" announcement_milestone: "14.5" # The milestone when this feature was first announced as deprecated. announcement_date: "2021-11-22" - removal_milestone: "15.0" # the milestone when this feature is planned to be removed - removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed + removal_milestone: "16.0" # the milestone when this feature is planned to be removed + removal_date: "2023-04-22" # the date of the milestone release when this feature is planned to be removed breaking_change: true body: | # Do not modify this line, instead modify the lines below. - The GitLab Runner REST and GraphQL API endpoints will not return `paused` or `active` as a status in GitLab 15.0. + The GitLab Runner REST and GraphQL API endpoints will not return `paused` or `active` as a status in GitLab 16.0. A runner's status will only relate to runner contact status, such as: `online`, `offline`, or `not_connected`. Status `paused` or `active` will no longer appear. diff --git a/doc/tutorials/index.md b/doc/tutorials/index.md index f40d77879fd..5f2b436e1c4 100644 --- a/doc/tutorials/index.md +++ b/doc/tutorials/index.md @@ -1,7 +1,7 @@ --- stage: none group: unassigned -info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments +info: For assistance with this tutorials page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments-to-other-projects-and-subjects. --- # Learn GitLab with tutorials diff --git a/doc/tutorials/make_your_first_git_commit.md b/doc/tutorials/make_your_first_git_commit.md index 06ab3301bd4..4b88b528be6 100644 --- a/doc/tutorials/make_your_first_git_commit.md +++ b/doc/tutorials/make_your_first_git_commit.md @@ -1,7 +1,7 @@ --- stage: none group: unassigned -info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments +info: For assistance with this tutorial, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments-to-other-projects-and-subjects. --- # Make your first Git commit diff --git a/doc/update/deprecations.md b/doc/update/deprecations.md index 592aafe28b9..4aaee1172a5 100644 --- a/doc/update/deprecations.md +++ b/doc/update/deprecations.md @@ -1315,12 +1315,12 @@ In milestone 15.0, we will remove the `pipelines` attribute from the API respons ### REST and GraphQL API Runner status will not return `paused` WARNING: -This feature will be changed or removed in 15.0 +This feature will be changed or removed in 16.0 as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#breaking-changes). Before updating GitLab, review the details carefully to determine if you need to make any changes to your code, settings, or workflow. -The GitLab Runner REST and GraphQL API endpoints will not return `paused` or `active` as a status in GitLab 15.0. +The GitLab Runner REST and GraphQL API endpoints will not return `paused` or `active` as a status in GitLab 16.0. A runner's status will only relate to runner contact status, such as: `online`, `offline`, or `not_connected`. Status `paused` or `active` will no longer appear. @@ -1328,7 +1328,7 @@ A runner's status will only relate to runner contact status, such as: When checking if a runner is `paused`, API users are advised to check the boolean attribute `paused` to be `true` instead. When checking if a runner is `active`, check if `paused` is `false`. -**Planned removal milestone: 15.0 (2022-05-22)** +**Planned removal milestone: 16.0 (2023-04-22)** ### Support for SLES 12 SP2 diff --git a/doc/user/admin_area/license.md b/doc/user/admin_area/license.md index bee784e850b..892b9f6e5b6 100644 --- a/doc/user/admin_area/license.md +++ b/doc/user/admin_area/license.md @@ -36,7 +36,7 @@ To activate your instance with an activation code: The subscription is activated. -If you have an offline or airgapped environment, +If you have an offline or air gapped environment, [activate GitLab EE with a license file or key](license_file.md) instead. If you have questions or need assistance activating your instance, @@ -51,7 +51,19 @@ To verify the edition, sign in to GitLab and select **Help** (**{question-o}**) > **Help**. The GitLab edition and version are listed at the top of the page. -If you are running GitLab Community Edition (CE), you can upgrade your installation to GitLab +If you are running GitLab Community Edition, you can upgrade your installation to GitLab EE. For more details, see [Upgrading between editions](../../update/index.md#upgrading-between-editions). -If you have questions or need assistance upgrading from GitLab CE to EE, +If you have questions or need assistance upgrading from GitLab Community Edition (CE) to EE, [contact GitLab Support](https://about.gitlab.com/support/#contact-support). + +## Troubleshooting + +### Cannot activate instance due to connectivity error + +This error occurs when you use an activation code to activate your instance, but your instance is unable to connect to the GitLab servers. + +You may have connectivity issues due to the following reasons: + +- **You have an offline or air gapped environment**: Configure your setup to allow connection to GitLab servers. If connection to GitLab servers is not possible, contact [GitLab support](https://about.gitlab.com/support/#contact-support) to request a license key. +- **Firewall settings**: Enable an encrypted HTTPS connection from your GitLab instance to `customers.gitlab.com` (with IP addresses 104.18.26.123 and 104.18.27.123) on port 443. +- **Customers Portal is not operational**: To check for performance or service disruptions, check the Customers Portal [status](https://status.gitlab.com/). diff --git a/jest.config.base.js b/jest.config.base.js index 0eab5caffb0..59c127fcb8a 100644 --- a/jest.config.base.js +++ b/jest.config.base.js @@ -109,7 +109,7 @@ module.exports = (path, options = {}) => { return { clearMocks: true, testMatch, - moduleFileExtensions: ['js', 'json', 'vue', 'gql', 'graphql'], + moduleFileExtensions: ['js', 'json', 'vue', 'gql', 'graphql', 'yaml'], moduleNameMapper, collectCoverageFrom, coverageDirectory: coverageDirectory(), @@ -127,6 +127,7 @@ module.exports = (path, options = {}) => { '^.+_worker\\.js$': './spec/frontend/__helpers__/web_worker_transformer.js', '^.+\\.js$': 'babel-jest', '^.+\\.vue$': 'vue-jest', + '^.+\\.yml$': './spec/frontend/__helpers__/yaml_transformer.js', '^.+\\.(md|zip|png)$': 'jest-raw-loader', }, transformIgnorePatterns: [ diff --git a/lib/backup/manager.rb b/lib/backup/manager.rb index a33ebf1b83a..2d7277c7f8d 100644 --- a/lib/backup/manager.rb +++ b/lib/backup/manager.rb @@ -389,7 +389,8 @@ module Backup end def skipped?(item) - backup_information[:skipped] && backup_information[:skipped].include?(item) + ENV.fetch('SKIP', '').include?(item) || + backup_information[:skipped] && backup_information[:skipped].include?(item) end def enabled_task?(task_name) diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 39fa905bdda..12e17901aea 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -18864,7 +18864,7 @@ msgstr "" msgid "Import and export rate limits" msgstr "" -msgid "Import failed due to a GitHub error: %{original}" +msgid "Import failed due to a GitHub error: %{original} (HTTP %{code})" msgstr "" msgid "Import from" diff --git a/package.json b/package.json index d7908b33ec9..fc8d43d6a1f 100644 --- a/package.json +++ b/package.json @@ -206,6 +206,8 @@ "@types/jest": "^26.0.24", "@vue/test-utils": "1.3.0", "acorn": "^6.3.0", + "ajv": "^8.10.0", + "ajv-formats": "^2.1.1", "axios-mock-adapter": "^1.15.0", "babel-jest": "^26.5.2", "babel-plugin-dynamic-import-node": "^2.3.3", diff --git a/spec/frontend/__helpers__/matchers/index.js b/spec/frontend/__helpers__/matchers/index.js index 76571bafb06..9b83ced10e1 100644 --- a/spec/frontend/__helpers__/matchers/index.js +++ b/spec/frontend/__helpers__/matchers/index.js @@ -1,3 +1,4 @@ export * from './to_have_sprite_icon'; export * from './to_have_tracking_attributes'; export * from './to_match_interpolated_text'; +export * from './to_validate_json_schema'; diff --git a/spec/frontend/__helpers__/matchers/to_validate_json_schema.js b/spec/frontend/__helpers__/matchers/to_validate_json_schema.js new file mode 100644 index 00000000000..ff391f08c55 --- /dev/null +++ b/spec/frontend/__helpers__/matchers/to_validate_json_schema.js @@ -0,0 +1,34 @@ +// NOTE: Make sure to initialize ajv when using this helper + +const getAjvErrorMessage = ({ errors }) => { + return (errors || []).map((error) => { + return `Error with item ${error.instancePath}: ${error.message}`; + }); +}; + +export function toValidateJsonSchema(testData, validator) { + if (!(validator instanceof Function && validator.schema)) { + return { + validator, + message: () => + 'Validator must be a validating function with property "schema", created with `ajv.compile`. See https://ajv.js.org/api.html#ajv-compile-schema-object-data-any-boolean-promise-any.', + pass: false, + }; + } + + const isValid = validator(testData); + + return { + actual: testData, + message: () => { + if (isValid) { + // We can match, but still fail because we're in a `expect...not.` context + return 'Expected the given data not to pass the schema validation, but found that it was considered valid.'; + } + + const errorMessages = getAjvErrorMessage(validator).join('\n'); + return `Expected the given data to pass the schema validation, but found that it was considered invalid. Errors:\n${errorMessages}`; + }, + pass: isValid, + }; +} diff --git a/spec/frontend/__helpers__/matchers/to_validate_json_schema_spec.js b/spec/frontend/__helpers__/matchers/to_validate_json_schema_spec.js new file mode 100644 index 00000000000..fd42c710c65 --- /dev/null +++ b/spec/frontend/__helpers__/matchers/to_validate_json_schema_spec.js @@ -0,0 +1,65 @@ +import Ajv from 'ajv'; +import AjvFormats from 'ajv-formats'; + +const JSON_SCHEMA = { + type: 'object', + properties: { + fruit: { + type: 'string', + minLength: 3, + }, + }, +}; + +const ajv = new Ajv({ + strictTypes: false, + strictTuples: false, + allowMatchingProperties: true, +}); + +AjvFormats(ajv); +const schema = ajv.compile(JSON_SCHEMA); + +describe('custom matcher toValidateJsonSchema', () => { + it('throws error if validator is not compiled correctly', () => { + expect(() => { + expect({}).toValidateJsonSchema({}); + }).toThrow( + 'Validator must be a validating function with property "schema", created with `ajv.compile`. See https://ajv.js.org/api.html#ajv-compile-schema-object-data-any-boolean-promise-any.', + ); + }); + + describe('positive assertions', () => { + it.each` + description | input + ${'valid input'} | ${{ fruit: 'apple' }} + `('schema validation passes for $description', ({ input }) => { + expect(input).toValidateJsonSchema(schema); + }); + + it('throws if not matching', () => { + expect(() => expect(null).toValidateJsonSchema(schema)).toThrowError( + `Expected the given data to pass the schema validation, but found that it was considered invalid. Errors: +Error with item : must be object`, + ); + }); + }); + + describe('negative assertions', () => { + it.each` + description | input + ${'no input'} | ${null} + ${'input with invalid type'} | ${'banana'} + ${'input with invalid length'} | ${{ fruit: 'aa' }} + ${'input with invalid type'} | ${{ fruit: 12345 }} + `('schema validation fails for $description', ({ input }) => { + expect(input).not.toValidateJsonSchema(schema); + }); + + it('throws if matching', () => { + expect(() => expect({ fruit: 'apple' }).not.toValidateJsonSchema(schema)).toThrowError( + 'Expected the given data not to pass the schema validation, but found that it was considered valid.', + ); + }); + }); +}); diff --git a/spec/frontend/__helpers__/yaml_transformer.js b/spec/frontend/__helpers__/yaml_transformer.js new file mode 100644 index 00000000000..a23f9b1f715 --- /dev/null +++ b/spec/frontend/__helpers__/yaml_transformer.js @@ -0,0 +1,11 @@ +/* eslint-disable import/no-commonjs */ +const JsYaml = require('js-yaml'); + +// This will transform YAML files to JSON strings +module.exports = { + process: (sourceContent) => { + const jsonContent = JsYaml.load(sourceContent); + const json = JSON.stringify(jsonContent); + return `module.exports = ${json}`; + }, +}; diff --git a/spec/frontend/editor/schema/ci/ci_schema_spec.js b/spec/frontend/editor/schema/ci/ci_schema_spec.js new file mode 100644 index 00000000000..628c34a27c1 --- /dev/null +++ b/spec/frontend/editor/schema/ci/ci_schema_spec.js @@ -0,0 +1,90 @@ +import Ajv from 'ajv'; +import AjvFormats from 'ajv-formats'; +import CiSchema from '~/editor/schema/ci.json'; + +// JSON POSITIVE TESTS +import AllowFailureJson from './json_tests/positive_tests/allow_failure.json'; +import EnvironmentJson from './json_tests/positive_tests/environment.json'; +import GitlabCiDependenciesJson from './json_tests/positive_tests/gitlab-ci-dependencies.json'; +import GitlabCiJson from './json_tests/positive_tests/gitlab-ci.json'; +import InheritJson from './json_tests/positive_tests/inherit.json'; +import MultipleCachesJson from './json_tests/positive_tests/multiple-caches.json'; +import RetryJson from './json_tests/positive_tests/retry.json'; +import TerraformReportJson from './json_tests/positive_tests/terraform_report.json'; +import VariablesMixStringAndUserInputJson from './json_tests/positive_tests/variables_mix_string_and_user_input.json'; +import VariablesJson from './json_tests/positive_tests/variables.json'; + +// JSON NEGATIVE TESTS +import DefaultNoAdditionalPropertiesJson from './json_tests/negative_tests/default_no_additional_properties.json'; +import InheritDefaultNoAdditionalPropertiesJson from './json_tests/negative_tests/inherit_default_no_additional_properties.json'; +import JobVariablesMustNotContainObjectsJson from './json_tests/negative_tests/job_variables_must_not_contain_objects.json'; +import ReleaseAssetsLinksEmptyJson from './json_tests/negative_tests/release_assets_links_empty.json'; +import ReleaseAssetsLinksInvalidLinkTypeJson from './json_tests/negative_tests/release_assets_links_invalid_link_type.json'; +import ReleaseAssetsLinksMissingJson from './json_tests/negative_tests/release_assets_links_missing.json'; +import RetryUnknownWhenJson from './json_tests/negative_tests/retry_unknown_when.json'; + +// YAML POSITIVE TEST +import CacheYaml from './yaml_tests/positive_tests/cache.yml'; +import FilterYaml from './yaml_tests/positive_tests/filter.yml'; +import IncludeYaml from './yaml_tests/positive_tests/include.yml'; +import RulesYaml from './yaml_tests/positive_tests/rules.yml'; + +// YAML NEGATIVE TEST +import CacheNegativeYaml from './yaml_tests/negative_tests/cache.yml'; +import IncludeNegativeYaml from './yaml_tests/negative_tests/include.yml'; + +const ajv = new Ajv({ + strictTypes: false, + strictTuples: false, + allowMatchingProperties: true, +}); + +AjvFormats(ajv); +const schema = ajv.compile(CiSchema); + +describe('positive tests', () => { + it.each( + Object.entries({ + // JSON + AllowFailureJson, + EnvironmentJson, + GitlabCiDependenciesJson, + GitlabCiJson, + InheritJson, + MultipleCachesJson, + RetryJson, + TerraformReportJson, + VariablesMixStringAndUserInputJson, + VariablesJson, + + // YAML + CacheYaml, + FilterYaml, + IncludeYaml, + RulesYaml, + }), + )('schema validates %s', (_, input) => { + expect(input).toValidateJsonSchema(schema); + }); +}); + +describe('negative tests', () => { + it.each( + Object.entries({ + // JSON + DefaultNoAdditionalPropertiesJson, + JobVariablesMustNotContainObjectsJson, + InheritDefaultNoAdditionalPropertiesJson, + ReleaseAssetsLinksEmptyJson, + ReleaseAssetsLinksInvalidLinkTypeJson, + ReleaseAssetsLinksMissingJson, + RetryUnknownWhenJson, + + // YAML + CacheNegativeYaml, + IncludeNegativeYaml, + }), + )('schema validates %s', (_, input) => { + expect(input).not.toValidateJsonSchema(schema); + }); +}); diff --git a/spec/frontend/editor/schema/ci/json_tests/negative_tests/default_no_additional_properties.json b/spec/frontend/editor/schema/ci/json_tests/negative_tests/default_no_additional_properties.json new file mode 100644 index 00000000000..955c19ef1ab --- /dev/null +++ b/spec/frontend/editor/schema/ci/json_tests/negative_tests/default_no_additional_properties.json @@ -0,0 +1,12 @@ +{ + "default": { + "secrets": { + "DATABASE_PASSWORD": { + "vault": "production/db/password" + } + }, + "environment": { + "name": "test" + } + } +} diff --git a/spec/frontend/editor/schema/ci/json_tests/negative_tests/inherit_default_no_additional_properties.json b/spec/frontend/editor/schema/ci/json_tests/negative_tests/inherit_default_no_additional_properties.json new file mode 100644 index 00000000000..7411e4c2434 --- /dev/null +++ b/spec/frontend/editor/schema/ci/json_tests/negative_tests/inherit_default_no_additional_properties.json @@ -0,0 +1,8 @@ +{ + "karma": { + "inherit": { + "default": ["secrets"] + }, + "script": "karma" + } +} diff --git a/spec/frontend/editor/schema/ci/json_tests/negative_tests/job_variables_must_not_contain_objects.json b/spec/frontend/editor/schema/ci/json_tests/negative_tests/job_variables_must_not_contain_objects.json new file mode 100644 index 00000000000..bfdbf26ee70 --- /dev/null +++ b/spec/frontend/editor/schema/ci/json_tests/negative_tests/job_variables_must_not_contain_objects.json @@ -0,0 +1,12 @@ +{ + "gitlab-ci-variables-object": { + "stage": "test", + "script": ["true"], + "variables": { + "DEPLOY_ENVIRONMENT": { + "value": "staging", + "description": "The deployment target. Change this variable to 'canary' or 'production' if needed." + } + } + } +} diff --git a/spec/frontend/editor/schema/ci/json_tests/negative_tests/release_assets_links_empty.json b/spec/frontend/editor/schema/ci/json_tests/negative_tests/release_assets_links_empty.json new file mode 100644 index 00000000000..84a1aa14698 --- /dev/null +++ b/spec/frontend/editor/schema/ci/json_tests/negative_tests/release_assets_links_empty.json @@ -0,0 +1,13 @@ +{ + "gitlab-ci-release-assets-links-empty": { + "script": "dostuff", + "stage": "deploy", + "release": { + "description": "Created using the release-cli $EXTRA_DESCRIPTION", + "tag_name": "$CI_COMMIT_TAG", + "assets": { + "links": [] + } + } + } +} diff --git a/spec/frontend/editor/schema/ci/json_tests/negative_tests/release_assets_links_invalid_link_type.json b/spec/frontend/editor/schema/ci/json_tests/negative_tests/release_assets_links_invalid_link_type.json new file mode 100644 index 00000000000..048911aefa3 --- /dev/null +++ b/spec/frontend/editor/schema/ci/json_tests/negative_tests/release_assets_links_invalid_link_type.json @@ -0,0 +1,24 @@ +{ + "gitlab-ci-release-assets-links-invalid-link-type": { + "script": "dostuff", + "stage": "deploy", + "release": { + "description": "Created using the release-cli $EXTRA_DESCRIPTION", + "tag_name": "$CI_COMMIT_TAG", + "assets": { + "links": [ + { + "name": "asset1", + "url": "https://example.com/assets/1" + }, + { + "name": "asset2", + "url": "https://example.com/assets/2", + "filepath": "/pretty/url/1", + "link_type": "invalid" + } + ] + } + } + } +} diff --git a/spec/frontend/editor/schema/ci/json_tests/negative_tests/release_assets_links_missing.json b/spec/frontend/editor/schema/ci/json_tests/negative_tests/release_assets_links_missing.json new file mode 100644 index 00000000000..6f0b5a3bff8 --- /dev/null +++ b/spec/frontend/editor/schema/ci/json_tests/negative_tests/release_assets_links_missing.json @@ -0,0 +1,11 @@ +{ + "gitlab-ci-release-assets-links-missing": { + "script": "dostuff", + "stage": "deploy", + "release": { + "description": "Created using the release-cli $EXTRA_DESCRIPTION", + "tag_name": "$CI_COMMIT_TAG", + "assets": {} + } + } +} diff --git a/spec/frontend/editor/schema/ci/json_tests/negative_tests/retry_unknown_when.json b/spec/frontend/editor/schema/ci/json_tests/negative_tests/retry_unknown_when.json new file mode 100644 index 00000000000..433504f52c6 --- /dev/null +++ b/spec/frontend/editor/schema/ci/json_tests/negative_tests/retry_unknown_when.json @@ -0,0 +1,9 @@ +{ + "gitlab-ci-retry-object-unknown-when": { + "stage": "test", + "script": "rspec", + "retry": { + "when": "gitlab-ci-retry-object-unknown-when" + } + } +} diff --git a/spec/frontend/editor/schema/ci/json_tests/positive_tests/allow_failure.json b/spec/frontend/editor/schema/ci/json_tests/positive_tests/allow_failure.json new file mode 100644 index 00000000000..44d42116c1a --- /dev/null +++ b/spec/frontend/editor/schema/ci/json_tests/positive_tests/allow_failure.json @@ -0,0 +1,19 @@ +{ + "job1": { + "stage": "test", + "script": ["execute_script_that_will_fail"], + "allow_failure": true + }, + "job2": { + "script": ["exit 1"], + "allow_failure": { + "exit_codes": 137 + } + }, + "job3": { + "script": ["exit 137"], + "allow_failure": { + "exit_codes": [137, 255] + } + } +} diff --git a/spec/frontend/editor/schema/ci/json_tests/positive_tests/environment.json b/spec/frontend/editor/schema/ci/json_tests/positive_tests/environment.json new file mode 100644 index 00000000000..0c6f7935063 --- /dev/null +++ b/spec/frontend/editor/schema/ci/json_tests/positive_tests/environment.json @@ -0,0 +1,75 @@ +{ + "deploy to production 1": { + "stage": "deploy", + "script": "git push production HEAD: master", + "environment": "production" + }, + "deploy to production 2": { + "stage": "deploy", + "script": "git push production HEAD:master", + "environment": { + "name": "production" + } + }, + "deploy to production 3": { + "stage": "deploy", + "script": "git push production HEAD:master", + "environment": { + "name": "production", + "url": "https://prod.example.com" + } + }, + "review_app 1": { + "stage": "deploy", + "script": "make deploy-app", + "environment": { + "name": "review/$CI_COMMIT_REF_NAME", + "url": "https://$CI_ENVIRONMENT_SLUG.example.com", + "on_stop": "stop_review_app" + } + }, + "stop_review_app": { + "stage": "deploy", + "variables": { + "GIT_STRATEGY": "none" + }, + "script": "make delete-app", + "when": "manual", + "environment": { + "name": "review/$CI_COMMIT_REF_NAME", + "action": "stop" + } + }, + "review_app 2": { + "script": "deploy-review-app", + "environment": { + "name": "review/$CI_COMMIT_REF_NAME", + "auto_stop_in": "1 day" + } + }, + "deploy 1": { + "stage": "deploy", + "script": "make deploy-app", + "environment": { + "name": "production", + "kubernetes": { + "namespace": "production" + } + } + }, + "deploy 2": { + "script": "echo", + "environment": { + "name": "customer-portal", + "deployment_tier": "production" + } + }, + "deploy as review app": { + "stage": "deploy", + "script": "make deploy", + "environment": { + "name": "review/$CI_COMMIT_REF_NAME", + "url": "https://$CI_ENVIRONMENT_SLUG.example.com/" + } + } +} diff --git a/spec/frontend/editor/schema/ci/json_tests/positive_tests/gitlab-ci-dependencies.json b/spec/frontend/editor/schema/ci/json_tests/positive_tests/gitlab-ci-dependencies.json new file mode 100644 index 00000000000..5ffa7fa799e --- /dev/null +++ b/spec/frontend/editor/schema/ci/json_tests/positive_tests/gitlab-ci-dependencies.json @@ -0,0 +1,68 @@ +{ + ".build_config": { + "before_script": ["echo test"] + }, + ".build_script": "echo build script", + "default": { + "image": "ruby:2.5", + "services": ["docker:dind"], + "cache": { + "paths": ["vendor/"] + }, + "before_script": ["bundle install --path vendor/"], + "after_script": ["rm -rf tmp/"] + }, + "stages": ["install", "build", "test", "deploy"], + "image": "foo:latest", + "install task1": { + "image": "node:latest", + "stage": "install", + "script": "npm install", + "artifacts": { + "paths": ["node_modules/"] + } + }, + "build dev": { + "image": "node:latest", + "stage": "build", + "needs": [ + { + "job": "install task1" + } + ], + "script": "npm run build:dev" + }, + "build prod": { + "image": "node:latest", + "stage": "build", + "needs": ["install task1"], + "script": "npm run build:prod" + }, + "test": { + "image": "node:latest", + "stage": "build", + "needs": [ + "install task1", + { + "job": "build dev", + "artifacts": true + } + ], + "script": "npm run test" + }, + "deploy it": { + "image": "node:latest", + "stage": "deploy", + "needs": [ + { + "job": "build dev", + "artifacts": false + }, + { + "job": "build prod", + "artifacts": true + } + ], + "script": "npm run test" + } +} diff --git a/spec/frontend/editor/schema/ci/json_tests/positive_tests/gitlab-ci.json b/spec/frontend/editor/schema/ci/json_tests/positive_tests/gitlab-ci.json new file mode 100644 index 00000000000..89420bbc35f --- /dev/null +++ b/spec/frontend/editor/schema/ci/json_tests/positive_tests/gitlab-ci.json @@ -0,0 +1,350 @@ +{ + ".build_config": { + "before_script": ["echo test"] + }, + ".build_script": "echo build script", + ".example_variables": { + "foo": "hello", + "bar": 42 + }, + ".example_services": [ + "docker:dind", + { + "name": "sql:latest", + "command": ["/usr/bin/super-sql", "run"] + } + ], + "default": { + "image": "ruby:2.5", + "services": ["docker:dind"], + "cache": { + "paths": ["vendor/"] + }, + "before_script": ["bundle install --path vendor/"], + "after_script": ["rm -rf tmp/"], + "tags": ["ruby", "postgres"], + "artifacts": { + "name": "%CI_COMMIT_REF_NAME%", + "expose_as": "artifact 1", + "paths": ["path/to/file.txt", "target/*.war"], + "when": "on_failure" + }, + "retry": 2, + "timeout": "3 hours 30 minutes", + "interruptible": true + }, + "stages": ["build", "test", "deploy", "random"], + "image": "foo:latest", + "services": ["sql:latest"], + "before_script": ["echo test", "echo test2"], + "after_script": [], + "cache": { + "key": "asd", + "paths": ["dist/", ".foo"], + "untracked": false, + "policy": "pull" + }, + "variables": { + "STAGE": "yep", + "PROD": "nope" + }, + "include": [ + "https://gitlab.com/awesome-project/raw/master/.before-script-template.yml", + "/templates/.after-script-template.yml", + { "template": "Auto-DevOps.gitlab-ci.yml" }, + { + "project": "my-group/my-project", + "ref": "master", + "file": "/templates/.gitlab-ci-template.yml" + }, + { + "project": "my-group/my-project", + "ref": "master", + "file": ["/templates/.gitlab-ci-template.yml", "/templates/another-template-to-include.yml"] + } + ], + "build": { + "image": { + "name": "node:latest" + }, + "services": [], + "stage": "build", + "script": "npm run build", + "before_script": ["npm install"], + "rules": [ + { + "if": "moo", + "changes": ["Moofile"], + "exists": ["main.cow"], + "when": "delayed", + "start_in": "3 hours" + } + ], + "retry": { + "max": 1, + "when": "stuck_or_timeout_failure" + }, + "cache": { + "key": "$CI_COMMIT_REF_NAME", + "paths": ["node_modules/"], + "policy": "pull-push" + }, + "artifacts": { + "paths": ["dist/"], + "expose_as": "link_name_in_merge_request", + "name": "bundles", + "when": "on_success", + "expire_in": "1 week", + "reports": { + "junit": "result.xml", + "cobertura": "cobertura-coverage.xml", + "codequality": "codequality.json", + "sast": "sast.json", + "dependency_scanning": "scan.json", + "container_scanning": "scan2.json", + "dast": "dast.json", + "license_management": "license.json", + "performance": "performance.json", + "metrics": "metrics.txt" + } + }, + "variables": { + "FOO_BAR": "..." + }, + "only": { + "kubernetes": "active", + "variables": ["$FOO_BAR == '...'"], + "changes": ["/path/to/file", "/another/file"] + }, + "except": ["master", "tags"], + "tags": ["docker"], + "allow_failure": true, + "when": "manual" + }, + "error-report": { + "when": "on_failure", + "script": "report error", + "stage": "test" + }, + "test": { + "image": { + "name": "node:latest", + "entrypoint": [""] + }, + "stage": "test", + "script": "npm test", + "parallel": 5, + "retry": { + "max": 2, + "when": [ + "runner_system_failure", + "stuck_or_timeout_failure", + "script_failure", + "unknown_failure", + "always" + ] + }, + "artifacts": { + "reports": { + "junit": ["result.xml"], + "cobertura": ["cobertura-coverage.xml"], + "codequality": ["codequality.json"], + "sast": ["sast.json"], + "dependency_scanning": ["scan.json"], + "container_scanning": ["scan2.json"], + "dast": ["dast.json"], + "license_management": ["license.json"], + "performance": ["performance.json"], + "metrics": ["metrics.txt"] + } + }, + "coverage": "/Cycles: \\d+\\.\\d+$/", + "dependencies": [] + }, + "docker": { + "script": "docker build -t foo:latest", + "when": "delayed", + "start_in": "10 min", + "timeout": "1h", + "retry": 1, + "only": { + "changes": ["Dockerfile", "docker/scripts/*"] + } + }, + "deploy": { + "services": [ + { + "name": "sql:latest", + "entrypoint": [""], + "command": ["/usr/bin/super-sql", "run"], + "alias": "super-sql" + }, + "sql:latest", + { + "name": "sql:latest", + "alias": "default-sql" + } + ], + "script": "dostuff", + "stage": "deploy", + "environment": { + "name": "prod", + "url": "http://example.com", + "on_stop": "stop-deploy" + }, + "only": ["master"], + "release": { + "name": "Release $CI_COMMIT_TAG", + "description": "Created using the release-cli $EXTRA_DESCRIPTION", + "tag_name": "$CI_COMMIT_TAG", + "ref": "$CI_COMMIT_TAG", + "milestones": ["m1", "m2", "m3"], + "released_at": "2020-07-15T08:00:00Z", + "assets": { + "links": [ + { + "name": "asset1", + "url": "https://example.com/assets/1" + }, + { + "name": "asset2", + "url": "https://example.com/assets/2", + "filepath": "/pretty/url/1", + "link_type": "other" + }, + { + "name": "asset3", + "url": "https://example.com/assets/3", + "link_type": "runbook" + }, + { + "name": "asset4", + "url": "https://example.com/assets/4", + "link_type": "package" + }, + { + "name": "asset5", + "url": "https://example.com/assets/5", + "link_type": "image" + } + ] + } + } + }, + ".performance-tmpl": { + "after_script": ["echo after"], + "before_script": ["echo before"], + "variables": { + "SCRIPT_NOT_REQUIRED": "true" + } + }, + "performance-a": { + "extends": ".performance-tmpl", + "script": "echo test" + }, + "performance-b": { + "extends": ".performance-tmpl" + }, + "workflow": { + "rules": [ + { + "if": "$CI_COMMIT_REF_NAME =~ /-wip$/", + "when": "never" + }, + { + "if": "$CI_COMMIT_TAG", + "when": "never" + }, + { + "when": "always" + } + ] + }, + "job": { + "script": "echo Hello, Rules!", + "rules": [ + { + "if": "$CI_MERGE_REQUEST_TARGET_BRANCH_NAME == \"master\"", + "when": "manual", + "allow_failure": true + } + ] + }, + "microservice_a": { + "trigger": { + "include": "path/to/microservice_a.yml" + } + }, + "microservice_b": { + "trigger": { + "include": [{ "local": "path/to/microservice_b.yml" }, { "template": "SAST.gitlab-cy.yml" }], + "strategy": "depend" + } + }, + "child-pipeline": { + "stage": "test", + "trigger": { + "include": [ + { + "artifact": "generated-config.yml", + "job": "generate-config" + } + ] + } + }, + "child-pipeline-simple": { + "stage": "test", + "trigger": { + "include": "other/file.yml" + } + }, + "complex": { + "stage": "deploy", + "trigger": { + "project": "my/deployment", + "branch": "stable" + } + }, + "parallel-integer": { + "stage": "test", + "script": ["echo ${CI_NODE_INDEX} ${CI_NODE_TOTAL}"], + "parallel": 5 + }, + "parallel-matrix-simple": { + "stage": "test", + "script": ["echo ${MY_VARIABLE}"], + "parallel": { + "matrix": [ + { + "MY_VARIABLE": 0 + }, + { + "MY_VARIABLE": "sample" + }, + { + "MY_VARIABLE": ["element0", 1, "element2"] + } + ] + } + }, + "parallel-matrix-gitlab-docs": { + "stage": "deploy", + "script": ["bin/deploy"], + "parallel": { + "matrix": [ + { + "PROVIDER": "aws", + "STACK": ["app1", "app2"] + }, + { + "PROVIDER": "ovh", + "STACK": ["monitoring", "backup", "app"] + }, + { + "PROVIDER": ["gcp", "vultr"], + "STACK": ["data", "processing"] + } + ] + } + } +} diff --git a/spec/frontend/editor/schema/ci/json_tests/positive_tests/inherit.json b/spec/frontend/editor/schema/ci/json_tests/positive_tests/inherit.json new file mode 100644 index 00000000000..3f72afa6ceb --- /dev/null +++ b/spec/frontend/editor/schema/ci/json_tests/positive_tests/inherit.json @@ -0,0 +1,54 @@ +{ + "default": { + "image": "ruby:2.4", + "before_script": ["echo Hello World"] + }, + "variables": { + "DOMAIN": "example.com", + "WEBHOOK_URL": "https://my-webhook.example.com" + }, + "rubocop": { + "inherit": { + "default": false, + "variables": false + }, + "script": "bundle exec rubocop" + }, + "rspec": { + "inherit": { + "default": ["image"], + "variables": ["WEBHOOK_URL"] + }, + "script": "bundle exec rspec" + }, + "capybara": { + "inherit": { + "variables": false + }, + "script": "bundle exec capybara" + }, + "karma": { + "inherit": { + "default": true, + "variables": ["DOMAIN"] + }, + "script": "karma" + }, + "inherit literally all": { + "inherit": { + "default": [ + "after_script", + "artifacts", + "before_script", + "cache", + "image", + "interruptible", + "retry", + "services", + "tags", + "timeout" + ] + }, + "script": "true" + } +} diff --git a/spec/frontend/editor/schema/ci/json_tests/positive_tests/multiple-caches.json b/spec/frontend/editor/schema/ci/json_tests/positive_tests/multiple-caches.json new file mode 100644 index 00000000000..360938e5ce7 --- /dev/null +++ b/spec/frontend/editor/schema/ci/json_tests/positive_tests/multiple-caches.json @@ -0,0 +1,24 @@ +{ + "test-job": { + "stage": "build", + "cache": [ + { + "key": { + "files": ["Gemfile.lock"] + }, + "paths": ["vendor/ruby"] + }, + { + "key": { + "files": ["yarn.lock"] + }, + "paths": [".yarn-cache/"] + } + ], + "script": [ + "bundle install --path=vendor", + "yarn install --cache-folder .yarn-cache", + "echo Run tests..." + ] + } +} diff --git a/spec/frontend/editor/schema/ci/json_tests/positive_tests/retry.json b/spec/frontend/editor/schema/ci/json_tests/positive_tests/retry.json new file mode 100644 index 00000000000..1337e5e7bc8 --- /dev/null +++ b/spec/frontend/editor/schema/ci/json_tests/positive_tests/retry.json @@ -0,0 +1,60 @@ +{ + "gitlab-ci-retry-int": { + "stage": "test", + "script": "rspec", + "retry": 2 + }, + "gitlab-ci-retry-object-no-max": { + "stage": "test", + "script": "rspec", + "retry": { + "when": "runner_system_failure" + } + }, + "gitlab-ci-retry-object-single-when": { + "stage": "test", + "script": "rspec", + "retry": { + "max": 2, + "when": "runner_system_failure" + } + }, + "gitlab-ci-retry-object-multiple-when": { + "stage": "test", + "script": "rspec", + "retry": { + "max": 2, + "when": ["runner_system_failure", "stuck_or_timeout_failure"] + } + }, + "gitlab-ci-retry-object-multiple-when-dupes": { + "stage": "test", + "script": "rspec", + "retry": { + "max": 2, + "when": ["runner_system_failure", "runner_system_failure"] + } + }, + "gitlab-ci-retry-object-all-when": { + "stage": "test", + "script": "rspec", + "retry": { + "max": 2, + "when": [ + "always", + "unknown_failure", + "script_failure", + "api_failure", + "stuck_or_timeout_failure", + "runner_system_failure", + "runner_unsupported", + "stale_schedule", + "job_execution_timeout", + "archived_failure", + "unmet_prerequisites", + "scheduler_failure", + "data_integrity_failure" + ] + } + } +} diff --git a/spec/frontend/editor/schema/ci/json_tests/positive_tests/terraform_report.json b/spec/frontend/editor/schema/ci/json_tests/positive_tests/terraform_report.json new file mode 100644 index 00000000000..0e444a4ba62 --- /dev/null +++ b/spec/frontend/editor/schema/ci/json_tests/positive_tests/terraform_report.json @@ -0,0 +1,50 @@ +{ + "image": { + "name": "registry.gitlab.com/gitlab-org/gitlab-build-images:terraform", + "entrypoint": [ + "/usr/bin/env", + "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" + ] + }, + "variables": { + "PLAN": "plan.tfplan", + "JSON_PLAN_FILE": "tfplan.json" + }, + "cache": { + "paths": [".terraform"] + }, + "before_script": [ + "alias convert_report=\"jq -r '([.resource_changes[]?.change.actions?]|flatten)|{\"create\":(map(select(.==\"create\"))|length),\"update\":(map(select(.==\"update\"))|length),\"delete\":(map(select(.==\"delete\"))|length)}'\"", + "terraform --version", + "terraform init" + ], + "stages": ["validate", "build", "test", "deploy"], + "validate": { + "stage": "validate", + "script": ["terraform validate"] + }, + "plan": { + "stage": "build", + "script": [ + "terraform plan -out=$PLAN", + "terraform show --json $PLAN | convert_report > $JSON_PLAN_FILE" + ], + "artifacts": { + "name": "plan", + "paths": ["$PLAN"], + "reports": { + "terraform": "$JSON_PLAN_FILE" + } + } + }, + "apply": { + "stage": "deploy", + "environment": { + "name": "production" + }, + "script": ["terraform apply -input=false $PLAN"], + "dependencies": ["plan"], + "when": "manual", + "only": ["master"] + } +} diff --git a/spec/frontend/editor/schema/ci/json_tests/positive_tests/variables.json b/spec/frontend/editor/schema/ci/json_tests/positive_tests/variables.json new file mode 100644 index 00000000000..ce59b3fbbec --- /dev/null +++ b/spec/frontend/editor/schema/ci/json_tests/positive_tests/variables.json @@ -0,0 +1,22 @@ +{ + "variables": { + "DEPLOY_ENVIRONMENT": { + "value": "staging", + "description": "The deployment target. Change this variable to 'canary' or 'production' if needed." + } + }, + "gitlab-ci-variables-string": { + "stage": "test", + "script": ["true"], + "variables": { + "TEST_VAR": "String variable" + } + }, + "gitlab-ci-variables-integer": { + "stage": "test", + "script": ["true"], + "variables": { + "canonical": 685230 + } + } +} diff --git a/spec/frontend/editor/schema/ci/json_tests/positive_tests/variables_mix_string_and_user_input.json b/spec/frontend/editor/schema/ci/json_tests/positive_tests/variables_mix_string_and_user_input.json new file mode 100644 index 00000000000..87a9ec05b57 --- /dev/null +++ b/spec/frontend/editor/schema/ci/json_tests/positive_tests/variables_mix_string_and_user_input.json @@ -0,0 +1,10 @@ +{ + "variables": { + "SOME_STR": "--batch-mode --errors --fail-at-end --show-version", + "SOME_INT": 10, + "SOME_USER_INPUT_FLAG": { + "value": "flag value", + "description": "Some Flag!" + } + } +} diff --git a/spec/frontend/editor/schema/ci/yaml_tests/negative_tests/cache.yml b/spec/frontend/editor/schema/ci/yaml_tests/negative_tests/cache.yml new file mode 100644 index 00000000000..ee533f54d3b --- /dev/null +++ b/spec/frontend/editor/schema/ci/yaml_tests/negative_tests/cache.yml @@ -0,0 +1,15 @@ +# Covers https://gitlab.com/gitlab-org/gitlab/-/merge_requests/70779 +stages: + - prepare + +# invalid cache:when value +job1: + stage: prepare + cache: + when: 0 + +# invalid cache:when value +job2: + stage: prepare + cache: + when: 'never' diff --git a/spec/frontend/editor/schema/ci/yaml_tests/negative_tests/include.yml b/spec/frontend/editor/schema/ci/yaml_tests/negative_tests/include.yml new file mode 100644 index 00000000000..287150a765f --- /dev/null +++ b/spec/frontend/editor/schema/ci/yaml_tests/negative_tests/include.yml @@ -0,0 +1,17 @@ +# Covers https://gitlab.com/gitlab-org/gitlab/-/merge_requests/70779 +stages: + - prepare + +# missing file property +childPipeline: + stage: prepare + trigger: + include: + - project: 'my-group/my-pipeline-library' + +# missing project property +childPipeline2: + stage: prepare + trigger: + include: + - file: '.gitlab-ci.yml' diff --git a/spec/frontend/editor/schema/ci/yaml_tests/positive_tests/cache.yml b/spec/frontend/editor/schema/ci/yaml_tests/positive_tests/cache.yml new file mode 100644 index 00000000000..436c7d72699 --- /dev/null +++ b/spec/frontend/editor/schema/ci/yaml_tests/positive_tests/cache.yml @@ -0,0 +1,25 @@ +# Covers https://gitlab.com/gitlab-org/gitlab/-/merge_requests/70779 +stages: + - prepare + +# test for cache:when values +job1: + stage: prepare + script: + - echo 'running job' + cache: + when: 'on_success' + +job2: + stage: prepare + script: + - echo 'running job' + cache: + when: 'on_failure' + +job3: + stage: prepare + script: + - echo 'running job' + cache: + when: 'always' diff --git a/spec/frontend/editor/schema/ci/yaml_tests/positive_tests/filter.yml b/spec/frontend/editor/schema/ci/yaml_tests/positive_tests/filter.yml new file mode 100644 index 00000000000..2b29c24fa3c --- /dev/null +++ b/spec/frontend/editor/schema/ci/yaml_tests/positive_tests/filter.yml @@ -0,0 +1,18 @@ +# Covers https://gitlab.com/gitlab-org/gitlab/-/merge_requests/79335 +deploy-template: + script: + - echo "hello world" + only: + - foo + except: + - bar + +# null value allowed +deploy-without-only: + extends: deploy-template + only: + +# null value allowed +deploy-without-except: + extends: deploy-template + except: diff --git a/spec/frontend/editor/schema/ci/yaml_tests/positive_tests/include.yml b/spec/frontend/editor/schema/ci/yaml_tests/positive_tests/include.yml new file mode 100644 index 00000000000..3497be28058 --- /dev/null +++ b/spec/frontend/editor/schema/ci/yaml_tests/positive_tests/include.yml @@ -0,0 +1,32 @@ +# Covers https://gitlab.com/gitlab-org/gitlab/-/merge_requests/70779 + +# test for include:rules +include: + - local: builds.yml + rules: + - if: '$INCLUDE_BUILDS == "true"' + when: always + +stages: + - prepare + +# test for trigger:include +childPipeline: + stage: prepare + script: + - echo 'creating pipeline...' + trigger: + include: + - project: 'my-group/my-pipeline-library' + file: '.gitlab-ci.yml' + +# accepts optional ref property +childPipeline2: + stage: prepare + script: + - echo 'creating pipeline...' + trigger: + include: + - project: 'my-group/my-pipeline-library' + file: '.gitlab-ci.yml' + ref: 'main' diff --git a/spec/frontend/editor/schema/ci/yaml_tests/positive_tests/rules.yml b/spec/frontend/editor/schema/ci/yaml_tests/positive_tests/rules.yml new file mode 100644 index 00000000000..27a199cff13 --- /dev/null +++ b/spec/frontend/editor/schema/ci/yaml_tests/positive_tests/rules.yml @@ -0,0 +1,13 @@ +# Covers https://gitlab.com/gitlab-org/gitlab/-/merge_requests/74164 + +# test for workflow:rules:changes and workflow:rules:exists +workflow: + rules: + - if: '$CI_PIPELINE_SOURCE == "schedule"' + exists: + - Dockerfile + changes: + - Dockerfile + variables: + IS_A_FEATURE: 'true' + when: always diff --git a/spec/lib/backup/manager_spec.rb b/spec/lib/backup/manager_spec.rb index ac169927978..04045c00981 100644 --- a/spec/lib/backup/manager_spec.rb +++ b/spec/lib/backup/manager_spec.rb @@ -228,6 +228,20 @@ RSpec.describe Backup::Manager do end end + context 'when SKIP env is set' do + let(:expected_backup_contents) { %w{backup_information.yml task1.tar.gz} } + + before do + stub_env('SKIP', 'task2') + end + + it 'executes tar' do + subject.create # rubocop:disable Rails/SaveBang + + expect(Kernel).to have_received(:system).with(*tar_cmdline) + end + end + context 'when the destination is optional' do let(:expected_backup_contents) { %w{backup_information.yml task1.tar.gz} } let(:definitions) do diff --git a/spec/services/import/github_service_spec.rb b/spec/services/import/github_service_spec.rb index 04a94d96f67..58afae1e647 100644 --- a/spec/services/import/github_service_spec.rb +++ b/spec/services/import/github_service_spec.rb @@ -34,11 +34,11 @@ RSpec.describe Import::GithubService do subject.execute(access_params, :github) end - it 'returns an error' do + it 'returns an error with message and code' do result = subject.execute(access_params, :github) expect(result).to include( - message: 'Import failed due to a GitHub error: Not Found', + message: 'Import failed due to a GitHub error: Not Found (HTTP 404)', status: :error, http_status: :unprocessable_entity ) diff --git a/yarn.lock b/yarn.lock index 9a1ed097f38..239cdab6692 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2516,10 +2516,10 @@ ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.3, ajv@^6.12.4, ajv@^6.12.5: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ajv@^8.0.0, ajv@^8.0.1, ajv@^8.8.0: - version "8.9.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.9.0.tgz#738019146638824dea25edcf299dcba1b0e7eb18" - integrity sha512-qOKJyNj/h+OWx7s5DePL6Zu1KeM9jPZhwBqs+7DzP6bGOvqzVCSf0xueYmVuaC/oQ/VtS2zLMLHdQFbkka+XDQ== +ajv@^8.0.0, ajv@^8.0.1, ajv@^8.10.0, ajv@^8.8.0: + version "8.10.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.10.0.tgz#e573f719bd3af069017e3b66538ab968d040e54d" + integrity sha512-bzqAEZOjkrUMl2afH8dknrq5KEk2SrwdBROR+vH1EKVQTqaUbJVPdc/gEdggTMM0Se+s+Ja4ju4TlNcStKl2Hw== dependencies: fast-deep-equal "^3.1.1" json-schema-traverse "^1.0.0"