Skip to content

Commit 4c0633d

Browse files
committed
Merge branch 'main' into stable-dt19-v1
2 parents c69a977 + 04f3a63 commit 4c0633d

File tree

9 files changed

+437
-5
lines changed

9 files changed

+437
-5
lines changed
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
name: Validate Pull Request
2+
3+
on:
4+
pull_request:
5+
types:
6+
- opened
7+
- synchronize
8+
- edited
9+
- reopened
10+
branches:
11+
- 'main'
12+
- 'release-**'
13+
# paths-ignore:
14+
# - 'docs/**'
15+
# - '.github/'
16+
# - 'CHANGELOG/'
17+
# - 'charts/'
18+
# - 'manifests/'
19+
# - 'sample-docker-templates/'
20+
21+
jobs:
22+
validate-PR-issue:
23+
runs-on: ubuntu-latest
24+
permissions:
25+
issues: write
26+
contents: read
27+
pull-requests: write
28+
steps:
29+
- name: Checkout repository
30+
uses: actions/checkout@v2
31+
32+
- name: Validate Issue Reference
33+
env:
34+
GITHUB_TOKEN: ${{ github.token }}
35+
PR_BODY: ${{ github.event.pull_request.body }}
36+
url: ${{ github.event.pull_request.url }}
37+
PRNUM: ${{ github.event.pull_request.number }}
38+
TITLE: ${{ github.event.pull_request.title }}
39+
run: |
40+
set -x
41+
if [[ "$TITLE" == *"doc:"* || "$TITLE" == *"docs:"* || "$TITLE" == *"chore:"* ]]; then
42+
echo "Skipping validation as this is a PR for documentation or chore."
43+
gh pr edit $PRNUM --remove-label "PR:Issue-verification-failed"
44+
gh pr edit $PRNUM --add-label "PR:Ready-to-Review"
45+
exit 0
46+
fi
47+
48+
### For ex: Fixes #2123
49+
pattern1="((Fixes|Resolves) #[0-9]+)"
50+
51+
### For ex: Resolves https://github.com/devtron-labs/devtron/issues/2123
52+
pattern2="((Fixes|Resolves) https://github.com/devtron-labs/devtron/issues/[0-9]+)"
53+
54+
### For ex: Fixes devtron-labs/devtron#2123
55+
pattern3="((Fixes|Resolves) devtron-labs/devtron#[0-9]+)"
56+
57+
# Get the pull request body
58+
PR_BODY=$(jq -r '.pull_request.body' $GITHUB_EVENT_PATH)
59+
echo "PR_BODY = $PR_BODY"
60+
61+
### Checks if PR_BODY matches pattern1 or pattern2 or pattern3 or none
62+
### grep -i (case insensitive) -E (enables extended regular expression in grep) -q (this option suppresses normal output)
63+
if echo "$PR_BODY" | grep -iEq "$pattern1"; then
64+
### Here we are taking only the numerical value ie. issue number
65+
### head -n1 only prints the 1st line.
66+
### grep -o -E "[0-9]+ basically outputs only the number between [0-9]+
67+
issue_num=$(echo "$PR_BODY" | grep -iE "$pattern1" | head -n1 | grep -o -E "[0-9]+")
68+
echo "issue_num is : $issue_num"
69+
elif echo "$PR_BODY" | grep -iEq "$pattern2"; then
70+
issue_num=$(echo "$PR_BODY" | grep -iE "$pattern2" | head -n1 | awk -F '/' '{print $NF}')
71+
echo "issue_num is : $issue_num"
72+
elif echo "$PR_BODY" | grep -iEq "$pattern3"; then
73+
issue_num=$(echo "$PR_BODY" | grep -iE "$pattern3" | head -n1 | awk -F '#' '{print $NF}')
74+
else
75+
echo "No Issue number detected hence failing the PR Validation check."
76+
gh pr edit $PRNUM --add-label "PR:Issue-verification-failed"
77+
gh pr edit $PRNUM --remove-label "PR:Ready-to-Review"
78+
exit 1
79+
fi
80+
81+
### hardcoding the url here to devtron repo as issues will always be created inside devtron repo.
82+
url=https://api.github.com/repos/devtron-labs/devtron
83+
84+
# Add the issue number to the URL
85+
url="${url}/issues/${issue_num}"
86+
echo "$url"
87+
response_code=$(curl -s -o /dev/null -w "%{http_code}" "$url")
88+
if [[ "$response_code" -eq 200 ]]; then
89+
# Check if issue is open or closed
90+
text=$(curl -s "$url")
91+
echo "checking status of the issue"
92+
# Skipping this condition as the Issue can be in closed state as BE PRs are merged before FE
93+
# if [[ $(echo "$text" | jq -r '.state') == "open" ]]; then
94+
echo "Issue #$issue_num is open"
95+
echo "Issue reference found in the pull request body."
96+
gh pr edit $PRNUM --remove-label "PR:Issue-verification-failed"
97+
gh pr edit $PRNUM --add-label "PR:Ready-to-Review"
98+
exit 0
99+
# else
100+
# echo "Issue #$issue_num is not open"
101+
# exit 1
102+
# fi
103+
else
104+
echo "Invalid Response Code obtained - error code: $response_code"
105+
echo "No valid issue reference found in the pull request body."
106+
gh pr comment $PRNUM --body "PR is not linked to any issue, please make the corresponding changes in the body."
107+
gh pr edit $PRNUM --add-label "PR:Issue-verification-failed"
108+
gh pr edit $PRNUM --remove-label "PR:Ready-to-Review"
109+
exit 1
110+
fi

