From d40bb5a10f032f70ab8eb06781d019f3dd636b94 Mon Sep 17 00:00:00 2001 From: greenamber676 Date: Thu, 9 Jan 2025 20:05:17 -0500 Subject: [PATCH] addeded jenkins pipe --- DockerFile | 31 ++++++++++++++++ Jenkinsfile | 63 +++++++++++++++++++++++++++++++++ entrypoint.sh | 20 +++++++++++ main/migrations/0001_initial.py | 49 +++++++++++++++++++++++++ main/urls.py | 6 ++-- main/views.py | 5 --- project_management/settings.py | 46 +++++++++++++++--------- requirements.txt | 8 +++++ 8 files changed, 204 insertions(+), 24 deletions(-) create mode 100644 DockerFile create mode 100644 Jenkinsfile create mode 100755 entrypoint.sh create mode 100644 main/migrations/0001_initial.py create mode 100644 requirements.txt diff --git a/DockerFile b/DockerFile new file mode 100644 index 0000000..f722de3 --- /dev/null +++ b/DockerFile @@ -0,0 +1,31 @@ +# pull official base image +FROM python:3.11.4-slim-buster + +# set work directory +WORKDIR /usr/src/app + +# set environment variables +ENV PYTHONDONTWRITEBYTECODE 1 +ENV PYTHONUNBUFFERED 1 + +# install system dependencies +RUN apt-get update && apt-get install -y netcat + +# install dependencies +RUN pip install --upgrade pip +COPY ./requirements.txt . +RUN pip install -r requirements.txt + +# copy project +COPY . . + +# copy entrypoint.sh +COPY ./entrypoint.sh . +RUN sed -i 's/\r$//g' /usr/src/app/entrypoint.sh +RUN chmod +x /usr/src/app/entrypoint.sh + + + +# run entrypoint.sh +ENTRYPOINT ["/usr/src/app/entrypoint.sh"] + diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000..1ebce07 --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,63 @@ +pipeline { + agent any + + environment { + DOCKER_IMAGE_NODE = 'your-node-image:latest' + DOCKER_IMAGE_DJANGO = 'your-django-image:latest' + DOCKER_IMAGE_POSTGRES = 'postgres:latest' + DOCKER_COMPOSE_FILE = 'docker-compose.yml' + } + + stages { + stage('Checkout') { + steps { + // Checkout the code from Gitea + git url: 'http://your-gitea-instance/your-repo.git', branch: 'main' + } + } + + stage('Build Node.js') { + steps { + script { + // Build Node.js application + sh 'docker build -t ${DOCKER_IMAGE_NODE} ./node-app' + } + } + } + + stage('Build Django') { + steps { + script { + // Build Django application + sh 'docker build -t ${DOCKER_IMAGE_DJANGO} ./django-app' + } + } + } + + stage('Run Tests') { + steps { + script { + // Run tests using Docker Compose + sh "docker-compose -f ${DOCKER_COMPOSE_FILE} up --abort-on-container-exit" + } + } + } + + stage('Deploy') { + steps { + script { + // Deploy using Docker Compose + sh "docker-compose -f ${DOCKER_COMPOSE_FILE} up -d" + } + } + } + } + + post { + always { + // Clean up Docker containers and images + sh 'docker-compose -f ${DOCKER_COMPOSE_FILE} down' + sh "docker rmi ${DOCKER_IMAGE_NODE} ${DOCKER_IMAGE_DJANGO} || true" + } + } +} \ No newline at end of file diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100755 index 0000000..e6c10a0 --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,20 @@ +#!/bin/sh + +if [ "$DATABASE" = "postgres" ] +then + echo "Waiting for postgres..." + + while ! nc -z $POSTGRESQL_HOST $POSTGRESQL_PORT; do + sleep 0.1 + done + + echo "PostgreSQL started" +fi +find . -path "*/main/migrations/*.py" -not -name "__init__.py" -delete +find . -path "*/main/migrations/*.pyc" -delete +python manage.py makemigrations +python manage.py migrate +python manage.py runserver 0.0.0.0:8000 + +exec "$@" + diff --git a/main/migrations/0001_initial.py b/main/migrations/0001_initial.py new file mode 100644 index 0000000..c1d0296 --- /dev/null +++ b/main/migrations/0001_initial.py @@ -0,0 +1,49 @@ +# Generated by Django 5.1.1 on 2025-01-09 16:09 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='Profile', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('role', models.CharField(choices=[('Application Admin', 'Application Admin'), ('Application Designer', 'Application Designer'), ('Database Admin', 'Database Admin'), ('PMO Admin', 'PMO Admin'), ('Program Manager', 'Program Manager'), ('Project Manager', 'Project Manager'), ('Project Coordinator', 'Project Coordinator'), ('Project User', 'Project User'), ('Project Initiator', 'Project Initiator')], max_length=50)), + ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.CreateModel( + name='Project', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=255)), + ('description', models.TextField()), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ('initiator', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='initiated_projects', to=settings.AUTH_USER_MODEL)), + ('manager', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='managed_projects', to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.CreateModel( + name='Task', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=255)), + ('description', models.TextField(blank=True)), + ('status', models.CharField(choices=[('todo', 'To Do'), ('in_progress', 'In Progress'), ('done', 'Done')], default='todo', max_length=50)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ('project', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='tasks', to='main.project')), + ], + ), + ] diff --git a/main/urls.py b/main/urls.py index 4ae88de..24e9f6f 100644 --- a/main/urls.py +++ b/main/urls.py @@ -10,9 +10,9 @@ router.register(r'tasks', TaskViewSet) urlpatterns = [ path('api/', include(router.urls)), - path('login/', login_view, name='login'), - path('logout/', logout_view, name='logout'), - path('welcome/', welcome_view, name='welcome'), +# path('login/', login_view, name='login'), +# path('logout/', logout_view, name='logout'), +# path('welcome/', welcome_view, name='welcome'), path('projects/create/', create_project, name='create_project'), path('projects//', project_dashboard, name='project_dashboard'), path('projects//tasks/create/', create_task, name='create_task'), diff --git a/main/views.py b/main/views.py index 60a156b..744e124 100644 --- a/main/views.py +++ b/main/views.py @@ -57,8 +57,3 @@ def create_task(request, project_id): form = TaskForm() return render(request, 'create_task.html', {'form': form, 'project': project}) -# main/views.py -from django.core.mail import send_mail -from django.contrib.auth.models import User - - diff --git a/project_management/settings.py b/project_management/settings.py index 72f1316..45afdf0 100644 --- a/project_management/settings.py +++ b/project_management/settings.py @@ -12,6 +12,8 @@ https://docs.djangoproject.com/en/4.1/ref/settings/ from pathlib import Path +import os + # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent @@ -20,24 +22,25 @@ BASE_DIR = Path(__file__).resolve().parent.parent # See https://docs.djangoproject.com/en/4.1/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = 'django-insecure-e#$wxb+=br=3u(ju%$dzru!=6p4myj^!3fyb8-@d@y+9dx0od2' +SECRET_KEY = os.environ.get("SECRET_KEY") # SECURITY WARNING: don't run with debug turned on in production! -DEBUG = True +DEBUG = bool(os.environ.get("DEBUG", default=0)) -ALLOWED_HOSTS = [] +ALLOWED_HOSTS = os.environ.get("DJANGO_ALLOWED_HOSTS").split(" ") # Application definition INSTALLED_APPS = [ + 'rest_framework', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', - 'rest_framework', + 'main', ] MIDDLEWARE = [ @@ -50,7 +53,7 @@ MIDDLEWARE = [ 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] -ROOT_URLCONF = 'wbsportal.urls' +ROOT_URLCONF = 'project_management.urls' TEMPLATES = [ { @@ -76,12 +79,12 @@ WSGI_APPLICATION = 'project_management.wsgi.application' DATABASES = { 'default': { - 'ENGINE': 'django.db.backends.postgresql', - 'NAME': 'p00003db', - 'USER': 'p00003dbuser', - 'PASSWORD': 'Express.123', - 'HOST': 'localhost', # Set to 'localhost' or your database server IP - 'PORT': '5432', # Default port for PostgreSQL + 'ENGINE': os.environ.get('POSTGRESQL_ENGINE'), + 'NAME': os.environ.get('POSTGRESQL_NAME'), + 'USER': os.environ.get('POSTGRESQL_USER'), + 'PASSWORD': os.environ.get('POSTGRESQL_PASSWORD'), + 'HOST': os.environ.get('POSTGRESQL_HOST'), + 'PORT': os.environ.get('POSTGRESQL_PORT'), } } @@ -91,19 +94,30 @@ DATABASES = { AUTH_PASSWORD_VALIDATORS = [ { - 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + 'NAME': + 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', }, { - 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + 'NAME': + 'django.contrib.auth.password_validation.MinimumLengthValidator', }, { - 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + 'NAME': + 'django.contrib.auth.password_validation.CommonPasswordValidator', }, { - 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', - }, + 'NAME': + 'django.contrib.auth.password_validation.NumericPasswordValidator', }, ] +REST_FRAMEWORK = { + # Use Django's standard `django.contrib.auth` permissions, + # or allow read-only access for unauthenticated users. + 'DEFAULT_PERMISSION_CLASSES': [ + 'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly', + ] +} + # Internationalization # https://docs.djangoproject.com/en/4.1/topics/i18n/ diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..80e79bf --- /dev/null +++ b/requirements.txt @@ -0,0 +1,8 @@ +asgiref==3.8.1 +Django==5.1.1 +djangorestframework==3.15.2 +psycopg2-binary==2.9.10 +sqlparse==0.5.1 +typing_extensions==4.12.2 +tzdata==2024.2 +whitenoise==6.8.2