Repository navigation
Refactor CI test environments #87
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 14 commits
Commits
Show all changes
58 commits
Select commit
Hold shift + click to select a range
35103ff
Add PET-OAM
frostedoyster 4e0be09
Apply suggestion from review
frostedoyster cc68b2a
Apply one more suggestion
frostedoyster 7e5fbf5
Add PET-MAD
frostedoyster c2fb4a7
Add package to optional dependencies
frostedoyster 5f5dc43
Merge branch 'develop' into add/pet-mad
chiang-yuan 22b5113
adjust deps group
chiang-yuan 360c2ea
ruff format
chiang-yuan 1babd6d
bump versions; fix tests
chiang-yuan c46c463
remove 3.10, add 3.13
chiang-yuan 0582298
fix diatomics output path
chiang-yuan 0cd6b7c
move stability flow under mlip_arena.flows and benchmarks/stability.py
chiang-yuan 0a0df46
rollback dependencies
chiang-yuan 3b85011
Refactor CI test environments to split conflicting models
chiang-yuan 03e7e83
Refactor CI test dependencies: move model deps to optional group 'all…
chiang-yuan 05204e1
ci: disable fail-fast in test matrix strategy
chiang-yuan c0ff4f1
ci: exclude python 3.13 for GNN/compiled model test groups and skip t…
chiang-yuan 61aabbf
Refactor: remove torch_geometric and torch_scatter dependencies, impl…
chiang-yuan 25c927d
move torch_dftd and matscipy to base dep
chiang-yuan fa2d864
Fix default CI test marker selection
Copilot 08e9304
refactor: apply PyTorch/e3nn compatibility patches at model calculato…
chiang-yuan ea55fd1
refactor: consolidate asymptotes and shifts benchmarks into submit.py
chiang-yuan c026b2a
refactor: implement modular model-level reporting and refactor stabil…
chiang-yuan 5167391
refactor: extract model name and calculator resolution to DRY helpers…
chiang-yuan ca182e0
refactor: simplify calculator resolution and restrict e3nn monkey-pat…
chiang-yuan c6be86e
test stability benchmark run
chiang-yuan a1bfdfe
Merge branch 'develop' into refactor/ci-test-environments
chiang-yuan 400dc08
Merge branch 'develop' into refactor/ci-test-environments
chiang-yuan 68c4d90
move stability from tasks to flows
chiang-yuan 5eaa752
handle cache separately for each test group in CI
chiang-yuan 30b49a5
test external calculators in different groups separately in CI
chiang-yuan 2227a12
mark fairchem uma as xfail
chiang-yuan ba17517
separate orb-models into a separate test group and allow version <0.8.0
chiang-yuan 91b8372
add to() method to custom Data class in collate.py
chiang-yuan ca06673
fix parameter binding for EOSFlow and EVFlow in submit.py
chiang-yuan acd2410
pin orb-models to 0.4.0 in pyproject.toml
chiang-yuan 87b9ed6
gracefully handle pytest exit code 5 (no tests collected) in CI
chiang-yuan e80025c
set torch to 2.2 for orb test group and exclude python 3.13 in CI
chiang-yuan ab25cd5
monkeypatch typing.io in nequip model and exclude orb test group on p…
chiang-yuan e691ef9
remove e3nn optimization defaults workaround in nequip.py
chiang-yuan 20a8e72
remove nequip patch and exclude nequip+py3.13 in CI
chiang-yuan 3fdc925
pin orb-models to 0.5.5 and update torch dep to 2.8 in install-linux.sh
chiang-yuan ff3e9c7
increase test coverage
chiang-yuan ba8ee45
disable cache
chiang-yuan 2365411
refactor(deps): loosen prefect constraint and comment out ipykernel/i…
chiang-yuan fa72868
ci: disable caching in setup-uv step
chiang-yuan c2cf674
test: switch prefect tests skip condition from python 3.11 to 3.12
chiang-yuan f5a8b81
test: run test_stability.py flows inside prefect_test_harness on pyth…
chiang-yuan 024941b
test: isolate PREFECT_HOME in conftest.py to prevent concurrent datab…
chiang-yuan b627ba1
ci: add Free Disk Space step and update fairchem-core version to 2.21…
chiang-yuan 6d8282d
test: remove xfail handler for UMA-S-1P1 to enable testing on CPU in CI
chiang-yuan 9af14d3
test: set PREFECT_HOME env variables at top-level of conftest.py to e…
chiang-yuan 090b273
test: classify uma family under fairchem test group
chiang-yuan 1062fb6
refactor(deps): restore prefect version pin constraint <3.7.0
chiang-yuan f264975
ci: restore -n 5 flag to pytest command to run tests in parallel proc…
chiang-yuan 00f1d2e
refactor(deps): pin fastapi<0.115.0 to fix PrefectRouter AttributeErr…
chiang-yuan fd88b54
ci: disable pytest-xdist and upgrade prefect dependency to avoid fast…
chiang-yuan eb9a3bf
fix(stability): disable prefect persistence and refresh cache; update…
chiang-yuan File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,117 @@ | ||
| from __future__ import annotations | ||
|
|
||
| from pathlib import Path | ||
|
|
||
| from ase.calculators.calculator import BaseCalculator | ||
| from loguru import logger | ||
| from prefect import flow | ||
| from prefect.context import FlowRunContext | ||
|
|
||
| from mlip_arena.flows.stability import compression, heating | ||
| from mlip_arena.models import REGISTRY, MLIPEnum | ||
| from mlip_arena.tasks.stability.analysis import gather_results | ||
| from mlip_arena.tasks.stability.data import get_atoms_from_db | ||
|
|
||
|
|
||
| @flow | ||
| def random_mixtures(calculator: str | BaseCalculator, calculator_kwargs: dict | None = None): | ||
| ctx = FlowRunContext.get() | ||
| parent_task_runner = ctx.task_runner if ctx else None | ||
|
|
||
| if isinstance(calculator, BaseCalculator): | ||
| model_name = calculator.__class__.__name__ | ||
| model = calculator | ||
| family = "custom" | ||
| elif isinstance(calculator, str) and hasattr(MLIPEnum, calculator): | ||
| model_name = calculator | ||
| model = MLIPEnum[calculator] | ||
| family = REGISTRY[model_name]["family"] | ||
| else: | ||
| raise ValueError(f"Unsupported model: {calculator}") | ||
|
|
||
| run_dir = Path(__file__).parent / "stability" / family | ||
|
|
||
| # 1. Run heating | ||
| print(f"Starting stability heating simulation for {model_name}...") | ||
| heating.with_options( | ||
| name=f"stability-heating-{model_name}", | ||
| task_runner=parent_task_runner, | ||
| log_prints=True, | ||
| )(model, run_dir) | ||
|
|
||
| # 2. Run compression | ||
| print(f"Starting stability compression simulation for {model_name}...") | ||
| compression.with_options( | ||
| name=f"stability-compression-{model_name}", | ||
| task_runner=parent_task_runner, | ||
| log_prints=True, | ||
| )(model, run_dir) | ||
|
|
||
| # 3. Analysis / gather results | ||
| print(f"Analyzing stability results for {model_name}...") | ||
| compositions = [] | ||
| for atoms in get_atoms_from_db("random-mixture.db"): | ||
| if len(atoms) == 0: | ||
| continue | ||
| compositions.append(atoms.get_chemical_formula()) | ||
|
|
||
| try: | ||
| df = gather_results(run_dir, prefix=model_name, run_type="nvt") | ||
| df = df[df["formula"].isin(compositions[:120])].copy() # tentatively we only take the first 120 structures | ||
| assert len(df) > 0 | ||
| df.to_parquet(run_dir / f"{model_name}-heating.parquet", index=False) | ||
| except Exception as e: | ||
| logger.warning(f"Error processing model {model_name} (heating): {e}") | ||
|
|
||
| try: | ||
| df = gather_results(run_dir, prefix=model_name, run_type="npt") | ||
| df = df[df["formula"].isin(compositions[:80])].copy() # tentatively we only take the first 80 structures | ||
| assert len(df) > 0 | ||
| df.to_parquet(run_dir / f"{model_name}-compression.parquet", index=False) | ||
| except Exception as e: | ||
| logger.warning(f"Error processing model {model_name} (compression): {e}") | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| from dask.distributed import Client | ||
| from dask_jobqueue import SLURMCluster | ||
| from prefect_dask import DaskTaskRunner | ||
|
|
||
| nodes_per_alloc = 1 | ||
| gpus_per_alloc = 4 | ||
|
|
||
| cluster_kwargs = dict( | ||
| cores=1, | ||
| memory="64 GB", | ||
| processes=1, | ||
| shebang="#!/bin/bash", | ||
| account="matgen", | ||
| walltime="04:00:00", | ||
| job_mem="0", | ||
| job_script_prologue=[ | ||
| "source ~/.bashrc", | ||
| "module load python", | ||
| "source activate /pscratch/sd/c/cyrusyc/.conda/mlip-arena", | ||
| ], | ||
| job_directives_skip=["-n", "--cpus-per-task", "-J"], | ||
| job_extra_directives=[ | ||
| "-J arena-stability", | ||
| "-q preempt", | ||
| "--time-min=00:30:00", | ||
| "--comment=12:00:00", | ||
| f"-N {nodes_per_alloc}", | ||
| "-C gpu", | ||
| f"-G {gpus_per_alloc}", | ||
| ], | ||
| ) | ||
|
|
||
| cluster = SLURMCluster(**cluster_kwargs) | ||
| print(cluster.job_script()) | ||
| cluster.adapt(minimum_jobs=10, maximum_jobs=50) | ||
| client = Client(cluster) | ||
|
|
||
| for model in MLIPEnum: | ||
| random_mixtures.with_options( | ||
| task_runner=DaskTaskRunner(address=client.scheduler.address), | ||
| log_prints=True, | ||
| )(model.name) |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
Repository: atomind-ai/mlip-arena
Length of output: 4853
🏁 Script executed:
Repository: atomind-ai/mlip-arena
Length of output: 1964
🏁 Script executed:
Repository: atomind-ai/mlip-arena
Length of output: 1964
🌐 Web query:
GitHub Actions best practices pinning commit SHA vs version tags security💡 Result:
In GitHub Actions, pinning to a full-length commit SHA is the recommended security best practice for ensuring the immutability of your CI/CD pipelines [1][2]. The primary differences and security considerations are: Commit SHA Pinning - Security: Provides maximum security by referencing a specific, immutable version of the action [1][3]. Even if a repository is compromised and a tag is moved or deleted, the pinned SHA will continue to resolve to the exact same code that you have verified [4][5]. - Enforcement: Administrators can enforce SHA pinning at the organization or repository level via GitHub Actions policies to ensure all workflows use immutable references [1][2]. - Workflow Maintenance: Because SHAs do not auto-update, you must manually update them or use automated dependency management tools like Dependabot or Renovate [2][4]. A common practice is to use a comment in the workflow file to keep track of the original version, such as uses: owner/repo@sha123... # v1.0.0; tools like Dependabot use this convention to suggest updates while maintaining the security benefit of the pin [4][5]. Version Tag Pinning - Security: Referencing a tag (e.g.,
@v1) is mutable and carries significant risk [5][3]. If an attacker gains access to the action's repository, they can overwrite the existing tag to point to malicious code, which would immediately affect your workflows [1][5]. - Convenience: It is more convenient for developers as it allows for automatic updates when tags are moved, but it lacks the security guarantees of an immutable reference [1][6]. - Recommendation: Only pin to tags if you fully trust the creator and the source, such as first-party GitHub-owned actions [5][6]. Even then, SHA pinning remains the superior approach for high-security environments [3]. Summary For production and high-security workflows, you should always pin actions to a full 40-character commit SHA [1][5]. This protects against supply chain attacks where a malicious actor alters a previously trusted tag [2][3]. Automated tools can help manage these updates, allowing you to benefit from both security and maintainability [4][5].Citations:
Pin third-party actions to commit SHAs and disable persisted checkout credentials.
Lines 17 and 20 use floating action version tags (
@v4,@v6), which are mutable and can be exploited to compromise your CI pipeline. The checkout actions (lines 17 and 44) also persist credentials by default, increasing token exposure risk. Pin all actions to specific commit SHAs and disable credential persistence on checkout steps.Suggested hardening diff
Also applies to checkout at line 44 and other floating-tag actions throughout the workflow.
🧰 Tools
🪛 zizmor (1.25.2)
[warning] 16-17: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
[error] 17-17: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
🤖 Prompt for AI Agents
Source: Linters/SAST tools