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
75 changes: 0 additions & 75 deletions crates/rattler_build_recipe/src/variant_render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1326,18 +1326,6 @@ fn render_multi_output_with_variants(
variant_config: &VariantConfig,
config: RenderConfig,
) -> Result<Vec<RenderedVariant>, RenderError> {
// Check if recipe contains staging outputs - these require experimental flag
let has_staging = stage0_recipe
.outputs
.iter()
.any(|o| matches!(o, stage0::Output::Staging(_)));

if has_staging && !config.experimental {
return Err(RenderError::ExperimentalRequired {
message: "staging outputs are an experimental feature: provide the `--experimental` flag to enable this feature".to_string(),
});
}

let stage0 = Stage0Recipe::MultiOutput(Box::new(stage0_recipe.clone()));
render_with_variants(&stage0, variant_config, config)
}
Expand Down Expand Up @@ -2156,69 +2144,6 @@ variant:
assert_eq!(names, vec!["my-package-a"]);
}

#[test]
fn test_staging_requires_experimental() {
// Test that staging outputs require the experimental flag
let recipe_yaml = r#"
schema_version: 1

context:
version: "1.0.0"

recipe:
version: ${{ version }}

build:
number: 0

outputs:
- staging:
name: build-cache
build:
script:
- echo "Building..."

- package:
name: my-pkg
inherit: build-cache
build:
noarch: generic
"#;

let variant_yaml = r#"{}"#;

let stage0_recipe = stage0::parse_recipe_or_multi_from_source(recipe_yaml).unwrap();
let variant_config = VariantConfig::from_yaml_str(variant_yaml).unwrap();

// Without experimental flag, should fail
let result =
render_recipe_with_variant_config(&stage0_recipe, &variant_config, RenderConfig::new());

assert!(
result.is_err(),
"Staging outputs should require experimental flag"
);
let err = result.unwrap_err();
assert!(
err.to_string().contains("experimental"),
"Error should mention experimental flag: {}",
err
);

// With experimental flag, should succeed
let result = render_recipe_with_variant_config(
&stage0_recipe,
&variant_config,
RenderConfig::new().with_experimental(true),
);

assert!(
result.is_ok(),
"Staging outputs should work with experimental flag: {:?}",
result.err()
);
}

