Compare commits

...

21 Commits

Author SHA1 Message Date
valeros
7ab894f8a6 Free up disk space via an external action 2025-12-15 22:40:51 +02:00
valeros
cc529de888 Temporarily disable some CI 2025-12-15 22:40:25 +02:00
Ivan Kravets
b7aec5a838 Lint codebase with Python 3.14 2025-12-11 16:31:20 +02:00
Ivan Kravets
8011eea34a Ignore:'protected_args' is deprecated and will be removed in Click 9.0:DeprecationWarning 2025-12-11 16:30:56 +02:00
Ritesh Kudkelwar
d22216d4d1 Fix: exclude nested .vscode directories from package publish (#5239)
Exclude nested .vscode folders from package output
2025-12-08 16:48:03 +02:00
Ivan Kravets
41c8e63cd5 Added support for Python 3.14 2025-12-08 16:37:55 +02:00
Ivan Kravets
3bbe176ae3 Upgrade to latest click 8.3.1 2025-12-08 16:36:58 +02:00
Ivan Kravets
8e561c3c55 Upgrade to latest click 8.3.1 2025-12-08 16:01:27 +02:00
Ivan Kravets
f00ef57089 Update dependencies 2025-12-08 15:56:36 +02:00
Ivan Kravets
4850c1069c Update deps 2025-09-21 12:48:30 +03:00
Ivan Kravets
487a894a71 Fixed an issue where fully-qualified serial port URLs (e.g., `rfc2217://host:port`) were incorrectly treated as wildcard patterns // Resolve #5225 2025-08-09 13:31:17 +03:00
Youssef Benhammouda
8df56dfbb2 Fix: Preserve RFC2217 URLs in SerialPortFinder.find() in "device monitor" (#5226)
Fix: Preserve RFC2217 URLs in SerialPortFinder.find()
Fixes platformio/platformio-core#5225
2025-08-09 13:01:33 +03:00
valeros
31d630b766 Sync docs 2025-07-31 14:57:19 +03:00
Ivan Kravets
de02eafa06 Docs: Fix a link to the default debug init commands 2025-07-22 15:35:31 +03:00
Ivan Kravets
903a013cbd Update SPDX license list 2025-07-08 17:45:31 +03:00
Ivan Kravets
6cf8b8172f Update deps 2025-07-08 17:45:14 +03:00
Ivan Kravets
444c57b4a6 Bump version to 6.1.19a2 2025-05-07 19:49:31 +03:00
Ivan Kravets
d787648e71 Fixed a regression issue where custom build flags were not properly reflected in the compile_commands.json // Resolve #5090 Resolve #5147 2025-05-07 19:45:16 +03:00
Ivan Kravets
846588deec Sync examples 2025-05-07 19:43:52 +03:00
Ivan Kravets
79142965ce Bump version to 6.1.19a1 2025-03-11 22:15:54 +02:00
Ivan Kravets
93bc4fae6c Merge tag 'v6.1.18' into develop
Bump version to 6.1.18
2025-03-11 21:47:33 +02:00
20 changed files with 146 additions and 302 deletions

View File

@@ -1,53 +0,0 @@
name: Core
on: [push, pull_request]
jobs:
build:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
python-version: ["3.11", "3.12", "3.13"]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
with:
submodules: "recursive"
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install tox
- name: Run "codespell" on Linux
if: startsWith(matrix.os, 'ubuntu')
run: |
python -m pip install codespell
make codespell
- name: Core System Info
run: |
tox -e py
- name: Integration Tests
if: ${{ matrix.python-version == '3.11' }}
run: |
tox -e testcore
- name: Slack Notification
uses: homoluctus/slatify@master
if: failure()
with:
type: ${{ job.status }}
job_name: '*Core*'
commit: true
url: ${{ secrets.SLACK_BUILD_WEBHOOK }}
token: ${{ secrets.SLACK_GITHUB_TOKEN }}

View File

@@ -1,45 +0,0 @@
name: Deployment
on:
push:
branches:
- "master"
- "release/**"
jobs:
deployment:
runs-on: ubuntu-latest
environment: production
steps:
- uses: actions/checkout@v4
with:
submodules: "recursive"
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.11"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install tox build
- name: Deployment Tests
env:
TEST_EMAIL_LOGIN: ${{ secrets.TEST_EMAIL_LOGIN }}
TEST_EMAIL_PASSWORD: ${{ secrets.TEST_EMAIL_PASSWORD }}
TEST_EMAIL_IMAP_SERVER: ${{ secrets.TEST_EMAIL_IMAP_SERVER }}
run: |
tox -e testcore
- name: Build Python distributions
run: python -m build
- name: Publish package to PyPI
if: ${{ github.ref == 'refs/heads/master' }}
uses: pypa/gh-action-pypi-publish@release/v1
with:
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}

View File

@@ -1,109 +0,0 @@
name: Docs
on: [push, pull_request]
jobs:
build:
name: Build Docs
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: "recursive"
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install tox
- name: Build docs
run: |
tox -e docs
- name: Slack Notification
uses: homoluctus/slatify@master
if: failure()
with:
type: ${{ job.status }}
job_name: '*Docs*'
commit: true
url: ${{ secrets.SLACK_BUILD_WEBHOOK }}
token: ${{ secrets.SLACK_GITHUB_TOKEN }}
- name: Preserve Docs
if: ${{ github.event_name == 'push' }}
run: |
tar -czvf docs.tar.gz -C docs/_build html rtdpage
- name: Save artifact
if: ${{ github.event_name == 'push' }}
uses: actions/upload-artifact@v4
with:
name: docs
path: ./docs.tar.gz
deploy:
name: Deploy Docs
needs: build
runs-on: ubuntu-latest
env:
DOCS_REPO: platformio/platformio-docs
DOCS_DIR: platformio-docs
LATEST_DOCS_DIR: latest-docs
RELEASE_BUILD: ${{ startsWith(github.ref, 'refs/tags/v') }}
if: ${{ github.event_name == 'push' }}
steps:
- name: Download artifact
uses: actions/download-artifact@v4
with:
name: docs
- name: Unpack artifact
run: |
mkdir ./${{ env.LATEST_DOCS_DIR }}
tar -xzf ./docs.tar.gz -C ./${{ env.LATEST_DOCS_DIR }}
- name: Delete Artifact
uses: geekyeggo/delete-artifact@v5
with:
name: docs
- name: Select Docs type
id: get-destination-dir
run: |
if [[ ${{ env.RELEASE_BUILD }} == true ]]; then
echo "::set-output name=dst_dir::stable"
else
echo "::set-output name=dst_dir::latest"
fi
- name: Checkout latest Docs
continue-on-error: true
uses: actions/checkout@v4
with:
repository: ${{ env.DOCS_REPO }}
path: ${{ env.DOCS_DIR }}
ref: gh-pages
- name: Synchronize Docs
run: |
rm -rf ${{ env.DOCS_DIR }}/.git
rm -rf ${{ env.DOCS_DIR }}/en/${{ steps.get-destination-dir.outputs.dst_dir }}
mkdir -p ${{ env.DOCS_DIR }}/en/${{ steps.get-destination-dir.outputs.dst_dir }}
cp -rf ${{ env.LATEST_DOCS_DIR }}/html/* ${{ env.DOCS_DIR }}/en/${{ steps.get-destination-dir.outputs.dst_dir }}
if [[ ${{ env.RELEASE_BUILD }} == false ]]; then
rm -rf ${{ env.DOCS_DIR }}/page
mkdir -p ${{ env.DOCS_DIR }}/page
cp -rf ${{ env.LATEST_DOCS_DIR }}/rtdpage/* ${{ env.DOCS_DIR }}/page
fi
- name: Validate Docs
run: |
if [ -z "$(ls -A ${{ env.DOCS_DIR }})" ]; then
echo "Docs folder is empty. Aborting!"
exit 1
fi
- name: Deploy to Github Pages
uses: peaceiris/actions-gh-pages@v4
with:
personal_token: ${{ secrets.DEPLOY_GH_DOCS_TOKEN }}
external_repository: ${{ env.DOCS_REPO }}
publish_dir: ./${{ env.DOCS_DIR }}
commit_message: Sync Docs

View File

@@ -15,6 +15,16 @@ jobs:
PIO_INSTALL_DEVPLATFORM_NAMES: "aceinna_imu,atmelavr,atmelmegaavr,atmelsam,espressif32,espressif8266,nordicnrf52,raspberrypi,ststm32,teensy"
steps:
- name: Free Disk Space
uses: endersonmenezes/free-disk-space@v3
with:
remove_android: true
remove_dotnet: true
remove_haskell: true
# Faster cleanup
remove_packages_one_command: true
rm_cmd: "rmz"
- uses: actions/checkout@v4
with:
submodules: "recursive"

View File

@@ -1,56 +0,0 @@
name: Projects
on: [push, pull_request]
jobs:
build:
strategy:
fail-fast: false
matrix:
project:
- marlin:
repository: "MarlinFirmware/Marlin"
folder: "Marlin"
config_dir: "Marlin"
env_name: "mega2560"
- smartknob:
repository: "scottbez1/smartknob"
folder: "smartknob"
config_dir: "smartknob"
env_name: "view"
- espurna:
repository: "xoseperez/espurna"
folder: "espurna"
config_dir: "espurna/code"
env_name: "nodemcu-lolin"
- OpenMQTTGateway:
repository: "1technophile/OpenMQTTGateway"
folder: "OpenMQTTGateway"
config_dir: "OpenMQTTGateway"
env_name: "esp32-m5atom-lite"
os: [ubuntu-latest, windows-latest, macos-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
with:
submodules: "recursive"
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: 3.11
- name: Install PlatformIO
run: pip install -U .
- name: Check out ${{ matrix.project.repository }}
uses: actions/checkout@v4
with:
submodules: "recursive"
repository: ${{ matrix.project.repository }}
path: ${{ matrix.project.folder }}
- name: Compile ${{ matrix.project.repository }}
run: pio run -d ${{ matrix.project.config_dir }} -e ${{ matrix.project.env_name }}

View File

@@ -19,6 +19,13 @@ Unlock the true potential of embedded software development with
PlatformIO's collaborative ecosystem, embracing declarative principles,
test-driven methodologies, and modern toolchains for unrivaled success.
6.1.19 (2025-??-??)
~~~~~~~~~~~~~~~~~~~
* Added support for Python 3.14
* Fixed a regression issue where custom build flags were not properly reflected in the `compile_commands.json <https://docs.platformio.org/en/latest/integration/compile_commands.html>`__ file, ensuring accurate compilation database generation
* Fixed an issue where fully-qualified serial port URLs (e.g., ``rfc2217://host:port``) were incorrectly treated as wildcard patterns (`issue #5225 <https://github.com/platformio/platformio-core/issues/5225>`_)
6.1.18 (2025-03-11)
~~~~~~~~~~~~~~~~~~~

2
docs

Submodule docs updated: 70ab7ee27b...23ef0f85ca

View File

@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
VERSION = (6, 1, 18)
VERSION = (6, 1, "19a2")
__version__ = ".".join([str(s) for s in VERSION])
__title__ = "platformio"

View File

@@ -58,8 +58,8 @@ def GetBuildType(env):
def BuildProgram(env):
env.ProcessCompileDbToolchainOption()
env.ProcessProgramDeps()
env.ProcessCompileDbToolchainOption()
env.ProcessProjectDeps()
# append into the beginning a main LD script
@@ -91,26 +91,6 @@ def BuildProgram(env):
return program
def ProcessCompileDbToolchainOption(env):
if "compiledb" not in COMMAND_LINE_TARGETS:
return
# Resolve absolute path of toolchain
for cmd in ("CC", "CXX", "AS"):
if cmd not in env:
continue
if os.path.isabs(env[cmd]) or '"' in env[cmd]:
continue
env[cmd] = where_is_program(env.subst("$%s" % cmd), env.subst("${ENV['PATH']}"))
if " " in env[cmd]: # issue #4998: Space in compilator path
env[cmd] = f'"{env[cmd]}"'
if env.get("COMPILATIONDB_INCLUDE_TOOLCHAIN"):
print("Warning! `COMPILATIONDB_INCLUDE_TOOLCHAIN` is scoping")
for scope, includes in env.DumpIntegrationIncludes().items():
if scope in ("toolchain",):
env.Append(CPPPATH=includes)
def ProcessProgramDeps(env):
def _append_pio_macros():
core_version = pepver_to_semver(__version__)
@@ -148,6 +128,27 @@ def ProcessProgramDeps(env):
env.ProcessUnFlags(env.get("BUILD_UNFLAGS"))
def ProcessCompileDbToolchainOption(env):
if "compiledb" not in COMMAND_LINE_TARGETS:
return
# Resolve absolute path of toolchain
for cmd in ("CC", "CXX", "AS"):
if cmd not in env:
continue
if os.path.isabs(env[cmd]) or '"' in env[cmd]:
continue
env[cmd] = where_is_program(env.subst("$%s" % cmd), env.subst("${ENV['PATH']}"))
if " " in env[cmd]: # issue #4998: Space in compilator path
env[cmd] = f'"{env[cmd]}"'
if env.get("COMPILATIONDB_INCLUDE_TOOLCHAIN"):
print("Warning! `COMPILATIONDB_INCLUDE_TOOLCHAIN` is scoping")
for scope, includes in env.DumpIntegrationIncludes().items():
if scope in ("toolchain",):
env.Append(CPPPATH=includes)
def ProcessProjectDeps(env):
plb = env.ConfigureProjectLibBuilder()

View File

@@ -18,7 +18,7 @@ from pathlib import Path
import click
class PlatformioCLI(click.MultiCommand):
class PlatformioCLI(click.Group):
leftover_args = []
def __init__(self, *args, **kwargs):
@@ -84,7 +84,7 @@ class PlatformioCLI(click.MultiCommand):
PlatformioCLI.leftover_args = ctx.protected_args + ctx.args
return super().invoke(ctx)
def list_commands(self, ctx):
def list_commands(self, ctx): # pylint: disable=unused-argument
return sorted(list(self._find_pio_commands()))
def get_command(self, ctx, cmd_name):

View File

@@ -146,3 +146,84 @@ def is_proxy_set(socks=False):
continue
return True
return False
def click_launch(url, wait=False, locate=False) -> int:
return _click_open_url(url, wait=wait, locate=locate)
def _click_open_url( # pylint: disable=too-many-branches, too-many-return-statements, consider-using-with, import-outside-toplevel, unspecified-encoding
url, wait=False, locate=False
):
"""
Issue https://github.com/pallets/click/issues/2868
Keep in sync with https://github.com/pallets/click/blob/main/src/click/_termui_impl.py
"""
import subprocess
def _unquote_file(url) -> str:
from urllib.parse import unquote
if url.startswith("file://"):
url = unquote(url[7:])
return url
if IS_MACOS:
args = ["open"]
if wait:
args.append("-W")
if locate:
args.append("-R")
args.append(_unquote_file(url))
null = open("/dev/null", "w")
try:
return subprocess.Popen(args, stderr=null).wait()
finally:
null.close()
elif IS_WINDOWS:
if locate:
url = _unquote_file(url)
args = ["explorer", f"/select,{url}"]
else:
args = ["start"]
if wait:
args.append("/WAIT")
args.append("")
args.append(url)
try:
return subprocess.call(args, shell=True)
except OSError:
# Command not found
return 127
elif IS_CYGWIN:
if locate:
url = _unquote_file(url)
args = ["cygstart", os.path.dirname(url)]
else:
args = ["cygstart"]
if wait:
args.append("-w")
args.append(url)
try:
return subprocess.call(args)
except OSError:
# Command not found
return 127
try:
if locate:
url = os.path.dirname(_unquote_file(url)) or "."
else:
url = _unquote_file(url)
c = subprocess.Popen(["xdg-open", url])
if wait:
return c.wait()
return 0
except OSError:
if url.startswith(("http://", "https://")) and not locate and not wait:
import webbrowser
webbrowser.open(url)
return 0
return 1

View File

@@ -167,7 +167,10 @@ def _configure(
def _run(project_dir, debug_config, client_extra_args):
loop = asyncio.ProactorEventLoop() if IS_WINDOWS else asyncio.get_event_loop()
try:
loop = asyncio.ProactorEventLoop() if IS_WINDOWS else asyncio.get_event_loop()
except RuntimeError:
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
client = GDBClientProcess(project_dir, debug_config)

View File

@@ -29,7 +29,7 @@ def get_core_dependencies():
def get_pip_dependencies():
core = [
"bottle == 0.13.*",
"click >=8.0.4, <8.1.8",
"click >=8.0.4, <8.4", # click 9.0 removes 'protected_args' attribute
"colorama",
"marshmallow == 3.*",
"pyelftools >=0.27, <1",
@@ -42,8 +42,8 @@ def get_pip_dependencies():
home = [
# PIO Home requirements
"ajsonrpc == 1.2.*",
"starlette >=0.19, <0.47",
"uvicorn >=0.16, <0.35",
"starlette >=0.19, <0.51",
"uvicorn >=0.16, <0.39",
"wsproto == 1.*",
]

View File

@@ -133,6 +133,10 @@ class SerialPortFinder:
def find(self, initial_port=None):
if initial_port:
# Treat any URL (contains '://') as a literal port
if "://" in initial_port:
return initial_port
# Otherwise fall back to existing wildcard logic
if not is_pattern_port(initial_port):
return initial_port
return self.match_serial_port(initial_port)

View File

@@ -17,7 +17,7 @@ import socket
import click
from platformio.compat import IS_WINDOWS
from platformio.compat import IS_WINDOWS, click_launch
from platformio.home.run import run_server
from platformio.package.manager.core import get_core_package_dir
@@ -86,7 +86,7 @@ def cli(port, host, no_open, shutdown_timeout, session_id):
"PlatformIO Home server is already started in another process.", fg="yellow"
)
if not no_open:
click.launch(home_url)
click_launch(home_url)
return
run_server(

View File

@@ -18,11 +18,9 @@ import os
import shutil
from functools import cmp_to_key
import click
from platformio import fs
from platformio.cache import ContentCache
from platformio.compat import aio_to_thread
from platformio.compat import aio_to_thread, click_launch
from platformio.device.list.util import list_logical_devices
from platformio.home.rpc.handlers.base import BaseRPCHandler
from platformio.http import HTTPSession, ensure_internet_on
@@ -84,15 +82,15 @@ class OSRPC(BaseRPCHandler):
@staticmethod
def open_url(url):
return click.launch(url)
return click_launch(url)
@staticmethod
def reveal_file(path):
return click.launch(path, locate=True)
return click_launch(path, locate=True)
@staticmethod
def open_file(path):
return click.launch(path)
return click_launch(path)
@staticmethod
def call_path_module_func(name, args, **kwargs):

View File

@@ -276,7 +276,7 @@ class ManifestSchema(BaseSchema):
@staticmethod
@memoized(expire="1h")
def load_spdx_licenses():
version = "3.26.0"
version = "3.27.0"
spdx_data_url = (
"https://raw.githubusercontent.com/spdx/license-list-data/"
f"v{version}/json/licenses.json"

View File

@@ -49,6 +49,7 @@ class PackagePacker:
"__*",
".DS_Store",
".vscode",
"**/.vscode/",
".cache",
"**/.cache",
"**/__pycache__",

View File

@@ -21,6 +21,8 @@ filterwarnings =
error
# Bottle
ignore:.*'cgi' is deprecated and slated for removal
ignore:'protected_args' is deprecated and will be removed in Click 9.0:DeprecationWarning
[testenv]
passenv = *