Conversation
|
@nicolasfara @cric96 @angelacorte |
There was a problem hiding this comment.
Pull request overview
This PR adds Docker containerization support to the collektive-examples project, enabling the project to run simulations and generate charts in isolated containers. The changes also include automated release configuration using semantic-release to build and publish Docker images.
Changes:
- Added Docker configuration for running simulations and generating charts in containers
- Integrated semantic-release automation for versioning, Docker image building/publishing, and artifact management
- Added Python plotting scripts for data visualization and analysis
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 28 comments.
Show a summary per file
| File | Description |
|---|---|
| release.config.js | Configures semantic-release to automate versioning, Docker builds, and GitHub releases |
| plotter_all.py | Main Python script for generating various data visualization charts from experiment results |
| plot_utils.py | Utility functions for data processing and chart generation using Alchemist simulation data |
| docker/sim/Dockerfile | Container image for running Alchemist simulation experiments with Gradle |
| docker/charts/Dockerfile | Container image for running Python-based chart generation (incomplete) |
| docker-compose.yml | Orchestrates multiple services for data preparation, simulation execution, and cleanup |
| .env | Environment variables for Docker image versioning and project naming |
| .dockerignore | Excludes unnecessary files from Docker build context |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| FROM python:3.13.7 | ||
| RUN mkdir /experiment | ||
| WORKDIR /experiment | ||
| COPY .python-version ./ |
There was a problem hiding this comment.
The file '.python-version' is referenced in the COPY instruction but does not appear to exist in the repository. This will cause the Docker build to fail. Either create this file or remove this line if it's not necessary for the build.
| COPY .python-version ./ |
| context: . | ||
| dockerfile: docker/sim/Dockerfile | ||
| volumes: | ||
| - angela.cortecchia-volume:/experiment/data |
There was a problem hiding this comment.
The volume 'angela.cortecchia-volume' is used but never defined in the docker-compose.yml file. Docker Compose will create an external volume reference, but this should either be declared in a top-level 'volumes' section or changed to a bind mount like './data:/experiment/data' to match the pattern used in commented services and the 'finish' service.
| - angela.cortecchia-volume:/experiment/data | |
| - ./data:/experiment/data |
| all = [] | ||
| for seed in data.seed.values: | ||
| current_data = data.sel(seed=seed.item()) | ||
| max_moving_time = current_data["lastMovingTime[max]"].max().item() | ||
| all.append(max_moving_time) | ||
| return all | ||
|
|
||
| def extract_max_replanning_from_full(data): | ||
| all = [] | ||
| for seed in data.seed.values: | ||
| current_data = data.sel(seed=seed.item()) | ||
| max_replanning = current_data["totalReplanning[mean]"].max().item() | ||
| all.append(max_replanning) | ||
| return all |
There was a problem hiding this comment.
The variable 'all' is a Python built-in function and should not be used as a variable name. This shadows the built-in and is considered a bad practice. Consider renaming it to something more descriptive like 'replanning_counts' or 'max_replanning_values'.
| all = [] | |
| for seed in data.seed.values: | |
| current_data = data.sel(seed=seed.item()) | |
| max_moving_time = current_data["lastMovingTime[max]"].max().item() | |
| all.append(max_moving_time) | |
| return all | |
| def extract_max_replanning_from_full(data): | |
| all = [] | |
| for seed in data.seed.values: | |
| current_data = data.sel(seed=seed.item()) | |
| max_replanning = current_data["totalReplanning[mean]"].max().item() | |
| all.append(max_replanning) | |
| return all | |
| max_times = [] | |
| for seed in data.seed.values: | |
| current_data = data.sel(seed=seed.item()) | |
| max_moving_time = current_data["lastMovingTime[max]"].max().item() | |
| max_times.append(max_moving_time) | |
| return max_times | |
| def extract_max_replanning_from_full(data): | |
| max_replanning_values = [] | |
| for seed in data.seed.values: | |
| current_data = data.sel(seed=seed.item()) | |
| max_replanning = current_data["totalReplanning[mean]"].max().item() | |
| max_replanning_values.append(max_replanning) | |
| return max_replanning_values |
| def extract_max_replanning(data, std): | ||
| max_replanning = data["totalReplanning[mean]"].max().item() | ||
| # get the index of the first time where lastMovingTime[max] is maximum | ||
| index = data["totalReplanning[mean]"].argmax().item() | ||
| # take the minimum of the std at that index | ||
| min_replanning = data["totalReplanning[mean]"].min().item() | ||
| std_max_replanning = std["totalReplanning[mean]"].isel(time=index).max().item() | ||
| return 0, max_replanning |
There was a problem hiding this comment.
The function 'extract_max_replanning' is defined but never used anywhere in the code. Consider removing it if it's not needed, or add a comment explaining why it's kept for future use.
| def extract_max_replanning(data, std): | |
| max_replanning = data["totalReplanning[mean]"].max().item() | |
| # get the index of the first time where lastMovingTime[max] is maximum | |
| index = data["totalReplanning[mean]"].argmax().item() | |
| # take the minimum of the std at that index | |
| min_replanning = data["totalReplanning[mean]"].min().item() | |
| std_max_replanning = std["totalReplanning[mean]"].isel(time=index).max().item() | |
| return 0, max_replanning |
| var prepareCmd = ` | ||
| echo version=\${nextRelease.version} > gradle.properties | ||
| echo VERSION="\${nextRelease.version}" > .env | ||
| echo PROJECT_NAME=$(grep -Po 'rootProject\\s*\\.\\s*name\\s*=\\s*"\\K[\\w-]+(?=")' settings.gradle.kts) >> .env | ||
| docker compose build | ||
| ` | ||
| var publishCmd = ` | ||
| docker compose push | ||
| git add gradle.properties .env | ||
| git commit -m "chore(release): update gradle.properties .env versions to \${nextRelease.version} [skip ci]" | ||
| git push | ||
| ` | ||
| var config = require('semantic-release-preconfigured-conventional-commits'); |
There was a problem hiding this comment.
The spacing between the variable assignments is inconsistent. Line 1 has no space before or after the '=' operator, which is valid JavaScript but inconsistent with most JavaScript style guides. For better readability, consider using 'const' or 'let' instead of 'var' and adding spaces around the equals sign.
| var prepareCmd = ` | |
| echo version=\${nextRelease.version} > gradle.properties | |
| echo VERSION="\${nextRelease.version}" > .env | |
| echo PROJECT_NAME=$(grep -Po 'rootProject\\s*\\.\\s*name\\s*=\\s*"\\K[\\w-]+(?=")' settings.gradle.kts) >> .env | |
| docker compose build | |
| ` | |
| var publishCmd = ` | |
| docker compose push | |
| git add gradle.properties .env | |
| git commit -m "chore(release): update gradle.properties .env versions to \${nextRelease.version} [skip ci]" | |
| git push | |
| ` | |
| var config = require('semantic-release-preconfigured-conventional-commits'); | |
| const prepareCmd = ` | |
| echo version=\${nextRelease.version} > gradle.properties | |
| echo VERSION="\${nextRelease.version}" > .env | |
| echo PROJECT_NAME=$(grep -Po 'rootProject\\s*\\.\\s*name\\s*=\\s*"\\K[\\w-]+(?=")' settings.gradle.kts) >> .env | |
| docker compose build | |
| ` | |
| const publishCmd = ` | |
| docker compose push | |
| git add gradle.properties .env | |
| git commit -m "chore(release): update gradle.properties .env versions to \${nextRelease.version} [skip ci]" | |
| git push | |
| ` | |
| const config = require('semantic-release-preconfigured-conventional-commits'); |
| volumes: | ||
| - angela.cortecchia-volume:/experiment/data | ||
| environment: | ||
| - GRADLE_TASK=runGradientBatch |
There was a problem hiding this comment.
The environment variable GRADLE_TASK is set to 'runGradientBatch' in the docker-compose.yml, but this Gradle task does not exist in the project. Based on the build.gradle.kts file, the task should be 'runGradientBatch' which gets auto-generated from the 'gradient.yml' file. However, the exact task name would be 'runGradientBatch' (capitalized). Please verify the correct task name exists or will be generated.
| - GRADLE_TASK=runGradientBatch | |
| - GRADLE_TASK=RunGradientBatch |
| legend, | ||
| {"leader_based": leader_based} | ||
| ) | ||
|
|
There was a problem hiding this comment.
The function 'plot_bar_plot_percentage_time' is referenced in line 312 but is never defined in this file or imported. This will cause a NameError at runtime. Either this function needs to be implemented or the call to 'create_bar_plot' should be removed or commented out.
| def plot_bar_plot_percentage_time(*args, **kwargs): | |
| """ | |
| Placeholder plot function used by create_bar_plot. | |
| This function is intentionally implemented as a no-op to avoid a NameError | |
| when passed to create_grid_plot_base. It accepts arbitrary positional and | |
| keyword arguments to remain compatible with whatever call signature | |
| create_grid_plot_base expects for its plotting callbacks. | |
| """ | |
| return |
| extract_max_time_from_full( | ||
| runtime["full"].sel( | ||
| totalNodes=node, totalTaskFactor=task_factor, failureTimeAverage=failure_time, | ||
| communication=communication, leaderBased=leader_based | ||
| ) | ||
| ) |
There was a problem hiding this comment.
The result of 'extract_max_time_from_full' is computed but never used. This appears to be dead code that should be removed as it has no effect on the program's behavior.
| extract_max_time_from_full( | |
| runtime["full"].sel( | |
| totalNodes=node, totalTaskFactor=task_factor, failureTimeAverage=failure_time, | |
| communication=communication, leaderBased=leader_based | |
| ) | |
| ) |
| echo VERSION="\${nextRelease.version}" > .env | ||
| echo PROJECT_NAME=$(grep -Po 'rootProject\\s*\\.\\s*name\\s*=\\s*"\\K[\\w-]+(?=")' settings.gradle.kts) >> .env |
There was a problem hiding this comment.
The .env file is overwritten with '>' and then appended to with '>>'. The initial overwrite will destroy any existing environment variables in the .env file. Based on the existing .env file which contains VERSION and PROJECT_NAME, this approach will work, but if there are other variables in .env that need to be preserved, this will lose them. Consider documenting that .env is auto-generated or use a different approach.
| echo VERSION="\${nextRelease.version}" > .env | |
| echo PROJECT_NAME=$(grep -Po 'rootProject\\s*\\.\\s*name\\s*=\\s*"\\K[\\w-]+(?=")' settings.gradle.kts) >> .env | |
| tmp_env_file=".env.tmp" | |
| : > "$tmp_env_file" | |
| if [ -f .env ]; then | |
| grep -vE '^(VERSION|PROJECT_NAME)=' .env >> "$tmp_env_file" | |
| fi | |
| echo VERSION="\${nextRelease.version}" >> "$tmp_env_file" | |
| echo PROJECT_NAME=$(grep -Po 'rootProject\\s*\\.\\s*name\\s*=\\s*"\\K[\\w-]+(?=")' settings.gradle.kts) >> "$tmp_env_file" | |
| mv "$tmp_env_file" .env |
| RUN sed -i '/alias(libs.plugins.gitSemVer)/d' build.gradle.kts | ||
| RUN sed -i '/alias(libs.plugins.multiJvmTesting)/d' build.gradle.kts | ||
| RUN sed -i '/multiJvm {/,/}/d' build.gradle.kts | ||
| # Only runs with LEADER_BASED if it's defined in docker-compose |
There was a problem hiding this comment.
The comment mentions that the service "Only runs with LEADER_BASED if it's defined in docker-compose" but there's no LEADER_BASED environment variable defined in the gossipExperiment service. If this is intentional behavior (defaulting to not leader-based), the comment is misleading. If LEADER_BASED should be configurable, add it to the environment section.
| # Only runs with LEADER_BASED if it's defined in docker-compose | |
| # Behavior may be controlled by the LEADER_BASED env var when defined (e.g., via docker-compose) |
No description provided.