From 194fdbc8f43339af404a70590bad3d214810a2a2 Mon Sep 17 00:00:00 2001 From: Thomas Robitaille Date: Sat, 28 Feb 2026 12:12:07 +0000 Subject: [PATCH 1/2] Added support for specifying a working directory other than the root of the repository --- .github/workflows/publish.yml | 7 ++++++ .github/workflows/publish_pure_python.yml | 6 +++++ .github/workflows/test_publish.yml | 12 ++++++++++ .../workflows/test_publish_pure_python.yml | 10 ++++++++ .github/workflows/test_tox.yml | 9 ++++++++ .github/workflows/tox.yml | 6 +++++ .gitignore | 2 ++ docs/source/publish.rst | 19 +++++++++++++++ docs/source/publish_pure_python.rst | 19 +++++++++++++++ docs/source/tox.rst | 18 +++++++++++++++ packages/subpackage/pyproject.toml | 19 +++++++++++++++ packages/subpackage/subpackage/__init__.py | 1 + .../subpackage/subpackage/tests/__init__.py | 0 .../subpackage/tests/test_subpackage.py | 3 +++ packages/subpackage/tox.ini | 6 +++++ packages/subpackage_c/pyproject.toml | 10 ++++++++ packages/subpackage_c/setup.py | 8 +++++++ .../subpackage_c/subpackage_c/__init__.py | 5 ++++ packages/subpackage_c/subpackage_c/_example.c | 23 +++++++++++++++++++ 19 files changed, 183 insertions(+) create mode 100644 packages/subpackage/pyproject.toml create mode 100644 packages/subpackage/subpackage/__init__.py create mode 100644 packages/subpackage/subpackage/tests/__init__.py create mode 100644 packages/subpackage/subpackage/tests/test_subpackage.py create mode 100644 packages/subpackage/tox.ini create mode 100644 packages/subpackage_c/pyproject.toml create mode 100644 packages/subpackage_c/setup.py create mode 100644 packages/subpackage_c/subpackage_c/__init__.py create mode 100644 packages/subpackage_c/subpackage_c/_example.c diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 79f1b6ce..9e1c5a8d 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -101,6 +101,11 @@ on: required: false default: '' type: string + working-directory: + description: The working directory containing the package to build, relative to the repository root + required: false + default: '.' + type: string secrets: pypi_token: required: false @@ -207,6 +212,7 @@ jobs: uses: pypa/cibuildwheel@298ed2fb2c105540f5ed055e8a6ad78d82dd3a7e # v3.3.1 with: output-dir: dist + package-dir: ${{ inputs.working-directory }} extras: uv env: CIBW_BUILD: ${{ matrix.CIBW_BUILD }} @@ -256,6 +262,7 @@ jobs: test_command: ${{ inputs.test_command }} pure_python_wheel: false python-version: '3.12' + source-directory: ${{ inputs.working-directory }} - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 if: | needs.targets.outputs.upload_to_pypi == 'true' || inputs.upload_to_anaconda || inputs.save_artifacts diff --git a/.github/workflows/publish_pure_python.yml b/.github/workflows/publish_pure_python.yml index 8b6ff129..c85175cf 100644 --- a/.github/workflows/publish_pure_python.yml +++ b/.github/workflows/publish_pure_python.yml @@ -88,6 +88,11 @@ on: required: false default: '' type: string + working-directory: + description: The working directory containing the package to build, relative to the repository root + required: false + default: '.' + type: string secrets: pypi_token: required: false @@ -133,6 +138,7 @@ jobs: test_command: ${{ inputs.test_command }} python-version: ${{ inputs.python-version }} pure_python_wheel: true + source-directory: ${{ inputs.working-directory }} - id: set-upload run: | if [ $UPLOAD_TO_PYPI == "true" ] || [ $UPLOAD_TAG == "true" ]; diff --git a/.github/workflows/test_publish.yml b/.github/workflows/test_publish.yml index 3d5f91c5..76c1d0c1 100644 --- a/.github/workflows/test_publish.yml +++ b/.github/workflows/test_publish.yml @@ -4,10 +4,12 @@ on: paths: - .github/workflows/publish.yml - .github/workflows/test_publish.yml + - packages/subpackage_c/** pull_request: paths: - .github/workflows/publish.yml - .github/workflows/test_publish.yml + - packages/subpackage_c/** concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -51,6 +53,16 @@ jobs: test_command: pytest --pyargs test_package targets: '' + release_working_directory: + uses: ./.github/workflows/publish.yml + with: + working-directory: packages/subpackage_c + test_command: python -c "from subpackage_c import example_func; assert example_func() == 42" + targets: | + - linux + upload_to_pypi: false + timeout-minutes: 30 + test-upload-external: name: Use built dists and test upload runs-on: ubuntu-latest diff --git a/.github/workflows/test_publish_pure_python.yml b/.github/workflows/test_publish_pure_python.yml index 82d23382..c45e135f 100644 --- a/.github/workflows/test_publish_pure_python.yml +++ b/.github/workflows/test_publish_pure_python.yml @@ -4,10 +4,12 @@ on: paths: - .github/workflows/publish_pure_python.yml - .github/workflows/test_publish_pure_python.yml + - packages/subpackage/** pull_request: paths: - .github/workflows/publish_pure_python.yml - .github/workflows/test_publish_pure_python.yml + - packages/subpackage/** concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -30,6 +32,14 @@ jobs: env: | CUSTOM_VAR: custom value + release_working_directory: + uses: ./.github/workflows/publish_pure_python.yml + with: + working-directory: packages/subpackage + test_extras: test + test_command: pytest --pyargs subpackage + upload_to_pypi: false + timeout-minutes: 5 test-upload-external: name: Use built dists and test upload diff --git a/.github/workflows/test_tox.yml b/.github/workflows/test_tox.yml index 04a57508..86cdc564 100644 --- a/.github/workflows/test_tox.yml +++ b/.github/workflows/test_tox.yml @@ -6,12 +6,14 @@ on: - .github/workflows/test_tox.yml - pyproject.toml - tox.ini + - packages/subpackage/** pull_request: paths: - .github/workflows/tox.yml - .github/workflows/test_tox.yml - pyproject.toml - tox.ini + - packages/subpackage/** concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -204,3 +206,10 @@ jobs: - linux: py313t-linux - macos: py313t-macos - windows: py313t-windows + + test_working_directory: + uses: ./.github/workflows/tox.yml + with: + working-directory: packages/subpackage + envs: | + - linux: py312 diff --git a/.github/workflows/tox.yml b/.github/workflows/tox.yml index ea7e1076..c5b9873b 100644 --- a/.github/workflows/tox.yml +++ b/.github/workflows/tox.yml @@ -107,6 +107,11 @@ on: required: false default: '' type: string + working-directory: + description: The working directory for running tox, relative to the repository root + required: false + default: '.' + type: string secrets: CODECOV_TOKEN: description: Codecov upload token @@ -153,6 +158,7 @@ jobs: defaults: run: shell: bash -l {0} + working-directory: ${{ inputs.working-directory }} steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 diff --git a/.gitignore b/.gitignore index 0c889d2e..fda05527 100644 --- a/.gitignore +++ b/.gitignore @@ -34,6 +34,8 @@ MANIFEST *.manifest *.spec *.c +# Exception for test package C extension +!packages/subpackage_c/subpackage_c/_example.c # Installer logs pip-log.txt diff --git a/docs/source/publish.rst b/docs/source/publish.rst index acf48e27..869e21fb 100644 --- a/docs/source/publish.rst +++ b/docs/source/publish.rst @@ -224,6 +224,25 @@ submodules Whether to checkout submodules. Default is ``true``. +working-directory +^^^^^^^^^^^^^^^^^ + +The working directory containing the package to build, relative to the +repository root. Default is ``.`` (the repository root). + +This is useful when your package is located in a subdirectory of the +repository, such as in monorepos where multiple packages exist in the +same repository, or when using a non-standard project layout. + +.. code:: yaml + + uses: OpenAstronomy/github-actions-workflows/.github/workflows/publish.yml@v1 + with: + working-directory: packages/my-package + test_command: pytest --pyargs my_package + secrets: + pypi_token: ${{ secrets.pypi_token }} + Secrets ~~~~~~~ diff --git a/docs/source/publish_pure_python.rst b/docs/source/publish_pure_python.rst index b55a7f8e..97d46f78 100644 --- a/docs/source/publish_pure_python.rst +++ b/docs/source/publish_pure_python.rst @@ -141,6 +141,25 @@ submodules Whether to checkout submodules. Default is ``true``. +working-directory +^^^^^^^^^^^^^^^^^ + +The working directory containing the package to build, relative to the +repository root. Default is ``.`` (the repository root). + +This is useful when your package is located in a subdirectory of the +repository, such as in monorepos where multiple packages exist in the +same repository, or when using a non-standard project layout. + +.. code:: yaml + + uses: OpenAstronomy/github-actions-workflows/.github/workflows/publish_pure_python.yml@v1 + with: + working-directory: packages/my-package + test_command: pytest --pyargs my_package + secrets: + pypi_token: ${{ secrets.pypi_token }} + save_artifacts ^^^^^^^^^^^^^^ diff --git a/docs/source/tox.rst b/docs/source/tox.rst index b61e49e4..58ba9db1 100644 --- a/docs/source/tox.rst +++ b/docs/source/tox.rst @@ -434,6 +434,24 @@ submodules Whether to checkout submodules. Default is ``true``. +working-directory +^^^^^^^^^^^^^^^^^ + +The working directory for running tox, relative to the repository root. +Default is ``.`` (the repository root). + +This is useful when your package is located in a subdirectory of the +repository, such as in monorepos where multiple packages exist in the +same repository, or when using a non-standard project layout. + +.. code:: yaml + + uses: OpenAstronomy/github-actions-workflows/.github/workflows/tox.yml@v1 + with: + working-directory: packages/my-package + envs: | + - linux: py312 + Secrets ~~~~~~~ diff --git a/packages/subpackage/pyproject.toml b/packages/subpackage/pyproject.toml new file mode 100644 index 00000000..de911425 --- /dev/null +++ b/packages/subpackage/pyproject.toml @@ -0,0 +1,19 @@ +[build-system] +requires = ["setuptools>=61.2"] +build-backend = "setuptools.build_meta" + +[project] +name = "subpackage" +version = "0.1.0" + +[project.optional-dependencies] +test = ["pytest"] + +[dependency-groups] +test = ["pytest>=8.0.0"] + +[tool.setuptools] +include-package-data = false + +[tool.setuptools.packages] +find = {namespaces = false} diff --git a/packages/subpackage/subpackage/__init__.py b/packages/subpackage/subpackage/__init__.py new file mode 100644 index 00000000..3dc1f76b --- /dev/null +++ b/packages/subpackage/subpackage/__init__.py @@ -0,0 +1 @@ +__version__ = "0.1.0" diff --git a/packages/subpackage/subpackage/tests/__init__.py b/packages/subpackage/subpackage/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/packages/subpackage/subpackage/tests/test_subpackage.py b/packages/subpackage/subpackage/tests/test_subpackage.py new file mode 100644 index 00000000..68ada713 --- /dev/null +++ b/packages/subpackage/subpackage/tests/test_subpackage.py @@ -0,0 +1,3 @@ +def test_import(): + import subpackage + assert subpackage.__version__ == "0.1.0" diff --git a/packages/subpackage/tox.ini b/packages/subpackage/tox.ini new file mode 100644 index 00000000..17282538 --- /dev/null +++ b/packages/subpackage/tox.ini @@ -0,0 +1,6 @@ +[tox] +envlist = py312 + +[testenv] +deps = pytest +commands = pytest {posargs} diff --git a/packages/subpackage_c/pyproject.toml b/packages/subpackage_c/pyproject.toml new file mode 100644 index 00000000..bc701f65 --- /dev/null +++ b/packages/subpackage_c/pyproject.toml @@ -0,0 +1,10 @@ +[build-system] +requires = ["setuptools>=61.2"] +build-backend = "setuptools.build_meta" + +[project] +name = "subpackage_c" +version = "0.1.0" + +[project.optional-dependencies] +test = ["pytest"] diff --git a/packages/subpackage_c/setup.py b/packages/subpackage_c/setup.py new file mode 100644 index 00000000..16a7b980 --- /dev/null +++ b/packages/subpackage_c/setup.py @@ -0,0 +1,8 @@ +from setuptools import Extension, find_packages, setup + +setup( + packages=find_packages(), + ext_modules=[ + Extension("subpackage_c._example", ["subpackage_c/_example.c"]), + ], +) diff --git a/packages/subpackage_c/subpackage_c/__init__.py b/packages/subpackage_c/subpackage_c/__init__.py new file mode 100644 index 00000000..f2888f54 --- /dev/null +++ b/packages/subpackage_c/subpackage_c/__init__.py @@ -0,0 +1,5 @@ +__version__ = "0.1.0" + +from ._example import example_func + +__all__ = ["example_func"] diff --git a/packages/subpackage_c/subpackage_c/_example.c b/packages/subpackage_c/subpackage_c/_example.c new file mode 100644 index 00000000..1a946ce7 --- /dev/null +++ b/packages/subpackage_c/subpackage_c/_example.c @@ -0,0 +1,23 @@ +#define PY_SSIZE_T_CLEAN +#include + +static PyObject* example_func(PyObject* self, PyObject* args) { + return PyLong_FromLong(42); +} + +static PyMethodDef ExampleMethods[] = { + {"example_func", example_func, METH_NOARGS, "Return 42"}, + {NULL, NULL, 0, NULL} +}; + +static struct PyModuleDef examplemodule = { + PyModuleDef_HEAD_INIT, + "_example", + NULL, + -1, + ExampleMethods +}; + +PyMODINIT_FUNC PyInit__example(void) { + return PyModule_Create(&examplemodule); +} From 293b81b8f984dfca15fa5200d129c6f91b48cb27 Mon Sep 17 00:00:00 2001 From: Thomas Robitaille Date: Sun, 1 Mar 2026 20:00:58 +0000 Subject: [PATCH 2/2] Mention that working-directory can't be specified per tox env --- docs/source/tox.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/tox.rst b/docs/source/tox.rst index 58ba9db1..1f6721de 100644 --- a/docs/source/tox.rst +++ b/docs/source/tox.rst @@ -31,7 +31,7 @@ Inputs A specification of tox environments must be passed to the ``envs`` input. There are a number of other inputs. All of these inputs (except -``submodules``) can also be specified under each tox environment to +``submodules`` and ``working-directory``) can also be specified under each tox environment to overwrite the global value. In the following example ``test1`` will pass ``--arg-local`` to pytest,