Skip to content
Merged
4 changes: 2 additions & 2 deletions .github/workflows/build-deploy-non-framework-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,11 @@ jobs:
python -m poetry install
python -m pip install -e ../datasets
- name: Update HTML theme options
run: python dev/update-html-themes.py
run: python -m devtool.update_html_themes
- name: Build baselines docs
run: ./dev/build-baseline-docs.sh
- name: Build examples docs
run: python dev/build-example-docs.py
run: python -m devtool.build_example_docs
- name: Build datasets docs
run: ./datasets/dev/build-flwr-datasets-docs.sh
- name: Deploy docs
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/datasets-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ on:
- main
paths:
- "datasets/**"
- "dev/devtool/**"
- ".github/workflows/datasets-*.yml"
pull_request:
branches:
- main
paths:
- "datasets/**"
- "dev/devtool/**"
- ".github/workflows/datasets-*.yml"

concurrency:
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/framework-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ jobs:
filters: |
framework:
- 'framework/**/*'
- 'dev/devtool/**'
- '.github/workflows/framework-test.yml'
ex_bench:
- 'examples/**/*'
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/repo-check-pr-title.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@ jobs:
- name: Check PR title format
env:
PR_TITLE: ${{ github.event.pull_request.title }}
run: python ./dev/check_pr_title.py "$PR_TITLE"
run: PYTHONPATH=dev python -m devtool.check_pr_title "$PR_TITLE"
2 changes: 1 addition & 1 deletion dev/changelog_config.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Defines the PR title format to be used in the `check_pr_title.py` script
# Defines the PR title format to be used in the `devtool.check_pr_title` script
# and in the `update_changelog.py` script

type = ["ci", "docs", "feat", "fix", "refactor", "break"]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
import subprocess
from pathlib import Path

ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
INDEX = os.path.join(ROOT, "examples", "docs", "source", "index.rst")
ROOT = Path(__file__).resolve().parents[2]
INDEX = ROOT / "examples" / "docs" / "source" / "index.rst"

initial_text = """
Flower Examples Documentation
Expand Down Expand Up @@ -179,14 +179,14 @@ def _copy_markdown_files(example):
if file.endswith(".md"):
src = os.path.join(example, file)
dest = os.path.join(
ROOT, "examples", "docs", "source", os.path.basename(example) + ".md"
str(ROOT), "examples", "docs", "source", os.path.basename(example) + ".md"
)
shutil.copyfile(src, dest)


def _add_gh_button(example):
gh_text = f'[<img src="_static/view-gh.png" alt="View on GitHub" width="200"/>](https://github.com/adap/flower/blob/main/examples/{example})'
readme_file = os.path.join(ROOT, "examples", "docs", "source", example + ".md")
readme_file = os.path.join(str(ROOT), "examples", "docs", "source", example + ".md")
with open(readme_file, "r+") as f:
content = f.read()
if gh_text not in content:
Expand All @@ -200,7 +200,7 @@ def _add_gh_button(example):

def _copy_images(example):
static_dir = os.path.join(example, "_static")
dest_dir = os.path.join(ROOT, "examples", "docs", "source", "_static")
dest_dir = os.path.join(str(ROOT), "examples", "docs", "source", "_static")
if os.path.isdir(static_dir):
for file in os.listdir(static_dir):
if file.endswith((".jpg", ".png", ".jpeg")):
Expand All @@ -220,10 +220,10 @@ def _add_all_entries():


def _main():
if os.path.exists(INDEX):
os.remove(INDEX)
if INDEX.exists():
INDEX.unlink()

with open(INDEX, "w") as index_file:
with INDEX.open("w", encoding="utf-8") as index_file:
index_file.write(initial_text)

examples_dir = os.path.join(ROOT, "examples")
Expand All @@ -238,7 +238,7 @@ def _main():
if not _add_table_entry(example_path, "advanced", "advanced"):
_add_table_entry(example_path, "", "other")

with open(INDEX, "a") as index_file:
with INDEX.open("a", encoding="utf-8") as index_file:
index_file.write(categories["quickstart"]["table"])

index_file.write("\nAdvanced Examples\n-----------------\n")
Expand Down
34 changes: 24 additions & 10 deletions dev/check_pr_title.py → dev/devtool/check_pr_title.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,20 @@
# ==============================================================================
"""Used to check a given PR title format."""

import pathlib
import re
import sys
import tomllib
from pathlib import Path
from typing import Any

if __name__ == "__main__":

pr_title = sys.argv[1]
def _load_config() -> dict[str, Any]:
config_path = Path(__file__).resolve().parent.parent / "changelog_config.toml"
with config_path.open("rb") as file:
return tomllib.load(file)

# Load the YAML configuration
with (pathlib.Path(__file__).parent.resolve() / "changelog_config.toml").open(
"rb"
) as file:
config = tomllib.load(file)

def _validate_title(pr_title: str, config: dict[str, Any]) -> tuple[bool, str]:
# Extract types, project, and scope from the config
types = "|".join(config["type"])
projects = "|".join(config["project"]) + "|\\*"
Expand All @@ -39,15 +38,15 @@
pattern_template = config["pattern_template"]
pattern = pattern_template.format(types=types, projects=projects, scope=scope)

# Check for the pattern in the first argument given to the script
# Check title against pattern.
match = re.search(pattern, pr_title)

valid = True
error = "it doesn't have the correct format"

# This check is there to ignore dependabot PRs from title checks
if pr_title.startswith("build"):
sys.exit(0)
return True, ""
elif not match:
valid = False
else:
Expand All @@ -57,8 +56,19 @@
elif match.group(2) == "*" and match.group(3) is None:
valid = False
error = "the <PR_PROJECT> cannot be '*' without using the ':skip' flag"
return valid, error


def main() -> None:
if len(sys.argv) < 2:
raise ValueError("Usage: python -m devtool.check_pr_title '<title>'")

pr_title = sys.argv[1]
config = _load_config()
valid, error = _validate_title(pr_title, config)

if not valid:
types = "|".join(config["type"])
print(
f"PR title `{pr_title}` is invalid, {error}.\n\nA PR title should "
"be of the form:\n\n\t<PR_TYPE>(<PR_PROJECT>): <PR_SUBJECT>\n\n"
Expand All @@ -73,3 +83,7 @@
"the changelog:\n\n\t`feat(framework:skip): Add new option to build CLI`\n"
)
sys.exit(1)


if __name__ == "__main__":
main()
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@
import re
from pathlib import Path
from typing import Optional, Union

import yaml

# Change this if you want to search a different directory.
ROOT_DIR = Path(".")
REPO_ROOT = Path(__file__).resolve().parents[2]
ROOT_DIR = REPO_ROOT

# Define new fields to be added to the `html_theme_options` dictionary in `conf.py`.
# If no fields are needed, set to an empty dictionary.
Expand All @@ -37,7 +38,7 @@
},
}

with (ROOT_DIR / "dev" / "docs-ui-config.yml").open() as f:
with (REPO_ROOT / "dev" / "docs-ui-config.yml").open(encoding="utf-8") as f:
announcement = yaml.safe_load(f)["announcement"]
if announcement["enabled"]:
NEW_FIELDS["announcement"] = announcement["html"]
Expand Down
2 changes: 1 addition & 1 deletion dev/update_python.py → dev/devtool/update_python.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ def _update_python_versions(
r"\g<1>" + new_major_minor + r"\g<2>",
),
],
"dev/*.py": [
"dev/devtool/*.py": [
# Update version assignments
(
r'(["\'])' + re.escape(old_version) + r'(\.\d+)?(["\'],?)\s*\n?',
Expand Down