src/components/ApplicationGroup/Constants.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,3 +167,16 @@ export const CREATE_GROUP_TABS = {
167167
selectedApps: 'Selected applications',
168168
allApps: 'Add/Remove applications',
169169
}
170+
171+
export const GetBranchChangeStatus = (statusText: string): BulkResponseStatus => {
172+
switch (statusText) {
173+
case BULK_VIRTUAL_RESPONSE_STATUS.pass:
174+
return BulkResponseStatus.PASS
175+
case BULK_VIRTUAL_RESPONSE_STATUS.fail:
176+
return BulkResponseStatus.FAIL
177+
case BULK_VIRTUAL_RESPONSE_STATUS.unauthorized:
178+
return BulkResponseStatus.UNAUTHORIZE
179+
default:
180+
return
181+
}
182+
}
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
import { CustomInput, Drawer, InfoColourBar, Progressing } from '@devtron-labs/devtron-fe-common-lib'
2+
import React, { useEffect, useRef, useState } from 'react'
3+
import { ReactComponent as Close } from '../../../../assets/icons/ic-cross.svg'
4+
import { ReactComponent as Warn } from '../../../../assets/icons/ic-warning.svg'
5+
import SourceUpdateResponseModal from './SourceUpdateResponseModal'
6+
7+
export default function BulkSourceChange({ closePopup, responseList, changeBranch, loading, selectedAppCount }) {
8+
const sourceChangeDetailRef = useRef<HTMLDivElement>(null)
9+
10+
const [showResponseModal, setShowResponseModal] = useState(false)
11+
const [inputError, setInputError] = useState('')
12+
const [branchName, setBranchName] = useState('')
13+
14+
const closeBulkCIModal = (evt) => {
15+
closePopup(evt)
16+
}
17+
18+
const escKeyPressHandler = (evt): void => {
19+
if (evt && evt.key === 'Escape' && typeof closePopup === 'function') {
20+
evt.preventDefault()
21+
closeBulkCIModal(evt)
22+
}
23+
}
24+
const outsideClickHandler = (evt): void => {
25+
if (
26+
sourceChangeDetailRef.current &&
27+
!sourceChangeDetailRef.current.contains(evt.target) &&
28+
typeof closePopup === 'function'
29+
) {
30+
closeBulkCIModal(evt)
31+
}
32+
}
33+
34+
useEffect(() => {
35+
document.addEventListener('keydown', escKeyPressHandler)
36+
return (): void => {
37+
document.removeEventListener('keydown', escKeyPressHandler)
38+
}
39+
}, [escKeyPressHandler])
40+
41+
useEffect(() => {
42+
document.addEventListener('click', outsideClickHandler)
43+
return (): void => {
44+
document.removeEventListener('click', outsideClickHandler)
45+
}
46+
}, [outsideClickHandler])
47+
48+
useEffect(() => {
49+
setShowResponseModal(responseList.length > 0)
50+
}, [responseList])
51+
52+
const updateBranch = () => {
53+
if (branchName.length === 0) {
54+
setInputError('This is required')
55+
return
56+
}
57+
changeBranch(branchName)
58+
}
59+
60+
const renderHeaderSection = (): JSX.Element | null => {
61+
return (
62+
<div className="flex flex-align-center flex-justify dc__border-bottom bcn-0 pt-16 pr-20 pb-16 pl-20">
63+
<h2 className="fs-16 fw-6 lh-1-43 m-0">Change branch for {selectedAppCount} applications</h2>
64+
<button
65+
type="button"
66+
className="dc__transparent flex icon-dim-24"
67+
disabled={loading}
68+
onClick={closeBulkCIModal}
69+
>
70+
<Close className="icon-dim-24" />
71+
</button>
72+
</div>
73+
)
74+
}
75+
76+
const renderInfoBar = (): JSX.Element => {
77+
return (
78+
<InfoColourBar
79+
message="Branch will be changed only for build pipelines with source type as ‘Branch Fixed’ or ‘Branch Regex’."
80+
classname="warn dc__no-border-radius dc__no-top-border dc__no-left-border dc__no-right-border"
81+
Icon={Warn}
82+
iconClass="warning-icon"
83+
/>
84+
)
85+
}
86+
87+
const checkInput = (): boolean => {
88+
return branchName === ''
89+
}
90+
91+
const handleInputChange = (e): void => {
92+
setBranchName(e.target.value)
93+
setInputError('')
94+
}
95+
96+
const renderForm = (): JSX.Element => {
97+
const isDisabled = checkInput()
98+
99+
return (
100+
<div className="p-20">
101+
<div className="form__row">
102+
<CustomInput
103+
labelClassName="dc__required-field"
104+
autoComplete="off"
105+
name="branch_name"
106+
disabled={false}
107+
value={branchName}
108+
error={inputError}
109+
onChange={handleInputChange}
110+
label="Change to branch"
111+
placeholder="Enter branch name"
112+
/>
113+
</div>
114+
<div className="flexbox">
115+
<button
116+
data-testid="cancel_button"
117+
className="cta cancel h-36 lh-36"
118+
type="button"
119+
onClick={closeBulkCIModal}
120+
>
121+
Cancel
122+
</button>
123+
<button
124+
data-testid="save_cluster_after_entering_cluster_details"
125+
className="cta ml-12 h-36 lh-36"
126+
onClick={updateBranch}
127+
disabled={isDisabled}
128+
>
129+
{loading ? <Progressing /> : 'Update branch'}
130+
</button>
131+
</div>
132+
</div>
133+
)
134+
}
135+
return (
136+
<Drawer position="right" width="75%" minWidth={showResponseModal ? '1024px' : '600px'} maxWidth={showResponseModal ? '1200px' : '600px'}>
137+
<div className="dc__window-bg h-100 bcn-0 bulk-ci-trigger-container" ref={sourceChangeDetailRef}>
138+
{renderHeaderSection()}
139+
{showResponseModal ? (
140+
<SourceUpdateResponseModal closePopup={closePopup} isLoading={false} responseList={responseList} />
141+
) : (
142+
<>
143+
{renderInfoBar()}
144+
{renderForm()}
145+
</>
146+
)}
147+
</div>
148+
</Drawer>
149+
)
150+
}

src/components/ApplicationGroup/Details/TriggerView/EnvTriggerView.scss

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,14 @@
1919
}
2020
}
2121

22+
.filter-divider {
23+
width: 1px;
24+
height: 20px;
25+
background-color: var(--N200);
26+
margin-left: 12px;
27+
margin-right: 12px;
28+
}
29+
2230
.bulk-ci-trigger-container {
2331
.bulk-ci-trigger {
2432
display: grid;

0 commit comments

Comments
 (0)