Skip to content

Commit

Permalink
refactor: 🚸 improve user feedback for nexus warnings
Browse files Browse the repository at this point in the history
  • Loading branch information
ArnaudTA committed Oct 14, 2024
1 parent 2d9a4e4 commit 09d6768
Show file tree
Hide file tree
Showing 19 changed files with 95 additions and 31 deletions.
12 changes: 11 additions & 1 deletion apps/client/src/components/LogsViewer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,18 @@ async function showLogs(index: number) {
/>
</div>
</div>
<template
v-if="hideLogs"
>
<pre
v-if="log.data.messageResume"
:data-testid="`${log.id}-json`"
copyable
style="white-space: pre-wrap; "
>{{ log.data.messageResume.trim() }}</pre>
</template>
<JsonViewer
v-if="!hideLogs"
v-else
:data-testid="`${log.id}-json`"
:value="hideLogDetails ? sliceLog(log) : log"
class="json-box !my-0"
Expand Down
1 change: 1 addition & 0 deletions apps/client/src/stores/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ export const useProjectStore = defineStore('project', () => {
const project = await apiClient.Projects.createProject({ body })
.then(response => extractData(response, 201))
await updateStores(project, ['mine'])
return project
}

const replayHooksForProject = async (projectId: string, stores?: StoresTarget) => {
Expand Down
15 changes: 14 additions & 1 deletion apps/client/src/views/projects/DsoDashboard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,20 @@ async function replayHooks() {
const callback = projectStore.selectedProject.addOperation('replay')
await projectStore.replayHooksForProject(projectStore.selectedProject.id)
await projectStore.getMyProjects()
snackbarStore.setMessage('Le projet a été reprovisionné avec succès', 'success')
switch (projectStore.selectedProject.status) {
case 'created':
snackbarStore.setMessage('Le projet a été reprovisionné avec succès', 'success')
break
case 'failed':
snackbarStore.setMessage('Le projet a été reprovisionné mais a rencontré une erreur bloquante, veuillez réessayer dans quelques instants. Si le problème persiste veuillez contacter un administrateur', 'error')
break
case 'warning':
snackbarStore.setMessage('Le projet a été reprovisionné et a rencontré une erreur non bloquante, veuillez réessayer dans quelques instants. Si le problème persiste veuillez contacter un administrateur', 'warning', 20_000)
break
default:
snackbarStore.setMessage('Le projet a été reprovisionné mais se trouve dans un état inconnu', 'info')
break
}
callback.fn(callback.args)
logStore.needRefresh = true
}
Expand Down
20 changes: 19 additions & 1 deletion packages/hooks/src/hooks/hook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export interface HookPayload<Args extends DefaultArgs> {
config: Config
}

export type HookResult<Args extends DefaultArgs> = Omit<HookPayload<Args>, 'apis'> & { totalExecutionTime: number }
export type HookResult<Args extends DefaultArgs> = Omit<HookPayload<Args>, 'apis'> & { totalExecutionTime: number, messageResume?: string }

export type StepCall<Args extends DefaultArgs> = (payload: HookPayload<Args>) => Promise<PluginResult>
type HookStep = Record<string, StepCall<DefaultArgs>>
Expand All @@ -45,6 +45,22 @@ export interface Hook<E extends DefaultArgs, V extends DefaultArgs> {
}
export type HookList<E extends DefaultArgs, V extends DefaultArgs> = Record<keyof typeof hooks, Hook<E, V>>

function generateMessageResume<Args extends DefaultArgs>(payload: HookPayload<Args>): string | undefined {
let messageResume = ''
if (Array.isArray(payload.failed)) {
for (const pluginName of payload.failed) {
messageResume += 'Errors:'
messageResume += `\n${pluginName}: ${payload.results[pluginName].status.message};`
}
}
if (payload.warning.length) {
for (const pluginName of payload.warning) {
messageResume += 'Warnings:'
messageResume += `\n${pluginName}: ${payload.results[pluginName].status.message};`
}
}
return messageResume || undefined
}
export async function executeStep<Args extends DefaultArgs>(step: HookStep, payload: HookPayload<Args>, stepName: string) {
const names = Object.keys(step)
const fns = names.map(async (name) => {
Expand Down Expand Up @@ -114,6 +130,7 @@ export function createHook<E extends DefaultArgs, V extends DefaultArgs>(unique
warning: payload.warning,
totalExecutionTime: Date.now() - startTime,
config,
messageResume: generateMessageResume(payload),
}
}

Expand All @@ -140,6 +157,7 @@ export function createHook<E extends DefaultArgs, V extends DefaultArgs>(unique
totalExecutionTime: Date.now() - startTime,
config,
warning: payload.warning,
messageResume: generateMessageResume(result),
}
}
const hook: Hook<E, V> = {
Expand Down
2 changes: 2 additions & 0 deletions packages/shared/src/schemas/log.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export const CleanLogSchema = z.object({
failed: z.boolean().or(z.array(z.string())).optional(),
warning: z.string().array().optional(),
totalExecutionTime: z.number().optional(),
messageResume: z.string().optional(),
}).strip(),
action: z.string(),
userId: z.string().nullable(),
Expand All @@ -21,6 +22,7 @@ export const LogSchema = z.object({
warning: z.string().array().optional(),
results: z.any(),
totalExecutionTime: z.number().optional(),
messageResume: z.string().optional(),
})
.passthrough()
.transform((data) => {
Expand Down
2 changes: 1 addition & 1 deletion plugins/gitlab/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@cpn-console/gitlab-plugin",
"type": "module",
"version": "2.3.1",
"version": "2.3.2",
"private": false,
"description": "",
"main": "dist/index.js",
Expand Down
2 changes: 1 addition & 1 deletion plugins/gitlab/src/functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export const checkApi: StepCall<Project> = async (payload) => {
status: {
result: 'KO',
// @ts-ignore prévoir une fonction générique
message: error.message,
message: 'An unexpected error occured',
},
}
}
Expand Down
2 changes: 1 addition & 1 deletion plugins/harbor/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@cpn-console/harbor-plugin",
"type": "module",
"version": "2.2.0",
"version": "2.2.1",
"private": false,
"description": "",
"main": "dist/index.js",
Expand Down
4 changes: 2 additions & 2 deletions plugins/harbor/src/functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export const createDsoProject: StepCall<Project> = async (payload) => {
status: {
result: 'KO',
// @ts-ignore prévoir une fonction générique
message: error.message,
message: 'An unexpected error occured',
},
}
}
Expand All @@ -88,7 +88,7 @@ export const deleteDsoProject: StepCall<Project> = async (payload) => {
status: {
result: 'KO',
// @ts-ignore prévoir une fonction générique
message: error.message,
message: 'An unexpected error occured',
},
}
}
Expand Down
2 changes: 1 addition & 1 deletion plugins/keycloak/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@cpn-console/keycloak-plugin",
"type": "module",
"version": "2.0.4",
"version": "2.0.5",
"private": false,
"description": "",
"main": "dist/index.js",
Expand Down
6 changes: 3 additions & 3 deletions plugins/keycloak/src/functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const retrieveKeycloakUserByEmail: StepCall<UserEmail> = async ({ args: {
status: {
result: 'KO',
// @ts-ignore prévoir une fonction générique
message: error.message,
message: 'An unexpected error occured',
},
}
}
Expand Down Expand Up @@ -53,7 +53,7 @@ export const deleteProject: StepCall<Project> = async ({ args: project }) => {
status: {
result: 'KO',
// @ts-ignore prévoir une fonction générique
message: error.message,
message: 'An unexpected error occured',
},
}
}
Expand Down Expand Up @@ -203,7 +203,7 @@ export const deleteZone: StepCall<ZoneObject> = async ({ args: zone }) => {
error: parseError(error),
status: {
result: 'KO',
message: error.message,
message: 'An unexpected error occured',
},
}
}
Expand Down
2 changes: 1 addition & 1 deletion plugins/nexus/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@cpn-console/nexus-plugin",
"type": "module",
"version": "2.1.0",
"version": "2.1.1",
"private": false,
"description": "",
"main": "dist/index.js",
Expand Down
4 changes: 2 additions & 2 deletions plugins/nexus/src/infos.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const infos = {
},
title: 'Créer un dépôt NPM privé',
value: 'disabled',
description: 'Default: utilise le paramétrage globale de la console',
description: 'Default: utilise le paramétrage globale de la console. Attention: Nexus met un certain temps pour activer/désactiver les dépôts, un reprovisonnage après plusieurs minutes peut être nécessaire',
},
{
key: 'activateMavenRepo',
Expand All @@ -29,7 +29,7 @@ const infos = {
},
title: 'Créer un dépôt MAVEN privé',
value: 'disabled',
description: 'Default: utilise le paramétrage globale de la console',
description: 'Default: utilise le paramétrage globale de la console. Attention: Nexus met un certain temps pour activer/désactiver les dépôts, un reprovisonnage après plusieurs minutes peut être nécessaire',
},
],
global: [
Expand Down
41 changes: 30 additions & 11 deletions plugins/nexus/src/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export const deleteNexusProject: StepCall<Project> = async ({ args: project }) =
status: {
result: 'KO',
// @ts-ignore prévoir une fonction générique
message: error.message,
message: 'An unexpected error occured',
},
}
}
Expand All @@ -54,21 +54,30 @@ export const createNexusProject: StepCall<Project> = async (payload) => {
const owner = payload.args.owner
const res: any = {}

const failedProvisionning: Partial<Record<keyof typeof techUsed, { error: Error | unknown, message: string }>> = {}
const techUsed = getTechUsed(payload)
const privilegesToAccess = [] as string[]

if (techUsed.maven) {
const names = await createMavenRepo(axiosInstance, projectName)
privilegesToAccess.push(names.group.privilege, ...names.hosted.map(({ privilege }) => privilege))
} else {
await Promise.all(deleteMavenRepo(axiosInstance, projectName))
try {
if (techUsed.maven) {
const names = await createMavenRepo(axiosInstance, projectName)
privilegesToAccess.push(names.group.privilege, ...names.hosted.map(({ privilege }) => privilege))
} else {
await Promise.all(deleteMavenRepo(axiosInstance, projectName))
}
} catch (error) {
failedProvisionning.maven = { error, message: `Maven failed to ${techUsed.maven ? 'provision' : 'delete'} repositories please try again in few minutes` }
}

if (techUsed.npm) {
const names = await createNpmRepo(axiosInstance, projectName)
privilegesToAccess.push(names.group.privilege, ...names.hosted.map(({ privilege }) => privilege))
} else {
await Promise.all(deleteNpmRepo(axiosInstance, projectName))
try {
if (techUsed.npm) {
const names = await createNpmRepo(axiosInstance, projectName)
privilegesToAccess.push(names.group.privilege, ...names.hosted.map(({ privilege }) => privilege))
} else {
await Promise.all(deleteNpmRepo(axiosInstance, projectName))
}
} catch (error) {
failedProvisionning.npm = { error, message: `Npm failed to ${techUsed.npm ? 'provision' : 'delete'} repositories please try again in few minutes` }
}

const roleId = `${projectName}-ID`
Expand Down Expand Up @@ -147,6 +156,16 @@ export const createNexusProject: StepCall<Project> = async (payload) => {
}, 'NEXUS')
}

if (Object.keys(failedProvisionning).length) {
const failed = Object.values(failedProvisionning)
return {
status: {
result: 'WARNING',
message: failed.map(({ message }) => message).join('; '),
},
errors: failed.map(({ error }) => parseError(error)),
}
}
return {
status: { result: 'OK', message: 'Up-to-date' },
}
Expand Down
1 change: 1 addition & 0 deletions plugins/nexus/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"paths": {
"@/*": ["src/*"]
},
"useUnknownInCatchVariables": true,
"declarationDir": "./types",
"outDir": "./dist"
},
Expand Down
2 changes: 1 addition & 1 deletion plugins/sonarqube/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@cpn-console/sonarqube-plugin",
"type": "module",
"version": "2.0.4",
"version": "2.0.5",
"private": false,
"description": "",
"main": "dist/index.js",
Expand Down
2 changes: 1 addition & 1 deletion plugins/sonarqube/src/check.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export async function check(): Promise<PluginResult> {
status: {
result: 'KO',
// @ts-ignore prévoir une fonction générique
message: error.message,
message: 'An unexpected error occured',
},
updatedAt: Date.now(),
}
Expand Down
2 changes: 1 addition & 1 deletion plugins/vault/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@cpn-console/vault-plugin",
"type": "module",
"version": "2.0.3",
"version": "2.0.4",
"private": false,
"description": "",
"main": "dist/index.js",
Expand Down
4 changes: 2 additions & 2 deletions plugins/vault/src/functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export const upsertProjectAppRole: StepCall<Project> = async (payload) => {
error: parseError(error),
status: {
result: 'KO',
message: error instanceof Error ? error.message : 'An unexpected error has occurred',
message: 'An unexpected error occured',
},
}
}
Expand Down Expand Up @@ -44,7 +44,7 @@ export const archiveDsoProject: StepCall<Project> = async (payload) => {
error: parseError(error),
status: {
result: 'KO',
message: error instanceof Error ? error.message : 'An unexpected error has occurred',
message: 'An unexpected error occured',
},
}
}
Expand Down

0 comments on commit 09d6768

Please sign in to comment.