mirror of
https://github.com/nix-community/nixvim.git
synced 2025-07-12 02:04:31 +02:00
ci: tag-maintainers extract maintainers in a separate script
Make it easier to test the workflow by moving logic out into separate script.
This commit is contained in:
parent
860754350d
commit
405132bab3
2 changed files with 119 additions and 46 deletions
49
.github/workflows/tag-maintainers.yml
vendored
49
.github/workflows/tag-maintainers.yml
vendored
|
@ -67,52 +67,9 @@ jobs:
|
|||
PR_AUTHOR: "${{ github.event.pull_request.user.login }}"
|
||||
CHANGED_FILES: '${{ steps.changed-files.outputs.changed_files }}'
|
||||
run: |
|
||||
if [[ -z "$CHANGED_FILES" ]]; then
|
||||
echo "No plugin files changed. No maintainers to tag."
|
||||
echo "maintainers=" >> "$GITHUB_OUTPUT"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "Evaluating nixvim meta system for all maintainers..."
|
||||
# Get a JSON object mapping plugin paths to maintainer data.
|
||||
ALL_MAINTAINERS=$(nix eval --impure --expr "
|
||||
let
|
||||
nixvim = import ./.;
|
||||
lib = nixvim.inputs.nixpkgs.lib.extend nixvim.lib.overlay;
|
||||
emptyConfig = lib.nixvim.evalNixvim {
|
||||
modules = [ { _module.check = false; } ];
|
||||
extraSpecialArgs = { pkgs = null; };
|
||||
};
|
||||
inherit (emptyConfig.config.meta) maintainers;
|
||||
in
|
||||
maintainers
|
||||
" --json 2>/dev/null || echo "{}")
|
||||
|
||||
echo "Finding maintainers for changed files..."
|
||||
FOUND_MAINTAINERS=$(
|
||||
echo "$CHANGED_FILES" | while IFS= read -r FILE; do
|
||||
[[ -z "$FILE" ]] && continue
|
||||
PLUGIN_DIR=$(dirname "$FILE")
|
||||
|
||||
# Use jq to find maintainers whose path key ends with the plugin directory.
|
||||
echo "$ALL_MAINTAINERS" | jq -r --arg plugindir "$PLUGIN_DIR" '
|
||||
to_entries[] |
|
||||
select(.key | endswith($plugindir)) |
|
||||
.value[] |
|
||||
select(has("github")) |
|
||||
.github
|
||||
' 2>/dev/null
|
||||
done
|
||||
)
|
||||
|
||||
# De-duplicate the list, remove the PR author, and format as a space-separated string.
|
||||
MAINTAINERS_LIST=$(echo "$FOUND_MAINTAINERS" | grep -v -w -F "$PR_AUTHOR" | sort -u | tr '\n' ' ' | sed 's/ *$//')
|
||||
|
||||
if [[ -z "$MAINTAINERS_LIST" ]]; then
|
||||
echo "No maintainers found for changed files (or only the PR author is a maintainer)."
|
||||
else
|
||||
echo "Found maintainers to notify: $MAINTAINERS_LIST"
|
||||
fi
|
||||
MAINTAINERS_LIST=$(./ci/tag-maintainers/extract-maintainers.py \
|
||||
--changed-files "$CHANGED_FILES" \
|
||||
--pr-author "$PR_AUTHOR")
|
||||
|
||||
echo "maintainers=$MAINTAINERS_LIST" >> "$GITHUB_OUTPUT"
|
||||
|
||||
|
|
116
ci/tag-maintainers/extract-maintainers.py
Executable file
116
ci/tag-maintainers/extract-maintainers.py
Executable file
|
@ -0,0 +1,116 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
Extract maintainers from changed plugin files.
|
||||
|
||||
This script extracts the maintainer extraction logic from the tag-maintainers workflow
|
||||
for easier testing and validation.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import subprocess
|
||||
import sys
|
||||
from typing import List
|
||||
|
||||
|
||||
def run_nix_eval(expr: str) -> str:
|
||||
"""Run a Nix evaluation expression and return the result."""
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["nix", "eval", "--impure", "--json", "--expr", expr],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=True,
|
||||
)
|
||||
return result.stdout.strip()
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"Error running Nix evaluation: {e}", file=sys.stderr)
|
||||
print(f"Stderr: {e.stderr}", file=sys.stderr)
|
||||
return "[]"
|
||||
|
||||
|
||||
def extract_maintainers(changed_files: List[str], pr_author: str) -> List[str]:
|
||||
"""Extract maintainers from changed plugin files."""
|
||||
if not changed_files:
|
||||
print("No plugin files changed. No maintainers to tag.", file=sys.stderr)
|
||||
return []
|
||||
|
||||
print("Finding maintainers for changed files...", file=sys.stderr)
|
||||
|
||||
changed_files_nix = '[ ' + ' '.join(f'"{f}"' for f in changed_files) + ' ]'
|
||||
|
||||
nix_expr = f"""
|
||||
let
|
||||
nixvim = import ./.;
|
||||
lib = nixvim.inputs.nixpkgs.lib;
|
||||
emptyConfig = nixvim.lib.nixvim.evalNixvim {{
|
||||
modules = [ {{ _module.check = false; }} ];
|
||||
extraSpecialArgs.pkgs = null;
|
||||
}};
|
||||
inherit (emptyConfig.config.meta) maintainers;
|
||||
|
||||
changedFiles = {changed_files_nix};
|
||||
|
||||
# Find maintainers for files that match changed plugin directories
|
||||
relevantMaintainers = lib.concatLists (
|
||||
lib.mapAttrsToList (path: maintainerList:
|
||||
let
|
||||
matchingFiles = lib.filter (file:
|
||||
lib.hasSuffix (dirOf file) path
|
||||
) changedFiles;
|
||||
in
|
||||
if matchingFiles != [] then maintainerList else []
|
||||
) maintainers
|
||||
);
|
||||
|
||||
# Extract GitHub usernames
|
||||
githubUsers = lib.concatMap (maintainer:
|
||||
if maintainer ? github then [ maintainer.github ] else []
|
||||
) relevantMaintainers;
|
||||
|
||||
in
|
||||
lib.unique githubUsers
|
||||
"""
|
||||
|
||||
result = run_nix_eval(nix_expr)
|
||||
|
||||
try:
|
||||
maintainers = json.loads(result)
|
||||
except json.JSONDecodeError:
|
||||
print(f"Error parsing Nix evaluation result: {result}", file=sys.stderr)
|
||||
return []
|
||||
|
||||
filtered_maintainers = [m for m in maintainers if m != pr_author]
|
||||
|
||||
if not filtered_maintainers:
|
||||
print("No maintainers found for changed files (or only the PR author is a maintainer).", file=sys.stderr)
|
||||
return []
|
||||
else:
|
||||
print(f"Found maintainers to notify: {' '.join(filtered_maintainers)}", file=sys.stderr)
|
||||
return filtered_maintainers
|
||||
|
||||
|
||||
def main() -> None:
|
||||
"""Main function to handle command line arguments and run the extraction."""
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Extract maintainers from changed plugin files"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--changed-files",
|
||||
help="Newline-separated list of changed files",
|
||||
default="",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--pr-author",
|
||||
required=True,
|
||||
help="GitHub username of the PR author",
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
changed_files = [f.strip() for f in args.changed_files.split('\n') if f.strip()]
|
||||
maintainers = extract_maintainers(changed_files, args.pr_author)
|
||||
print(' '.join(maintainers))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
Loading…
Add table
Add a link
Reference in a new issue