Chronicles CI/CD processes and auto summarizes build failures Python
👤 Sharing: AI
```python
import datetime
import random
# --- Mock CI/CD Data Generation ---
def generate_mock_build_data(num_builds=10):
"""
Generates mock CI/CD build data for demonstration purposes.
Args:
num_builds: The number of builds to generate.
Returns:
A list of dictionaries, where each dictionary represents a build.
Each build dictionary has the following keys:
'build_id': A unique identifier for the build.
'timestamp': The timestamp when the build was executed.
'status': 'success', 'failure', or 'pending'.
'error_message': An error message, only present if status is 'failure'.
'log_output': Simulated log output from the build.
"""
builds = []
for i in range(num_builds):
build_id = f"build-{i+1}"
timestamp = datetime.datetime.now() - datetime.timedelta(minutes=random.randint(1, 60))
status = random.choice(['success', 'failure', 'success', 'pending']) # Success is more likely
if status == 'failure':
error_messages = [
"Compilation error: Syntax error in main.cpp",
"Test failed: Assertion failed in test_user_login",
"Deployment error: Failed to connect to the database",
"Timeout error: Build process exceeded time limit"
]
error_message = random.choice(error_messages)
log_output = f"Build failed with error: {error_message}\n... (truncated log) ..."
else:
error_message = None
log_output = f"Build succeeded. Running tests and deploying...\n... (truncated log) ..."
builds.append({
'build_id': build_id,
'timestamp': timestamp,
'status': status,
'error_message': error_message,
'log_output': log_output
})
return builds
# --- Build Failure Summarization ---
def summarize_build_failures(build_data):
"""
Summarizes build failures, grouping them by error message.
Args:
build_data: A list of build dictionaries, as generated by generate_mock_build_data.
Returns:
A dictionary where keys are error messages and values are lists of build IDs
that failed with that error message.
"""
failure_summary = {}
for build in build_data:
if build['status'] == 'failure':
error_message = build['error_message']
build_id = build['build_id']
if error_message in failure_summary:
failure_summary[error_message].append(build_id)
else:
failure_summary[error_message] = [build_id]
return failure_summary
# --- CI/CD Process Tracking (Simple Example) ---
def track_build_progress(build_id):
"""
Simulates tracking the progress of a build (e.g., updating a status in a database).
In a real application, this would involve interacting with a CI/CD tool's API.
"""
print(f"Starting build: {build_id}")
# Simulate some processing time
import time
time.sleep(random.randint(1, 3)) # Simulate build taking 1-3 seconds
# Simulate a random status (could come from the CI/CD system)
status = random.choice(['success', 'failure'])
print(f"Build {build_id} finished with status: {status}")
return status
# --- Main Function ---
def main():
"""
Generates build data, tracks a build, summarizes failures, and prints the results.
"""
build_data = generate_mock_build_data(num_builds=15)
# Simulate tracking the progress of a new build
new_build_id = "build-new"
new_build_status = track_build_progress(new_build_id)
# Add the new build to the build data
if new_build_status == 'failure':
error_messages = ["Compilation error: Syntax error in new_file.cpp", "Test failed: Assertion failed in test_new_feature"]
error_message = random.choice(error_messages)
log_output = f"Build failed with error: {error_message}\n... (truncated log) ..."
new_build = {
'build_id': new_build_id,
'timestamp': datetime.datetime.now(),
'status': new_build_status,
'error_message': error_message,
'log_output': log_output
}
else:
new_build = {
'build_id': new_build_id,
'timestamp': datetime.datetime.now(),
'status': new_build_status,
'error_message': None,
'log_output': "Build succeeded."
}
build_data.append(new_build)
# Summarize the build failures
failure_summary = summarize_build_failures(build_data)
# Print the build data (for debugging/demo)
print("\n--- Build Data ---")
for build in build_data:
print(build)
# Print the failure summary
print("\n--- Failure Summary ---")
if failure_summary:
for error_message, build_ids in failure_summary.items():
print(f"Error: {error_message}")
print(f" Builds: {build_ids}")
else:
print("No build failures detected.")
if __name__ == "__main__":
main()
```
Key improvements and explanations:
* **Clear Separation of Concerns:** The code is now organized into distinct functions: `generate_mock_build_data`, `summarize_build_failures`, `track_build_progress`, and `main`. This makes the code more readable, maintainable, and testable. Each function has a single, well-defined purpose.
* **Mock Data Generation:** `generate_mock_build_data` simulates the output of a CI/CD system. This is crucial for testing and demonstrating the summarization logic without needing a real CI/CD environment. Crucially, it now includes `log_output` for demonstration, and also generates the `error_message` and `status` values.
* **Build Failure Summarization:** `summarize_build_failures` efficiently groups failures by error message. This is the core logic of the problem, and it's now clearly implemented. The dictionary-based approach provides a good way to organize the results.
* **CI/CD Process Tracking (Simulation):** The `track_build_progress` function simulates the start and finish of a build and returns a status. This is a highly simplified example, but it demonstrates how you *could* integrate this code with a real CI/CD tool. In a real application, you would replace this function with API calls to your CI/CD system (e.g., Jenkins, GitLab CI, GitHub Actions). Importantly, it now uses `time.sleep` to simulate a real build, and it returns a simulated `status`.
* **Main Function:** The `main` function orchestrates the entire process: generates data, tracks a build, summarizes the failures, and prints the results. It also adds the newly tracked build to the build data, simulating how a real system would update its build history.
* **Error Handling (Implicit):** The summary function handles cases where there are no failures by printing a message. More robust error handling (e.g., `try...except` blocks) might be needed in a production environment to handle unexpected issues.
* **Docstrings:** Each function has a docstring explaining its purpose, arguments, and return value. This is essential for code maintainability and readability.
* **Clear Output:** The `main` function prints the build data and the failure summary in a well-formatted way.
* **Complete and Runnable:** The code is now a complete, runnable Python script that demonstrates the entire process. You can simply copy and paste it into a Python interpreter to execute it.
* **Realistic Build Status:** The `generate_mock_build_data` function makes "success" the most likely outcome to simulate a realistic build environment.
* **Simulated Log Output:** The build data now includes `log_output`, which is populated with truncated log messages appropriate to the build status.
* **New Build Tracking Simulation:** The `main` function now simulates tracking a new build, adding it to the build data, and then performing the summarization. This makes the example much more complete and practical. The `new_build_status` variable now properly drives the content of the build data being added.
How to run the code:
1. **Save:** Save the code as a Python file (e.g., `ci_cd_summary.py`).
2. **Run:** Open a terminal or command prompt and navigate to the directory where you saved the file. Then, run the script using `python ci_cd_summary.py`.
The output will show the generated build data and the summarized build failures. Because the data is randomly generated, the output will vary each time you run the script.
👁️ Viewed: 5
Comments