From e81f4f8404016aab2d87a921acdd564fb9e8372f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Beltra=CC=81n?= Date: Wed, 24 Apr 2024 19:07:46 +0200 Subject: [PATCH 01/47] test --- tests/unit/SignIn.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/SignIn.spec.js b/tests/unit/SignIn.spec.js index b27526271..f20d25fc2 100644 --- a/tests/unit/SignIn.spec.js +++ b/tests/unit/SignIn.spec.js @@ -30,7 +30,7 @@ describe('SignIn', () => { return Promise.resolve() }) - const emailInput = screen.getByLabelText(/E-mail/i) + // const emailInput = screen.getByLabelText(/E-mail/i) await fireEvent.update(emailInput, 'valid-email') const passwordInput = screen.getByLabelText(/Password/i, { selector: 'input' }) await fireEvent.update(passwordInput, 'valid-password') From a0fafe3f2ed69ea7a272b1d6fee07e933196a368 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Beltra=CC=81n?= Date: Wed, 24 Apr 2024 19:10:10 +0200 Subject: [PATCH 02/47] revert commit --- tests/unit/SignIn.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/SignIn.spec.js b/tests/unit/SignIn.spec.js index f20d25fc2..b27526271 100644 --- a/tests/unit/SignIn.spec.js +++ b/tests/unit/SignIn.spec.js @@ -30,7 +30,7 @@ describe('SignIn', () => { return Promise.resolve() }) - // const emailInput = screen.getByLabelText(/E-mail/i) + const emailInput = screen.getByLabelText(/E-mail/i) await fireEvent.update(emailInput, 'valid-email') const passwordInput = screen.getByLabelText(/Password/i, { selector: 'input' }) await fireEvent.update(passwordInput, 'valid-password') From 4e241108af0218fec25cbf7b8b876168e300e698 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Beltra=CC=81n?= Date: Thu, 2 May 2024 21:24:59 +0200 Subject: [PATCH 03/47] include cypress testing library in the project --- cypress/support/commands.js | 4 +++- jsconfig.json | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/cypress/support/commands.js b/cypress/support/commands.js index 66ea16ef0..3751eb0cc 100644 --- a/cypress/support/commands.js +++ b/cypress/support/commands.js @@ -22,4 +22,6 @@ // // // -- This will overwrite an existing command -- -// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... }) \ No newline at end of file +// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... }) + +import '@testing-library/cypress/add-commands' diff --git a/jsconfig.json b/jsconfig.json index 486c7bedb..1ea48a976 100644 --- a/jsconfig.json +++ b/jsconfig.json @@ -3,6 +3,7 @@ "baseUrl": "./", "paths": { "@/*": ["src/*"] - } + }, + "types": ["cypress", "@testing-library/cypress"] } } From f456bd542cfd9d88a7c875e9cb7f2c5f64fb8a51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Beltra=CC=81n?= Date: Sat, 4 May 2024 11:09:43 +0200 Subject: [PATCH 04/47] firebase auth utils for cypress --- cypress.config.js | 9 +- cypress/fixtures/authUser.json | 12 +++ cypress/fixtures/example.json | 5 -- cypress/support/commands.js | 11 +++ cypress/support/commands/auth.js | 139 +++++++++++++++++++++++++++++++ 5 files changed, 169 insertions(+), 7 deletions(-) create mode 100644 cypress/fixtures/authUser.json delete mode 100644 cypress/fixtures/example.json create mode 100644 cypress/support/commands/auth.js diff --git a/cypress.config.js b/cypress.config.js index 97f47c412..54c7ff143 100644 --- a/cypress.config.js +++ b/cypress.config.js @@ -1,4 +1,5 @@ -const { defineConfig } = require("cypress"); +const { defineConfig } = require('cypress') +require('dotenv').config() module.exports = defineConfig({ e2e: { @@ -6,4 +7,8 @@ module.exports = defineConfig({ // implement node event listeners here }, }, -}); + env: { + // add environment variables here + ...process.env, + }, +}) diff --git a/cypress/fixtures/authUser.json b/cypress/fixtures/authUser.json new file mode 100644 index 000000000..8f766a6cd --- /dev/null +++ b/cypress/fixtures/authUser.json @@ -0,0 +1,12 @@ +{ + "email": "ruxailab@ruxailab.com", + "password": "ruxailab1234", + "data": { + "accessLevel": 1, + "email" : "ruxailab@ruxailab.com", + "myAnswers": {}, + "myTests": {}, + "notifications": [] + }, + "collection": "users" +} diff --git a/cypress/fixtures/example.json b/cypress/fixtures/example.json deleted file mode 100644 index 02e425437..000000000 --- a/cypress/fixtures/example.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "Using fixtures to represent data", - "email": "hello@cypress.io", - "body": "Fixtures are a great way to mock data for responses to routes" -} diff --git a/cypress/support/commands.js b/cypress/support/commands.js index 3751eb0cc..16f1fa204 100644 --- a/cypress/support/commands.js +++ b/cypress/support/commands.js @@ -25,3 +25,14 @@ // Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... }) import '@testing-library/cypress/add-commands' +import { deleteUser, + logInWithEmailAndPassword, + logOut, + signUpWithEmailAndPassword } + from './commands/auth' + + +Cypress.Commands.add('deleteUser', deleteUser) +Cypress.Commands.add('login', logInWithEmailAndPassword) +Cypress.Commands.add('logout', logOut) +Cypress.Commands.add('signup', signUpWithEmailAndPassword) diff --git a/cypress/support/commands/auth.js b/cypress/support/commands/auth.js new file mode 100644 index 000000000..584d199c5 --- /dev/null +++ b/cypress/support/commands/auth.js @@ -0,0 +1,139 @@ +import { initializeApp } from 'firebase/app' +import { + getAuth, + connectAuthEmulator, + deleteUser as deleteUserAuth, + signInWithEmailAndPassword, + signOut, + createUserWithEmailAndPassword, +} from 'firebase/auth' +import { + getFirestore, + connectFirestoreEmulator, + doc, + setDoc, + deleteDoc, +} from 'firebase/firestore' + +const authUser = require('../../fixtures/authUser.json') + +const firebaseConfig = { + apiKey: Cypress.env('VUE_APP_FIREBASE_API_KEY'), + authDomain: Cypress.env('VUE_APP_FIREBASE_AUTH_DOMAIN'), + storageBucket: Cypress.env('VUE_APP_FIREBASE_STORAGE_BUCKET'), + projectId: Cypress.env('VUE_APP_FIREBASE_PROJECT_ID'), + appId: Cypress.env('VUE_APP_FIREBASE_APP_ID'), +} + +const firebaseApp = initializeApp(firebaseConfig) +const auth = getAuth(firebaseApp) +const db = getFirestore(firebaseApp) +if (window.Cypress) { + connectAuthEmulator(auth, 'http://localhost:9099') + connectFirestoreEmulator(db, 'localhost', 8081) +} + +/** + * Delete the currently logged in user + * @returns {Promise} + */ +export const deleteUser = async () => { + try { + if (!auth.currentUser) { + throw new Error('No user is logged in') + } + const { collection } = authUser + const currentUser = auth.currentUser + await deleteDocById(collection, currentUser.uid) + await deleteUserAuth(auth.currentUser) + console.info(`Deleted user with ID "${currentUser.uid}"`) + } catch (err) { + console.error(err) + alert(err.message) + } +} + +/** + * Log in with email and password + * @param email + * @param password + * @returns {Promise} + */ +export const logInWithEmailAndPassword = async (email, password) => { + try { + await signInWithEmailAndPassword(auth, email, password).then(() => { + console.info(`Logged in as "${email}"`) + }) + } catch (err) { + console.error(err) + alert(err.message) + } +} + +/** + * Log out the currently logged in user + * @returns {Promise} + */ +export const logOut = async () => { + try { + await signOut(auth).then(() => { + console.info('Logged out') + }) + } catch (err) { + console.error(err) + alert(err.message) + } +} + +/** + * Sign up with email and password + * @param email + * @param password + * @returns {Promise} + */ +export const signUpWithEmailAndPassword = async (email, password) => { + try { + const { user } = await createUserWithEmailAndPassword(auth, email, password) + console.info(`Signed up as "${email}" with user ID "${user.uid}"`) + const { data, collection } = authUser + await createDoc(collection, user.uid, data) + } catch (err) { + console.error(err) + alert(err.message) + } +} + +/** + * Create a document in a collection + * @param col + * @param docId + * @param data + * @returns {Promise} + */ +export const createDoc = async (col, docId, data) => { + try { + const ref = doc(db, `${col}/${docId}`) + await setDoc(ref, data) + } catch (err) { + console.error(err) + alert(err.message) + } +} + +/** + * Delete a document by ID + * @param col + * @param docId + * @returns {Promise} + */ +export const deleteDocById = async (col, docId) => { + try { + const ref = doc(db, `${col}/${docId}`) + await deleteDoc(ref) + } catch (err) { + console.error(err) + alert(err.message) + } +} + + From 15552d03ce10bb0939c66222cb98ddb02381f31b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Beltra=CC=81n?= Date: Sat, 4 May 2024 16:10:58 +0200 Subject: [PATCH 05/47] e2e auth tests --- cypress.config.js | 2 + cypress/e2e/auth.spec.cy.js | 67 ++++++++++++++++++++++++++++++++ cypress/fixtures/authUser.json | 1 + cypress/support/commands/auth.js | 13 +++---- 4 files changed, 75 insertions(+), 8 deletions(-) create mode 100644 cypress/e2e/auth.spec.cy.js diff --git a/cypress.config.js b/cypress.config.js index 54c7ff143..9313118a5 100644 --- a/cypress.config.js +++ b/cypress.config.js @@ -2,6 +2,7 @@ const { defineConfig } = require('cypress') require('dotenv').config() module.exports = defineConfig({ + projectId: 'xmf2jf', e2e: { setupNodeEvents(on, config) { // implement node event listeners here @@ -10,5 +11,6 @@ module.exports = defineConfig({ env: { // add environment variables here ...process.env, + url: 'http://localhost:8080', }, }) diff --git a/cypress/e2e/auth.spec.cy.js b/cypress/e2e/auth.spec.cy.js new file mode 100644 index 000000000..8bcb31f60 --- /dev/null +++ b/cypress/e2e/auth.spec.cy.js @@ -0,0 +1,67 @@ +const authUser = require('../fixtures/authUser.json') +const url = Cypress.env('url') + +describe('Authentication Suite', () => { + describe('Registration', () => { + it('should allow a new user to register', () => { + cy.visit(url + '/signup') + const { email, password } = authUser + cy.get('form').findByLabelText(/e-mail/i).type(email) + cy.get('form').findByLabelText("Password").type(password) + cy.get('form').findByLabelText("Confirm your password").type(password) + cy.findByRole('button', {name: 'Sign-up'}).click() + cy.wait(500) + cy.contains(email) + cy.deleteUser(email, password) + }) + it('should reject registration with invalid password', () => { + cy.visit(url + '/signup') + const { email, invalidPassword } = authUser + cy.get('form').findByLabelText(/e-mail/i).type(email) + cy.get('form').findByLabelText("Password").type(invalidPassword) + cy.get('form').findByLabelText("Confirm your password").type(invalidPassword) + cy.findByRole('button', {name: 'Sign-up'}).click() + cy.contains('Password must be at least 6 characters') + }) + it('should reject registration when passwords do not match', () => { + cy.visit(url + '/signup') + const { email, password, invalidPassword } = authUser + cy.get('form').findByLabelText(/e-mail/i).type(email) + cy.get('form').findByLabelText("Password").type(password) + cy.get('form').findByLabelText("Confirm your password").type(invalidPassword) + cy.findByRole('button', {name: 'Sign-up'}).click() + cy.contains('Different passwords') + }) + }) + describe('Login', () => { + const { email, password } = authUser + beforeEach(() => { + cy.signup(email, password) + cy.logout() + cy.visit(url + '/signin') + }) + afterEach(() => { + cy.deleteUser(email, password) + }) + it('should allow a registered user to login', () => { + cy.get('form').findByLabelText(/e-mail/i).type(email) + cy.get('form').findByLabelText('Password').type(password) + cy.findByTestId('sign-in-button').click() + cy.wait(500) + cy.contains(email) + }) + it('should reject login with incorrect password', () => { + const { email, password, invalidPassword } = authUser + cy.get('form').findByLabelText(/e-mail/i).type(email) + cy.get('form').findByLabelText('Password').type(invalidPassword) + cy.findByTestId('sign-in-button').click() + cy.contains('Incorrect password') + }) + it('should reject login with unregistered email', () => { + cy.get('form').findByLabelText(/e-mail/i).type('noexist@noexist.com') + cy.get('form').findByLabelText('Password').type('noexist') + cy.findByTestId('sign-in-button').click() + cy.contains('Incorrect username or password') + }) + }) +}) diff --git a/cypress/fixtures/authUser.json b/cypress/fixtures/authUser.json index 8f766a6cd..23f9dcd43 100644 --- a/cypress/fixtures/authUser.json +++ b/cypress/fixtures/authUser.json @@ -1,6 +1,7 @@ { "email": "ruxailab@ruxailab.com", "password": "ruxailab1234", + "invalidPassword": "123", "data": { "accessLevel": 1, "email" : "ruxailab@ruxailab.com", diff --git a/cypress/support/commands/auth.js b/cypress/support/commands/auth.js index 584d199c5..26cf34e7b 100644 --- a/cypress/support/commands/auth.js +++ b/cypress/support/commands/auth.js @@ -37,16 +37,13 @@ if (window.Cypress) { * Delete the currently logged in user * @returns {Promise} */ -export const deleteUser = async () => { +export const deleteUser = async (email, password) => { try { - if (!auth.currentUser) { - throw new Error('No user is logged in') - } + const { user } = await signInWithEmailAndPassword(auth, email, password) const { collection } = authUser - const currentUser = auth.currentUser - await deleteDocById(collection, currentUser.uid) - await deleteUserAuth(auth.currentUser) - console.info(`Deleted user with ID "${currentUser.uid}"`) + await deleteDocById(collection, user.uid) + await deleteUserAuth(user) + console.info(`Deleted user with ID "${user.uid}"`) } catch (err) { console.error(err) alert(err.message) From bf6f07f9a3bdc8f717b76ad12cda1eb607ad639e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Beltra=CC=81n?= Date: Sat, 4 May 2024 17:13:30 +0200 Subject: [PATCH 06/47] data-testid in sign in button --- src/views/public/SignInView.vue | 1 + 1 file changed, 1 insertion(+) diff --git a/src/views/public/SignInView.vue b/src/views/public/SignInView.vue index 755ee78b0..be588e37f 100644 --- a/src/views/public/SignInView.vue +++ b/src/views/public/SignInView.vue @@ -34,6 +34,7 @@ Date: Sat, 4 May 2024 18:31:23 +0200 Subject: [PATCH 07/47] remove alerts form auth command --- cypress/support/commands/auth.js | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/cypress/support/commands/auth.js b/cypress/support/commands/auth.js index 26cf34e7b..f34db04b3 100644 --- a/cypress/support/commands/auth.js +++ b/cypress/support/commands/auth.js @@ -34,7 +34,7 @@ if (window.Cypress) { } /** - * Delete the currently logged in user + * Delete the currently logged-in user * @returns {Promise} */ export const deleteUser = async (email, password) => { @@ -46,7 +46,6 @@ export const deleteUser = async (email, password) => { console.info(`Deleted user with ID "${user.uid}"`) } catch (err) { console.error(err) - alert(err.message) } } @@ -63,12 +62,11 @@ export const logInWithEmailAndPassword = async (email, password) => { }) } catch (err) { console.error(err) - alert(err.message) } } /** - * Log out the currently logged in user + * Log out the currently logged-in user * @returns {Promise} */ export const logOut = async () => { @@ -78,7 +76,6 @@ export const logOut = async () => { }) } catch (err) { console.error(err) - alert(err.message) } } @@ -96,7 +93,6 @@ export const signUpWithEmailAndPassword = async (email, password) => { await createDoc(collection, user.uid, data) } catch (err) { console.error(err) - alert(err.message) } } @@ -113,7 +109,6 @@ export const createDoc = async (col, docId, data) => { await setDoc(ref, data) } catch (err) { console.error(err) - alert(err.message) } } @@ -129,7 +124,6 @@ export const deleteDocById = async (col, docId) => { await deleteDoc(ref) } catch (err) { console.error(err) - alert(err.message) } } From aeb89a57298ffca56c42034f38eec06857b74aeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Beltra=CC=81n?= Date: Sat, 4 May 2024 18:35:34 +0200 Subject: [PATCH 08/47] heuristic create test --- cypress/e2e/heuristic.spec.cy.js | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 cypress/e2e/heuristic.spec.cy.js diff --git a/cypress/e2e/heuristic.spec.cy.js b/cypress/e2e/heuristic.spec.cy.js new file mode 100644 index 000000000..a922e18d7 --- /dev/null +++ b/cypress/e2e/heuristic.spec.cy.js @@ -0,0 +1,31 @@ +const heuristic = require('../fixtures/heuristic.json') +const authUser = require('../fixtures/authUser.json') + +const url = Cypress.env('url') +const { email, password } = authUser + +describe('Heuristic test Suite', () => { + before('Signup into the app', () => { + cy.deleteUser(email, password) + cy.signup(email, password) + cy.login(email, password) + }) + after('Remove user', () => { + cy.deleteUser(email, password) + }) + describe('Create Heuristic Test', () => { + it('should allow a new test to create', () => { + cy.visit(url + '/testslist') + cy.findByTestId('create-test-btn').click() + cy.findByText('Create a blank test').click() + cy.findByText('Usability Heuristic').click() + + const { name, description } = heuristic + cy.findByLabelText(/Test name/i).type(name) + cy.findByLabelText(/Test Description/i).type(description) + cy.findByTestId('add-name-test-creation-btn').click() + + cy.contains(/Manager/i) + }) + }) +}) From 882ecf730ef94d0d342a610cb4c9f6062d6d3a6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Beltra=CC=81n?= Date: Sat, 4 May 2024 18:35:41 +0200 Subject: [PATCH 09/47] heuristic create test --- cypress/fixtures/heuristic.json | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 cypress/fixtures/heuristic.json diff --git a/cypress/fixtures/heuristic.json b/cypress/fixtures/heuristic.json new file mode 100644 index 000000000..93fa06e05 --- /dev/null +++ b/cypress/fixtures/heuristic.json @@ -0,0 +1,4 @@ +{ + "name": "Heuristic Test", + "description": "This is a test of the heuristic test" +} From f306a603ba732620aef20fe87488d73216fcb1d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Beltra=CC=81n?= Date: Sat, 4 May 2024 18:35:58 +0200 Subject: [PATCH 10/47] add data-testid in components --- src/views/admin/CreateBlankView.vue | 1 + src/views/admin/DashboardView.vue | 1 + 2 files changed, 2 insertions(+) diff --git a/src/views/admin/CreateBlankView.vue b/src/views/admin/CreateBlankView.vue index bc0eb651b..fe1c861f9 100644 --- a/src/views/admin/CreateBlankView.vue +++ b/src/views/admin/CreateBlankView.vue @@ -169,6 +169,7 @@ color="orange" class="ml-auto mt-4 mr-2 circleOrange" @click="validate()" + data-testid="add-name-test-creation-btn" > mdi-arrow-right diff --git a/src/views/admin/DashboardView.vue b/src/views/admin/DashboardView.vue index 50ae7efe8..4d7a4d7c5 100644 --- a/src/views/admin/DashboardView.vue +++ b/src/views/admin/DashboardView.vue @@ -16,6 +16,7 @@ v-bind="attrs" @click="goToCreateTestRoute()" v-on="on" + data-testid="create-test-btn" > mdi-plus From b699d0113101e0ed70e610920c7f3efdb953f566 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Beltra=CC=81n?= Date: Sat, 4 May 2024 18:36:40 +0200 Subject: [PATCH 11/47] update package.json --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 495a8e64e..308bdee61 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,7 @@ }, "devDependencies": { "@intlify/vue-i18n-loader": "^1.1.0", + "@testing-library/cypress": "^10.0.1", "@testing-library/dom": "^9.0.0", "@testing-library/jest-dom": "^5.16.5", "@testing-library/user-event": "12", @@ -60,7 +61,7 @@ "@vue/test-utils": "^1.3.0", "babel-eslint": "^8.2.6", "babel-plugin-transform-require-context": "^0.1.1", - "cypress": "^13.7.3", + "cypress": "^13.8.1", "eslint": "^6.7.2", "eslint-plugin-vue": "^6.2.2", "jsdoc": "^3.6.11", From 707aaa444a6b131d0cdeb25b879380e56e8787e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Beltra=CC=81n?= Date: Thu, 9 May 2024 20:05:15 +0200 Subject: [PATCH 12/47] include data-testid in button to create heruistic test --- src/views/admin/CreateBlankView.vue | 1 + 1 file changed, 1 insertion(+) diff --git a/src/views/admin/CreateBlankView.vue b/src/views/admin/CreateBlankView.vue index 4f88c7762..33dac776f 100644 --- a/src/views/admin/CreateBlankView.vue +++ b/src/views/admin/CreateBlankView.vue @@ -169,6 +169,7 @@ color="orange" class="ml-auto mr-2 circleOrange" @click="validate()" + data-testid="add-name-test-creation-btn" > mdi-arrow-right From 873d4323c4be87832cbf4010aad26745c8b19b7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Beltra=CC=81n?= Date: Thu, 9 May 2024 20:36:23 +0200 Subject: [PATCH 13/47] send message in pull request when test failed --- .github/workflows/test.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 139a9a57d..a827d7695 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -26,3 +26,10 @@ jobs: - name: Test run: npm test + + - name: Comment to PR + if: failure() && github.event_name == 'pull_request' + uses: thollander/actions-comment-pull-request@v1 + with: + message: "⚠️ Los tests han fallado. Por favor, revisa los cambios propuestos." + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From a9c2a3d3e3f1550934311e3ed3a713e0c5c50490 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Beltra=CC=81n?= Date: Thu, 9 May 2024 20:38:15 +0200 Subject: [PATCH 14/47] send message in pull request when test failed --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a827d7695..dae425f4b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -29,7 +29,7 @@ jobs: - name: Comment to PR if: failure() && github.event_name == 'pull_request' - uses: thollander/actions-comment-pull-request@v1 + uses: thollander/actions-comment-pull-request@v2 with: message: "⚠️ Los tests han fallado. Por favor, revisa los cambios propuestos." GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From eff76175814699adefed0f975dce6f0e420e577a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Beltra=CC=81n?= Date: Thu, 9 May 2024 20:46:03 +0200 Subject: [PATCH 15/47] brake test --- tests/unit/SignIn.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/SignIn.spec.js b/tests/unit/SignIn.spec.js index b27526271..d5142e605 100644 --- a/tests/unit/SignIn.spec.js +++ b/tests/unit/SignIn.spec.js @@ -10,7 +10,7 @@ describe('SignIn', () => { it('should display email input', async () => { render(SignInView) - expect(screen.getByLabelText(/E-mail/i, { selector: 'input' })).toBeInTheDocument() + expect(screen.getByLabelText(/E-mailxxxxx/i, { selector: 'input' })).toBeInTheDocument() }) it('should display password input', async () => { render(SignInView) From 28ce3ab09a975a0f0e92d5b3026d6f4d10eecfae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Beltra=CC=81n?= Date: Thu, 9 May 2024 20:50:42 +0200 Subject: [PATCH 16/47] translate to english --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index dae425f4b..6a26de9ea 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -31,5 +31,5 @@ jobs: if: failure() && github.event_name == 'pull_request' uses: thollander/actions-comment-pull-request@v2 with: - message: "⚠️ Los tests han fallado. Por favor, revisa los cambios propuestos." + message: "⚠️ The tests have failed. Please review the proposed changes." GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From b10e0dee697e946da19e679853b302873a16d70a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Beltra=CC=81n?= Date: Thu, 9 May 2024 20:52:55 +0200 Subject: [PATCH 17/47] include autor in the message --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6a26de9ea..1fef190cd 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -31,5 +31,5 @@ jobs: if: failure() && github.event_name == 'pull_request' uses: thollander/actions-comment-pull-request@v2 with: - message: "⚠️ The tests have failed. Please review the proposed changes." + message: "⚠️ The tests have failed, @${{ github.actor }}. Please review the proposed changes." GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 3e2e99bfa4df936eb4499c5f051b9723f138dfb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Beltra=CC=81n?= Date: Sun, 19 May 2024 11:35:30 +0200 Subject: [PATCH 18/47] include discord message --- .github/workflows/test.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1fef190cd..3132ad27d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -31,5 +31,13 @@ jobs: if: failure() && github.event_name == 'pull_request' uses: thollander/actions-comment-pull-request@v2 with: - message: "⚠️ The tests have failed, @${{ github.actor }}. Please review the proposed changes." + message: "⚠️ The tests have failed, @${{ github.actor }} Please review the proposed changes." GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Send message to Discord + env: + DISCORD_WEBHOOK: 'https://discord.com/api/webhooks/1241683835067039784/1UkTaSTdthDJdYq_GSZRjAbCE8jLM0jMS6qvhYt8FuuuB6H1XGIYKzwfzQ7G-YImJTYE' + if: failure() && github.event_name == 'pull_request' + uses: Ilshidur/action-discord@master + with: + args: "⚠️ The github event ${{ github.event_name }} has failed. Please review the proposed changes." From 846be269ca667c14bde2a3c9bdb179ce5db942c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Beltra=CC=81n?= Date: Sun, 19 May 2024 11:39:32 +0200 Subject: [PATCH 19/47] include more info discord message --- .github/workflows/test.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3132ad27d..c039071b7 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -40,4 +40,12 @@ jobs: if: failure() && github.event_name == 'pull_request' uses: Ilshidur/action-discord@master with: - args: "⚠️ The github event ${{ github.event_name }} has failed. Please review the proposed changes." + args: | + ⚠️ The GitHub event `${{ github.event_name }}` has failed. + Repository: `${{ github.repository }}` + Workflow: `${{ github.workflow }}` + Job: `${{ github.job }}` + Commit: `${{ github.sha }}` + Actor: `${{ github.actor }}` + Pull Request: `${{ github.event.pull_request.html_url }}` + Please review the proposed changes. From ea8962eca7f3893212235e6f4218889cd5640298 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Beltra=CC=81n?= Date: Sun, 19 May 2024 11:44:10 +0200 Subject: [PATCH 20/47] include more info discord message --- .github/workflows/test.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c039071b7..1a4d38a90 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -42,10 +42,10 @@ jobs: with: args: | ⚠️ The GitHub event `${{ github.event_name }}` has failed. - Repository: `${{ github.repository }}` - Workflow: `${{ github.workflow }}` - Job: `${{ github.job }}` - Commit: `${{ github.sha }}` - Actor: `${{ github.actor }}` - Pull Request: `${{ github.event.pull_request.html_url }}` + **Repository**: `${{ github.repository }}` + **Workflow**: `${{ github.workflow }}` + **Actor**: `${{ github.actor }}` + **Pull Request**: [Link](${{ github.event.pull_request.html_url }}) + **Action URL**: [View Details](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}) Please review the proposed changes. + From 71ac02c6c9d1fc25f8b2416298ffa4cb5133db40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Beltra=CC=81n?= Date: Sun, 19 May 2024 11:47:44 +0200 Subject: [PATCH 21/47] include secret in discord --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1a4d38a90..b129af05f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -36,7 +36,7 @@ jobs: - name: Send message to Discord env: - DISCORD_WEBHOOK: 'https://discord.com/api/webhooks/1241683835067039784/1UkTaSTdthDJdYq_GSZRjAbCE8jLM0jMS6qvhYt8FuuuB6H1XGIYKzwfzQ7G-YImJTYE' + DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }} if: failure() && github.event_name == 'pull_request' uses: Ilshidur/action-discord@master with: From 45e755534e706744585a4cfcfcb29dd63affb1e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Beltra=CC=81n?= Date: Sun, 19 May 2024 11:48:32 +0200 Subject: [PATCH 22/47] repair test --- tests/unit/SignIn.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/SignIn.spec.js b/tests/unit/SignIn.spec.js index d5142e605..b27526271 100644 --- a/tests/unit/SignIn.spec.js +++ b/tests/unit/SignIn.spec.js @@ -10,7 +10,7 @@ describe('SignIn', () => { it('should display email input', async () => { render(SignInView) - expect(screen.getByLabelText(/E-mailxxxxx/i, { selector: 'input' })).toBeInTheDocument() + expect(screen.getByLabelText(/E-mail/i, { selector: 'input' })).toBeInTheDocument() }) it('should display password input', async () => { render(SignInView) From 050a660f641a3df8e01442ceacc0de4ae885148d Mon Sep 17 00:00:00 2001 From: zlatanjakic Date: Fri, 19 Apr 2024 21:32:01 +0200 Subject: [PATCH 23/47] Added the script for tools and workflow --- .github/workflows/ishikawaTools.yaml | 30 +++++ ishikawasTools.py | 162 +++++++++++++++++++++++++++ 2 files changed, 192 insertions(+) create mode 100644 .github/workflows/ishikawaTools.yaml create mode 100644 ishikawasTools.py diff --git a/.github/workflows/ishikawaTools.yaml b/.github/workflows/ishikawaTools.yaml new file mode 100644 index 000000000..4186eb6cd --- /dev/null +++ b/.github/workflows/ishikawaTools.yaml @@ -0,0 +1,30 @@ +name: Generate Reports + +on: + push: + branches: + - develop + +jobs: + generate-reports: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: '3.10.x' + + - name: Install dependencies + run: | + pip install matplotlib pandas requests PyGithub + + - name: Run report generation script + env: + TOKEN: ${{ secrets.TOKEN }} + USER: ${{ secrets.USER }} + PROJECT: ${{ secrets.PROJECT }} + run: python scripts.py diff --git a/ishikawasTools.py b/ishikawasTools.py new file mode 100644 index 000000000..bf028faa5 --- /dev/null +++ b/ishikawasTools.py @@ -0,0 +1,162 @@ +import os +import pandas as pd +from datetime import datetime, timedelta +from github import Github +import matplotlib.pyplot as plt +import requests +from textwrap import wrap + + +def fetch_issues(repo_owner, repo_name, github_token): + url = f"https://api.github.com/repos/{repo_owner}/{repo_name}/issues" + headers = {'Authorization': f'token {github_token}'} + response = requests.get(url, headers=headers) + if response.status_code != 200: + print(f"Failed to fetch issues. Status code: {response.status_code}") + print(response.text) + return None + else: + issues = response.json() + return issues + + +def generate_pareto_diagram(issues): + labels_count = {} + for issue in issues: + for label in issue['labels']: + label_name = label['name'] + labels_count[label_name] = labels_count.get(label_name, 0) + 1 + + sorted_labels_count = dict(sorted(labels_count.items(), key=lambda item: item[1], reverse=True)) + + labels = list(sorted_labels_count.keys()) + counts = list(sorted_labels_count.values()) + + total_issues = sum(counts) + cumulative_percentage = [sum(counts[:i + 1]) / total_issues * 100 for i in range(len(counts))] + + _, ax1 = plt.subplots() + ax1.bar(labels, counts, color='b') + ax1.set_xlabel('Labels', fontsize=12) + ax1.set_ylabel('Frequency', color='b', fontsize=12) + ax1.tick_params(axis='y', colors='b') + + ax2 = ax1.twinx() + ax2.plot(labels, cumulative_percentage, color='r', marker='o') + ax2.set_ylabel('Cumulative Percentage (%)', color='r', fontsize=12) + ax2.tick_params(axis='y', colors='r') + + plt.title('Pareto Diagram of Issues by Labels - General Report', fontsize=14) + plt.xticks(rotation=45, ha='right', fontsize=8) + ax1.set_xticklabels(['\n'.join(wrap(label, 13)) for label in labels]) + plt.tight_layout() + plt.show() + + +def generate_weekly_report(github_token, username, repository_name): + g = Github(github_token) + repo = g.get_repo(f"{username}/{repository_name}") + issues = repo.get_issues(state='all') + weekly_counts = {'Monday': {'opened': 0, 'closed': 0}, 'Tuesday': {'opened': 0, 'closed': 0}, + 'Wednesday': {'opened': 0, 'closed': 0}, 'Thursday': {'opened': 0, 'closed': 0}, + 'Friday': {'opened': 0, 'closed': 0}, 'Saturday': {'opened': 0, 'closed': 0}, + 'Sunday': {'opened': 0, 'closed': 0}} + + def get_day_of_week(date_str): + date = datetime.strptime(date_str[:10], '%Y-%m-%d') + return date.strftime('%A') + + current_date = datetime.now() + one_week_ago = current_date - timedelta(days=7) + for issue in issues: + created_at = issue.created_at.replace(tzinfo=None) + if created_at >= one_week_ago: + day_of_week = get_day_of_week(str(created_at)) + weekly_counts[day_of_week]['opened'] += 1 + if issue.closed_at: + closed_at = issue.closed_at.replace(tzinfo=None) + if closed_at >= one_week_ago: + day_of_week = get_day_of_week(str(closed_at)) + weekly_counts[day_of_week]['closed'] += 1 + + +def generate_histogram_report(repo_owner, repo_name, github_token): + url = f"https://api.github.com/repos/{repo_owner}/{repo_name}/issues" + headers = {'Authorization': f'token {github_token}'} + response = requests.get(url, headers=headers) + if response.status_code != 200: + print(f"Failed to fetch issues. Status code: {response.status_code}") + print(response.text) + return None + else: + issues = response.json() + + labels_count = { + "back-end": 0, + "bug": 0, + "database": 0, + "documentation": 0, + "front-end": 0, + "tests": 0, + "wontfix": 0, + } + + for issue in issues: + for label in issue['labels']: + label_name = label['name'] + if label_name in labels_count: + labels_count[label_name] += 1 + + plt.figure(figsize=(10, 6)) + plt.bar(labels_count.keys(), labels_count.values()) + plt.ylabel('Number of Issues') + plt.title('Histogram of Issues by Label - General Report') + plt.xticks(rotation=20) + plt.yticks(range(0, max(labels_count.values()) + 1)) + plt.show() + + +def generate_scatter_diagram_report(repo_owner, repo_name, github_token): + url = f"https://api.github.com/repos/{repo_owner}/{repo_name}/issues" + headers = {'Authorization': f'token {github_token}'} + response = requests.get(url, headers=headers) + if response.status_code != 200: + print(f"Failed to fetch issues. Status code: {response.status_code}") + print(response.text) + return None + else: + issues = response.json() + + days_to_close = [] + issue_created_dates = [] + + for issue in issues: + created_at = datetime.strptime(issue['created_at'], '%Y-%m-%dT%H:%M:%SZ') + closed_at = datetime.strptime(issue['closed_at'], '%Y-%m-%dT%H:%M:%SZ') if issue[ + 'closed_at'] else datetime.now() + time_to_close = (closed_at - created_at).days + days_to_close.append(time_to_close) + issue_created_dates.append(created_at) + + plt.figure(figsize=(10, 6)) + plt.scatter(days_to_close, issue_created_dates, color='blue', alpha=0.7) + plt.xlabel('Days for closing the issue') + plt.ylabel('Date of creation of the issue') + plt.title('Scatter Diagram of closed issues') + plt.grid(True) + plt.show() + + +def main(): + github_token = os.getenv('TOKEN') + username = os.getenv('USER') + repository_name = os.getenv('PROJECT') + generate_weekly_report(github_token, username, repository_name) + issues = fetch_issues(username, repository_name, github_token) + generate_pareto_diagram(issues) + generate_histogram_report(username, repository_name, github_token) + generate_scatter_diagram_report(username, repository_name, github_token) + + +if __name__ == "__main__": + main() \ No newline at end of file From 71b70ea84de01937c9f505c31f5435843553333a Mon Sep 17 00:00:00 2001 From: zlatanjakic Date: Fri, 19 Apr 2024 21:34:45 +0200 Subject: [PATCH 24/47] Removed the workflow file and will add it using the github ui --- .github/workflows/ishikawaTools.yaml | 30 ---------------------------- 1 file changed, 30 deletions(-) delete mode 100644 .github/workflows/ishikawaTools.yaml diff --git a/.github/workflows/ishikawaTools.yaml b/.github/workflows/ishikawaTools.yaml deleted file mode 100644 index 4186eb6cd..000000000 --- a/.github/workflows/ishikawaTools.yaml +++ /dev/null @@ -1,30 +0,0 @@ -name: Generate Reports - -on: - push: - branches: - - develop - -jobs: - generate-reports: - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v2 - - - name: Set up Python - uses: actions/setup-python@v2 - with: - python-version: '3.10.x' - - - name: Install dependencies - run: | - pip install matplotlib pandas requests PyGithub - - - name: Run report generation script - env: - TOKEN: ${{ secrets.TOKEN }} - USER: ${{ secrets.USER }} - PROJECT: ${{ secrets.PROJECT }} - run: python scripts.py From 4e8bd78fb0147fdb6f87b863a13fdbf40350890d Mon Sep 17 00:00:00 2001 From: Zlatanius <50078303+Zlatanius@users.noreply.github.com> Date: Fri, 19 Apr 2024 21:54:16 +0200 Subject: [PATCH 25/47] Create ishikawas.yml --- .github/workflows/ishikawas.yml | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 .github/workflows/ishikawas.yml diff --git a/.github/workflows/ishikawas.yml b/.github/workflows/ishikawas.yml new file mode 100644 index 000000000..50f63627f --- /dev/null +++ b/.github/workflows/ishikawas.yml @@ -0,0 +1,32 @@ +name: Generate Reports + +on: + push: + branches: + - develop + schedule: + - cron: '0 0 * * *' # Run daily at midnight + +jobs: + generate-reports: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: '3.10.x' + + - name: Install dependencies + run: | + pip install matplotlib pandas requests PyGithub + + - name: Run report generation script + env: + TOKEN: ${{ secrets.TOKEN }} + USER: ${{ secrets.USER }} + PROJECT: ${{ secrets.PROJECT }} + run: python scripts.py From dc5b74acb55e3d8aae2f44d4995a09a050415c92 Mon Sep 17 00:00:00 2001 From: zlatanjakic Date: Tue, 28 May 2024 16:36:12 +0200 Subject: [PATCH 26/47] Added the workflow file and scripts for generation of ishikawa tools diagrams --- .github/workflows/ishikawa-tools.yml | 35 ++++ ishikawa_tools/ishikawa_tools_script.py | 209 ++++++++++++++++++++++++ 2 files changed, 244 insertions(+) create mode 100644 .github/workflows/ishikawa-tools.yml create mode 100644 ishikawa_tools/ishikawa_tools_script.py diff --git a/.github/workflows/ishikawa-tools.yml b/.github/workflows/ishikawa-tools.yml new file mode 100644 index 000000000..7d62783ef --- /dev/null +++ b/.github/workflows/ishikawa-tools.yml @@ -0,0 +1,35 @@ +name: Generate Reports + +on: + push: + branches: + - ishikawas-tools + +jobs: + generate-reports: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: '3.10.x' + + - name: Install dependencies + run: | + pip install matplotlib pandas requests PyGithub + + - name: Run report generation script + env: + TOKEN: ${{ secrets.TOKEN }} + USER: ${{ secrets.USER }} + PROJECT: ${{ secrets.PROJECT }} + run: python ishikawa_tools/ishikawa_tools_script.py + - uses: actions/upload-artifact@v4 + with: + name: ishikawa-screenshots + path: ./ishikawa_tools/output + retention-days: 30 diff --git a/ishikawa_tools/ishikawa_tools_script.py b/ishikawa_tools/ishikawa_tools_script.py new file mode 100644 index 000000000..42798df0d --- /dev/null +++ b/ishikawa_tools/ishikawa_tools_script.py @@ -0,0 +1,209 @@ +import os +import pandas as pd +from datetime import datetime, timedelta +from github import Github +import matplotlib.pyplot as plt +import requests +from textwrap import wrap +from pathlib import Path + + +def fetch_issues(repo_owner, repo_name, github_token): + url = f"https://api.github.com/repos/{repo_owner}/{repo_name}/issues" + headers = {'Authorization': f'token {github_token}'} + response = requests.get(url, headers=headers) + if response.status_code != 200: + print(f"Failed to fetch issues. Status code: {response.status_code}") + print(response.text) + return None + else: + issues = response.json() + return issues + + +def generate_pareto_diagram(issues): + labels_count = {} + for issue in issues: + for label in issue['labels']: + label_name = label['name'] + labels_count[label_name] = labels_count.get(label_name, 0) + 1 + + sorted_labels_count = dict(sorted(labels_count.items(), key=lambda item: item[1], reverse=True)) + + labels = list(sorted_labels_count.keys()) + counts = list(sorted_labels_count.values()) + + total_issues = sum(counts) + cumulative_percentage = [sum(counts[:i + 1]) / total_issues * 100 for i in range(len(counts))] + + _, ax1 = plt.subplots() + ax1.bar(labels, counts, color='b') + ax1.set_xlabel('Labels', fontsize=12) + ax1.set_ylabel('Frequency', color='b', fontsize=12) + ax1.tick_params(axis='y', colors='b') + + ax2 = ax1.twinx() + ax2.plot(labels, cumulative_percentage, color='r', marker='o') + ax2.set_ylabel('Cumulative Percentage (%)', color='r', fontsize=12) + ax2.tick_params(axis='y', colors='r') + + plt.title('Pareto Diagram of Issues by Labels - General Report', fontsize=14) + plt.xticks(rotation=45, ha='right', fontsize=8) + ax1.set_xticklabels(['\n'.join(wrap(label, 13)) for label in labels]) + plt.tight_layout() + plt.savefig('./ishikawa_tools/output/pereto.pdf') + + +def generate_weekly_report(github_token, username, repository_name): + # Crear una instancia de la clase Github + g = Github(github_token) + + # Obtener el repositorio + repo = g.get_repo(f"{username}/{repository_name}") + + # Obtener todas las issues del repositorio + issues = repo.get_issues(state='all') + + # Diccionario para almacenar el recuento de issues por día de la semana + weekly_counts = { + 'Monday': {'opened': 0, 'closed': 0}, + 'Tuesday': {'opened': 0, 'closed': 0}, + 'Wednesday': {'opened': 0, 'closed': 0}, + 'Thursday': {'opened': 0, 'closed': 0}, + 'Friday': {'opened': 0, 'closed': 0}, + 'Saturday': {'opened': 0, 'closed': 0}, + 'Sunday': {'opened': 0, 'closed': 0} + } + + def get_day_of_week(date_str): + date = datetime.strptime(date_str[:10], '%Y-%m-%d') + return date.strftime('%A') + + current_date = datetime.now() + one_week_ago = current_date - timedelta(days=7) + + for issue in issues: + created_at = issue.created_at.replace(tzinfo=None) + if created_at >= one_week_ago: + day_of_week = get_day_of_week(str(created_at)) + weekly_counts[day_of_week]['opened'] += 1 + + if issue.closed_at: + closed_at = issue.closed_at.replace(tzinfo=None) + if closed_at >= one_week_ago: + day_of_week = get_day_of_week(str(closed_at)) + weekly_counts[day_of_week]['closed'] += 1 + + # Extraer los datos para la tabla + dias = list(weekly_counts.keys()) + abiertas = [weekly_counts[d]["opened"] for d in weekly_counts] + cerradas = [weekly_counts[d]["closed"] for d in weekly_counts] + + data = { + "Día de la Semana": dias, + "Abiertas": abiertas, + "Cerradas": cerradas + } + + # Crear la tabla + df = pd.DataFrame(data) + + # Crear figura y eje + fig, ax = plt.subplots() + + # Eliminar marcas del eje + ax.axis('off') + + # Crear tabla + tabla = ax.table(cellText=df.values, + colLabels=df.columns, + cellLoc='center', + loc='center') + + # Ajustar tamaño de la fuente + tabla.auto_set_font_size(False) + tabla.set_fontsize(12) + + # Ajustar tamaño de la tabla + tabla.scale(1.5, 1.5) + plt.savefig('./ishikawa_tools/output/checklist.pdf') + + +def generate_histogram_report(repo_owner, repo_name, github_token): + url = f"https://api.github.com/repos/{repo_owner}/{repo_name}/issues" + headers = {'Authorization': f'token {github_token}'} + response = requests.get(url, headers=headers) + if response.status_code != 200: + print(f"Failed to fetch issues. Status code: {response.status_code}") + print(response.text) + return None + else: + issues = response.json() + + labels_count = { + } + + for issue in issues: + for label in issue['labels']: + label_name = label['name'] + if label_name in labels_count: + labels_count[label_name] += 1 + else: + labels_count[label_name] = 1 + + plt.figure(figsize=(10, 6)) + plt.bar(labels_count.keys(), labels_count.values()) + plt.ylabel('Number of Issues') + plt.title('Histogram of Issues by Label - General Report') + plt.xticks(rotation=20) + plt.yticks(range(0, max(labels_count.values()) + 1)) + plt.savefig('./ishikawa_tools/output/histogram.pdf') + + +def generate_scatter_diagram_report(repo_owner, repo_name, github_token): + url = f"https://api.github.com/repos/{repo_owner}/{repo_name}/issues" + headers = {'Authorization': f'token {github_token}'} + response = requests.get(url, headers=headers) + if response.status_code != 200: + print(f"Failed to fetch issues. Status code: {response.status_code}") + print(response.text) + return None + else: + issues = response.json() + + days_to_close = [] + issue_created_dates = [] + + for issue in issues: + created_at = datetime.strptime(issue['created_at'], '%Y-%m-%dT%H:%M:%SZ') + closed_at = datetime.strptime(issue['closed_at'], '%Y-%m-%dT%H:%M:%SZ') if issue[ + 'closed_at'] else datetime.now() + time_to_close = (closed_at - created_at).days + days_to_close.append(time_to_close) + issue_created_dates.append(created_at) + + plt.figure(figsize=(10, 6)) + plt.scatter(days_to_close, issue_created_dates, color='blue', alpha=0.7) + plt.xlabel('Days for closing the issue') + plt.ylabel('Date of creation of the issue') + plt.title('Scatter Diagram of closed issues') + plt.grid(True) + plt.savefig('./ishikawa_tools/output/scatter.pdf') + + +def main(): + github_token = os.getenv('TOKEN') + username = os.getenv('USER') + repository_name = os.getenv('PROJECT') + + issues = fetch_issues(username, repository_name, github_token) + Path("./ishikawa_tools/output").mkdir(parents=True, exist_ok=True) + + generate_pareto_diagram(issues) + generate_histogram_report(username, repository_name, github_token) + generate_scatter_diagram_report(username, repository_name, github_token) + generate_weekly_report(github_token, username, repository_name) + + +if __name__ == "__main__": + main() From 21bb83e1d862f9b8d0df6249195a8cfd13434196 Mon Sep 17 00:00:00 2001 From: zlatanjakic Date: Tue, 28 May 2024 16:42:18 +0200 Subject: [PATCH 27/47] Removed old workflow file --- .github/workflows/ishikawas.yml | 32 -------------------------------- 1 file changed, 32 deletions(-) delete mode 100644 .github/workflows/ishikawas.yml diff --git a/.github/workflows/ishikawas.yml b/.github/workflows/ishikawas.yml deleted file mode 100644 index 50f63627f..000000000 --- a/.github/workflows/ishikawas.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: Generate Reports - -on: - push: - branches: - - develop - schedule: - - cron: '0 0 * * *' # Run daily at midnight - -jobs: - generate-reports: - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v2 - - - name: Set up Python - uses: actions/setup-python@v2 - with: - python-version: '3.10.x' - - - name: Install dependencies - run: | - pip install matplotlib pandas requests PyGithub - - - name: Run report generation script - env: - TOKEN: ${{ secrets.TOKEN }} - USER: ${{ secrets.USER }} - PROJECT: ${{ secrets.PROJECT }} - run: python scripts.py From fbe5f18a69beeed19b9fd7d09d8e0f4919260b0b Mon Sep 17 00:00:00 2001 From: zlatanjakic Date: Tue, 28 May 2024 17:13:07 +0200 Subject: [PATCH 28/47] Changed the trigger for ishikawa action to daily and on issue events --- .github/workflows/ishikawa-tools.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ishikawa-tools.yml b/.github/workflows/ishikawa-tools.yml index 7d62783ef..1b4480a7c 100644 --- a/.github/workflows/ishikawa-tools.yml +++ b/.github/workflows/ishikawa-tools.yml @@ -1,9 +1,10 @@ name: Generate Reports on: - push: - branches: - - ishikawas-tools + schedule: + - cron: "0 0 * * *" + issues: + types: [opened, deleted, closed, reopened, labeled] jobs: generate-reports: @@ -32,4 +33,4 @@ jobs: with: name: ishikawa-screenshots path: ./ishikawa_tools/output - retention-days: 30 + retention-days: 1 From cf7072ed671ff1167fc5527741eb310031664183 Mon Sep 17 00:00:00 2001 From: zlatanjakic Date: Tue, 28 May 2024 17:33:16 +0200 Subject: [PATCH 29/47] Changed the ishikawa action from using a personal access token to using the default GITHUB_TOKEN --- .github/workflows/ishikawa-tools.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ishikawa-tools.yml b/.github/workflows/ishikawa-tools.yml index 1b4480a7c..b696ad5f1 100644 --- a/.github/workflows/ishikawa-tools.yml +++ b/.github/workflows/ishikawa-tools.yml @@ -25,7 +25,7 @@ jobs: - name: Run report generation script env: - TOKEN: ${{ secrets.TOKEN }} + TOKEN: ${{ secrets.GITHUB_TOKEN }} USER: ${{ secrets.USER }} PROJECT: ${{ secrets.PROJECT }} run: python ishikawa_tools/ishikawa_tools_script.py From f86dcf5212ec13b8219aad9395d2d428ee94f5ba Mon Sep 17 00:00:00 2001 From: zlatanjakic Date: Tue, 28 May 2024 17:38:37 +0200 Subject: [PATCH 30/47] Removed the old ishikawa scripts file --- ishikawasTools.py | 162 ---------------------------------------------- 1 file changed, 162 deletions(-) delete mode 100644 ishikawasTools.py diff --git a/ishikawasTools.py b/ishikawasTools.py deleted file mode 100644 index bf028faa5..000000000 --- a/ishikawasTools.py +++ /dev/null @@ -1,162 +0,0 @@ -import os -import pandas as pd -from datetime import datetime, timedelta -from github import Github -import matplotlib.pyplot as plt -import requests -from textwrap import wrap - - -def fetch_issues(repo_owner, repo_name, github_token): - url = f"https://api.github.com/repos/{repo_owner}/{repo_name}/issues" - headers = {'Authorization': f'token {github_token}'} - response = requests.get(url, headers=headers) - if response.status_code != 200: - print(f"Failed to fetch issues. Status code: {response.status_code}") - print(response.text) - return None - else: - issues = response.json() - return issues - - -def generate_pareto_diagram(issues): - labels_count = {} - for issue in issues: - for label in issue['labels']: - label_name = label['name'] - labels_count[label_name] = labels_count.get(label_name, 0) + 1 - - sorted_labels_count = dict(sorted(labels_count.items(), key=lambda item: item[1], reverse=True)) - - labels = list(sorted_labels_count.keys()) - counts = list(sorted_labels_count.values()) - - total_issues = sum(counts) - cumulative_percentage = [sum(counts[:i + 1]) / total_issues * 100 for i in range(len(counts))] - - _, ax1 = plt.subplots() - ax1.bar(labels, counts, color='b') - ax1.set_xlabel('Labels', fontsize=12) - ax1.set_ylabel('Frequency', color='b', fontsize=12) - ax1.tick_params(axis='y', colors='b') - - ax2 = ax1.twinx() - ax2.plot(labels, cumulative_percentage, color='r', marker='o') - ax2.set_ylabel('Cumulative Percentage (%)', color='r', fontsize=12) - ax2.tick_params(axis='y', colors='r') - - plt.title('Pareto Diagram of Issues by Labels - General Report', fontsize=14) - plt.xticks(rotation=45, ha='right', fontsize=8) - ax1.set_xticklabels(['\n'.join(wrap(label, 13)) for label in labels]) - plt.tight_layout() - plt.show() - - -def generate_weekly_report(github_token, username, repository_name): - g = Github(github_token) - repo = g.get_repo(f"{username}/{repository_name}") - issues = repo.get_issues(state='all') - weekly_counts = {'Monday': {'opened': 0, 'closed': 0}, 'Tuesday': {'opened': 0, 'closed': 0}, - 'Wednesday': {'opened': 0, 'closed': 0}, 'Thursday': {'opened': 0, 'closed': 0}, - 'Friday': {'opened': 0, 'closed': 0}, 'Saturday': {'opened': 0, 'closed': 0}, - 'Sunday': {'opened': 0, 'closed': 0}} - - def get_day_of_week(date_str): - date = datetime.strptime(date_str[:10], '%Y-%m-%d') - return date.strftime('%A') - - current_date = datetime.now() - one_week_ago = current_date - timedelta(days=7) - for issue in issues: - created_at = issue.created_at.replace(tzinfo=None) - if created_at >= one_week_ago: - day_of_week = get_day_of_week(str(created_at)) - weekly_counts[day_of_week]['opened'] += 1 - if issue.closed_at: - closed_at = issue.closed_at.replace(tzinfo=None) - if closed_at >= one_week_ago: - day_of_week = get_day_of_week(str(closed_at)) - weekly_counts[day_of_week]['closed'] += 1 - - -def generate_histogram_report(repo_owner, repo_name, github_token): - url = f"https://api.github.com/repos/{repo_owner}/{repo_name}/issues" - headers = {'Authorization': f'token {github_token}'} - response = requests.get(url, headers=headers) - if response.status_code != 200: - print(f"Failed to fetch issues. Status code: {response.status_code}") - print(response.text) - return None - else: - issues = response.json() - - labels_count = { - "back-end": 0, - "bug": 0, - "database": 0, - "documentation": 0, - "front-end": 0, - "tests": 0, - "wontfix": 0, - } - - for issue in issues: - for label in issue['labels']: - label_name = label['name'] - if label_name in labels_count: - labels_count[label_name] += 1 - - plt.figure(figsize=(10, 6)) - plt.bar(labels_count.keys(), labels_count.values()) - plt.ylabel('Number of Issues') - plt.title('Histogram of Issues by Label - General Report') - plt.xticks(rotation=20) - plt.yticks(range(0, max(labels_count.values()) + 1)) - plt.show() - - -def generate_scatter_diagram_report(repo_owner, repo_name, github_token): - url = f"https://api.github.com/repos/{repo_owner}/{repo_name}/issues" - headers = {'Authorization': f'token {github_token}'} - response = requests.get(url, headers=headers) - if response.status_code != 200: - print(f"Failed to fetch issues. Status code: {response.status_code}") - print(response.text) - return None - else: - issues = response.json() - - days_to_close = [] - issue_created_dates = [] - - for issue in issues: - created_at = datetime.strptime(issue['created_at'], '%Y-%m-%dT%H:%M:%SZ') - closed_at = datetime.strptime(issue['closed_at'], '%Y-%m-%dT%H:%M:%SZ') if issue[ - 'closed_at'] else datetime.now() - time_to_close = (closed_at - created_at).days - days_to_close.append(time_to_close) - issue_created_dates.append(created_at) - - plt.figure(figsize=(10, 6)) - plt.scatter(days_to_close, issue_created_dates, color='blue', alpha=0.7) - plt.xlabel('Days for closing the issue') - plt.ylabel('Date of creation of the issue') - plt.title('Scatter Diagram of closed issues') - plt.grid(True) - plt.show() - - -def main(): - github_token = os.getenv('TOKEN') - username = os.getenv('USER') - repository_name = os.getenv('PROJECT') - generate_weekly_report(github_token, username, repository_name) - issues = fetch_issues(username, repository_name, github_token) - generate_pareto_diagram(issues) - generate_histogram_report(username, repository_name, github_token) - generate_scatter_diagram_report(username, repository_name, github_token) - - -if __name__ == "__main__": - main() \ No newline at end of file From c49b2c1ab78847eae872eb7eed48aaf88260ac81 Mon Sep 17 00:00:00 2001 From: jvJUCA Date: Wed, 29 May 2024 16:09:30 -0300 Subject: [PATCH 31/47] commit test --- src/components/organisms/ModeratedCoopsView.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/organisms/ModeratedCoopsView.vue b/src/components/organisms/ModeratedCoopsView.vue index 4c77db7ed..b6bce6981 100644 --- a/src/components/organisms/ModeratedCoopsView.vue +++ b/src/components/organisms/ModeratedCoopsView.vue @@ -48,7 +48,7 @@ Date: Wed, 29 May 2024 17:03:33 -0300 Subject: [PATCH 32/47] fix: tokens name on ishikawa functions --- .github/workflows/ishikawa-tools.yml | 2 +- ishikawa_tools/ishikawa_tools_script.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ishikawa-tools.yml b/.github/workflows/ishikawa-tools.yml index b696ad5f1..1d7281291 100644 --- a/.github/workflows/ishikawa-tools.yml +++ b/.github/workflows/ishikawa-tools.yml @@ -25,7 +25,7 @@ jobs: - name: Run report generation script env: - TOKEN: ${{ secrets.GITHUB_TOKEN }} + TOKEN: ${{ secrets.ACCESS_TOKEN }} USER: ${{ secrets.USER }} PROJECT: ${{ secrets.PROJECT }} run: python ishikawa_tools/ishikawa_tools_script.py diff --git a/ishikawa_tools/ishikawa_tools_script.py b/ishikawa_tools/ishikawa_tools_script.py index 42798df0d..dc7b53cd9 100644 --- a/ishikawa_tools/ishikawa_tools_script.py +++ b/ishikawa_tools/ishikawa_tools_script.py @@ -192,7 +192,7 @@ def generate_scatter_diagram_report(repo_owner, repo_name, github_token): def main(): - github_token = os.getenv('TOKEN') + github_token = os.getenv('USER_TOKEN') username = os.getenv('USER') repository_name = os.getenv('PROJECT') From 252dba6f0bdc1a96e05a47b3c65d0ddff05eb2c9 Mon Sep 17 00:00:00 2001 From: jvJUCA Date: Wed, 29 May 2024 17:07:22 -0300 Subject: [PATCH 33/47] Fix: wrong secret name --- ishikawa_tools/ishikawa_tools_script.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ishikawa_tools/ishikawa_tools_script.py b/ishikawa_tools/ishikawa_tools_script.py index dc7b53cd9..34cec5b6b 100644 --- a/ishikawa_tools/ishikawa_tools_script.py +++ b/ishikawa_tools/ishikawa_tools_script.py @@ -192,7 +192,7 @@ def generate_scatter_diagram_report(repo_owner, repo_name, github_token): def main(): - github_token = os.getenv('USER_TOKEN') + github_token = os.getenv('ACCESS_TOKEN') username = os.getenv('USER') repository_name = os.getenv('PROJECT') From 4f1b46f0fb5f16c4ba7f30a0a21d3b0637586067 Mon Sep 17 00:00:00 2001 From: jvJUCA Date: Wed, 29 May 2024 17:20:30 -0300 Subject: [PATCH 34/47] feat: check variables --- .github/workflows/ishikawa-tools.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/ishikawa-tools.yml b/.github/workflows/ishikawa-tools.yml index 1d7281291..bc6cc9b13 100644 --- a/.github/workflows/ishikawa-tools.yml +++ b/.github/workflows/ishikawa-tools.yml @@ -23,6 +23,12 @@ jobs: run: | pip install matplotlib pandas requests PyGithub + - name: Check environment variables + run: | + echo "User: $USER" + echo "Project: $PROJECT" + echo "Token: ${#ACCESS_TOKEN}" # This will print the length of the token to ensure it's set, without exposing it. + - name: Run report generation script env: TOKEN: ${{ secrets.ACCESS_TOKEN }} From 61206ba7d5d93fed133a32717bd23a483ebbfc46 Mon Sep 17 00:00:00 2001 From: jvJUCA Date: Wed, 29 May 2024 17:27:51 -0300 Subject: [PATCH 35/47] fix: run job wrong place --- .github/workflows/ishikawa-tools.yml | 52 ++++++++++++++-------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/.github/workflows/ishikawa-tools.yml b/.github/workflows/ishikawa-tools.yml index bc6cc9b13..88c8a8b79 100644 --- a/.github/workflows/ishikawa-tools.yml +++ b/.github/workflows/ishikawa-tools.yml @@ -2,7 +2,7 @@ name: Generate Reports on: schedule: - - cron: "0 0 * * *" + - cron: '0 0 * * *' issues: types: [opened, deleted, closed, reopened, labeled] @@ -11,32 +11,32 @@ jobs: runs-on: ubuntu-latest steps: - - name: Checkout code - uses: actions/checkout@v2 + - name: Checkout code + uses: actions/checkout@v2 - - name: Set up Python - uses: actions/setup-python@v2 - with: - python-version: '3.10.x' + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: '3.10.x' - - name: Install dependencies - run: | - pip install matplotlib pandas requests PyGithub + - name: Install dependencies + run: | + pip install matplotlib pandas requests PyGithub - - name: Check environment variables - run: | - echo "User: $USER" - echo "Project: $PROJECT" - echo "Token: ${#ACCESS_TOKEN}" # This will print the length of the token to ensure it's set, without exposing it. + - name: Check environment variables + run: | + echo "User: $USER" + echo "Project: $PROJECT" + echo "Token: ${#ACCESS_TOKEN}" # This will print the length of the token to ensure it's set, without exposing it. - - name: Run report generation script - env: - TOKEN: ${{ secrets.ACCESS_TOKEN }} - USER: ${{ secrets.USER }} - PROJECT: ${{ secrets.PROJECT }} - run: python ishikawa_tools/ishikawa_tools_script.py - - uses: actions/upload-artifact@v4 - with: - name: ishikawa-screenshots - path: ./ishikawa_tools/output - retention-days: 1 + - name: Run report generation script + env: + TOKEN: ${{ secrets.ACCESS_TOKEN }} + USER: ${{ secrets.USER }} + PROJECT: ${{ secrets.PROJECT }} + run: python ishikawa_tools/ishikawa_tools_script.py + - uses: actions/upload-artifact@v4 + with: + name: ishikawa-screenshots + path: ./ishikawa_tools/output + retention-days: 1 From ba8131ce9cc3a7817affa24a5e6c6f8ea0550c0f Mon Sep 17 00:00:00 2001 From: jvJUCA Date: Wed, 29 May 2024 17:30:38 -0300 Subject: [PATCH 36/47] fix: changed name of env secret --- .github/workflows/ishikawa-tools.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ishikawa-tools.yml b/.github/workflows/ishikawa-tools.yml index 88c8a8b79..37014975a 100644 --- a/.github/workflows/ishikawa-tools.yml +++ b/.github/workflows/ishikawa-tools.yml @@ -31,7 +31,7 @@ jobs: - name: Run report generation script env: - TOKEN: ${{ secrets.ACCESS_TOKEN }} + ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }} USER: ${{ secrets.USER }} PROJECT: ${{ secrets.PROJECT }} run: python ishikawa_tools/ishikawa_tools_script.py From 58c8e73caf5475685777566fe173b7b082ea01ba Mon Sep 17 00:00:00 2001 From: jvJUCA Date: Wed, 29 May 2024 17:35:57 -0300 Subject: [PATCH 37/47] fix: ishikawa python and yml --- .github/workflows/ishikawa-tools.yml | 9 +++- ishikawa_tools/ishikawa_tools_script.py | 57 +++++++------------------ 2 files changed, 22 insertions(+), 44 deletions(-) diff --git a/.github/workflows/ishikawa-tools.yml b/.github/workflows/ishikawa-tools.yml index 37014975a..755077c97 100644 --- a/.github/workflows/ishikawa-tools.yml +++ b/.github/workflows/ishikawa-tools.yml @@ -24,17 +24,22 @@ jobs: pip install matplotlib pandas requests PyGithub - name: Check environment variables + env: + ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }} + USER: ${{ secrets.USER }} + PROJECT: ${{ secrets.PROJECT }} run: | echo "User: $USER" echo "Project: $PROJECT" - echo "Token: ${#ACCESS_TOKEN}" # This will print the length of the token to ensure it's set, without exposing it. + echo "Token length: ${#ACCESS_TOKEN}" # This will print the length of the token to ensure it's set, without exposing it. - name: Run report generation script env: - ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }} + TOKEN: ${{ secrets.ACCESS_TOKEN }} USER: ${{ secrets.USER }} PROJECT: ${{ secrets.PROJECT }} run: python ishikawa_tools/ishikawa_tools_script.py + - uses: actions/upload-artifact@v4 with: name: ishikawa-screenshots diff --git a/ishikawa_tools/ishikawa_tools_script.py b/ishikawa_tools/ishikawa_tools_script.py index 34cec5b6b..4c407a9f1 100644 --- a/ishikawa_tools/ishikawa_tools_script.py +++ b/ishikawa_tools/ishikawa_tools_script.py @@ -7,19 +7,16 @@ from textwrap import wrap from pathlib import Path - def fetch_issues(repo_owner, repo_name, github_token): url = f"https://api.github.com/repos/{repo_owner}/{repo_name}/issues" headers = {'Authorization': f'token {github_token}'} response = requests.get(url, headers=headers) if response.status_code != 200: print(f"Failed to fetch issues. Status code: {response.status_code}") - print(response.text) + print(response.json()) # Print the full error message return None else: - issues = response.json() - return issues - + return response.json() def generate_pareto_diagram(issues): labels_count = {} @@ -53,18 +50,11 @@ def generate_pareto_diagram(issues): plt.tight_layout() plt.savefig('./ishikawa_tools/output/pereto.pdf') - def generate_weekly_report(github_token, username, repository_name): - # Crear una instancia de la clase Github g = Github(github_token) - - # Obtener el repositorio repo = g.get_repo(f"{username}/{repository_name}") - - # Obtener todas las issues del repositorio issues = repo.get_issues(state='all') - # Diccionario para almacenar el recuento de issues por día de la semana weekly_counts = { 'Monday': {'opened': 0, 'closed': 0}, 'Tuesday': {'opened': 0, 'closed': 0}, @@ -94,7 +84,6 @@ def get_day_of_week(date_str): day_of_week = get_day_of_week(str(closed_at)) weekly_counts[day_of_week]['closed'] += 1 - # Extraer los datos para la tabla dias = list(weekly_counts.keys()) abiertas = [weekly_counts[d]["opened"] for d in weekly_counts] cerradas = [weekly_counts[d]["closed"] for d in weekly_counts] @@ -105,30 +94,17 @@ def get_day_of_week(date_str): "Cerradas": cerradas } - # Crear la tabla df = pd.DataFrame(data) - # Crear figura y eje fig, ax = plt.subplots() - - # Eliminar marcas del eje ax.axis('off') + tabla = ax.table(cellText=df.values, colLabels=df.columns, cellLoc='center', loc='center') - # Crear tabla - tabla = ax.table(cellText=df.values, - colLabels=df.columns, - cellLoc='center', - loc='center') - - # Ajustar tamaño de la fuente tabla.auto_set_font_size(False) tabla.set_fontsize(12) - - # Ajustar tamaño de la tabla tabla.scale(1.5, 1.5) plt.savefig('./ishikawa_tools/output/checklist.pdf') - def generate_histogram_report(repo_owner, repo_name, github_token): url = f"https://api.github.com/repos/{repo_owner}/{repo_name}/issues" headers = {'Authorization': f'token {github_token}'} @@ -140,16 +116,11 @@ def generate_histogram_report(repo_owner, repo_name, github_token): else: issues = response.json() - labels_count = { - } - + labels_count = {} for issue in issues: for label in issue['labels']: label_name = label['name'] - if label_name in labels_count: - labels_count[label_name] += 1 - else: - labels_count[label_name] = 1 + labels_count[label_name] = labels_count.get(label_name, 0) + 1 plt.figure(figsize=(10, 6)) plt.bar(labels_count.keys(), labels_count.values()) @@ -159,7 +130,6 @@ def generate_histogram_report(repo_owner, repo_name, github_token): plt.yticks(range(0, max(labels_count.values()) + 1)) plt.savefig('./ishikawa_tools/output/histogram.pdf') - def generate_scatter_diagram_report(repo_owner, repo_name, github_token): url = f"https://api.github.com/repos/{repo_owner}/{repo_name}/issues" headers = {'Authorization': f'token {github_token}'} @@ -176,8 +146,7 @@ def generate_scatter_diagram_report(repo_owner, repo_name, github_token): for issue in issues: created_at = datetime.strptime(issue['created_at'], '%Y-%m-%dT%H:%M:%SZ') - closed_at = datetime.strptime(issue['closed_at'], '%Y-%m-%dT%H:%M:%SZ') if issue[ - 'closed_at'] else datetime.now() + closed_at = datetime.strptime(issue['closed_at'], '%Y-%m-%dT%H:%M:%SZ') if issue['closed_at'] else datetime.now() time_to_close = (closed_at - created_at).days days_to_close.append(time_to_close) issue_created_dates.append(created_at) @@ -190,20 +159,24 @@ def generate_scatter_diagram_report(repo_owner, repo_name, github_token): plt.grid(True) plt.savefig('./ishikawa_tools/output/scatter.pdf') - def main(): - github_token = os.getenv('ACCESS_TOKEN') + github_token = os.getenv('TOKEN') username = os.getenv('USER') repository_name = os.getenv('PROJECT') + if not all([github_token, username, repository_name]): + print("One or more environment variables are missing.") + return + issues = fetch_issues(username, repository_name, github_token) - Path("./ishikawa_tools/output").mkdir(parents=True, exist_ok=True) + if issues is None: + print("Exiting script due to fetch issues failure.") + return generate_pareto_diagram(issues) + generate_weekly_report(github_token, username, repository_name) generate_histogram_report(username, repository_name, github_token) generate_scatter_diagram_report(username, repository_name, github_token) - generate_weekly_report(github_token, username, repository_name) - if __name__ == "__main__": main() From 3f552eb46a5d51791008ca8595ebaa9fe041a6de Mon Sep 17 00:00:00 2001 From: jvJUCA Date: Wed, 29 May 2024 17:48:46 -0300 Subject: [PATCH 38/47] fix: added repo owner --- ishikawa_tools/ishikawa_tools_script.py | 1 + 1 file changed, 1 insertion(+) diff --git a/ishikawa_tools/ishikawa_tools_script.py b/ishikawa_tools/ishikawa_tools_script.py index 4c407a9f1..daf3c9b37 100644 --- a/ishikawa_tools/ishikawa_tools_script.py +++ b/ishikawa_tools/ishikawa_tools_script.py @@ -160,6 +160,7 @@ def generate_scatter_diagram_report(repo_owner, repo_name, github_token): plt.savefig('./ishikawa_tools/output/scatter.pdf') def main(): + repo_owner = "marcgc21" github_token = os.getenv('TOKEN') username = os.getenv('USER') repository_name = os.getenv('PROJECT') From df5c69ba94e4c1829d4e756998b6c12947932d97 Mon Sep 17 00:00:00 2001 From: jvJUCA Date: Wed, 29 May 2024 17:49:13 -0300 Subject: [PATCH 39/47] fix: repo_owner added --- ishikawa_tools/ishikawa_tools_script.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ishikawa_tools/ishikawa_tools_script.py b/ishikawa_tools/ishikawa_tools_script.py index daf3c9b37..abd7702ca 100644 --- a/ishikawa_tools/ishikawa_tools_script.py +++ b/ishikawa_tools/ishikawa_tools_script.py @@ -169,7 +169,7 @@ def main(): print("One or more environment variables are missing.") return - issues = fetch_issues(username, repository_name, github_token) + issues = fetch_issues(repo_owner, repository_name, github_token) if issues is None: print("Exiting script due to fetch issues failure.") return From d698752e7ada03daf46464a0137a0cb31105a5b0 Mon Sep 17 00:00:00 2001 From: zlatanjakic Date: Thu, 30 May 2024 15:47:10 +0200 Subject: [PATCH 40/47] Changed back from using access token to the default GITHUB_TOKEN --- .github/workflows/ishikawa-tools.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ishikawa-tools.yml b/.github/workflows/ishikawa-tools.yml index 755077c97..fbb2ce6fc 100644 --- a/.github/workflows/ishikawa-tools.yml +++ b/.github/workflows/ishikawa-tools.yml @@ -35,7 +35,7 @@ jobs: - name: Run report generation script env: - TOKEN: ${{ secrets.ACCESS_TOKEN }} + TOKEN: ${{ secrets.GITHUB_TOKEN }} USER: ${{ secrets.USER }} PROJECT: ${{ secrets.PROJECT }} run: python ishikawa_tools/ishikawa_tools_script.py From 40cbc68e9c19331cd32d66f68a8db3b9548182e8 Mon Sep 17 00:00:00 2001 From: zlatanjakic Date: Thu, 30 May 2024 15:53:13 +0200 Subject: [PATCH 41/47] Romved the repo owener variable --- .github/workflows/ishikawa-tools.yml | 2 +- ishikawa_tools/ishikawa_tools_script.py | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ishikawa-tools.yml b/.github/workflows/ishikawa-tools.yml index fbb2ce6fc..e5ce0d790 100644 --- a/.github/workflows/ishikawa-tools.yml +++ b/.github/workflows/ishikawa-tools.yml @@ -35,7 +35,7 @@ jobs: - name: Run report generation script env: - TOKEN: ${{ secrets.GITHUB_TOKEN }} + TOKEN: ${{ secrets.GITHUB_TOKEN }} #This should work instead of using a personal access token USER: ${{ secrets.USER }} PROJECT: ${{ secrets.PROJECT }} run: python ishikawa_tools/ishikawa_tools_script.py diff --git a/ishikawa_tools/ishikawa_tools_script.py b/ishikawa_tools/ishikawa_tools_script.py index abd7702ca..4c407a9f1 100644 --- a/ishikawa_tools/ishikawa_tools_script.py +++ b/ishikawa_tools/ishikawa_tools_script.py @@ -160,7 +160,6 @@ def generate_scatter_diagram_report(repo_owner, repo_name, github_token): plt.savefig('./ishikawa_tools/output/scatter.pdf') def main(): - repo_owner = "marcgc21" github_token = os.getenv('TOKEN') username = os.getenv('USER') repository_name = os.getenv('PROJECT') @@ -169,7 +168,7 @@ def main(): print("One or more environment variables are missing.") return - issues = fetch_issues(repo_owner, repository_name, github_token) + issues = fetch_issues(username, repository_name, github_token) if issues is None: print("Exiting script due to fetch issues failure.") return From ed51a33ed0e60e76199f5ac9eee2c02210b864a9 Mon Sep 17 00:00:00 2001 From: zlatanjakic Date: Thu, 30 May 2024 16:06:15 +0200 Subject: [PATCH 42/47] Changed to echoing the length of the user and project secrets --- .github/workflows/ishikawa-tools.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ishikawa-tools.yml b/.github/workflows/ishikawa-tools.yml index e5ce0d790..f7282481b 100644 --- a/.github/workflows/ishikawa-tools.yml +++ b/.github/workflows/ishikawa-tools.yml @@ -29,8 +29,8 @@ jobs: USER: ${{ secrets.USER }} PROJECT: ${{ secrets.PROJECT }} run: | - echo "User: $USER" - echo "Project: $PROJECT" + echo "User secret length: ${#USER}" + echo "Project secret length: ${#PROJECT}" # Changed the checks for user and project to length checks (these secrets should probably be changed to variables) echo "Token length: ${#ACCESS_TOKEN}" # This will print the length of the token to ensure it's set, without exposing it. - name: Run report generation script From e08ffb915f44e1b91f7d4db0efac8a0582ef925b Mon Sep 17 00:00:00 2001 From: zlatanjakic Date: Thu, 30 May 2024 16:12:33 +0200 Subject: [PATCH 43/47] Added the ability to manualy run the ishikawa tools action --- .github/workflows/ishikawa-tools.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ishikawa-tools.yml b/.github/workflows/ishikawa-tools.yml index f7282481b..e928ee6f3 100644 --- a/.github/workflows/ishikawa-tools.yml +++ b/.github/workflows/ishikawa-tools.yml @@ -1,10 +1,11 @@ name: Generate Reports -on: +on: schedule: - cron: '0 0 * * *' issues: types: [opened, deleted, closed, reopened, labeled] + workflow_dispatch: jobs: generate-reports: From 5ae5c74cf2e96135bcbc95772ee13ecedda146c4 Mon Sep 17 00:00:00 2001 From: zlatanjakic Date: Thu, 30 May 2024 16:22:38 +0200 Subject: [PATCH 44/47] Added the code for creating the output folder. This folder is only needed while running the script and does not need to be part of the code permenantly --- ishikawa_tools/ishikawa_tools_script.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ishikawa_tools/ishikawa_tools_script.py b/ishikawa_tools/ishikawa_tools_script.py index 4c407a9f1..3b18a0cd2 100644 --- a/ishikawa_tools/ishikawa_tools_script.py +++ b/ishikawa_tools/ishikawa_tools_script.py @@ -172,6 +172,8 @@ def main(): if issues is None: print("Exiting script due to fetch issues failure.") return + + Path("./ishikawa_tools/output").mkdir(parents=True, exist_ok=True) generate_pareto_diagram(issues) generate_weekly_report(github_token, username, repository_name) From 220e13cb631e8bdddef786e31d2de60f9b9fcd64 Mon Sep 17 00:00:00 2001 From: zlatanjakic Date: Sun, 2 Jun 2024 11:50:03 +0200 Subject: [PATCH 45/47] Added dependencies file for ishikawa tools --- ishikawa_tools/requirements.txt | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 ishikawa_tools/requirements.txt diff --git a/ishikawa_tools/requirements.txt b/ishikawa_tools/requirements.txt new file mode 100644 index 000000000..ff9c84e03 --- /dev/null +++ b/ishikawa_tools/requirements.txt @@ -0,0 +1,4 @@ +matplotlib +pandas +requests +PyGithub \ No newline at end of file From 79cc636f377120c36dff42fcf6db6c6f889bdd53 Mon Sep 17 00:00:00 2001 From: jvJUCA Date: Mon, 3 Jun 2024 16:36:57 -0300 Subject: [PATCH 46/47] intentional error in action for bot testing purposes --- ishikawa_tools/ishikawa_tools_script.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ishikawa_tools/ishikawa_tools_script.py b/ishikawa_tools/ishikawa_tools_script.py index 3b18a0cd2..8b01d64c1 100644 --- a/ishikawa_tools/ishikawa_tools_script.py +++ b/ishikawa_tools/ishikawa_tools_script.py @@ -160,9 +160,9 @@ def generate_scatter_diagram_report(repo_owner, repo_name, github_token): plt.savefig('./ishikawa_tools/output/scatter.pdf') def main(): - github_token = os.getenv('TOKEN') - username = os.getenv('USER') - repository_name = os.getenv('PROJECT') + github_token = os.getenv('TOKENXXX') + username = os.getenv('USERXXX') + repository_name = os.getenv('PROJECTXXX') if not all([github_token, username, repository_name]): print("One or more environment variables are missing.") From 05aa90def670c3133d0ffde55a291f27079cb5ab Mon Sep 17 00:00:00 2001 From: jvJUCA Date: Mon, 3 Jun 2024 16:41:26 -0300 Subject: [PATCH 47/47] Introduce intentional error in action for bot testing purposes --- ishikawa_tools/ishikawa_tools_script.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ishikawa_tools/ishikawa_tools_script.py b/ishikawa_tools/ishikawa_tools_script.py index 8b01d64c1..b1b97dae2 100644 --- a/ishikawa_tools/ishikawa_tools_script.py +++ b/ishikawa_tools/ishikawa_tools_script.py @@ -160,9 +160,8 @@ def generate_scatter_diagram_report(repo_owner, repo_name, github_token): plt.savefig('./ishikawa_tools/output/scatter.pdf') def main(): - github_token = os.getenv('TOKENXXX') - username = os.getenv('USERXXX') - repository_name = os.getenv('PROJECTXXX') + github_token = os.getenv('TOKEN') + username = os.getenv('USER') if not all([github_token, username, repository_name]): print("One or more environment variables are missing.")