diff --git a/.github/workflows/base-demo-e2e.yml b/.github/workflows/base-demo-e2e.yml index b6f7ef48..f21956ad 100644 --- a/.github/workflows/base-demo-e2e.yml +++ b/.github/workflows/base-demo-e2e.yml @@ -110,6 +110,18 @@ jobs: printf ' enabled: false\n' } >> "$HOME/.base.d/config.yaml" + - name: Trust the selected base-demo mise configuration + env: + BASE_DEMO_ROOT: ${{ github.workspace }}/../base-demo + run: | + set -euo pipefail + mise_config="$BASE_DEMO_ROOT/.mise.toml" + if [[ -f "$mise_config" ]]; then + mise trust "$mise_config" + else + printf 'No mise configuration declared by base-demo; continuing without provider trust.\n' + fi + - name: Run Base demo end-to-end loop env: BASE_DEMO_ROOT: ${{ github.workspace }}/../base-demo diff --git a/.github/workflows/ecosystem-release-bom.yml b/.github/workflows/ecosystem-release-bom.yml index acb8c9c6..df3a42d6 100644 --- a/.github/workflows/ecosystem-release-bom.yml +++ b/.github/workflows/ecosystem-release-bom.yml @@ -189,6 +189,16 @@ jobs: if: matrix.platform == 'macos-14' run: ./bin/basectl setup --ci base --format json + - name: Trust the selected base-demo mise configuration + run: | + set -euo pipefail + mise_config="$GITHUB_WORKSPACE/../base-demo/.mise.toml" + if [[ -f "$mise_config" ]]; then + mise trust "$mise_config" + else + printf 'No mise configuration declared by base-demo; continuing without provider trust.\n' + fi + - name: Validate Base release stack run: | set -euo pipefail diff --git a/docs/manifest-command-trust.md b/docs/manifest-command-trust.md index 00a9aa81..88befa94 100644 --- a/docs/manifest-command-trust.md +++ b/docs/manifest-command-trust.md @@ -55,6 +55,13 @@ and user-settings plan, and applying that plan requires `--allow-project-ide-mutations`. `--yes` never supplies this approval. This keeps command execution trust and machine-wide IDE mutation consent separate. +`mise` configuration trust remains owned by mise. A disposable CI checkout that +declares `.mise.toml` must explicitly trust that reviewed file before running +`basectl setup`; use a path-scoped command such as `mise trust +/workspace/base-demo/.mise.toml`. This does not trust the user's whole home +directory, and it does not grant Base manifest-command approval. CI should keep +this provider trust step separate from `basectl trust allow `. + ## Runtime verification consent Project `check` and `doctor`, workspace `check` and `doctor`, and workspace diff --git a/tests/test_github_workflows.py b/tests/test_github_workflows.py index ae66e8a9..c96899ae 100644 --- a/tests/test_github_workflows.py +++ b/tests/test_github_workflows.py @@ -321,6 +321,19 @@ def test_base_demo_e2e_workflow_covers_the_external_project_loop() -> None: assert job["env"]["BASE_DEMO_FULL_VALIDATION"] == "1" assert job["env"]["BASE_CLI_SOURCE_DIR"].endswith(".dependencies/base-cli/lib/python") + trust_step_index = next( + index + for index, step in enumerate(steps) + if isinstance(step, dict) and step.get("name") == "Trust the selected base-demo mise configuration" + ) + setup_step_index = next( + index + for index, step in enumerate(steps) + if isinstance(step, dict) and "basectl setup --ci base-demo" in step.get("run", "") + ) + assert trust_step_index < setup_step_index + assert 'mise trust "$mise_config"' in steps[trust_step_index]["run"] + checkout_repositories = [ step.get("with", {}).get("repository") for step in steps @@ -357,6 +370,22 @@ def test_base_demo_e2e_workflow_covers_the_external_project_loop() -> None: assert "BASE_DEMO_ROOT/base_manifest.yaml" in run_commands assert "--non-interactive" in run_commands + bom_workflow = load_workflow(ECOSYSTEM_RELEASE_BOM_WORKFLOW) + bom_compatibility = bom_workflow["jobs"]["compatibility"] + bom_steps = bom_compatibility["steps"] + bom_trust_step_index = next( + index + for index, step in enumerate(bom_steps) + if isinstance(step, dict) and step.get("name") == "Trust the selected base-demo mise configuration" + ) + bom_setup_step_index = next( + index + for index, step in enumerate(bom_steps) + if isinstance(step, dict) and "basectl setup --ci base-demo" in step.get("run", "") + ) + assert bom_trust_step_index < bom_setup_step_index + assert 'mise trust "$mise_config"' in bom_steps[bom_trust_step_index]["run"] + def test_copilot_repository_instructions_stay_anchored_to_base_guidance() -> None: text = COPILOT_INSTRUCTIONS.read_text(encoding="utf-8")