Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
d03aeb1110
commit
1c635e68ea
33 changed files with 622 additions and 68 deletions
127
app/assets/javascripts/repository/components/code_owners.vue
Normal file
127
app/assets/javascripts/repository/components/code_owners.vue
Normal file
|
@ -0,0 +1,127 @@
|
|||
<script>
|
||||
import { GlIcon, GlLink } from '@gitlab/ui';
|
||||
import { __ } from '~/locale';
|
||||
import createFlash from '~/flash';
|
||||
import { helpPagePath } from '~/helpers/help_page_helper';
|
||||
import codeOwnersInfoQuery from '../queries/code_owners_info.query.graphql';
|
||||
import getRefMixin from '../mixins/get_ref';
|
||||
|
||||
export default {
|
||||
i18n: {
|
||||
title: __('Code owners'),
|
||||
about: __('About this feature'),
|
||||
andSeparator: __('and'),
|
||||
errorMessage: __('An error occurred while loading code owners.'),
|
||||
},
|
||||
codeOwnersHelpPath: helpPagePath('user/project/code_owners'),
|
||||
components: {
|
||||
GlIcon,
|
||||
GlLink,
|
||||
},
|
||||
mixins: [getRefMixin],
|
||||
apollo: {
|
||||
project: {
|
||||
query: codeOwnersInfoQuery,
|
||||
variables() {
|
||||
return {
|
||||
projectPath: this.projectPath,
|
||||
filePath: this.filePath,
|
||||
ref: this.ref,
|
||||
};
|
||||
},
|
||||
skip() {
|
||||
return !this.filePath;
|
||||
},
|
||||
result() {
|
||||
this.isFetching = false;
|
||||
},
|
||||
error() {
|
||||
createFlash({ message: this.$options.i18n.errorMessage });
|
||||
},
|
||||
},
|
||||
},
|
||||
props: {
|
||||
projectPath: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
filePath: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: null,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isFetching: false,
|
||||
project: {
|
||||
repository: {
|
||||
blobs: {
|
||||
nodes: [
|
||||
{
|
||||
codeOwners: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
blobInfo() {
|
||||
return this.project?.repository?.blobs?.nodes[0];
|
||||
},
|
||||
codeOwners() {
|
||||
return this.blobInfo?.codeOwners || [];
|
||||
},
|
||||
hasCodeOwners() {
|
||||
return this.filePath && Boolean(this.codeOwners.length);
|
||||
},
|
||||
commaSeparateList() {
|
||||
return this.codeOwners.length > 2;
|
||||
},
|
||||
showAndSeparator() {
|
||||
return this.codeOwners.length > 1;
|
||||
},
|
||||
lastListItem() {
|
||||
return this.codeOwners.length - 1;
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
filePath() {
|
||||
this.isFetching = true;
|
||||
this.$apollo.queries.project.refetch();
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
v-if="hasCodeOwners && !isFetching"
|
||||
class="well-segment blob-auxiliary-viewer file-owner-content qa-file-owner-content"
|
||||
>
|
||||
<gl-icon name="users" data-testid="users-icon" />
|
||||
<strong>{{ $options.i18n.title }}</strong>
|
||||
<gl-link :href="$options.codeOwnersHelpPath" target="_blank" :title="$options.i18n.about">
|
||||
<gl-icon name="question-o" data-testid="help-icon" />
|
||||
</gl-link>
|
||||
:
|
||||
<div
|
||||
v-for="(owner, index) in codeOwners"
|
||||
:key="index"
|
||||
:class="[
|
||||
{ 'gl-display-inline-block': commaSeparateList, 'gl-display-inline': !commaSeparateList },
|
||||
]"
|
||||
data-testid="code-owners"
|
||||
>
|
||||
<span v-if="commaSeparateList && index > 0" data-testid="comma-separator">,</span>
|
||||
<span v-if="showAndSeparator && index === lastListItem" data-testid="and-separator">{{
|
||||
$options.i18n.andSeparator
|
||||
}}</span>
|
||||
<gl-link :href="owner.webPath" target="_blank" :title="$options.i18n.about">
|
||||
{{ owner.name }}
|
||||
</gl-link>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
|
@ -111,7 +111,7 @@ export default {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div class="info-well d-none d-sm-flex project-last-commit commit p-3">
|
||||
<div class="well-segment commit gl-p-5 gl-w-full">
|
||||
<gl-loading-icon v-if="isLoading" size="md" color="dark" class="m-auto" />
|
||||
<template v-else-if="commit">
|
||||
<user-avatar-link
|
||||
|
|
|
@ -9,6 +9,7 @@ import App from './components/app.vue';
|
|||
import Breadcrumbs from './components/breadcrumbs.vue';
|
||||
import DirectoryDownloadLinks from './components/directory_download_links.vue';
|
||||
import LastCommit from './components/last_commit.vue';
|
||||
import CodeOwners from './components/code_owners.vue';
|
||||
import apolloProvider from './graphql';
|
||||
import commitsQuery from './queries/commits.query.graphql';
|
||||
import projectPathQuery from './queries/project_path.query.graphql';
|
||||
|
@ -71,7 +72,23 @@ export default function setupVueRepositoryList() {
|
|||
},
|
||||
});
|
||||
|
||||
const initCodeOwnersApp = () =>
|
||||
new Vue({
|
||||
el: document.getElementById('js-code-owners'),
|
||||
router,
|
||||
apolloProvider,
|
||||
render(h) {
|
||||
return h(CodeOwners, {
|
||||
props: {
|
||||
filePath: this.$route.params.path,
|
||||
projectPath,
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
initLastCommitApp();
|
||||
initCodeOwnersApp();
|
||||
|
||||
router.afterEach(({ params: { path } }) => {
|
||||
setTitle(path, ref, fullName);
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
query getCodeOwnersInfo($projectPath: ID!, $filePath: String!, $ref: String!) {
|
||||
project(fullPath: $projectPath) {
|
||||
id
|
||||
repository {
|
||||
blobs(paths: [$filePath], ref: $ref) {
|
||||
nodes {
|
||||
codeOwners {
|
||||
name
|
||||
webPath
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
<script>
|
||||
import { GlTable, GlTooltipDirective, GlSkeletonLoader } from '@gitlab/ui';
|
||||
import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate.vue';
|
||||
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
|
||||
import { __, s__ } from '~/locale';
|
||||
import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue';
|
||||
|
@ -32,6 +33,7 @@ export default {
|
|||
components: {
|
||||
GlTable,
|
||||
GlSkeletonLoader,
|
||||
TooltipOnTruncate,
|
||||
TimeAgo,
|
||||
RunnerActionsCell,
|
||||
RunnerSummaryCell,
|
||||
|
@ -101,11 +103,15 @@ export default {
|
|||
</template>
|
||||
|
||||
<template #cell(version)="{ item: { version } }">
|
||||
{{ version }}
|
||||
<tooltip-on-truncate class="gl-display-block gl-text-truncate" :title="version">
|
||||
{{ version }}
|
||||
</tooltip-on-truncate>
|
||||
</template>
|
||||
|
||||
<template #cell(ipAddress)="{ item: { ipAddress } }">
|
||||
{{ ipAddress }}
|
||||
<tooltip-on-truncate class="gl-display-block gl-text-truncate" :title="ipAddress">
|
||||
{{ ipAddress }}
|
||||
</tooltip-on-truncate>
|
||||
</template>
|
||||
|
||||
<template #cell(tagList)="{ item: { tagList } }">
|
||||
|
|
|
@ -104,16 +104,7 @@ export default {
|
|||
},
|
||||
},
|
||||
mounted() {
|
||||
this.fetchCollapsedData(this.$props)
|
||||
.then((data) => {
|
||||
this.collapsedData = data;
|
||||
this.loadingState = null;
|
||||
})
|
||||
.catch((e) => {
|
||||
this.loadingState = LOADING_STATES.collapsedError;
|
||||
|
||||
Sentry.captureException(e);
|
||||
});
|
||||
this.loadCollapsedData();
|
||||
},
|
||||
methods: {
|
||||
triggerRedisTracking: once(function triggerRedisTracking() {
|
||||
|
@ -126,6 +117,20 @@ export default {
|
|||
|
||||
this.triggerRedisTracking();
|
||||
},
|
||||
loadCollapsedData() {
|
||||
this.loadingState = LOADING_STATES.collapsedLoading;
|
||||
|
||||
this.fetchCollapsedData(this.$props)
|
||||
.then((data) => {
|
||||
this.collapsedData = data;
|
||||
this.loadingState = null;
|
||||
})
|
||||
.catch((e) => {
|
||||
this.loadingState = LOADING_STATES.collapsedError;
|
||||
|
||||
Sentry.captureException(e);
|
||||
});
|
||||
},
|
||||
loadAllData() {
|
||||
if (this.hasFullData) return;
|
||||
|
||||
|
|
|
@ -71,6 +71,10 @@ module Types
|
|||
field :pipeline_editor_path, GraphQL::Types::String, null: true,
|
||||
description: 'Web path to edit .gitlab-ci.yml file.'
|
||||
|
||||
field :code_owners, [Types::UserType], null: true,
|
||||
description: 'List of code owners for the blob.',
|
||||
calls_gitaly: true
|
||||
|
||||
field :file_type, GraphQL::Types::String, null: true,
|
||||
description: 'Expected format of the blob based on the extension.'
|
||||
|
||||
|
|
|
@ -20,13 +20,13 @@ module Packages
|
|||
belongs_to :component, class_name: "Packages::Debian::#{container_type.capitalize}Component", inverse_of: :files
|
||||
belongs_to :architecture, class_name: "Packages::Debian::#{container_type.capitalize}Architecture", inverse_of: :files, optional: true
|
||||
|
||||
enum file_type: { packages: 1, source: 2, di_packages: 3 }
|
||||
enum file_type: { packages: 1, sources: 2, di_packages: 3 }
|
||||
enum compression_type: { gz: 1, bz2: 2, xz: 3 }
|
||||
|
||||
validates :component, presence: true
|
||||
validates :file_type, presence: true
|
||||
validates :architecture, presence: true, unless: :source?
|
||||
validates :architecture, absence: true, if: :source?
|
||||
validates :architecture, presence: true, unless: :sources?
|
||||
validates :architecture, absence: true, if: :sources?
|
||||
validates :file, length: { minimum: 0, allow_nil: false }
|
||||
validates :size, presence: true
|
||||
validates :file_store, presence: true
|
||||
|
@ -81,7 +81,7 @@ module Packages
|
|||
case file_type
|
||||
when 'packages'
|
||||
"#{component.name}/binary-#{architecture.name}/#{file_name}#{extension}"
|
||||
when 'source'
|
||||
when 'sources'
|
||||
"#{component.name}/source/#{file_name}#{extension}"
|
||||
when 'di_packages'
|
||||
"#{component.name}/debian-installer/binary-#{architecture.name}/#{file_name}#{extension}"
|
||||
|
|
|
@ -66,6 +66,10 @@ class BlobPresenter < Gitlab::View::Presenter::Delegated
|
|||
project_ci_pipeline_editor_path(project, branch_name: blob.commit_id) if can_collaborate_with_project?(project) && blob.path == project.ci_config_path_or_default
|
||||
end
|
||||
|
||||
def code_owners
|
||||
Gitlab::CodeOwners.for_blob(project, blob)
|
||||
end
|
||||
|
||||
def fork_and_edit_path
|
||||
fork_path_for_current_user(project, edit_blob_path)
|
||||
end
|
||||
|
|
|
@ -91,7 +91,7 @@ module Packages
|
|||
generate_component_file(component, :packages, architecture, :deb)
|
||||
generate_component_file(component, :di_packages, architecture, :udeb)
|
||||
end
|
||||
generate_component_file(component, :source, nil, :dsc)
|
||||
generate_component_file(component, :sources, nil, :dsc)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -10,10 +10,11 @@
|
|||
.nav-block.gl-display-flex.gl-xs-flex-direction-column.gl-align-items-stretch
|
||||
= render 'projects/tree/tree_header', tree: @tree
|
||||
|
||||
#js-last-commit
|
||||
.info-well.gl-display-none.gl-sm-display-flex.project-last-commit
|
||||
.info-well.gl-display-none.gl-sm-display-flex.project-last-commit.gl-flex-direction-column
|
||||
#js-last-commit.gl-m-auto
|
||||
.gl-spinner-container.m-auto
|
||||
= loading_icon(size: 'md', color: 'dark', css_class: 'align-text-bottom')
|
||||
#js-code-owners
|
||||
|
||||
- if is_project_overview
|
||||
.project-buttons.gl-mb-3.js-show-on-project-root
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ChangeIndexUsersOnPublicEmail < Gitlab::Database::Migration[1.0]
|
||||
INDEX_NAME = 'index_users_on_public_email'
|
||||
INDEX_EXCLUDING_NULL_NAME = 'index_users_on_public_email_excluding_null_and_empty'
|
||||
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
index_condition = "public_email != '' AND public_email IS NOT NULL"
|
||||
|
||||
add_concurrent_index :users, [:public_email], where: index_condition, name: INDEX_EXCLUDING_NULL_NAME
|
||||
remove_concurrent_index_by_name :users, INDEX_NAME
|
||||
end
|
||||
|
||||
def down
|
||||
index_condition = "public_email != ''"
|
||||
|
||||
add_concurrent_index :users, [:public_email], where: index_condition, name: INDEX_NAME
|
||||
remove_concurrent_index_by_name :users, INDEX_EXCLUDING_NULL_NAME
|
||||
end
|
||||
end
|
1
db/schema_migrations/20211124132705
Normal file
1
db/schema_migrations/20211124132705
Normal file
|
@ -0,0 +1 @@
|
|||
4eacad00017890c71f3354d80061fae7af40499256475cdf035bdf41b916e5f3
|
|
@ -27534,7 +27534,7 @@ CREATE INDEX index_users_on_name ON users USING btree (name);
|
|||
|
||||
CREATE INDEX index_users_on_name_trigram ON users USING gin (name gin_trgm_ops);
|
||||
|
||||
CREATE INDEX index_users_on_public_email ON users USING btree (public_email) WHERE ((public_email)::text <> ''::text);
|
||||
CREATE INDEX index_users_on_public_email_excluding_null_and_empty ON users USING btree (public_email) WHERE (((public_email)::text <> ''::text) AND (public_email IS NOT NULL));
|
||||
|
||||
CREATE INDEX index_users_on_require_two_factor_authentication_from_group ON users USING btree (require_two_factor_authentication_from_group) WHERE (require_two_factor_authentication_from_group = true);
|
||||
|
||||
|
|
|
@ -14073,6 +14073,7 @@ Returns [`Tree`](#tree).
|
|||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="repositoryblobcanmodifyblob"></a>`canModifyBlob` | [`Boolean`](#boolean) | Whether the current user can modify the blob. |
|
||||
| <a id="repositoryblobcodeowners"></a>`codeOwners` | [`[UserCore!]`](#usercore) | List of code owners for the blob. |
|
||||
| <a id="repositoryblobeditblobpath"></a>`editBlobPath` | [`String`](#string) | Web path to edit the blob in the old-style editor. |
|
||||
| <a id="repositoryblobexternalstorageurl"></a>`externalStorageUrl` | [`String`](#string) | Web path to download the raw blob via external storage, if enabled. |
|
||||
| <a id="repositoryblobfiletype"></a>`fileType` | [`String`](#string) | Expected format of the blob based on the extension. |
|
||||
|
|
|
@ -109,6 +109,7 @@ GET /projects/:id/members/all
|
|||
| `id` | integer/string | yes | The ID or [URL-encoded path of the project or group](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `query` | string | no | A query string to search for members |
|
||||
| `user_ids` | array of integers | no | Filter the results on the given user IDs |
|
||||
| `state` | string | no | Filter results by member state, one of `awaiting`, `active` or `created` **(PREMIUM)** |
|
||||
|
||||
```shell
|
||||
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/:id/members/all"
|
||||
|
|
|
@ -294,7 +294,12 @@ POST /projects/:id/approval_rules
|
|||
| `rule_type` | string | no | The type of rule. `any_approver` is a pre-configured default rule with `approvals_required` at `0`. Other rules are `regular`.
|
||||
| `user_ids` | Array | no | The ids of users as approvers |
|
||||
| `group_ids` | Array | no | The ids of groups as approvers |
|
||||
| `protected_branch_ids` | Array | no | **(PREMIUM)** The ids of protected branches to scope the rule by. To identify the ID, [use the API](protected_branches.md#list-protected-branches). |
|
||||
| `protected_branch_ids` | Array | no | The IDs of protected branches to scope the rule by. To identify the ID, [use the API](protected_branches.md#list-protected-branches). |
|
||||
| `report_type` | string | no | The report type required when the rule type is `report_approver`. The supported report types are: `vulnerability`, `license_scanning`, `code_coverage`. |
|
||||
| `scanners` | Array | no | The security scanners the `Vulnerability-Check` approval rule considers. The supported scanners are: `sast`, `secret_detection`, `dependency_scanning`, `container_scanning`, `dast`, `coverage_fuzzing`, `api_fuzzing`. Defaults to all supported scanners. |
|
||||
| `severity_levels` | Array | no | The severity levels the `Vulnerability-Check` approval rule considers. The supported severity levels are: `info`, `unknown`, `low`, `medium`, `high`, `critical`. Defaults to `unknown`, `high`, and `critical`. |
|
||||
| `vulnerabilities_allowed` | integer | no | The number of vulnerabilities allowed for the `Vulnerability-Check` approval rule. Defaults to `0`. |
|
||||
| `vulnerability_states` | Array | no | The vulnerability states the `Vulnerability-Check` approval rule considers. The supported vulnerability states are: `newly_detected` (default), `detected`, `confirmed`, `resolved`, `dismissed`. |
|
||||
|
||||
```json
|
||||
{
|
||||
|
@ -417,7 +422,11 @@ PUT /projects/:id/approval_rules/:approval_rule_id
|
|||
| `approvals_required` | integer | yes | The number of required approvals for this rule |
|
||||
| `user_ids` | Array | no | The ids of users as approvers |
|
||||
| `group_ids` | Array | no | The ids of groups as approvers |
|
||||
| `protected_branch_ids` | Array | no | **(PREMIUM)** The ids of protected branches to scope the rule by. To identify the ID, [use the API](protected_branches.md#list-protected-branches). |
|
||||
| `protected_branch_ids` | Array | no | The IDs of protected branches to scope the rule by. To identify the ID, [use the API](protected_branches.md#list-protected-branches). |
|
||||
| `scanners` | Array | no | The security scanners the `Vulnerability-Check` approval rule considers. The supported scanners are: `sast`, `secret_detection`, `dependency_scanning`, `container_scanning`, `dast`, `coverage_fuzzing`, `api_fuzzing`. Defaults to all supported scanners. |
|
||||
| `severity_levels` | Array | no | The severity levels the `Vulnerability-Check` approval rule considers. The supported severity levels are: `info`, `unknown`, `low`, `medium`, `high`, `critical`. Defaults to `unknown`, `high`, and `critical`. |
|
||||
| `vulnerabilities_allowed` | integer | no | The number of vulnerabilities allowed for the `Vulnerability-Check` approval rule. Defaults to `0`. |
|
||||
| `vulnerability_states` | Array | no | The vulnerability states the `Vulnerability-Check` approval rule considers. The supported vulnerability states are: `newly_detected` (default), `detected`, `confirmed`, `resolved`, `dismissed`. |
|
||||
|
||||
```json
|
||||
{
|
||||
|
|
|
@ -465,7 +465,14 @@ If you regenerate 2FA recovery codes, save them. You can't use any previously cr
|
|||
|
||||
### Have 2FA disabled on your account
|
||||
|
||||
If you cannot use a saved recovery code or generate new recovery codes then please submit a [support ticket](https://support.gitlab.com/hc/en-us/requests/new) requesting that a GitLab global administrator disables two-factor authentication for your account. Please note that only the actual owner of the account can make this request and that disabling this setting will temporarily leave your account in a less secure state. You should therefore sign in and re-enable two-factor authentication as soon as possible.
|
||||
If you can't use a saved recovery code or generate new recovery codes, submit a [support ticket](https://support.gitlab.com/hc/en-us/requests/new) to
|
||||
request a GitLab global administrator disable two-factor authentication for your account. Note that:
|
||||
|
||||
- Only the owner of the account can make this request.
|
||||
- This service is only available for accounts that have a GitLab.com subscription. For more information, see our
|
||||
[blog post](https://about.gitlab.com/blog/2020/08/04/gitlab-support-no-longer-processing-mfa-resets-for-free-users/).
|
||||
- Disabling this setting temporarily leaves your account in a less secure state. You should sign in and re-enable two-factor authentication
|
||||
as soon as possible.
|
||||
|
||||
## Note to GitLab administrators
|
||||
|
||||
|
|
|
@ -8,6 +8,9 @@ module API
|
|||
params :optional_filter_params_ee do
|
||||
end
|
||||
|
||||
params :optional_state_filter_ee do
|
||||
end
|
||||
|
||||
def find_source(source_type, id)
|
||||
public_send("find_#{source_type}!", id) # rubocop:disable GitlabSecurity/PublicSend
|
||||
end
|
||||
|
|
|
@ -41,6 +41,7 @@ module API
|
|||
optional :query, type: String, desc: 'A query string to search for members'
|
||||
optional :user_ids, type: Array[Integer], coerce_with: ::API::Validations::Types::CommaSeparatedToIntegerArray.coerce, desc: 'Array of user ids to look up for membership'
|
||||
optional :show_seat_info, type: Boolean, desc: 'Show seat information for members'
|
||||
use :optional_state_filter_ee
|
||||
use :pagination
|
||||
end
|
||||
|
||||
|
|
|
@ -776,6 +776,9 @@ msgstr ""
|
|||
msgid "%{name} is already being used for another emoji"
|
||||
msgstr ""
|
||||
|
||||
msgid "%{name} is reserved for %{type} report type"
|
||||
msgstr ""
|
||||
|
||||
msgid "%{name} is scheduled for %{action}"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1014,6 +1017,9 @@ msgstr ""
|
|||
msgid "%{total} warnings found: showing first %{warningsDisplayed}"
|
||||
msgstr ""
|
||||
|
||||
msgid "%{type} only supports %{name} name"
|
||||
msgstr ""
|
||||
|
||||
msgid "%{userName} (cannot merge)"
|
||||
msgstr ""
|
||||
|
||||
|
@ -3746,6 +3752,9 @@ msgstr ""
|
|||
msgid "An error occurred while loading chart data"
|
||||
msgstr ""
|
||||
|
||||
msgid "An error occurred while loading code owners."
|
||||
msgstr ""
|
||||
|
||||
msgid "An error occurred while loading commit signatures"
|
||||
msgstr ""
|
||||
|
||||
|
@ -40600,9 +40609,6 @@ msgstr ""
|
|||
msgid "cannot be enabled until a valid credit card is on file"
|
||||
msgstr ""
|
||||
|
||||
msgid "cannot be modified"
|
||||
msgstr ""
|
||||
|
||||
msgid "cannot be used for user namespace"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ class JobFinder
|
|||
pipeline_query: {}.freeze,
|
||||
job_query: {}.freeze
|
||||
).freeze
|
||||
MAX_PIPELINES_TO_ITERATE = 200
|
||||
MAX_PIPELINES_TO_ITERATE = 20
|
||||
|
||||
def initialize(options)
|
||||
@project = options.delete(:project)
|
||||
|
@ -51,7 +51,7 @@ class JobFinder
|
|||
end
|
||||
end
|
||||
|
||||
raise 'Job not found!'
|
||||
warn 'Job not found!'
|
||||
end
|
||||
|
||||
def find_job_with_filtered_pipelines
|
||||
|
@ -63,7 +63,7 @@ class JobFinder
|
|||
end
|
||||
end
|
||||
|
||||
raise 'Job not found!'
|
||||
warn 'Job not found!'
|
||||
end
|
||||
|
||||
def find_job_in_pipeline
|
||||
|
@ -73,7 +73,7 @@ class JobFinder
|
|||
return job if found_job_by_name?(job) # rubocop:disable Cop/AvoidReturnFromBlocks
|
||||
end
|
||||
|
||||
raise 'Job not found!'
|
||||
warn 'Job not found!'
|
||||
end
|
||||
|
||||
def found_job_with_artifact?(job)
|
||||
|
@ -87,7 +87,7 @@ class JobFinder
|
|||
end
|
||||
|
||||
def pipeline_query_params
|
||||
@pipeline_query_params ||= { per_page: 100, **pipeline_query }
|
||||
@pipeline_query_params ||= { per_page: MAX_PIPELINES_TO_ITERATE, **pipeline_query }
|
||||
end
|
||||
|
||||
def job_query_params
|
||||
|
|
|
@ -108,12 +108,7 @@ function retrieve_frontend_fixtures_mapping() {
|
|||
local job_name="generate-frontend-fixtures-mapping"
|
||||
local test_metadata_with_mapping_job_id
|
||||
|
||||
# On the MR that introduces 'generate-frontend-fixtures-mapping', we cannot retrieve the file from a master scheduled pipeline, so we take it from a known MR pipeline
|
||||
if [[ "${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME}" == "339343-execute-related-jests-specs-for-mrs-with-backend-changes" ]]; then
|
||||
test_metadata_with_mapping_job_id=$(scripts/api/get_job_id.rb --endpoint "https://gitlab.com/api/v4" --project "${project_path}" --pipeline-id "414921396" -Q "scope=success" --job-name "${job_name}")
|
||||
else
|
||||
test_metadata_with_mapping_job_id=$(scripts/api/get_job_id.rb --endpoint "https://gitlab.com/api/v4" --project "${project_path}" -q "ref=${artifact_branch}" -q "username=${username}" -Q "scope=success" --job-name "${job_name}")
|
||||
fi
|
||||
test_metadata_with_mapping_job_id=$(scripts/api/get_job_id.rb --endpoint "https://gitlab.com/api/v4" --project "${project_path}" -q "ref=${artifact_branch}" -q "username=${username}" -Q "scope=success" --job-name "${job_name}")
|
||||
|
||||
if [[ $? -eq 0 ]] && [[ -n "${test_metadata_with_mapping_job_id}" ]]; then
|
||||
echo "test_metadata_with_mapping_job_id: ${test_metadata_with_mapping_job_id}"
|
||||
|
|
|
@ -27,8 +27,8 @@ FactoryBot.define do
|
|||
file_type { :packages }
|
||||
end
|
||||
|
||||
trait(:source) do
|
||||
file_type { :source }
|
||||
trait(:sources) do
|
||||
file_type { :sources }
|
||||
architecture { nil }
|
||||
end
|
||||
|
||||
|
|
|
@ -0,0 +1,220 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Code owners component matches the snapshot 1`] = `<!---->`;
|
||||
|
||||
exports[`Code owners component matches the snapshot 2`] = `
|
||||
<div
|
||||
class="well-segment blob-auxiliary-viewer file-owner-content qa-file-owner-content"
|
||||
>
|
||||
<gl-icon-stub
|
||||
data-testid="users-icon"
|
||||
name="users"
|
||||
size="16"
|
||||
/>
|
||||
|
||||
<strong>
|
||||
Code owners
|
||||
</strong>
|
||||
|
||||
<gl-link-stub
|
||||
href="/help/user/project/code_owners"
|
||||
target="_blank"
|
||||
title="About this feature"
|
||||
>
|
||||
<gl-icon-stub
|
||||
data-testid="help-icon"
|
||||
name="question-o"
|
||||
size="16"
|
||||
/>
|
||||
</gl-link-stub>
|
||||
|
||||
:
|
||||
|
||||
<div
|
||||
class="gl-display-inline"
|
||||
data-testid="code-owners"
|
||||
>
|
||||
<!---->
|
||||
|
||||
<!---->
|
||||
|
||||
<gl-link-stub
|
||||
href="path/to/@johnDoe"
|
||||
target="_blank"
|
||||
title="About this feature"
|
||||
>
|
||||
|
||||
John Doe
|
||||
|
||||
</gl-link-stub>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Code owners component matches the snapshot 3`] = `
|
||||
<div
|
||||
class="well-segment blob-auxiliary-viewer file-owner-content qa-file-owner-content"
|
||||
>
|
||||
<gl-icon-stub
|
||||
data-testid="users-icon"
|
||||
name="users"
|
||||
size="16"
|
||||
/>
|
||||
|
||||
<strong>
|
||||
Code owners
|
||||
</strong>
|
||||
|
||||
<gl-link-stub
|
||||
href="/help/user/project/code_owners"
|
||||
target="_blank"
|
||||
title="About this feature"
|
||||
>
|
||||
<gl-icon-stub
|
||||
data-testid="help-icon"
|
||||
name="question-o"
|
||||
size="16"
|
||||
/>
|
||||
</gl-link-stub>
|
||||
|
||||
:
|
||||
|
||||
<div
|
||||
class="gl-display-inline"
|
||||
data-testid="code-owners"
|
||||
>
|
||||
<!---->
|
||||
|
||||
<!---->
|
||||
|
||||
<gl-link-stub
|
||||
href="path/to/@johnDoe"
|
||||
target="_blank"
|
||||
title="About this feature"
|
||||
>
|
||||
|
||||
John Doe
|
||||
|
||||
</gl-link-stub>
|
||||
</div>
|
||||
<div
|
||||
class="gl-display-inline"
|
||||
data-testid="code-owners"
|
||||
>
|
||||
<!---->
|
||||
|
||||
<span
|
||||
data-testid="and-separator"
|
||||
>
|
||||
and
|
||||
</span>
|
||||
|
||||
<gl-link-stub
|
||||
href="path/to/@johnDoe"
|
||||
target="_blank"
|
||||
title="About this feature"
|
||||
>
|
||||
|
||||
John Doe
|
||||
|
||||
</gl-link-stub>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Code owners component matches the snapshot 4`] = `
|
||||
<div
|
||||
class="well-segment blob-auxiliary-viewer file-owner-content qa-file-owner-content"
|
||||
>
|
||||
<gl-icon-stub
|
||||
data-testid="users-icon"
|
||||
name="users"
|
||||
size="16"
|
||||
/>
|
||||
|
||||
<strong>
|
||||
Code owners
|
||||
</strong>
|
||||
|
||||
<gl-link-stub
|
||||
href="/help/user/project/code_owners"
|
||||
target="_blank"
|
||||
title="About this feature"
|
||||
>
|
||||
<gl-icon-stub
|
||||
data-testid="help-icon"
|
||||
name="question-o"
|
||||
size="16"
|
||||
/>
|
||||
</gl-link-stub>
|
||||
|
||||
:
|
||||
|
||||
<div
|
||||
class="gl-display-inline-block"
|
||||
data-testid="code-owners"
|
||||
>
|
||||
<!---->
|
||||
|
||||
<!---->
|
||||
|
||||
<gl-link-stub
|
||||
href="path/to/@johnDoe"
|
||||
target="_blank"
|
||||
title="About this feature"
|
||||
>
|
||||
|
||||
John Doe
|
||||
|
||||
</gl-link-stub>
|
||||
</div>
|
||||
<div
|
||||
class="gl-display-inline-block"
|
||||
data-testid="code-owners"
|
||||
>
|
||||
<span
|
||||
data-testid="comma-separator"
|
||||
>
|
||||
,
|
||||
</span>
|
||||
|
||||
<!---->
|
||||
|
||||
<gl-link-stub
|
||||
href="path/to/@johnDoe"
|
||||
target="_blank"
|
||||
title="About this feature"
|
||||
>
|
||||
|
||||
John Doe
|
||||
|
||||
</gl-link-stub>
|
||||
</div>
|
||||
<div
|
||||
class="gl-display-inline-block"
|
||||
data-testid="code-owners"
|
||||
>
|
||||
<span
|
||||
data-testid="comma-separator"
|
||||
>
|
||||
,
|
||||
</span>
|
||||
|
||||
<span
|
||||
data-testid="and-separator"
|
||||
>
|
||||
and
|
||||
</span>
|
||||
|
||||
<gl-link-stub
|
||||
href="path/to/@johnDoe"
|
||||
target="_blank"
|
||||
title="About this feature"
|
||||
>
|
||||
|
||||
John Doe
|
||||
|
||||
</gl-link-stub>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
exports[`Repository last commit component renders commit widget 1`] = `
|
||||
<div
|
||||
class="info-well d-none d-sm-flex project-last-commit commit p-3"
|
||||
class="well-segment commit gl-p-5 gl-w-full"
|
||||
>
|
||||
<user-avatar-link-stub
|
||||
class="avatar-cell"
|
||||
|
@ -108,7 +108,7 @@ exports[`Repository last commit component renders commit widget 1`] = `
|
|||
|
||||
exports[`Repository last commit component renders the signature HTML as returned by the backend 1`] = `
|
||||
<div
|
||||
class="info-well d-none d-sm-flex project-last-commit commit p-3"
|
||||
class="well-segment commit gl-p-5 gl-w-full"
|
||||
>
|
||||
<user-avatar-link-stub
|
||||
class="avatar-cell"
|
||||
|
|
89
spec/frontend/repository/components/code_owners_spec.js
Normal file
89
spec/frontend/repository/components/code_owners_spec.js
Normal file
|
@ -0,0 +1,89 @@
|
|||
import { GlLink } from '@gitlab/ui';
|
||||
import { shallowMount, createLocalVue } from '@vue/test-utils';
|
||||
import VueApollo from 'vue-apollo';
|
||||
import createMockApollo from 'helpers/mock_apollo_helper';
|
||||
import waitForPromises from 'helpers/wait_for_promises';
|
||||
import CodeOwners from '~/repository/components/code_owners.vue';
|
||||
import codeOwnersInfoQuery from '~/repository/queries/code_owners_info.query.graphql';
|
||||
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
|
||||
import { codeOwnerMock, codeOwnersDataMock, refMock } from '../mock_data';
|
||||
|
||||
let wrapper;
|
||||
let mockResolver;
|
||||
|
||||
const localVue = createLocalVue();
|
||||
|
||||
const createComponent = async (codeOwners = [codeOwnerMock]) => {
|
||||
localVue.use(VueApollo);
|
||||
|
||||
const project = {
|
||||
...codeOwnersDataMock,
|
||||
repository: {
|
||||
blobs: {
|
||||
nodes: [{ codeOwners }],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
mockResolver = jest.fn().mockResolvedValue({ data: { project } });
|
||||
|
||||
wrapper = extendedWrapper(
|
||||
shallowMount(CodeOwners, {
|
||||
localVue,
|
||||
apolloProvider: createMockApollo([[codeOwnersInfoQuery, mockResolver]]),
|
||||
propsData: { projectPath: 'some/project', filePath: 'some/file' },
|
||||
mixins: [{ data: () => ({ ref: refMock }) }],
|
||||
}),
|
||||
);
|
||||
|
||||
wrapper.setData({ isFetching: false });
|
||||
|
||||
await waitForPromises();
|
||||
};
|
||||
|
||||
describe('Code owners component', () => {
|
||||
const findHelpIcon = () => wrapper.findByTestId('help-icon');
|
||||
const findUsersIcon = () => wrapper.findByTestId('users-icon');
|
||||
const findCodeOwners = () => wrapper.findAllByTestId('code-owners');
|
||||
const findCommaSeparators = () => wrapper.findAllByTestId('comma-separator');
|
||||
const findAndSeparator = () => wrapper.findAllByTestId('and-separator');
|
||||
const findLink = () => wrapper.findComponent(GlLink);
|
||||
|
||||
beforeEach(() => createComponent());
|
||||
|
||||
afterEach(() => wrapper.destroy());
|
||||
|
||||
describe('help link', () => {
|
||||
it('renders a GlLink component', () => {
|
||||
expect(findLink().exists()).toBe(true);
|
||||
expect(findLink().attributes('href')).toBe('/help/user/project/code_owners');
|
||||
expect(findLink().attributes('target')).toBe('_blank');
|
||||
expect(findLink().attributes('title')).toBe('About this feature');
|
||||
});
|
||||
|
||||
it('renders a Help icon', () => {
|
||||
expect(findHelpIcon().exists()).toBe(true);
|
||||
expect(findHelpIcon().props('name')).toBe('question-o');
|
||||
});
|
||||
});
|
||||
|
||||
it('renders a Users icon', () => {
|
||||
expect(findUsersIcon().exists()).toBe(true);
|
||||
expect(findUsersIcon().props('name')).toBe('users');
|
||||
});
|
||||
|
||||
it.each`
|
||||
codeOwners | commaSeparators | hasAndSeparator
|
||||
${[]} | ${0} | ${false}
|
||||
${[codeOwnerMock]} | ${0} | ${false}
|
||||
${[codeOwnerMock, codeOwnerMock]} | ${0} | ${true}
|
||||
${[codeOwnerMock, codeOwnerMock, codeOwnerMock]} | ${2} | ${true}
|
||||
`('matches the snapshot', async ({ codeOwners, commaSeparators, hasAndSeparator }) => {
|
||||
await createComponent(codeOwners);
|
||||
|
||||
expect(findCommaSeparators().length).toBe(commaSeparators);
|
||||
expect(findAndSeparator().exists()).toBe(hasAndSeparator);
|
||||
expect(findCodeOwners().length).toBe(codeOwners.length);
|
||||
expect(wrapper.element).toMatchSnapshot();
|
||||
});
|
||||
});
|
|
@ -55,3 +55,18 @@ export const projectMock = {
|
|||
export const propsMock = { path: 'some_file.js', projectPath: 'some/path' };
|
||||
|
||||
export const refMock = 'default-ref';
|
||||
|
||||
export const codeOwnerMock = { name: 'John Doe', webPath: 'path/to/@johnDoe' };
|
||||
|
||||
export const codeOwnersDataMock = {
|
||||
id: '1234',
|
||||
repository: {
|
||||
blobs: {
|
||||
nodes: [
|
||||
{
|
||||
codeOwners: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -24,6 +24,7 @@ RSpec.describe Types::Repository::BlobType do
|
|||
:raw_path,
|
||||
:replace_path,
|
||||
:pipeline_editor_path,
|
||||
:code_owners,
|
||||
:simple_viewer,
|
||||
:rich_viewer,
|
||||
:plain_data,
|
||||
|
|
|
@ -61,9 +61,9 @@ RSpec.describe Packages::Debian::UpdateDistributionService do
|
|||
let_it_be(:architecture0) { create("debian_#{container_type}_architecture", distribution: distribution, name: 'all') }
|
||||
let_it_be(:architecture1) { create("debian_#{container_type}_architecture", distribution: distribution, name: 'architecture1') }
|
||||
let_it_be(:architecture2) { create("debian_#{container_type}_architecture", distribution: distribution, name: 'architecture2') }
|
||||
let_it_be(:component_file1) { create("debian_#{container_type}_component_file", :source, component: component1) }
|
||||
let_it_be(:component_file1) { create("debian_#{container_type}_component_file", :sources, component: component1) }
|
||||
let_it_be(:component_file2) { create("debian_#{container_type}_component_file", component: component1, architecture: architecture1) }
|
||||
let_it_be(:component_file3) { create("debian_#{container_type}_component_file", :source, component: component2) }
|
||||
let_it_be(:component_file3) { create("debian_#{container_type}_component_file", :sources, component: component2) }
|
||||
let_it_be(:component_file4) { create("debian_#{container_type}_component_file", component: component2, architecture: architecture2) }
|
||||
|
||||
let(:original_params) do
|
||||
|
|
|
@ -23,7 +23,7 @@ RSpec.shared_examples 'Debian Component File' do |container_type, can_freeze|
|
|||
let_it_be(:component_file_other_file_md5, freeze: can_freeze) { create("debian_#{container_type}_component_file", component: component1_1, architecture: architecture1_1, file_md5: 'other_md5') }
|
||||
let_it_be(:component_file_other_file_sha256, freeze: can_freeze) { create("debian_#{container_type}_component_file", component: component1_1, architecture: architecture1_1, file_sha256: 'other_sha256') }
|
||||
let_it_be(:component_file_other_container, freeze: can_freeze) { create("debian_#{container_type}_component_file", component: component2_1, architecture: architecture2_1) }
|
||||
let_it_be_with_refind(:component_file_with_file_type_source) { create("debian_#{container_type}_component_file", :source, component: component1_1) }
|
||||
let_it_be_with_refind(:component_file_with_file_type_sources) { create("debian_#{container_type}_component_file", :sources, component: component1_1) }
|
||||
let_it_be(:component_file_with_file_type_di_packages, freeze: can_freeze) { create("debian_#{container_type}_component_file", :di_packages, component: component1_1, architecture: architecture1_1) }
|
||||
|
||||
subject { component_file_with_architecture }
|
||||
|
@ -43,8 +43,8 @@ RSpec.shared_examples 'Debian Component File' do |container_type, can_freeze|
|
|||
it { is_expected.to belong_to(:architecture).class_name("Packages::Debian::#{container_type.capitalize}Architecture").inverse_of(:files) }
|
||||
end
|
||||
|
||||
context 'with :source file_type' do
|
||||
subject { component_file_with_file_type_source }
|
||||
context 'with :sources file_type' do
|
||||
subject { component_file_with_file_type_sources }
|
||||
|
||||
it { is_expected.to belong_to(:architecture).class_name("Packages::Debian::#{container_type.capitalize}Architecture").inverse_of(:files).optional }
|
||||
end
|
||||
|
@ -66,8 +66,8 @@ RSpec.shared_examples 'Debian Component File' do |container_type, can_freeze|
|
|||
it { is_expected.to validate_presence_of(:architecture) }
|
||||
end
|
||||
|
||||
context 'with :source file_type' do
|
||||
subject { component_file_with_file_type_source }
|
||||
context 'with :sources file_type' do
|
||||
subject { component_file_with_file_type_sources }
|
||||
|
||||
it { is_expected.to validate_absence_of(:architecture) }
|
||||
end
|
||||
|
@ -135,10 +135,10 @@ RSpec.shared_examples 'Debian Component File' do |container_type, can_freeze|
|
|||
end
|
||||
|
||||
describe '.with_file_type' do
|
||||
subject { described_class.with_file_type(:source) }
|
||||
subject { described_class.with_file_type(:sources) }
|
||||
|
||||
it do
|
||||
expect(subject.to_a).to contain_exactly(component_file_with_file_type_source)
|
||||
expect(subject.to_a).to contain_exactly(component_file_with_file_type_sources)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -214,9 +214,9 @@ RSpec.shared_examples 'Debian Component File' do |container_type, can_freeze|
|
|||
end
|
||||
|
||||
context 'with a Source file_type' do
|
||||
subject { component_file_with_file_type_source.relative_path }
|
||||
subject { component_file_with_file_type_sources.relative_path }
|
||||
|
||||
it { is_expected.to eq("#{component1_1.name}/source/Source") }
|
||||
it { is_expected.to eq("#{component1_1.name}/source/Sources") }
|
||||
end
|
||||
|
||||
context 'with a DI Packages file_type' do
|
||||
|
|
|
@ -126,7 +126,7 @@ RSpec.shared_examples 'Generate Debian Distribution and component files' do
|
|||
SHA256: #{package_files[4].file_sha256}
|
||||
EOF
|
||||
|
||||
expected_main_source_content = <<~EOF
|
||||
expected_main_sources_content = <<~EOF
|
||||
Package: #{package.name}
|
||||
Binary: sample-dev, libsample0, sample-udeb
|
||||
Version: #{package.version}
|
||||
|
@ -158,7 +158,7 @@ RSpec.shared_examples 'Generate Debian Distribution and component files' do
|
|||
check_component_file(current_time.round, 'main', :di_packages, 'amd64', expected_main_amd64_di_content)
|
||||
check_component_file(current_time.round, 'main', :di_packages, 'arm64', nil)
|
||||
|
||||
check_component_file(current_time.round, 'main', :source, nil, expected_main_source_content)
|
||||
check_component_file(current_time.round, 'main', :sources, nil, expected_main_sources_content)
|
||||
|
||||
check_component_file(current_time.round, 'contrib', :packages, 'all', nil)
|
||||
check_component_file(current_time.round, 'contrib', :packages, 'amd64', nil)
|
||||
|
@ -168,7 +168,7 @@ RSpec.shared_examples 'Generate Debian Distribution and component files' do
|
|||
check_component_file(current_time.round, 'contrib', :di_packages, 'amd64', nil)
|
||||
check_component_file(current_time.round, 'contrib', :di_packages, 'arm64', nil)
|
||||
|
||||
check_component_file(current_time.round, 'contrib', :source, nil, nil)
|
||||
check_component_file(current_time.round, 'contrib', :sources, nil, nil)
|
||||
|
||||
main_amd64_size = expected_main_amd64_content.length
|
||||
main_amd64_md5sum = Digest::MD5.hexdigest(expected_main_amd64_content)
|
||||
|
@ -182,9 +182,9 @@ RSpec.shared_examples 'Generate Debian Distribution and component files' do
|
|||
main_amd64_di_md5sum = Digest::MD5.hexdigest(expected_main_amd64_di_content)
|
||||
main_amd64_di_sha256 = Digest::SHA256.hexdigest(expected_main_amd64_di_content)
|
||||
|
||||
main_source_size = expected_main_source_content.length
|
||||
main_source_md5sum = Digest::MD5.hexdigest(expected_main_source_content)
|
||||
main_source_sha256 = Digest::SHA256.hexdigest(expected_main_source_content)
|
||||
main_sources_size = expected_main_sources_content.length
|
||||
main_sources_md5sum = Digest::MD5.hexdigest(expected_main_sources_content)
|
||||
main_sources_sha256 = Digest::SHA256.hexdigest(expected_main_sources_content)
|
||||
|
||||
expected_release_content = <<~EOF
|
||||
Codename: unstable
|
||||
|
@ -199,14 +199,14 @@ RSpec.shared_examples 'Generate Debian Distribution and component files' do
|
|||
d41d8cd98f00b204e9800998ecf8427e 0 contrib/debian-installer/binary-amd64/Packages
|
||||
d41d8cd98f00b204e9800998ecf8427e 0 contrib/binary-arm64/Packages
|
||||
d41d8cd98f00b204e9800998ecf8427e 0 contrib/debian-installer/binary-arm64/Packages
|
||||
d41d8cd98f00b204e9800998ecf8427e 0 contrib/source/Source
|
||||
d41d8cd98f00b204e9800998ecf8427e 0 contrib/source/Sources
|
||||
d41d8cd98f00b204e9800998ecf8427e 0 main/binary-all/Packages
|
||||
d41d8cd98f00b204e9800998ecf8427e 0 main/debian-installer/binary-all/Packages
|
||||
#{main_amd64_md5sum} #{main_amd64_size} main/binary-amd64/Packages
|
||||
#{main_amd64_di_md5sum} #{main_amd64_di_size} main/debian-installer/binary-amd64/Packages
|
||||
d41d8cd98f00b204e9800998ecf8427e 0 main/binary-arm64/Packages
|
||||
d41d8cd98f00b204e9800998ecf8427e 0 main/debian-installer/binary-arm64/Packages
|
||||
#{main_source_md5sum} #{main_source_size} main/source/Source
|
||||
#{main_sources_md5sum} #{main_sources_size} main/source/Sources
|
||||
SHA256:
|
||||
#{contrib_all_sha256} #{contrib_all_size} contrib/binary-all/Packages
|
||||
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 0 contrib/debian-installer/binary-all/Packages
|
||||
|
@ -214,14 +214,14 @@ RSpec.shared_examples 'Generate Debian Distribution and component files' do
|
|||
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 0 contrib/debian-installer/binary-amd64/Packages
|
||||
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 0 contrib/binary-arm64/Packages
|
||||
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 0 contrib/debian-installer/binary-arm64/Packages
|
||||
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 0 contrib/source/Source
|
||||
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 0 contrib/source/Sources
|
||||
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 0 main/binary-all/Packages
|
||||
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 0 main/debian-installer/binary-all/Packages
|
||||
#{main_amd64_sha256} #{main_amd64_size} main/binary-amd64/Packages
|
||||
#{main_amd64_di_sha256} #{main_amd64_di_size} main/debian-installer/binary-amd64/Packages
|
||||
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 0 main/binary-arm64/Packages
|
||||
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 0 main/debian-installer/binary-arm64/Packages
|
||||
#{main_source_sha256} #{main_source_size} main/source/Source
|
||||
#{main_sources_sha256} #{main_sources_size} main/source/Sources
|
||||
EOF
|
||||
|
||||
check_release_files(expected_release_content)
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
|
@ -28,6 +29,14 @@ type testCase struct {
|
|||
expectedResponse string
|
||||
}
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
// Secret should be configured before any Geo API poll happens to prevent
|
||||
// race conditions where the first API call happens without a secret path
|
||||
testhelper.ConfigureSecret()
|
||||
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
|
||||
func TestRouting(t *testing.T) {
|
||||
handle := func(u *upstream, regex string) routeEntry {
|
||||
handler := http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
||||
|
@ -288,11 +297,6 @@ func startWorkhorseServer(railsServerURL string, enableGeoProxyFeature bool) (*h
|
|||
}
|
||||
cfg := newUpstreamConfig(railsServerURL)
|
||||
upstreamHandler := newUpstream(*cfg, logrus.StandardLogger(), myConfigureRoutes)
|
||||
|
||||
// Secret should be configured before the first Geo API poll happens on server start
|
||||
// to prevent race conditions where the first API call happens without a secret path
|
||||
testhelper.ConfigureSecret()
|
||||
|
||||
ws := httptest.NewServer(upstreamHandler)
|
||||
|
||||
waitForNextApiPoll := func() {}
|
||||
|
|
Loading…
Reference in a new issue