easylink 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- easylink-0.1.0/.bandit +2 -0
- easylink-0.1.0/.flake8 +39 -0
- easylink-0.1.0/.github/CODEOWNERS +2 -0
- easylink-0.1.0/.github/pull_request_template.md +21 -0
- easylink-0.1.0/.github/workflows/build.yml +37 -0
- easylink-0.1.0/.github/workflows/deploy.yml +50 -0
- easylink-0.1.0/.gitignore +151 -0
- easylink-0.1.0/CHANGELOG.rst +3 -0
- easylink-0.1.0/Jenkinsfile +259 -0
- easylink-0.1.0/Makefile +101 -0
- easylink-0.1.0/PKG-INFO +93 -0
- easylink-0.1.0/README.rst +63 -0
- easylink-0.1.0/pyproject.toml +11 -0
- easylink-0.1.0/pytype.cfg +14 -0
- easylink-0.1.0/setup.cfg +4 -0
- easylink-0.1.0/setup.py +71 -0
- easylink-0.1.0/src/easylink/__about__.py +19 -0
- easylink-0.1.0/src/easylink/__init__.py +10 -0
- easylink-0.1.0/src/easylink/_version.py +1 -0
- easylink-0.1.0/src/easylink/cli.py +131 -0
- easylink-0.1.0/src/easylink/configuration.py +232 -0
- easylink-0.1.0/src/easylink/graph_components.py +158 -0
- easylink-0.1.0/src/easylink/images/spark_cluster/Dockerfile +16 -0
- easylink-0.1.0/src/easylink/images/spark_cluster/README.md +15 -0
- easylink-0.1.0/src/easylink/implementation.py +138 -0
- easylink-0.1.0/src/easylink/implementation_metadata.yaml +142 -0
- easylink-0.1.0/src/easylink/pipeline.py +188 -0
- easylink-0.1.0/src/easylink/pipeline_graph.py +337 -0
- easylink-0.1.0/src/easylink/pipeline_schema.py +81 -0
- easylink-0.1.0/src/easylink/pipeline_schema_constants/__init__.py +9 -0
- easylink-0.1.0/src/easylink/pipeline_schema_constants/development.py +191 -0
- easylink-0.1.0/src/easylink/pipeline_schema_constants/integration_test.py +39 -0
- easylink-0.1.0/src/easylink/rule.py +185 -0
- easylink-0.1.0/src/easylink/runner.py +154 -0
- easylink-0.1.0/src/easylink/step.py +732 -0
- easylink-0.1.0/src/easylink/steps/dev/README.md +89 -0
- easylink-0.1.0/src/easylink/steps/dev/build-containers-local.sh +12 -0
- easylink-0.1.0/src/easylink/steps/dev/build-containers-remote.sh +12 -0
- easylink-0.1.0/src/easylink/steps/dev/input_data/create_input_files.ipynb +105 -0
- easylink-0.1.0/src/easylink/steps/dev/input_data/input_file_1.csv +10001 -0
- easylink-0.1.0/src/easylink/steps/dev/input_data/input_file_1.parquet +0 -0
- easylink-0.1.0/src/easylink/steps/dev/input_data/input_file_2.csv +10001 -0
- easylink-0.1.0/src/easylink/steps/dev/input_data/input_file_2.parquet +0 -0
- easylink-0.1.0/src/easylink/steps/dev/python_pandas/README.md +25 -0
- easylink-0.1.0/src/easylink/steps/dev/python_pandas/dummy_step.py +125 -0
- easylink-0.1.0/src/easylink/steps/dev/python_pandas/python_pandas.def +33 -0
- easylink-0.1.0/src/easylink/steps/dev/python_pyspark/README.md +32 -0
- easylink-0.1.0/src/easylink/steps/dev/python_pyspark/dummy_step.py +140 -0
- easylink-0.1.0/src/easylink/steps/dev/python_pyspark/python_pyspark.def +36 -0
- easylink-0.1.0/src/easylink/steps/dev/r/README.md +27 -0
- easylink-0.1.0/src/easylink/steps/dev/r/dummy_step.R +129 -0
- easylink-0.1.0/src/easylink/steps/dev/r/r-image.def +29 -0
- easylink-0.1.0/src/easylink/steps/dev/test.py +206 -0
- easylink-0.1.0/src/easylink/utilities/__init__.py +8 -0
- easylink-0.1.0/src/easylink/utilities/data_utils.py +60 -0
- easylink-0.1.0/src/easylink/utilities/general_utils.py +111 -0
- easylink-0.1.0/src/easylink/utilities/paths.py +10 -0
- easylink-0.1.0/src/easylink/utilities/spark.smk +202 -0
- easylink-0.1.0/src/easylink/utilities/validation_utils.py +23 -0
- easylink-0.1.0/src/easylink.egg-info/PKG-INFO +93 -0
- easylink-0.1.0/src/easylink.egg-info/SOURCES.txt +101 -0
- easylink-0.1.0/src/easylink.egg-info/dependency_links.txt +1 -0
- easylink-0.1.0/src/easylink.egg-info/entry_points.txt +2 -0
- easylink-0.1.0/src/easylink.egg-info/not-zip-safe +1 -0
- easylink-0.1.0/src/easylink.egg-info/requires.txt +24 -0
- easylink-0.1.0/src/easylink.egg-info/top_level.txt +1 -0
- easylink-0.1.0/tests/__init__.py +0 -0
- easylink-0.1.0/tests/conftest.py +39 -0
- easylink-0.1.0/tests/e2e/test_easylink_run.py +122 -0
- easylink-0.1.0/tests/e2e/test_step_types.py +83 -0
- easylink-0.1.0/tests/integration/test_snakemake.py +40 -0
- easylink-0.1.0/tests/integration/test_snakemake_slurm.py +69 -0
- easylink-0.1.0/tests/integration/test_snakemake_spark.py +83 -0
- easylink-0.1.0/tests/specifications/common/environment_local.yaml +2 -0
- easylink-0.1.0/tests/specifications/common/input_data.yaml +3 -0
- easylink-0.1.0/tests/specifications/common/pipeline.yaml +13 -0
- easylink-0.1.0/tests/specifications/e2e/environment_slurm.yaml +16 -0
- easylink-0.1.0/tests/specifications/e2e/pipeline.yaml +19 -0
- easylink-0.1.0/tests/specifications/e2e/pipeline_expanded.yaml +29 -0
- easylink-0.1.0/tests/specifications/integration/environment_spark_slurm.yaml +16 -0
- easylink-0.1.0/tests/specifications/integration/pipeline.yaml +4 -0
- easylink-0.1.0/tests/specifications/integration/pipeline_spark.yaml +4 -0
- easylink-0.1.0/tests/unit/__init__.py +0 -0
- easylink-0.1.0/tests/unit/conftest.py +627 -0
- easylink-0.1.0/tests/unit/rule_strings/implemented_rule_local.txt +20 -0
- easylink-0.1.0/tests/unit/rule_strings/implemented_rule_slurm.txt +26 -0
- easylink-0.1.0/tests/unit/rule_strings/pipeline_local.txt +133 -0
- easylink-0.1.0/tests/unit/rule_strings/pipeline_slurm.txt +157 -0
- easylink-0.1.0/tests/unit/rule_strings/target_rule.txt +12 -0
- easylink-0.1.0/tests/unit/rule_strings/validation_rule.txt +10 -0
- easylink-0.1.0/tests/unit/test_cli.py +8 -0
- easylink-0.1.0/tests/unit/test_config.py +207 -0
- easylink-0.1.0/tests/unit/test_data_utils.py +55 -0
- easylink-0.1.0/tests/unit/test_general_utils.py +11 -0
- easylink-0.1.0/tests/unit/test_graph_components.py +138 -0
- easylink-0.1.0/tests/unit/test_implementation.py +25 -0
- easylink-0.1.0/tests/unit/test_pipeline.py +47 -0
- easylink-0.1.0/tests/unit/test_pipeline_graph.py +631 -0
- easylink-0.1.0/tests/unit/test_pipeline_schema.py +156 -0
- easylink-0.1.0/tests/unit/test_rule.py +115 -0
- easylink-0.1.0/tests/unit/test_runner.py +49 -0
- easylink-0.1.0/tests/unit/test_step.py +615 -0
- easylink-0.1.0/tests/unit/test_validations.py +438 -0
easylink-0.1.0/.bandit
ADDED
easylink-0.1.0/.flake8
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
[flake8]
|
|
2
|
+
# Use the following flake8 plugins:
|
|
3
|
+
# ANN : flake8-annotations
|
|
4
|
+
# B,B9 : flake8-bugbear
|
|
5
|
+
# BLK : flake8-black
|
|
6
|
+
# C : mccabe code complexity
|
|
7
|
+
# D : flake8-docstrings
|
|
8
|
+
# DAR : darglint. Not currently in use because it was too slow.
|
|
9
|
+
# F : pyflakes
|
|
10
|
+
# I : flake8-isort
|
|
11
|
+
# S : flake8-bandit
|
|
12
|
+
# W,E : pycodestyle (pep8) warnings and errors
|
|
13
|
+
select = ANN,B,B9,BLK,C,D,E,F,I,S,W
|
|
14
|
+
|
|
15
|
+
# Ignore these flake8 errors across the board.
|
|
16
|
+
extend-ignore =
|
|
17
|
+
ANN101, # Missing type annotation for self
|
|
18
|
+
ANN102, # Missing type annotation for cls
|
|
19
|
+
ANN204, # Missing type annotation for special method
|
|
20
|
+
D100, # Missing docstring in public module
|
|
21
|
+
D104, # Missing docstring in public package
|
|
22
|
+
E203, # Colons should not have whitespace before them (needed for black)
|
|
23
|
+
W503, # Line break before binary operator (needed for black)
|
|
24
|
+
|
|
25
|
+
# Only use strict docstring linting in the api/ or cli/ directory. Unfortunately it's not
|
|
26
|
+
# possible to enable only those directories, so instead we disable strict docstring linting
|
|
27
|
+
# everywhere else.
|
|
28
|
+
# Also allow unused imports in __init__ files.
|
|
29
|
+
per-file-ignores =
|
|
30
|
+
tests/**:D105,D106,D107,D205,D207,D208,D212,D214,D215,D301,D4,S101
|
|
31
|
+
src/vivarium_gbd_access/lib/**:D105,D106,D107,D205,D207,D208,D212,D214,D215,D301,D4
|
|
32
|
+
**/__init__.py:F401
|
|
33
|
+
|
|
34
|
+
# Function complexity and line length
|
|
35
|
+
max-complexity = 10
|
|
36
|
+
max-line-length = 95
|
|
37
|
+
|
|
38
|
+
# Docstrings
|
|
39
|
+
docstring-convention = google
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
## Title: Summary, imperative, start upper case, don't end with a period
|
|
2
|
+
<!-- Ideally, <=50 chars. 50 chars is here..: -->
|
|
3
|
+
|
|
4
|
+
### Description
|
|
5
|
+
<!-- For use in commit message, wrap at 72 chars. 72 chars is here: -->
|
|
6
|
+
- *Category*: <!-- one of bugfix, implementation, refactor, revert,
|
|
7
|
+
test, release, other/misc -->
|
|
8
|
+
- *JIRA issue*: https://jira.ihme.washington.edu/browse/MIC-XYZ
|
|
9
|
+
- *Research reference*: <!--Link to research documentation for code -->
|
|
10
|
+
|
|
11
|
+
### Changes and notes
|
|
12
|
+
<!--
|
|
13
|
+
Change description – why, what, anything unexplained by the above.
|
|
14
|
+
Include guidance to reviewers if changes are complex.
|
|
15
|
+
-->
|
|
16
|
+
|
|
17
|
+
### Verification and Testing
|
|
18
|
+
<!--
|
|
19
|
+
Details on how code was verified. Consider: plots, images, (small) csv files.
|
|
20
|
+
-->
|
|
21
|
+
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# -----------------------------------------------------------------------------
|
|
2
|
+
# - invoked on push, pull_request, or manual trigger
|
|
3
|
+
# - test under at least 3 versions of python
|
|
4
|
+
# -----------------------------------------------------------------------------
|
|
5
|
+
name: build
|
|
6
|
+
on: [push, pull_request, workflow_dispatch]
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
build:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
strategy:
|
|
12
|
+
matrix:
|
|
13
|
+
python-version: ["3.11", "3.12"]
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v3
|
|
16
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
17
|
+
uses: actions/setup-python@v4
|
|
18
|
+
with:
|
|
19
|
+
python-version: ${{ matrix.python-version }}
|
|
20
|
+
- name: Print environment values
|
|
21
|
+
run: |
|
|
22
|
+
python --version
|
|
23
|
+
cat $GITHUB_ENV
|
|
24
|
+
- name: Update pip
|
|
25
|
+
run: |
|
|
26
|
+
python -m pip install --upgrade pip
|
|
27
|
+
- name: Lint
|
|
28
|
+
run: |
|
|
29
|
+
pip install black==22.3.0 isort
|
|
30
|
+
black . --check --diff
|
|
31
|
+
isort . --check --verbose --only-modified --diff
|
|
32
|
+
- name: Install dependencies
|
|
33
|
+
run: |
|
|
34
|
+
pip install .[dev]
|
|
35
|
+
- name: Test
|
|
36
|
+
run: |
|
|
37
|
+
pytest ./tests
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
name: deploy
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
deploy:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
permissions:
|
|
11
|
+
id-token: write
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v3
|
|
14
|
+
- name: Set up Python
|
|
15
|
+
uses: actions/setup-python@v4
|
|
16
|
+
with:
|
|
17
|
+
python-version: '3.11'
|
|
18
|
+
- name: Install dependencies
|
|
19
|
+
run: |
|
|
20
|
+
python --version
|
|
21
|
+
python -m pip install --upgrade pip
|
|
22
|
+
pip install setuptools wheel build
|
|
23
|
+
- name: Test
|
|
24
|
+
run: |
|
|
25
|
+
pip install .[test]
|
|
26
|
+
pytest ./tests
|
|
27
|
+
- name: Build
|
|
28
|
+
run: python -m build
|
|
29
|
+
- name: Publish
|
|
30
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
31
|
+
- name: Send mail
|
|
32
|
+
# Notify when cron job fails
|
|
33
|
+
if: failure()
|
|
34
|
+
uses: dawidd6/action-send-mail@v2
|
|
35
|
+
with:
|
|
36
|
+
# mail server settings
|
|
37
|
+
server_address: smtp.gmail.com
|
|
38
|
+
server_port: 465
|
|
39
|
+
# user credentials
|
|
40
|
+
username: ${{ secrets.NOTIFY_EMAIL }}
|
|
41
|
+
password: ${{ secrets.NOTIFY_PASSWORD }}
|
|
42
|
+
# email subject
|
|
43
|
+
subject: ${{ github.job }} job of ${{ github.repository }} has ${{ job.status }}
|
|
44
|
+
# email body as text
|
|
45
|
+
body: ${{ github.job }} job in worflow ${{ github.workflow }} of ${{ github.repository }} has ${{ job.status }}
|
|
46
|
+
# comma-separated string, send email to
|
|
47
|
+
to: uw_ihme_simulationscience@uw.edu
|
|
48
|
+
# from email name
|
|
49
|
+
from: Vivarium Notifications
|
|
50
|
+
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
**/*.tar
|
|
2
|
+
**/*.tar.gz
|
|
3
|
+
**/*.sif
|
|
4
|
+
|
|
5
|
+
# Byte-compiled / optimized / DLL files
|
|
6
|
+
__pycache__/
|
|
7
|
+
*.py[cod]
|
|
8
|
+
*$py.class
|
|
9
|
+
|
|
10
|
+
# C extensions
|
|
11
|
+
*.so
|
|
12
|
+
|
|
13
|
+
# Distribution / packaging
|
|
14
|
+
.Python
|
|
15
|
+
build/
|
|
16
|
+
develop-eggs/
|
|
17
|
+
dist/
|
|
18
|
+
downloads/
|
|
19
|
+
eggs/
|
|
20
|
+
.eggs/
|
|
21
|
+
lib/
|
|
22
|
+
lib64/
|
|
23
|
+
parts/
|
|
24
|
+
sdist/
|
|
25
|
+
var/
|
|
26
|
+
wheels/
|
|
27
|
+
pip-wheel-metadata/
|
|
28
|
+
share/python-wheels/
|
|
29
|
+
*.egg-info/
|
|
30
|
+
.installed.cfg
|
|
31
|
+
*.egg
|
|
32
|
+
*.pyc
|
|
33
|
+
MANIFEST
|
|
34
|
+
|
|
35
|
+
# PyInstaller
|
|
36
|
+
# Usually these files are written by a python script from a template
|
|
37
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
38
|
+
*.manifest
|
|
39
|
+
*.spec
|
|
40
|
+
|
|
41
|
+
# Installer logs
|
|
42
|
+
pip-log.txt
|
|
43
|
+
pip-delete-this-directory.txt
|
|
44
|
+
|
|
45
|
+
# Unit test / coverage reports
|
|
46
|
+
htmlcov/
|
|
47
|
+
.tox/
|
|
48
|
+
.nox/
|
|
49
|
+
.coverage
|
|
50
|
+
.coverage.*
|
|
51
|
+
.cache
|
|
52
|
+
nosetests.xml
|
|
53
|
+
coverage.xml
|
|
54
|
+
*.cover
|
|
55
|
+
*.py,cover
|
|
56
|
+
.hypothesis/
|
|
57
|
+
.pytest_cache/
|
|
58
|
+
|
|
59
|
+
# Translations
|
|
60
|
+
*.mo
|
|
61
|
+
*.pot
|
|
62
|
+
|
|
63
|
+
# Django stuff:
|
|
64
|
+
*.log
|
|
65
|
+
local_settings.py
|
|
66
|
+
db.sqlite3
|
|
67
|
+
db.sqlite3-journal
|
|
68
|
+
|
|
69
|
+
# Flask stuff:
|
|
70
|
+
instance/
|
|
71
|
+
.webassets-cache
|
|
72
|
+
|
|
73
|
+
# Scrapy stuff:
|
|
74
|
+
.scrapy
|
|
75
|
+
|
|
76
|
+
# Sphinx documentation
|
|
77
|
+
docs/_build/
|
|
78
|
+
|
|
79
|
+
# PyBuilder
|
|
80
|
+
target/
|
|
81
|
+
|
|
82
|
+
# Jupyter Notebook
|
|
83
|
+
.ipynb_checkpoints
|
|
84
|
+
|
|
85
|
+
# IPython
|
|
86
|
+
profile_default/
|
|
87
|
+
ipython_config.py
|
|
88
|
+
|
|
89
|
+
# pyenv
|
|
90
|
+
.python-version
|
|
91
|
+
|
|
92
|
+
# pipenv
|
|
93
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
94
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
95
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
96
|
+
# install all needed dependencies.
|
|
97
|
+
#Pipfile.lock
|
|
98
|
+
|
|
99
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
|
100
|
+
__pypackages__/
|
|
101
|
+
|
|
102
|
+
# Celery stuff
|
|
103
|
+
celerybeat-schedule
|
|
104
|
+
celerybeat.pid
|
|
105
|
+
|
|
106
|
+
# SageMath parsed files
|
|
107
|
+
*.sage.py
|
|
108
|
+
|
|
109
|
+
# Environments
|
|
110
|
+
.env
|
|
111
|
+
.venv
|
|
112
|
+
env/
|
|
113
|
+
venv/
|
|
114
|
+
ENV/
|
|
115
|
+
env.bak/
|
|
116
|
+
venv.bak/
|
|
117
|
+
|
|
118
|
+
# Spyder project settings
|
|
119
|
+
.spyderproject
|
|
120
|
+
.spyproject
|
|
121
|
+
|
|
122
|
+
# Rope project settings
|
|
123
|
+
.ropeproject
|
|
124
|
+
|
|
125
|
+
# mkdocs documentation
|
|
126
|
+
/site
|
|
127
|
+
|
|
128
|
+
# mypy
|
|
129
|
+
.mypy_cache/
|
|
130
|
+
.dmypy.json
|
|
131
|
+
dmypy.json
|
|
132
|
+
|
|
133
|
+
# Pycharm project settings
|
|
134
|
+
.idea/
|
|
135
|
+
|
|
136
|
+
# Vscode project settings
|
|
137
|
+
.vscode/
|
|
138
|
+
|
|
139
|
+
# Local user jupyter notebooks directory
|
|
140
|
+
notebooks/
|
|
141
|
+
|
|
142
|
+
# Mac OS stuff
|
|
143
|
+
.DS_Store
|
|
144
|
+
|
|
145
|
+
# Version
|
|
146
|
+
src/easylink/_version.py
|
|
147
|
+
|
|
148
|
+
# Local specification files
|
|
149
|
+
.specifications/
|
|
150
|
+
|
|
151
|
+
.snakemake/
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
def githubUsernameToSlackName(github_author) {
|
|
2
|
+
// Add team members as necessary
|
|
3
|
+
def mapping = [
|
|
4
|
+
"Jim Albright": "albrja",
|
|
5
|
+
"Steve Bachmeier": "sbachmei",
|
|
6
|
+
"Hussain Jafari": "hjafari",
|
|
7
|
+
"Patrick Nast": "pnast",
|
|
8
|
+
"Rajan Mudambi": "rmudambi",
|
|
9
|
+
]
|
|
10
|
+
return mapping.get(github_author, "channel")
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
pipeline_name="easylink"
|
|
14
|
+
conda_env_name="${pipeline_name}-${BUILD_NUMBER}"
|
|
15
|
+
// using /tmp for things is MUCH faster but not shared between nodes.
|
|
16
|
+
shared_filesystem_path="/mnt/team/simulation_science/priv/engineering/tests"
|
|
17
|
+
conda_env_path="${shared_filesystem_path}/venv/${conda_env_name}"
|
|
18
|
+
// defaults for conda and pip are a local directory /svc-simsci for improved speed.
|
|
19
|
+
// In the past, we used /ihme/code/* on the NFS (which is slower)
|
|
20
|
+
shared_jenkins_node_path="/svc-simsci"
|
|
21
|
+
|
|
22
|
+
pipeline {
|
|
23
|
+
// This agent runs as svc-simsci on node simsci-slurm-sbuild-p01.
|
|
24
|
+
// It has access to standard IHME filesystems and singularity
|
|
25
|
+
agent { label "svc-simsci" }
|
|
26
|
+
|
|
27
|
+
options {
|
|
28
|
+
// Keep 100 old builds.
|
|
29
|
+
buildDiscarder logRotator(numToKeepStr: "100")
|
|
30
|
+
|
|
31
|
+
// Wait 60 seconds before starting the build.
|
|
32
|
+
// If another commit enters the build queue in this time, the first build will be discarded.
|
|
33
|
+
quietPeriod(60)
|
|
34
|
+
|
|
35
|
+
// Fail immediately if any part of a parallel stage fails
|
|
36
|
+
parallelsAlwaysFailFast()
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
parameters {
|
|
40
|
+
string(
|
|
41
|
+
name: "SLACK_TO",
|
|
42
|
+
defaultValue: "simsci-ci-status",
|
|
43
|
+
description: "The Slack channel to send messages to."
|
|
44
|
+
)
|
|
45
|
+
booleanParam(
|
|
46
|
+
name: "DEBUG",
|
|
47
|
+
defaultValue: false,
|
|
48
|
+
description: "Used as needed for debugging purposes."
|
|
49
|
+
)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
environment {
|
|
53
|
+
// Get the branch being built and strip everything but the text after the last "/"
|
|
54
|
+
BRANCH = sh(script: "echo ${GIT_BRANCH} | rev | cut -d '/' -f1 | rev", returnStdout: true).trim()
|
|
55
|
+
TIMESTAMP = sh(script: 'date', returnStdout: true)
|
|
56
|
+
// Specify the path to the .condarc file via environment variable.
|
|
57
|
+
// This file configures the shared conda package cache.
|
|
58
|
+
CONDARC = "${shared_jenkins_node_path}/miniconda3/.condarc"
|
|
59
|
+
CONDA_BIN_PATH = "${shared_jenkins_node_path}/miniconda3/bin"
|
|
60
|
+
// Specify conda env by build number so that we don't have collisions if builds from
|
|
61
|
+
// different branches happen concurrently.
|
|
62
|
+
CONDA_ENV_NAME = "${conda_env_name}"
|
|
63
|
+
CONDA_ENV_PATH = "${conda_env_path}"
|
|
64
|
+
// Set the Pip cache.
|
|
65
|
+
XDG_CACHE_HOME = "${shared_jenkins_node_path}/pip-cache"
|
|
66
|
+
// Jenkins commands run in separate processes, so need to activate the environment every
|
|
67
|
+
// time we run pip, poetry, etc.
|
|
68
|
+
ACTIVATE = "source ${CONDA_BIN_PATH}/activate ${CONDA_ENV_PATH} &> /dev/null"
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
stages {
|
|
72
|
+
stage("Initialization") {
|
|
73
|
+
steps {
|
|
74
|
+
script {
|
|
75
|
+
// Use the name of the branch in the build name
|
|
76
|
+
currentBuild.displayName = "#${BUILD_NUMBER} ${GIT_BRANCH}"
|
|
77
|
+
// Tell BitBucket that a build has started.
|
|
78
|
+
notifyBitbucket()
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
stage("Debug Info") {
|
|
84
|
+
steps {
|
|
85
|
+
echo "Jenkins pipeline run timestamp: ${TIMESTAMP}"
|
|
86
|
+
// Display environment variables from Jenkins.
|
|
87
|
+
echo """Environment:
|
|
88
|
+
ACTIVATE: '${ACTIVATE}'
|
|
89
|
+
BUILD_NUMBER: '${BUILD_NUMBER}'
|
|
90
|
+
BRANCH: '${BRANCH}'
|
|
91
|
+
CONDARC: '${CONDARC}'
|
|
92
|
+
CONDA_BIN_PATH: '${CONDA_BIN_PATH}'
|
|
93
|
+
CONDA_ENV_NAME: '${CONDA_ENV_NAME}'
|
|
94
|
+
CONDA_ENV_PATH: '${CONDA_ENV_PATH}'
|
|
95
|
+
GIT_BRANCH: '${GIT_BRANCH}'
|
|
96
|
+
JOB_NAME: '${JOB_NAME}'
|
|
97
|
+
WORKSPACE: '${WORKSPACE}'
|
|
98
|
+
XDG_CACHE_HOME: '${XDG_CACHE_HOME}'"""
|
|
99
|
+
// display env
|
|
100
|
+
sh "env | sort"
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
stage("Build Environment") {
|
|
105
|
+
environment {
|
|
106
|
+
// Command for activating the base environment. Activating the base environment sets
|
|
107
|
+
// the correct path to the conda binary which is used to create a new conda env.
|
|
108
|
+
ACTIVATE_BASE = "source ${CONDA_BIN_PATH}/activate &> /dev/null"
|
|
109
|
+
}
|
|
110
|
+
steps {
|
|
111
|
+
// The env should have been cleaned out after the last build, but delete it again
|
|
112
|
+
// here just to be safe.
|
|
113
|
+
sh "rm -rf ${CONDA_ENV_PATH}"
|
|
114
|
+
sh "${ACTIVATE_BASE} && make build-env"
|
|
115
|
+
// open permissions for test users to create file in workspace
|
|
116
|
+
sh "chmod 777 ${WORKSPACE}"
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
stage("Install Package") {
|
|
121
|
+
steps {
|
|
122
|
+
// NOTE: If you're having issues with the env not being found, it's possible
|
|
123
|
+
// that 'make install' is generating symlinks. Try adding
|
|
124
|
+
// '&& pip install .' to install a second time w/ realpaths.
|
|
125
|
+
sh "${ACTIVATE} && make install && pip install ."
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
stage("Quality Checks") {
|
|
130
|
+
parallel {
|
|
131
|
+
stage("Format") {
|
|
132
|
+
steps {
|
|
133
|
+
sh "${ACTIVATE} && make format"
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
stage("Lint") {
|
|
138
|
+
steps {
|
|
139
|
+
sh "${ACTIVATE} && make lint"
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
stage("Type Check") {
|
|
144
|
+
steps {
|
|
145
|
+
sh "${ACTIVATE} && make typecheck"
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
stage("Test") {
|
|
152
|
+
parallel {
|
|
153
|
+
stage("Run End-to-End Tests") {
|
|
154
|
+
steps {
|
|
155
|
+
sh "${ACTIVATE} && make e2e"
|
|
156
|
+
publishHTML([
|
|
157
|
+
allowMissing: true,
|
|
158
|
+
alwaysLinkToLastBuild: false,
|
|
159
|
+
keepAll: true,
|
|
160
|
+
reportDir: "output/htmlcov_e2e",
|
|
161
|
+
reportFiles: "index.html",
|
|
162
|
+
reportName: "Coverage Report - E2E Tests",
|
|
163
|
+
reportTitles: ''
|
|
164
|
+
])
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
stage("Run Integration Tests") {
|
|
169
|
+
steps {
|
|
170
|
+
sh "${ACTIVATE} && make integration"
|
|
171
|
+
publishHTML([
|
|
172
|
+
allowMissing: true,
|
|
173
|
+
alwaysLinkToLastBuild: false,
|
|
174
|
+
keepAll: true,
|
|
175
|
+
reportDir: "output/htmlcov_integration",
|
|
176
|
+
reportFiles: "index.html",
|
|
177
|
+
reportName: "Coverage Report - Integration Tests",
|
|
178
|
+
reportTitles: ''
|
|
179
|
+
])
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
stage("Run Unit Tests") {
|
|
184
|
+
steps {
|
|
185
|
+
sh "${ACTIVATE} && make unit"
|
|
186
|
+
publishHTML([
|
|
187
|
+
allowMissing: true,
|
|
188
|
+
alwaysLinkToLastBuild: false,
|
|
189
|
+
keepAll: true,
|
|
190
|
+
reportDir: "output/htmlcov_unit",
|
|
191
|
+
reportFiles: "index.html",
|
|
192
|
+
reportName: "Coverage Report - Unit Tests",
|
|
193
|
+
reportTitles: ''
|
|
194
|
+
])
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
post {
|
|
202
|
+
always {
|
|
203
|
+
script {
|
|
204
|
+
if (env.BRANCH == "main") {
|
|
205
|
+
channelName = "simsci-ci-status"
|
|
206
|
+
} else {
|
|
207
|
+
channelName = "simsci-ci-status-test"
|
|
208
|
+
}
|
|
209
|
+
// Run git command to get the author of the last commit
|
|
210
|
+
developerID = sh(
|
|
211
|
+
script: "git log -1 --pretty=format:'%an'",
|
|
212
|
+
returnStdout: true
|
|
213
|
+
).trim()
|
|
214
|
+
slackID = githubUsernameToSlackName(developerID)
|
|
215
|
+
slackMessage = """
|
|
216
|
+
Job: *${env.JOB_NAME}*
|
|
217
|
+
Build number: #${env.BUILD_NUMBER}
|
|
218
|
+
Build status: *${currentBuild.result}*
|
|
219
|
+
Author: @${slackID}
|
|
220
|
+
Build details: <${env.BUILD_URL}/console|See in web console>
|
|
221
|
+
""".stripIndent()
|
|
222
|
+
|
|
223
|
+
// Must be after setting up slack message
|
|
224
|
+
if (params.DEBUG) {
|
|
225
|
+
echo "Debug is enabled. Not cleaning up."
|
|
226
|
+
} else {
|
|
227
|
+
echo "Cleaning up."
|
|
228
|
+
sh "${ACTIVATE} && make clean"
|
|
229
|
+
sh "rm -rf ${CONDA_ENV_PATH}"
|
|
230
|
+
|
|
231
|
+
// Delete the workspace directory.
|
|
232
|
+
deleteDir()
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Tell BitBucket whether the build succeeded or failed.
|
|
237
|
+
script {
|
|
238
|
+
notifyBitbucket()
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
failure {
|
|
242
|
+
slackSend channel: "#${params.SLACK_TO}",
|
|
243
|
+
message: slackMessage,
|
|
244
|
+
teamDomain: "ihme",
|
|
245
|
+
tokenCredentialId: "slack"
|
|
246
|
+
}
|
|
247
|
+
success {
|
|
248
|
+
script {
|
|
249
|
+
if (params.DEBUG) {
|
|
250
|
+
echo "Debug is enabled. Sending a success message to Slack."
|
|
251
|
+
slackSend channel: "#${params.SLACK_TO}",
|
|
252
|
+
message: slackMessage,
|
|
253
|
+
teamDomain: "ihme",
|
|
254
|
+
tokenCredentialId: "slack"
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
easylink-0.1.0/Makefile
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
this_makefile := $(lastword $(MAKEFILE_LIST)) # Used to automatically list targets
|
|
2
|
+
.DEFAULT_GOAL := list # If someone runs "make", run "make list"
|
|
3
|
+
|
|
4
|
+
# Source files to format, lint, and type check.
|
|
5
|
+
LOCATIONS=src tests
|
|
6
|
+
|
|
7
|
+
# Unless overridden, build conda environment using the package name.
|
|
8
|
+
PACKAGE_NAME = easylink
|
|
9
|
+
SAFE_NAME = $(shell python -c "from pkg_resources import safe_name; print(safe_name(\"$(PACKAGE_NAME)\"))")
|
|
10
|
+
|
|
11
|
+
about_file = $(shell find src -name __about__.py)
|
|
12
|
+
version_file = $(shell find src -name _version.py)
|
|
13
|
+
version_line = $(shell grep "__version__ = " ${version_file})
|
|
14
|
+
PACKAGE_VERSION = $(shell echo ${version_line} | cut -d "=" -f 2 | xargs)
|
|
15
|
+
|
|
16
|
+
# Use this URL to pull IHME Python packages and deploy this package to PyPi.
|
|
17
|
+
IHME_PYPI := https://artifactory.ihme.washington.edu/artifactory/api/pypi/pypi-shared/
|
|
18
|
+
|
|
19
|
+
# If CONDA_ENV_PATH is set (from a Jenkins build), use the -p flag when making Conda env in
|
|
20
|
+
# order to make env at specific path. Otherwise, make a named env at the default path using
|
|
21
|
+
# the -n flag.
|
|
22
|
+
# TODO: [MIC-4953] build w/ multiple python versions
|
|
23
|
+
PYTHON_VERSION ?= 3.11
|
|
24
|
+
CONDA_ENV_NAME ?= ${PACKAGE_NAME}_py${PYTHON_VERSION}
|
|
25
|
+
CONDA_ENV_CREATION_FLAG = $(if $(CONDA_ENV_PATH),-p ${CONDA_ENV_PATH},-n ${CONDA_ENV_NAME})
|
|
26
|
+
|
|
27
|
+
# These are the doc and source code files in this repo.
|
|
28
|
+
# When one of these files changes, it means that Make targets need to run again.
|
|
29
|
+
MAKE_SOURCES := $(shell find . -type d -name "*" ! -path "./.git*" ! -path "./.vscode" ! -path "./output" ! -path "./output/*" ! -path "./archive" ! -path "./dist" ! -path "./output/htmlcov*" ! -path "**/.pytest_cache*" ! -path "**/__pycache__" ! -path "./output/docs_build*" ! -path "./.pytype*" ! -path "." ! -path "./src/${PACKAGE_NAME}/legacy*" ! -path ./.history ! -path "./.history/*" ! -path "./src/${PACKAGE_NAME}.egg-info" ! -path ./.idea ! -path "./.idea/*" )
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
# Phony targets don't produce artifacts.
|
|
33
|
+
.PHONY: .list-targets build-env clean debug deploy-doc deploy-package full help install list quick
|
|
34
|
+
|
|
35
|
+
# List of Make targets is generated dynamically. To add description of target, use a # on the target definition.
|
|
36
|
+
list help: debug .list-targets
|
|
37
|
+
|
|
38
|
+
.list-targets: # Print available Make targets
|
|
39
|
+
@echo
|
|
40
|
+
@echo "Make targets:"
|
|
41
|
+
@grep -i "^[a-zA-Z][a-zA-Z0-9_ \.\-]*: .*[#].*" ${this_makefile} | sort | sed 's/:.*#/ : /g' | column -t -s:
|
|
42
|
+
@echo
|
|
43
|
+
|
|
44
|
+
debug: # Print debug information (environment variables)
|
|
45
|
+
@echo "'make' invoked with these environment variables:"
|
|
46
|
+
@echo "CONDA_ENV_NAME: ${CONDA_ENV_NAME}"
|
|
47
|
+
@echo "IHME_PYPI: ${IHME_PYPI}"
|
|
48
|
+
@echo "LOCATIONS: ${LOCATIONS}"
|
|
49
|
+
@echo "PACKAGE_NAME: ${PACKAGE_NAME}"
|
|
50
|
+
@echo "PACKAGE_VERSION: ${PACKAGE_VERSION}"
|
|
51
|
+
@echo "PYPI_ARTIFACTORY_CREDENTIALS_USR: ${PYPI_ARTIFACTORY_CREDENTIALS_USR} "
|
|
52
|
+
@echo "Make sources: ${MAKE_SOURCES}"
|
|
53
|
+
|
|
54
|
+
build-env: # Make a new conda environment
|
|
55
|
+
@[ "${CONDA_ENV_NAME}" ] && echo "" > /dev/null || ( echo "CONDA_ENV_NAME is not set"; exit 1 )
|
|
56
|
+
conda create ${CONDA_ENV_CREATION_FLAG} python=${PYTHON_VERSION} --yes
|
|
57
|
+
|
|
58
|
+
install: # Install setuptools, install this package in editable mode
|
|
59
|
+
conda install python-graphviz
|
|
60
|
+
pip install --upgrade pip setuptools
|
|
61
|
+
pip install -e .[DEV]
|
|
62
|
+
|
|
63
|
+
format: setup.py pyproject.toml $(MAKE_SOURCES) # Run the code formatter and import sorter
|
|
64
|
+
-black $(LOCATIONS)
|
|
65
|
+
-isort $(LOCATIONS)
|
|
66
|
+
@echo "Ignore, Created by Makefile, `date`" > $@
|
|
67
|
+
|
|
68
|
+
lint: .flake8 .bandit $(MAKE_SOURCES) # Run the code linter and package security vulnerability checker
|
|
69
|
+
-flake8 $(LOCATIONS)
|
|
70
|
+
-safety check
|
|
71
|
+
@echo "Ignore, Created by Makefile, `date`" > $@
|
|
72
|
+
|
|
73
|
+
typecheck: pytype.cfg $(MAKE_SOURCES) # Run the type checker
|
|
74
|
+
-pytype --config=pytype.cfg $(LOCATIONS)
|
|
75
|
+
@echo "Ignore, Created by Makefile, `date`" > $@
|
|
76
|
+
|
|
77
|
+
e2e: $(MAKE_SOURCES) # Run the e2e tests
|
|
78
|
+
export COVERAGE_FILE=./output/.coverage.e2e
|
|
79
|
+
pytest -vvv --runslow --cov --cov-report term --cov-report html:./output/htmlcov_e2e tests/e2e/
|
|
80
|
+
@echo "Ignore, Created by Makefile, `date`" > $@
|
|
81
|
+
|
|
82
|
+
integration: $(MAKE_SOURCES) # Run unit tests
|
|
83
|
+
export COVERAGE_FILE=./output/.coverage.integration
|
|
84
|
+
pytest -vvv --runslow --cov --cov-report term --cov-report html:./output/htmlcov_integration tests/integration/
|
|
85
|
+
@echo "Ignore, Created by Makefile, `date`" > $@
|
|
86
|
+
|
|
87
|
+
unit: $(MAKE_SOURCES) # Run unit tests
|
|
88
|
+
export COVERAGE_FILE=./output/.coverage.unit
|
|
89
|
+
pytest -vvv --runslow --cov --cov-report term --cov-report html:./output/htmlcov_unit tests/unit/
|
|
90
|
+
@echo "Ignore, Created by Makefile, `date`" > $@
|
|
91
|
+
|
|
92
|
+
clean: # Delete build artifacts and do any custom cleanup such as spinning down services
|
|
93
|
+
@rm -rf format lint typecheck build-doc build-package unit e2e integration .pytest_cache .pytype
|
|
94
|
+
@rm -rf dist output
|
|
95
|
+
$(shell find . -type f -name '*py[co]' -delete -o -type d -name __pycache__ -delete)
|
|
96
|
+
|
|
97
|
+
quick: # Run a "quick" build
|
|
98
|
+
$(MAKE) format lint typecheck unit build-doc
|
|
99
|
+
|
|
100
|
+
full: clean # Run a "full" build
|
|
101
|
+
$(MAKE) install quick e2e build-package
|