mirror of https://github.com/harness/drone.git
feat: [CODE-2411] add support for Fast-forward merge (#2803)
* feat: [CODE-2411] add support for Fast-forward mergepull/3576/head
parent
bbb7bce02a
commit
f6ac58f036
|
@ -166,6 +166,9 @@ const BranchProtectionForm = (props: {
|
|||
const isRebasePresent = (rule.definition as ProtectionBranch)?.pullreq?.merge?.strategies_allowed?.includes(
|
||||
MergeStrategy.REBASE
|
||||
)
|
||||
const isFFMergePresent = (rule.definition as ProtectionBranch)?.pullreq?.merge?.strategies_allowed?.includes(
|
||||
MergeStrategy.FAST_FORWARD
|
||||
)
|
||||
// List of strings to be included in the final array
|
||||
const includeList = (rule?.pattern as ProtectionPattern)?.include ?? []
|
||||
const excludeList = (rule?.pattern as ProtectionPattern)?.exclude ?? []
|
||||
|
@ -201,6 +204,7 @@ const BranchProtectionForm = (props: {
|
|||
mergeCommit: isMergePresent,
|
||||
squashMerge: isSquashPresent,
|
||||
rebaseMerge: isRebasePresent,
|
||||
fastForwardMerge: isFFMergePresent,
|
||||
autoDelete: (rule.definition as ProtectionBranch)?.pullreq?.merge?.delete_branch,
|
||||
blockBranchCreation: (rule.definition as ProtectionBranch)?.lifecycle?.create_forbidden,
|
||||
blockBranchUpdate:
|
||||
|
@ -244,7 +248,8 @@ const BranchProtectionForm = (props: {
|
|||
const stratArray = [
|
||||
formData.squashMerge && MergeStrategy.SQUASH,
|
||||
formData.rebaseMerge && MergeStrategy.REBASE,
|
||||
formData.mergeCommit && MergeStrategy.MERGE
|
||||
formData.mergeCommit && MergeStrategy.MERGE,
|
||||
formData.fastForwardMerge && MergeStrategy.FAST_FORWARD
|
||||
].filter(Boolean) as EnumMergeMethod[]
|
||||
const includeArray =
|
||||
formData?.targetList?.filter(([type]) => type === 'include').map(([, value]) => value) ?? []
|
||||
|
|
|
@ -269,6 +269,11 @@ const ProtectionRulesForm = (props: {
|
|||
<FormInput.CheckBox className={css.minText} label={getString('mergeCommit')} name={'mergeCommit'} />
|
||||
<FormInput.CheckBox className={css.minText} label={getString('squashMerge')} name={'squashMerge'} />
|
||||
<FormInput.CheckBox className={css.minText} label={getString('rebaseMerge')} name={'rebaseMerge'} />
|
||||
<FormInput.CheckBox
|
||||
className={css.minText}
|
||||
label={getString('fastForwardMerge')}
|
||||
name={'fastForwardMerge'}
|
||||
/>
|
||||
</Container>
|
||||
</Container>
|
||||
)}
|
||||
|
|
|
@ -424,6 +424,7 @@ export interface StringsMap {
|
|||
failedToFetchFileContent: string
|
||||
failedToImportSpace: string
|
||||
failedToSavePipeline: string
|
||||
fastForwardMerge: string
|
||||
featureRoadmap: string
|
||||
fileDeleted: string
|
||||
fileTooLarge: string
|
||||
|
@ -801,6 +802,8 @@ export interface StringsMap {
|
|||
'pr.mergeOptions.createAMergeCommit': string
|
||||
'pr.mergeOptions.createMergeCommit': string
|
||||
'pr.mergeOptions.createMergeCommitDesc': string
|
||||
'pr.mergeOptions.fastForwardMerge': string
|
||||
'pr.mergeOptions.fastForwardMergeDesc': string
|
||||
'pr.mergeOptions.rebaseAndMerge': string
|
||||
'pr.mergeOptions.rebaseAndMergeDesc': string
|
||||
'pr.mergeOptions.squashAndMerge': string
|
||||
|
@ -825,6 +828,7 @@ export interface StringsMap {
|
|||
'pr.prStateChanged': string
|
||||
'pr.prStateChangedDraft': string
|
||||
'pr.readyForReview': string
|
||||
'pr.rebaseMergePossible': string
|
||||
'pr.removeSuggestion': string
|
||||
'pr.requestSubmitted': string
|
||||
'pr.requestedChanges': string
|
||||
|
@ -995,6 +999,7 @@ export interface StringsMap {
|
|||
'securitySettings.vulnerabilityScanning': string
|
||||
'securitySettings.vulnerabilityScanningDesc': string
|
||||
seeNMoreMatches: string
|
||||
selectAuthor: string
|
||||
selectBranchPlaceHolder: string
|
||||
selectLanguagePlaceholder: string
|
||||
selectMergeStrat: string
|
||||
|
|
|
@ -302,6 +302,7 @@ pr:
|
|||
reviewChanges: Review changes
|
||||
mergePR: Merge pull request
|
||||
branchHasNoConflicts: Pull request can be merged
|
||||
rebaseMergePossible: Pull request can be merged after rebase
|
||||
checkingToMerge: Checking for ability to merge automatically...
|
||||
prCanBeMerged: Mergeing can be performed automatically.
|
||||
enterDesc: Enter description here
|
||||
|
@ -341,6 +342,8 @@ pr:
|
|||
createMergeCommitDesc: All commits from this branch will be added to the base branch via a merge commit.
|
||||
rebaseAndMerge: Rebase and merge
|
||||
rebaseAndMergeDesc: All commits from this branch will be rebased and added to the base branch.
|
||||
fastForwardMerge: Fast-forward merge
|
||||
fastForwardMergeDesc: All commits from this branch will be added to the base branch without a merge commit. Rebase may be required.
|
||||
close: Close pull request
|
||||
closeDesc: Close this pull request. You can still re-open the request after closing.
|
||||
createAMergeCommit: Create a merge commit
|
||||
|
@ -539,6 +542,7 @@ zoomIn: Zoom In
|
|||
zoomOut: Zoom Out
|
||||
checks: Checks
|
||||
blameCommitLine: '{author} committed {timestamp}'
|
||||
selectAuthor: Select Author
|
||||
tooltipRepoEdit: You are not authorized to {PERMS}
|
||||
missingPerms: 'You are missing the following permission:'
|
||||
createRepoPerms: 'Create / Edit Repository'
|
||||
|
@ -964,6 +968,7 @@ setting: Setting
|
|||
mergeCommit: Merge commit
|
||||
squashMerge: Squash and merge
|
||||
rebaseMerge: Rebase and merge
|
||||
fastForwardMerge: Fast-forward merge
|
||||
Enable: Enable
|
||||
imageUpload:
|
||||
title: Upload attachment
|
||||
|
|
|
@ -27,6 +27,7 @@ import { MergeStrategy } from 'utils/GitUtils'
|
|||
import mergeVideo from '../../../../videos/merge.mp4'
|
||||
import squashVideo from '../../../../videos/squash.mp4'
|
||||
import rebaseVideo from '../../../../videos/rebase.mp4'
|
||||
import fastForward from '../../../../videos/fastForward.mp4'
|
||||
import css from './PullRequestActionsBox.module.scss'
|
||||
|
||||
interface InlineMergeBoxProps {
|
||||
|
@ -96,6 +97,8 @@ const InlineMergeBox = (props: InlineMergeBoxProps) => {
|
|||
<video height={36} width={148} src={rebaseVideo} autoPlay={true} loop={false} muted={true} />
|
||||
) : mergeOption.method === MergeStrategy.SQUASH ? (
|
||||
<video height={36} width={148} src={squashVideo} autoPlay={true} loop={false} muted={true} />
|
||||
) : mergeOption.method === MergeStrategy.FAST_FORWARD ? (
|
||||
<video height={36} width={148} src={fastForward} autoPlay={true} loop={false} muted={true} />
|
||||
) : (
|
||||
<video height={36} width={148} src={mergeVideo} autoPlay={true} loop={false} muted={true} />
|
||||
)}
|
||||
|
@ -142,11 +145,12 @@ const InlineMergeBox = (props: InlineMergeBoxProps) => {
|
|||
{(mergeOption.method === MergeStrategy.SQUASH || mergeOption.method === MergeStrategy.MERGE) && (
|
||||
<FormInput.Text name="commitTitle"></FormInput.Text>
|
||||
)}
|
||||
{mergeOption.method !== MergeStrategy.REBASE && (
|
||||
<FormInput.TextArea
|
||||
placeholder={getString('addOptionalCommitMessage')}
|
||||
name="commitMessage"></FormInput.TextArea>
|
||||
)}
|
||||
{mergeOption.method !== MergeStrategy.REBASE &&
|
||||
mergeOption.method !== MergeStrategy.FAST_FORWARD && (
|
||||
<FormInput.TextArea
|
||||
placeholder={getString('addOptionalCommitMessage')}
|
||||
name="commitMessage"></FormInput.TextArea>
|
||||
)}
|
||||
</FormikForm>
|
||||
)
|
||||
}}
|
||||
|
|
|
@ -89,6 +89,8 @@
|
|||
&.merged {
|
||||
font-weight: unset !important;
|
||||
color: var(--purple-700) !important;
|
||||
white-space: nowrap !important;
|
||||
font-size: 14px !important;
|
||||
}
|
||||
|
||||
&.draft {
|
||||
|
@ -108,7 +110,7 @@
|
|||
.boldText {
|
||||
color: var(--purple-700) !important;
|
||||
font-weight: 600 !important;
|
||||
font-size: 16px !important;
|
||||
font-size: 14px !important;
|
||||
line-height: 24px !important;
|
||||
}
|
||||
.widthContainer {
|
||||
|
|
|
@ -30,17 +30,18 @@ import {
|
|||
useToaster
|
||||
} from '@harnessio/uicore'
|
||||
import { Icon } from '@harnessio/icons'
|
||||
import { Color } from '@harnessio/design-system'
|
||||
import { Color, FontVariation } from '@harnessio/design-system'
|
||||
import { MutateMethod, useMutate } from 'restful-react'
|
||||
import { Case, Else, Match, Render, Truthy } from 'react-jsx-match'
|
||||
import { Menu, PopoverPosition, Icon as BIcon } from '@blueprintjs/core'
|
||||
import cx from 'classnames'
|
||||
import ReactTimeago from 'react-timeago'
|
||||
import { defaultTo } from 'lodash-es'
|
||||
import type {
|
||||
CreateBranchPathParams,
|
||||
DeletePullReqSourceBranchQueryParams,
|
||||
OpenapiCreateBranchRequest,
|
||||
OpenapiStatePullReqRequest,
|
||||
RebaseBranchRequestBody,
|
||||
TypesListCommitResponse,
|
||||
TypesPullReq,
|
||||
TypesRuleViolations
|
||||
|
@ -58,9 +59,9 @@ import {
|
|||
permissionProps
|
||||
} from 'utils/Utils'
|
||||
import { OptionsMenuButton } from 'components/OptionsMenuButton/OptionsMenuButton'
|
||||
import { UserPreference, useUserPreference } from 'hooks/useUserPreference'
|
||||
import { useGetRepositoryMetadata } from 'hooks/useGetRepositoryMetadata'
|
||||
import { PullReqSuggestionsBatch } from 'components/PullReqSuggestionsBatch/PullReqSuggestionsBatch'
|
||||
import { TimePopoverWithLocal } from 'utils/timePopoverLocal/TimePopoverWithLocal'
|
||||
import { BranchActionsButton } from '../PullRequestOverviewPanel/sections/BranchActionsSection'
|
||||
import InlineMergeBox from './InlineMergeBox'
|
||||
import css from './PullRequestActionsBox.module.scss'
|
||||
|
@ -83,6 +84,9 @@ export interface PullRequestActionsBoxProps extends Pick<GitInfoProps, 'repoMeta
|
|||
setShowDeleteBranchButton: React.Dispatch<React.SetStateAction<boolean>>
|
||||
setShowRestoreBranchButton: React.Dispatch<React.SetStateAction<boolean>>
|
||||
isSourceBranchDeleted: boolean
|
||||
mergeOption: PRMergeOption
|
||||
setMergeOption: (val: PRMergeOption) => void
|
||||
rebasePossible: boolean
|
||||
}
|
||||
|
||||
export const PullRequestActionsBox: React.FC<PullRequestActionsBoxProps> = ({
|
||||
|
@ -102,10 +106,13 @@ export const PullRequestActionsBox: React.FC<PullRequestActionsBoxProps> = ({
|
|||
showDeleteBranchButton,
|
||||
setShowRestoreBranchButton,
|
||||
setShowDeleteBranchButton,
|
||||
isSourceBranchDeleted
|
||||
isSourceBranchDeleted,
|
||||
mergeOption,
|
||||
setMergeOption,
|
||||
rebasePossible
|
||||
}) => {
|
||||
const { getString } = useStrings()
|
||||
const { showError } = useToaster()
|
||||
const { showSuccess, showError } = useToaster()
|
||||
const inlineMergeRef = useRef<inlineMergeFormRefType>(null)
|
||||
const { hooks, standalone } = useAppContext()
|
||||
const space = useGetSpaceParam()
|
||||
|
@ -122,6 +129,19 @@ export const PullRequestActionsBox: React.FC<PullRequestActionsBoxProps> = ({
|
|||
verb: 'POST',
|
||||
path: `/api/v1/repos/${repoMetadata.path}/+/pullreq/${pullReqMetadata.number}/state`
|
||||
})
|
||||
const { mutate: rebase } = useMutate<RebaseBranchRequestBody>({
|
||||
verb: 'POST',
|
||||
path: `/api/v1/repos/${repoMetadata.path}/+/rebase`
|
||||
})
|
||||
|
||||
const rebaseRequestPayload = {
|
||||
base_branch: pullReqMetadata.target_branch,
|
||||
bypass_rules: true,
|
||||
dry_run_rules: false,
|
||||
head_branch: pullReqMetadata.source_branch,
|
||||
head_commit_sha: pullReqMetadata.source_sha
|
||||
}
|
||||
|
||||
const mergeable = useMemo(() => pullReqMetadata.merge_check_status === MergeCheckStatus.MERGEABLE, [pullReqMetadata])
|
||||
const isClosed = pullReqMetadata.state === PullRequestState.CLOSED
|
||||
const isOpen = pullReqMetadata.state === PullRequestState.OPEN
|
||||
|
@ -193,11 +213,12 @@ export const PullRequestActionsBox: React.FC<PullRequestActionsBoxProps> = ({
|
|||
} // eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [onPRStateChanged, isMerged, isClosed, pullReqMetadata?.source_sha])
|
||||
|
||||
const mergeOptions = useMemo(() => getMergeOptions(getString, mergeable).slice(0, 3), [mergeable])
|
||||
const mergeOptions = useMemo(() => getMergeOptions(getString, mergeable).slice(0, 4), [mergeable])
|
||||
const [allowedStrats, setAllowedStrats] = useState<string[]>([
|
||||
mergeOptions[0].method,
|
||||
mergeOptions[1].method,
|
||||
mergeOptions[2].method
|
||||
mergeOptions[2].method,
|
||||
mergeOptions[3].method
|
||||
])
|
||||
const draftOptions: PRDraftOption[] = [
|
||||
{
|
||||
|
@ -212,11 +233,6 @@ export const PullRequestActionsBox: React.FC<PullRequestActionsBoxProps> = ({
|
|||
}
|
||||
]
|
||||
const [showInlineMergeContainer, setShowInlineMergeContainer] = useState(false)
|
||||
const [mergeOption, setMergeOption] = useUserPreference<PRMergeOption>(
|
||||
UserPreference.PULL_REQUEST_MERGE_STRATEGY,
|
||||
mergeOptions[0],
|
||||
option => option.method !== 'close'
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
if (allowedStrats) {
|
||||
|
@ -283,6 +299,7 @@ export const PullRequestActionsBox: React.FC<PullRequestActionsBoxProps> = ({
|
|||
className={cx(css.main, {
|
||||
[css.primary]: !PRStateLoading,
|
||||
[css.error]: mergeable === false && !unchecked && !isClosed && !isDraft,
|
||||
[css.error]: mergeOption.method === MergeStrategy.FAST_FORWARD && rebasePossible,
|
||||
[css.unchecked]: unchecked,
|
||||
[css.closed]: isClosed,
|
||||
[css.draft]: isDraft,
|
||||
|
@ -302,6 +319,7 @@ export const PullRequestActionsBox: React.FC<PullRequestActionsBoxProps> = ({
|
|||
[css.draft]: isDraft,
|
||||
[css.closed]: isClosed,
|
||||
[css.unmergeable]: mergeable === false && isOpen,
|
||||
[css.unmergeable]: mergeOption.method === MergeStrategy.FAST_FORWARD && rebasePossible && isOpen,
|
||||
[css.ruleViolate]: ruleViolation && !isClosed
|
||||
})}>
|
||||
{getString(
|
||||
|
@ -315,6 +333,8 @@ export const PullRequestActionsBox: React.FC<PullRequestActionsBoxProps> = ({
|
|||
? 'branchProtection.prFailedText'
|
||||
: ruleViolation
|
||||
? 'branchProtection.prFailedText'
|
||||
: mergeOption.method === MergeStrategy.FAST_FORWARD && rebasePossible
|
||||
? 'branchProtection.prFailedText'
|
||||
: 'pr.branchHasNoConflicts'
|
||||
)}
|
||||
</Text>
|
||||
|
@ -473,7 +493,9 @@ export const PullRequestActionsBox: React.FC<PullRequestActionsBoxProps> = ({
|
|||
<Button
|
||||
type="submit"
|
||||
onClick={handleSubmit}
|
||||
disabled={isMerged}
|
||||
disabled={
|
||||
isMerged || (mergeOption.method === MergeStrategy.FAST_FORWARD && rebasePossible)
|
||||
}
|
||||
variation={ButtonVariation.PRIMARY}
|
||||
text={getString('confirmStrat', { strat: mergeOption.title })}
|
||||
/>
|
||||
|
@ -506,7 +528,25 @@ export const PullRequestActionsBox: React.FC<PullRequestActionsBoxProps> = ({
|
|||
})
|
||||
.catch(exception => showError(getErrorMessage(exception)))
|
||||
}
|
||||
}
|
||||
},
|
||||
...(rebasePossible
|
||||
? [
|
||||
{
|
||||
hasIcon: true,
|
||||
iconName: 'code-pull',
|
||||
text: getString('rebase'),
|
||||
onClick: () =>
|
||||
rebase(rebaseRequestPayload)
|
||||
.then(() => {
|
||||
showSuccess(getString('updatedBranchMessageRebase'))
|
||||
setTimeout(() => {
|
||||
refetchActivities()
|
||||
}, 1000)
|
||||
})
|
||||
.catch(err => showError(getErrorMessage(err)))
|
||||
}
|
||||
]
|
||||
: [])
|
||||
]}
|
||||
tooltipProps={{
|
||||
interactionKind: 'click',
|
||||
|
@ -593,7 +633,15 @@ const MergeInfo: React.FC<{
|
|||
</strong>
|
||||
</Container>
|
||||
),
|
||||
time: <ReactTimeago className={css.dateText} date={pullRequestMetadata.merged as number} />
|
||||
time: (
|
||||
<TimePopoverWithLocal
|
||||
className={css.dateText}
|
||||
time={defaultTo(pullRequestMetadata.merged as number, 0)}
|
||||
inline={false}
|
||||
font={{ variation: FontVariation.SMALL }}
|
||||
color={Color.GREY_400}
|
||||
/>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
</Text>
|
||||
|
|
|
@ -30,15 +30,17 @@ import type {
|
|||
TypesBranch
|
||||
} from 'services/code'
|
||||
import {
|
||||
PRMergeOption,
|
||||
PanelSectionOutletPosition,
|
||||
extractSpecificViolations,
|
||||
getMergeOptions
|
||||
} from 'pages/PullRequest/PullRequestUtils'
|
||||
import { MergeCheckStatus, extractInfoFromRuleViolationArr } from 'utils/Utils'
|
||||
import { PullRequestState, dryMerge } from 'utils/GitUtils'
|
||||
import { MergeStrategy, PullRequestState, dryMerge } from 'utils/GitUtils'
|
||||
import { useStrings } from 'framework/strings'
|
||||
import type { PRChecksDecisionResult } from 'hooks/usePRChecksDecision'
|
||||
import { useGetRepositoryMetadata } from 'hooks/useGetRepositoryMetadata'
|
||||
import { UserPreference, useUserPreference } from 'hooks/useUserPreference'
|
||||
import { PullRequestActionsBox } from '../PullRequestActionsBox/PullRequestActionsBox'
|
||||
import PullRequestPanelSections from './PullRequestPanelSections'
|
||||
import ChecksSection from './sections/ChecksSection'
|
||||
|
@ -241,6 +243,12 @@ const PullRequestOverviewPanel = (props: PullRequestOverviewPanelProps) => {
|
|||
[pullReqMetadata]
|
||||
)
|
||||
|
||||
const [mergeOption, setMergeOption] = useUserPreference<PRMergeOption>(
|
||||
UserPreference.PULL_REQUEST_MERGE_STRATEGY,
|
||||
mergeOptions[0],
|
||||
option => option.method !== 'close'
|
||||
)
|
||||
|
||||
return (
|
||||
<Container margin={{ bottom: 'medium' }} className={css.mainContainer}>
|
||||
<Layout.Vertical>
|
||||
|
@ -264,6 +272,9 @@ const PullRequestOverviewPanel = (props: PullRequestOverviewPanelProps) => {
|
|||
setShowDeleteBranchButton={setShowDeleteBranchButton}
|
||||
setShowRestoreBranchButton={setShowRestoreBranchButton}
|
||||
isSourceBranchDeleted={isSourceBranchDeleted}
|
||||
mergeOption={mergeOption}
|
||||
setMergeOption={setMergeOption}
|
||||
rebasePossible={rebasePossible}
|
||||
/>
|
||||
{!isClosed ? (
|
||||
<PullRequestPanelSections
|
||||
|
@ -312,7 +323,8 @@ const PullRequestOverviewPanel = (props: PullRequestOverviewPanelProps) => {
|
|||
),
|
||||
[PanelSectionOutletPosition.REBASE_SOURCE_BRANCH]: rebasePossible &&
|
||||
!mergeLoading &&
|
||||
!conflictingFiles?.length && (
|
||||
!conflictingFiles?.length &&
|
||||
mergeOption.method === MergeStrategy.FAST_FORWARD && (
|
||||
<RebaseSourceSection
|
||||
pullReqMetadata={pullReqMetadata}
|
||||
repoMetadata={repoMetadata}
|
||||
|
|
|
@ -87,6 +87,7 @@ export const BranchActionsButton = ({
|
|||
|
||||
return (
|
||||
<Button
|
||||
style={{ whiteSpace: 'nowrap' }}
|
||||
text={showDeleteBranchButton ? getString('deleteBranch') : getString('restoreBranch')}
|
||||
variation={ButtonVariation.SECONDARY}
|
||||
onClick={() => {
|
||||
|
|
|
@ -33,7 +33,7 @@ import { GitRefLink } from 'components/GitRefLink/GitRefLink'
|
|||
import { getErrorMessage, permissionProps } from 'utils/Utils'
|
||||
import { useGetSpaceParam } from 'hooks/useGetSpaceParam'
|
||||
import { useAppContext } from 'AppContext'
|
||||
import Fail from '../../../../../icons/code-fail-grey.svg?url'
|
||||
import FailRed from '../../../../../icons/code-fail.svg?url'
|
||||
import css from '../PullRequestOverviewPanel.module.scss'
|
||||
|
||||
interface RebaseSourceSectionProps {
|
||||
|
@ -80,9 +80,9 @@ const RebaseSourceSection = (props: RebaseSourceSectionProps) => {
|
|||
<Container className={cx(css.sectionContainer, css.borderRadius)}>
|
||||
<Layout.Horizontal flex={{ justifyContent: 'space-between' }}>
|
||||
<Layout.Horizontal flex={{ alignItems: 'center' }}>
|
||||
<img alt={getString('failed')} width={26} height={26} color={Color.GREY_500} src={Fail} />
|
||||
<img alt={getString('failed')} width={26} height={26} src={FailRed} />
|
||||
<Layout.Vertical padding={{ left: 'medium' }}>
|
||||
<Text padding={{ bottom: 'xsmall' }} className={css.sectionTitle} color={Color.GREY_600}>
|
||||
<Text padding={{ bottom: 'xsmall' }} className={css.sectionTitle} color={Color.RED_500}>
|
||||
{getString('rebaseSource.title')}
|
||||
</Text>
|
||||
<Text className={css.sectionSubheader} color={Color.GREY_450} font={{ variation: FontVariation.BODY }}>
|
||||
|
|
|
@ -65,7 +65,7 @@ export const SystemComment: React.FC<SystemCommentProps> = ({ pullReqMetadata, c
|
|||
</Container>
|
||||
|
||||
<Avatar name={pullReqMetadata.merger?.display_name} size="small" hoverCard={false} />
|
||||
<Text flex tag="div">
|
||||
<Text flex tag="div" style={{ whiteSpace: 'nowrap' }}>
|
||||
<StringSubstitute
|
||||
str={
|
||||
(payload?.payload as MergePayload)?.merge_method === MergeStrategy.REBASE
|
||||
|
@ -74,8 +74,16 @@ export const SystemComment: React.FC<SystemCommentProps> = ({ pullReqMetadata, c
|
|||
}
|
||||
vars={{
|
||||
user: <strong className={css.rightTextPadding}>{pullReqMetadata.merger?.display_name}</strong>,
|
||||
source: <strong className={css.textPadding}>{pullReqMetadata.source_branch}</strong>,
|
||||
target: <strong className={css.textPadding}>{pullReqMetadata.target_branch}</strong>,
|
||||
source: (
|
||||
<Text lineClamp={1}>
|
||||
<strong className={css.textPadding}>{pullReqMetadata.source_branch}</strong>
|
||||
</Text>
|
||||
),
|
||||
target: (
|
||||
<Text lineClamp={1}>
|
||||
<strong className={css.textPadding}>{pullReqMetadata.target_branch}</strong>
|
||||
</Text>
|
||||
),
|
||||
bypassed: (payload?.payload as MergePayload)?.rules_bypassed,
|
||||
mergeSha: (
|
||||
<Container className={css.commitContainer} padding={{ left: 'small', right: 'xsmall' }}>
|
||||
|
|
|
@ -113,6 +113,14 @@ export const getMergeOptions = (getString: UseStringsReturn['getString'], mergea
|
|||
label: getString('pr.mergeOptions.rebaseAndMerge'),
|
||||
value: MergeStrategy.REBASE
|
||||
},
|
||||
{
|
||||
method: MergeStrategy.FAST_FORWARD,
|
||||
title: getString('pr.mergeOptions.fastForwardMerge'),
|
||||
desc: getString('pr.mergeOptions.fastForwardMergeDesc'),
|
||||
disabled: mergeable === false,
|
||||
label: getString('pr.mergeOptions.fastForwardMerge'),
|
||||
value: MergeStrategy.FAST_FORWARD
|
||||
},
|
||||
{
|
||||
method: 'close',
|
||||
title: getString('pr.mergeOptions.close'),
|
||||
|
|
|
@ -209,7 +209,7 @@ export function PullRequestsContentHeader({
|
|||
popoverClassName={css.branchDropdown}
|
||||
icon="nav-user-profile"
|
||||
iconProps={{ size: 16 }}
|
||||
placeholder="Select Authors"
|
||||
placeholder={getString('selectAuthor')}
|
||||
addClearBtn={true}
|
||||
resetOnClose
|
||||
resetOnSelect
|
||||
|
|
|
@ -116,7 +116,7 @@ export type EnumMembershipRole = 'contributor' | 'executor' | 'reader' | 'space_
|
|||
|
||||
export type EnumMergeCheckStatus = string
|
||||
|
||||
export type EnumMergeMethod = 'merge' | 'rebase' | 'squash'
|
||||
export type EnumMergeMethod = 'fast-forward' | 'merge' | 'rebase' | 'squash'
|
||||
|
||||
export type EnumParentResourceType = 'space' | 'repo'
|
||||
|
||||
|
@ -1156,9 +1156,12 @@ export type TypesGitspaceInstance = {
|
|||
access_key?: string | null
|
||||
access_key_ref?: string | null
|
||||
access_type?: EnumGitspaceAccessType
|
||||
active_time_ended?: number | null
|
||||
active_time_started?: number | null
|
||||
created?: number
|
||||
identifier?: string
|
||||
last_used?: number
|
||||
last_heartbeat?: number | null
|
||||
last_used?: number | null
|
||||
machine_user?: string | null
|
||||
resource_usage?: string | null
|
||||
space_path?: string
|
||||
|
@ -1475,6 +1478,9 @@ export interface TypesPullReqStats {
|
|||
}
|
||||
|
||||
export interface TypesRebaseResponse {
|
||||
already_ancestor?: boolean
|
||||
conflict_files?: string[]
|
||||
dry_run?: boolean
|
||||
dry_run_rules?: boolean
|
||||
new_head_branch_sha?: ShaSHA
|
||||
rule_violations?: TypesRuleViolations[]
|
||||
|
@ -6240,6 +6246,7 @@ export interface RebaseBranchPathParams {
|
|||
export interface RebaseBranchRequestBody {
|
||||
base_branch?: string
|
||||
bypass_rules?: boolean
|
||||
dry_run?: boolean
|
||||
dry_run_rules?: boolean
|
||||
head_branch?: string
|
||||
head_commit_sha?: ShaSHA
|
||||
|
|
|
@ -6225,6 +6225,8 @@ paths:
|
|||
type: string
|
||||
bypass_rules:
|
||||
type: boolean
|
||||
dry_run:
|
||||
type: boolean
|
||||
dry_run_rules:
|
||||
type: boolean
|
||||
head_branch:
|
||||
|
@ -10540,6 +10542,7 @@ components:
|
|||
type: string
|
||||
EnumMergeMethod:
|
||||
enum:
|
||||
- fast-forward
|
||||
- merge
|
||||
- rebase
|
||||
- squash
|
||||
|
@ -12408,11 +12411,21 @@ components:
|
|||
type: string
|
||||
access_type:
|
||||
$ref: '#/components/schemas/EnumGitspaceAccessType'
|
||||
active_time_ended:
|
||||
nullable: true
|
||||
type: integer
|
||||
active_time_started:
|
||||
nullable: true
|
||||
type: integer
|
||||
created:
|
||||
type: integer
|
||||
identifier:
|
||||
type: string
|
||||
last_heartbeat:
|
||||
nullable: true
|
||||
type: integer
|
||||
last_used:
|
||||
nullable: true
|
||||
type: integer
|
||||
machine_user:
|
||||
nullable: true
|
||||
|
@ -13013,6 +13026,14 @@ components:
|
|||
type: object
|
||||
TypesRebaseResponse:
|
||||
properties:
|
||||
already_ancestor:
|
||||
type: boolean
|
||||
conflict_files:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
dry_run:
|
||||
type: boolean
|
||||
dry_run_rules:
|
||||
type: boolean
|
||||
new_head_branch_sha:
|
||||
|
|
|
@ -233,7 +233,8 @@ export const PullRequestFilterOption = {
|
|||
export enum MergeStrategy {
|
||||
MERGE = 'merge',
|
||||
SQUASH = 'squash',
|
||||
REBASE = 'rebase'
|
||||
REBASE = 'rebase',
|
||||
FAST_FORWARD = 'fast-forward'
|
||||
}
|
||||
|
||||
export const CodeIcon = {
|
||||
|
|
|
@ -385,6 +385,7 @@ export type RulesFormPayload = {
|
|||
mergeCommit?: boolean
|
||||
squashMerge?: boolean
|
||||
rebaseMerge?: boolean
|
||||
fastForwardMerge?: boolean
|
||||
autoDelete?: boolean
|
||||
blockBranchCreation?: boolean
|
||||
blockBranchDeletion?: boolean
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue