Cuarto trabajo de Gestión de Proyectos Software - UExGPSASEE/proyecto24-gc04 GitHub Wiki

Proceso seguido por Javier González Béjar

Preparación del proyecto individual

  • Se accede a la página principal este repositorio:

image

  • Se pulsa en Fork para acceder a la siguiente página:

image

  • Se dejan los valores como vienen establecidos por defecto.

  • Se pulsa en Create fork para crear la copia individual y acceder a ella:

image

Gestión del progreso del mantenimiento

Para gestionar el progreso del mantenimiento del código fuente, se ha creado una incidencia épica en Jira con el nombre "Source code maintenance", a la cual se le ha añadido una descripción indicando que su objetivo es el de realizar un análisis del código existente utilizando SonarCloud, identificar problemas críticos y aplicar correcciones para mejorar la calidad del software. Además, se le han asignado las etiquetas MAINTENANCE y SONARCLOUD.

image

  • Se añade una incidencia secundaria dentro de esta.

  • Se la titula como "SCM - JAVIER GONZÁLEZ BÉJAR".

  • Se accede a la nueva incidencia.

  • Se le añade una descripción, especificando que se trata de la parte correspondiente a Javier González Béjar.

  • Se le asigna a Javier González Béjar.

  • Se le asignan las etiquetas MAINTENANCE y SONARCLOUD.

image

Importación del proyecto en SonarCloud

image

  • Se pulsa en Log in para acceder a la siguiente página:

image

  • Se pulsa en GITHUB para acceder a la siguiente página:

image

  • Se pulsa en Authorize SonarQubeCloud para acceder a la siguiente página:

image

  • Se pulsa en Import an organization para acceder a la siguiente página:

image

  • Se pulsa en jgonzalerj para acceder a la siguiente página:

image

  • Se marca la opción Only select repositories.

  • Se pulsa en Select repositories.

  • Se selecciona jgonzalerj/proyecto24-gc04:

image

  • Se pulsa en Install para acceder a la siguiente página:

image

  • Se introduce la contraseña en Password.

  • Se pulsa en Confirm para acceder a la siguiente página:

image

  • Se dejan los campos Name y Key como vienen por defecto.

  • En Choose a plan, se pulsa en Select Free:

image image

  • Se pulsa en Create Organization y se accede a la siguiente página:

image

  • Se pulsa en Analyze a new project y se accede a la siguiente página:

image

  • Se marca el proyecto proyecto24-gc04.

  • Se pulsa en Set Up y se accede a la siguiente página:

image

  • Se marca la opción Previous version.

  • Se pulsa en Create project.

Configuración del método de análisis del proyecto

image

  • Se deja el cursor sobre ⚙️, se pulsa en Analysis Method y se accede a la siguiente página:

image

  • Se pulsa en With GitHub Actions y se accede a la siguiente página:

image

  • Se desmarca la opción Switch off Automatic Analysis.

  • Se pulsa sobre Settings > Secrets > Actions y se accede a la siguiente página:

image

  • Se pulsa en New repository secret para acceder a la siguiente página:

image

  • Se introduce en Name el nombre SONAR_TOKEN.

  • Se introduce en Secret el valor del token que se indica en la página de SonarCloud.

  • Se pulsa en Add secret para añadir el valor del token como un secreto del repositorio.

  • Se vuelve a la página de SonarCloud.

  • Se selecciona Other (for JS, TS, Go, Python, PHP, ...) y Windows y se obtiene el siguiente contenido:

image image

Definición del flujo de trabajo

image

  • Se pulsa en Add file y en Create new file y se accede a la siguiente página:

image

  • En Name your file... se introduce ".github/workflows/build.yml".

  • Se introduce el siguiente contenido en este archivo:

name: Build
on:
  push:
    branches:
      - main
  pull_request:
    types: [opened, synchronize, reopened]
jobs:
  sonarqube:
    name: SonarQube
    runs-on: windows-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0  # Shallow clones should be disabled for a better relevancy of analysis
      - name: SonarQube Scan
        uses: SonarSource/sonarqube-scan-action@v4
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}  # Needed to get PR information, if any
          SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
  • Se pulsa en Commit changes... para acceder a la siguiente ventana:

image

  • En Commit message se introduce "GC04-348 Creation of .github/workflows/build.yml".

  • Se marca la opción Commit directly to the main branch.

  • Se pulsa en Commit changes.

Configuración de los detalles del análisis

