Skip to content

Commit

Permalink
Merge pull request #15 from GallVp/add-exclude-tag-functionality
Browse files Browse the repository at this point in the history
Add exclude tag functionality
  • Loading branch information
sateeshperi authored Nov 28, 2024
2 parents 6bf6fd9 + ee6251d commit d9265f6
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 18 deletions.
17 changes: 14 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,14 +73,24 @@ jobs:
head: modify_main_nextflow_file
base: main

- name: Detect tags
- name: Include tags
id: detect_tags
uses: ./
with:
root: testrepo/test
head: change_module_a
head: modify_main_nextflow_file
base: main
tags: "PIPELINE" # should pick one test

- name: Exclude tags
id: exclude_tags
uses: ./
with:
root: testrepo/test
head: modify_main_nextflow_file
base: main
tags: "test" # should pick up no tests
tags: "PIPELINE" # should pick one test
exclude_tags: "PIPELINE" # should drop the test

- name: Detect multi-line include
id: multi_line_include
Expand All @@ -99,4 +109,5 @@ jobs:
echo Config files: ${{ steps.detect_config_changes.outputs.components }}
echo Additional include file: ${{ steps.detect_additional_include_file.outputs.components }}
echo Tags: ${{ steps.detect_tags.outputs.components }}
echo Exclude tags: ${{ steps.exclude_tags.outputs.components }}
echo Multi-line include: ${{ steps.multi_line_include.outputs.components }}
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,18 @@ steps:
tags: "gpu"
```

You may wish to exclude tests with specific tags. You can do this by specifying the tags in the `exclude_tags` parameter.

```yaml
steps:
- uses: actions/checkout@v4
- uses: adamrtalbot/detect-nf-test
with:
head: ${{ github.sha }}
base: ${{ github.base_ref }}
exclude_tags: "gpu"
```

## Outputs

A list of changed directories or files and their immediate dependencies is returned under the variable `components`.
Expand Down
5 changes: 5 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ inputs:
description: 'List of tags to include in the output as a comma separated list. Default: "".'
required: false
default: ''
exclude_tags:
description: 'List of tags to exclude in the output as a comma separated list. Default: "".'
required: false
default: ''
log_level:
description: 'Log level for the action. Default: "INFO".'
required: false
Expand All @@ -55,3 +59,4 @@ runs:
TYPES: ${{ inputs.types }}
N_PARENTS: ${{ inputs.n_parents }}
TAGS: ${{ inputs.tags }}
EXCLUDE_TAGS: ${{ inputs.exclude_tags }}
49 changes: 35 additions & 14 deletions entrypoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,15 @@
# with changed dependencies, then return as a JSON list

import argparse
import fnmatch
import json
import logging
import os
import yaml
import logging

from enum import Enum
from git import Repo
from pathlib import Path
import fnmatch

import yaml
from git import Repo


class TestTargetType(Enum):
Expand All @@ -39,6 +38,7 @@ class NextflowFile:

def __init__(self, path):
self.path = path
logging.debug(f"Reading {self.path}")
self.lines = self.read_nf_file()
self.includes = self.find_include_statements()

Expand Down Expand Up @@ -229,7 +229,10 @@ def find_common_path(self) -> Path:
nf_path_dir = self.nextflow.path.parent.resolve()
test_path_dir = self.test_path.parent.resolve()
# Find diff between them
diff = nf_path_dir.relative_to(test_path_dir, walk_up=True)
try:
diff = nf_path_dir.relative_to(test_path_dir)
except ValueError:
diff = nf_path_dir
# Return common path
return test_path_dir.joinpath(diff).resolve()

Expand All @@ -240,8 +243,10 @@ def find_tags(self) -> list[str]:
result = []
for line in self.lines:
if line.strip().startswith("tag "):
logging.debug(f"Found tag line: {line}")
tag = line.strip().removeprefix("tag ").strip().strip("'\"").casefold()
result.append(tag)
logging.debug(f"Found tags: {result}")
return result

def detect_if_path_is_in_test(self, path: Path) -> bool:
Expand Down Expand Up @@ -305,12 +310,6 @@ def find_matching_dependencies(self, other_nf_tests):
if nf_test.test_name.casefold() in self.dependencies
]

def find_matching_tags(self, other_nf_tests):
"""
Finds and returns a list of NF tests from `other_nf_tests` that have matching tags in `self.tags`.
"""
return [nf_test for nf_test in other_nf_tests if nf_test.tags in self.tags]

def get_parents(self, n: int) -> Path:
"""
Get the parent directory of a path n levels up.
Expand Down Expand Up @@ -406,6 +405,7 @@ def parse_args() -> argparse.Namespace:
default="",
help="Tags to include.",
)
parser.add_argument("--exclude_tags", type=str, default="", help="Tags to exclude.")
return parser.parse_args()


Expand Down Expand Up @@ -548,6 +548,8 @@ def detect_files(paths: list[Path], suffix: str) -> list[Path]:
logging.basicConfig(level=args.log_level)
# Argparse handling of nargs is a bit rubbish. So we do it manually here.
args.types = args.types.split(",")
args.tags = [tag.strip().casefold() for tag in args.tags.split(",")]
args.exclude_tags = [tag.strip().casefold() for tag in args.exclude_tags.split(",")]
# Quick validation of args.types since we cant do this in argparse
if any(
_type not in ["function", "process", "workflow", "pipeline"]
Expand Down Expand Up @@ -628,13 +630,32 @@ def detect_files(paths: list[Path], suffix: str) -> list[Path]:
nf_test for nf_test in all_nf_tests if nf_test.test_type.value in args.types
]
if args.tags:
logging.debug(f"Filtering down to only relevant test tags: {args.tags}")
logging.debug(f"Filtering down to only included test tags: {args.tags}")
logging.debug(
f"Tests before the filter are: {[test.test_path for test in only_selected_nf_tests]}"
)
only_selected_nf_tests = [
nf_test
for nf_test in only_selected_nf_tests
if nf_test.find_matching_tags(only_selected_nf_tests)
if any(tag in args.tags for tag in nf_test.tags)
]
logging.debug(
f"Tests after the filter are: {[test.test_path for test in only_selected_nf_tests]}"
)

if args.exclude_tags:
logging.debug(f"Excluding test tags: {args.exclude_tags}")
logging.debug(
f"Tests before the filter are: {[test.test_path for test in only_selected_nf_tests]}"
)
only_selected_nf_tests = [
nf_test
for nf_test in only_selected_nf_tests
if all(tag not in args.exclude_tags for tag in nf_test.tags)
]
logging.debug(
f"Tests after the filter are: {[test.test_path for test in only_selected_nf_tests]}"
)
# Go back n_parents directories, remove root from path and stringify
# It's a bit much but might as well do all path manipulation in one place
logging.info("Normalising test file paths")
Expand Down
3 changes: 2 additions & 1 deletion entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ python /entrypoint.py \
${LOG_LEVEL:+"--log-level=$LOG_LEVEL"} \
${TYPES:+"-t=$TYPES"} \
${N_PARENTS:+"--n_parents=$N_PARENTS"} \
${TAGS:+"-T=$TAGS"}
${TAGS:+"-T=$TAGS"} \
${EXCLUDE_TAGS:+"--exclude_tags=$EXCLUDE_TAGS"}

0 comments on commit d9265f6

Please sign in to comment.