quicktest #26
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: PR quicktest | |
# File: quicktest.yaml | |
# Author: Taha Abdullah | |
# Created on: 2023-07-10 | |
# Functionality: This workflow runs FastSurfer on MRI data and runs pytest to check if the results are acceptable. It | |
# also checks if the FastSurfer environment and output already exist, and if not, it creates them. | |
# Usage: This workflow is triggered on a pull request to the dev and main branch. It can also be triggered manually | |
# with workflow-dispatch. | |
# Expected Secrets: | |
# - QUICKTEST_IMAGE_HREF_08mm: URL to a sample 0.8mm image | |
# - QUICKTEST_IMAGE_HREF_1mm: URL to a sample 1mm image | |
# - QUICKTEST_TARGET_HREF_08mm: URL to the reference processing of the sample 0.8mm image | |
# - QUICKTEST_TARGET_HREF_1mm: URL to the reference processing of the sample 1mm image | |
# - QUICKTEST_LICENSE: content of a FreeSurfer license file | |
concurrency: | |
# maybe the group here should actually not depend on the ref (only number would mean there are | |
# not concurrent runs of the same pr) -- but then we should probably add the branch name (for | |
# manually triggered workflows) | |
group: ${{ github.workflow }}-${{ github.event.number }}-${{ github.event.ref }} | |
cancel-in-progress: true | |
on: | |
pull_request: | |
types: [labeled, unlabeled] | |
workflow_dispatch: | |
inputs: | |
docker-image: | |
description: 'Which docker image should be used to run this test (build-cached => build from git)' | |
default: build-cached | |
type: string | |
freesurfer_build_image: | |
description: 'FreeSurfer build image to build with' | |
type: string | |
permissions: read-all | |
env: | |
SUBJECTS_DIR: /tmp/subjects | |
REFERENCE_DIR: /tmp/reference | |
jobs: | |
build-docker-latest: | |
name: 'Check and build the current docker image' | |
runs-on: ubuntu-latest | |
timeout-minutes: 180 | |
outputs: | |
continue: ${{ steps.parse.outputs.CONTINUE }} | |
docker-image: ${{ steps.parse.outputs.DOCKER_IMAGE }} | |
extra-args: ${{ steps.parse.outputs.EXTRA_ARGS }} | |
fs-build-image: ${{ steps.parse-version.outputs.FS_BUILD_IMAGE }} | |
fs-version: ${{ steps.parse-version.outputs.FS_VERSION }} | |
fs-version-short: ${{ steps.parse-version.outputs.FS_VERSION_SHORT }} | |
fastsurfer-home: ${{ steps.parse-version.outputs.FASTSURFER_HOME }} | |
steps: | |
- name: 'Check whether the tests should run' | |
id: parse | |
shell: bash | |
env: | |
GH_TOKEN: ${{ github.token }} | |
run: | | |
h1="Accept: application/vnd.github+json" | |
h2="X-GitHub-Api-Version: 2022-11-28" | |
if [[ "${{ github.event_name }}" == "pull_request" ]] | |
then | |
if [[ "${{ github.event.action }}" != "labeled" ]] && [[ "${{ github.event.action }}" != "unlabeled" ]] | |
then | |
# not a label-related action, should not be triggered | |
echo "The Workflow '${{ github.workflow }}' was triggered by 'pull_request' of type" | |
echo " '${{ github.event.action }}' but should only be triggered by 'labeled' or 'unlabeled' actions." | |
echo "CONTINUE=false" > $GITHUB_OUTPUT | |
exit | |
elif [[ "${{ github.event.label.name }}" == "quicktest" ]] | |
then | |
echo "CONTINUE=true" > $GITHUB_OUTPUT | |
else | |
echo "This is a different label that was attached." | |
echo "CONTINUE=false" > $GITHUB_OUTPUT | |
exit | |
fi | |
echo "DOCKER_IMAGE=build-cached" >> $GITHUB_OUTPUT | |
elif [[ "${{ github.event_name }}" == "workflow_dispatch" ]] | |
then | |
if [[ "${{ inputs }}" == "{}" ]] || "${{ inputs.docker-image }}" == "" ]] ; then | |
echo "DOCKER_IMAGE=build-cached" > $GITHUB_OUTPUT | |
else | |
echo "DOCKER_IMAGE=${{ inputs.docker-image }}" > $GITHUB_OUTPUT | |
fi | |
echo "CONTINUE=true" >> $GITHUB_OUTPUT | |
exit | |
else # this event has no specific rules | |
echo "This workflow is not defined for the event ${{ github.event_name }}!" | |
exit 1 | |
fi | |
if ! gh api -H "$h1" -H "$h2" /repos/${{ github.repository }}/collaborators/${{ github.event.sender.login }} | |
then | |
echo "Only collaborators explicitly listed as collaborators can trigger this workflow!" | |
echo "CONTINUE=false" >> $GITHUB_OUTPUT | |
exit | |
fi | |
# later, we might want to extract additional run options from the pr text or issue comments | |
# these should just be added here | |
# https://api.github.com/repos/${{ github.repository }}/issues/${{ github.number }} | |
# https://api.github.com/repos/${{ github.repository }}/issues/${{ github.number }}/comments | |
# this may also need adaptations in the test script at the bottom | |
echo "EXTRA_ARGS=" >> $GITHUB_OUTPUT | |
- name: Checkout repository | |
if: ${{ steps.parse.outputs.continue && steps.parse.outputs.docker-image == 'build-cached' }} | |
uses: actions/checkout@v4 | |
- name: Get the FreeSurfer version | |
if: ${{ steps.parse.outputs.continue && steps.parse.outputs.docker-image == 'build-cached' }} | |
shell: bash | |
id: parse-version | |
run: | | |
# get the FreeSurfer version from install_fs_pruned.sh | |
{ | |
eval "$(grep "^fslink=" ./Docker/install_fs_pruned.sh)" | |
fs_version="$(basename "$(dirname "$fslink")")" | |
fs_version_short="${fs_version//\./}" | |
echo "FS_VERSION=$fs_version" | |
echo "FS_VERSION_SHORT=$fs_version_short" | |
if [[ -n "${{ inputs.freesurfer_build_image }}" ]] ; then | |
echo "FS_BUILD_IMAGE=${{ inputs.freesurfer_build_image }}" | |
else | |
echo "FS_BUILD_IMAGE=deepmi/fastsurfer-build:freesurfer$fs_version_short" | |
fi | |
echo "FASTSURFER_HOME=$(pwd)" | |
} > $GITHUB_OUTPUT | |
- uses: Deep-MI/FastSurfer/.github/actions/build-docker@dev | |
if: ${{ steps.parse.outputs.continue && steps.parse.outputs.docker-image == 'build-cached' }} | |
# This action needs the "full" checkout (located at ${{ inputs.fastsurfer-home }}) | |
with: | |
fastsurfer-home: ${{ steps.parse-version.outputs.FASTSURFER_HOME }} | |
# currently, this image has to be updated and used to circumvent storage limitations in github actions | |
# and it is also faster to use this prebuilt, reduced-size freesurfer distribution | |
freesurfer-build-image: "${{ steps.parse-version.outputs.FS_BUILD_IMAGE }}" | |
fastsurfer: | |
name: 'Run FastSurfer on sample images' | |
needs: build-docker-latest | |
runs-on: ubuntu-latest | |
timeout-minutes: 180 | |
strategy: | |
# the following matrix strategy will result in one run per subject as matrix is "one-dimensional". | |
# Additional parameters under "include" are then added as additional (dependent) information | |
matrix: | |
subject-id: [0.8mm, 1.0mm] | |
include: | |
- subject-id: 1.0mm | |
file-extension: ".mgz" | |
image-key: QUICKTEST_IMAGE_HREF_1mm | |
- subject-id: 0.8mm | |
file-extension: ".nii.gz" | |
image-key: QUICKTEST_IMAGE_HREF_08mm | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
sparse-checkout: .github/actions | |
- name: Run FastSurfer for ${{ matrix.subject-id }} with the previously created docker container | |
uses: Deep-MI/FastSurfer/.github/actions/run-fastsurfer@dev | |
with: | |
subject-id: ${{ matrix.subject-id }} | |
file-extension: ${{ matrix.file-extension }} | |
image-href: ${{ secrets[matrix.image-key] }} | |
license: ${{ secrets.QUICKTEST_LICENSE }} | |
docker-image: ${{ needs.build-docker-latest.outputs.docker-image }} | |
extra-args: ${{ needs.build-docker-latest.outputs.extra-args }} | |
tests: | |
name: Download data and perform tests (1.0mm) | |
needs: fastsurfer | |
runs-on: ubuntu-latest | |
timeout-minutes: 60 | |
strategy: | |
# the following matrix strategy will result in one run per subject as matrix is "one-dimensional". | |
# Additional parameters under "include" are then added as additional (dependent) information | |
matrix: | |
subject-id: [0.8mm, 1.0mm] | |
include: | |
- subject-id: 0.8mm | |
case-key: QUICKTEST_TARGET_HREF_08mm | |
- subject-id: 1.0mm | |
case-key: QUICKTEST_TARGET_HREF_1mm | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Run tests | |
uses: Deep-MI/FastSurfer/.github/actions/run-tests@dev | |
with: | |
subject-id: ${{ matrix.subject-id }} | |
subjects-dir: ${{ env.SUBJECTS_DIR }} | |
reference-dir: ${{ env.REFERENCE_DIR }} | |
case-href: ${{ secrets[matrix.case-href] }} |