Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions .github/actions/get-shards/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
name: "Get number of shards"
description: "Get the number of nf-test shards for the current CI job"
inputs:
max_shards:
description: "Maximum number of shards allowed"
required: true
paths:
description: "Component paths to test"
required: false
outputs:
shard:
description: "Array of shard numbers"
value: ${{ steps.shards.outputs.shard }}
total_shards:
description: "Total number of shards"
value: ${{ steps.shards.outputs.total_shards }}
runs:
using: "composite"
steps:
- name: Install nf-test
uses: nf-core/setup-nf-test@v1
with:
version: ${{ env.NFT_VER }}
- name: Get number of shards
id: shards
shell: bash
run: |
# Run nf-test with dynamic parameter
nftest_output=$(nf-test test \
--dry-run \
--profile +docker \
--filter function,workflow,pipeline \
--ci \
--changed-since HEAD^) || {
echo "nf-test command failed with exit code $?"
echo "Full output: $nftest_output"
exit 1
}
echo "nf-test dry-run output: $nftest_output"

# Default values for shard and total_shards
shard="[]"
total_shards=0

# Check if there are related tests
if echo "$nftest_output" | grep -q 'No tests to execute'; then
echo "No related tests found."
else
# Extract the number of related tests
number_of_shards=$(echo "$nftest_output" | sed -n 's|.*Executed \([0-9]*\) tests.*|\1|p')
if [[ -n "$number_of_shards" && "$number_of_shards" -gt 0 ]]; then
shards_to_run=$(( $number_of_shards < ${{ inputs.max_shards }} ? $number_of_shards : ${{ inputs.max_shards }} ))
shard=$(seq 1 "$shards_to_run" | jq -R . | jq -c -s .)
total_shards="$shards_to_run"
else
echo "Unexpected output format. Falling back to default values."
fi
fi

# Write to GitHub Actions outputs
echo "shard=$shard" >> $GITHUB_OUTPUT
echo "total_shards=$total_shards" >> $GITHUB_OUTPUT

# Debugging output
echo "Final shard array: $shard"
echo "Total number of shards: $total_shards"
118 changes: 118 additions & 0 deletions .github/actions/nf-test/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
name: "nf-test Action"
description: "Runs nf-test with common setup steps"
inputs:
profile:
description: "Profile to use"
required: true
shard:
description: "Shard number for this CI job"
required: true
total_shards:
description: "Total number of test shards(NOT the total number of matrix jobs)"
required: true
paths:
description: "Test paths"
required: true

runs:
using: "composite"
steps:
- name: Setup Nextflow
uses: nf-core/setup-nextflow@v2
with:
version: "${{ env.NXF_VERSION }}"

- name: Set up Python
uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5
with:
python-version: "3.11"

- name: Install nf-test
uses: nf-core/setup-nf-test@v1
with:
version: "${{ env.NFT_VER }}"

- name: Setup apptainer
if: contains(inputs.profile, 'singularity')
uses: eWaterCycle/setup-apptainer@main

- name: Set up Singularity
if: contains(inputs.profile, 'singularity')
shell: bash
run: |
mkdir -p $NXF_SINGULARITY_CACHEDIR
mkdir -p $NXF_SINGULARITY_LIBRARYDIR

- name: Conda setup
if: ${{inputs.profile == 'conda'}}
uses: conda-incubator/setup-miniconda@505e6394dae86d6a5c7fbb6e3fb8938e3e863830 # v3
with:
auto-update-conda: true
conda-solver: libmamba
conda-remove-defaults: true

- name: Install pdiff
shell: bash
run: |
python -m pip install pdiff

- name: Clean up Disk space
uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1

# TODO Skip failing conda tests and document their failures
# https://github.com/nf-core/modules/issues/7017
- name: Run nf-test
shell: bash
env:
NFT_DIFF: ${{ env.NFT_DIFF }}
NFT_DIFF_ARGS: ${{ env.NFT_DIFF_ARGS }}
NFT_WORKDIR: ${{ env.NFT_WORKDIR }}
run: |
nf-test test \
--profile=+${{ inputs.profile }} \
--tap=test.tap \
--verbose \
--ci \
--changed-since HEAD^ \
--shard ${{ inputs.shard }}/${{ inputs.total_shards }} \
--filter function,workflow,pipeline

# Save the absolute path of the test.tap file to the output
echo "tap_file_path=$(realpath test.tap)" >> $GITHUB_OUTPUT

- name: Generate test summary
if: always()
shell: bash
run: |
# Add header if it doesn't exist (using a token file to track this)
if [ ! -f ".summary_header" ]; then
echo "# 🚀 nf-test results" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| Status | Test Name | Profile | Shard |" >> $GITHUB_STEP_SUMMARY
echo "|:------:|-----------|---------|-------|" >> $GITHUB_STEP_SUMMARY
touch .summary_header
fi

if [ -f test.tap ]; then
while IFS= read -r line; do
if [[ $line =~ ^ok ]]; then
test_name="${line#ok }"
# Remove the test number from the beginning
test_name="${test_name#* }"
echo "| ✅ | ${test_name} | ${{ inputs.profile }} | ${{ inputs.shard }}/${{ inputs.total_shards }} |" >> $GITHUB_STEP_SUMMARY
elif [[ $line =~ ^not\ ok ]]; then
test_name="${line#not ok }"
# Remove the test number from the beginning
test_name="${test_name#* }"
echo "| ❌ | ${test_name} | ${{ inputs.profile }} | ${{ inputs.shard }}/${{ inputs.total_shards }} |" >> $GITHUB_STEP_SUMMARY
fi
done < test.tap
else
echo "| ⚠️ | No test results found | ${{ inputs.profile }} | ${{ inputs.shard }}/${{ inputs.total_shards }} |" >> $GITHUB_STEP_SUMMARY
fi

