Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
6747e39
Migrate to ifileeditor from ifilemanager, which adds support of unsav…
Aksem Jan 11, 2026
c336325
WM LSP Server: put actions in a group
Aksem Jan 11, 2026
3d78a40
Alpha releases of all active packages
Aksem Jan 18, 2026
ec7ec10
Allow alpha version in dependencies. Fix start
Aksem Jan 22, 2026
d111e4f
Migrate isort handler to format_files from format. Activate it by def…
Aksem Jan 22, 2026
ae28fb6
Fix run context: it should be initialised per action, not per handler
Aksem Jan 22, 2026
d0ae9c7
Add logs about saving files
Aksem Jan 22, 2026
f498797
Format finecode_extension_api
Aksem Jan 22, 2026
9b72f8c
Add missing gitignore files in extensions
Aksem Jan 22, 2026
2b06272
Fix exclusion of egg-info dir in extensions
Aksem Jan 22, 2026
4f9d964
Show error message to user instead of raising exception in lsp server
Aksem Jan 22, 2026
27848be
Rename group_project_files_by_lang to group_src_artifact_files_by_lang
Aksem Jan 23, 2026
8fb36b1
Rename list_project_files_by_lang to list_src_artifact_files_by_lang
Aksem Jan 23, 2026
2393cd1
Finish renaming project to src artifact. Move all py-related modules …
Aksem Jan 24, 2026
2d123f3
Add missing 'from eg' to all exception handlers with exception group
Aksem Jan 24, 2026
db5824c
Remove outdated lock files in tests
Aksem Jan 26, 2026
7e759fb
Http client interface and implementation
Aksem Jan 26, 2026
067f013
Implementation of http client
Aksem Jan 26, 2026
8514cb2
New actions: publish artifact, publish artifact to registry, is artif…
Aksem Jan 27, 2026
97f20ff
Export all new handlers from fine_python_package_info
Aksem Jan 27, 2026
cfc79a6
Extend isort config and make it compatible in fine_python_format with…
Aksem Jan 27, 2026
8a96371
Fix typing of action runner. Add 'build artifact action'. Move 'Forma…
Aksem Jan 31, 2026
194896d
New fine_python_setuptools_scm extension with handler of get_src_arti…
Aksem Feb 13, 2026
e14cf43
Split 'build and publish' to 'build' and 'publish_and_verify'. Add (p…
Aksem Feb 16, 2026
0526f4d
Interfaces for jsonrpcclient, lspclient and serviceregistry
Aksem Feb 21, 2026
de72fdb
Initial docs and docs deployment
Aksem Feb 21, 2026
e6d42f2
Add section about CI/CD on main docs page
Aksem Feb 21, 2026
c8d34f6
Fix isort action: pass serializable data between processes
Aksem Feb 21, 2026
da95aa7
Add extension activators, in which default service implementations ca…
Aksem Feb 21, 2026
075d42d
Add possibility to define custom impls for services in config. Move l…
Aksem Feb 21, 2026
703a2f7
Add discord link in docs
Aksem Feb 21, 2026
26320f3
Fix formatting of prepare_envs output in case of error. It was wrong …
Aksem Feb 22, 2026
8f72470
Migrate to culsans 0.11
Aksem Feb 22, 2026
cc3288a
Make finecode_jsonrpc editable in dev_no_runtime and dev_workspace of…
Aksem Feb 22, 2026
b39729a
Eager initialization of action handlers: if IDE is active, all handle…
Aksem Feb 28, 2026
6358569
LspClient (and json rpc client), use it optionally(enabled by default…
Aksem Mar 1, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
135 changes: 52 additions & 83 deletions .github/workflows/ci-cd.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
# TODO: check formatting
# TODO: lock files on all platforms
# TODO: test with all supported python versions
name: CI

on:
merge_group:
push:
pull_request:
workflow_dispatch:
inputs:
publish_testpypi:
description: 'Publish to TestPyPI'
required: true
type: boolean
default: false

defaults:
run:
Expand Down Expand Up @@ -47,7 +57,7 @@ jobs:
run: |
python -m venv .venvs/dev_workspace
source .venvs/dev_workspace/bin/activate
python -m pip install --upgrade pip==25.1.1
python -m pip install --upgrade pip==25.3

# split installation into 2 steps: first internal preset because it is not
# published as pypi package, so pip will fail to resolve it in dev_workspace
Expand All @@ -58,102 +68,61 @@ jobs:
python -m finecode prepare-envs
shell: bash

# TODO: install all other supported python versions. Version can be extracted from finecode
- name: Lint
run: |
source .venvs/dev_workspace/bin/activate
python -m finecode run lint
shell: bash

- name: Build artifacts
id: build
if: runner.os == 'Linux'
run: |
source .venvs/dev_workspace/bin/activate
python -m finecode run build_artifact
shell: bash

# - name: Lint
# - name: Run unit tests
# if: ${{ !cancelled() }}
# run: |
# poetry run python -m finecode run lint
# source .venvs/dev_workspace/bin/activate
# python -m finecode run test
# shell: bash

- name: Build all packages
if: runner.os == 'Linux'
- name: Publish to TestPyPI and verify
if: runner.os == 'Linux' && github.event_name == 'workflow_dispatch' && inputs.publish_testpypi
env:
FINECODE_CONFIG_PUBLISH_AND_VERIFY_ARTIFACT__INIT_REPOSITORY_PROVIDER__REPOSITORIES: '[{"name": "testpypi", "url": "https://test.pypi.org/"}]'
FINECODE_CONFIG_PUBLISH_AND_VERIFY_ARTIFACT__INIT_REPOSITORY_PROVIDER__CREDENTIALS_BY_REPOSITORY: '{"testpypi": {"username": "${{ secrets.TESTPYPI_USERNAME }}", "password": "${{ secrets.TESTPYPI_PASSWORD }}"}}'
run: |
source .venvs/dev_workspace/bin/activate
python -m finecode run build
python -m finecode run \
--map-payload-fields="src-artifact-def-path,dist-artifact-paths" \
publish_and_verify_artifact \
--src-artifact-def-path="build_artifact.src_artifact_def_path" \
--dist-artifact-paths="build_artifact.build_output_paths"
shell: bash

- name: Collect all distribution packages
if: runner.os == 'Linux'
- name: Publish to PyPI and verify
if: runner.os == 'Linux' && startsWith(github.ref, 'refs/tags/')
env:
FINECODE_CONFIG_PUBLISH_AND_VERIFY_ARTIFACT__INIT_REPOSITORY_PROVIDER__REPOSITORIES: '[{"name": "pypi", "url": "https://pypi.org/"}]'
FINECODE_CONFIG_PUBLISH_AND_VERIFY_ARTIFACT__INIT_REPOSITORY_PROVIDER__CREDENTIALS_BY_REPOSITORY: '{"pypi": {"username": "${{ secrets.PYPI_USERNAME }}", "password": "${{ secrets.PYPI_PASSWORD }}"}}'
run: |
# TODO: finecode action to copy only updated packages in dist
mkdir -p dist
cp finecode_extension_api/dist/* dist/
cp extensions/fine_python_ast/dist/* dist/
cp extensions/fine_python_black/dist/* dist/
cp extensions/fine_python_flake8/dist/* dist/
cp extensions/fine_python_isort/dist/* dist/
cp extensions/fine_python_module_exports/dist/* dist/
cp extensions/fine_python_mypy/dist/* dist/
cp presets/fine_python_format/dist/* dist/
cp presets/fine_python_lint/dist/* dist/
cp presets/fine_python_recommended/dist/* dist/
# TODO: make sure git tag exists (for manual trigger)
source .venvs/dev_workspace/bin/activate
python -m finecode run \
--map-payload-fields="src-artifact-def-path,dist-artifact-paths" \
publish_and_verify_artifact \
--src-artifact-def-path="build_artifact.src_artifact_def_path" \
--dist-artifact-paths="build_artifact.build_output_paths"

shell: bash

# TODO: try to replace by finecode action
- name: Store the distribution packages
uses: actions/upload-artifact@v4
if: runner.os == 'Linux'
with:
name: python-package-distributions
path: dist/

# - name: Run unit tests
# if: ${{ !cancelled() }}
# run: |
# poetry run python -m pytest tests/
# shell: bash

publish-to-pypi:
name: >-
Publish Python 🐍 distribution 📦 to PyPI
if: startsWith(github.ref, 'refs/tags/')
needs:
- build
runs-on: ubuntu-24.04
environment:
name: pypi
url: https://pypi.org/p/finecode
permissions:
id-token: write # IMPORTANT: mandatory for trusted publishing

steps:
- name: Download all the dists
uses: actions/download-artifact@v4
with:
name: python-package-distributions
path: dist/
- name: Publish distribution 📦 to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
# temporary skip existing packages, because not always all packages at once
# are updated.
# TODO: implement publishing only of changed in finecode
skip-existing: true

publish-to-testpypi:
name: Publish Python 🐍 distribution 📦 to TestPyPI
needs:
- build
runs-on: ubuntu-24.04

environment:
name: testpypi
url: https://test.pypi.org/p/finecode

permissions:
id-token: write # IMPORTANT: mandatory for trusted publishing

steps:
- name: Download all the dists
uses: actions/download-artifact@v4
with:
name: python-package-distributions
path: dist/
- name: Publish distribution 📦 to TestPyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
repository-url: https://test.pypi.org/legacy/
verbose: true
# temporary skip existing packages, because not always all packages at once
# are updated.
# TODO: implement publishing only of changed in finecode
skip-existing: true
42 changes: 42 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: Deploy docs

on:
push:
tags:
- 'v*'
workflow_dispatch:

jobs:
deploy:
runs-on: ubuntu-24.04

steps:
- uses: actions/checkout@v5

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.13'

- name: Install docs dependencies
run: |
python -m pip install --upgrade pip
# TODO: prepare_env docs
python -m venv .venvs/docs
source .venvs/docs/bin/activate
python -m pip install --group="docs"

- name: Build docs
env:
MKDOCS_SITE_URL: https://finecode-dev.github.io
run: |
source .venvs/docs/bin/activate
mkdocs build

- name: Deploy to finecode.github.io
uses: peaceiris/actions-gh-pages@v4
with:
personal_token: ${{ secrets.PAGES_DEPLOY_TOKEN }}
external_repository: finecode-dev/finecode.github.io
publish_branch: main
publish_dir: ./site
18 changes: 0 additions & 18 deletions .vscode/tasks.json

This file was deleted.

135 changes: 135 additions & 0 deletions docs/cli.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
# CLI Reference

All commands are run from the workspace or project root directory, inside the `dev_workspace` virtual environment.

```bash
source .venvs/dev_workspace/bin/activate
python -m finecode <command> [options]
```

---

## `run`

Run one or more actions across projects.

```
python -m finecode run [options] <action> [<action> ...] [payload] [--config.<key>=<value> ...]
```

### Options

| Option | Description |
|---|---|
| `--workdir=<path>` | Use `<path>` as the workspace root instead of `cwd` |
| `--project=<name>` | Run only in this project. Repeatable for multiple projects. |
| `--concurrently` | Run actions concurrently within each project |
| `--trace` | Enable verbose (trace-level) logging |
| `--no-env-config` | Ignore `FINECODE_CONFIG_*` environment variables |
| `--no-save-results` | Do not write action results to the cache directory |

### Payload

Named parameters passed to the action payload. All must use `--<name>=<value>` form:

```bash
python -m finecode run format --save=true
python -m finecode run lint --target=files --file-paths='["src/main.py"]'
```

### Config overrides

Override handler configuration inline:

```bash
# Action-level (applies to all handlers)
python -m finecode run lint --config.line_length=120

# Handler-specific
python -m finecode run lint --config.ruff.line_length=120 --config.mypy.strict=true
```

See [Configuration](configuration.md) for full details on config precedence.

### Behavior

- With no `--project`: FineCode treats `cwd` (or `--workdir`) as the workspace root, discovers all projects, and runs the action in each project that defines it.
- With `--project`: the action must exist in every specified project.
- Action results are saved to `<venv>/cache/finecode/results/<action>.json` (one entry per project path).

### Examples

```bash
# Lint all projects
python -m finecode run lint

# Lint and check_formatting concurrently
python -m finecode run --concurrently lint check_formatting

# Run only in two specific projects
python -m finecode run --project=fine_python_mypy --project=fine_python_ruff run lint

# Run from a different directory
python -m finecode --workdir=./finecode_extension_api run lint

# Override ruff line length
python -m finecode run lint --config.ruff.line_length=120
```

---

## `prepare-envs`

Create and populate virtual environments for all handler dependencies.

```
python -m finecode prepare-envs [--recreate] [--trace] [--debug]
```

Must be run from the workspace or project root. Creates venvs under `.venvs/<env_name>/` and installs each handler's declared dependencies.

| Option | Description |
|---|---|
| `--recreate` | Delete and recreate all venvs from scratch |
| `--trace` | Enable verbose logging |
| `--debug` | Wait for a debugpy client on port 5680 before starting |

---

## `dump-config`

Dump the fully resolved configuration for a project to disk, useful for debugging preset and config merging.

```
python -m finecode dump-config --project=<name> [--trace] [--debug]
```

Output is written to `<cwd>/finecode_config_dump/`.

| Option | Description |
|---|---|
| `--project=<name>` | **(Required)** Project to dump config for |
| `--trace` | Enable verbose logging |
| `--debug` | Wait for a debugpy client on port 5680 |

---

## `start-api`

Start the FineCode LSP server. Used by the IDE extension — you typically don't call this directly.

```
python -m finecode start-api --stdio | --socket <port> | --ws [--host <host>] [--port <port>]
```

| Option | Description |
|---|---|
| `--stdio` | Communicate over stdin/stdout |
| `--socket <port>` | Start a TCP server on the given port |
| `--ws` | Start a WebSocket server |
| `--host <host>` | Host for TCP/WS server (default: 127.0.0.1 for TCP) |
| `--port <port>` | Port for TCP/WS server |
| `--mcp` | Also start an MCP server |
| `--mcp-port <port>` | Port for the MCP server |
| `--trace` | Enable verbose logging |
| `--debug` | Wait for a debugpy client on port 5680 |
Loading
Loading