Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 2 additions & 1 deletion docs/USAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -515,7 +515,7 @@ The generated jobs follow the pattern:

1. **Setup Python + Conan** (`xmsconan_conan_setup --remote-url … --login`)
2. **Generate build files** (`xmsconan_gen --version …`)
3. **Build** (`python build.py --filter='{"build_type": "<type>"}' --wheel-dir wheelhouse --artifacts-dir test_artifacts`)
3. **Build** (`python build.py --filter='{"build_type": "<type>"}' --artifacts-dir test_artifacts`, plus `--wheel-dir wheelhouse` on Release — §10.1)
4. **Repair wheel** on Release (`xmsconan_wheel_repair --wheel-dir wheelhouse`)
5. **On tag pushes:** `xmsconan_wheel_deploy` and `xmsconan_conan_deploy … --upload`

Expand All @@ -526,6 +526,7 @@ The generated jobs follow the pattern:
- Job `name:` carries the version on any platform that fans out (`GCC-13 (Release, 3.14, Linux)`). GitHub uses an explicit `name:` verbatim and only auto-appends matrix values when none is given, so without this two legs would share one status-check name — ambiguous in the checks list and in branch-protection matching. A single-version platform keeps its original name, so existing required checks keep matching.
- **Windows** matrix: `build_type × compiler-version × python-version=ci_python_versions`.
- Wheel artifacts carry `-py${{ matrix.python-version }}` on any platform that fans out; a single-version platform keeps its bare `wheel-${{ runner.os }}` name.
- **`--wheel-dir` is passed on the Release leg only.** `[matrix].pybind_build_types` defaults to `["Release"]` (§5.4.1), so a Debug leg builds no pybind package — and `build.py` treats `--wheel-dir` as a request it must satisfy, exiting 1 when no complete set of wheels comes out (§9.1). Passing it on every leg therefore failed every Debug leg; it did exactly that in xmsconan 2.22.0–2.22.2, so a repo generated by one of those needs `xmsconan ci` re-run. Repair, artifact upload and deploy are already gated the same way, so a library that also names `Debug` loses no wheel it was publishing.
- Linux containers resolve to `conan-gcc13-py${{ matrix.python-version }}:latest`.
- `flake` deliberately stays on a single hardcoded interpreter — linting is ABI-independent, and pinning it keeps lint results identical across repos.
- Third-party actions are referenced by **commit SHA**, with the tag in a trailing comment (`uses: nelonoel/branch-name@1ea5c86… # v1.0.1`). A tag is a movable ref in a repository Aquaveo does not control, and the job it runs in holds the Conan and devpi secrets. `actions/*` stays on tags — a compromise of GitHub's own namespace is a compromise of the runner regardless. To move a pin, resolve the new tag with `gh api repos/<owner>/<repo>/commits/<tag> --jq .sha` and edit the **template**. `test_github_ci_pins_third_party_actions_to_a_sha` fails on any third-party action added by tag.
Expand Down
49 changes: 49 additions & 0 deletions tests/test_ci_file_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,55 @@ def test_ci_pins_conan_version(ci_toml, tmp_path):
assert [line for line in conan_installs if '"conan~=' not in line] == []


def _build_step_run(job):
"""The ``run:`` of one job's "Build the Conan Packages" step."""
for step in job["steps"]:
if step.get("name") == "Build the Conan Packages":
return step["run"]
raise AssertionError("job has no 'Build the Conan Packages' step")


@pytest.mark.parametrize("job_name", ["mac", "linux", "windows"])
def test_github_build_step_requests_a_wheel_only_on_release(ci_toml, tmp_path, job_name):
"""``--wheel-dir`` reaches build.py on the Release leg alone.

``[matrix].pybind_build_types`` defaults to Release, so a Debug leg builds
no pybind package -- and build.py treats ``--wheel-dir`` as a request it
must satisfy, exiting 1 when no complete set of wheels comes out. Passing
the flag unconditionally therefore failed every Debug leg of every
consumer, which is what it did between xmsconan 2.22.0 and this fix.

Asserted per job rather than over the whole document so a regression names
the platform that lost the gate.
"""
run = _build_step_run(_github_jobs(ci_toml, tmp_path)[job_name])

assert run.count("--wheel-dir") == 1
assert "${{ matrix.build_type == 'Release' && '--wheel-dir wheelhouse" in run


def test_github_windows_skip_dependency_libs_stays_inside_the_wheel_gate(tmp_path):
"""The unrepaired-Windows companion flag is gated with ``--wheel-dir``.

``--skip-dependency-libs`` is read only inside build.py's ``if
args.wheel_dir`` branch, so leaving it outside the gate would put a flag on
the Debug command line that reads as staging control and does nothing.
"""
toml_file = tmp_path / "build.toml"
toml_file.write_text(
'library_name = "xmscore"\ndescription = "Core library"\nci_type = "github"\n'
"\n[ci]\nwindows_wheel_repair = false\n",
encoding="utf-8",
)