image

  • Se pulsa en Add file y en Create new file y se accede a la siguiente página:

image

  • En Name your file... se introduce "sonar-project.properties".

  • Se introduce el siguiente contenido en este archivo:

sonar.projectKey=jgonzalerj_proyecto24-gc04
sonar.organization=jgonzalerj

# This is the name and version displayed in the SonarCloud UI.
#sonar.projectName=proyecto24-gc04
#sonar.projectVersion=1.0


# Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows.
#sonar.sources=.

# Encoding of the source code. Default is default system encoding
#sonar.sourceEncoding=UTF-8
  • Se pulsa en Commit changes... y se accede a la siguiente ventana:

image

  • En Commit message se introduce "GC04-348 Creation of sonar-project.properties".

  • Se marca la opción Commit directly to the main branch.

  • Se pulsa en Commit changes.

Ejecución del primer análisis del proyecto

Al añadir los archivos .github/workflows/build.yml y sonar-project.properties, se comprueba que en SonarCloud se ejecuta automáticamente el primer análisis. Al finalizar, se obtiene la calidad del proyecto antes de realizar ningún cambio al acceder a https://sonarcloud.io/summary/overall?id=jgonzalerj_proyecto24-gc04&branch=main:

image

Si se pulsa en Issues, se accede a una página en la que se muestra el listado de incidencias existentes:

image

Resolución de incidencias

De entre todas las incidencias, se decide resolver las siguientes 4:

image

image

image

image

Se puede observar que el esfuerzo estimado para resolver estas incidencias son 30 minutos, 6 minutos, 5 minutos y 5 minutos respectivamente. Por lo tanto, se establece en la tarea de Jira "SCM - JAVIER GONZÁLEZ BÉJAR" una estimación original de 46 minutos y se marca como EN CURSO.

Para poder realizar los cambios oportunos en el código y reflejarlos en GitHub, se clona el repositorio remoto para trabajar en local. Una vez se resuelvan las incidencias en el repositorio local, se registrarán dichos cambios en el repositorio remoto.

Resolución de la primera incidencia

  • Se accede a la página en la que se muestra el listado de incidencias existentes.

  • Para conocer dónde se encuentra el error, se pulsa en Make sure this Django key gets revoked, changed, and removed from the code. y se accede a la siguiente página:

image

  • Para conocer cómo se resuelve el error, se pulsa en How y se accede a la siguiente página:

image

  • Se abre el archivo proyecto24-gc04\Django-api\NetflixContent\netflix_content\settings.py del repositorio local.

  • Se añade la importación de la biblioteca os con import os.

  • Se sustituye SECRET_KEY = "django-insecure-0lm3&9_ae724ct_q4513(!aj3csm&f8+9cz_369q6i6a@@zp_&" por os.environ["SECRET_KEY"].

La corrección se refleja en el siguiente bloque de código:

from pathlib import Path
import os

# Build paths inside the project like this: BASE_DIR / "subdir".
BASE_DIR = Path(__file__).resolve().parent.parent


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/5.1/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = os.environ.get("SECRET_KEY")

De este modo, se resuelve la incidencia que se daba porque se divulgaba la clave secreta de Django.

