Skip to content

Ensure individual properties updated across modules in generic first appointments #993

Ensure individual properties updated across modules in generic first appointments

Ensure individual properties updated across modules in generic first appointments #993

# 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.
## [10-07-2023] The current token will expire 10-07-2024
- 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