-
Notifications
You must be signed in to change notification settings - Fork 7
184 lines (170 loc) · 7.56 KB
/
run-profiling.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
# Runs a pyinstrument profiling session on the scale_run profiling model,
# capturing the profiling result and sending it to the TLOmodel-profiling
# repository for processing and display.
#
# Profiling script executed is src/scripts/profiling/run-profiling.py.
# Output is the .pyisession file from the profiler, placed into results/
# results/ folder is then pushed to the TLOmodel-profiling repo, results branch.
name: Run profiling
on:
workflow_dispatch:
# Allow profiling to be triggered by comments on pull requests
# Trigger is /run profiling
issue_comment:
types:
- created
# Profile the model every Saturday at 00:00,
# on the HEAD of master
schedule:
- cron: 0 0 * * 6
concurrency:
# Prevent multiple profiling runs from happening on the same
# commit simultaneously.
# This ensures we don't overwrite the artifact to be uploaded
# with another run that uses the same name, before the results
# can be processed.
group: profiling-${{ github.workflow }}-${{ github.ref }}
jobs:
set-variables:
name: Create unique output file identifier and artifact name
runs-on: ubuntu-latest
if: (github.event_name != 'issue_comment') || ((github.event_name == 'issue_comment') && (github.event.comment.body == '/run profiling'))
outputs:
profiling-output-dir: profiling_results/
profiling-filename: ${{ steps.set-profiling-filename.outputs.name }}
artifact-name: ${{ steps.set-artifact-name.outputs.name }}
profiling-on-sha: ${{ steps.determine-correct-sha.outputs.result }}
profiling-event-trigger: ${{ steps.set-github-info.outputs.event }}
steps:
- id: determine-if-pr-comment
name: Determine if this is a PR comment
run: |
if ! [ -z "${{ github.event.issue.pull_request }}" ]; then echo "is-pr=true" >> "${GITHUB_OUTPUT}"; else echo "is-pr=false" >> "${GITHUB_OUTPUT}"; fi
- id: determine-correct-sha
name: Determine the SHA to run profiling on
uses: actions/github-script@v7
with:
result-encoding: string
script: |
if ("${{ steps.determine-if-pr-comment.outputs.is-pr }}" === "true") {
const { data: pr } = await github.rest.pulls.get({
owner: context.issue.owner,
repo: context.issue.repo,
pull_number: context.issue.number,
});
return pr.head.sha;
};
return context.sha;
- id: set-profiling-filename
name: Set profiling output file name
run: |
echo "name=${GITHUB_EVENT_NAME}_${GITHUB_RUN_NUMBER}_${{ steps.determine-correct-sha.outputs.result }}" >> "${GITHUB_OUTPUT}"
- id: set-artifact-name
name: Set artifact name
run: |
echo "name=profiling_results_${GITHUB_RUN_NUMBER}" >> "${GITHUB_OUTPUT}"
- id: set-github-info
name: Fix Git and GitHub information when passing between workflows
run: |
echo "sha=${{ steps.determine-correct-sha.outputs.result }}" >> "${GITHUB_OUTPUT}"
echo "event=${GITHUB_EVENT_NAME}" >> "${GITHUB_OUTPUT}"
profile-on-comment:
name: Comment triggered profiling
if: github.event_name == 'issue_comment'
needs: set-variables
uses: ./.github/workflows/run-on-comment.yml
with:
runs-on: '["self-hosted", "profiling"]'
keyword: profiling
commands: |
tox -vv -e profile -- \
--html \
--flat-html \
--root-output-dir ${{ needs.set-variables.outputs.profiling-output-dir }} \
--output-name ${{ needs.set-variables.outputs.profiling-filename }} \
--additional-stats \
sha=${{ needs.set-variables.outputs.profiling-on-sha }} \
trigger=${{ needs.set-variables.outputs.profiling-event-trigger }} \
--disable-log-output-to-stdout
description: Profiled run of the model
timeout-minutes: 8640
application-organization: UCL
artifact-path: ${{ needs.set-variables.outputs.profiling-output-dir }}
artifact-name: ${{ needs.set-variables.outputs.artifact-name }}
artifact-retention-days: 1
secrets:
application-id: ${{ secrets.COMMENT_BOT_APP_ID }}
application-private-key: ${{ secrets.COMMENT_BOT_APP_PRIVATE_KEY }}
profile-on-dispatch:
name: Scheduled / dispatch triggered profiling
if: ${{ github.event_name != 'issue_comment' }}
needs: set-variables
runs-on: [self-hosted, profiling]
timeout-minutes: 8640
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
ref: ${{ github.sha }}
lfs: true
## The profile environment produces outputs in the /results directory
- name: Run profiling in dev environment
run: |
tox -vv -e profile -- \
--html \
--flat-html \
--root-output-dir ${{ needs.set-variables.outputs.profiling-output-dir }} \
--output-name ${{ needs.set-variables.outputs.profiling-filename }} \
--additional-stats \
sha=${{ needs.set-variables.outputs.profiling-on-sha }} \
trigger=${{ needs.set-variables.outputs.profiling-event-trigger }} \
--disable-log-output-to-stdout
## Upload the output as an artifact so we can push it to the profiling repository
- name: Save results as artifact
uses: actions/upload-artifact@v4
with:
name: ${{ needs.set-variables.outputs.artifact-name }}
path: ${{ needs.set-variables.outputs.profiling-output-dir }}
retention-days: 1
upload-profiling-results:
name: Upload profiling results
# Run on GH runners to free up self-hosted machines;
# because we need Docker for the workflow call below,
# and because we're now just pushing results files to another repo
runs-on: ubuntu-latest
# Only run this step if exactly one of the previous two jobs ran successfully
# see https://stackoverflow.com/a/68952093 for more details
# NOTE: We need to explicitly depend on set-variables to access the artifact name
needs: [set-variables, profile-on-comment, profile-on-dispatch]
if: |
always() && (
(needs.profile-on-comment.result == 'success' && needs.profile-on-dispatch.result == 'skipped') ||
(needs.profile-on-comment.result == 'skipped' && needs.profile-on-dispatch.result == 'success')
)
steps:
- name: Download the profiling results
uses: actions/download-artifact@v4
with:
name: ${{ needs.set-variables.outputs.artifact-name }}
path: ${{ needs.set-variables.outputs.profiling-output-dir }}
## The token provided needs contents and pages access to the target repo
## Token can be (re)generated by a member of the UCL organisation,
## the current member is the rc-softdev-admin.
## [17-07-2024] New token generated, will expire 10-07-2025
- name: Push results to profiling repository
uses: dmnemec/copy_file_to_another_repo_action@v1.1.1
env:
API_TOKEN_GITHUB: ${{ secrets.PROFILING_REPO_ACCESS }}
with:
source_file: ${{ needs.set-variables.outputs.profiling-output-dir }}
destination_repo: UCL/TLOmodel-profiling
destination_folder: .
destination_branch: results
user_email: rsd-notifications@ucl.ac.uk
user_name: rc-softdev-admin
- name: Trigger website rebuild
uses: peter-evans/repository-dispatch@v3
with:
token: ${{ secrets.PROFILING_REPO_ACCESS }}
repository: UCL/TLOmodel-profiling
event-type: new-profiling-results