chaos4455's picture
Update app.py
448b694 verified
import streamlit as st
import google.generativeai as genai
import re
import os
import textwrap
# Secret key and Google Gemini API configuration
API_KEY = st.secrets["GOOGLE_API_KEY"]
# Page configuration
st.set_page_config(page_title="πŸš€βœ¨ Gemini2 CI/CD Gen Pro", page_icon="πŸš€βœ¨", layout="wide")
# --- Helper Functions ---
def send_message_to_model(message, model_name, temperature, top_p, top_k, max_tokens):
"""Sends a message to the AI model and returns the response."""
try:
# AI model configurations
GENERATION_CONFIG = {
"temperature": temperature,
"top_p": top_p,
"top_k": top_k,
"response_mime_type": "text/plain",
"max_output_tokens": max_tokens,
}
MODEL = genai.GenerativeModel(
model_name=model_name,
generation_config=GENERATION_CONFIG,
)
response = MODEL.start_chat(history=[]).send_message(message)
return response.text
except Exception as e:
st.error(f"❌ Error communicating with the AI: {e}")
return None
def generate_cicd_pipeline(prompt_base, model_name, temperature, top_p, top_k, max_tokens, target_systems, custom_requirements, specific_details, deploy_details, docker_details, kubernetes_details, test_details):
"""Generates a CI/CD pipeline based on user settings."""
prompt = f"""
You are an expert DevOps engineer specializing in CI/CD pipelines. Your task is to generate complete, secure, and efficient CI/CD pipeline configurations based on the following description:
**Goal:** Create the most complete, detailed, and efficient CI/CD pipeline possible, considering all variables, edge cases, and potential scenarios.
**Pipeline Description:** {prompt_base}
**Target Systems:** {target_systems if target_systems else "None"}
**Deployment Details:** {deploy_details if deploy_details else "None"}
**Docker Details:** {docker_details if docker_details else "None"}
**Kubernetes Details:** {kubernetes_details if kubernetes_details else "None"}
**Test Details:** {test_details if test_details else "None"}
**Custom Requirements:** {custom_requirements if custom_requirements else "None"}
**Specific Details:** {specific_details if specific_details else "None"}
**Response Format:**
- Respond in Markdown format, including YAML code blocks for Argo CD, GitHub Actions, GitLab Runner, Jenkins, CircleCI, and a Docker Compose, with their original formatting and without line breaks.
- The Argo CD code block must be delimited by ```yaml argocd and ```.
- The GitHub Actions code block must be delimited by ```yaml githubactions and ```.
- The GitLab Runner code block must be delimited by ```yaml gitlabrunner and ```.
- The Jenkins code block must be delimited by ```yaml jenkins and ```.
- The CircleCI code block must be delimited by ```yaml circleci and ```.
- The Docker Compose code block must be delimited by ```yaml dockercompose and ```.
- Do not include comments, explanations, or any other text outside the code block, unless the prompt requires.
- The code must maintain its full vertical formatting, respecting indentation and line breaks.
- The code must be realistic, using real-world examples, data, and situations.
- Explore different approaches, techniques, and advanced practices, always prioritizing security and efficiency.
- Use best practices for building images, running tests, and deploying applications.
- Unless the user specifies otherwise, use the most current and secure versions of the tools and resources, using YAML and following best practices.
- Use incremental reasoning to add improvements, expansions, and considerations to your code.
- Use the history of the conversations so that the response is incremental.
- If Docker is required, generate configurations to build Docker Images and push to Dockerhub.
- If kubernetes is required, use Argo CD for deployments and create the necessary configurations, generating the application.yaml, and any other resources.
- If any connection parameters are needed, use placeholders in the code with comments like 'PLEASE FILL THIS' indicating where the user should fill in.
- Use comments to explain the configurations.
- If the user does not specify target systems, generate for Argo CD, Github Actions and Gitlab Runner.
**Important:**
- Generate only one pipeline at a time.
- Create the longest, most complete, and detailed code possible to cover a wide range of possibilities and scenarios.
- Consider all the details of the request, expanding the response and improving the code.
"""
response = send_message_to_model(prompt, model_name, temperature, top_p, top_k, max_tokens)
return response
def parse_and_save_yaml(ai_code, short_title):
"""Parses the markdown and saves the YAML code."""
argocd_match = re.search(r'```yaml argocd\s*(.*?)\s*```', ai_code, re.DOTALL | re.IGNORECASE)
github_actions_match = re.search(r'```yaml githubactions\s*(.*?)\s*```', ai_code, re.DOTALL | re.IGNORECASE)
gitlab_runner_match = re.search(r'```yaml gitlabrunner\s*(.*?)\s*```', ai_code, re.DOTALL | re.IGNORECASE)
jenkins_match = re.search(r'```yaml jenkins\s*(.*?)\s*```', ai_code, re.DOTALL | re.IGNORECASE)
circleci_match = re.search(r'```yaml circleci\s*(.*?)\s*```', ai_code, re.DOTALL | re.IGNORECASE)
dockercompose_match = re.search(r'```yaml dockercompose\s*(.*?)\s*```', ai_code, re.DOTALL | re.IGNORECASE)
argocd_code = argocd_match.group(1).strip() if argocd_match else None
github_actions_code = github_actions_match.group(1).strip() if github_actions_match else None
gitlab_runner_code = gitlab_runner_match.group(1).strip() if gitlab_runner_match else None
jenkins_code = jenkins_match.group(1).strip() if jenkins_match else None
circleci_code = circleci_match.group(1).strip() if circleci_match else None
dockercompose_code = dockercompose_match.group(1).strip() if dockercompose_match else None
base_file_name = f"cicd_pipeline_{short_title}"
files = {}
if argocd_code:
files["argocd"] = {"name":f"{base_file_name}_argocd.yaml", "code":argocd_code}
if github_actions_code:
files["githubactions"] = {"name":f"{base_file_name}_githubactions.yaml", "code":github_actions_code}
if gitlab_runner_code:
files["gitlabrunner"] = {"name":f"{base_file_name}_gitlabrunner.yaml", "code":gitlab_runner_code}
if jenkins_code:
files["jenkins"] = {"name":f"{base_file_name}_jenkins.yaml", "code":jenkins_code}
if circleci_code:
files["circleci"] = {"name":f"{base_file_name}_circleci.yaml", "code":circleci_code}
if dockercompose_code:
files["dockercompose"] = {"name":f"{base_file_name}_dockercompose.yaml", "code":dockercompose_code}
for key, value in files.items():
with open(value["name"], "w", encoding="utf-8") as f:
f.write(value["code"])
return files
def main():
st.title("πŸš€βœ¨ Gemini2 CI/CD Gen Pro by [Elias Andrade](https://github.com/chaos4455)")
st.markdown("Generate advanced CI/CD pipelines with ease! πŸš€")
st.markdown("---")
# Layout in columns (sidebar and main area)
col1, col2 = st.columns([1, 3])
with col1:
st.header("βš™οΈ Settings")
with st.expander("✨ AI Settings"):
model_name = st.selectbox("πŸ€– AI Model", ["gemini-2.0-flash-exp", "gemini-1.5-flash"], index=0, help="Choose the AI model.")
temperature = st.slider("🌑️ Temperature", min_value=0.1, max_value=1.0, value=0.7, step=0.1, help="Adjust the AI's creativity.")
top_p = st.slider("Top P", min_value=0.1, max_value=1.0, value=0.8, step=0.1, help="Adjust the AI's sampling.")
top_k = st.slider("Top K", min_value=1, max_value=100, value=40, step=1, help="Adjust the AI's number of candidate tokens.")
max_tokens = st.number_input("πŸ“ Max Tokens", min_value=128, max_value=8192, value=8192, step=128, help="Adjust the maximum size of the response.")
with st.expander("🧰 Pipeline Settings"):
target_systems = st.multiselect("🎯 Target Systems", ["Argo CD", "GitHub Actions", "GitLab Runner", "Jenkins", "CircleCI", "Docker Compose", "Other"], default=["Argo CD", "GitHub Actions", "GitLab Runner"], help="Select the target systems for the pipeline.")
deploy_details = st.text_area("πŸš€ Deployment Details", placeholder="Specify deployment details, e.g., Kubernetes manifests, Dockerfiles, etc.", help="Provide any details about how and where to deploy")
docker_details = st.text_input("🐳 Docker Details", placeholder="Specify details like Docker registry, image names, etc.", help="Provide details about docker builds")
kubernetes_details = st.text_input("☸️ Kubernetes Details", placeholder="Specify details like namespaces, deployments, etc.", help="Provide details about kubernetes deployments")
test_details = st.text_input("πŸ§ͺ Test Details", placeholder="Specify test details or test commands", help="Provide any details about the tests to be executed")
custom_requirements = st.text_input("βž• Custom Requirements:", placeholder="Specific steps or tools (e.g., terraform, ansible)", help="List any specific steps or tools.")
specific_details = st.text_input("ℹ️ Specific Details", placeholder="Special options, edge cases", help="Add specific details for the pipeline generation.")
with col2:
# User's base prompt
prompt_base = st.text_area("πŸ“ Describe the CI/CD Pipeline:",
placeholder=textwrap.dedent("""
Describe your CI/CD pipeline in detail.
Include:
- Steps for building, testing, and deploying your application.
- Specific tools to be used (e.g., Docker, Kubernetes, Argo CD, etc).
- DockerHub details (user, password) or any other registry details.
- Kubernetes cluster details.
- Any custom parameters, configurations, or secrets you need.
If those details are not included, the pipeline will be generated using defaults, and you must fill in the parameters.
"""), key="prompt_base",
help="Provide a detailed description of your CI/CD pipeline.")
if st.button("✨ Generate CI/CD Pipeline"):
if not prompt_base:
st.error("⚠️ Please enter a pipeline description.")
return
with st.spinner("⏳ Generating pipeline..."):
ai_code = generate_cicd_pipeline(
prompt_base,
model_name,
temperature,
top_p,
top_k,
max_tokens,
target_systems,
custom_requirements,
specific_details,
deploy_details,
docker_details,
kubernetes_details,
test_details
)
if ai_code:
st.markdown("### βœ… Generated Pipeline:")
st.code(ai_code, language="text")
short_title = prompt_base[:30].strip().replace(" ", "_").lower()
files = parse_and_save_yaml(ai_code, short_title)
for key, value in files.items():
st.download_button(
label=f"⬇️ Download Pipeline (.{(key)})",
data=value["code"],
file_name=value["name"],
mime="application/x-yaml",
)
else:
st.error("❌ Error generating the pipeline. Check the connection with the AI and try again.")
if __name__ == "__main__":
main()