#[test]
fn test_attestation_requires_experimental() {
let recipe_yaml = r#"
Expand Down
2 changes: 1 addition & 1 deletion docs/debugging_builds.md
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ output/
│ └─ host_env_placehold_.../ # Host environment (runtime dependencies)
│ └─ build_env/ # Build environment (build-time dependencies)
└─ src_cache/ # Downloaded and extracted sources
└─ build_cache/ # Staging cache (experimental)
└─ build_cache/ # Staging cache
│ └─ staging_<sha256>/ # Per-staging-output cache
│ └─ metadata.json # Cache metadata (deps, sources, variant)
│ └─ prefix/ # Cached prefix files from staging build
Expand Down
37 changes: 0 additions & 37 deletions docs/experimental_features.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,43 +9,6 @@ Currently only the `build` and `rebuild` commands support the following experime
To enable them, use the `--experimental` flag with the command.
Or, use the environment variable, `RATTLER_BUILD_EXPERIMENTAL=true`.

## Staging outputs

Staging outputs allow you to build code once and cache the results, then have
multiple package outputs inherit those cached files. This is useful for
splitting a single build into multiple packages (e.g. a runtime library and
development headers) without rebuilding.

```yaml
outputs:
- staging:
name: mylib-build
requirements:
build:
- ${{ compiler('c') }}
build:
script:
- cmake -B build && cmake --build build --target install

- package:
name: mylib
inherit: mylib-build
build:
files:
- lib/**

- package:
name: mylib-dev
inherit: mylib-build
build:
files:
- include/**
```

See the [staging outputs guide](multiple_output_cache.md) for full
documentation, and the [recipe reference](reference/recipe_file.md#staging-outputs)
for the complete YAML schema.

## Sigstore source attestation

The `attestation` field on URL sources allows verifying that downloaded source archives were produced by a trusted publisher using [Sigstore](https://sigstore.dev) attestations. This is supported for PyPI packages (where the bundle URL is automatically derived) and GitHub releases (where you specify the `bundle_url` manually).
Expand Down
4 changes: 0 additions & 4 deletions docs/multiple_output_cache.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,6 @@ outputs:
- include/*
```

!!!note

Since this is an experimental feature, you need to pass the `--experimental` flag to enable parsing of staging outputs.

In this example, we have a staging output called `mypackage-build` that creates files during its build. The two package outputs `mypackage-library` and `mypackage-headers` inherit from it using the `inherit:` key.

When building, the staging output runs first and creates files in `$PREFIX`. These files are then copied into the `$PREFIX` of each inheriting output package.
Expand Down
6 changes: 1 addition & 5 deletions docs/reference/multi_output.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,11 +133,7 @@ outputs:
```


## Staging Outputs (Experimental)

!!! warning
Staging outputs require the `--experimental` flag:
`rattler-build build --experimental -r recipe.yaml`
## Staging Outputs

A staging output compiles code once and caches the result. Package outputs then
inherit from the staging cache and select subsets of the built files. This avoids
Expand Down
2 changes: 0 additions & 2 deletions docs/reference/recipe_file.md
Original file line number Diff line number Diff line change
Expand Up @@ -1416,8 +1416,6 @@ will also build two versions of `test`, one that depends on `libtest (openssl

!!!note

Staging outputs are an experimental feature. You need to pass the
`--experimental` flag or set `RATTLER_BUILD_EXPERIMENTAL=true` to use them.
See the [staging outputs guide](../multiple_output_cache.md) for a full
walkthrough.

Expand Down
4 changes: 1 addition & 3 deletions py-rattler-build/notebooks/multi_output_and_staging.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -274,9 +274,7 @@
"\n",
"# Render the recipe\n",
"staging_variants = VariantConfig()\n",
"platform_config = PlatformConfig(experimental=True) # Staging is still experimental\n",
"staging_render = RenderConfig(platform=platform_config)\n",
"staging_results = staging_recipe.render(staging_variants, staging_render)\n",
"staging_results = staging_recipe.render(staging_variants)\n",
"\n",
"print(f\"\\nRendered {len(staging_results)} package(s)\")\n",
"print(\"(Staging outputs don't produce packages)\")\n",
Expand Down
6 changes: 2 additions & 4 deletions py-rattler-build/tests/unit/test_render.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,8 +175,7 @@ def test_render_recipe_with_staging(test_data_dir: Path) -> None:
recipe_yaml = recipe_path.read_text()
recipe = Stage0Recipe.from_yaml(recipe_yaml)
variant_config = VariantConfig()
render_config = RenderConfig(platform=PlatformConfig(experimental=True))
rendered = recipe.render(variant_config, render_config)
rendered = recipe.render(variant_config)
assert len(rendered) == 2
assert isinstance(rendered[0], RenderedVariant)

Expand Down Expand Up @@ -219,9 +218,8 @@ def test_render_recipe_from_path(test_data_dir: Path) -> None:
recipe_path = test_data_dir / "recipes" / "with-staging.yaml"
recipe = Stage0Recipe.from_file(recipe_path)
variant_config = VariantConfig()
render_config = RenderConfig(platform=PlatformConfig(experimental=True))

rendered = recipe.render(variant_config, render_config)
rendered = recipe.render(variant_config)

assert len(rendered) == 2
assert rendered[0].recipe.package.name == "mixed-compiled"
Expand Down
18 changes: 5 additions & 13 deletions test/end-to-end/test_staging.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@

def test_basic_staging(rattler_build: RattlerBuild, recipes: Path, tmp_path: Path):
"""Test basic staging output with multiple package outputs inheriting from it."""
rattler_build.build(
recipes / "staging/basic-staging.yaml", tmp_path, extra_args=["--experimental"]
)
rattler_build.build(recipes / "staging/basic-staging.yaml", tmp_path)

# Both package outputs should be built
pkg1 = get_extracted_package(tmp_path, "foo-split-1")
Expand Down Expand Up @@ -434,9 +432,7 @@ def test_staging_render_only(
rattler_build: RattlerBuild, recipes: Path, tmp_path: Path
):
"""Test that rendering works correctly with staging outputs."""
rendered = rattler_build.render(
recipes / "staging/basic-staging.yaml", tmp_path, extra_args=["--experimental"]
)
rendered = rattler_build.render(recipes / "staging/basic-staging.yaml", tmp_path)

# Should have 2 outputs (foo-split-1 and foo-othersplit)
assert len(rendered) == 2
Expand All @@ -453,9 +449,7 @@ def test_staging_hash_includes_variant(
rattler_build: RattlerBuild, recipes: Path, tmp_path: Path
):
"""Test that staging cache hash includes variant information."""
rendered = rattler_build.render(
recipes / "staging/basic-staging.yaml", tmp_path, extra_args=["--experimental"]
)
rendered = rattler_build.render(recipes / "staging/basic-staging.yaml", tmp_path)

# Check that used_variant is set for staging caches
for output in rendered:
Expand Down Expand Up @@ -487,7 +481,7 @@ def test_staging_different_platforms(
rattler_build.build(
recipes / "staging/basic-staging.yaml",
tmp_path,
extra_args=["--experimental", "--target-platform", target_platform],
extra_args=["--target-platform", target_platform],
)

pkg1 = get_extracted_package(tmp_path, "foo-split-1")
Expand All @@ -499,9 +493,7 @@ def test_staging_with_tests(rattler_build: RattlerBuild, recipes: Path, tmp_path
# The basic-staging.yaml includes tests that run 'cat $PREFIX/foo.txt'
# This verifies the staging cache files are available during tests

rattler_build.build(
recipes / "staging/basic-staging.yaml", tmp_path, extra_args=["--experimental"]
)
rattler_build.build(recipes / "staging/basic-staging.yaml", tmp_path)

# If tests failed, the build would have failed
# Just verify the packages were created
Expand Down