- name: Clean up
if: always()
shell: bash
run: |
sudo rm -rf /home/ubuntu/tests/
149 changes: 149 additions & 0 deletions .github/workflows/nf-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
name: Run nf-test
on:
push:
paths-ignore:
- "docs/**"
- "**/meta.yml"
- "**/*.md"
- "**/*.png"
- "**/*.svg"
pull_request:
paths-ignore:
- "docs/**"
- "**/meta.yml"
- "**/*.md"
- "**/*.png"
- "**/*.svg"
release:
types: [published]
workflow_dispatch:
inputs:
runners:
description: "Runners to test on"
type: choice
options:
- "ubuntu-latest"
- "self-hosted"
default: "ubuntu-latest"

# Cancel if a newer run is started
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NFT_DIFF: "pdiff"
NFT_DIFF_ARGS: "--line-numbers --width 120 --expand-tabs=2"
# renovate: datasource=github-releases depName=askimed/nf-test versioning=semver
NFT_VER: "0.9.2"
NFT_WORKDIR: "~"
NXF_ANSI_LOG: false
NXF_SINGULARITY_CACHEDIR: ${{ github.workspace }}/.singularity
NXF_SINGULARITY_LIBRARYDIR: ${{ github.workspace }}/.singularity

jobs:
nf-test-changes:
name: nf-test-changes
runs-on: ${{ github.event.inputs.runners || github.run_number > 1 && 'ubuntu-latest' || 'self-hosted' }}
outputs:
shard: ${{ steps.set-shards.outputs.shard }}
total_shards: ${{ steps.set-shards.outputs.total_shards }}
steps:
- name: Clean Workspace # Purge the workspace in case it's running on a self-hosted runner
run: |
ls -la ./
rm -rf ./* || true
rm -rf ./.??* || true
ls -la ./
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
with:
fetch-depth: 0

- name: get number of shards
id: set-shards
uses: ./.github/actions/get-shards
env:
NFT_VER: ${{ env.NFT_VER }}
with:
max_shards: 7

- name: debug
run: |
echo ${{ steps.set-shards.outputs.shard }}
echo ${{ steps.set-shards.outputs.total_shards }}

nf-test:
runs-on: ${{ github.event.inputs.runners || github.run_number > 1 && 'ubuntu-latest' || 'self-hosted' }}
name: "${{ matrix.profile }} | ${{ matrix.NXF_VER }} | ${{ matrix.shard }}/${{ needs.nf-test-changes.outputs.total_shards }}"
needs: [nf-test-changes]
if: ${{ needs.nf-test-changes.outputs.total_shards != '0' }}
strategy:
fail-fast: false
matrix:
shard: ${{ fromJson(needs.nf-test-changes.outputs.shard) }}
profile: [conda, docker, singularity]
isMaster:
- ${{ github.base_ref == 'master' }}
# Exclude conda and singularity on dev
exclude:
- isMaster: false
profile: "conda"
- isMaster: false
profile: "singularity"
NXF_VER:
# renovate: datasource=github-releases depName=nextflow/nextflow versioning=semver
- "24.10.2"
- "latest-everything"
env:
NXF_ANSI_LOG: false
TOTAL_SHARDS: ${{ needs.nf-test-changes.outputs.total_shards }}

steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
with:
fetch-depth: 0

- name: Run nf-test
uses: ./.github/actions/nf-test
env:
NFT_DIFF: ${{ env.NFT_DIFF }}
NFT_DIFF_ARGS: ${{ env.NFT_DIFF_ARGS }}
NFT_WORKDIR: ${{ env.NFT_WORKDIR }}
with:
profile: ${{ matrix.profile }}
shard: ${{ matrix.shard }}
total_shards: ${{ env.TOTAL_SHARDS }}

confirm-pass:
runs-on: ${{ github.event.inputs.runners || github.run_number > 1 && 'ubuntu-latest' || 'self-hosted' }}
needs: [nf-test]
if: always()
steps:
- name: One or more tests failed
if: ${{ contains(needs.*.result, 'failure') }}
run: exit 1

- name: One or more tests cancelled
if: ${{ contains(needs.*.result, 'cancelled') }}
run: exit 1

- name: All tests ok
if: ${{ contains(needs.*.result, 'success') }}
run: exit 0

- name: debug-print
if: always()
run: |
echo "::group::DEBUG: `needs` Contents"
echo "DEBUG: toJSON(needs) = ${{ toJSON(needs) }}"
echo "DEBUG: toJSON(needs.*.result) = ${{ toJSON(needs.*.result) }}"
echo "::endgroup::"

- name: Clean Workspace # Purge the workspace in case it's running on a self-hosted runner
if: always()
run: |
ls -la ./
rm -rf ./* || true
rm -rf ./.??* || true
ls -la ./
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@ testing/
testing*
*.pyc
null/

nf-test/*
Binary file modified assets/proteinannotator-metromap.excalidraw.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
24 changes: 24 additions & 0 deletions nf-test.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
config {
// location for all nf-test tests
testsDir "."

// nf-test directory including temporary files for each test
workDir System.getenv("NFT_WORKDIR") ?: ".nf-test"

// location of an optional nextflow.config file specific for executing tests
configFile "tests/nextflow.config"

// ignore tests coming from the nf-core/modules repo
ignore 'modules/nf-core/**/*', 'subworkflows/nf-core/**/*'

// run all test with defined profile(s) from the main nextflow.config
profile "test"

// list of filenames or patterns that should be trigger a full test run
triggers 'nextflow.config', 'nf-test.config', 'conf/test.config', 'tests/nextflow.config'

// load the necessary plugins
plugins {
load "nft-utils@0.0.3"
}
}
Loading