From b0624b8419bd21d8e5673e6b299676179810f679 Mon Sep 17 00:00:00 2001 From: Nicholas Bollweg Date: Sun, 10 Nov 2024 13:13:46 -0500 Subject: [PATCH] fix ci (#2) --- .github/workflows/ci.yml | 48 ++++++++++-- .github/workflows/pages.yml | 18 ++++- docs/.readthedocs.yml | 12 +++ js/README.md | 2 +- js/package.json | 2 +- pixi.toml | 75 ++++++++++++------- scripts/schema.py | 10 ++- scripts/vale/check.py | 13 +++- .../config/vocabularies/urljsf/accept.txt | 3 + 9 files changed, 134 insertions(+), 49 deletions(-) create mode 100644 docs/.readthedocs.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b4351a9..2aa3eca 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,7 +14,7 @@ concurrency: env: PYTHONUNBUFFERED: '1' PIP_DISABLE_PIP_VERSION_CHECK: '1' - CACHE_EPOCH: '0' + CACHE_EPOCH: '3' URLJSF_PIXI_VERSION: 0.35.0 jobs: @@ -30,16 +30,27 @@ jobs: cache-key: job-build - name: cache (node) uses: actions/cache@v4 - id: cache-node-modules with: path: node_modules key: | ${{ env.CACHE_EPOCH }}-${{ runner.os }}-node_modules-${{ hashFiles('yarn.lock') }} + - run: pixi run build-yarn + - run: ls node_modules/.skip-yarn || mkdir -p build && echo '1' > node_modules/.skip-yarn - run: pixi run dist - uses: actions/upload-artifact@v4 with: name: urljsf-${{ github.run_number }}-dist - path: ./dist + path: | + ./dist + - uses: actions/upload-artifact@v4 + with: + name: urljsf-${{ github.run_number }}-build + path: | + build/task-cache-v0 + js/lib + js/dist + js/tsconfig.tsbuildinfo + src/urljs/_static lint: runs-on: ubuntu-latest @@ -52,13 +63,16 @@ jobs: cache: true environments: build lint cache-key: job-lint + - uses: actions/download-artifact@v4 + with: + name: urljsf-${{ github.run_number }}-build - name: cache (node) uses: actions/cache@v4 - id: cache-node-modules with: path: node_modules key: | ${{ env.CACHE_EPOCH }}-${{ runner.os }}-node_modules-${{ hashFiles('yarn.lock') }} + - run: pixi run fix - run: pixi run lint test: @@ -87,8 +101,12 @@ jobs: - uses: actions/download-artifact@v4 with: name: urljsf-${{ github.run_number }}-dist - path: ./dist - - run: pixi run ${{ matrix.test-env }}-pytest + path: | + ./dist + - uses: actions/download-artifact@v4 + with: + name: urljsf-${{ github.run_number }}-build + - run: pixi run -v ${{ matrix.test-env }}-pytest - uses: actions/upload-artifact@v4 if: always() with: @@ -106,20 +124,34 @@ jobs: cache: true environments: build docs check atest cache-key: job-docs + - name: cache (node) + uses: actions/cache@v4 + with: + path: node_modules + key: | + ${{ env.CACHE_EPOCH }}-${{ runner.os }}-node_modules-${{ hashFiles('yarn.lock') }} - uses: actions/download-artifact@v4 with: name: urljsf-${{ github.run_number }}-dist - path: ./dist - - run: pixi run docs-sphinx + path: | + ./dist + - uses: actions/download-artifact@v4 + with: + name: urljsf-${{ github.run_number }}-build + - run: pixi run build-yarn + - run: pixi run docs - uses: actions/upload-artifact@v4 + if: always() with: name: urljsf-${{ github.run_number }}-docs path: ./build/docs + - run: pixi run build-app-cov - run: pixi run atest - run: pixi run check - run: pixi run report if: always() - uses: actions/upload-artifact@v4 + if: always() with: name: urljsf-${{ github.run_number }}-docs-reports path: ./build/reports diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index 68eef3a..ce6313e 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -11,6 +11,7 @@ permissions: env: PYTHONUNBUFFERED: '1' PIP_DISABLE_PIP_VERSION_CHECK: '1' + URLJSF_PIXI_VERSION: 0.35.0 jobs: build: @@ -22,13 +23,22 @@ jobs: - uses: actions/checkout@v4 - uses: prefix-dev/setup-pixi@v0.8.1 with: - pixi-version: v0.27.0 - cache: true - environments: build docs test test-min - cache-key: job-pages + pixi-version: v${{ env.URLJSF_PIXI_VERSION }} + cache: false + environments: | + atest + build + docs + test + test-min + - run: pixi run build-yarn + - run: pixi run build - run: pixi run dist - run: pixi run test - run: pixi run docs + - run: pixi run atest + - run: pixi run report + - run: cp -r build/reports/ build/docs/_static/ - uses: actions/upload-pages-artifact@v3 with: path: build/docs diff --git a/docs/.readthedocs.yml b/docs/.readthedocs.yml new file mode 100644 index 0000000..8ce7a39 --- /dev/null +++ b/docs/.readthedocs.yml @@ -0,0 +1,12 @@ +version: 2 + +build: + os: ubuntu-lts-latest + tools: + # `mambaforge-latest` will now start failing: we just need a working `mamba` + python: mambaforge-23.11 + commands: + - mamba install -c conda-forge -c nodefaults pixi==0.35.0 + - pixi r build + - pixi r docs-sphinx + - pixi r -v docs-rtd diff --git a/js/README.md b/js/README.md index aef98d2..27b5dd7 100644 --- a/js/README.md +++ b/js/README.md @@ -2,5 +2,5 @@ This is the browser side of [`urljsf`](https://github.com/deathbeds/urljsf). -You might be able to install this and use it directly, but no particular support will be +You _might_ be able to install this and use it directly, but no particular support is provided for using it outside of its host application. diff --git a/js/package.json b/js/package.json index 4475a63..17c2074 100644 --- a/js/package.json +++ b/js/package.json @@ -7,7 +7,7 @@ "browser": "lib/index.js", "types": "lib/index.d.ts", "files": [ - "{lib,dist}/**/*.{js,ts,json,html,toml,yaml}" + "{lib,dist}/**/*.{js,ts,json,html,toml,yaml,map}" ], "scripts": { "build": "yarn build:lib && yarn build:app", diff --git a/pixi.toml b/pixi.toml index d1f96f7..e8584c9 100644 --- a/pixi.toml +++ b/pixi.toml @@ -62,6 +62,7 @@ build ALL distributed artifacts""", depends-on = [ ], cmd = "echo 📦"} test = {description = """ run ALL unit tests""", depends-on = [ + "dist-pypi", "test-pytest", "test-min-pytest", ], cmd = "echo 🧪"} @@ -92,13 +93,14 @@ py-static-- = """rm -rf src/urljsf/_static/ platform-- = '''mkdir -p build && python -c 'import platform; u = platform.uname(); print(f"{u.system}-{u.machine}".lower())' > build/platform.txt''' -pip-e-- = """python -m pip install +pip-- = """python -m pip install -vv - -e . --no-deps --no-build-isolation --disable-pip-version-check --ignore-installed""" +pip-e-- = """pixi r pip-- -e .""" +pip-whl-- = """pixi r pip-- urljsf --find-links=dist --no-index""" schema-vars-- = '''echo PROPS_TS=$PIXI_PROJECT_ROOT/js/src/_props.ts PROPS_JSON=$PIXI_PROJECT_ROOT/js/schema/v0/props.schema.json @@ -121,34 +123,35 @@ schema-all-- = '''pixi r schema-props # setup ######################################################################## [feature.tasks-build.tasks.build-yarn] description = "- install nodejs-based dependencies" -cmd = "yarn" +cmd = "(cat node_modules/.skip-yarn && echo 'skipping yarn install') || yarn" inputs = ["{yarn.lock,package.json,.yarnrc.yml}", "js/package.json"] outputs = ["node_modules/.yarn-state.yml"] +[feature.tasks-dev.tasks.dev-pip] +description = "- install the editable python package for development" +cmd = "pixi r -e dev pip-e--" +inputs = ["pyproject.toml"] + [feature.tasks-lint.tasks.lint-pip] description = "- install the editable python package for linting" cmd = "pixi r -e lint pip-e--" inputs = ["pyproject.toml"] [feature.tasks-test.tasks.test-pip] -description = "- install the editable python package for testing" -cmd = "pixi r -e test pip-e--" -inputs = ["pyproject.toml"] +description = "- install the built python package for testing" +cmd = "pixi r -e test pip-whl--" +inputs = ["dist/*.whl"] [feature.tasks-test-min.tasks.test-min-pip] -description = "- install the editable python package for testing (oldest)" -cmd = "pixi r -e test-min pip-e--" -inputs = ["pyproject.toml"] - -[feature.tasks-dev.tasks.dev-pip] -description = "- install the editable python package for development" -cmd = "pixi r -e dev pip-e--" -inputs = ["pyproject.toml"] +description = "- install the built python package for testing (oldest)" +cmd = "pixi r -e test-min pip-whl--" +inputs = ["dist/*.whl"] [feature.tasks-docs.tasks.docs-pip] -description = "- install the editable python package for docs" -cmd = "pixi r -e docs pip-e--" -inputs = ["pyproject.toml"] +description = "- install the built python package for docs" +cmd = "pixi r -e docs pip-whl--" +inputs = ["dist/*.whl"] +depends-on = ["dist-pypi"] # build ######################################################################## [feature.tasks-build.tasks.build-demo] @@ -196,7 +199,7 @@ description = "- build the Python distributions for pypi.org" cmd = "pyproject-build . --no-isolation" depends-on = ["build-static", "schema-py"] inputs = ["{pyproject.toml,LICENSE,README.md}", "src", "!**/__pycache__"] -outputs = ["dist/*.whl", "dist/*.tar.gz"] +outputs = ["dist/*.{whl,tar.gz}"] [feature.tasks-build.tasks.dist-hash] description = "- hash the built distributions" @@ -218,6 +221,7 @@ description = "- build JSON schema for rjsf form props" cmd = "export $(pixi r schema-vars--) && pixi r schema-ts-json--" inputs = ["js/src/_props.ts", "scripts/schema.py"] outputs = ["js/schema/v0/props.schema.json"] +depends-on = ["build-yarn"] [feature.tasks-build.tasks.schema-json] description = "- build JSON schema from TOML" @@ -353,8 +357,8 @@ cmd = """export PIXI_PLATFORM=$(cat build/platform.txt) --cov-context=test --no-cov-on-fail --cov-fail-under=97""" -depends-on = ["test-pip", "build-static", "platform--"] -inputs = ["{tests,src/urljsf}/**/*.{py,rst,json}", "src/urljsf/{_static,_templates}"] +depends-on = ["test-pip", "platform--"] +inputs = ["tests/**/*.{py,rst,json}", "dist/*.whl"] outputs = ["build/reports/test_*"] [feature.tasks-test.tasks.report] @@ -369,8 +373,8 @@ cmd = """export PIXI_PLATFORM=$(cat build/platform.txt) -n auto --html=build/reports/test-min_pytest_$PIXI_PLATFORM.html --self-contained-html""" -depends-on = ["test-min-pip", "build-static", "platform--"] -inputs = ["{tests,src/urljsf}/**/*.{py,rst,json}", "src/urljsf/{_static,_templates}"] +depends-on = ["test-min-pip", "platform--"] +inputs = ["tests/**/*.{py,rst,json}", "dist/*.whl"] outputs = ["build/reports/test-min_*"] # docs ######################################################################### @@ -388,15 +392,28 @@ description = "- build docs with sphinx" cmd = """export PYDEVD_DISABLE_FILE_VALIDATION=1 && sphinx-build -W --keep-going --color -b html docs build/docs""" inputs = [ - "*.md", - "*.toml", + "*.{md,toml}", "src/**/*.py", "dist/*.whl", - "docs/**/*.{css,ipynb,md,py}", + "docs/**/*.{css,rst,md,py}", ] -depends-on = ["docs-pip", "docs-scour"] +depends-on = ["docs-pip", "docs-scour", "dist-hash"] outputs = ["build/docs"] +[feature.tasks-docs.tasks.docs-rtd] +description = "... copy the documentation site to where ReadTheDocs wants it" +cmd = """ +python -c " +import os; +assert all(map(os.getenv, ['READTHEDOCS', 'READTHEDOCS_OUTPUT'])), 'not on ReadTheDocs' +" +&& mkdir -p "$READTHEDOCS_OUTPUT" +&& cp -r docs/build "$READTHEDOCS_OUTPUT/html" +&& ls "$READTHEDOCS_OUTPUT/html" +""" +depends-on = ["docs-sphinx"] + +# atest ######################################################################## [feature.tasks-atest.tasks.atest-robot] description = "- run acceptance test reports with robot" cmd = "python scripts/atest.py" @@ -436,13 +453,13 @@ cmd = """rm -rf build/reports/check-links -k "not (404 or coverage or lite or mypy or Untitled)" ../../../build/docs/**/*.html""" depends-on = ["docs-sphinx"] -inputs = ["docs/**/*.html"] +inputs = ["build/docs/**/*.html"] [feature.tasks-check.tasks.check-vale] description = "... check spelling in documentation" cmd = "python scripts/vale/check.py" depends-on = ["docs-sphinx"] -inputs = ["build/docs", "scripts/vale"] +inputs = ["build/docs/**/*.html", "scripts/vale", "{src,tests,scripts,atest}/**/*.py"] [feature.tasks-check.tasks.check-wheel] description = "... check the built wheel" @@ -658,7 +675,7 @@ myst_heading_anchors = 3 html_theme = "pydata_sphinx_theme" html_logo = "_static/logo.svg" html_favicon = "_static/icon.svg" -html_static_path = ["_static", "../js/dist/"] +html_static_path = ["_static", "../js/dist/", "../dist"] [tool.sphinx.html_theme_options] github_url = "{{ ppt.project.urls.Source }}" diff --git a/scripts/schema.py b/scripts/schema.py index abc860d..2ed797f 100644 --- a/scripts/schema.py +++ b/scripts/schema.py @@ -5,6 +5,7 @@ from __future__ import annotations import json +import shutil import sys from pathlib import Path from subprocess import call as _call @@ -20,6 +21,7 @@ # Distributed under the terms of the Modified BSD License. ''' ROOT = Path(__file__).parent.parent +YARN = f"""{shutil.which("yarn") or shutil.which("yarn.cmd")}""" def call(args: list[str | Path], **kwargs: Any) -> int: @@ -36,7 +38,7 @@ def call(args: list[str | Path], **kwargs: Any) -> int: def ts_to_json(in_path: Path, out_path: Path) -> int: """Get JSON schema from TypeScript.""" args = [ - "yarn", + YARN, "ts-json-schema-generator", "--tsconfig=js/tsconfig.json", f"--path={in_path}", @@ -44,7 +46,7 @@ def ts_to_json(in_path: Path, out_path: Path) -> int: ] if in_path.name == "_props.ts": args += ["--type=Props"] - return call(args) or call(["yarn", "prettier", "--write", out_path]) + return call(args) or call([YARN, "prettier", "--write", out_path]) def toml_to_json(in_path: Path, out_path: Path, *def_paths: Path) -> int: @@ -60,7 +62,7 @@ def toml_to_json(in_path: Path, out_path: Path, *def_paths: Path) -> int: def_schema["description"] = desc.strip() text = json.dumps(raw, indent=2) out_path.write_text(text, **UTF8) - return call(["yarn", "prettier", "--write", out_path]) + return call([YARN, "prettier", "--write", out_path]) def json_to_ts(in_path: Path, out_path: Path) -> int: @@ -77,7 +79,7 @@ def json_to_ts(in_path: Path, out_path: Path) -> int: ] return call(args) or call([ - "yarn", + YARN, "prettier", "--write", str(out_path), diff --git a/scripts/vale/check.py b/scripts/vale/check.py index 633f6da..fe6993a 100644 --- a/scripts/vale/check.py +++ b/scripts/vale/check.py @@ -20,8 +20,17 @@ REPORTS = BUILD / "reports" VALE_REPORT = REPORTS / "vale.html" SRC = ROOT / "src" - -ALL_PY = [*SRC.rglob("*.py"), *DOCS.rglob("*.py")] +SCRIPTS = ROOT / "scripts" +TESTS = ROOT / "tests" +ATEST = ROOT / "atest" + +ALL_PY = [ + *ATEST.rglob("*.py"), + *DOCS.rglob("*.py"), + *SCRIPTS.rglob("*.py"), + *SRC.rglob("*.py"), + *TESTS.rglob("*.py"), +] ALL_HTML = [*DOCS_BUILD.rglob("*.html")] CHECK_PATHS = { diff --git a/scripts/vale/config/vocabularies/urljsf/accept.txt b/scripts/vale/config/vocabularies/urljsf/accept.txt index 9ef7e75..6567365 100644 --- a/scripts/vale/config/vocabularies/urljsf/accept.txt +++ b/scripts/vale/config/vocabularies/urljsf/accept.txt @@ -10,6 +10,7 @@ _.+_ acceptCharset addButton additionalProperties +args aspirational autoComplete autocompletion @@ -30,11 +31,13 @@ enctype endmacro enum extraErrorsBlockSubmit +fixtured focusOnFirstError form_data form(Context|Data) Git(Lab|Hub) globals +http i\.e\. idPrefix idSeparator