Skip to content

Commit 8ec2d93

Browse files
authored
Merge pull request #286 from nf-core/dev
Dev -> Master for v1.12.0 release
2 parents 04ee503 + 755ca35 commit 8ec2d93

File tree

174 files changed

+15748
-2773
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

174 files changed

+15748
-2773
lines changed

.editorconfig

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,20 @@ end_of_line = unset
1818
insert_final_newline = unset
1919
trim_trailing_whitespace = unset
2020
indent_style = unset
21-
indent_size = unset
21+
[/subworkflows/nf-core/**]
22+
charset = unset
23+
end_of_line = unset
24+
insert_final_newline = unset
25+
trim_trailing_whitespace = unset
26+
indent_style = unset
2227

2328
[/assets/email*]
2429
indent_size = unset
30+
31+
# ignore Readme
32+
[README.md]
33+
indent_style = unset
34+
35+
# ignore python
36+
[*.{py,md}]
37+
indent_style = unset

.github/CONTRIBUTING.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ If you're not used to this workflow with git, you can start with some [docs from
2727

2828
## Tests
2929

30+
You can optionally test your changes by running the pipeline locally. Then it is recommended to use the `debug` profile to
31+
receive warnings about process selectors and other debug info. Example: `nextflow run . -profile debug,test,docker --outdir <OUTDIR>`.
32+
3033
When you create a pull request with changes, [GitHub Actions](https://github.com/features/actions) will run automatic tests.
3134
Typically, pull-requests are only fully reviewed when these tests are passing, though of course we can help out before then.
3235

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ Learn more about contributing: [CONTRIBUTING.md](https://github.com/nf-core/fetc
1919
- [ ] If necessary, also make a PR on the nf-core/fetchngs _branch_ on the [nf-core/test-datasets](https://github.com/nf-core/test-datasets) repository.
2020
- [ ] Make sure your code lints (`nf-core lint`).
2121
- [ ] Ensure the test suite passes (`nextflow run . -profile test,docker --outdir <OUTDIR>`).
22+
- [ ] Check for unexpected warnings in debug mode (`nextflow run . -profile debug,test,docker --outdir <OUTDIR>`).
2223
- [ ] Usage Documentation in `docs/usage.md` is updated.
2324
- [ ] Output Documentation in `docs/output.md` is updated.
2425
- [ ] `CHANGELOG.md` is updated.
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
#!/usr/bin/env python
2+
3+
## This script is used to generate scan *.nf.test files for function/process/workflow name and return as a JSON list
4+
# It is functionally similar to nf-test list but fills a gap until feature https://github.com/askimed/nf-test/issues/196 is added
5+
6+
import argparse
7+
import json
8+
import logging
9+
import re
10+
11+
from itertools import chain
12+
from pathlib import Path
13+
14+
15+
def parse_args() -> argparse.Namespace:
16+
"""
17+
Parse command line arguments and return an ArgumentParser object.
18+
19+
Returns:
20+
argparse.ArgumentParser: The ArgumentParser object with the parsed arguments.
21+
"""
22+
parser = argparse.ArgumentParser(
23+
description="Scan *.nf.test files for function/process/workflow name and return as a JSON list"
24+
)
25+
parser.add_argument(
26+
"-p",
27+
"--paths",
28+
nargs="+",
29+
default=["."],
30+
help="List of directories or files to scan",
31+
)
32+
parser.add_argument(
33+
"-l",
34+
"--log-level",
35+
choices=["DEBUG", "INFO", "WARNING", "ERROR"],
36+
default="INFO",
37+
help="Logging level",
38+
)
39+
parser.add_argument(
40+
"-t",
41+
"--types",
42+
nargs="+",
43+
choices=["function", "process", "workflow", "pipeline"],
44+
default=["function", "process", "workflow", "pipeline"],
45+
help="Types of tests to include.",
46+
)
47+
return parser.parse_args()
48+
49+
50+
def find_files(paths: list[str]) -> list[Path]:
51+
"""
52+
Find all files matching pattern *.nf.test recursively from a list of paths.
53+
54+
Args:
55+
paths (list): List of directories or files to scan.
56+
57+
Returns:
58+
list: List of files matching the pattern *.nf.test.
59+
"""
60+
# this is a bit clunky
61+
result = []
62+
for path in paths:
63+
path_obj = Path(path)
64+
# If Path is the exact nf-test file add to list:
65+
if path_obj.match("*.nf.test"):
66+
result.append(path_obj)
67+
# Else recursively search for nf-test files:
68+
else:
69+
for file in path_obj.rglob("*.nf.test"):
70+
result.append(file)
71+
return result
72+
73+
74+
def process_files(files: list[Path]) -> list[str]:
75+
"""
76+
Process the files and return lines that begin with 'workflow', 'process', or 'function' and have a single string afterwards.
77+
78+
Args:
79+
files (list): List of files to process.
80+
81+
Returns:
82+
list: List of lines that match the criteria.
83+
"""
84+
result = []
85+
for file in files:
86+
with open(file, "r") as f:
87+
is_pipeline_test = True
88+
lines = f.readlines()
89+
for line in lines:
90+
line = line.strip()
91+
if line.startswith(("workflow", "process", "function")):
92+
words = line.split()
93+
if len(words) == 2 and re.match(r'^".*"$', words[1]):
94+
result.append(line)
95+
is_pipeline_test = False
96+
97+
# If no results included workflow, process or function
98+
# Add a dummy result to fill the 'pipeline' category
99+
if is_pipeline_test:
100+
result.append("pipeline 'PIPELINE'")
101+
102+
return result
103+
104+
105+
def generate(
106+
lines: list[str], types: list[str] = ["function", "process", "workflow", "pipeline"]
107+
) -> dict[str, list[str]]:
108+
"""
109+
Generate a dictionary of function, process and workflow lists from the lines.
110+
111+
Args:
112+
lines (list): List of lines to process.
113+
types (list): List of types to include.
114+
115+
Returns:
116+
dict: Dictionary with function, process and workflow lists.
117+
"""
118+
result: dict[str, list[str]] = {
119+
"function": [],
120+
"process": [],
121+
"workflow": [],
122+
"pipeline": [],
123+
}
124+
for line in lines:
125+
words = line.split()
126+
if len(words) == 2:
127+
keyword = words[0]
128+
name = words[1].strip("'\"") # Strip both single and double quotes
129+
if keyword in types:
130+
result[keyword].append(name)
131+
return result
132+
133+
134+
if __name__ == "__main__":
135+
136+
# Utility stuff
137+
args = parse_args()
138+
logging.basicConfig(level=args.log_level)
139+
140+
# Parse nf-test files for targets of tests
141+
files = find_files(args.paths)
142+
lines = process_files(files)
143+
result = generate(lines)
144+
145+
# Get only relevant results (specified by -t)
146+
# Unique using a set
147+
target_results = list(
148+
{item for sublist in map(result.get, args.types) for item in sublist}
149+
)
150+
151+
# Print to stdout
152+
print(json.dumps(target_results))

.github/workflows/branch.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919
# NOTE - this doesn't currently work if the PR is coming from a fork, due to limitations in GitHub actions secrets
2020
- name: Post PR comment
2121
if: failure()
22-
uses: mshick/add-pr-comment@v1
22+
uses: mshick/add-pr-comment@b8f338c590a895d50bcbfa6c5859251edc8952fc # v2
2323
with:
2424
message: |
2525
## This PR is against the `master` branch :x:

.github/workflows/ci.yml

Lines changed: 105 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@ on:
1313

1414
env:
1515
NXF_ANSI_LOG: false
16-
NFTEST_VER: "0.8.1"
16+
NFT_VER: "0.8.4"
17+
NFT_WORKDIR: "~"
18+
NFT_DIFF: "pdiff"
19+
NFT_DIFF_ARGS: "--line-numbers --expand-tabs=2"
1720

1821
concurrency:
1922
group: "${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}"
@@ -24,64 +27,110 @@ jobs:
2427
name: Check for changes
2528
runs-on: ubuntu-latest
2629
outputs:
27-
# Expose matched filters as job 'tags' output variable
28-
tags: ${{ steps.filter.outputs.changes }}
30+
changes: ${{ steps.changed_files.outputs.any_modified }}
31+
tags: ${{ steps.list.outputs.tags }}
2932
steps:
33+
- uses: actions/setup-python@v4
34+
with:
35+
python-version: "3.11"
36+
architecture: "x64"
37+
3038
- uses: actions/checkout@v3
31-
- name: Combine all tags.yml files
32-
id: get_username
33-
run: find . -name "tags.yml" -not -path "./.github/*" -exec cat {} + > .github/tags.yml
34-
- name: debug
35-
run: cat .github/tags.yml
36-
- uses: dorny/paths-filter@v2
37-
id: filter
3839
with:
39-
filters: ".github/tags.yml"
40+
fetch-depth: 0
4041

41-
define_nxf_versions:
42-
name: Choose nextflow versions to test against depending on target branch
43-
runs-on: ubuntu-latest
44-
outputs:
45-
matrix: ${{ steps.nxf_versions.outputs.matrix }}
46-
steps:
47-
- id: nxf_versions
42+
- uses: tj-actions/changed-files@v42
43+
id: changed_files
44+
with:
45+
dir_names: "true"
46+
output_renamed_files_as_deleted_and_added: "true"
47+
# Define list of additional rules for testing paths
48+
# Mostly, we define additional 'pipeline' or 'all' tests here
49+
files_yaml: |
50+
".":
51+
- .github/workflows/**
52+
- nf-test.config
53+
- nextflow.config
54+
tests:
55+
- assets/*
56+
- bin/*
57+
- conf/*
58+
- main.nf
59+
- nextflow_schema.json
60+
61+
files_ignore: |
62+
.git*
63+
.gitpod.yml
64+
.prettierignore
65+
.prettierrc.yml
66+
**.md
67+
**.png
68+
modules.json
69+
pyproject.toml
70+
tower.yml
71+
72+
- name: debug
4873
run: |
49-
if [[ "${{ github.event_name }}" == "pull_request" && "${{ github.base_ref }}" == "dev" && "${{ matrix.NXF_VER }}" != "latest-everything" ]]; then
50-
echo matrix='["latest-everything"]' | tee -a $GITHUB_OUTPUT
51-
else
52-
echo matrix='["latest-everything", "23.04.0"]' | tee -a $GITHUB_OUTPUT
53-
fi
74+
echo ${{ steps.changed_files.outputs.any_modified }}
75+
echo ${{ steps.changed_files.outputs.all_changed_files }}
76+
echo ${{ steps.changed_files.outputs.changed_keys }}
77+
78+
- name: nf-test list tags
79+
id: list
80+
if: ${{ steps.changed_files.outputs.any_modified }}
81+
run: |
82+
echo tags=$(python \
83+
.github/python/find_changed_files.py \
84+
-t pipeline workflow process \
85+
-p ${{ steps.changed_files.outputs.all_changed_files }} ${{ steps.changed_files.outputs.changed_keys }} \
86+
) >> $GITHUB_OUTPUT
87+
88+
- name: debug2
89+
run: |
90+
echo ${{ steps.list.outputs.tags }}
5491
5592
test:
56-
name: ${{ matrix.tags }} ${{ matrix.profile }} NF ${{ matrix.NXF_VER }}
57-
needs: [changes, define_nxf_versions]
58-
if: needs.changes.outputs.tags != '[]'
93+
name: ${{ matrix.tags }} ${{ matrix.profile }} NF-${{ matrix.NXF_VER }}
94+
needs: [changes]
95+
if: needs.changes.outputs.changes
5996
runs-on: ubuntu-latest
6097
strategy:
6198
fail-fast: false
6299
matrix:
63-
NXF_VER: ${{ fromJson(needs.define_nxf_versions.outputs.matrix) }}
100+
NXF_VER:
101+
- "latest-everything"
102+
- "23.04"
64103
tags: ["${{ fromJson(needs.changes.outputs.tags) }}"]
65104
profile:
66105
- "docker"
67106

68107
steps:
69108
- name: Check out pipeline code
70-
uses: actions/checkout@v3
109+
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
71110

72111
- name: Install Nextflow
73-
uses: nf-core/setup-nextflow@v1
112+
uses: nf-core/setup-nextflow@b9f764e8ba5c76b712ace14ecbfcef0e40ae2dd8 # v1
74113
with:
75114
version: "${{ matrix.NXF_VER }}"
76115

116+
- uses: actions/setup-python@v4
117+
with:
118+
python-version: "3.11"
119+
architecture: "x64"
120+
121+
- name: Install pdiff to see diff between nf-test snapshots
122+
run: |
123+
python -m pip install --upgrade pip
124+
pip install pdiff
125+
77126
- name: Cache nf-test installation
78127
id: cache-software
79128
uses: actions/cache@v3
80129
with:
81130
path: |
82131
/usr/local/bin/nf-test
83132
/home/runner/.nf-test/nf-test.jar
84-
key: ${{ runner.os }}-${{ env.NFTEST_VER }}-nftest
133+
key: ${{ runner.os }}-${{ env.NFT_VER }}-nftest
85134

86135
- name: Install nf-test
87136
if: steps.cache-software.outputs.cache-hit != 'true'
@@ -91,7 +140,12 @@ jobs:
91140
92141
- name: Run nf-test
93142
run: |
94-
nf-test test --tag ${{ matrix.tags }} --profile "test,${{ matrix.profile }}" --junitxml=test.xml
143+
nf-test test --verbose --tag ${{ matrix.tags }} --profile "+${{ matrix.profile }}" --junitxml=test.xml --tap=test.tap
144+
145+
- uses: pcolby/tap-summary@v1
146+
with:
147+
path: >-
148+
test.tap
95149
96150
- name: Output log on failure
97151
if: failure()
@@ -104,3 +158,23 @@ jobs:
104158
if: always() # always run even if the previous step fails
105159
with:
106160
report_paths: test.xml
161+
162+
confirm-pass:
163+
runs-on: ubuntu-latest
164+
needs:
165+
- changes
166+
- test
167+
if: always()
168+
steps:
169+
- name: All tests ok
170+
if: ${{ !contains(needs.*.result, 'failure') }}
171+
run: exit 0
172+
- name: One or more tests failed
173+
if: ${{ contains(needs.*.result, 'failure') }}
174+
run: exit 1
175+
176+
- name: debug-print
177+
if: always()
178+
run: |
179+
echo "toJSON(needs) = ${{ toJSON(needs) }}"
180+
echo "toJSON(needs.*.result) = ${{ toJSON(needs.*.result) }}"

0 commit comments

Comments
 (0)