Run SOMISANA forecast models on MIMS #413
This file contains 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
name: Run SOMISANA forecast models on MIMS | |
on: | |
schedule: | |
# the workflow designed to every 6 hours. Optionally it can also be run every 12 or 24 hours | |
# initialise once a day | |
- cron: '0 0 * * *' | |
# initialise twice a day | |
# - cron: '0 0,12 * * *' | |
workflow_dispatch: | |
inputs: | |
run_date: | |
description: 'Date and time for T0 for the run in format YYYYMMDD_HH' | |
required: false | |
default: '' | |
type: string | |
jobs: | |
# note that the jobs aren't executed in the order they are written below | |
# they are executed in the order depending on the 'needs' attribute of each job | |
build_cli: | |
uses: ./.github/workflows/build_images.yml # Path to your reusable workflow | |
with: | |
IMAGE_ID: cli | |
# set some environment variables | |
envs: | |
runs-on: ubuntu-latest | |
outputs: | |
BRANCH_REF: ${{ steps.BRANCH_REF.outputs.value }} | |
RUN_DATE: ${{ steps.calculate_date.outputs.value }} | |
steps: | |
- name: Calculate run_date | |
id: calculate_date | |
run: | | |
input_run_date=${{ github.event.inputs.run_date || 'unspecified' }} | |
if [[ ${{ github.event_name }} == 'workflow_dispatch' && ${input_run_date} != 'unspecified' ]] | |
then | |
run_date="${{ github.event.inputs.run_date }}" # Use provided run_date | |
else | |
# automatically set the run_date by finding an appropriate time stamp in the past (corresponding to our cron schedule) | |
# Get the current time in UTC | |
current_time=$(date -u +'%Y%m%d_%H') | |
# Extract the hour and calculate the nearest multiple of 12 in the past (as per our cron schedule above) | |
hour=$(echo ${current_time:9:2} | awk '{print int($1 - ($1%12))}') | |
# Correct hour formatting (ensure leading zero) | |
hour=$(printf "%02d" $hour) | |
# Assemble the run_date | |
run_date=$(echo ${current_time:0:8}_${hour}) | |
fi | |
echo "value=$run_date" >> $GITHUB_OUTPUT | |
# Dynamically set the branch ref to the currently executing branch | |
- name: Set the BRANCH_REF | |
id: BRANCH_REF | |
run: | | |
echo "value=${GITHUB_REF##*/}" >> $GITHUB_OUTPUT | |
# everything below here runs using the `mims1` self-hosted runner | |
# This is a server with 128 cpu's and 256 G ram, dedictated to running SOMISANA's operational models | |
# It is possible that we may want to use an additional modelling server (which will be a separate node on MIMS) | |
# In that event, we could put all the code below here in a new reusable workflow called run_ops_mims1.yml | |
# And then set up another one called run_ops_mims2.yml set up in the same way but obviously running different models/domains | |
# (note you'll also have to include another `git pull` command at the end of build_images.yml to make sure the latest images are available on the new server) | |
# | |
cleanup: | |
needs: [envs,build_cli] | |
uses: ./.github/workflows/cleanup.yml # Path to your reusable workflow | |
with: | |
RUNNER_NAME: mims1 | |
BRANCH_REF: ${{ needs.envs.outputs.BRANCH_REF }} | |
# download all the data we'll need to force the models | |
# no need to provide any model specific inputs as we hard code the extent to cover the whole EEZ | |
get_forcing: | |
needs: [envs, build_cli] | |
uses: ./.github/workflows/get_forcing.yml # Path to your reusable workflow | |
with: | |
RUNNER_NAME: mims1 | |
RUN_DATE: ${{ needs.envs.outputs.RUN_DATE }} | |
BRANCH_REF: ${{ needs.envs.outputs.BRANCH_REF }} | |
HDAYS: 5 | |
FDAYS: 5 | |
secrets: inherit | |
# prepare croco config dirs for each domain | |
prep_domains: | |
needs: [envs,get_forcing] | |
strategy: | |
matrix: | |
# running as a matrix strategy allows us to prepare different domains in parallel inside a single job | |
domain: ['sa_southeast_01','sa_west_02'] | |
uses: ./.github/workflows/prep_domain.yml # Path to your reusable workflow | |
with: | |
RUN_DATE: ${{ needs.envs.outputs.RUN_DATE }} | |
BRANCH_REF: ${{ needs.envs.outputs.BRANCH_REF }} | |
RUNNER_NAME: mims1 | |
MODEL: croco_v1.3.1 | |
DOMAIN: ${{ matrix.domain }} | |
COMP: C04 | |
# in future we may want to use different compile options for each domain | |
# one way of handling that may be to add the compile option to each string in the domain variable under the matrix strategy | |
# and then tease out the domain and compile option inside prep_domain.yml | |
# prepare croco boundary forcing for each domain | |
make_forcing: | |
needs: [envs,get_forcing,prep_domains] | |
strategy: | |
matrix: | |
# running as a matrix strategy allows us to prepare different domains in parallel inside a single job | |
domain: ['sa_southeast_01','sa_west_02'] | |
ogcm: ['MERCATOR','HYCOM'] | |
uses: ./.github/workflows/make_forcing.yml # Path to your reusable workflow | |
with: | |
RUN_DATE: ${{ needs.envs.outputs.RUN_DATE }} | |
BRANCH_REF: ${{ needs.envs.outputs.BRANCH_REF }} | |
RUNNER_NAME: mims1 | |
MODEL: croco_v1.3.1 | |
DOMAIN: ${{ matrix.domain }} | |
OGCM: ${{ matrix.ogcm }} | |
HDAYS: 5 | |
FDAYS: 5 | |
# run the model, do the postprocessing, archive the output | |
# | |
# we considered using githubs 'matrix' strategy to run different domains in parallel, | |
# but opted against it as if one of the domains fails, then it cancels all others running in parallel... | |
# so separating the jobs makes it more robust... and also easier to follow in the actions log on github | |
# | |
# we rather run 4 jobs in prallel inside a calleable workflow, called run_all_domains.yml | |
# for now this is 2 domains, each with a single OGCM and both SAWS and GFS forcing | |
# but this could be changed in future, depending on how we develop further | |
# | |
# the point is that run_all_domains.yml must use less than 120 processors in parallel - this is our limit | |
# then we can have sequential calls to run_all_domains.yml in series | |
run_mercator_domains: | |
needs: [envs,get_forcing,prep_domains,make_forcing] | |
uses: ./.github/workflows/run_all_domains.yml # Path to your reusable workflow | |
with: | |
RUN_DATE: ${{ needs.envs.outputs.RUN_DATE }} | |
BRANCH_REF: ${{ needs.envs.outputs.BRANCH_REF }} | |
RUNNER_NAME: mims1 | |
OGCM: MERCATOR | |
SAWS_OK: ${{ needs.get_forcing.outputs.SAWS_OK }} | |
run_hycom_domains: | |
needs: [envs,get_forcing,prep_domains,make_forcing,run_mercator_domains] | |
if: ${{ always() }} # execute even if there was an error with the mercator runs | |
uses: ./.github/workflows/run_all_domains.yml # Path to your reusable workflow | |
with: | |
RUN_DATE: ${{ needs.envs.outputs.RUN_DATE }} | |
BRANCH_REF: ${{ needs.envs.outputs.BRANCH_REF }} | |
RUNNER_NAME: mims1 | |
OGCM: HYCOM | |
SAWS_OK: ${{ needs.get_forcing.outputs.SAWS_OK }} |