Skip to content

Commit

Permalink
add Jira and PR creation logic with submitRequest button
Browse files Browse the repository at this point in the history
  • Loading branch information
DennisPeriquet committed Oct 25, 2024
1 parent b02cb17 commit c40500a
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 46 deletions.
5 changes: 3 additions & 2 deletions components/api_calls/api_calls.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ axios.defaults.xsrfHeaderName = 'X-CSRFToken';
let server_endpoint = null;

if (process.env.NEXT_PUBLIC_RUN_ENV === "dev") {
server_endpoint = "http://localhost:8080";
server_endpoint = "http://chopin2:8080";
} else {
server_endpoint = process.env.NEXT_PUBLIC_ART_DASH_SERVER_ROUTE;
}
Expand Down Expand Up @@ -61,5 +61,6 @@ function makeApiCall(urlPath, method, data = {}, headers = {}, params = {}, req
}

module.exports = {
makeApiCall
makeApiCall,
server_endpoint
};
161 changes: 118 additions & 43 deletions components/self-service/new-content-done.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
import Box from '@mui/material/Box'
import { Button, Typography } from '@mui/material'
import { Button, Typography, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle } from '@mui/material';
import * as React from 'react';
import { useState } from 'react';
import { useNewContentState } from './new-content-state'
import YAML from 'yaml'
const { server_endpoint } = require('../api_calls/api_calls.js');