run = _build_step_run(_github_jobs(toml_file, tmp_path)["windows"])

assert (
"${{ matrix.build_type == 'Release' && "
"'--wheel-dir wheelhouse --skip-dependency-libs' || '' }}" in run
)


def test_github_ci_includes_artifacts_dir_flag(ci_toml, tmp_path):
"""Rendered GitHub CI build commands include --artifacts-dir test_artifacts."""
output_dir = tmp_path / "output"
Expand Down
15 changes: 11 additions & 4 deletions xmsconan/generator_tools/ci_templates/github-ci.yaml.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@
# (`gh api repos/<owner>/<repo>/commits/<tag> --jq .sha`) and editing the
# template -- not the generated file.
#
# Every wheel step -- `--wheel-dir` on the build, then repair, artifact
# upload and deploy -- runs on the Release leg only.
# `[matrix].pybind_build_types` defaults to Release alone, so a Debug leg
# builds no pybind package, and build.py treats `--wheel-dir` as a request
# it must satisfy: it exits 1 when no complete set of wheels comes out.
# Asking a Debug leg for a wheel fails the leg instead of producing one.
#
# Generated by xmsconan_ci — do not edit manually.

name: << display_name >>-CI
Expand Down Expand Up @@ -159,7 +166,7 @@ jobs:
run: xmsconan_gen --version ${{ env.XMS_VERSION }} build.toml
# Build the Conan Package
- name: Build the Conan Packages
run: "python build.py --filter=\"{\\\"build_type\\\": \\\"${{ matrix.build_type }}\\\"}\" --wheel-dir wheelhouse --artifacts-dir test_artifacts"
run: "python build.py --filter=\"{\\\"build_type\\\": \\\"${{ matrix.build_type }}\\\"}\" ${{ matrix.build_type == 'Release' && '--wheel-dir wheelhouse' || '' }} --artifacts-dir test_artifacts"
shell: bash
- name: Upload test artifacts
uses: actions/upload-artifact@v4
Expand Down Expand Up @@ -302,7 +309,7 @@ jobs:
run: xmsconan_gen --version ${{ env.XMS_VERSION }} build.toml
# Build the Conan Package
- name: Build the Conan Packages
run: "python build.py --filter=\"{\\\"build_type\\\": \\\"${{ matrix.build_type }}\\\"}\" --wheel-dir wheelhouse --artifacts-dir test_artifacts"
run: "python build.py --filter=\"{\\\"build_type\\\": \\\"${{ matrix.build_type }}\\\"}\" ${{ matrix.build_type == 'Release' && '--wheel-dir wheelhouse' || '' }} --artifacts-dir test_artifacts"
shell: bash
- name: Upload test artifacts
uses: actions/upload-artifact@v4
Expand Down Expand Up @@ -446,7 +453,7 @@ jobs:
run: xmsconan_gen --version ${{ env.XMS_VERSION }} build.toml
# Build the Conan Package
- name: Build the Conan Packages
run: "python build.py --filter=\"{\\\"build_type\\\": \\\"${{ matrix.build_type }}\\\"}\" --wheel-dir wheelhouse --artifacts-dir test_artifacts"
run: "python build.py --filter=\"{\\\"build_type\\\": \\\"${{ matrix.build_type }}\\\"}\" ${{ matrix.build_type == 'Release' && '--wheel-dir wheelhouse' || '' }} --artifacts-dir test_artifacts"
shell: bash
- name: Upload test artifacts
uses: actions/upload-artifact@v4
Expand Down Expand Up @@ -598,7 +605,7 @@ jobs:
run: xmsconan_gen --version ${{ env.XMS_VERSION }} build.toml
# Build the Conan Package
- name: Build the Conan Packages
run: "python build.py --filter=\"{\\\"build_type\\\": \\\"${{ matrix.build_type }}\\\"}\" --wheel-dir wheelhouse<% if not ci_windows_wheel_repair %> --skip-dependency-libs<% endif %> --artifacts-dir test_artifacts"
run: "python build.py --filter=\"{\\\"build_type\\\": \\\"${{ matrix.build_type }}\\\"}\" ${{ matrix.build_type == 'Release' && '--wheel-dir wheelhouse<% if not ci_windows_wheel_repair %> --skip-dependency-libs<% endif %>' || '' }} --artifacts-dir test_artifacts"
shell: cmd
- name: Upload test artifacts
uses: actions/upload-artifact@v4
Expand Down
Loading