mirror of
https://github.com/bmad-code-org/BMAD-METHOD.git
synced 2026-10-31 03:02:25 +08:00
* ci: run the Python quality job on Windows beside Ubuntu
The python job now runs on ubuntu-latest and windows-latest with the
same steps and triggers. fail-fast is off so each platform reports its
own result. The Windows job is expected to be red until the defects it
exposes are fixed; no check is skipped or branched by platform.
* fix: make pytest hook portable on Windows
* fix(bmad): replace _bmad on Windows when it already exists (#2918)
A later setup run reserved an empty _bmad.old-* directory with mkdtemp
and renamed _bmad onto it. Windows refuses a rename onto an existing
directory, so every run after the first failed with WinError 183. The
backup is now a name that does not exist yet, made from the time of
the run.
Fixes #2879
* fix: write UTF-8 from every script on Windows (#2920)
A script run by an agent or a hook writes to a pipe. On Windows, piped
output defaults to a legacy code page: a character outside it crashes
the script, and one inside it reaches the reader as the wrong bytes.
Every script now sets stdout and stderr to UTF-8 when it starts on
Windows. A ticketing test reads and writes text outside ASCII to prove
it.
A Breakdown entry's title is now separated with a hyphen, not a long
dash. The ticketing tests wrote that dash in the legacy code page on
Windows; the parser still accepts either.
* fix(quality): accept the platform's line endings in the Python checks (#2919)
A standard Windows checkout has CRLF. yamllint expected LF everywhere,
and four test assertions compared text-mode fixtures byte for byte with
LF. yamllint now expects the line ending of the platform it runs on,
and those assertions no longer depend on the line ending.
* fix(tools): parse skills with the platform's line ending in the skill validator (#2921)
* test: create every temp directory under the resolved temp root (#2922)
* fix(tools): report repo paths with forward slashes on every platform (#2923)
* fix(skills): write paths into rendered prompts with forward slashes on every platform (#2924)
* test(skills): expect forward-slash paths in the rendered text of two more tests (#2925)
* fix(skills): report a folder that refuses new files on Windows, and test denied access there (#2926)
On Windows, tempfile.mkstemp takes "access denied" for a name collision and tries the next name, up to os.TMP_MAX times, so sprint_status.py hung in a folder it cannot write to. _atomic_write now creates its temp file in one attempt.
The tests that need an unreadable file or a folder that takes no new file set the case up with icacls on Windows, where os.chmod cannot. The test of a preserved file mode is skipped there.
* fix(skills): resolve git through PATH in the retrospective's git script, and write its fake git in Python (#2927)
On Windows a bare "git" handed to CreateProcess finds only git.exe, so a
git.cmd or git.bat ahead of it on PATH was never run. The script now resolves
git with shutil.which, which honours PATHEXT.
The tests' fake git was an sh script, which Windows cannot run, so four tests
failed there. It is now a Python script behind a launcher: git.cmd on Windows,
an sh one-liner elsewhere.
* fix(skills): report a folder that refuses new files on Windows in sprint planning, the renderer, and setup (#2928)
On Windows, tempfile in Python before 3.14 takes "access denied" for a name
collision and tries the next name, some two billion times. In a folder whose
access list denies new files, sprint_plan.py, render_skill.py, and setup.py
hung instead of reporting the failure.
Each now creates its temp file or folder in one attempt, exclusively, private
to the user, under a random name: what tempfile does inside, without the retry.
One test per script denies new files in the folder, with icacls on Windows and
chmod elsewhere, and runs the script as a child with a timeout.
* test: share one chmod helper across the test suite (#2929)
Five test files each defined the same helper: os.chmod, or on Windows icacls
with a deny entry. It now lives once in tools/tests/helpers.py. pytest's
pythonpath setting puts that folder on the import path, so the tests under
skills/ find it too, however they are run from the repo.
* revert: resolve git through PATH in the retrospective's git script (#2927) (#2930)
This reverts the product change of 1c2fb5b4 and drops the four tests it was
made for. The product changed so that a fake git on PATH could run on Windows,
and the fake became a Python script behind a launcher per platform.
The four tests need a git that answers what the installed git never does. Two
of them stand for a git older than 2.31 and for a git killed without a word,
which no repository can arrange. They are more trouble than they are worth.
The product runs a bare "git" again, and the fake git and its helpers are
gone. The code the four tests pinned is unchanged.
67 lines
1.9 KiB
TOML
67 lines
1.9 KiB
TOML
# Development tooling for the BMAD-METHOD repository.
|
|
#
|
|
# This is not a distributable package: the repository tree itself is what
|
|
# `npx skills add bmad-code-org/BMAD-METHOD` and the plugin marketplaces
|
|
# install, and each shipped script under skills/*/scripts declares its own
|
|
# dependencies inline (PEP 723) so `uv run` works without this file.
|
|
# The release version lives in [bmod] of each skills/bmod-*/bmod.toml, not here.
|
|
|
|
[project]
|
|
name = "bmad-method"
|
|
version = "0"
|
|
description = "Repository tooling for BMAD-METHOD (not published)"
|
|
requires-python = ">=3.11"
|
|
dependencies = []
|
|
|
|
[dependency-groups]
|
|
dev = [
|
|
"jinja2>=3.1",
|
|
"pre-commit>=4.6.2",
|
|
"pytest>=8",
|
|
"pytest-xdist>=3",
|
|
"pyyaml>=6.0.2,<7",
|
|
"ruamel.yaml>=0.18",
|
|
"ruff>=0.14",
|
|
]
|
|
|
|
[tool.uv]
|
|
package = false
|
|
|
|
[tool.pytest.ini_options]
|
|
addopts = "-q -ra --tb=short -n auto -p no:cacheprovider"
|
|
testpaths = ["tools/tests", "skills"]
|
|
# tools/tests/helpers.py, for the tests under skills/ as well.
|
|
pythonpath = ["tools/tests"]
|
|
|
|
[tool.ruff]
|
|
# Every shipped script declares the same floor inline (PEP 723) as
|
|
# requires-python above; tools/tests/test_python_floor.py enforces that,
|
|
# since ruff reads only this setting.
|
|
target-version = "py311"
|
|
line-length = 120
|
|
extend-exclude = ["tools/tests/fixtures"]
|
|
|
|
[tool.ruff.lint]
|
|
select = ["E", "F", "I", "UP", "B"]
|
|
ignore = [
|
|
"E501", # long lines: the formatter handles code; strings and comments may exceed
|
|
]
|
|
|
|
[tool.rumdl]
|
|
# The five rules markdownlint enforced before; the rest stay off.
|
|
enable = ["MD001", "MD024", "MD026", "MD034", "MD037"]
|
|
exclude = ["node_modules", "tools/tests/fixtures", "CODE_OF_CONDUCT.md", "docs-site/dist", "docs-site/.astro"]
|
|
|
|
[tool.rumdl.MD024]
|
|
siblings-only = true
|
|
|
|
[tool.rumdl.MD026]
|
|
punctuation = ","
|
|
|
|
[tool.yamlfix]
|
|
# yamlfix's default of 0 also strips blank lines inside block scalars,
|
|
# which rewrites the shell scripts in workflows. 1 keeps them.
|
|
whitelines = 1
|
|
section_whitelines = 1
|
|
explicit_start = false
|