export default function NewContentDone() {
const { activeStep, handleBack, handleReset, inputs } = useNewContentState();

const [dialogOpen, setDialogOpen] = useState(false);
const [dialogContent, setDialogContent] = useState('');
const [isSubmitted, setIsSubmitted] = useState(false);

const distgit_ns = inputs.componentType == 'rpm' ? 'rpms' : 'containers';
let web_url = inputs.sourceRepo;
if (web_url?.endsWith('.git'))
Expand Down Expand Up @@ -112,52 +120,97 @@ export default function NewContentDone() {
return YAML.stringify(result);
};

// safeEncodeURIComponent wraps the library function, and additionally encodes
// square brackets. Square brackets are NOT unsafe per RFC1738, but Google and
// others mishandle them.
const safeEncodeURIComponent = (value) => {
return encodeURIComponent(value)
.replace('[', '%5B')
.replace(']', '%5D')
.replace('{', '%7B')
.replace('}', '%7D')
}

// Create jira summary.
const jiraSummary = `[BuildAuto] Add OCP component - ${distgit_ns}/${distgitName}`
const jiraSummaryEncoded = safeEncodeURIComponent(jiraSummary);

// Combine YAMLs as Jira description
const jiraDescription = `${generateYaml()}\n\n${generateHBYaml()}`;
const jiraDescriptionEncoded = safeEncodeURIComponent(jiraDescription);
const handleSubmitRequest = async () => {
const gitUser = "DennisPeriquet"; // FIXME
const gitBranch = "master"; // FIXME

const imageName = web_url?.substring(web_url.lastIndexOf('/')+ 1)
const jiraDescription = `${generateYaml()}\n\n${generateHBYaml()}`;
const ARTProjectID = "ART"
const ARTStoryTypeID = "Story"
const component = "Release work";
const priority = "Normal";

const releaseWork = safeEncodeURIComponent("Release work")
const fileContent = `content:
source:
dockerfile: Dockerfile.openshift
git:
branch:
target: release-{MAJOR}.{MINOR}
url: ${repo_url}
web: ${web_url}
ci_alignment:
streams_prs:
ci_build_root:
stream: rhel-9-golang-ci-build-root
distgit:
branch: rhaos-{MAJOR}.{MINOR}-rhel-9
component: ${imageName}-container
enabled_repos:
- rhel-9-appstream-rpms
- rhel-9-baseos-rpms
for_payload: false
from:
builder:
- stream: rhel-9-golang
member: openshift-enterprise-base-rhel9
name: openshift/${imageName}-rhel9
owners:
- ${inputs.deliveryRepoImageOwner}@redhat.com
`;

const ARTProjectID = "12323120"
const ARTStoryTypeID = 17
const params = new URLSearchParams({
git_user: gitUser,
branch: gitBranch,
image_name: imageName,
file_content: fileContent,
jira_summary: jiraSummary,
jira_description: jiraDescription,
jira_project_id: ARTProjectID,
jira_story_type_id: ARTStoryTypeID,
jira_component: component,
jira_priority: priority,
git_test_mode: "false",
jira_test_mode: "false",
});

// Build the Jira URL
let jiraUrl = `https://issues.redhat.com/secure/CreateIssueDetails!init.jspa?priority=10200`
jiraUrl += `&pid=${ARTProjectID}`
jiraUrl += `&issuetype=${ARTStoryTypeID}`
jiraUrl += `&summary=${jiraSummaryEncoded}`
jiraUrl += `&description=${jiraDescriptionEncoded}`
jiraUrl += `&component=${releaseWork}`
const requestUrl = `${server_endpoint}/api/v1/git_jira_api?${params.toString()}`;

const handleCreateJira = () => {
try {
const response = await fetch(requestUrl, {
method: 'GET',
});

const data = await response.json();
if (data.status === "success") {
// Track if submitted successfully so we can suppress the button.
setIsSubmitted(true);
setDialogContent(`${data.jira_url}\n\n${data.pr_url}`);
setDialogOpen(true);
} else {
setDialogContent(`Error: ${data.error}`);
setDialogOpen(true);
}
} catch (error) {
setDialogContent(`Failed to create Jira issue: ${error}`);
setDialogOpen(true);
}
};

// Open the Jira creation page in a new tab with pre-filled data
window.open(jiraUrl, '_blank');
const handleCloseDialog = () => {
setDialogOpen(false);
};

return (<Box
component="div"
sx={{
'& > :not(style)': { m: 2},
'& > :not(style)': { m: 2 },
}}
>
<Box>
<Typography sx={{ mb: 3 }}>About to make a Jira in the <strong>ART</strong> project using the <strong>Summary</strong> and <strong>Description</strong> below:</Typography>
<Typography sx={{ mb: 3 }}>About to make a Jira in the <strong>ART</strong> project using the <strong>Summary</strong> and <strong>Description</strong> below:</Typography>
<hr />
<Typography component="h6" sx={{ mt: 2 }}><b>Summary</b></Typography>
<Typography>{jiraSummary}</Typography>
Expand All @@ -174,20 +227,20 @@ export default function NewContentDone() {
Follow these steps:
</Typography>
<ul>
<li>If the above looks good, login to Jira <a href="https://issues.redhat.com/" target="_blank" rel="noopener noreferrer">here</a> (a separate tab will open) then click the "Create Jira" button below</li>
<li>In the "Create Issue" page, set the "Reporter" field as your UserId and click the "Create" button at the bottom</li>
<li>Send the Jira number to the <strong>ART</strong> project</li>
<li>Inform <strong>@release-artists</strong> on <strong>#forum-ocp-art</strong> on Slack</li>
<li>If the above looks good, click SubmitRequest and a Jira and PR will be created</li>
<li>Inform <strong>@release-artists</strong> on <strong>#forum-ocp-art</strong> on Slack about the Jira and PR</li>
</ul>
</Box>
<Box sx={{ py: 2 }}>
<Button
variant="contained"
onClick={handleCreateJira}
sx={{ mt: 1, mr: 1 }}
>
Create Jira
</Button>
{!isSubmitted && (
<Button
variant="contained"
onClick={handleSubmitRequest}
sx={{ mt: 1, mr: 1 }}
>
SubmitRequest
</Button>
)}
<Button
variant="contained"
onClick={handleReset}
Expand All @@ -202,6 +255,28 @@ export default function NewContentDone() {
>
Back
</Button>
<Dialog
open={dialogOpen}
onClose={handleCloseDialog}
>
<DialogTitle>Jira and PR created successfully:</DialogTitle>
<DialogContent>
<DialogContentText>
{dialogContent.split('\n\n').map((text, index) => (
<span key={index}>
{text}
<br />
</span>
))}
</DialogContentText>
</DialogContent>
<DialogActions sx={{ justifyContent: 'center' }}>
<Button onClick={handleCloseDialog} color="primary">
Dismiss
</Button>
</DialogActions>
</Dialog>

</Box>
</Box>)
}
2 changes: 1 addition & 1 deletion components/self-service/new-content-state.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export const NewContentContext = createContext<NewContentContext | undefined>(un
export function NewContentStateProvider({ children }: { children: ReactNode }) {

// Set this to true when you want to run through the workflows without entering values manually.
const debugMode = false
const debugMode = true

let initialValues: Inputs

Expand Down

0 comments on commit c40500a

Please sign in to comment.