A partir de ahora, se deberá configurar la variable de entorno SECRET_KEY antes de ejecutar el proyecto mediante el comando export SECRET_KEY="django-insecure-0lm3&9_ae724ct_q4513(!aj3csm&f8+9cz_369q6i6a@@zp_&" o añadiendo la línea SECRET_KEY=django-insecure-0lm3&9_ae724ct_q4513(!aj3csm&f8+9cz_369q6i6a@@zp_& en el archivo .env.

Resolución de la segunda incidencia

  • Se accede a la página en la que se muestra el listado de incidencias existentes.

  • Para conocer dónde se encuentra el error, se pulsa en Define a constant instead of duplicating this literal 'The brief summary or synopsis of the content.' 3 times. y se accede a la siguiente página:

image

  • Para conocer cómo se resuelve el error, se pulsa en How y se accede a la siguiente página:

image

  • Se abre el archivo Django-api/NetflixContent/content/migrations/0001_initial.py del repositorio local.

  • Se define la constante CONTENT_DESCRIPTION_HELP_TEXT = 'The brief summary or synopsis of the content.'.

  • Se reemplaza la cadena 'The brief summary or synopsis of the content.' por la constante CONTENT_DESCRIPTION_HELP_TEXT en el resto del código.

La corrección se refleja en el siguiente bloque de código:

# Generated by Django 5.1.3 on 2024-11-23 12:20

import django.core.validators
import django.db.models.deletion
from decimal import Decimal
from django.db import migrations, models

CONTENT_DESCRIPTION_HELP_TEXT = 'The brief summary or synopsis of the content.'

class Migration(migrations.Migration):
    ...
    operations = [
        ...
        migrations.CreateModel(
            name='Movie',
            fields=[
                ('description', models.TextField(help_text=CONTENT_DESCRIPTION_HELP_TEXT)),
                ...
            ]
            ...
        ),
        migrations.CreateModel(
            name='Series',
            fields=[
                ('description', models.TextField(help_text=CONTENT_DESCRIPTION_HELP_TEXT)),
                ...
            ]
            ...
        ),
        migrations.CreateModel(
            name='Episode',
            fields=[
                ('description', models.TextField(help_text=CONTENT_DESCRIPTION_HELP_TEXT)),
                ...
            ]
            ...
        ),
    ]

De este modo, se resuelve la incidencia que se daba porque se duplicaba la cadena 'The brief summary or synopsis of the content.' a lo largo del código autogenerado por Django.

Resolución de la tercera incidencia

  • Se accede a la página en la que se muestra el listado de incidencias existentes.

  • Para conocer dónde se encuentra el error, se pulsa en Remove this "null=True" flag. y se accede a la siguiente página:

image

  • Para conocer cómo se resuelve el error, se pulsa en How y se accede a la siguiente página:

image

  • Se abre el archivo Django-api/NetflixUsers/users/models.py del repositorio local.

  • En el atributo favorite_genre_ids del modelo User se elimina null=True.

La corrección se refleja en el siguiente bloque de código:

class User(models.Model):
    ...
    favorite_genre_ids = models.TextField(
        blank=True,
        help_text=(
            "The ids for the user's favorite genres; "
            "may be null if no genres are defined."
        )
    )

De este modo, se resuelve la incidencia que se daba porque se usaba null=True en un TextField de la clase Model de Django.

Resolución de la cuarta incidencia

  • Se accede a la página en la que se muestra el listado de incidencias existentes.

  • Para conocer dónde se encuentra el error, se pulsa en Rename this variable; it shadows a builtin. y se accede a la siguiente página:

image

  • Para conocer por qué se da el error, se pulsa en Why y se accede a la siguiente página:

image

  • Se abre el archivo Django-api/NetflixUsers/users/views.py del repositorio local.

  • En la función destroy de la clase UserViewSet se renombra la variable id para que pase a llamarse user_id:

La corrección se refleja en el siguiente bloque de código:

    def destroy(self, request, *args, **kwargs):
        user_id = self.get_object().id
        url = f"{WATCHED_EPISODES_URL}?user_id={user_id}"
        destroy_related_watched_contents(
            "Episode", "Episodes", "episode_id", url
        )
        url = f"{WATCHED_MOVIES_URL}?user_id={user_id}"
        destroy_related_watched_contents("Movie", "Movies", "movie_id", url)
        url = f"{WATCHED_SERIES_URL}?user_id={user_id}"
        destroy_related_watched_contents("Series", "Series", "series_id", url)
        return super().destroy(request, *args, **kwargs)

De este modo, se resuelve la incidencia que se daba porque la variable integrada id era ocultada por una variable local con el mismo nombre.

Ejecución del análisis del proyecto con las incidencias resueltas

Una vez resueltas las incidencias en el repositorio local, se registran las correcciones realizadas en el repositorio remoto y entonces tiene lugar la ejecución automática del análisis en SonarCloud:

image

Al finalizar, se obtiene la calidad del proyecto tras resolver las 4 incidencias al acceder a https://sonarcloud.io/summary/overall?id=jgonzalerj_proyecto24-gc04&branch=main:

image

Como se puede observar al comparar las incidencias actuales con las incidencias que existían anteriormente, se ha producido una mejora debido a la resolución de una incidencia de seguridad y 3 incidencias de mantenibilidad.

Si se pulsa en Activity, se puede observar la siguiente gráfica reflejando un descenso de las incidencias de 199 a 195:

image

Finalmente, se registra en la tarea de Jira "SCM - JAVIER GONZÁLEZ BÉJAR" el tiempo empleado y la fecha de inicio de esta y se marca como FINALIZADA.