From f66266612121c34bc46d32f20b06ccd6a7221a10 Mon Sep 17 00:00:00 2001 From: Vlada Dusek Date: Wed, 24 Jun 2026 10:05:30 +0200 Subject: [PATCH 1/8] ci: add markdown, website, and image lint checks --- .editorconfig | 1 + .github/workflows/_checks.yaml | 81 + .markdownlint.yaml | 24 +- CONTRIBUTING.md | 43 +- README.md | 2 +- docs/02_concepts/09_logging.mdx | 3 - docs/03_guides/06_scrapy.mdx | 2 +- docs/03_guides/09_browser_use.mdx | 2 +- docs/04_upgrading/upgrading_to_v2.md | 6 +- docs/04_upgrading/upgrading_to_v3.md | 4 + docs/04_upgrading/upgrading_to_v4.md | 2 + website/.eslintrc.json | 27 - website/.oxfmtrc.json | 19 + website/docusaurus.config.js | 6 +- website/oxlint.config.ts | 20 + website/package.json | 26 +- website/pnpm-lock.yaml | 2852 ++++------------- website/roa-loader/index.js | 4 +- website/sidebars.js | 2 +- website/src/components/Gradients.jsx | 28 +- website/src/components/Highlights.jsx | 16 +- website/src/components/RunnableCodeBlock.jsx | 52 +- .../docusaurus-plugin-segment/segment.js | 38 +- website/src/theme/DocItem/Content/index.js | 2 +- website/tools/docs-prettier.config.js | 12 - website/tools/utils/externalLink.js | 11 +- 26 files changed, 931 insertions(+), 2354 deletions(-) delete mode 100644 website/.eslintrc.json create mode 100644 website/.oxfmtrc.json create mode 100644 website/oxlint.config.ts delete mode 100644 website/tools/docs-prettier.config.js diff --git a/.editorconfig b/.editorconfig index 31447bf17..a182e3b56 100644 --- a/.editorconfig +++ b/.editorconfig @@ -7,6 +7,7 @@ charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true end_of_line = lf +quote_type = single [Makefile] indent_style = tab diff --git a/.github/workflows/_checks.yaml b/.github/workflows/_checks.yaml index b6fec131d..2f35bb38b 100644 --- a/.github/workflows/_checks.yaml +++ b/.github/workflows/_checks.yaml @@ -15,6 +15,9 @@ on: permissions: contents: read +env: + NODE_VERSION: 22 + jobs: actions_lint_check: name: Actions lint check @@ -46,6 +49,84 @@ jobs: with: python_versions: '["3.11", "3.12", "3.13", "3.14"]' + markdown_lint_check: + name: Markdown lint check + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v7 + + - name: Set up Node + uses: actions/setup-node@v6 + with: + node-version: ${{ env.NODE_VERSION }} + + - name: Install pnpm and website dependencies + uses: apify/actions/pnpm-install@v1.2.0 + with: + working-directory: website + + - name: Lint Markdown + run: pnpm lint:md + working-directory: website + + website_lint_check: + name: Website lint check + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v7 + + - name: Set up Node + uses: actions/setup-node@v6 + with: + node-version: ${{ env.NODE_VERSION }} + + - name: Install pnpm and website dependencies + uses: apify/actions/pnpm-install@v1.2.0 + with: + working-directory: website + + - name: Lint website code + run: pnpm lint:code + working-directory: website + + - name: Check website formatting + run: pnpm format:check + working-directory: website + + image_lint_check: + name: Image lint check + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v7 + + # Doc images must be committed as optimized `.webp`. This fails when a PR adds raster + # images in another format so they get converted via `pnpm opt:images` first. + - name: Get changed unoptimized images + id: changed-files + uses: tj-actions/changed-files@v47 + with: + files: | + docs/**/*.{png,jpg,jpeg,gif,bmp,tif,tiff,avif} + website/static/**/*.{png,jpg,jpeg,gif,bmp,tif,tiff,avif} + separator: "\n" + + - name: Fail on unoptimized images + if: steps.changed-files.outputs.any_changed == 'true' + env: + UNOPTIMIZED_IMAGE_FILES: ${{ steps.changed-files.outputs.all_changed_files }} + run: | + echo "Unoptimized images detected! Convert each one to WebP, e.g.:" + echo "" + while IFS= read -r file_path; do + echo " (cd website && pnpm opt:images \"../$file_path\")" + done <<< "$UNOPTIMIZED_IMAGE_FILES" + echo "" + echo "Then reference the resulting .webp files in your Markdown." + exit 1 + unit_tests: name: Unit tests if: inputs.run_tests diff --git a/.markdownlint.yaml b/.markdownlint.yaml index 01c2c62fa..868c63a7e 100644 --- a/.markdownlint.yaml +++ b/.markdownlint.yaml @@ -1,5 +1,25 @@ +# markdownlint config for the docs and top-level Markdown files. +# Run via `pnpm lint:md` / `pnpm lint:md:fix` from the `website/` directory. default: true -line-length: - line_length: 150 + +# Prose is written one sentence per line, so line length is not enforced. +line-length: false + ul-style: dash + +# Docs are MDX and embed JSX components. no-inline-html: false + +# MDX pages set their title via front matter, so multiple/duplicate H1s are fine. +single-title: false +no-duplicate-heading: + siblings_only: true + +# Anchor links into other pages can't be validated locally. +link-fragments: false + +no-bare-urls: false +no-trailing-punctuation: + punctuation: ".,;:。,;:" +no-multiple-blanks: + maximum: 2 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index cbcaa8b21..3ba981919 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -118,6 +118,22 @@ To run the documentation locally (requires Node.js): uv run poe run-docs ``` +### Linting the docs and website + +Markdown content (this guide, `README.md`, and the `docs/` folder) is checked with +[markdownlint](https://github.com/DavidAnson/markdownlint). The Docusaurus website code is linted +with [oxlint](https://oxc.rs/) and formatted with [oxfmt](https://oxc.rs/). All of them run in CI. +To run them locally (requires Node.js and pnpm), from the `website/` directory: + +```sh +pnpm lint # lint Markdown and website code +pnpm lint:fix # auto-fix both +pnpm format # format the website code +``` + +Doc images are committed as optimized `.webp`. To convert a new image, run +`pnpm opt:images ` from the `website/` directory. + ## Commits We use [Conventional Commits](https://www.conventionalcommits.org/) format for commit messages. This convention is used to automatically determine version bumps during the release process. @@ -149,25 +165,22 @@ Publishing new versions to [PyPI](https://pypi.org/project/apify) is automated t 1. **Do not do this unless absolutely necessary.** In all conceivable scenarios, you should use the `release` workflow instead. 2. **Make sure you know what you're doing.** +3. Update the version number by modifying the `version` field under `project` in `pyproject.toml`: -3. Update the version number: - -- Modify the `version` field under `project` in `pyproject.toml`. - -```toml -[project] -name = "apify" -version = "x.z.y" -``` + ```toml + [project] + name = "apify" + version = "x.z.y" + ``` 4. Build the package: -```sh -uv run poe build -``` + ```sh + uv run poe build + ``` 5. Upload to PyPI: -```sh -uv publish --token YOUR_API_TOKEN -``` + ```sh + uv publish --token YOUR_API_TOKEN + ``` diff --git a/README.md b/README.md index 56f78840e..b9c9ea55e 100644 --- a/README.md +++ b/README.md @@ -195,7 +195,7 @@ async def main() -> None: The full SDK documentation lives at **[docs.apify.com/sdk/python](https://docs.apify.com/sdk/python)**. For the Apify platform itself, see the [Apify documentation](https://docs.apify.com/). | Section | What you'll find | -|---|---| +| --- | --- | | [Overview](https://docs.apify.com/sdk/python/docs/overview) | What the SDK is, what Actors are, and how the pieces fit together. | | [Quick start](https://docs.apify.com/sdk/python/docs/quick-start) | Create, run, and deploy your first Python Actor. | | [Concepts](https://docs.apify.com/sdk/python/docs/concepts/actor-lifecycle) | Actor lifecycle, input, storages, events, proxy management, interacting with other Actors, webhooks, accessing the Apify API, logging, configuration, and pay-per-event. | diff --git a/docs/02_concepts/09_logging.mdx b/docs/02_concepts/09_logging.mdx index cc0b519f1..a953a3b05 100644 --- a/docs/02_concepts/09_logging.mdx +++ b/docs/02_concepts/09_logging.mdx @@ -53,7 +53,6 @@ You can use the `extra` argument for all log levels, it's not specific to the wa Result: -