-
Notifications
You must be signed in to change notification settings - Fork 5
203 lines (186 loc) · 7.94 KB
/
calibration.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
name: Calibration
on:
workflow_dispatch:
inputs:
commit:
description: '40-character commit hash'
required: true
default: ""
type: string
schedule:
- cron: 31 2 * * *
env:
REPO_PATH: /mnt/tlo/TLOmodel
OUTPUT_ROOT: /mnt/tlodev2stg/tlo-dev-fs-2/task-runner/output
RUNS_NUMBER: 10
PYTHON_VER: 3.11
RUN_NAME: 021_long_run_all_diseases_run
PROCESS_NAME: 022_long_run_all_diseases_process
jobs:
# Do a single clone from the remote repository, to reduce bandwidth usage.
# The repo is cloned to a directory outside of the runner workspace, because
# we want it to survive the current job, but this also means we can't use the
# `actions/checkout` workflow.
setup:
name: Setup
runs-on: [tlo-dev-vm-1]
strategy:
fail-fast: false
outputs:
# Environment variables can be passed to following steps within the same job by adding
# them to `GITHUB_ENV`, but to pass data to other jobs we have to necessarily use
# `GITHUB_OUTPUT`.
environment_path: ${{ steps.vars.outputs.environment_path }}
worktree_path: ${{ steps.vars.outputs.worktree_path }}
output_dir: ${{ steps.out-dir.outputs.output_dir }}
skip_tasks: ${{ steps.tasks.outputs.skip_tasks }}
tasks: ${{ steps.tasks.outputs.tasks }}
steps:
- name: Generate environment variables
id: vars
run: |
if [[ ${{ github.event_name }} == 'workflow_dispatch' ]] && [[ -n "${{ inputs.commit }}" ]]; then
SHA=${{ inputs.commit }}
else
SHA=${{ github.sha }}
fi
ENV="/mnt/tlo/env-${SHA}"
if [[ -d "${ENV}" ]]; then
echo "Virtual environment directory ${ENV} already exists, leaving..."
exit 1
fi
WORKTREE_PATH="/mnt/tlo/${SHA}"
if [[ -d "${WORKTREE_PATH}" ]]; then
echo "Worktree directory ${WORKTREE_PATH} already exists, leaving..."
exit 1
fi
echo "SHA=${SHA}"
echo "SHA=${SHA}" >> "${GITHUB_ENV}"
echo "ENV=${ENV}"
echo "ENV=${ENV}" >> "${GITHUB_ENV}"
echo "environment_path=${ENV}" >> "${GITHUB_OUTPUT}"
echo "WORKTREE_PATH=${WORKTREE_PATH}"
echo "WORKTREE_PATH=${WORKTREE_PATH}" >> "${GITHUB_ENV}"
echo "worktree_path=${WORKTREE_PATH}" >> "${GITHUB_OUTPUT}"
- name: Clone remote TLO repository and fetch desired commit
run: |
# If the repository doesn't exist on disk, clone it.
if [[ ! -d "${REPO_PATH}" ]]; then
git clone --depth=1 --branch="${{ github.ref_name }}" "https://github.com/${{ github.repository }}.git" "${REPO_PATH}"
fi
# In any case, fetch the requested commit.
git -C "${REPO_PATH}" fetch --depth=1 origin "${SHA}"
- name: Create worktree
run: |
git -C "${REPO_PATH}" worktree add "${WORKTREE_PATH}" ${SHA}
- name: Create virtual environment
run: |
python${PYTHON_VER} -m venv "${ENV}"
source "${ENV}/bin/activate"
pip install -r requirements/dev.txt
pip install -e .
working-directory: "${{ env.WORKTREE_PATH }}"
- name: Generate output directory
id: out-dir
run: |
commit_dir=$(git show -s --date=format:'%Y-%m-%d_%H%M%S' --format=%cd_%h "${SHA}")
output_dir="${OUTPUT_ROOT}/${commit_dir}"
echo "output_dir=${output_dir}"
echo "output_dir=${output_dir}" >> "${GITHUB_ENV}"
echo "output_dir=${output_dir}" >> "${GITHUB_OUTPUT}"
working-directory: "${{ env.WORKTREE_PATH }}"
- name: Generate list of tasks
id: tasks
run: |
SKIP_TASKS="false"
if [[ -d "${output_dir}" ]]; then
echo "Output directory ${output_dir} already exists, setting RUNS_NUMBER to 1 and skipping further task runs"
RUNS_NUMBER=1
# Set variable to make task job run, but exit immediately, so that
# the build doesn't fail.
SKIP_TASKS="true"
fi
echo "SKIP_TASKS=${SKIP_TASKS}"
echo "SKIP_TASKS=${SKIP_TASKS}" >> "${GITHUB_ENV}"
echo "skip_tasks=${SKIP_TASKS}" >> "${GITHUB_OUTPUT}"
RUNS="["
for run in $(seq 0 $((${RUNS_NUMBER} - 1))); do
RUNS="${RUNS}\"${run}\","
done
RUNS="${RUNS}]"
echo "tasks=${RUNS}"
echo "tasks=${RUNS}" >> "${GITHUB_OUTPUT}"
- name: Write info.txt file
if: ${{ env.SKIP_TASKS == 'false' }}
run: |
mkdir -p "${output_dir}"
info_txt="${output_dir}/info.txt"
git -C "${WORKTREE_PATH}" log --pretty=format:"%H%x09%ad%x09%s" --date=iso-strict -n 1 > "${info_txt}"
echo -e "\n${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}" >> "${info_txt}"
echo "Content of ${info_txt}:"
cat "${info_txt}"
# Run the tasks.
tasks:
needs: setup
name: Run task ${{ matrix.index }}
runs-on: [tlo-dev-vm-1, tasks] # Use only runners dedicated to running the tasks.
timeout-minutes: 5760 # = 4 * 24 * 60 minutes = 4 days
strategy:
fail-fast: false
matrix:
index: ${{ fromJSON(needs.setup.outputs.tasks) }}
steps:
- name: Run the task
run: |
if [[ "${{ needs.setup.outputs.skip_tasks }}" == true ]]; then
echo "Nothing to be done, exiting..."
exit 0
fi
source "${{ needs.setup.outputs.environment_path }}/bin/activate"
draw=0
task_output_dir="${{ needs.setup.outputs.output_dir }}/${RUN_NAME}/${draw}/${{ matrix.index }}"
mkdir -p "${task_output_dir}"
tlo scenario-run --output-dir "${task_output_dir}" --draw "${draw}" ${{ matrix.index }} "${{ needs.setup.outputs.worktree_path }}/src/scripts/calibration_analyses/scenarios/long_run_all_diseases.py"
working-directory: "${{ needs.setup.outputs.worktree_path }}"
# Do the postprocessing
postprocess:
name: Post processing
needs: [setup, tasks]
runs-on: [tlo-dev-vm-1, postprocess] # Use only the runners dedicated to postprocessing
strategy:
fail-fast: false
steps:
- name: Run post-processing
run: |
if [[ "${{ needs.setup.outputs.skip_tasks }}" == true ]]; then
echo "Nothing to be done, exiting..."
exit 0
fi
source "${{ needs.setup.outputs.environment_path }}/bin/activate"
task_output_dir="${{ needs.setup.outputs.output_dir }}/${PROCESS_NAME}"
mkdir -p "${task_output_dir}"
python3 "${{ needs.setup.outputs.worktree_path }}/src/scripts/calibration_analyses/analysis_scripts/process.py" "${task_output_dir}" "${RUN_NAME}" "${{ needs.setup.outputs.worktree_path }}/resources"
python3 "${{ needs.setup.outputs.worktree_path }}/src/scripts/task_runner/generate_html.py" "${OUTPUT_ROOT}" > "${OUTPUT_ROOT}/index.html"
working-directory: "${{ needs.setup.outputs.worktree_path }}"
- name: Compress log files
run: |
find "${{ needs.setup.outputs.output_dir }}" -name '*.log' -exec gzip --best --force --verbose '{}' \;
# Cleanup stage, to remove temporary directories and such
cleanup:
name: Cleanup job
timeout-minutes: 10
needs: [setup, tasks, postprocess]
# `always()` to run even if tasks and postprocess are skipped, but make sure
# `setup` was successful, to avoid cleaning up existing worktrees and
# environments used by other builds.
if: ${{ always() && needs.setup.result == 'success' }}
runs-on: [tlo-dev-vm-1]
strategy:
fail-fast: false
steps:
- name: Cleanup worktree
run: |
git -C "${REPO_PATH}" worktree remove -f "${{ needs.setup.outputs.worktree_path }}" || true
- name: Cleanup virtual environment
run: |
rm -rvf "${{ needs.setup.outputs.environment_path }}"