diff --git a/.gitlab/ci/cng.gitlab-ci.yml b/.gitlab/ci/cng.gitlab-ci.yml index bf439288be2..d720ec5ae45 100644 --- a/.gitlab/ci/cng.gitlab-ci.yml +++ b/.gitlab/ci/cng.gitlab-ci.yml @@ -1,10 +1,51 @@ +cloud-native-image-env: + extends: + - .default-retry + - .cng:rules + image: ${GITLAB_DEPENDENCY_PROXY}ruby:2.7-alpine3.13 + stage: post-test + before_script: + - source ./scripts/utils.sh + - install_gitlab_gem + script: + - 'ruby -r./scripts/trigger-build.rb -e "puts Trigger.variables_for_env_file(Trigger::CNG.new.variables)" > build.env' + - cat build.env + artifacts: + reports: + dotenv: build.env + paths: + - build.env + expire_in: 7 days + when: always + cloud-native-image: extends: .cng:rules - image: ${GITLAB_DEPENDENCY_PROXY}ruby:2.7-alpine - dependencies: [] stage: post-test + needs: ["cloud-native-image-env"] + inherit: + variables: false variables: - GIT_DEPTH: "1" - script: - - install_gitlab_gem - - ./scripts/trigger-build cng + TOP_UPSTREAM_SOURCE_PROJECT: "${TOP_UPSTREAM_SOURCE_PROJECT}" + TOP_UPSTREAM_SOURCE_REF: "${TOP_UPSTREAM_SOURCE_REF}" + TOP_UPSTREAM_SOURCE_JOB: "${TOP_UPSTREAM_SOURCE_JOB}" + TOP_UPSTREAM_SOURCE_SHA: "${TOP_UPSTREAM_SOURCE_SHA}" + TOP_UPSTREAM_MERGE_REQUEST_PROJECT_ID: "${TOP_UPSTREAM_MERGE_REQUEST_PROJECT_ID}" + TOP_UPSTREAM_MERGE_REQUEST_IID: "${TOP_UPSTREAM_MERGE_REQUEST_IID}" + GITLAB_REF_SLUG: "${GITLAB_REF_SLUG}" + # CNG pipeline specific variables + GITLAB_VERSION: "${GITLAB_VERSION}" + GITLAB_TAG: "${GITLAB_TAG}" + GITLAB_ASSETS_TAG: "${GITLAB_ASSETS_TAG}" + FORCE_RAILS_IMAGE_BUILDS: "${FORCE_RAILS_IMAGE_BUILDS}" + CE_PIPELINE: "${CE_PIPELINE}" # Based on https://docs.gitlab.com/ee/ci/jobs/job_control.html#check-if-a-variable-exists, `if: '$CE_PIPELINE'` will evaluate to `false` when this variable is empty + EE_PIPELINE: "${EE_PIPELINE}" # Based on https://docs.gitlab.com/ee/ci/jobs/job_control.html#check-if-a-variable-exists, `if: '$EE_PIPELINE'` will evaluate to `false` when this variable is empty + GITLAB_SHELL_VERSION: "${GITLAB_SHELL_VERSION}" + GITLAB_ELASTICSEARCH_INDEXER_VERSION: "${GITLAB_ELASTICSEARCH_INDEXER_VERSION}" + GITLAB_KAS_VERSION: "${GITLAB_KAS_VERSION}" + GITLAB_WORKHORSE_VERSION: "${GITLAB_WORKHORSE_VERSION}" + GITLAB_PAGES_VERSION: "${GITLAB_PAGES_VERSION}" + GITALY_SERVER_VERSION: "${GITALY_SERVER_VERSION}" + trigger: + project: gitlab-org/build/CNG + branch: $TRIGGER_BRANCH + strategy: depend diff --git a/.gitlab/ci/docs.gitlab-ci.yml b/.gitlab/ci/docs.gitlab-ci.yml index 796dd261824..8b7691045cb 100644 --- a/.gitlab/ci/docs.gitlab-ci.yml +++ b/.gitlab/ci/docs.gitlab-ci.yml @@ -28,7 +28,7 @@ review-docs-deploy: extends: .review-docs script: - - ./scripts/trigger-build docs deploy + - ./scripts/trigger-build.rb docs deploy # Cleanup remote environment of gitlab-docs review-docs-cleanup: @@ -37,7 +37,7 @@ review-docs-cleanup: name: review-docs/mr-${CI_MERGE_REQUEST_IID} action: stop script: - - ./scripts/trigger-build docs cleanup + - ./scripts/trigger-build.rb docs cleanup docs-lint markdown: extends: diff --git a/.gitlab/ci/qa.gitlab-ci.yml b/.gitlab/ci/qa.gitlab-ci.yml index b12f76f2823..77d12a3e848 100644 --- a/.gitlab/ci/qa.gitlab-ci.yml +++ b/.gitlab/ci/qa.gitlab-ci.yml @@ -73,7 +73,7 @@ update-qa-cache: - echo $exit_code - | if [ $exit_code -eq 0 ]; then - ./scripts/trigger-build omnibus + ./scripts/trigger-build.rb omnibus elif [ $exit_code -eq 1 ]; then exit 1 else @@ -108,7 +108,7 @@ update-qa-cache: if [[ $feature_flags ]]; then export GITLAB_QA_OPTIONS="--set-feature-flags $feature_flags" echo $GITLAB_QA_OPTIONS - ./scripts/trigger-build omnibus + ./scripts/trigger-build.rb omnibus else echo "No changed feature flag found to test. The tests are skipped if the flag was removed." fi diff --git a/.gitlab/ci/rails.gitlab-ci.yml b/.gitlab/ci/rails.gitlab-ci.yml index 702bba8ae97..2ae81dbb5ba 100644 --- a/.gitlab/ci/rails.gitlab-ci.yml +++ b/.gitlab/ci/rails.gitlab-ci.yml @@ -438,7 +438,7 @@ db:gitlabcom-database-testing: script: - source scripts/utils.sh - install_gitlab_gem - - ./scripts/trigger-build gitlab-com-database-testing + - ./scripts/trigger-build.rb gitlab-com-database-testing gitlab:setup: extends: .db-job-base diff --git a/.gitlab/ci/review-apps/main.gitlab-ci.yml b/.gitlab/ci/review-apps/main.gitlab-ci.yml index 16ef3c82cda..d083f876b03 100644 --- a/.gitlab/ci/review-apps/main.gitlab-ci.yml +++ b/.gitlab/ci/review-apps/main.gitlab-ci.yml @@ -16,20 +16,58 @@ include: - source ./scripts/review_apps/review-apps.sh - install_api_client_dependencies_with_apk -review-build-cng: +review-build-cng-env: extends: - .default-retry - .review:rules:review-build-cng image: ${GITLAB_DEPENDENCY_PROXY}ruby:2.7-alpine3.13 stage: prepare - variables: - CNG_PROJECT_ACCESS_TOKEN: "${CNG_MIRROR_PROJECT_ACCESS_TOKEN}" # "Multi-pipeline (from 'gitlab-org/gitlab' 'review-build-cng' job)" at https://gitlab.com/gitlab-org/build/CNG-mirror/-/settings/access_tokens - CNG_PROJECT_PATH: "gitlab-org/build/CNG-mirror" + needs: [] before_script: - source ./scripts/utils.sh - install_gitlab_gem script: - - ./scripts/trigger-build cng + - 'ruby -r./scripts/trigger-build.rb -e "puts Trigger.variables_for_env_file(Trigger::CNG.new.variables)" > build.env' + - cat build.env + artifacts: + reports: + dotenv: build.env + paths: + - build.env + expire_in: 7 days + when: always + +review-build-cng: + extends: .review:rules:review-build-cng + stage: prepare + needs: ["review-build-cng-env"] + inherit: + variables: false + variables: + TOP_UPSTREAM_SOURCE_PROJECT: "${TOP_UPSTREAM_SOURCE_PROJECT}" + TOP_UPSTREAM_SOURCE_REF: "${TOP_UPSTREAM_SOURCE_REF}" + TOP_UPSTREAM_SOURCE_JOB: "${TOP_UPSTREAM_SOURCE_JOB}" + TOP_UPSTREAM_SOURCE_SHA: "${TOP_UPSTREAM_SOURCE_SHA}" + TOP_UPSTREAM_MERGE_REQUEST_PROJECT_ID: "${TOP_UPSTREAM_MERGE_REQUEST_PROJECT_ID}" + TOP_UPSTREAM_MERGE_REQUEST_IID: "${TOP_UPSTREAM_MERGE_REQUEST_IID}" + GITLAB_REF_SLUG: "${GITLAB_REF_SLUG}" + # CNG pipeline specific variables + GITLAB_VERSION: "${GITLAB_VERSION}" + GITLAB_TAG: "${GITLAB_TAG}" + GITLAB_ASSETS_TAG: "${GITLAB_ASSETS_TAG}" + FORCE_RAILS_IMAGE_BUILDS: "${FORCE_RAILS_IMAGE_BUILDS}" + CE_PIPELINE: "${CE_PIPELINE}" # Based on https://docs.gitlab.com/ee/ci/jobs/job_control.html#check-if-a-variable-exists, `if: '$CE_PIPELINE'` will evaluate to `false` when this variable is empty + EE_PIPELINE: "${EE_PIPELINE}" # Based on https://docs.gitlab.com/ee/ci/jobs/job_control.html#check-if-a-variable-exists, `if: '$EE_PIPELINE'` will evaluate to `false` when this variable is empty + GITLAB_SHELL_VERSION: "${GITLAB_SHELL_VERSION}" + GITLAB_ELASTICSEARCH_INDEXER_VERSION: "${GITLAB_ELASTICSEARCH_INDEXER_VERSION}" + GITLAB_KAS_VERSION: "${GITLAB_KAS_VERSION}" + GITLAB_WORKHORSE_VERSION: "${GITLAB_WORKHORSE_VERSION}" + GITLAB_PAGES_VERSION: "${GITLAB_PAGES_VERSION}" + GITALY_SERVER_VERSION: "${GITALY_SERVER_VERSION}" + trigger: + project: gitlab-org/build/CNG-mirror + branch: $TRIGGER_BRANCH + strategy: depend .review-workflow-base: extends: diff --git a/.gitlab/ci/rules.gitlab-ci.yml b/.gitlab/ci/rules.gitlab-ci.yml index 3e23f5f8bd7..2f1dbfce860 100644 --- a/.gitlab/ci/rules.gitlab-ci.yml +++ b/.gitlab/ci/rules.gitlab-ci.yml @@ -141,7 +141,7 @@ - ".gitlab/ci/review-apps/**/*" - "scripts/review_apps/base-config.yaml" - "scripts/review_apps/review-apps.sh" - - "scripts/trigger-build" + - "scripts/trigger-build.rb" - "{,ee/,jh/}{bin,config}/**/*.rb" .ci-qa-patterns: &ci-qa-patterns diff --git a/.rubocop_todo/database/multiple_databases.yml b/.rubocop_todo/database/multiple_databases.yml index 3e48215fd5c..69bc0b64a30 100644 --- a/.rubocop_todo/database/multiple_databases.yml +++ b/.rubocop_todo/database/multiple_databases.yml @@ -24,7 +24,6 @@ Database/MultipleDatabases: - lib/gitlab/import_export/group/relation_tree_restorer.rb - lib/gitlab/legacy_github_import/importer.rb - lib/gitlab/seeder.rb - - lib/system_check/orphans/repository_check.rb - spec/db/schema_spec.rb - spec/initializers/database_config_spec.rb - spec/lib/backup/manager_spec.rb diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c2b44662f6..8bd24e50e14 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,17 @@ documentation](doc/development/changelog.md) for instructions on adding your own entry. +## 14.7.3 (2022-02-15) + +### Fixed (2 changes) + +- [Update GitHub PRs Importer to force update repository](gitlab-org/gitlab@33f12736b070362cb89e9bbb4b3aa7d86fc373c3) ([merge request](gitlab-org/gitlab!80595)) +- [Fix Geo checksummable check failing when file is nil](gitlab-org/gitlab@f49e3ea3e4d4ca7a64607687f9aaa974801b6bf9) ([merge request](gitlab-org/gitlab!80595)) **GitLab Enterprise Edition** + +### Changed (1 change) + +- [Properly exclude pending_destruction packages when creating one](gitlab-org/gitlab@9fb9f1ca8a2342225b7017c211f85175a4ef56dd) ([merge request](gitlab-org/gitlab!80595)) + ## 14.7.2 (2022-02-08) ### Added (1 change) diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION index 55bda4ed23a..fd29e16738c 100644 --- a/GITALY_SERVER_VERSION +++ b/GITALY_SERVER_VERSION @@ -1 +1 @@ -d3ab199f7923a9d75516b8d1f1ea2f84b03190b1 +a67a6fdd96ba690d57c919f9a042dceebab2832e diff --git a/app/assets/javascripts/lib/graphql.js b/app/assets/javascripts/lib/graphql.js index 0fb7bf52562..f533ba3671c 100644 --- a/app/assets/javascripts/lib/graphql.js +++ b/app/assets/javascripts/lib/graphql.js @@ -44,6 +44,9 @@ export const typePolicies = { PipelinePermissions: { merge: true, }, + DesignCollection: { + merge: true, + }, }; export const stripWhitespaceFromQuery = (url, path) => { diff --git a/app/assets/javascripts/runner/components/runner_list.vue b/app/assets/javascripts/runner/components/runner_list.vue index 50fb8d36992..bb36882d3ae 100644 --- a/app/assets/javascripts/runner/components/runner_list.vue +++ b/app/assets/javascripts/runner/components/runner_list.vue @@ -2,31 +2,14 @@ import { GlTable, GlTooltipDirective, GlSkeletonLoader } from '@gitlab/ui'; import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate/tooltip_on_truncate.vue'; import { getIdFromGraphQLId } from '~/graphql_shared/utils'; -import { formatNumber, __, s__ } from '~/locale'; +import { __, s__ } from '~/locale'; import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue'; -import { RUNNER_JOB_COUNT_LIMIT } from '../constants'; +import { formatJobCount, tableField } from '../utils'; import RunnerActionsCell from './cells/runner_actions_cell.vue'; import RunnerSummaryCell from './cells/runner_summary_cell.vue'; import RunnerStatusCell from './cells/runner_status_cell.vue'; import RunnerTags from './runner_tags.vue'; -const tableField = ({ key, label = '', thClasses = [] }) => { - return { - key, - label, - thClass: [ - 'gl-bg-transparent!', - 'gl-border-b-solid!', - 'gl-border-b-gray-100!', - 'gl-border-b-1!', - ...thClasses, - ], - tdAttr: { - 'data-testid': `td-${key}`, - }, - }; -}; - export default { components: { GlTable, @@ -54,10 +37,7 @@ export default { }, methods: { formatJobCount(jobCount) { - if (jobCount > RUNNER_JOB_COUNT_LIMIT) { - return `${formatNumber(RUNNER_JOB_COUNT_LIMIT)}+`; - } - return formatNumber(jobCount); + return formatJobCount(jobCount); }, runnerTrAttr(runner) { if (runner) { diff --git a/app/assets/javascripts/runner/components/runner_projects.vue b/app/assets/javascripts/runner/components/runner_projects.vue index 2063404eb64..c4065a24ff2 100644 --- a/app/assets/javascripts/runner/components/runner_projects.vue +++ b/app/assets/javascripts/runner/components/runner_projects.vue @@ -9,6 +9,7 @@ import { I18N_FETCH_ERROR, RUNNER_DETAILS_PROJECTS_PAGE_SIZE, } from '../constants'; +import { getPaginationVariables } from '../utils'; import { captureException } from '../sentry_utils'; import RunnerAssignedItem from './runner_assigned_item.vue'; import RunnerPagination from './runner_pagination.vue'; @@ -62,19 +63,9 @@ export default { computed: { variables() { const { id } = this.runner; - const { before, after } = this.pagination; - - if (before) { - return { - id, - before, - last: RUNNER_DETAILS_PROJECTS_PAGE_SIZE, - }; - } return { id, - after, - first: RUNNER_DETAILS_PROJECTS_PAGE_SIZE, + ...getPaginationVariables(this.pagination, RUNNER_DETAILS_PROJECTS_PAGE_SIZE), }; }, loading() { diff --git a/app/assets/javascripts/runner/runner_search_utils.js b/app/assets/javascripts/runner/runner_search_utils.js index c80a73948b8..fe141332be3 100644 --- a/app/assets/javascripts/runner/runner_search_utils.js +++ b/app/assets/javascripts/runner/runner_search_utils.js @@ -18,6 +18,7 @@ import { RUNNER_PAGE_SIZE, STATUS_NEVER_CONTACTED, } from './constants'; +import { getPaginationVariables } from './utils'; /** * The filters and sorting of the runners are built around @@ -184,30 +185,27 @@ export const fromSearchToVariables = ({ sort = null, pagination = {}, } = {}) => { - const variables = {}; + const filterVariables = {}; const queryObj = filterToQueryObject(processFilters(filters), { filteredSearchTermKey: PARAM_KEY_SEARCH, }); - [variables.status] = queryObj[PARAM_KEY_STATUS] || []; - variables.search = queryObj[PARAM_KEY_SEARCH]; - variables.tagList = queryObj[PARAM_KEY_TAG]; + [filterVariables.status] = queryObj[PARAM_KEY_STATUS] || []; + filterVariables.search = queryObj[PARAM_KEY_SEARCH]; + filterVariables.tagList = queryObj[PARAM_KEY_TAG]; if (runnerType) { - variables.type = runnerType; + filterVariables.type = runnerType; } if (sort) { - variables.sort = sort; + filterVariables.sort = sort; } - if (pagination.before) { - variables.before = pagination.before; - variables.last = RUNNER_PAGE_SIZE; - } else { - variables.after = pagination.after; - variables.first = RUNNER_PAGE_SIZE; - } + const paginationVariables = getPaginationVariables(pagination, RUNNER_PAGE_SIZE); - return variables; + return { + ...filterVariables, + ...paginationVariables, + }; }; diff --git a/app/assets/javascripts/runner/utils.js b/app/assets/javascripts/runner/utils.js new file mode 100644 index 00000000000..6e4c8c45e7b --- /dev/null +++ b/app/assets/javascripts/runner/utils.js @@ -0,0 +1,72 @@ +import { formatNumber } from '~/locale'; +import { DEFAULT_TH_CLASSES } from '~/lib/utils/constants'; +import { RUNNER_JOB_COUNT_LIMIT } from './constants'; + +/** + * Formats a job count, limited to a max number + * + * @param {Number} jobCount + * @returns Formatted string + */ +export const formatJobCount = (jobCount) => { + if (typeof jobCount !== 'number') { + return ''; + } + if (jobCount > RUNNER_JOB_COUNT_LIMIT) { + return `${formatNumber(RUNNER_JOB_COUNT_LIMIT)}+`; + } + return formatNumber(jobCount); +}; + +/** + * Returns a GlTable fields with a given key and label + * + * @param {Object} options + * @returns Field object to add to GlTable fields + */ +export const tableField = ({ key, label = '', thClasses = [] }) => { + return { + key, + label, + thClass: [DEFAULT_TH_CLASSES, ...thClasses], + tdAttr: { + 'data-testid': `td-${key}`, + }, + }; +}; + +/** + * Returns variables for a GraphQL query that uses keyset + * pagination. + * + * https://docs.gitlab.com/ee/development/graphql_guide/pagination.html#keyset-pagination + * + * @param {Object} pagination - Contains before, after, page + * @param {Number} pageSize + * @returns Variables + */ +export const getPaginationVariables = (pagination, pageSize = 10) => { + const { before, after } = pagination; + + // first + after: Next page + // Get the first N items after item X + if (after) { + return { + after, + first: pageSize, + }; + } + + // last + before: Prev page + // Get the first N items before item X, when you click on Prev + if (before) { + return { + before, + last: pageSize, + }; + } + + // first page + // Get the first N items + return { first: pageSize }; +}; diff --git a/app/assets/javascripts/sidebar/components/sidebar_dropdown_widget.vue b/app/assets/javascripts/sidebar/components/sidebar_dropdown_widget.vue index 0de4cb2e59f..ec23e817127 100644 --- a/app/assets/javascripts/sidebar/components/sidebar_dropdown_widget.vue +++ b/app/assets/javascripts/sidebar/components/sidebar_dropdown_widget.vue @@ -10,6 +10,7 @@ import { GlIcon, GlTooltipDirective, } from '@gitlab/ui'; +import { kebabCase, snakeCase } from 'lodash'; import createFlash from '~/flash'; import { getIdFromGraphQLId } from '~/graphql_shared/utils'; import { IssuableType } from '~/issues/constants'; @@ -221,6 +222,12 @@ export default { // MV to EE https://gitlab.com/gitlab-org/gitlab/-/issues/345311 return this.issuableAttribute === IssuableType.Epic; }, + formatIssuableAttribute() { + return { + kebab: kebabCase(this.issuableAttribute), + snake: snakeCase(this.issuableAttribute), + }; + }, }, methods: { updateAttribute(attributeId) { @@ -300,26 +307,28 @@ export default {